| 923 | |
| 924 | |
| 925 | void HTTPHandler::handleRequest(HTTPServerRequest & request, HTTPServerResponse & response) |
| 926 | { |
| 927 | setThreadName("HTTPHandler"); |
| 928 | ThreadStatus thread_status; |
| 929 | |
| 930 | SCOPE_EXIT({ |
| 931 | // If there is no request_credentials instance waiting for the next round, then the request is processed, |
| 932 | // so no need to preserve request_context either. |
| 933 | // Needs to be performed with respect to the other destructors in the scope though. |
| 934 | if (!request_credentials) |
| 935 | request_context.reset(); |
| 936 | }); |
| 937 | |
| 938 | if (!request_context) |
| 939 | { |
| 940 | // Context should be initialized before anything, for correct memory accounting. |
| 941 | request_context = Context::createCopy(server.context()); |
| 942 | request_credentials.reset(); |
| 943 | } |
| 944 | |
| 945 | /// Cannot be set here, since query_id is unknown. |
| 946 | std::optional<CurrentThread::QueryScope> query_scope; |
| 947 | Output used_output; |
| 948 | |
| 949 | /// In case of exception, send stack trace to client. |
| 950 | bool with_stacktrace = false; |
| 951 | |
| 952 | try |
| 953 | { |
| 954 | response.setContentType("text/plain; charset=UTF-8"); |
| 955 | response.set("X-ClickHouse-Server-Display-Name", server_display_name); |
| 956 | /// For keep-alive to work. |
| 957 | if (request.getVersion() == HTTPServerRequest::HTTP_1_1) |
| 958 | response.setChunkedTransferEncoding(true); |
| 959 | |
| 960 | HTMLForm params(request_context->getSettingsRef(), request); |
| 961 | with_stacktrace = params.getParsed<bool>("stacktrace", false); |
| 962 | |
| 963 | /// FIXME: maybe this check is already unnecessary. |
| 964 | /// Workaround. Poco does not detect 411 Length Required case. |
| 965 | if (request.getMethod() == HTTPRequest::HTTP_POST && !request.getChunkedTransferEncoding() && !request.hasContentLength()) |
| 966 | { |
| 967 | throw Exception( |
| 968 | "The Transfer-Encoding is not chunked and there is no Content-Length header for POST request", |
| 969 | ErrorCodes::HTTP_LENGTH_REQUIRED); |
| 970 | } |
| 971 | |
| 972 | processQuery(request_context, request, params, response, used_output, query_scope); |
| 973 | LOG_DEBUG(log, (request_credentials ? "Authentication in progress..." : "Done processing query")); |
| 974 | } |
| 975 | catch (...) |
| 976 | { |
| 977 | SCOPE_EXIT({ |
| 978 | request_credentials.reset(); // ...so that the next requests on the connection have to always start afresh in case of exceptions. |
| 979 | }); |
| 980 | |
| 981 | tryLogCurrentException(log); |
| 982 |
no test coverage detected