MCPcopy Create free account
hub / github.com/ClickHouse/ClickHouse / HTTPServerRequest

Method HTTPServerRequest

src/Server/HTTP/HTTPServerRequest.cpp:30–112  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

28namespace DB
29{
30HTTPServerRequest::HTTPServerRequest(HTTPContextPtr context, HTTPServerResponse & response, Poco::Net::HTTPServerSession & session, const ProfileEvents::Event & read_event)
31 : max_uri_size(context->getMaxUriSize())
32 , max_fields_number(context->getMaxFields())
33 , max_field_name_size(context->getMaxFieldNameSize())
34 , max_field_value_size(context->getMaxFieldValueSize())
35 , max_request_header_size(context->getMaxRequestHeaderSize())
36{
37 response.attachRequest(this);
38
39 /// Now that we know socket is still connected, obtain addresses
40 client_address = session.clientAddress();
41 server_address = session.serverAddress();
42 secure = session.socket().secure();
43
44 auto receive_timeout = context->getReceiveTimeout();
45 auto send_timeout = context->getSendTimeout();
46 auto headers_read_timeout = context->getHeadersReadTimeout();
47
48 /// Use the smaller of headers_read_timeout and receive_timeout during header parsing
49 /// to enforce a total deadline on the entire handshake phase.
50 auto effective_timeout = (headers_read_timeout > Poco::Timespan(0) &&
51 (receive_timeout <= Poco::Timespan(0) || headers_read_timeout < receive_timeout))
52 ? headers_read_timeout : receive_timeout;
53
54 session.socket().setReceiveTimeout(effective_timeout);
55 session.socket().setSendTimeout(send_timeout);
56
57 auto socket_in = std::make_unique<ReadBufferFromPocoSocket>(session.socket(), read_event);
58 socket = session.socket().impl();
59
60 /// Wrap the socket buffer with a deadline check if configured.
61 /// The deadline is enforced in DeadlineReadBuffer::nextImpl on every buffer refill,
62 /// which protects all parsing (request line, URI, headers) automatically.
63 if (headers_read_timeout > Poco::Timespan(0))
64 {
65 auto deadline = std::chrono::steady_clock::now()
66 + std::chrono::microseconds(headers_read_timeout.totalMicroseconds());
67 DeadlineReadBuffer deadline_in(*socket_in, deadline);
68 readRequest(deadline_in); /// Try parse according to RFC7230
69 }
70 else
71 {
72 readRequest(*socket_in); /// Try parse according to RFC7230
73 }
74
75 /// Restore the original receive timeout for body reads.
76 session.socket().setReceiveTimeout(receive_timeout);
77
78 /// Build the body stream from the underlying socket buffer (not the deadline wrapper).
79 auto in = std::move(socket_in);
80
81 /// If a client crashes, most systems will gracefully terminate the connection with FIN just like it's done on close().
82 /// So we will get 0 from recv(...) and will not be able to understand that something went wrong (well, we probably
83 /// will get RST later on attempt to write to the socket that closed on the other side, but it will happen when the query is finished).
84 /// If we are extremely unlucky and data format is TSV, for example, then we may stop parsing exactly between rows
85 /// and decide that it's EOF (but it is not). It may break deduplication, because clients cannot control it
86 /// and retry with exactly the same (incomplete) set of rows.
87 /// That's why we have to check body size if it's provided.

Callers

nothing calls this directly

Calls 15

clientAddressMethod · 0.80
serverAddressMethod · 0.80
TimespanClass · 0.50
nowFunction · 0.50
getMethodFunction · 0.50
startsWithFunction · 0.50
getLoggerFunction · 0.50
getMaxUriSizeMethod · 0.45
getMaxFieldsMethod · 0.45
getMaxFieldNameSizeMethod · 0.45
getMaxFieldValueSizeMethod · 0.45

Tested by

no test coverage detected