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

Method processQuery

src/Server/HTTPHandler.cpp:185–654  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

183
184
185void HTTPHandler::processQuery(
186 HTTPServerRequest & request,
187 HTMLForm & params,
188 HTTPServerResponse & response,
189 Output & used_output,
190 QueryScope & query_scope,
191 const ProfileEvents::Event & write_event)
192{
193 using namespace Poco::Net;
194
195 LOG_TRACE(log, "Request URI: {}", request.getURI());
196
197 if (!authenticateUser(request, params, response))
198 return; // '401 Unauthorized' response with 'Negotiate' has been sent at this point.
199
200 /// The user could specify session identifier and session timeout.
201 /// It allows to modify settings, create temporary tables and reuse them in subsequent requests.
202
203 String session_id;
204 std::chrono::steady_clock::duration session_timeout;
205 bool session_is_set = params.has("session_id");
206 const auto & config = server.config();
207
208 /// Close http session (if any) after processing the request
209 bool close_session = false;
210 if (params.getParsed<bool>("close_session", false) && server.config().getBool("enable_http_close_session", true))
211 close_session = true;
212
213 if (session_is_set)
214 {
215 session_id = params.get("session_id");
216 if (session_id.empty())
217 throw Exception(ErrorCodes::SESSION_ID_EMPTY, "Session id query parameter was provided, but it was empty");
218 session_timeout = parseSessionTimeout(config, params);
219 std::string session_check = params.get("session_check", "");
220 session->makeSessionContext(session_id, session_timeout, session_check == "1");
221 }
222 else
223 {
224 session_id = "";
225 /// We should create it even if we don't have a session_id
226 session->makeSessionContext();
227 }
228
229 /// We need to have both releasing/closing a session here and below. The problem with having it only as a SCOPE_EXIT
230 /// is that it will be invoked after finalizing the buffer in the end of processQuery, and that technically means that
231 /// the client has received all the data, but the session is not released yet. And it can (and sometimes does) happen
232 /// that we'll try to acquire the same session in another request before releasing the session here, and the session for
233 /// the following request will be technically locked, while it shouldn't be.
234 /// Also, SCOPE_EXIT is still needed to release a session in case of any exception. If the exception occurs at some point
235 /// after releasing the session below, this whole call will be no-op (due to named_session being nullptr already inside a session).
236 SCOPE_EXIT_SAFE({ releaseOrCloseSession(session_id, close_session); });
237
238 auto context = session->makeQueryContext();
239
240 auto roles = params.getAll("role");
241 if (!roles.empty())
242 context->setCurrentRoles(roles);

Callers

nothing calls this directly

Calls 15

erase_ifFunction · 0.85
isControlASCIIFunction · 0.85
copyDataFunction · 0.85
wrapReadBufferPointerFunction · 0.85
chooseCompressionMethodFunction · 0.85
prevFunction · 0.85
applyHTTPResponseHeadersFunction · 0.85
drainRequestIfNeededFunction · 0.85

Tested by

no test coverage detected