Mongoose6.0源码分析(2)-http数据处理

来源:互联网 发布:淘宝逆战 编辑:程序博客网 时间:2024/05/21 10:47

http_handle开始新的旅程(老吴analyze_request


调用1:

mg_parse_http :处理请求包和应答包的头部

   {

    get_request_len:得到http包头状态行的长度,不包括body。

    mg_skip计算了请求行各标记的长度,不计空格

     [  

     

//////请求包

    s = mg_skip(s, end, " ", &hm->method);//将method的长度存储在hm->method.len,并把s指到uri的第一位,并将hm->method.p指在起始位置
    s = mg_skip(s, end, " ", &hm->uri);
    s = mg_skip(s, end, "\r\n", &hm->proto);

////应答包

    s = mg_skip(s, end, " ", &hm->proto);//协议处理

    hm->resp_code = atoi(s);//转换应答码

   s = mg_skip(s, end, "\r\n", &hm->resp_status_msg);//即 OK

    ]

    parse_http_headers:处理包头键值对,存储在array(header_names,header_value)中,通过Content-Length键值读取body长度body.len。

    req->message.len = len + req->body.len; //获得了总长度

   }


调用2: (s = mg_get_http_header(&hm, "Transfer-Encoding")) != NULL &&
        mg_vcasecmp(s, "chunked") == 0) {

    {

   这里是判断是否存在Transfer-Encoding键,及值是否为chunked;

  传输数据编码:Transfer-Encoding 
  数据编码,即表示数据在网络传输当中,使用怎么样的保证方式来保证数据是安全成功地传输处理。可以是分段传输,也可以是不分段,直接使用原数据进行传输。 
  有效的值为:Trunked和Identity. 

     }

调用3:mg_handle_chunked 处理分块传输 处理分块传输的数据(如果有的话)

  

   

回到http_handle

    else if (hm.message.len <= io->len) { //正确时走这里
      /* Whole HTTP message is fully buffered, call event handler */ //完全传送了调用事务处理

     nc->handler(nc, nc->listener ? MG_EV_HTTP_REQUEST : MG_EV_HTTP_REPLY,
                  &hm);  //调用了用户指定函数,分别是处理请求和做应答

   用户设置的回调函数调用 mg_serve_http

              [ 

                 1、  uri_to_path(hm, path, sizeof(path), &opts); //16进制字符码解码,uri重写(?)

                        [

                                *host_hdr = mg_get_http_header(hm, "Host");mg_get_http_header(hm, "Host");//寻找host键值对,返回值为键值对地址,给host_hdr

                                mg_url_decode(hm->uri.p, hm->uri.len, uri, sizeof(uri), 0);//16进制代替的字符解码(这函数名起的不好,糊涂) .p指在当前值起始位置

                                

                        ]

                2、指定了默认参数

                 3、mg_send_http_file 根据收到的http头内容分析,主要是对请求路径提取,对客户端进行反馈

                     [

                             static int is_dav_request(const struct mg_str *s) :寻找 "PUT","DELETE","MKCOL","PROPFIND"等特殊用法

                             S_ISDIR(st.st_mode)  ==#define S_ISDIR(x) ((x) &_S_IFDIR)  将st.st_mode与_S_IFDIR按位与,判定路径是目录还是文件

                             send_http_error(nc, 501, NULL);发送错误501 // 501错误:Web 服务器不理解或不支持客户端发送给它的 HTTP 数据流中找到的 HTTP 方法。

                            is_authorized:

                           mg_stat(path, &st):查找路径是否存在

                           !find_index_file(path, path_buf_len, opts->index_files, &st)) { //找寻路径下默认文件名,如index.htm存在,把文件信息存在st指向的缓存中,返回是否找到,找到返回1.否则返回0

                        

                     (注明一下opt选项

                            //s_http_server_opts.document_root = ".";  // Serve current directory  
                           //s_http_server_opts.enable_directory_listing = "yes"; 

                             //opts.per_directory_auth_file = ".htpasswd";

                             //opts.enable_directory_listing = "yes";

                           //opts.cgi_file_pattern = "**.cgi$|**.php$";

                           // opts.ssi_pattern = "**.shtml$|**.shtm$";

                           //opts.index_files = "index.html,index.htm,index.shtml,index.cgi,index.php";

                     )

                     mg_send_http_file2:重点处理了带range参数的请求包头,根据range情况计算应答文件长度,生成应答包头,并调用

                      transfer_file_data();

                            [

                                 transfer_file_data()组合数据,发送应答包。

                            ]

                          mg_printf(重要的函数)len = mg_vprintf(conn, fmt, ap);//把ap中的数据存入conn->send_mbuf中

                      ]

             ]

0 0