Goahead编译

Goahead 编译

目录说明#

Copy
Makefile #顶层Makefile,可以自动检测当前运行平台的环境,并调用projects的mk projects #子层的Makefile,有各个平台的 test # web 文件以及路由和配置文件 #可以看到直接make 输出如下 make --no-print-directory -f projects/goahead-linux-default.mk all # 安装 sudo make install

Ubuntu编译#

make

Copy
make sudo make install

selfkey处理

Copy
reallin@ubuntu:/work/goahead/goahead-5.0.1$ sudo goahead -v --home /etc/goahead /var/www/goahead goahead: 0: Unable to read key self.key goahead: 0: Cannot initialize server. Exiting. sudo cp ./build/linux-x64-default/bin/self.key /etc/goahead sudo cp ./build/linux-x64-default/bin/self.crt /etc/goahead

测试

Copy
#./goahead -v --home 配置文件路径 文档路径 绑定IP:监听端口 #./goahead -v --home /etc/goahead /var/www/goahead 0.0.0.0:8888 sudo goahead -v --home /etc/goahead /var/www/goahead # 下面是运行结果 goahead: 2: Configuration for Embedthis GoAhead Community Edition goahead: 2: --------------------------------------------- goahead: 2: Version: 5.0.1 goahead: 2: BuildType: Debug goahead: 2: CPU: x64 goahead: 2: OS: linux goahead: 2: Host: 127.0.1.1 goahead: 2: Directory: /etc/goahead goahead: 2: Documents: /var/www/goahead goahead: 2: Configure: me -d -q -platform linux-x86-default -configure . -gen make goahead: 2: --------------------------------------------- goahead: 2: Started http://*:80 goahead: 2: Started https://*:443

具体的install目录

Copy
ls /etc/goahead auth.txt route.txt self.crt self.key ls /var/www/goahead favicon.ico index.html # 这个就是网页了

交叉编译#

Copy
# 如果有错误提示 undefined reference to `__stack_chk_fail' 加上这个选项-fno-stack-protector make CC=arm-linux-gcc LD=arm-linux-ld CFLAGS=-fno-stack-protector

方便测试#

  1. cd build/linux-x64-default/bin

  2. cp ../../../src/auth.txt ./

  3. cp ../../../src/route.txt ./

  4. 新建一个myweb文件夹存网页

  5. sudo ./goahead -v ./myweb/

  6. 修改配置文件route.txt

    Copy
    1.把route uri=/action handler=action注释掉 在前面加个#即可 然后加一句route uri=/action/ methods=GET|POST handler=action 2. 把route uri=/ extensions=jst handler=jst改为route uri=/ extensions=jst,asp,html handler=jst 如果不做修改那我们在以后写html,asp文件里的action就不能被识别

win下编译#

顶层目录的make.bat 修改下,因为原来的默认工程找不到路径

Copy
projects\windows x64 nmake -f projects/goahead-windows-default.nmake %1 %2 %3 %4 %5 %6 %7 %8 %9

运行之后,打开projects下的goahead-windows-default.sln就可以编译了

如果要调试,需要设置调试目录为 ../../test,加上参数-v即可

可以选择启动项目为test或者goahead.

早期的源码流程#

Copy
-------------------------------------------------------------------------------------- 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(); //关闭相关资源
posted @   zongzi10010  阅读(1795)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?
点击右上角即可分享
微信分享提示
CONTENTS