Commit cce5ed38 authored by Siebers, Michael's avatar Siebers, Michael
Browse files

endpoints requiring body reply 408 on timeout

parent a75df315
......@@ -82,6 +82,24 @@ http:map_exception_to_http_status_hook(length_required,
message:"Header 'Content-Length' missing."})),
string_codes(Message, MessageBytes).
/* request_timeout => 408 Request Timeout
*
* Client send a POST request which requires a body. However, reading the body
* timed out. Most probable cause is an erroneous Content-Length header,
* promising more bytes than will actually be transmitted. Depending on the size
* of the body also a client's slow connection speed could be the cause.
*/
http:map_exception_to_http_status_hook(request_timeout,
bytes('application/json', MessageBytes),
[connection(close), status(Code)], []) :-
http_header:status_number_fact(request_timeout, Code),
with_output_to(codes(MessageBytes),
json_write_dict(current_output,
_{
code: Code,
message: "Client took too long to send request body. Perhaps the Content-Length header is wrong."
})).
/* parse_error(Reason, Location) => bad request
......
......@@ -20,6 +20,7 @@
% @throws invalid_header_value(content_length, Value) if a Content-Length header
% has been sent but the given value Value is invalid (no nonnegative
% integer).
% @throws `request_timeout` if reading the body timed out
read_json_body(Request, Payload) :-
( memberchk(content_length(Len), Request)
-> ( integer(Len),
......@@ -29,16 +30,29 @@ read_json_body(Request, Payload) :-
)
; throw(length_required)
),
catch(http_read_json_dict(Request, Payload, [value_string_as(atom)]),
error(syntax_error(json(Details)),
stream(_S, Line, LinePos, _CharNo)),
throw(parse_error(illegal_json_syntax(Details),
stream_position(Line, LinePos)))
)
read_json_body_(Request, Payload)
-> true
; throw(empty_request_body).
read_json_body_(Request, Payload) :-
catch(http_read_json_dict(Request, Payload, [value_string_as(atom)]),
Error, true),
( var(Error)
-> true
; Error = error(syntax_error(json(Details)),
stream(_S, Line, LinePos, _CharNo))
-> throw(parse_error(illegal_json_syntax(Details),
stream_position(Line, LinePos)))
; Error = error(timeout_error(read, _Stream),_)
-> throw(request_timeout)
; api_error(implementation_error,[
error(Error),
source(http_read_json_dict/3)
])
).
%! purge_input_stream(+Request) is det.
%
% Purge the content of the request body. Only possible if a
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment