首先我们来看一下HTTP报文的结构
解析请求行
int process_status_line(char *start, char *end, struct http_request *httpRequest) {
int size = end - start;
//method
char *space = strstr(start," ");
assert(space != NULL);
int method_size = space - start;
httpRequest->method = malloc(method_size + 1);
strncpy(httpRequest->method, start, method_size);
httpRequest->method[method_size] = '\0';
//url
start = space + 1;
space = strstr(start," ");
assert(space != NULL);
int url_size = space - start;
httpRequest->url = malloc(url_size + 1);
strncpy(httpRequest->url, start, url_size);
httpRequest->url[url_size] = '\0';
//version
start = space + 1;
space = strstr(start," ");
assert(space != NULL);
int version_size = space - start;
httpRequest->version = malloc(version_size + 1);
strncpy(httpRequest->version, start, version_size);
httpRequest->version[version_size] = '\0';
return size;
}
解析请求头部
int parse_http_request(struct Buffer *buf, struct http_request *httpRequest) {
int ok = 1;
int cnt = 0;
while(httpRequest->current_state != REQUEST_DONE && cnt < 100) {
cnt++;
if (httpRequest->current_state == REQUEST_STATUS) {
printf("httpRequest->current_state == REQUEST_STATUS\n");
printf("buf->read_index= %d, buf->write->index=%d\n", buf->read_index, buf->write_index);
char *crlf = strstr(buf->data + buf->read_index, "\r\n");
if (crlf != NULL) {
int status_line_size = process_status_line(buf->data + buf->read_index, crlf, httpRequest);
if (status_line_size) {
buf->read_index = status_line_size + 2; //crlf + 2
httpRequest->current_state = REQUEST_HEADERS; //等待解析headers
printf("REQUEST_STATUS done!\n");
}
} else printf("crlf error!\n");
} else if (httpRequest->current_state == REQUEST_HEADERS) {
printf("httpRequest->current_state == REQUEST_HEADERS\n");
char *crlf = strstr(buf->data + buf->read_index,"\r\n");
if (crlf) {
char *start = buf->data + buf->read_index;
char *colon = strstr(start, ": ");
if (colon != NULL) {
char *key = malloc(colon - start + 1);
strncpy(key, start, colon - start);
key[crlf - start] = '\0';
char *val = malloc(crlf - colon - 1);
strncpy(val, colon + 2, crlf - colon - 2);
val[crlf - colon - 2] = '\0';
httpRequest->request_headers[httpRequest->request_header_num].key = key;
httpRequest->request_headers[httpRequest->request_header_num].val = val;
httpRequest->request_header_num++;
buf->read_index = crlf + 2 - buf->data;
} else {
buf->read_index = crlf + 2 - buf->data;
httpRequest->current_state = REQUEST_DONE;
}
}
}
}
return ok;
}