zoukankan      html  css  js  c++  java
  • goahead(web服务器)分析

    一、参考网址

      1、源码的github地址

    二、网页是采用文件读写方式,还是转换为数组方式?

      1)其通过宏定义“WEBS_PAGE_ROM”来区分,我是在websPageReadData()(page.c)函数源码发现的

    int websPageReadData(webs_t wp, char *buf, int nBytes)
    {
    
    #ifdef WEBS_PAGE_ROM
        a_assert(websValid(wp));
        return websRomPageReadData(wp, buf, nBytes);
    #else
        a_assert(websValid(wp));
        return read(wp->docfd, buf, nBytes);
    #endif
    }

      2) 其保存网页的数组定义:websRomPageIndexType websRomPageIndex[], 其内部有个Page成员指向网页数组数据:

    /*
     *    Compiled Rom Page Index
     */
    typedef struct {
        char_t            *path;                    /* Web page URL path */
        unsigned char    *page;                    /* Web page data */
        int                size;                    /* Size of web page in bytes */
        int                pos;                    /* Current read position */
    } websRomPageIndexType;

      3) websRomPageIndex[]数组初始化过程

          websRomOpen()

            symEnter(romTab, name, valueInteger((int) wip), 0); //填充到sym[romTab]中

      4) 从数组中读出网页的过程:

        websDefaultHandler 注册了写事件处理

          websDefaultWriteEvent

            websPageReadData

               websRomPageReadData

    2、输入URL时,其默认网页定义

      在initwebs()函数中有UrlHandlerDefine(T("/"), NULL, 0, websHomePageHandler, 0); 

      其websHomePageHandler()定义如下:

    static int websHomePageHandler(webs_t wp, char_t *urlPrefix, char_t *webDir,
        int arg, char_t *url, char_t *path, char_t *query)
    {
    /*
     *    If the empty or "/" URL is invoked, redirect default URLs to the home page
     */
        if (*url == '' || gstrcmp(url, T("/")) == 0) {
            websRedirect(wp, T("home.asp"));
            return 1;
        }
        return 0;
    }

    3、浏览器提交的数据处理流程

      initWebs() (main.c)

        websOpenServer(port, retries);

          websOpenListen(port, retries);

            socketOpenConnection(NULL, port, websAccept, 0); 中的websAccept

              int websAccept(int sid, char *ipaddr, int port, int listenSid)

                socketCreateHandler(sid, SOCKET_READABLE, websSocketEvent, (int) wp);

                  static void websSocketEvent(int sid, int mask, int iwp)

                    void websReadEvent(webs_t wp)

                       websUrlHandlerRequest(wp)

                         sp = &websUrlHandler[i]; 其数组内容由websUrlHandlerDefine()函数填充           

                         if ((*sp->handler)(wp, sp->urlPrefix, sp->webDir, sp->arg,
                          wp->url, wp->path, wp->query))

                            int websFormHandler(webs_t wp, char_t *urlPrefix, char_t *webDir, int arg, 

                              char_t *url, char_t *path, char_t *query)

                                 sp = symLookup(formSymtab, formName);// formSymtab数组内容由websFormDefine()函数填充

                                 fn = (int (*)(void *, char_t *, char_t *)) sp->content.value.integer;

                                 (*fn)((void*) wp, formName, query); 最后的表单处理函数,

    4、对浏览器提交的数据处理,移植需要注意的两步(即最后两步)

      1)先由websUrlHandlerDefine(T("/goform"), NULL, 0, websFormHandler, 0);中注册的websFormHandler()函数处理

        其内部有怎么一段:fn = (int (*)(void *, char_t *, char_t *)) sp->content.value.integer;

                 (*fn)((void*) wp, formName, query); 

     1 int websFormHandler(webs_t wp, char_t *urlPrefix, char_t *webDir, int arg, 
     2     char_t *url, char_t *path, char_t *query)
     3 {
     4     printf("formhandler %s ----- %d
    ", __func__, __LINE__);
     5     sym_t        *sp;
     6     char_t        formBuf[FNAMESIZE];
     7     char_t        *cp, *formName;
     8     int            (*fn)(void *sock, char_t *path, char_t *args);
     9 
    10     a_assert(websValid(wp));
    11     a_assert(url && *url);
    12     a_assert(path && *path == '/');
    13 
    14     websStats.formHits++;
    15 
    16 /*
    17  *    Extract the form name
    18  */
    19     gstrncpy(formBuf, path, TSZ(formBuf));
    20     printf("path:%s
    ", path);
    21     printf("formbuf:%s
    ", formBuf);
    22     if ((formName = gstrchr(&formBuf[1], '/')) == NULL) {
    23         websError(wp, 200, T("Missing form name"));
    24         return 1;
    25     }
    26     //printf("111formname:%s
    ", formName);
    27     formName++;
    28     //printf("222formname:%s
    ", formName);
    29 #if 1
    30     if ((cp = gstrchr(formName, '/')) != NULL) //后续"/"之后的都失效
    31     {
    32         *cp = '';
    33     }
    34 #endif
    35     //printf("333formname:%s
    ", formName);
    36 /*
    37  *    Lookup the C form function first and then try tcl (no javascript support 
    38  *    yet).
    39  */
    40     sp = symLookup(formSymtab, formName);
    41     if (sp == NULL) {
    42         websError(wp, 200, T("Form %s is not defined"), formName);
    43     } else {
    44         fn = (int (*)(void *, char_t *, char_t *)) sp->content.value.integer;
    45         a_assert(fn);
    46         if (fn) {
    47 /*
    48  *            For good practice, forms must call websDone()
    49  */
    50             (*fn)((void*) wp, formName, query);
    51 
    52 /*
    53  *            Remove the test to force websDone, since this prevents
    54  *            the server "push" from a form>
    55  */
    56 #if 0 /* push */
    57             if (websValid(wp)) {
    58                 websError(wp, 200, T("Form didn't call websDone"));
    59             }
    60 #endif /* push */
    61         }
    62     }
    63     return 1;
    64 }

      2) 然后根据URL中判断是哪个表单,然后调用相应的在initWebs()函数中用websFormDefine()注册的回调函数:

          如:websFormDefine(T("gpio_p24"), on_gp24_set); 则表示URL中末尾是gpio_p24,则调用on_gp24_set()函数

    int websFormDefine(char_t *name, void (*fn)(webs_t wp, char_t *path, 
        char_t *query))
    {
        //1 printf("formdefine %s ----- %d
    ", __func__, __LINE__);
        a_assert(name && *name);
        a_assert(fn);
    
        if (fn == NULL) {
            return -1;
        }
    
        symEnter(formSymtab, name, valueInteger((long) fn), 0);
        return 0;
    }

    3

  • 相关阅读:
    oracle 游标例子
    oracle 认识
    Scut游戏服务器引擎之新手入门
    Scut游戏服务器引擎6.5.8.6发布
    Scut游戏服务器引擎之Unity3d接入
    Scut游戏服务器引擎6.1.5.6发布,直接可运行,支持热更新
    ScutSDK 0.9版本发布
    Scut游戏服务器引擎6.0.5.2发布
    Scut游戏服务器引擎6.0.5.1发布
    Scut游戏服务器引擎6.0.5.0发布-支持C#脚本
  • 原文地址:https://www.cnblogs.com/shanyu20/p/11676058.html
Copyright © 2011-2022 走看看