Refactored http header parsing error handling
This commit is contained in:
16
src/client.c
16
src/client.c
@ -40,6 +40,8 @@ int client_request_handler(sock *client, int req_num) {
|
|||||||
int ret, client_keep_alive;
|
int ret, client_keep_alive;
|
||||||
char buf[64];
|
char buf[64];
|
||||||
char msg_buf[4096];
|
char msg_buf[4096];
|
||||||
|
char err_msg[256];
|
||||||
|
err_msg[0] = 0;
|
||||||
char *host, *hdr_connection, *webroot;
|
char *host, *hdr_connection, *webroot;
|
||||||
|
|
||||||
fd_set socket_fds;
|
fd_set socket_fds;
|
||||||
@ -62,6 +64,15 @@ int client_request_handler(sock *client, int req_num) {
|
|||||||
ret = http_receive_request(client, &req);
|
ret = http_receive_request(client, &req);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
client_keep_alive = 0;
|
client_keep_alive = 0;
|
||||||
|
if (ret < 0) {
|
||||||
|
goto abort;
|
||||||
|
} else if (ret == 1) {
|
||||||
|
sprintf(err_msg, "Unable to parse header: Invalid header format.");
|
||||||
|
} else if (ret == 2) {
|
||||||
|
sprintf(err_msg, "Unable to parse header: Invalid method.");
|
||||||
|
} else if (ret == 3) {
|
||||||
|
sprintf(err_msg, "Unable to parse header: Invalid version");
|
||||||
|
}
|
||||||
res.status = http_get_status(400);
|
res.status = http_get_status(400);
|
||||||
goto respond;
|
goto respond;
|
||||||
}
|
}
|
||||||
@ -71,6 +82,7 @@ int client_request_handler(sock *client, int req_num) {
|
|||||||
host = http_get_header_field(&req.hdr, "Host");
|
host = http_get_header_field(&req.hdr, "Host");
|
||||||
if (host == NULL || strchr(host, '/') != NULL) {
|
if (host == NULL || strchr(host, '/') != NULL) {
|
||||||
res.status = http_get_status(400);
|
res.status = http_get_status(400);
|
||||||
|
sprintf(err_msg, "The client provided no or an invalid Host header field.");
|
||||||
goto respond;
|
goto respond;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,7 +108,7 @@ int client_request_handler(sock *client, int req_num) {
|
|||||||
if (res.status->code >= 300 && res.status->code < 600) {
|
if (res.status->code >= 300 && res.status->code < 600) {
|
||||||
http_error_msg *http_msg = http_get_error_msg(res.status->code);
|
http_error_msg *http_msg = http_get_error_msg(res.status->code);
|
||||||
len = sprintf(msg_buf, http_error_document, res.status->code, res.status->msg,
|
len = sprintf(msg_buf, http_error_document, res.status->code, res.status->msg,
|
||||||
http_msg != NULL ? http_msg->err_msg : "", NULL,
|
http_msg != NULL ? http_msg->err_msg : "", err_msg[0] != 0 ? err_msg : "",
|
||||||
res.status->code >= 300 && res.status->code < 400 ? "info" : "error");
|
res.status->code >= 300 && res.status->code < 400 ? "info" : "error");
|
||||||
sprintf(buf, "%i", len);
|
sprintf(buf, "%i", len);
|
||||||
http_add_header_field(&res.hdr, "Content-Length", buf);
|
http_add_header_field(&res.hdr, "Content-Length", buf);
|
||||||
@ -122,6 +134,8 @@ int client_request_handler(sock *client, int req_num) {
|
|||||||
print("%s%03i %s (%s)%s", http_get_status_color(res.status), res.status->code, res.status->msg,
|
print("%s%03i %s (%s)%s", http_get_status_color(res.status), res.status->code, res.status->msg,
|
||||||
format_duration(micros, buf), CLR_STR);
|
format_duration(micros, buf), CLR_STR);
|
||||||
|
|
||||||
|
abort:
|
||||||
|
|
||||||
http_free_req(&req);
|
http_free_req(&req);
|
||||||
http_free_res(&res);
|
http_free_res(&res);
|
||||||
return !client_keep_alive;
|
return !client_keep_alive;
|
||||||
|
@ -66,7 +66,7 @@ int http_receive_request(sock *client, http_req *req) {
|
|||||||
|
|
||||||
if (rcv_len == 0) {
|
if (rcv_len == 0) {
|
||||||
print("Unable to receive: closed");
|
print("Unable to receive: closed");
|
||||||
return 1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr = buf;
|
ptr = buf;
|
||||||
@ -75,7 +75,7 @@ int http_receive_request(sock *client, http_req *req) {
|
|||||||
if (pos0 == NULL || pos0[1] != '\n') {
|
if (pos0 == NULL || pos0[1] != '\n') {
|
||||||
print(ERR_STR "Unable to parse header: Invalid header format" CLR_STR);
|
print(ERR_STR "Unable to parse header: Invalid header format" CLR_STR);
|
||||||
free(buf);
|
free(buf);
|
||||||
return -1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (req->version[0] == 0) {
|
if (req->version[0] == 0) {
|
||||||
@ -98,7 +98,7 @@ int http_receive_request(sock *client, http_req *req) {
|
|||||||
} else {
|
} else {
|
||||||
print(ERR_STR "Unable to parse header: Invalid method" CLR_STR);
|
print(ERR_STR "Unable to parse header: Invalid method" CLR_STR);
|
||||||
free(buf);
|
free(buf);
|
||||||
return -1;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
pos1 = memchr(ptr, ' ', rcv_len - (ptr - buf)) + 1;
|
pos1 = memchr(ptr, ' ', rcv_len - (ptr - buf)) + 1;
|
||||||
@ -108,13 +108,13 @@ int http_receive_request(sock *client, http_req *req) {
|
|||||||
err_hdr_fmt:
|
err_hdr_fmt:
|
||||||
print(ERR_STR "Unable to parse header: Invalid header format" CLR_STR);
|
print(ERR_STR "Unable to parse header: Invalid header format" CLR_STR);
|
||||||
free(buf);
|
free(buf);
|
||||||
return -1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (memcmp(pos2, "HTTP/", 5) != 0 || memcmp(pos2 + 8, "\r\n", 2) != 0) {
|
if (memcmp(pos2, "HTTP/", 5) != 0 || memcmp(pos2 + 8, "\r\n", 2) != 0) {
|
||||||
print(ERR_STR "Unable to parse header: Invalid version" CLR_STR);
|
print(ERR_STR "Unable to parse header: Invalid version" CLR_STR);
|
||||||
free(buf);
|
free(buf);
|
||||||
return -1;
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
len = pos2 - pos1 - 1;
|
len = pos2 - pos1 - 1;
|
||||||
@ -126,7 +126,7 @@ int http_receive_request(sock *client, http_req *req) {
|
|||||||
if (pos1 == NULL) {
|
if (pos1 == NULL) {
|
||||||
print(ERR_STR "Unable to parse header: Invalid version" CLR_STR);
|
print(ERR_STR "Unable to parse header: Invalid version" CLR_STR);
|
||||||
free(buf);
|
free(buf);
|
||||||
return -1;
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
len = pos1 - ptr;
|
len = pos1 - ptr;
|
||||||
|
Reference in New Issue
Block a user