Resolved #325. Add 401 HTTP status code if auth failed. [#CLICKHOUSE-3]

This commit is contained in:
Vitaliy Lyudvichenko 2017-01-17 20:21:48 +03:00 committed by alexey-milovidov
parent e03a9c1611
commit ef6a4e08db
3 changed files with 48 additions and 4 deletions

View File

@ -42,6 +42,7 @@ private:
Poco::Net::HTTPServerResponse & response;
bool add_cors_header;
bool add_authenticate_header = false;
bool compress;
ZlibCompressionMethod compression_method;
int compression_level = Z_DEFAULT_COMPRESSION;
@ -76,6 +77,11 @@ private:
if (add_cors_header)
response.set("Access-Control-Allow-Origin", "*");
if (add_authenticate_header)
{
response.set("WWW-Authenticate", "Basic realm=\"User Visible Realm\"");
}
setResponseDefaultHeaders(response);
std::tie(response_header_ostr, response_body_ostr) = response.beginSend();
@ -215,6 +221,10 @@ public:
send_progress_interval_ms = send_progress_interval_ms_;
}
void addAuthenticateRequest()
{
add_authenticate_header = true;
}
~WriteBufferFromHTTPServerResponse()
{

View File

@ -33,6 +33,10 @@ namespace ErrorCodes
{
extern const int READONLY;
extern const int UNKNOWN_COMPRESSION_METHOD;
extern const int UNKNOWN_USER;
extern const int WRONG_PASSWORD;
extern const int REQUIRED_PASSWORD;
}
@ -270,7 +274,7 @@ void HTTPHandler::processQuery(
}
void HTTPHandler::trySendExceptionToClient(const std::string & s,
void HTTPHandler::trySendExceptionToClient(const std::string & s, int exception_code,
Poco::Net::HTTPServerRequest & request, Poco::Net::HTTPServerResponse & response,
Output & used_output)
{
@ -285,7 +289,18 @@ void HTTPHandler::trySendExceptionToClient(const std::string & s,
request.stream().ignore(std::numeric_limits<std::streamsize>::max());
}
response.setStatusAndReason(Poco::Net::HTTPResponse::HTTP_INTERNAL_SERVER_ERROR);
bool auth_fail = exception_code == ErrorCodes::UNKNOWN_USER || exception_code == ErrorCodes::WRONG_PASSWORD
|| exception_code == ErrorCodes::REQUIRED_PASSWORD;
if (auth_fail)
{
response.setStatusAndReason(Poco::Net::HTTPResponse::HTTP_UNAUTHORIZED);
used_output.out->addAuthenticateRequest();
}
else
{
response.setStatusAndReason(Poco::Net::HTTPResponse::HTTP_INTERNAL_SERVER_ERROR);
}
if (!response.sent() && !used_output.out_maybe_compressed)
{
@ -317,6 +332,24 @@ void HTTPHandler::trySendExceptionToClient(const std::string & s,
}
}
static int getCurrentExceptionCode()
{
try
{
throw;
}
catch (const Exception & e)
{
return e.code();
}
catch (...)
{
}
return 0;
}
void HTTPHandler::handleRequest(Poco::Net::HTTPServerRequest & request, Poco::Net::HTTPServerResponse & response)
{
@ -344,6 +377,7 @@ void HTTPHandler::handleRequest(Poco::Net::HTTPServerRequest & request, Poco::Ne
tryLogCurrentException(log);
std::string exception_message = getCurrentExceptionMessage(with_stacktrace);
int exception_code = getCurrentExceptionCode();
/** If exception is received from remote server, then stack trace is embedded in message.
* If exception is thrown on local server, then stack trace is in separate field.
@ -353,7 +387,7 @@ void HTTPHandler::handleRequest(Poco::Net::HTTPServerRequest & request, Poco::Ne
if (std::string::npos != embedded_stack_trace_pos && !with_stacktrace)
exception_message.resize(embedded_stack_trace_pos);
trySendExceptionToClient(exception_message, request, response, used_output);
trySendExceptionToClient(exception_message, exception_code, request, response, used_output);
}
}

View File

@ -32,7 +32,7 @@ public:
void handleRequest(Poco::Net::HTTPServerRequest & request, Poco::Net::HTTPServerResponse & response) override;
void trySendExceptionToClient(const std::string & s,
void trySendExceptionToClient(const std::string & s, int exception_code,
Poco::Net::HTTPServerRequest & request, Poco::Net::HTTPServerResponse & response,
Output & used_output);