goahead是一个轻量级的web server,在深入代码之前,结构体设计上有3个重要的结构体数组(或链表)需要提前了解
一、WebsRoute数组用于关联关联一类http请求,每一个http请求都会通过prefix(url请求的实际部分,如http://192.168.1.1/ddddffff/中的ddddffff)、protocol(HTTP 1.1等)、methods(GET、POST等)、authType(会话与认证相关) 等匹配确认
typedef struct WebsRoute {
char *prefix; /**< Route path prefix */
ssize prefixLen; /**< Prefix length */
char *dir; /**< Filesystem base directory for route documents */
char *protocol; /**< HTTP protocol to use for this route */
char *authType; /**< Authentication type */
WebsHandler *handler; /**< Request handler to service requests */
WebsHash abilities; /**< Required user abilities */
WebsHash extensions; /**< Permissible URI extensions */
WebsHash redirects; /**< Response redirections */
WebsHash methods; /**< Supported HTTP methods */
WebsAskLogin askLogin; /**< Route path prefix */
WebsParseAuth parseAuth; /**< Parse authentication details callback*/
WebsVerify verify; /**< Verify password callback */
int flags; /**< Route control flags */
} WebsRoute;
二、WebsHandler链表用于WebsRoute匹配后的内部处理,WebsRoute通过name关联起来,比如目前我们的做法是:http://192.168.1.1/XXXXXX/YYYYYY,这里XXXXXX可以是任意的,我们用到的比较有效的为login和ctfun2个
typedef struct WebsHandler {
char *name; /**< Handler name */
WebsHandlerProc match; /**< Handler match callback */
WebsHandlerProc service; /**< Handler service callback */
WebsHandlerClose close; /**< Handler close callback */
int flags; /**< Handler control flags */
} WebsHandler;
三、对于goahead的主流程:
websAuthInit -初始化认证信息
websListen -初始化监听端口,关键变量:socketList套接字链表、listens
build_default_route -初始化WebsRoute数组、WebsHandler链表(webFunNode数组为静态数组)
websServiceEvents -> socketProcess -循环处理套接字内容,每个套接字都会设置一个接收处理回调函数handler,这里基本分为2类:
对于监听套接字而言,最终调用的处理函数为socketAccept -> (sp->accept) -> websAccept,websAccept会为每一个连接请求分配一个Webs结构体用于连接请求相关信息,这就是我们在goahead中后续接触最多的wp指针
对于tcp accept的客户套接字而言,最终调用的处理函数为(sp->handler) -> socketEvent
而我们需要处理的本身就是tcp accept的客户套接字传输的文本内容,所以这里继续顺着socketEvent往下跟踪重要函数:
读取HTTP报文头部WEBS_BEGIN -> websPump -> parseIncoming -> websRouteRequest -> (route->handler->match)。匹配WebsRoute成功后 设置wp->route为对应WebsRoute数组的成员
读取HTTP报文正文WEBS_CONTENT -> processContent
读取HTTP报文完毕WEBS_READY -> websRunRequest -> (wp->route) -> (route->handler->service)