MythTV master
mythhttptypes.h
Go to the documentation of this file.
1#ifndef MYTHHTTPTYPES_H
2#define MYTHHTTPTYPES_H
3
4// Std
5#include <array>
6#include <deque>
7#include <chrono>
8
9// Qt
10#include <QMap>
11#include <QFile>
12#include <QString>
13#include <QDateTime>
14#include <QStringList>
15#include <QHostAddress>
16#ifndef QT_NO_OPENSSL
17#include <QSslConfiguration>
18#endif
19#include <QTimeZone>
20
21// MythTV
24
25#define HTTP_SOCKET_TIMEOUT_MS 10000 // 10 seconds
26#define HTTP_SERVICES_DIR QString("/services/")
27
28class MythHTTPData;
29class MythHTTPFile;
30class MythHTTPRequest;
32class MythHTTPService;
33
34using HTTPMap = QMultiMap<QString,QString>;
36using HTTPHeaders = std::shared_ptr<HTTPMap>;
37using HTTPData = std::shared_ptr<MythHTTPData>;
38using HTTPContents = std::vector<HTTPData>;
39using HTTPRequest2 = std::shared_ptr<MythHTTPRequest>; // HTTPRequest conflicts with existing class
40using HTTPResponse = std::shared_ptr<MythHTTPResponse>;
41using HTTPFile = std::shared_ptr<MythHTTPFile>;
42using HTTPVariant = std::variant<std::monostate, HTTPData, HTTPFile>;
43using HTTPQueue = std::deque<HTTPVariant>;
44using HTTPRange = std::pair<uint64_t,uint64_t>;
45using HTTPRanges = std::vector<HTTPRange>;
46using HTTPFunction = std::function<HTTPResponse(HTTPRequest2)>;
47using HTTPHandler = std::pair<QString,HTTPFunction>;
48using HTTPHandlers = std::vector<HTTPHandler>;
49using HTTPMulti = std::pair<HTTPData,HTTPData>;
50using HTTPRegisterTypes = std::function<void()>;
51using HTTPServicePtr = std::shared_ptr<MythHTTPService>;
52using HTTPServicePtrs = std::vector<HTTPServicePtr>;
53using HTTPServiceCtor = std::function<HTTPServicePtr()>;
54using HTTPService = std::pair<QString,HTTPServiceCtor>;
55using HTTPServices = std::vector<HTTPService>;
56
60
62{
63 public:
64 quint16 m_port { 0 };
65 quint16 m_port_2 { 0 };
66 quint16 m_sslPort { 0 };
67 QString m_rootDir;
68 QString m_serverName;
69 std::chrono::milliseconds m_timeout { HTTP_SOCKET_TIMEOUT_MS };
70 QString m_language;
71 QStringList m_hosts;
72 QStringList m_allowedOrigins;
73 QStringList m_filePaths;
77#ifndef QT_NO_OPENSSL
78 QSslConfiguration m_sslConfig;
79#endif
80};
81
83{
88};
89
91{
92 HTTPUnknown = 0x0000,
93 HTTPHead = 0x0001,
94 HTTPGet = 0x0002,
95 HTTPPost = 0x0004,
96 HTTPPut = 0x0008,
97 HTTPDelete = 0x0010,
98 HTTPOptions = 0x0020
99};
100
101// POST is needed here because all services are invoked with POST when using
102// SOAP, regardless of whether they require POST or not
103#define HTTP_DEFAULT_ALLOWED (HTTPHead | HTTPGet | HTTPOptions | HTTPPost)
104
106{
108 HTTPOK = 200,
127
129{
134
136{
141
143{
145 HTTPNoCache = 0x0001,
146 HTTPETag = 0x0002,
150 HTTPLongLife = 0x0400
152
153static QString s_multipartBoundary = "mYtHtVxXxXxX";
154static QString s_defaultHTTPPage =
155"<!DOCTYPE html>"
156"<HTML>"
157 "<HEAD>"
158 "<TITLE>%1</TITLE>"
159 "<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=ISO-8859-1\">"
160 "</HEAD>"
161 "<BODY><H1>%1</H1></BODY>"
162"</HTML>";
163
165{
166 public:
167 explicit MythHTTPContent(QString Name): m_fileName(std::move(Name)) {}
168 QString m_fileName;
170 int64_t m_partialSize { 0 };
173 int64_t m_written { 0 };
176 QDateTime m_lastModified;
177 QByteArray m_etag;
179};
180
182{
183 public:
184 static QString VersionToString(MythHTTPVersion Version)
185 {
186 switch (Version)
187 {
188 case HTTPOneDotOne: return QStringLiteral("HTTP/1.1");
189 case HTTPOneDotZero: return QStringLiteral("HTTP/1.0");
190 case HTTPZeroDotNine: return QStringLiteral("HTTP/0.9");
191 case HTTPUnknownVersion: break;
192 }
193 return QStringLiteral("Error");
194 }
195
196 static MythHTTPVersion VersionFromString(const QString& Version)
197 {
198 if (Version.startsWith(QStringLiteral("HTTP")))
199 {
200 if (Version.endsWith(QStringLiteral("1.1"))) return HTTPOneDotOne;
201 if (Version.endsWith(QStringLiteral("1.0"))) return HTTPOneDotZero;
202 if (Version.endsWith(QStringLiteral("0.9"))) return HTTPZeroDotNine;
203 }
204 return HTTPUnknownVersion;
205 }
206
208 {
209 switch (Type)
210 {
211 case HTTPHead: return QStringLiteral("HEAD");
212 case HTTPGet: return QStringLiteral("GET");
213 case HTTPPost: return QStringLiteral("POST");
214 case HTTPPut: return QStringLiteral("PUT");
215 case HTTPDelete: return QStringLiteral("DELETE");
216 case HTTPOptions: return QStringLiteral("OPTIONS");
217 case HTTPUnknown: break;
218 }
219 return QStringLiteral("Error");
220 }
221
222 static MythHTTPRequestType RequestFromString(const QString& Type)
223 {
224 if (Type == QStringLiteral("GET")) return HTTPGet;
225 if (Type == QStringLiteral("HEAD")) return HTTPHead;
226 if (Type == QStringLiteral("POST")) return HTTPPost;
227 if (Type == QStringLiteral("PUT")) return HTTPPut;
228 if (Type == QStringLiteral("OPTIONS")) return HTTPOptions;
229 if (Type == QStringLiteral("DELETE")) return HTTPDelete;
230 return HTTPUnknown;
231 }
232
233 static QString AllowedRequestsToString(int Allowed)
234 {
235 QStringList result;
236 if (Allowed & HTTPHead) result << QStringLiteral("HEAD");
237 if (Allowed & HTTPGet) result << QStringLiteral("GET");
238 if (Allowed & HTTPPost) result << QStringLiteral("POST");
239 if (Allowed & HTTPPut) result << QStringLiteral("PUT");
240 if (Allowed & HTTPDelete) result << QStringLiteral("DELETE");
241 if (Allowed & HTTPOptions) result << QStringLiteral("OPTIONS");
242 return result.join(QStringLiteral(", "));
243 }
244
245 static int RequestsFromString(const QString& Requests)
246 {
247 int result = HTTPUnknown;
248 if (Requests.contains("HEAD", Qt::CaseInsensitive)) result |= HTTPHead;
249 if (Requests.contains("GET", Qt::CaseInsensitive)) result |= HTTPGet;
250 if (Requests.contains("POST", Qt::CaseInsensitive)) result |= HTTPPost;
251 if (Requests.contains("PUT", Qt::CaseInsensitive)) result |= HTTPPut;
252 if (Requests.contains("DELETE", Qt::CaseInsensitive)) result |= HTTPDelete;
253 if (Requests.contains("OPTIONS", Qt::CaseInsensitive)) result |= HTTPOptions;
254 return result;
255 }
256
257 static QString StatusToString(MythHTTPStatus Status)
258 {
259 switch (Status)
260 {
261 case HTTPSwitchingProtocols: return QStringLiteral("101 Switching Protocols");
262 case HTTPOK: return QStringLiteral("200 OK");
263 case HTTPAccepted: return QStringLiteral("202 Accepted");
264 case HTTPPartialContent: return QStringLiteral("206 Partial Content");
265 case HTTPMovedPermanently: return QStringLiteral("301 Moved Permanently");
266 case HTTPNotModified: return QStringLiteral("304 Not Modified");
267 case HTTPBadRequest: return QStringLiteral("400 Bad Request");
268 case HTTPUnauthorized: return QStringLiteral("401 Unauthorized");
269 case HTTPForbidden: return QStringLiteral("403 Forbidden");
270 case HTTPNotFound: return QStringLiteral("404 Not Found");
271 case HTTPMethodNotAllowed: return QStringLiteral("405 Method Not Allowed");
272 case HTTPRequestTimeout: return QStringLiteral("408 Request Timeout");
273 case HTTPRequestedRangeNotSatisfiable: return QStringLiteral("416 Requested Range Not Satisfiable");
274 case HTTPTooManyRequests: return QStringLiteral("429 Too Many Requests");
275 case HTTPInternalServerError: return QStringLiteral("500 Internal Server Error");
276 case HTTPNotImplemented: return QStringLiteral("501 Not Implemented");
277 case HTTPBadGateway: return QStringLiteral("502 Bad Gateway");
278 case HTTPServiceUnavailable: return QStringLiteral("503 Service Unavailable");
279 case HTTPNetworkAuthenticationRequired: return QStringLiteral("511 Network Authentication Required");
280 }
281 return QStringLiteral("Error");
282 }
283
284 static MythHTTPStatus StatusFromString(const QString& Status)
285 {
286 if (Status.startsWith(QStringLiteral("200"))) return HTTPOK;
287 if (Status.startsWith(QStringLiteral("101"))) return HTTPSwitchingProtocols;
288 if (Status.startsWith(QStringLiteral("206"))) return HTTPPartialContent;
289 if (Status.startsWith(QStringLiteral("301"))) return HTTPMovedPermanently;
290 if (Status.startsWith(QStringLiteral("304"))) return HTTPNotModified;
291 //if (Status.startsWith(QStringLiteral("400"))) return HTTPBadRequest;
292 if (Status.startsWith(QStringLiteral("401"))) return HTTPUnauthorized;
293 if (Status.startsWith(QStringLiteral("403"))) return HTTPForbidden;
294 if (Status.startsWith(QStringLiteral("404"))) return HTTPNotFound;
295 if (Status.startsWith(QStringLiteral("405"))) return HTTPMethodNotAllowed;
296 if (Status.startsWith(QStringLiteral("408"))) return HTTPRequestTimeout;
297 if (Status.startsWith(QStringLiteral("416"))) return HTTPRequestedRangeNotSatisfiable;
298 if (Status.startsWith(QStringLiteral("429"))) return HTTPTooManyRequests;
299 if (Status.startsWith(QStringLiteral("500"))) return HTTPNotImplemented;
300 if (Status.startsWith(QStringLiteral("501"))) return HTTPBadGateway;
301 if (Status.startsWith(QStringLiteral("502"))) return HTTPServiceUnavailable;
302 if (Status.startsWith(QStringLiteral("511"))) return HTTPNetworkAuthenticationRequired;
303 return HTTPBadRequest;
304 }
305
306 static QString ConnectionToString(MythHTTPConnection Connection)
307 {
308 switch (Connection)
309 {
310 case HTTPConnectionClose: return QStringLiteral("close");
311 case HTTPConnectionKeepAlive: break;
312 case HTTPConnectionUpgrade: return QStringLiteral("Upgrade");
313 }
314 return QStringLiteral("keep-alive");
315 }
316
317 // N.B. Value must be lower case
318 static QString GetHeader(const HTTPHeaders& Headers, const QString& Value, const QString& Default = "")
319 {
320 if (Headers && Headers->contains(Value))
321 return Headers->value(Value);
322 return Default;
323 }
324
325 static inline QString GetContentType(const MythMimeType& Mime)
326 {
327 QString type = Mime.Name();
328 if (Mime.Inherits("text/plain"))
329 type += "; charset=\"UTF-8\"";
330 return type;
331 }
332
333 static inline QString AddressToString(QHostAddress& Address)
334 {
335 if (Address.protocol() == QAbstractSocket::IPv6Protocol)
336 {
337 Address.setScopeId("");
338 return QString("[%1]").arg(Address.toString());
339 }
340 return Address.toString();
341 }
342};
343#endif
QSslConfiguration m_sslConfig
Definition: mythhttptypes.h:78
QStringList m_filePaths
Definition: mythhttptypes.h:73
HTTPHandler m_errorPageHandler
Definition: mythhttptypes.h:76
HTTPHandlers m_handlers
Definition: mythhttptypes.h:74
QString m_rootDir
Definition: mythhttptypes.h:67
QStringList m_allowedOrigins
Definition: mythhttptypes.h:72
QStringList m_hosts
Definition: mythhttptypes.h:71
HTTPServices m_services
Definition: mythhttptypes.h:75
QString m_serverName
Definition: mythhttptypes.h:68
QString m_language
Definition: mythhttptypes.h:70
MythHTTPContent(QString Name)
MythHTTPEncode m_encoding
int64_t m_multipartHeaderSize
HTTPContents m_multipartHeaders
MythMimeType m_mimeType
QByteArray m_etag
QDateTime m_lastModified
HTTPRanges m_ranges
int64_t m_partialSize
Limited parsing of HTTP method and some headers to determine validity of request.
static MythHTTPVersion VersionFromString(const QString &Version)
static int RequestsFromString(const QString &Requests)
static QString GetContentType(const MythMimeType &Mime)
static QString AllowedRequestsToString(int Allowed)
static QString AddressToString(QHostAddress &Address)
static QString RequestToString(MythHTTPRequestType Type)
static QString ConnectionToString(MythHTTPConnection Connection)
static QString GetHeader(const HTTPHeaders &Headers, const QString &Value, const QString &Default="")
static MythHTTPRequestType RequestFromString(const QString &Type)
static MythHTTPStatus StatusFromString(const QString &Status)
static QString VersionToString(MythHTTPVersion Version)
static QString StatusToString(MythHTTPStatus Status)
QString Name() const
bool Inherits(const QString &Name) const
Does this type inherit from the given type.
Q_DECLARE_METATYPE(std::chrono::seconds)
std::vector< HTTPRange > HTTPRanges
std::pair< uint64_t, uint64_t > HTTPRange
Definition: mythhttpranges.h:9
MythHTTPStatus
@ HTTPRequestedRangeNotSatisfiable
@ HTTPMovedPermanently
@ HTTPBadRequest
@ HTTPServiceUnavailable
@ HTTPNotImplemented
@ HTTPOK
@ HTTPTooManyRequests
@ HTTPInternalServerError
@ HTTPAccepted
@ HTTPSwitchingProtocols
@ HTTPUnauthorized
@ HTTPForbidden
@ HTTPNotModified
@ HTTPBadGateway
@ HTTPMethodNotAllowed
@ HTTPPartialContent
@ HTTPRequestTimeout
@ HTTPNetworkAuthenticationRequired
@ HTTPNotFound
std::function< void()> HTTPRegisterTypes
Definition: mythhttptypes.h:50
MythHTTPConnection
@ HTTPConnectionClose
@ HTTPConnectionKeepAlive
@ HTTPConnectionUpgrade
std::shared_ptr< MythHTTPFile > HTTPFile
Definition: mythhttptypes.h:41
std::shared_ptr< MythHTTPRequest > HTTPRequest2
Definition: mythhttptypes.h:39
std::pair< QString, HTTPServiceCtor > HTTPService
Definition: mythhttptypes.h:54
std::shared_ptr< HTTPMap > HTTPHeaders
Definition: mythhttptypes.h:36
std::vector< HTTPHandler > HTTPHandlers
Definition: mythhttptypes.h:48
MythHTTPRequestType
Definition: mythhttptypes.h:91
@ HTTPGet
Definition: mythhttptypes.h:94
@ HTTPUnknown
Definition: mythhttptypes.h:92
@ HTTPHead
Definition: mythhttptypes.h:93
@ HTTPPut
Definition: mythhttptypes.h:96
@ HTTPPost
Definition: mythhttptypes.h:95
@ HTTPOptions
Definition: mythhttptypes.h:98
@ HTTPDelete
Definition: mythhttptypes.h:97
std::shared_ptr< MythHTTPResponse > HTTPResponse
Definition: mythhttptypes.h:40
MythHTTPVersion
Definition: mythhttptypes.h:83
@ HTTPUnknownVersion
Definition: mythhttptypes.h:84
@ HTTPOneDotOne
Definition: mythhttptypes.h:87
@ HTTPOneDotZero
Definition: mythhttptypes.h:86
@ HTTPZeroDotNine
Definition: mythhttptypes.h:85
std::function< HTTPResponse(HTTPRequest2)> HTTPFunction
Definition: mythhttptypes.h:46
std::shared_ptr< MythHTTPService > HTTPServicePtr
Definition: mythhttptypes.h:51
std::shared_ptr< MythHTTPData > HTTPData
Definition: mythhttptypes.h:37
std::vector< HTTPService > HTTPServices
Definition: mythhttptypes.h:55
HTTPMap HTTPQueries
Definition: mythhttptypes.h:35
std::variant< std::monostate, HTTPData, HTTPFile > HTTPVariant
Definition: mythhttptypes.h:42
std::vector< HTTPServicePtr > HTTPServicePtrs
Definition: mythhttptypes.h:52
MythHTTPCacheType
@ HTTPMediumLife
@ HTTPNoCache
@ HTTPETag
@ HTTPLastModified
@ HTTPIgnoreCache
@ HTTPLongLife
@ HTTPShortLife
std::function< HTTPServicePtr()> HTTPServiceCtor
Definition: mythhttptypes.h:53
std::vector< HTTPData > HTTPContents
Definition: mythhttptypes.h:38
MythHTTPEncode
@ HTTPNoEncode
@ HTTPChunked
@ HTTPGzip
static QString s_defaultHTTPPage
std::pair< HTTPData, HTTPData > HTTPMulti
Definition: mythhttptypes.h:49
QMultiMap< QString, QString > HTTPMap
Definition: mythhttptypes.h:34
std::pair< QString, HTTPFunction > HTTPHandler
Definition: mythhttptypes.h:47
static QString s_multipartBoundary
std::deque< HTTPVariant > HTTPQueue
Definition: mythhttptypes.h:43
#define HTTP_SOCKET_TIMEOUT_MS
Definition: mythhttptypes.h:25
STL namespace.