mirror of
https://github.com/cesanta/mongoose.git
synced 2026-10-17 10:49:47 +00:00
64 lines
2.2 KiB
C
64 lines
2.2 KiB
C
#include "internal.h"
|
|
|
|
// Parse HTTP headers from the given buffer, advance buffer to the point
|
|
// where parsing stopped.
|
|
static void parse_http_headers(char **buf, struct mg_request_info *ri) {
|
|
int i;
|
|
|
|
for (i = 0; i < (int) ARRAY_SIZE(ri->http_headers); i++) {
|
|
ri->http_headers[i].name = skip_quoted(buf, ":", " ", 0);
|
|
ri->http_headers[i].value = skip(buf, "\r\n");
|
|
if (ri->http_headers[i].name[0] == '\0')
|
|
break;
|
|
ri->num_headers = i + 1;
|
|
}
|
|
}
|
|
|
|
static int is_valid_http_method(const char *method) {
|
|
return !strcmp(method, "GET") || !strcmp(method, "POST") ||
|
|
!strcmp(method, "HEAD") || !strcmp(method, "CONNECT") ||
|
|
!strcmp(method, "PUT") || !strcmp(method, "DELETE") ||
|
|
!strcmp(method, "OPTIONS") || !strcmp(method, "PROPFIND")
|
|
|| !strcmp(method, "MKCOL");
|
|
}
|
|
|
|
// Parse HTTP request, fill in mg_request_info structure.
|
|
// This function modifies the buffer by NUL-terminating
|
|
// HTTP request components, header names and header values.
|
|
static int parse_http_message(char *buf, int len, struct mg_request_info *ri) {
|
|
int is_request, request_length = get_request_len(buf, len);
|
|
if (request_length > 0) {
|
|
// Reset attributes. DO NOT TOUCH is_ssl, remote_ip, remote_port
|
|
ri->remote_user = ri->request_method = ri->uri = ri->http_version = NULL;
|
|
ri->num_headers = 0;
|
|
|
|
buf[request_length - 1] = '\0';
|
|
|
|
// RFC says that all initial whitespaces should be ingored
|
|
while (*buf != '\0' && isspace(* (unsigned char *) buf)) {
|
|
buf++;
|
|
}
|
|
ri->request_method = skip(&buf, " ");
|
|
ri->uri = skip(&buf, " ");
|
|
ri->http_version = skip(&buf, "\r\n");
|
|
|
|
// HTTP message could be either HTTP request or HTTP response, e.g.
|
|
// "GET / HTTP/1.0 ...." or "HTTP/1.0 200 OK ..."
|
|
is_request = is_valid_http_method(ri->request_method);
|
|
if ((is_request && memcmp(ri->http_version, "HTTP/", 5) != 0) ||
|
|
(!is_request && memcmp(ri->request_method, "HTTP/", 5) != 0)) {
|
|
request_length = -1;
|
|
} else {
|
|
if (is_request) {
|
|
ri->http_version += 5;
|
|
}
|
|
parse_http_headers(&buf, ri);
|
|
}
|
|
}
|
|
return request_length;
|
|
}
|
|
|
|
static int parse_range_header(const char *header, int64_t *a, int64_t *b) {
|
|
return sscanf(header, "bytes=%" INT64_FMT "-%" INT64_FMT, a, b);
|
|
}
|