Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ if (NOT TH_DISABLE_TESTS)
src/th_tcp_conn_test.c
src/th_router_test.c
src/th_allocator_test.c
src/th_request_test.c
src/th_request_parser_test.c
src/th_cookie_parser_test.c
src/th_multipart_parser_test.c
Expand Down
1 change: 1 addition & 0 deletions src/th_http.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ th_http_handle_request_and_write_response(th_http* http)
th_response* response = &http->response;
th_http_prehandle_request(http);
th_err err = th_http_error(th_http_handle_route(http->router, &http->request, &http->response));
th_response_set_code(response, TH_ERR_CODE(err));
switch (th_http_code_get_type(TH_ERR_CODE(err))) {
case TH_HTTP_CODE_TYPE_INFORMATIONAL:
if (request->version == 0) {
Expand Down
61 changes: 61 additions & 0 deletions src/th_http_test.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "th_conn_tracker.h"
#include "th_fmt.h"
#include "th_http.h"
#include "th_system_error.h"
#include "th_test.h"
#include "th_utility.h"

Expand Down Expand Up @@ -175,6 +176,24 @@ th_test_handler(void* user_data, const th_request* req, th_response* resp)
return TH_ERR_OK;
}

static th_err
th_test_informational_handler(void* user_data, const th_request* req, th_response* resp)
{
(void)user_data;
(void)req;
(void)resp;
return TH_ERR_HTTP(100); // Continue
}

static th_err
th_test_system_error_handler(void* user_data, const th_request* req, th_response* resp)
{
(void)user_data;
(void)req;
(void)resp;
return TH_ERR_SYSTEM(TH_ENOENT);
}

TH_TEST_BEGIN(http)
{
th_conn_tracker tracker;
Expand All @@ -183,6 +202,8 @@ TH_TEST_BEGIN(http)
th_router_init(&router, th_default_allocator_get());
TH_EXPECT(th_router_add_route(&router, TH_METHOD_GET, TH_STR("/test"), th_test_handler, NULL) == TH_ERR_OK);
TH_EXPECT(th_router_add_route(&router, TH_METHOD_POST, TH_STR("/test"), th_test_handler, NULL) == TH_ERR_OK);
TH_EXPECT(th_router_add_route(&router, TH_METHOD_GET, TH_STR("/informational"), th_test_informational_handler, NULL) == TH_ERR_OK);
TH_EXPECT(th_router_add_route(&router, TH_METHOD_GET, TH_STR("/system-error"), th_test_system_error_handler, NULL) == TH_ERR_OK);
th_http_upgrader upgrader;
th_http_upgrader_init(&upgrader, &tracker, &router, NULL, NULL, th_default_allocator_get());
th_fake_conn conn;
Expand Down Expand Up @@ -408,6 +429,46 @@ TH_TEST_BEGIN(http)
TH_EXPECT(conn.destroyed);
}
TH_TEST_CASE_END
TH_TEST_CASE_BEGIN(http_writes_informational_response_for_1_1)
{
th_fake_conn_set_request(&conn, TH_STR("GET /informational HTTP/1.1\r\nHost: example.com\r\nConnection: close\r\n\r\n"));

th_conn_upgrader_upgrade(&upgrader.base, &conn.base);
while (!conn.destroyed && conn.callback != NULL)
th_fake_conn_run(&conn);

TH_EXPECT(th_buf_starts_with(conn.written, conn.written_len, "HTTP/1.1 100 "));
TH_EXPECT(conn.destroyed);
}
TH_TEST_CASE_END
TH_TEST_CASE_BEGIN(http_rejects_informational_response_for_1_0)
{
// HTTP/1.0 clients can't handle 1xx responses, so this is
// downgraded to a 400 Bad Request instead.
th_fake_conn_set_request(&conn, TH_STR("GET /informational HTTP/1.0\r\nHost: example.com\r\nConnection: close\r\n\r\n"));

th_conn_upgrader_upgrade(&upgrader.base, &conn.base);
while (!conn.destroyed && conn.callback != NULL)
th_fake_conn_run(&conn);

TH_EXPECT(th_buf_starts_with(conn.written, conn.written_len, "HTTP/1.1 400 Bad Request\r\n"));
TH_EXPECT(conn.destroyed);
}
TH_TEST_CASE_END
TH_TEST_CASE_BEGIN(http_maps_unrelated_system_error_to_404)
{
// A handler returning a plain system error (not an HTTP error) gets
// translated by th_http_error, e.g. ENOENT maps to 404.
th_fake_conn_set_request(&conn, TH_STR("GET /system-error HTTP/1.1\r\nHost: example.com\r\nConnection: close\r\n\r\n"));

th_conn_upgrader_upgrade(&upgrader.base, &conn.base);
while (!conn.destroyed && conn.callback != NULL)
th_fake_conn_run(&conn);

TH_EXPECT(th_buf_starts_with(conn.written, conn.written_len, "HTTP/1.1 404 Not Found\r\n"));
TH_EXPECT(conn.destroyed);
}
TH_TEST_CASE_END

th_router_deinit(&router);
th_conn_tracker_deinit(&tracker);
Expand Down
13 changes: 6 additions & 7 deletions src/th_request.c
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ th_find_header(const th_request* req, const char* key)
{
size_t num = th_hstr_vec_size(&req->headers);
for (size_t i = 0; i < num; i++) {
if (strncmp(key, th_string_data(&req->headers.data[i].key), th_string_len(&req->headers.data[i].key)) == 0) {
if (strcmp(key, th_string_data(&req->headers.data[i].key)) == 0) {
return th_string_data(&req->headers.data[i].value);
}
}
Expand All @@ -376,7 +376,7 @@ th_find_cookie(const th_request* req, const char* key)
{
size_t num = th_hstr_vec_size(&req->cookies);
for (size_t i = 0; i < num; i++) {
if (strncmp(key, th_string_data(&req->cookies.data[i].key), th_string_len(&req->cookies.data[i].key)) == 0) {
if (strcmp(key, th_string_data(&req->cookies.data[i].key)) == 0) {
return th_string_data(&req->cookies.data[i].value);
}
}
Expand All @@ -398,7 +398,7 @@ th_find_queryvar(const th_request* req, const char* key)
{
size_t num = th_hstr_vec_size(&req->queryvars);
for (size_t i = 0; i < num; i++) {
if (strncmp(key, th_string_data(&req->queryvars.data[i].key), th_string_len(&req->queryvars.data[i].key)) == 0) {
if (strcmp(key, th_string_data(&req->queryvars.data[i].key)) == 0) {
return th_string_data(&req->queryvars.data[i].value);
}
}
Expand All @@ -420,7 +420,7 @@ th_find_formvar(const th_request* req, const char* key)
{
size_t num = th_hstr_vec_size(&req->formvars);
for (size_t i = 0; i < num; i++) {
if (strncmp(key, th_string_data(&req->formvars.data[i].key), th_string_len(&req->formvars.data[i].key)) == 0) {
if (strcmp(key, th_string_data(&req->formvars.data[i].key)) == 0) {
return th_string_data(&req->formvars.data[i].value);
}
}
Expand All @@ -442,7 +442,7 @@ th_find_pathvar(const th_request* req, const char* key)
{
size_t num = th_hstr_vec_size(&req->pathvars);
for (size_t i = 0; i < num; i++) {
if (strncmp(key, th_string_data(&req->pathvars.data[i].key), th_string_len(&req->pathvars.data[i].key)) == 0) {
if (strcmp(key, th_string_data(&req->pathvars.data[i].key)) == 0) {
return th_string_data(&req->pathvars.data[i].value);
}
}
Expand All @@ -464,8 +464,7 @@ th_find_part(const th_request* req, const char* name)
{
size_t num = th_part_vec_size(&req->parts);
for (size_t i = 0; i < num; i++) {
if (strncmp(name, th_string_data(&req->parts.data[i].name), th_string_len(&req->parts.data[i].name))
== 0) {
if (strcmp(name, th_string_data(&req->parts.data[i].name)) == 0) {
return th_part_vec_cat(&req->parts, i);
}
}
Expand Down
Loading
Loading