httpプロトコルの分析


一、httpプロトコル
http   -    
    -     (Request)  -          
        ○    :    ,    ,   ,     
            §    :       ,       ,      http  
            §    :              
            §   :         ,         
            §     :     ,            
        ○  :
        GET /3.txt HTTP/1.1
            /:         
                      
        Host: localhost:2222
        User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:24.0) Gecko/201001    01 Firefox/24.0
        Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
        Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
        Accept-Encoding: gzip, deflate
        Connection: keep-alive
        If-Modified-Since: Fri, 18 Jul 2014 08:36:36 GMT
               :       

            
                □ get:     
                □ post :    
          :\r
- (Response) - ○ : , , , § : http , , § : § : § : ○ : HTTP/1.1 200 Ok Server: micro_httpd Date: Fri, 18 Jul 2014 14:34:26 GMT Content-Type: text/plain; charset=iso-8859-1 ( ) Content-Length: 32 Content-Language: zh-CN Last-Modified: Fri, 18 Jul 2014 08:36:36 GMT Connection: close #include int main(void) { printf("hello world!
"
); return 0; } - HTTP1.1GET § , 。 ○ POST § ( )。 。POST / 。 ○ HEAD § get , , ○ PUT § 。 ○ DELETE § 。 ○ CONNECT § HTTP/1.1 。 ○ OPTIONS § 。 ○ TRACE § , 。 - HTTP , , : ○ 1xx: -- , ○ 2xx: -- 、 、 ○ 3xx: -- ○ 4xx: -- ○ 5xx: -- ○ : § 200 OK § 400 Bad Request , § 401 Unauthorized , WWW-Authenticate § 403 Forbidden , § 404 Not Found ,eg: URL § 500 Internal Server Error § 503 Server Unavailable ,

二、httpの4種類のフォーマット
    1. http    ,          Post  
    2.   
        ○  HTTP         :   、   、  、  
        ○      POST              (entity-body) ,                    。
        ○                   
        ○       ,             ,            (headers)   Content-Type                      ,        。
    3.     
        ○ application/x-www-form-urlencoded
            POST http://www.example.com HTTP/1.1
            Content-Type: application/x-www-form-urlencoded;charset=utf-8
            title=test&sub%5B%5D=1&sub%5B%5D=2&sub%5B%5D=3
        ○ application/json
            POST http://www.example.com HTTP/1.1
            Content-Type: application/json;charset=utf-8
            {"title":"test","sub":[1,2,3]}
        ○ text/xml
            POST http://www.example.com HTTP/1.1
            Content-Type: text/xml
            --?xml version="1.0"?-->
            
                examples.getStateName
                <params>
                    <value>41value>
                params>
            
        ○ multipart/form-data
            ------WebKitFormBoundaryPpL3BfPQ4cHShsBz \r
Content-Disposition: form-data; name="file"; filename="qw.png" Content-Type: image/png\r
\r
PNG ................................................................................... ................................................................................... ------WebKitFormBoundaryPpL3BfPQ4cHShsBz Content-Disposition: form-data; name="tailor" false ------WebKitFormBoundaryPpL3BfPQ4cHShsBz-- ○ § , § : - □ , . □ char *p = strstr(big, sub) ○ : § boundary , § HTML :"\r
"
§ BODY bounday HEADER “--”

三、httpフォーマットの解析
#include "fcgi_config.h"
#include "fcgi_stdio.h"
#include 
#include 
#include 
#include 
#include "fdfs_api.h"
#include "deal_mysql.h"
#include "make_log.h"
#include "upload.h"

char* memstr(char* full_data, int full_data_len, char* substr)
{
    if (full_data == NULL || full_data_len <= 0 || substr == NULL)
    {
        return NULL;

    }

    if (*substr == '\0')
    {
        return NULL;

    }

    int sublen = strlen(substr);
    char* cur = full_data;
    int last_possible = full_data_len - sublen + 1;
    for (int i = 0; i < last_possible; i++)
    {
        if (*cur == *substr)
        {
            if (memcmp(cur, substr, sublen) == 0)
            {
                // found
                return cur;
            }

        }
        cur++;
    }
    return NULL;
}

int get_file_content(char* begin, char* end, int len, char* filename)
{
    char *p = NULL;
    //            
    char boundary[256] = {0};
    // p      \r  
    p = strstr(begin, "\r
"
); strncpy(boundary, begin, p-begin); // p p += 2; // len -= (p-begin); printf("boundary: %s", boundary); // begin = p; // content-disp, begin p = strstr(begin, "\r
"
); // - p += 2; // len -= (p-begin); // filename char* pt = strstr(begin, "filename="); pt += strlen("filename="); // pt // pt ++; // char* q = strchr(pt, '"'); // strncpy(filename, pt, q-pt); printf("
filename: %s
"
, filename); // content-type begin = p; p = strstr(begin, "\r
"
); // \r
(\r
)
p += 4; // len -= (p-begin); // - begin = p; // p = memstr(begin, len, boundary); if(p == NULL) { // \r
p = end - 2; } else { // \r
p -= 2; } // int fd = open(filename, O_CREAT|O_WRONLY, 0664); write(fd, begin, p-begin); close(fd); return 0; } int store_data(char* filename, char* fileid) { // MYSQL* conn = NULL; conn = msql_conn("root", "root", "test"); if(conn == NULL) { LOG("upload_file", "mysql", " !"); return -1; } // , , mysql_query(conn, "set names utf8"); // // char buf[1024]; sprintf(buf, "insert into file (name, fileid) values ('%s', '%s')", filename, fileid); printf("
sql: %s

"
, buf); // sql // , 0。 if ( mysql_query (conn, buf) != 0 ) { LOG("upload_file", "mysql", " "); return -1; } // mysql_close(conn); return 0; } int main () { while (FCGI_Accept() >= 0) { int len = 0; // post char *contentLength = getenv("CONTENT_LENGTH"); printf("Content-type: text/html\r
"
"\r
"
); if (contentLength != NULL) { len = strtol(contentLength, NULL, 10); } if (len <= 0) { printf("No data from standard input.


"

); } else { int ch; char filename[128] = {0}; // post , char* file_data = (char*)malloc(len); char *begin, *end, *p; // end = NULL; begin = p = file_data; // post , file_data for (int i = 0; i < len; i++) { if ((ch = getchar()) < 0) { printf("Error: Not enough bytes received on standard input


"

); break; } *p = ch; // p++; } // end end = p; // get_file_content(begin, end, len, filename); // fastdfs char fileid[1024] = {0}; fdfs_upload_file(filename, fileid); printf("
fileid: %s

"
, fileid); // qw.png - /group1/M00/00/00/xxxxxx.png // store_data(filename, fileid); // free(file_data); // unlink(filename); } } /* while */ return 0; }