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