Goahead編譯



title: Goahead編譯
date: 2019/11/6 09:45:01
toc: true

Goahead 編譯

目錄說明

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

make
sudo make install

selfkey處理

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

測試

#./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目錄

ls /etc/goahead
auth.txt  route.txt  self.crt  self.key

ls /var/www/goahead
favicon.ico  index.html  # 這個就是網頁了

交叉編譯

# 如果有錯誤提示 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

    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 修改下,因為原來的默認工程找不到路徑

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.

早期的源碼流程

--------------------------------------------------------------------------------------
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();              //關閉相關資源


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM