blob: aa898a98dc48da974762c3ffa4b7246c3d6b6e87 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
// Copyright (C) 2025 David M. Cotter
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#pragma once
#include <QByteArray>
#include <QMap>
#include <QObject>
#include <QString>
#include <QStringList>
namespace Mcp::Internal {
/**
* @brief HTTP/1.1 Request Parser
*
* Parses HTTP requests from raw TCP data and extracts:
* - HTTP method (GET, POST, etc.)
* - Request URI
* - HTTP version
* - Headers
* - Body content
*
* Designed to work with the existing TCP MCP server to provide
* HTTP compatibility without requiring the HttpServer module.
*/
class HttpParser : public QObject
{
Q_OBJECT
public:
/**
* @brief HTTP request structure
*/
struct HttpRequest
{
QString method; ///< HTTP method (GET, POST, etc.)
QString uri; ///< Request URI
QString version; ///< HTTP version (1.1, etc.)
QMap<QString, QString> headers; ///< HTTP headers (case-insensitive keys)
QByteArray body; ///< Request body content
bool isValid; ///< Whether the request is valid
bool needMoreData; ///< Whether the request has all data available
QString errorMessage; ///< Error message if parsing failed
};
explicit HttpParser(QObject *parent = nullptr);
/**
* @brief Parse HTTP request from raw TCP data
* @param data Raw TCP data received from client
* @return Parsed HTTP request structure
*/
HttpRequest parseRequest(const QByteArray &data);
/**
* @brief Check if data looks like an HTTP request
* @param data Raw data to check
* @return true if data appears to be HTTP
*/
static bool isHttpRequest(const QByteArray &data);
private:
/**
* @brief Parse the HTTP request line (method URI version)
* @param requestLine First line of HTTP request
* @param request Output request structure
* @return true if parsing succeeded
*/
bool parseRequestLine(const QString &requestLine, HttpRequest &request);
/**
* @brief Parse HTTP headers
* @param headerLines List of header lines
* @param request Output request structure
*/
void parseHeaders(const QStringList &headerLines, HttpRequest &request);
/**
* @brief Normalize header name (lowercase for case-insensitive lookup)
* @param headerName Header name to normalize
* @return Normalized header name
*/
static QString normalizeHeaderName(const QString &headerName);
/**
* @brief Extract body content from HTTP data
* @param data Complete HTTP data
* @param headerEnd Position where headers end
* @param contentLength Content-Length header value
* @return Body content
*/
QByteArray extractBody(const QByteArray &data, int headerEnd, int contentLength);
/**
* @brief Split HTTP data into lines
* @param data HTTP data to split
* @return List of lines
*/
QStringList splitHttpLines(const QByteArray &data);
};
} // namespace Mcp::Internal
|