Skip to content
Snippets Groups Projects

daemon/http: HTTP response codes

Merged Oto Šťáva requested to merge doh2-status-codes into master
All threads resolved!
Files
2
+ 28
10
@@ -58,6 +58,7 @@ enum http_status {
HTTP_STATUS_NOT_FOUND = 404,
HTTP_STATUS_PAYLOAD_TOO_LARGE = 413,
HTTP_STATUS_REQUEST_HEADER_FIELDS_TOO_LARGE = 431,
HTTP_STATUS_NOT_IMPLEMENTED = 501,
};
struct http_data {
@@ -201,7 +202,7 @@ static int check_uri(const char* uri_path)
}
if (ret) /* no endpoint found */
return -1;
return kr_error(ENOENT);
/* FIXME This also passes for GET when no variables are provided.
* Fixing it doesn't seem straightforward, since :method may not be
@@ -367,9 +368,8 @@ static int header_callback(nghttp2_session *h2, const nghttp2_frame *frame,
kr_log_debug(DOH,
"[%p] stream %d: header too large (%zu B), refused\n",
(void *)h2, stream_id, valuelen);
http_send_response(ctx, stream_id, NULL,
return http_send_response(ctx, stream_id, NULL,
HTTP_STATUS_REQUEST_HEADER_FIELDS_TOO_LARGE);
return 0;
}
/* Copy the user-provided header name to keep the original case. */
@@ -387,9 +387,11 @@ static int header_callback(nghttp2_session *h2, const nghttp2_frame *frame,
}
if (!strcasecmp(":path", (const char *)name)) {
if (check_uri((const char *)value) < 0) {
http_send_response(ctx, stream_id, NULL, HTTP_STATUS_NOT_FOUND);
return 0;
int uri_result = check_uri((const char *)value);
if (uri_result == kr_error(ENOENT)) {
return http_send_response(ctx, stream_id, NULL, HTTP_STATUS_NOT_FOUND);
} else if (uri_result < 0) {
return http_send_response(ctx, stream_id, NULL, HTTP_STATUS_BAD_REQUEST);
}
kr_assert(ctx->uri_path == NULL);
@@ -405,8 +407,11 @@ static int header_callback(nghttp2_session *h2, const nghttp2_frame *frame,
ctx->current_method = HTTP_METHOD_GET;
} else if (!strcasecmp("post", (const char *)value)) {
ctx->current_method = HTTP_METHOD_POST;
} else if (!strcasecmp("head", (const char *)value)) {
ctx->current_method = HTTP_METHOD_HEAD;
} else {
ctx->current_method = HTTP_METHOD_NONE;
return http_send_response(ctx, stream_id, NULL, HTTP_STATUS_NOT_IMPLEMENTED);
}
}
@@ -491,7 +496,9 @@ static int submit_to_wirebuffer(struct http_ctx *ctx, int32_t stream_id)
len = ctx->buf_pos - sizeof(uint16_t);
if (len <= 0 || len > KNOT_WIRE_MAX_PKTSIZE) {
kr_log_debug(DOH, "[%p] invalid dnsmsg size: %zd B\n", (void *)ctx->h2, len);
http_send_response(ctx, stream_id, NULL, HTTP_STATUS_PAYLOAD_TOO_LARGE);
http_send_response(ctx, stream_id, NULL, (len <= 0)
? HTTP_STATUS_BAD_REQUEST
: HTTP_STATUS_PAYLOAD_TOO_LARGE);
ret = -1;
goto cleanup;
}
@@ -523,10 +530,10 @@ static int on_frame_recv_callback(nghttp2_session *h2, const nghttp2_frame *fram
return NGHTTP2_ERR_CALLBACK_FAILURE;
if ((frame->hd.flags & NGHTTP2_FLAG_END_STREAM) && ctx->incomplete_stream == stream_id) {
if (ctx->current_method == HTTP_METHOD_GET) {
if (ctx->current_method == HTTP_METHOD_GET || ctx->current_method == HTTP_METHOD_HEAD) {
if (process_uri_path(ctx, ctx->uri_path, stream_id) < 0) {
http_send_response(ctx, stream_id, NULL, HTTP_STATUS_BAD_REQUEST);
return 0; /* End processing - don't submit to wirebuffer. */
/* End processing - don't submit to wirebuffer. */
return http_send_response(ctx, stream_id, NULL, HTTP_STATUS_BAD_REQUEST);
}
}
@@ -735,6 +742,13 @@ static int http_send_response(struct http_ctx *ctx, int32_t stream_id,
auto_free char *size = NULL;
auto_free char *max_age = NULL;
if (ctx->current_method == HTTP_METHOD_HEAD && prov) {
/* HEAD method is the same as GET but only returns headers,
* so let's clean up the data here as we don't need it. */
free(prov->source.ptr);
prov = NULL;
}
if (prov) {
data = (struct http_data*)prov->source.ptr;
const char *directive_max_age = "max-age=";
@@ -783,6 +797,10 @@ static int http_send_response(struct http_ctx *ctx, int32_t stream_id,
return 0;
}
if (status != HTTP_STATUS_OK) {
nghttp2_submit_rst_stream(h2, NGHTTP2_FLAG_NONE, stream_id, NGHTTP2_NO_ERROR);
}
return 0;
}
Loading