Browse Source

Merge pull request #19292 from Chocobo1/head

Fix response for HTTP HEAD method
adaptive-webui-19844
Chocobo1 1 year ago committed by GitHub
parent
commit
20f4d0c4e3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 42
      src/base/http/connection.cpp
  2. 4
      src/base/http/requestparser.cpp
  3. 1
      src/base/http/requestparser.h
  4. 5
      src/base/http/responsegenerator.cpp

42
src/base/http/connection.cpp

@ -32,7 +32,6 @@
#include <QTcpSocket> #include <QTcpSocket>
#include "base/logger.h"
#include "irequesthandler.h" #include "irequesthandler.h"
#include "requestparser.h" #include "requestparser.h"
#include "responsegenerator.h" #include "responsegenerator.h"
@ -94,8 +93,8 @@ void Connection::read()
const long bufferLimit = RequestParser::MAX_CONTENT_SIZE * 1.1; // some margin for headers const long bufferLimit = RequestParser::MAX_CONTENT_SIZE * 1.1; // some margin for headers
if (m_receivedData.size() > bufferLimit) if (m_receivedData.size() > bufferLimit)
{ {
LogMsg(tr("Http request size exceeds limitation, closing socket. Limit: %1, IP: %2") qWarning("%s", qUtf8Printable(tr("Http request size exceeds limitation, closing socket. Limit: %1, IP: %2")
.arg(bufferLimit).arg(m_socket->peerAddress().toString()), Log::WARNING); .arg(QString::number(bufferLimit), m_socket->peerAddress().toString())));
Response resp(413, u"Payload Too Large"_s); Response resp(413, u"Payload Too Large"_s);
resp.headers[HEADER_CONNECTION] = u"close"_s; resp.headers[HEADER_CONNECTION] = u"close"_s;
@ -106,10 +105,23 @@ void Connection::read()
} }
return; return;
case RequestParser::ParseStatus::BadMethod:
{
qWarning("%s", qUtf8Printable(tr("Bad Http request method, closing socket. IP: %1. Method: \"%2\"")
.arg(m_socket->peerAddress().toString(), result.request.method)));
Response resp(501, u"Not Implemented"_s);
resp.headers[HEADER_CONNECTION] = u"close"_s;
sendResponse(resp);
m_socket->close();
}
return;
case RequestParser::ParseStatus::BadRequest: case RequestParser::ParseStatus::BadRequest:
{ {
LogMsg(tr("Bad Http request, closing socket. IP: %1") qWarning("%s", qUtf8Printable(tr("Bad Http request, closing socket. IP: %1")
.arg(m_socket->peerAddress().toString()), Log::WARNING); .arg(m_socket->peerAddress().toString())));
Response resp(400, u"Bad Request"_s); Response resp(400, u"Bad Request"_s);
resp.headers[HEADER_CONNECTION] = u"close"_s; resp.headers[HEADER_CONNECTION] = u"close"_s;
@ -123,14 +135,30 @@ void Connection::read()
{ {
const Environment env {m_socket->localAddress(), m_socket->localPort(), m_socket->peerAddress(), m_socket->peerPort()}; const Environment env {m_socket->localAddress(), m_socket->localPort(), m_socket->peerAddress(), m_socket->peerPort()};
if (result.request.method == HEADER_REQUEST_METHOD_HEAD)
{
Request getRequest = result.request;
getRequest.method = HEADER_REQUEST_METHOD_GET;
Response resp = m_requestHandler->processRequest(getRequest, env);
resp.headers[HEADER_CONNECTION] = u"keep-alive"_s;
resp.headers[HEADER_CONTENT_LENGTH] = QString::number(resp.content.length());
resp.content.clear();
sendResponse(resp);
}
else
{
Response resp = m_requestHandler->processRequest(result.request, env); Response resp = m_requestHandler->processRequest(result.request, env);
if (acceptsGzipEncoding(result.request.headers[u"accept-encoding"_s])) if (acceptsGzipEncoding(result.request.headers.value(u"accept-encoding"_s)))
resp.headers[HEADER_CONTENT_ENCODING] = u"gzip"_s; resp.headers[HEADER_CONTENT_ENCODING] = u"gzip"_s;
resp.headers[HEADER_CONNECTION] = u"keep-alive"_s; resp.headers[HEADER_CONNECTION] = u"keep-alive"_s;
sendResponse(resp); sendResponse(resp);
}
m_receivedData.remove(0, result.frameSize); m_receivedData.remove(0, result.frameSize);
} }
break; break;

4
src/base/http/requestparser.cpp

@ -103,6 +103,7 @@ RequestParser::ParseResult RequestParser::doParse(const QByteArray &data)
// handle supported methods // handle supported methods
if ((m_request.method == HEADER_REQUEST_METHOD_GET) || (m_request.method == HEADER_REQUEST_METHOD_HEAD)) if ((m_request.method == HEADER_REQUEST_METHOD_GET) || (m_request.method == HEADER_REQUEST_METHOD_HEAD))
return {ParseStatus::OK, m_request, headerLength}; return {ParseStatus::OK, m_request, headerLength};
if (m_request.method == HEADER_REQUEST_METHOD_POST) if (m_request.method == HEADER_REQUEST_METHOD_POST)
{ {
const auto parseContentLength = [this]() -> int const auto parseContentLength = [this]() -> int
@ -146,8 +147,7 @@ RequestParser::ParseResult RequestParser::doParse(const QByteArray &data)
return {ParseStatus::OK, m_request, (headerLength + contentLength)}; return {ParseStatus::OK, m_request, (headerLength + contentLength)};
} }
qWarning() << Q_FUNC_INFO << "unsupported request method: " << m_request.method; return {ParseStatus::BadMethod, m_request, 0};
return {ParseStatus::BadRequest, Request(), 0}; // TODO: SHOULD respond "501 Not Implemented"
} }
bool RequestParser::parseStartLines(const QStringView data) bool RequestParser::parseStartLines(const QStringView data)

1
src/base/http/requestparser.h

@ -41,6 +41,7 @@ namespace Http
{ {
OK, OK,
Incomplete, Incomplete,
BadMethod,
BadRequest BadRequest
}; };

5
src/base/http/responsegenerator.cpp

@ -38,8 +38,9 @@ QByteArray Http::toByteArray(Response response)
{ {
compressContent(response); compressContent(response);
response.headers[HEADER_CONTENT_LENGTH] = QString::number(response.content.length());
response.headers[HEADER_DATE] = httpDate(); response.headers[HEADER_DATE] = httpDate();
if (QString &value = response.headers[HEADER_CONTENT_LENGTH]; value.isEmpty())
value = QString::number(response.content.length());
QByteArray buf; QByteArray buf;
buf.reserve(1024 + response.content.length()); buf.reserve(1024 + response.content.length());
@ -63,7 +64,7 @@ QByteArray Http::toByteArray(Response response)
// the first empty line // the first empty line
buf += CRLF; buf += CRLF;
// message body // TODO: support HEAD request // message body
buf += response.content; buf += response.content;
return buf; return buf;

Loading…
Cancel
Save