这是我在学习搭建webserver时的笔记。此开源项目由C语言实现。
github开源项目链接:https://github.com/EZLippi/Tinyhttpd
建议参考:TinyHTTPd开源项目总结 - Caso_卡索 - 博客园 (cnblogs.com)
Tinyhttpd精读解析 - nengm - 博客园 (cnblogs.com)
HTTP服务器的本质:tinyhttpd源码分析及拓展 - 七夜的故事 - 博客园 (cnblogs.com)
这几个博客原理和代码讲得比较详细,有些遇到的问题可以参考着解决。
本人计算机小白,在搭建webserver之前建议小白先了解:HTTP协议、TCP协议、基本TCP套接字编程以及linux基本操作指令、vim的使用、如何makefile等等。
有几个需要注意的地方:
1、关于脚本实现的部分。
(1)测试CGI时需要本机安装PERL,同时安装perl-cgi。我的ubuntu系统自带perl,测试时报错:Can‘t locate CGI.pm in @INC (you may need to install the CGI module)
因此需要装perl-cgi模块,参考解决 Can‘t locate CGI.pm in @INC (you may need to install the CGI module)_胡鹄的博客-CSDN博客;
(2)需要修改htdocs文件夹下的.cgi代码首行路径为本机perl所在路径。在ubuntu终端可用指令which perl查看本机perl的路径。
2、关于makefile部分。
不需要按照原开源项目的makefile实现,可以只实现httpd,改成:
all: httpd httpd: httpd.c gcc -g -W -Wall -pthread -o httpd httpd.c clean: rm httpd
3、如何运行webserver
在ubuntu终端运行httpd程序,然后可在ubuntu系统的firefox浏览器中打开127.0.0.1:对应端口号。
下面是httpd.c的代码:
#include <stdio.h> #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <ctype.h> #include <strings.h> #include <string.h> #include <sys/stat.h> #include <pthread.h> #include <sys/wait.h> #include <stdlib.h> #include <stdint.h> #define ISspace(x) isspace((int)(x)) #define SERVER_STRING "Server: jdbhttpd/0.1.0 " #define STDIN 0 #define STDOUT 1 #define STDERR 2 void accept_request(void *); void bad_request(int); void cat(int, FILE *); void cannot_execute(int); void error_die(const char *); void execute_cgi(int, const char *, const char *, const char *); int get_line(int, char *, int); void headers(int, const char *); void not_found(int); void serve_file(int, const char *); int startup(u_short *); void unimplemented(int); /**********************************************************************/ /* A request has caused a call to accept() on the server port to * return. Process the request appropriately. * Parameters: the socket connected to the client */ /**********************************************************************/ void accept_request(void *arg) { int client = (intptr_t)arg; char buf[1024]; size_t numchars; char method[255]; char url[255]; char path[512]; size_t i, j; struct stat st; int cgi = 0; /* becomes true if server decides this is a CGI * program */ char *query_string = NULL; numchars = get_line(client, buf, sizeof(buf)); i = 0; j = 0; while (!ISspace(buf[i]) && (i < sizeof(method) - 1)) { method[i] = buf[i]; i++; } j=i; method[i] = '