源码结构:
--------------------------------------------------------------------------------------
MAIN(goahead, int argc, char **argv, char **envp)
-------------------------------------初始化过程开始-------------------------------------
|-->for(argv[...]){} //解析命令行
|-->initPlatform(); //注册信号处理函数
|-->signal(SIGTERM, sigHandler) ...
|-->websOpen(documents, route) //初始化服务器
|-->websOsOpen(); //生成系统启动随机数(标识系统)
|-->websRuntimeOpen(); //开始系统计时sym、symMax
|-->websTimeOpen(); //初始化hash结构timeTokens
|-->logOpen(); //初始化基本日志
|-->setFileLimits(); //设置最大文件描述符值
|-->socketOpen(); //初始化WebsSocket **socketList=NULL,socketMax =0,socketHighestFd=-1
|-->setLocalHost(); //设置服务器的hostname(websHost), 服务器的IP地址(websIpAddr)
|-->sslOpen(); //若支持ssl则初始化ssl相关信息
|-->sessions = hashCreate(-1); //初始化话hash结构sessions
|-->websStartEvent(...pruneSessions...); //启动定时调度函数pruneSessions ,pruneSessions每秒调度清除过期的sessions
|-->websSetDocuments(documents); //设置goahead访问根目录websDocuments
|-->websOpenRoute(); //初始化hash结构handlers,相应函数加入到handlers中.
|-->websDefineHandler("continue", continueHandler, 0, 0, 0); //continue的处理函数为continueHandler
|-->websDefineHandler("redirect", redirectHandler, 0, 0, 0); //redirect处理函数为redirectHandler
|-->websCgiOpen(); //定义cgi处理函数加入到handlers中.
|-->websDefineHandler("cgi", 0, cgiHandler, 0, 0); //定义cgi的处理函数为cgiHandler
|-->websOptionsOpen(); //定义options处理函数加入到handlers中.
|-->websDefineHandler("options", 0, optionsHandler, 0, 0); //定义options的处理函数为optionsHandler
|-->websActionOpen(); //初始化hash结构actionTable,定义action处理函数加入到handlers中,定义action对应值的函数加入到actionTable中. .
|-->websDefineHandler("action", 0, actionHandler, closeAction, 0); //定义action的处理函数为actionHandler
|-->WebActionDefineInit(); //初始化action对应值的处理函数
|-->websDefineAction("upgrade", ActionDefault); //定义action=upgrade的处理函数为ActionDefault,
|-->websDefineAction("...", ...); //同上的类似函数
|-->websFileOpen(); //设置默认页面websIndex="index.html",定义action处理函数加入到handlers中
|-->websDefineHandler("file", 0, fileHandler, fileClose, 0); //定义file的处理函数为fileHandler
|-->websUploadOpen(); //设置上传文件路径uploadDir = "/tmp",定义upload处理函数加入到handlers中
|-->websDefineHandler("upload", 0, uploadHandler, 0, 0); //定义upload的处理函数为uploadHandler
|-->websJstOpen(); //初始化hash结构websJstFunctions,定义write处理函数加入到websJstWrite中,定义jst处理函数加入到jstHandler中.
|-->websDefineJst("write", websJstWrite); //定义jst(javascript)的write的处理函数为websJstWrite,支持<% write("text"); %>
|-->websDefineHandler("jst", 0, jstHandler, closeJst, 0); //定义jst(javascript)的处理函数为jstHandler
|-->websOpenAuth(0); //初始化认证相关处理函数
|-->websDefineAction("userlogin", ActionUserLoginProc); //定义action=userlogin的处理函数为ActionUserLoginProc
|-->websDefineAction("userlogout", ActionUserLogoutProc); //定义action=userlogin的处理函数为ActionUserLoginProc
|-->verifyPassword = websVerifyPasswordFromFile; //设置验证密码函数
|-->websFsOpen(0); //初始化hash结构romFs,定义ME_ROM相关文件路径
|-->websLoad(routeFile); //load route.txt配置文件
|-->route = websAddRoute(uri, handler, -1) //将结构为WebsRoute的route加入hash结构routes中,初始化route中uri和handler
|-->websSetRouteMatch(route, dir, protocol, methods, extensions, abilities, redirects); //初始化route中protocol等
|-->websSetRouteAuth(route, auth) //初始化route中authType等
|-->for(websMimeList){hashEnter(websMime)} //初始化goahead默认支持的content type
|-->open(accessLog, O_CREAT | O_TRUNC | O_APPEND | O_WRONLY, 0666) //初始化access.log log日志文件
|-->websLoad(auth) //load auth.txt配置文件
|-->websAddRole(name, abilities) //增加管理角色,如role name=manager abilities=view,edit,delete
|--> websAddUser(username, password, roles) //增加管理用户,如user name=admin password=xx roles=manager,purchaser
---------------------------------------初始化过程结束-------------------------------------------
|-->logHeader(); //日志打印goahead基本配置信息
|-->websListen(endpoint) //初始化socket并监听
|-->socketParseAddress(endpoint, &ip, &port, &secure, 80); //解析监听ip 端口
|-->sid = socketListen(ip, port, websAccept, 0) //创建socket,并监听,初始化WebsSocket结构加入到socketlist中
|-->listens[listenMax++] = sid //保存socket的WebsSocket信息到listens中
|-->websGetBackground() //使用daemon(0, 0)设置后台运行
---------------------------------------主循环处理开始-------------------------------------------
|-->websServiceEvents(&finished); //while(!finished){}主循环
|-->socketSelect(-1, delay) //select socket
|-->nEvents = select(socketHighestFd + 1, (fd_set *) readFds, (fd_set *) writeFds, (fd_set *) exceptFds, &tv); //select socket
|-->socketProcess() //处理请求
|-->socketDoEvent(sp);
|-->socketAccept(sp); //accept新请求
|-->newSock = accept(sp->sock, addr, (Socklen*) &len) //accept 新socket
|-->nid = socketAlloc(sp->ip, sp->port, sp->accept, sp->flags); //分配并初始化新的WebsSocket,加入到socketList[nid]
|-->socketList[nid] ->sock = newSock ... //继续初始化新的socketList[nid]的WebsSocket结构
|-->(sp->accept)(nid, ipbuf, port, sp->sid) //调用websAccept函数, nid为新建请求的socketid, ipbuf为远端IP,port为远端port, sp->sid为本机监听的socketid
|-->wid = websAlloc(sid);wp=webs[wid]; //根据参数sid(即nid)分配并初始化新的Webs,加入到webs[wid]
|-->initWebs(wp, 0, 0); //初始化新的webs[wid]的Webs结构
|-->wp->state = WEBS_BEGIN; //初始化链接状态机初始值
|-->bufCreate(&wp->output); //初始化发送buf
|-->bufCreate(&wp->input); //初始化接收buf
|-->wp->listenSid = listenSid; ... //继续初始化新的webs[wid]的Webs结构
|-->wp->timeout = websStartEvent(PARSE_TIMEOUT, checkTimeout, (void*) wp); //设置wp的超时函数
|-->socketEvent(sid, SOCKET_READABLE, wp); //
|-->readEvent(wp); //一直调用readEvent读http和处理http,直至处理接收设置SOCKET_WRITABLE才可调用writeEvent
|-->nbytes = websRead(wp, (char*) rxbuf->endp, ME_GOAHEAD_LIMIT_BUFFER) //读取http报文
|-->websPump(wp); //根据wp->state状态机的值处理http报文
|-->case WEBS_BEGIN: parseIncoming(wp);
|-->parseFirstLine(wp); //处理http请求行,并保存到wp结构中
|-->parseHeaders(wp); //处理http请求头部,并保存到wp结构中
|-->wp->state = (wp->rxChunkState || wp->rxLen > 0) ? WEBS_CONTENT : WEBS_READY; //设置wp->state状态值
|-->websRouteRequest(wp); //设置此链接的处理函数
|-->case WEBS_CONTENT: processContent(wp);
|-->websProcessCgiData(wp); //设置此链接的处理函数jstHandler、cgiHandler、continueHandler、redirectHandler、actionHandler等
|-->case WEBS_READY: websRunRequest(wp);
|-->(*route->handler->service)(wp); //执行此链接的处理函数,
|-->hashLookup(actionTable, actionName);(*fn)((void*) wp); //以actionHandler为例,执行actionTable中对应函数,以ActionDefault为例
|-->ActionDefault
|-->websWrite_ex(webs, 0, json_object_to_json_string(obj),token); //返回页面数据
|-->jstHandler(Webs *wp); //以jstHandler为例,执行...
|-->...websDone(wp);
|-->websFlush(wp, 0); -->wp->state = WEBS_COMPLETE;
|-->socketCreateHandler(wp->sid, sp->handlerMask | SOCKET_WRITABLE, socketEvent, wp);
|-->case WEBS_RUNNING: /* Nothing to do until websDone is called */
|-->case WEBS_COMPLETE: complete(wp, 1);
|-->socketCreateHandler(wp->sid, sp->handlerMask | SOCKET_READABLE, socketEvent, wp); //初始化此链接的处理函数sp->handler=socketEvent
|-->writeEvent(wp);
|-->websFlush(wp, 0);
|-->while(websWriteSocket());
|-->wp->state = WEBS_COMPLETE;
|-->websFree(wp);
|-->(sp->handler)(sid, sp->handlerMask & sp->currentEvents, sp->handler_data) //
|-->websCgiPoll(); //如有cgi,只响应cgi
|-->websRunEvents(); //执行已加入定时器相关函数
|-->websClose(); //关闭相关资源