httpプロトコルの分析
19715 ワード
一、httpプロトコル
二、httpの4種類のフォーマット
三、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.1
○ GET
§ , 。
○ 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>41 value>
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;
}