MythTV  master
mythhttpresponse.cpp
Go to the documentation of this file.
1 // Qt
2 #include <QCryptographicHash>
3 #include <QMimeDatabase>
4 
5 // MythTV
6 #include "mythlogging.h"
7 #include "mythdate.h"
9 #include "http/mythhttpdata.h"
10 #include "http/mythhttpfile.h"
11 #include "http/mythhttpranges.h"
12 #include "http/mythhttpencoding.h"
13 #include "http/mythhttprequest.h"
14 #include "http/mythhttpcache.h"
15 
16 #define LOC QString("HTTPResp: ")
17 
21  : m_serverName(Request->m_serverName),
22  m_version(Request->m_version),
23  m_connection(Request->m_connection),
24  m_timeout(Request->m_timeout),
25  m_status(Request->m_status),
26  m_requestType(Request->m_type),
27  m_allowed(Request->m_allowed),
28  m_requestHeaders(Request->m_headers)
29 {
30 }
31 
35 {
36  // Remaining entity headers
37  auto * data = std::get_if<HTTPData>(&m_response);
38  auto * file = std::get_if<HTTPFile>(&m_response);
39  if ((data || file) && m_requestHeaders)
40  {
41  // Language
42  if (!Config.m_language.isEmpty())
43  AddHeader("Content-Language", Config.m_language);
44 
45  // Content disposition
46  QString filename = data ? (*data)->m_fileName : (*file)->m_fileName;
47  // Warn about programmer error
48  if (filename.isEmpty())
49  LOG(VB_GENERAL, LOG_WARNING, LOC + "Response has no name");
50 
51  // Default to 'inline' but we should support 'attachment' when it would
52  // be appropriate i.e. not when streaming a file to a upnp player or browser
53  // that can support it natively
54  // TODO: Add support for utf8 encoding - RFC 5987
55  AddHeader("Content-Disposition", QString("inline; filename=\"%2\"").arg(qPrintable(filename)));
56 
57  // TODO Should these be moved to UPnP handlers?
58  // UPnP headers
59  // DLNA 7.5.4.3.2.33 MT transfer mode indication
60  QString mode = MythHTTP::GetHeader(m_requestHeaders, "transferMode.dlna.org");
61  if (mode.isEmpty())
62  {
63  QString mime = data ? (*data)->m_mimeType.Name() : (*file)->m_mimeType.Name();
64  if (mime.startsWith("video/") || mime.startsWith("audio/"))
65  mode = "Streaming";
66  else
67  mode = "Interactive";
68  }
69 
70  if (mode == "Streaming" || mode == "Background" || mode == "Interactive")
71  AddHeader("transferMode.dlna.org", mode);
72 
73  // See DLNA 7.4.1.3.11.4.3 Tolerance to unavailable contentFeatures.dlna.org header
74  //
75  // It is better not to return this header, than to return it containing
76  // invalid or incomplete information. We are unable to currently determine
77  // this information at this stage, so do not return it. Only older devices
78  // look for it. Newer devices use the information provided in the UPnP
79  // response
80 
81  // HACK Temporary hack for Samsung TVs - Needs to be moved later as it's not entirely DLNA compliant
82  if (!MythHTTP::GetHeader(m_requestHeaders, "getcontentFeatures.dlna.org", "").isEmpty())
83  {
84  AddHeader("contentFeatures.dlna.org",
85  "DLNA.ORG_OP=01;DLNA.ORG_CI=0;DLNA.ORG_FLAGS=01500000000000000000000000000000");
86  }
87 
88  // Security (mostly copied from previous HTTP server implementation)
89  // TODO Are these all needed for all content?
90 
91  // Force IE into 'standards' mode
92  AddHeader("X-UA-Compatible", "IE=Edge");
93  // SECURITY: Set X-Content-Type-Options to 'nosniff'
94  AddHeader("X-Content-Type-Options", "nosniff");
95  // SECURITY: Set Content Security Policy
96  //
97  // *No external content allowed*
98  //
99  // This is an important safeguard. Third party content
100  // should never be permitted. It compromises security,
101  // privacy and violates the key principal that the
102  // WebFrontend should work on an isolated network with no
103  // internet access. Keep all content hosted locally!
104  //
105  // For now the following are disabled as we use xhr to
106  // trigger playback on frontends if we switch to triggering
107  // that through an internal request then these would be
108  // better enabled
109  //"default-src 'self'; "
110  //"connect-src 'self' https://services.mythtv.org; "
111 
112  // FIXME unsafe-inline should be phased out, replaced by nonce-{csp_nonce} but it requires
113  // all inline event handlers and style attributes to be removed ...
114  QString policy = "script-src 'self' 'unsafe-inline' 'unsafe-eval' https://services.mythtv.org; "
115  "style-src 'self' 'unsafe-inline'; "
116  "frame-src 'self'; "
117  "object-src 'none'; "
118  "media-src 'self'; "
119  "font-src 'self'; "
120  "img-src 'self'; "
121  "form-action 'self'; "
122  "frame-ancestors 'self'; ";
123 
124  // For standards compliant browsers
125  AddHeader("Content-Security-Policy", policy);
126  // For Internet Explorer
127  AddHeader("X-Content-Security-Policy", policy);
128  AddHeader("X-XSS-Protection", "1; mode=block");
129  }
130 
131  // Validate CORS requests
132  if (m_requestHeaders)
133  {
134  QString origin = MythHTTP::GetHeader(m_requestHeaders, "origin").trimmed().toLower();
135  if (!origin.isEmpty())
136  {
137  // Try allowed origins first
138  bool allow = Config.m_allowedOrigins.contains(origin);
139  if (!allow)
140  {
141  // Our list of hosts do not include the scheme (e.g. http) - so strip
142  // this from the origin.
143  if (auto index = origin.lastIndexOf("://"); index > -1)
144  {
145  auto scheme = origin.mid(0, index);
146  if (scheme == "http" || scheme == "https")
147  {
148  auto host = origin.mid(index + 3);
149  allow = Config.m_hosts.contains(host);
150  }
151  }
152  }
153  if (allow)
154  {
155  AddHeader("Access-Control-Allow-Origin" , origin);
156  AddHeader("Access-Control-Allow-Credentials" , "true");
157  AddHeader("Access-Control-Allow-Headers" , "Content-Type, Accept, Range");
158  AddHeader("Access-Control-Request-Method", MythHTTP::AllowedRequestsToString(m_allowed));
159  LOG(VB_HTTP, LOG_INFO, LOC + QString("Allowing CORS for origin: '%1'").arg(origin));
160  }
161  else
162  {
163  LOG(VB_HTTP, LOG_INFO, LOC + QString("Disallowing CORS for origin: '%1'").arg(origin));
164  }
165  }
166  }
167 
168  // Add line break after headers
169  m_responseHeaders.emplace_back(MythHTTPData::Create("", "\r\n"));
170 
171  // remove actual content for HEAD requests, failed range requests and 304 Not Modified's
172  if ((m_requestType == HTTPHead) || (m_status == HTTPNotModified) ||
174  {
175  m_response = std::monostate();
176  }
177 }
178 
180 {
181  if (!Request)
182  return nullptr;
183 
184  // The default allowed methods in MythHTTPRequest are HEAD, GET, OPTIONS.
185  // Override if necessary before calling this functions.
186  // N.B. GET and HEAD must be supported for HTTP/1.1
187  if ((Request->m_type & Request->m_allowed) != Request->m_type)
188  {
189  LOG(VB_GENERAL, LOG_WARNING, LOC + QString("'%1' is not allowed for '%2' (Allowed: %3)")
190  .arg(MythHTTP::RequestToString(Request->m_type), Request->m_fileName,
192  Request->m_status = HTTPMethodNotAllowed;
194  }
195 
196  // Options
197  if (Request->m_type == HTTPOptions)
199 
200  return nullptr;
201 }
202 
204 {
205  auto response = std::make_shared<MythHTTPResponse>();
206  response->m_serverName = ServerName;
207  response->m_status = Status;
208  if (Status != HTTPServiceUnavailable)
209  {
210  response->m_response = MythHTTPData::Create("error.html",
211  s_defaultHTTPPage.arg(MythHTTP::StatusToString(Status)).toUtf8().constData());
212  }
213  response->AddDefaultHeaders();
214  if (Status == HTTPMethodNotAllowed)
215  response->AddHeader("Allow", MythHTTP::AllowedRequestsToString(response->m_allowed));
216  response->AddContentHeaders();
217  return response;
218 }
219 
221 {
222  Request->m_status = HTTPMovedPermanently;
223  auto response = std::make_shared<MythHTTPResponse>(Request);
224  response->AddDefaultHeaders();
225  response->AddHeader("Location", Redirect);
226  response->AddContentHeaders();
227  return response;
228 }
229 
231 {
232  auto response = std::make_shared<MythHTTPResponse>(Request);
233  response->m_response = MythHTTPData::Create("error.html", s_defaultHTTPPage
234  .arg(Message.isEmpty() ? MythHTTP::StatusToString(Request->m_status) : Message).toUtf8().constData());
235  response->AddDefaultHeaders();
236  response->AddContentHeaders();
237  return response;
238 }
239 
241 {
242  auto response = std::make_shared<MythHTTPResponse>(Request);
243  response->AddDefaultHeaders();
244  response->AddHeader("Allow", MythHTTP::AllowedRequestsToString(response->m_allowed));
245  response->AddContentHeaders();
246  return response;
247 }
248 
250 {
251  auto response = std::make_shared<MythHTTPResponse>(Request);
252  response->m_response = Data;
254  response->AddDefaultHeaders();
255  response->AddContentHeaders();
257  return response;
258 }
259 
261 {
262  auto response = std::make_shared<MythHTTPResponse>(Request);
263  response->m_response = File;
265  response->AddDefaultHeaders();
266  response->AddContentHeaders();
268  return response;
269 }
270 
272 {
273  auto response = std::make_shared<MythHTTPResponse>(Request);
274  response->AddDefaultHeaders();
275  response->AddContentHeaders();
276  return response;
277 }
278 
280 {
281  // Handle range requests early as they influence the status, compression etc
282  QString range = MythHTTP::GetHeader(m_requestHeaders, "range", "");
283  if (!range.isEmpty())
285 
286  QByteArray def = QString("%1 %2\r\n").arg(MythHTTP::VersionToString(m_version),
288  m_responseHeaders.emplace_back(MythHTTPData::Create(def));
290  AddHeader("Server", m_serverName);
291  // Range requests are supported
292  AddHeader("Accept-Ranges", "bytes");
293  AddHeader("Connection", m_connection == HTTPConnectionClose ? "Close" : "Keep-Alive");
295  AddHeader("Keep-Alive", QString("timeout=%1").arg(m_timeout.count() / 1000));
296 
297  // Required error specific headers
299  AddHeader("Retry-After", HTTP_SOCKET_TIMEOUT_MS / 1000);
300 }
301 
303 {
304  // Check content type and size first
305  auto * data = std::get_if<HTTPData>(&m_response);
306  auto * file = std::get_if<HTTPFile>(&m_response);
307  int64_t size = data ? (*data)->size() : file ? (*file)->size() : 0;
308 
309  // Always add a zero length content header to keep some clients happy
310  if (size < 1)
311  {
312  AddHeader("Content-Length", 0);
313  return;
314  }
315 
316  // Check mime type if not already set
317  auto & mime = data ? (*data)->m_mimeType : (*file)->m_mimeType;
318  if (!mime.IsValid())
320 
321  // Range request?
322  HTTPRanges& ranges = data ? (*data)->m_ranges : (*file)->m_ranges;
323  bool rangerequest = !ranges.empty();
324  bool multipart = ranges.size() > 1;
325 
326  // We now have the mime type and we can generate the multipart headers for a
327  // multipart request
328  if (multipart)
330 
331  // Set the content type - with special handling for multipart ranges
332  AddHeader("Content-Type", multipart ? MythHTTPRanges::GetRangeHeader(ranges, size) :
334 
336  {
337  // Mandatory 416 (Range Not Satisfiable) response
338  // Note - we will remove content before sending
339  AddHeader("Content-Range", QString("bytes */%1").arg(size));
340  AddHeader("Content-Length", 0);
341  return;
342  }
343 
344  // Compress/chunk the result depending on client preferences, content and transfer type
345  auto encode = MythHTTPEncoding::Compress(this, size);
346 
347  // and finally set the length if we aren't chunking or the transfer-encoding
348  // header if we are
349  if (encode == HTTPChunked)
350  {
351  AddHeader("Transfer-Encoding", "chunked");
352  }
353  else
354  {
355  if (rangerequest)
356  {
357  // Inform the client of the (single) range being served
358  if (!multipart)
359  AddHeader("Content-Range", MythHTTPRanges::GetRangeHeader(ranges, size));
360  // Content-Length is now the number of bytes served, not the total
361  size = data ? (*data)->m_partialSize : (*file)->m_partialSize;
362  }
363 
364  // Add the size of the multipart headers to the content length
365  if (multipart)
366  size += data ? (*data)->m_multipartHeaderSize : (*file)->m_multipartHeaderSize;
367  AddHeader("Content-Length", size);
368  }
369 }
370 
372 {
373  // Assume the worst:) and create a default error response
374  Request->m_status = HTTPBadRequest;
375  auto response = std::make_shared<MythHTTPResponse>(Request);
376  response->AddDefaultHeaders();
377  response->AddContentHeaders();
378 
379  // This shouldn't happen
380  if (!Request)
381  return response;
382 
383  /* Excerpt from RFC 6455
384  The requirements for this handshake are as follows.
385  1. The handshake MUST be a valid HTTP request as specified by
386  [RFC2616].
387  2. The method of the request MUST be GET, and the HTTP version MUST
388  be at least 1.1.
389  For example, if the WebSocket URI is "ws://example.com/chat",
390  the first line sent should be "GET /chat HTTP/1.1".
391  */
392 
393  if ((Request->m_type != HTTPGet || Request->m_version != HTTPOneDotOne))
394  {
395  LOG(VB_HTTP, LOG_ERR, LOC + "Must be GET and HTTP/1.1");
396  return response;
397  }
398 
399  /*
400  3. The "Request-URI" part of the request MUST match the /resource
401  name/ defined in Section 3 (a relative URI) or be an absolute
402  http/https URI that, when parsed, has a /resource name/, /host/,
403  and /port/ that match the corresponding ws/wss URI.
404  */
405 
406  if (Request->m_path.isEmpty())
407  {
408  LOG(VB_HTTP, LOG_ERR, LOC + "Invalid Request-URI");
409  return response;
410  }
411 
412  /*
413  4. The request MUST contain a |Host| header field whose value
414  contains /host/ plus optionally ":" followed by /port/ (when not
415  using the default port).
416  */
417 
418  // Already checked in MythHTTPRequest
419 
420  /*
421  5. The request MUST contain an |Upgrade| header field whose value
422  MUST include the "websocket" keyword.
423  */
424 
425  auto header = MythHTTP::GetHeader(Request->m_headers, "upgrade");
426  if (header.isEmpty() || !header.contains("websocket", Qt::CaseInsensitive))
427  {
428  LOG(VB_HTTP, LOG_ERR, LOC + "Invalid/missing 'Upgrade' header");
429  return response;
430  }
431 
432  /*
433  6. The request MUST contain a |Connection| header field whose value
434  MUST include the "Upgrade" token.
435  */
436 
437  header = MythHTTP::GetHeader(Request->m_headers, "connection");
438  if (header.isEmpty() || !header.contains("upgrade", Qt::CaseInsensitive))
439  {
440  LOG(VB_HTTP, LOG_ERR, LOC + "Invalid/missing 'Connection' header");
441  return response;
442  }
443 
444  /*
445  7. The request MUST include a header field with the name
446  |Sec-WebSocket-Key|. The value of this header field MUST be a
447  nonce consisting of a randomly selected 16-byte value that has
448  been base64-encoded (see Section 4 of [RFC4648]). The nonce
449  MUST be selected randomly for each connection.
450  NOTE: As an example, if the randomly selected value was the
451  sequence of bytes 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09
452  0x0a 0x0b 0x0c 0x0d 0x0e 0x0f 0x10, the value of the header
453  field would be "AQIDBAUGBwgJCgsMDQ4PEC=="
454  */
455 
456  auto key = MythHTTP::GetHeader(Request->m_headers, "sec-websocket-key").trimmed();
457  if (key.isEmpty())
458  {
459  LOG(VB_HTTP, LOG_ERR, LOC + "No Sec-WebSocket-Key header");
460  return response;
461  }
462  auto nonce = QByteArray::fromBase64(key.toLatin1());
463  if (nonce.length() != 16)
464  {
465  LOG(VB_HTTP, LOG_ERR, LOC + QString("Invalid Sec-WebSocket-Key header (length: %1)").arg(nonce.length()));
466  return response;
467  }
468 
469  /*
470  8. The request MUST include a header field with the name |Origin|
471  [RFC6454] if the request is coming from a browser client. If
472  the connection is from a non-browser client, the request MAY
473  include this header field if the semantics of that client match
474  the use-case described here for browser clients. The value of
475  this header field is the ASCII serialization of origin of the
476  context in which the code establishing the connection is
477  running. See [RFC6454] for the details of how this header field
478  value is constructed.
479 
480  As an example, if code downloaded from www.example.com attempts
481  to establish a connection to ww2.example.com, the value of the
482  header field would be "http://www.example.com".
483  */
484 
485  // No reasonable way of knowing if the client is a browser. May need more work.
486 
487  /*
488  9. The request MUST include a header field with the name
489  |Sec-WebSocket-Version|. The value of this header field MUST be
490  13.
491  */
492 
493  if (header = MythHTTP::GetHeader(Request->m_headers, "sec-websocket-version"); header.trimmed().toInt() != 13)
494  {
495  LOG(VB_HTTP, LOG_ERR, LOC + QString("Unsupported websocket version %1").arg(header));
496  response->AddHeader(QStringLiteral("Sec-WebSocket-Version"), QStringLiteral("13"));
497  return response;
498  }
499 
500  /*
501  10. The request MAY include a header field with the name
502  |Sec-WebSocket-Protocol|. If present, this value indicates one
503  or more comma-separated subprotocol the client wishes to speak,
504  ordered by preference. The elements that comprise this value
505  MUST be non-empty strings with characters in the range U+0021 to
506  U+007E not including separator characters as defined in
507  [RFC2616] and MUST all be unique strings. The ABNF for the
508  value of this header field is 1#token, where the definitions of
509  constructs and rules are as given in [RFC2616].
510  */
511 
512  Protocol = MythHTTPWS::ProtocolFromString(MythHTTP::GetHeader(Request->m_headers, "sec-websocket-protocol"));
513 
514  // If we've got this far, everything is OK, we have set the protocol that will
515  // be used and we need to respond positively.
516 
517  static const auto magic = QStringLiteral("258EAFA5-E914-47DA-95CA-C5AB0DC85B11");
518  QString hash = QCryptographicHash::hash((key + magic).toUtf8(), QCryptographicHash::Sha1).toBase64();
519 
520  // Replace response
521  Request->m_status = HTTPSwitchingProtocols;
522  response = std::make_shared<MythHTTPResponse>(Request);
523  response->AddDefaultHeaders();
524  response->AddContentHeaders();
525  response->AddHeader(QStringLiteral("Connection"), QStringLiteral("Upgrade"));
526  response->AddHeader(QStringLiteral("Upgrade"), QStringLiteral("websocket"));
527  response->AddHeader(QStringLiteral("Sec-WebSocket-Accept"), hash);
528  if (Protocol != ProtFrame)
529  response->AddHeader(QStringLiteral("Sec-WebSocket-Protocol"), MythHTTPWS::ProtocolToString(Protocol));
530 
531  LOG(VB_HTTP, LOG_INFO, LOC + QString("Successful WebSocket upgrade (protocol: %1)")
532  .arg(MythHTTPWS::ProtocolToString(Protocol)));
533 
534  // Check for Autobahn test suite
535  if (header = MythHTTP::GetHeader(Request->m_headers, "user-agent"); header.contains("AutobahnTestSuite"))
536  {
537  LOG(VB_GENERAL, LOG_INFO, LOC + "Autobahn test suite detected. Will echooooo...");
538  Testing = true;
539  }
540 
541  // Ensure we pass handling to the websocket code once the response is sent
542  response->m_connection = HTTPConnectionUpgrade;
543  return response;
544 }
HTTPChunked
@ HTTPChunked
Definition: mythhttptypes.h:138
LOC
#define LOC
Definition: mythhttpresponse.cpp:16
mythhttpcache.h
MythDate::toString
QString toString(const QDateTime &raw_dt, uint format)
Returns formatted string representing the time.
Definition: mythdate.cpp:84
MythHTTPResponse::UpgradeResponse
static HTTPResponse UpgradeResponse(const HTTPRequest2 &Request, MythSocketProtocol &Protocol, bool &Testing)
Definition: mythhttpresponse.cpp:371
MythHTTPResponse::m_serverName
QString m_serverName
Definition: mythhttpresponse.h:48
MythHTTPConfig::m_allowedOrigins
QStringList m_allowedOrigins
Definition: mythhttptypes.h:71
MythHTTPResponse::FileResponse
static HTTPResponse FileResponse(const HTTPRequest2 &Request, const HTTPFile &File)
Definition: mythhttpresponse.cpp:260
MythHTTPRanges::BuildMultipartHeaders
static void BuildMultipartHeaders(MythHTTPResponse *Response)
Definition: mythhttpranges.cpp:32
MythHTTPResponse::DataResponse
static HTTPResponse DataResponse(const HTTPRequest2 &Request, const HTTPData &Data)
Definition: mythhttpresponse.cpp:249
HTTPConnectionKeepAlive
@ HTTPConnectionKeepAlive
Definition: mythhttptypes.h:130
HTTPOptions
@ HTTPOptions
Definition: mythhttptypes.h:97
HTTPGet
@ HTTPGet
Definition: mythhttptypes.h:93
MythHTTP::RequestToString
static QString RequestToString(MythHTTPRequestType Type)
Definition: mythhttptypes.h:206
MythHTTP::GetHeader
static QString GetHeader(const HTTPHeaders &Headers, const QString &Value, const QString &Default="")
Definition: mythhttptypes.h:317
MythHTTPConfig::m_language
QString m_language
Definition: mythhttptypes.h:69
mythhttpranges.h
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
MythHTTPWS::ProtocolFromString
static MythSocketProtocol ProtocolFromString(const QString &Protocols)
Definition: mythhttpcommon.cpp:56
build_compdb.file
file
Definition: build_compdb.py:55
MythHTTPResponse::MythHTTPResponse
MythHTTPResponse()=default
MythHTTPResponse::m_version
MythHTTPVersion m_version
Definition: mythhttpresponse.h:49
mythhttpdata.h
MythHTTPCache::PreConditionCheck
static void PreConditionCheck(const HTTPResponse &Response)
Process precondition checks.
Definition: mythhttpcache.cpp:51
MythDate::current
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:14
HTTPData
std::shared_ptr< MythHTTPData > HTTPData
Definition: mythhttptypes.h:36
mythhttpfile.h
HTTPMethodNotAllowed
@ HTTPMethodNotAllowed
Definition: mythhttptypes.h:116
MythSocketProtocol
MythSocketProtocol
Definition: mythhttpcommon.h:25
MythHTTPResponse::HandleOptions
static HTTPResponse HandleOptions(const HTTPRequest2 &Request)
Definition: mythhttpresponse.cpp:179
MythHTTPResponse::m_status
MythHTTPStatus m_status
Definition: mythhttpresponse.h:52
MythHTTP::StatusToString
static QString StatusToString(MythHTTPStatus Status)
Definition: mythhttptypes.h:256
mythdate.h
mythlogging.h
MythHTTPWS::ProtocolToString
static QString ProtocolToString(MythSocketProtocol Protocol)
Definition: mythhttpcommon.cpp:42
MythHTTPCache::PreConditionHeaders
static void PreConditionHeaders(const HTTPResponse &Response)
Add precondition (cache) headers to the response.
Definition: mythhttpcache.cpp:155
MythHTTP::AllowedRequestsToString
static QString AllowedRequestsToString(int Allowed)
Definition: mythhttptypes.h:232
MythHTTPEncoding::GetMimeType
static MythMimeType GetMimeType(HTTPVariant Content)
Return a QMimeType that represents Content.
Definition: mythhttpencoding.cpp:242
MythHTTPStatus
MythHTTPStatus
Definition: mythhttptypes.h:104
MythHTTPData::Create
static HTTPData Create()
Definition: mythhttpdata.cpp:4
MythHTTPResponse::m_response
HTTPVariant m_response
Definition: mythhttpresponse.h:57
MythHTTPResponse::AddContentHeaders
void AddContentHeaders()
Definition: mythhttpresponse.cpp:302
MythHTTP::GetContentType
static QString GetContentType(const MythMimeType &Mime)
Definition: mythhttptypes.h:324
MythHTTPResponse::ErrorResponse
static HTTPResponse ErrorResponse(MythHTTPStatus Status, const QString &ServerName)
Definition: mythhttpresponse.cpp:203
mythhttpencoding.h
HTTPNotModified
@ HTTPNotModified
Definition: mythhttptypes.h:111
HTTPConnectionClose
@ HTTPConnectionClose
Definition: mythhttptypes.h:129
MythHTTPResponse::AddDefaultHeaders
void AddDefaultHeaders()
Definition: mythhttpresponse.cpp:279
s_defaultHTTPPage
static QString s_defaultHTTPPage
Definition: mythhttptypes.h:153
HTTPRequestedRangeNotSatisfiable
@ HTTPRequestedRangeNotSatisfiable
Definition: mythhttptypes.h:118
mythhttpresponse.h
MythHTTPResponse::RedirectionResponse
static HTTPResponse RedirectionResponse(const HTTPRequest2 &Request, const QString &Redirect)
Definition: mythhttpresponse.cpp:220
MythHTTPResponse::m_requestType
MythHTTPRequestType m_requestType
Definition: mythhttpresponse.h:53
MythHTTPResponse::OptionsResponse
static HTTPResponse OptionsResponse(const HTTPRequest2 &Request)
Definition: mythhttpresponse.cpp:240
MythHTTPResponse::m_allowed
int m_allowed
Definition: mythhttpresponse.h:54
HTTPOneDotOne
@ HTTPOneDotOne
Definition: mythhttptypes.h:86
MythHTTPResponse::m_timeout
std::chrono::milliseconds m_timeout
Definition: mythhttpresponse.h:51
HTTPResponse
std::shared_ptr< MythHTTPResponse > HTTPResponse
Definition: mythhttptypes.h:39
hardwareprofile.distros.mythtv_data.request.Request
def Request(url=None)
Definition: distros/mythtv_data/request.py:62
HTTP_SOCKET_TIMEOUT_MS
#define HTTP_SOCKET_TIMEOUT_MS
Definition: mythhttptypes.h:24
HTTPBadRequest
@ HTTPBadRequest
Definition: mythhttptypes.h:112
HTTPHead
@ HTTPHead
Definition: mythhttptypes.h:92
MythHTTPResponse::m_connection
MythHTTPConnection m_connection
Definition: mythhttpresponse.h:50
HTTPMovedPermanently
@ HTTPMovedPermanently
Definition: mythhttptypes.h:110
MythDate::kRFC822
@ kRFC822
HTTP Date format.
Definition: mythdate.h:30
MythHTTP::VersionToString
static QString VersionToString(MythHTTPVersion Version)
Definition: mythhttptypes.h:183
MythHTTPConfig::m_hosts
QStringList m_hosts
Definition: mythhttptypes.h:70
HTTPRequest2
std::shared_ptr< MythHTTPRequest > HTTPRequest2
Definition: mythhttptypes.h:38
mythhttprequest.h
HTTPConnectionUpgrade
@ HTTPConnectionUpgrade
Definition: mythhttptypes.h:131
MythHTTPRanges::GetRangeHeader
static QString GetRangeHeader(HTTPRanges &Ranges, int64_t Size)
Definition: mythhttpranges.cpp:80
MythHTTPEncoding::Compress
static MythHTTPEncode Compress(MythHTTPResponse *Response, int64_t &Size)
Compress the response content under certain circumstances or mark the content as 'chunkable'.
Definition: mythhttpencoding.cpp:287
ProtFrame
@ ProtFrame
Definition: mythhttpcommon.h:28
MythHTTPResponse::EmptyResponse
static HTTPResponse EmptyResponse(const HTTPRequest2 &Request)
Definition: mythhttpresponse.cpp:271
MythHTTPResponse::Finalise
void Finalise(const MythHTTPConfig &Config)
Complete all necessary headers, add final line break after headers, remove data etc.
Definition: mythhttpresponse.cpp:34
MythHTTPResponse::m_requestHeaders
HTTPHeaders m_requestHeaders
Definition: mythhttpresponse.h:55
MythHTTPResponse::AddHeader
std::enable_if_t< std::is_convertible_v< T, QString >, void > AddHeader(const QString &key, const T &val)
Definition: mythhttpresponse.h:35
MythHTTPConfig
Definition: mythhttptypes.h:60
HTTPRanges
std::vector< HTTPRange > HTTPRanges
Definition: mythhttpranges.h:10
HTTPFile
std::shared_ptr< MythHTTPFile > HTTPFile
Definition: mythhttptypes.h:40
HTTPSwitchingProtocols
@ HTTPSwitchingProtocols
Definition: mythhttptypes.h:106
build_compdb.filename
filename
Definition: build_compdb.py:21
MythHTTPResponse::m_responseHeaders
HTTPContents m_responseHeaders
Definition: mythhttpresponse.h:56
HTTPServiceUnavailable
@ HTTPServiceUnavailable
Definition: mythhttptypes.h:123
MythHTTPRanges::HandleRangeRequest
static void HandleRangeRequest(MythHTTPResponse *Response, const QString &Request)
Definition: mythhttpranges.cpp:12