MythTV  master
mythhttpsocket.cpp
Go to the documentation of this file.
1 // Qt
2 #include <QThread>
3 #include <QTcpSocket>
4 #ifndef QT_NO_OPENSSL
5 #include <QSslSocket>
6 #endif
7 
8 // MythTV
9 #include "mythlogging.h"
10 #include "mythcorecontext.h"
11 #include "http/mythwebsocket.h"
12 #include "http/mythhttps.h"
13 #include "http/mythhttpsocket.h"
14 #include "http/mythhttpdata.h"
15 #include "http/mythhttpfile.h"
16 #include "http/mythhttpresponse.h"
17 #include "http/mythhttprequest.h"
18 #include "http/mythhttpranges.h"
19 #include "http/mythhttpservices.h"
21 
22 // Std
23 #include <chrono>
24 using namespace std::chrono_literals;
25 
26 #define LOC QString(m_peer + ": ")
27 
28 MythHTTPSocket::MythHTTPSocket(qintptr Socket, bool SSL, MythHTTPConfig Config)
29  : m_socketFD(Socket),
30  m_config(std::move(Config))
31 {
32  // Connect Finish signal to Stop
33  connect(this, &MythHTTPSocket::Finish, this, &MythHTTPSocket::Stop);
34 
35  // Create socket
36  QSslSocket* sslsocket = nullptr;
37  if (SSL)
38  {
39 #ifndef QT_NO_OPENSSL
40  sslsocket = new QSslSocket(this);
41  m_socket = sslsocket;
42 #endif
43  }
44  else
45  {
46  m_socket = new QTcpSocket(this);
47  }
48 
49  if (!m_socket)
50  {
51  Stop();
52  return;
53  }
54 
55  connect(m_socket, &QTcpSocket::readyRead, this, &MythHTTPSocket::Read);
56  connect(m_socket, &QTcpSocket::bytesWritten, this, &MythHTTPSocket::Write);
57  connect(m_socket, &QTcpSocket::disconnected, this, &MythHTTPSocket::Disconnected);
58  connect(m_socket, &QTcpSocket::disconnected, QThread::currentThread(), &QThread::quit);
59 #if QT_VERSION < QT_VERSION_CHECK(5,15,0)
60  connect(m_socket, qOverload<QAbstractSocket::SocketError>(&QTcpSocket::error),
61  this, &MythHTTPSocket::Error);
62 #else
63  connect(m_socket, &QTcpSocket::errorOccurred, this, &MythHTTPSocket::Error);
64 #endif
65  m_socket->setSocketDescriptor(m_socketFD);
66 
67 #ifndef QT_NO_OPENSSL
68  if (SSL && sslsocket)
70 #endif
71 
72  m_peer = QString("%1:%2").arg(m_socket->peerAddress().toString()).arg(m_socket->peerPort());
73  LOG(VB_HTTP, LOG_INFO, LOC + "New connection");
74 
75  // Setup up timeout timer
76  m_timer.setTimerType(Qt::PreciseTimer);
78  m_timer.start(m_config.m_timeout);
79 
81  Stop();
82 
83  // Setup root services handler - a service for services
84  // Note: the services service is not self aware - i.e. it doesn't list itself
85  // as a service. This is intentional; a client needs to know of the existence
86  // of /services/ already - otherwise it wouldn't be calling it and the 'services'
87  // service would appear again as /services/services/
88  auto service = MythHTTPService::Create<MythHTTPServices>();
89  m_activeServices.emplace_back(service);
90  auto * services = dynamic_cast<MythHTTPServices*>(service.get());
91  if (services == nullptr)
92  {
93  LOG(VB_HTTP, LOG_ERR, LOC + "Failed to get root services handler.");
94  return;
95  }
97  services->UpdateServices(m_config.m_services);
98 }
99 
101 {
102  delete m_websocketevent;
103  delete m_websocket;
104  if (m_socket)
105  m_socket->close();
106  delete m_socket;
107 }
108 
114 void MythHTTPSocket::PathsChanged(const QStringList& Paths)
115 {
116  m_config.m_filePaths = Paths;
117 }
118 
120 {
121  m_config.m_handlers = Handlers;
122 }
123 
125 {
126  m_config.m_services = Services;
128 }
129 
135 void MythHTTPSocket::OriginsChanged(const QStringList& Origins)
136 {
137  m_config.m_allowedOrigins = Origins;
138 }
139 
140 void MythHTTPSocket::HostsChanged(const QStringList& Hosts)
141 {
142  m_config.m_hosts = Hosts;
143 }
144 
151 {
152  LOG(VB_HTTP, LOG_INFO, LOC + "Disconnected");
153 }
154 
155 void MythHTTPSocket::Error(QAbstractSocket::SocketError Error)
156 {
157  if (Error != QAbstractSocket::RemoteHostClosedError)
158  LOG(VB_HTTP, LOG_INFO, LOC + QString("Error %1 (%2)").arg(Error).arg(m_socket->errorString()));
159 }
160 
166 {
167  LOG(VB_HTTP, LOG_DEBUG, LOC + "Timed out waiting for activity");
168  // Send '408 Request Timeout' - Respond will close the socket.
169  // Note: some clients will close the socket themselves at the correct time -
170  // in which case the disconnect may preceed the timeout here - so avoid
171  // misleading write errors...
172  if (m_socket->state() == QAbstractSocket::ConnectedState)
173  {
174  // If this has timed out while a write is in progress, then the socket
175  // buffers are not empty and we cannot send a response - so just close.
176  if (m_socket->bytesToWrite() || !m_queue.empty())
177  {
178  m_queue.clear();
179  LOG(VB_HTTP, LOG_INFO, LOC + "Timeout during write. Quitting.");
180  Stop();
181  return;
182  }
184  Stop();
185  }
186 }
187 
195 {
196  LOG(VB_HTTP, LOG_INFO, LOC + "Stop");
197  if (m_websocket)
198  m_websocket->Close();
199  m_timer.stop();
200  m_stopping = true;
201  // Note: previously this called QTcpSocket::disconnectFromHost - but when
202  // an interrupt is received (i.e. quit the app), there is an intermittent
203  // race condition where the socket is disconnected before the thread is told
204  // to quit and the call to QThread::quit is not triggered (i.e. the connection
205  // between QTcpSocket::disconnected and QThread::quit does not work). So
206  // just quit the thread.
207  QThread::currentThread()->quit();
208 }
209 
215 {
216  if (m_stopping)
217  return;
218 
219  // Warn if we haven't sent the last response
220  if (!m_queue.empty())
221  LOG(VB_GENERAL, LOG_WARNING, LOC + "New request but queue is not empty");
222 
223  // reset the idle timer
224  m_timer.start(m_config.m_timeout);
225 
226  bool ready = false;
227  if (!m_parser.Read(m_socket, ready))
228  {
229  LOG(VB_HTTP, LOG_WARNING, LOC + "HTTP error");
230  Stop();
231  return;
232  }
233 
234  if (!ready)
235  return;
236 
237  // We have a completed request
239  HTTPResponse response = nullptr;
240 
241  // Request should have initial OK status if valid
242  if (request->m_status != HTTPOK)
243  {
244  response = MythHTTPResponse::ErrorResponse(request);
245  Respond(response);
246  return;
247  }
248 
249  // Websocket upgrade request...
250  // This will have a connection type of HTTPConnectionUpgrade on success.
251  // Once the response is sent, we will create a WebSocket instance to handle
252  // further read/write signals.
253  if (!MythHTTP::GetHeader(request->m_headers, "upgrade").isEmpty())
255 
256  // Try (possibly file specific) handlers
257  if (response == nullptr)
258  {
259  // cppcheck-suppress unassignedVariable
260  for (const auto& [path, function] : m_config.m_handlers)
261  {
262  if (path == request->m_url.toString())
263  {
264  response = std::invoke(function, request);
265  if (response)
266  break;
267  }
268  }
269  }
270 
271  const QString& rpath = request->m_path;
272 
273  // Try active services first - this is currently the services root only
274  if (response == nullptr)
275  {
276  LOG(VB_HTTP, LOG_INFO, LOC + QString("Processing: path '%1' file '%2'")
277  .arg(rpath, request->m_fileName));
278 
279  for (auto & service : m_activeServices)
280  {
281  if (service->Name() == rpath)
282  {
283  response = service->HTTPRequest(request);
284  if (response)
285  break;
286  }
287  }
288  }
289 
290  // Then 'inactive' services
291  if (response == nullptr)
292  {
293  // cppcheck-suppress unassignedVariable
294  for (const auto & [path, constructor] : m_config.m_services)
295  {
296  if (path == rpath)
297  {
298  auto instance = std::invoke(constructor);
299  response = instance->HTTPRequest(request);
300  if (response)
301  break;
302  // the service object will be deleted here as it goes out of scope
303  // but we could retain a cache...
304  }
305  }
306  }
307 
308  // Try (dynamic) handlers
309  if (response == nullptr)
310  {
311  // cppcheck-suppress unassignedVariable
312  for (const auto& [path, function] : m_config.m_handlers)
313  {
314  if (path == rpath)
315  {
316  response = std::invoke(function, request);
317  if (response)
318  break;
319  }
320  }
321  }
322 
323  // then simple file path handlers
324  if (response == nullptr)
325  {
326  for (const auto & path : qAsConst(m_config.m_filePaths))
327  {
328  if (path == rpath)
329  {
330  response = MythHTTPFile::ProcessFile(request);
331  if (response)
332  break;
333  }
334  }
335  }
336 
337  // Try error page handler
338  if (response == nullptr || response->m_status == HTTPNotFound)
339  {
340  if(m_config.m_errorPageHandler.first.length() > 0)
341  {
342  auto function = m_config.m_errorPageHandler.second;
343  response = std::invoke(function, request);
344  }
345  }
346 
347  // nothing to see
348  if (response == nullptr)
349  {
350  request->m_status = HTTPNotFound;
351  response = MythHTTPResponse::ErrorResponse(request);
352  }
353 
354  // Send the response
355  Respond(response);
356 }
357 
364 {
365  if (!Response || (m_socket->state() != QAbstractSocket::ConnectedState))
366  return;
367 
368  // Warn if the last response has not been completed
369  if (!m_queue.empty())
370  LOG(VB_GENERAL, LOG_WARNING, LOC + "Responding but queue is not empty");
371 
372  // Reset the write tracker
373  m_writeTime.start();
374  m_totalToSend = 0;
375  m_totalWritten = 0;
376  m_totalSent = 0;
377  m_writeBuffer = nullptr;
378 
379  // Finalise the response
380  Response->Finalise(m_config);
381 
382  // Queue headers
383  for (const auto & header : qAsConst(Response->m_responseHeaders))
384  {
385  LOG(VB_HTTP, LOG_DEBUG, header->trimmed().constData());
386  m_queue.emplace_back(header);
387  }
388 
389  // Queue in memory response content or file
390  if (!std::get_if<std::monostate>(&Response->m_response))
391  m_queue.push_back(Response->m_response);
392  else
393  LOG(VB_HTTP, LOG_DEBUG, LOC + "No content in response");
394 
395  // Sum the expected number of bytes to be written. This is the size of the
396  // data or file OR the total size of the range request. For multipart range
397  // requests, add the total size of the additional headers.
398  for (const auto & content : qAsConst(m_queue))
399  {
400  if (const auto * data = std::get_if<HTTPData>(&content))
401  {
402  m_totalToSend += (*data)->m_partialSize > 0 ? (*data)->m_partialSize : (*data)->size();
403  m_totalToSend += (*data)->m_multipartHeaderSize;
404  }
405  else if (const auto * file = std::get_if<HTTPFile>(&content))
406  {
407  m_totalToSend += (*file)->m_partialSize > 0 ? (*file)->m_partialSize : (*file)->size();
408  m_totalToSend += (*file)->m_multipartHeaderSize;
409  }
410  }
411 
412  // Signal what to do once the response is sent (close, keep alive or upgrade)
413  m_nextConnection = Response->m_connection;
414 
415  // Get the ball rolling
416  Write();
417 }
418 
423 void MythHTTPSocket::RespondDirect(qintptr Socket, const HTTPResponse& Response, const MythHTTPConfig &Config)
424 {
425  if (!(Socket && Response))
426  return;
427 
428  Response->Finalise(Config);
429  auto * socket = new QTcpSocket();
430  socket->setSocketDescriptor(Socket);
431  for (const auto & header : qAsConst(Response->m_responseHeaders))
432  socket->write(*header);
433  socket->flush();
434  socket->disconnectFromHost();
435  delete socket;
436 }
437 
438 void MythHTTPSocket::Write(int64_t Written)
439 {
440  auto chunkheader = [&](const QByteArray& Data)
441  {
442  int64_t wrote = m_socket->write(Data);
443  if (wrote < 0)
444  {
445  LOG(VB_GENERAL, LOG_ERR, "Error writing chunk header");
446  return;
447  }
448  m_totalToSend += wrote;
449  m_totalWritten += wrote;
450  };
451 
452  if (m_stopping)
453  return;
454 
455  // Naughty clients have a habit of stopping reading but leaving the socket open.
456  // Instead of stopping the timer when a request has been received, we leave
457  // it running and update when we see any read OR write activity
458  // TODO perhaps worth using a larger timeout (e.g. *2) for writes - for clients
459  // that are streaming video and have buffered a large amount of data - but with range
460  // request support this probably shouldn't matter - as they can just reconnect
461  // and pick up where they left off.
462  m_timer.start(m_config.m_timeout);
463 
464  // Update write tracker
465  m_totalSent += Written;
466  int64_t buffered = m_socket->bytesToWrite();
467  LOG(VB_HTTP, LOG_DEBUG, LOC + QString("Socket sent %1bytes (still to send %2)")
468  .arg(Written).arg(buffered));
469 
470  // If the client cannot consume data as fast as we are sending it, we just
471  // buffer more and more data in the Qt socket code. So return and wait for
472  // the next write.
473  if (buffered > (HTTP_CHUNKSIZE << 1))
474  {
475  LOG(VB_HTTP, LOG_DEBUG, LOC + "Draining buffers");
476  return;
477  }
478 
479  if (m_totalSent >= m_totalToSend)
480  {
481  auto seconds = static_cast<double>(m_writeTime.nsecsElapsed()) / 1000000000.0;
482  auto rate = static_cast<uint64_t>(static_cast<double>(m_totalSent) / seconds);
483  LOG(VB_HTTP, LOG_INFO, LOC + QString("Wrote %1bytes in %2seconds (%3)")
484  .arg(m_totalSent).arg(seconds, 8, 'f', 6, '0')
485  .arg(MythHTTPWS::BitrateToString(rate)));
486 
487  if (m_queue.empty())
488  {
490  Stop();
492  SetupWebSocket();
493  return;
494  }
495  // This is going to be unrecoverable
496  LOG(VB_GENERAL, LOG_ERR, LOC + "Write complete but queue not empty");
497  Stop();
498  return;
499  }
500 
501  // Fill them buffers
502  int64_t available = HTTP_CHUNKSIZE;
503  while ((available > 0) && !m_queue.empty())
504  {
505  int64_t written = 0;
506  int64_t read = 0;
507  int64_t wrote = 0;
508  int64_t itemsize = 0;
509  int64_t towrite = 0;
510  bool chunk = false;
511  auto * data = std::get_if<HTTPData>(&m_queue.front());
512  auto * file = std::get_if<HTTPFile>(&m_queue.front());
513 
514  if (data)
515  {
516  chunk = (*data)->m_encoding == HTTPChunked;
517  written = (*data)->m_written;
518  itemsize = (*data)->m_partialSize > 0 ? (*data)->m_partialSize : static_cast<int64_t>((*data)->size());
519  towrite = std::min(itemsize - written, available);
520  int64_t offset = 0;
521  HTTPMulti multipart { nullptr, nullptr };
522  if (!(*data)->m_ranges.empty())
523  multipart = MythHTTPRanges::HandleRangeWrite(*data, available, towrite, offset);
524  if (chunk)
525  chunkheader(QStringLiteral("%1\r\n").arg(towrite, 0, 16).toLatin1().constData());
526  if (multipart.first)
527  wrote += m_socket->write(multipart.first->constData());
528  wrote += m_socket->write((*data)->constData() + written + offset, towrite);
529  if (multipart.second)
530  wrote += m_socket->write(multipart.second->constData());
531  if (chunk)
532  chunkheader("\r\n");
533  }
534  else if (file)
535  {
536  chunk = (*file)->m_encoding == HTTPChunked;
537  written = (*file)->m_written;
538  itemsize = (*file)->m_partialSize > 0 ? (*file)->m_partialSize : static_cast<int64_t>((*file)->size());
539  towrite = std::min(itemsize - written, available);
540  HTTPMulti multipart { nullptr, nullptr };
541  if (!(*file)->m_ranges.empty())
542  {
543  int64_t offset = 0;
544  multipart = MythHTTPRanges::HandleRangeWrite(*file, available, towrite, offset);
545  if (offset != (*file)->pos())
546  (*file)->seek(offset);
547  }
548  int64_t writebufsize = std::min(itemsize, static_cast<int64_t>(HTTP_CHUNKSIZE));
549  if (m_writeBuffer && (m_writeBuffer->size() < writebufsize))
550  m_writeBuffer = nullptr;
551  if (!m_writeBuffer)
552  m_writeBuffer = MythHTTPData::Create(static_cast<int>(writebufsize), '\0');
553  read = (*file)->read(m_writeBuffer->data(), towrite);
554  if (read > 0)
555  {
556  if (chunk)
557  chunkheader(QStringLiteral("%1\r\n").arg(read, 0, 16).toLatin1().constData());
558  if (multipart.first)
559  wrote += m_socket->write(multipart.first->constData());
560  wrote += m_socket->write(m_writeBuffer->data(), read);
561  if (multipart.second)
562  wrote += m_socket->write(multipart.second->constData());
563  if (chunk)
564  chunkheader("\r\n");
565  }
566  }
567 
568  if (wrote < 0 || read < 0)
569  {
570  LOG(VB_GENERAL, LOG_ERR, LOC + QString("Write error (Read: %1 Write: %2)")
571  .arg(read).arg(wrote));
572  Stop();
573  return;
574  }
575 
576  written += wrote;
577  if (data) (*data)->m_written = written;
578  if (file) (*file)->m_written = written;
579  m_totalWritten += wrote;
580  available -= wrote;
581 
582 #if 0
583  LOG(VB_HTTP, LOG_DEBUG, LOC + QString("Sent %1 bytes (cum: %2 of %3)")
584  .arg(wrote).arg(m_totalWritten).arg(m_totalToSend));
585 #endif
586 
587  // Move on to the next buffer?
588  if (written >= itemsize)
589  {
590  if (chunk)
591  chunkheader("0\r\n\r\n");
592  m_queue.pop_front();
593  m_writeBuffer = nullptr;
594  }
595  }
596 }
597 
601 {
602  // Disconnect and stop our read/write timer
603  m_timer.disconnect(this);
604  m_timer.stop();
605 
606  // Disconnect our socket read/writes
607  disconnect(m_socket, &QTcpSocket::readyRead, this, &MythHTTPSocket::Read);
608  disconnect(m_socket, &QTcpSocket::bytesWritten, this, &MythHTTPSocket::Write);
609 
610  // Create server websocket instance
612  if (!m_websocket)
613  {
614  LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to create websocket");
615  Stop();
616  return;
617  }
618  // Create event listener
620  if (!m_websocketevent)
621  {
622  LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to create websocket event listener");
623  Stop();
624  return;
625  }
626 
627  // Listen for messages
631 
632  // Sending messages
634 
635  // Add this thread to the list of upgraded threads, so we free up slots
636  // for regular HTTP sockets.
637  emit ThreadUpgraded(QThread::currentThread());
638 }
639 
641 {
642  if (!Text)
643  return;
645 }
646 
648 {
649  if (Payloads.empty())
650  return;
652 }
653 
655 {
656  if (Payloads.empty())
657  return;
658 }
HTTPChunked
@ HTTPChunked
Definition: mythhttptypes.h:137
MythHTTPSocket::m_config
MythHTTPConfig m_config
Definition: mythhttpsocket.h:56
MythHTTPSocket::Read
void Read()
Read data from the socket which is parsed by MythHTTPParser.
Definition: mythhttpsocket.cpp:214
StringPayload
std::shared_ptr< MythSharedString > StringPayload
Definition: mythhttpcommon.h:56
hardwareprofile.smolt.timeout
float timeout
Definition: smolt.py:103
MythHTTPResponse::UpgradeResponse
static HTTPResponse UpgradeResponse(const HTTPRequest2 &Request, MythSocketProtocol &Protocol, bool &Testing)
Definition: mythhttpresponse.cpp:371
MythHTTPSocket::m_writeTime
QElapsedTimer m_writeTime
Definition: mythhttpsocket.h:68
HTTPOK
@ HTTPOK
Definition: mythhttptypes.h:106
MythHTTPSocket::Finish
void Finish()
error
static void error(const char *str,...)
Definition: vbi.cpp:36
MythHTTPConfig::m_allowedOrigins
QStringList m_allowedOrigins
Definition: mythhttptypes.h:70
MythHTTPConfig::m_timeout
std::chrono::milliseconds m_timeout
Definition: mythhttptypes.h:67
MythHTTPSocket::ServicesChanged
void ServicesChanged(const HTTPServices &Services)
Definition: mythhttpsocket.cpp:124
MythHTTPSocket::m_totalSent
int64_t m_totalSent
Definition: mythhttpsocket.h:67
HTTP_CHUNKSIZE
#define HTTP_CHUNKSIZE
A group of functions shared between HTTP and WebSocket code.
Definition: mythhttpcommon.h:18
MythHTTPSocket::ThreadUpgraded
void ThreadUpgraded(QThread *Thread)
discid.disc.read
def read(device=None, features=[])
Definition: disc.py:35
MythHTTPSocket::Error
void Error(QAbstractSocket::SocketError Error)
Definition: mythhttpsocket.cpp:155
MythHTTPSocket::NewTextMessage
void NewTextMessage(const StringPayload &Text)
Definition: mythhttpsocket.cpp:640
build_compdb.content
content
Definition: build_compdb.py:38
MythHTTPSocket::m_websocket
MythWebSocket * m_websocket
Definition: mythhttpsocket.h:60
mythhttps.h
MythHTTP::GetHeader
static QString GetHeader(const HTTPHeaders &Headers, const QString &Value, const QString &Default="")
Definition: mythhttptypes.h:316
MythHTTPConfig::m_errorPageHandler
HTTPHandler m_errorPageHandler
Definition: mythhttptypes.h:74
mythhttpranges.h
MythHTTPSocket::m_timer
QTimer m_timer
Definition: mythhttpsocket.h:62
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
MythHTTPRanges::HandleRangeWrite
static HTTPMulti HandleRangeWrite(HTTPVariant Data, int64_t Available, int64_t &ToWrite, int64_t &Offset)
Definition: mythhttpranges.cpp:89
MythHTTPSocket::m_writeBuffer
HTTPData m_writeBuffer
Definition: mythhttpsocket.h:69
mythhttpsocket.h
MythHTTPSocket::Write
void Write(int64_t Written=0)
Definition: mythhttpsocket.cpp:438
build_compdb.file
file
Definition: build_compdb.py:55
mythhttpdata.h
MythHTTPConfig::m_sslConfig
QSslConfiguration m_sslConfig
Definition: mythhttptypes.h:76
MythHTTPSocket::m_websocketevent
MythWebSocketEvent * m_websocketevent
Definition: mythhttpsocket.h:74
MythHTTPSocket::UpdateServices
void UpdateServices(const HTTPServices &Services)
MythWebSocketEvent::HandleRawTextMessage
bool HandleRawTextMessage(const DataPayloads &Payloads)
Definition: mythwebsocketevent.cpp:15
HTTPNotFound
@ HTTPNotFound
Definition: mythhttptypes.h:114
MythHTTPSocket::m_totalWritten
int64_t m_totalWritten
Definition: mythhttpsocket.h:66
mythhttpfile.h
HTTPRequestTimeout
@ HTTPRequestTimeout
Definition: mythhttptypes.h:116
quit
@ quit
Definition: lirc_client.h:30
MythHTTPSocket::PathsChanged
void PathsChanged(const QStringList &Paths)
Update our list of recognised file paths.
Definition: mythhttpsocket.cpp:114
MythHTTPSocket::m_testSocket
bool m_testSocket
Definition: mythhttpsocket.h:73
MythHTTPFile::ProcessFile
static HTTPResponse ProcessFile(const HTTPRequest2 &Request)
Definition: mythhttpfile.cpp:35
mythlogging.h
HTTPMulti
std::pair< HTTPData, HTTPData > HTTPMulti
Definition: mythhttptypes.h:48
MythWebSocket::CreateWebsocket
static MythWebSocket * CreateWebsocket(bool Server, QTcpSocket *Socket, MythSocketProtocol Protocol, bool Testing)
Definition: mythwebsocket.cpp:31
MythHTTPConfig::m_filePaths
QStringList m_filePaths
Definition: mythhttptypes.h:71
MythWebSocketEvent::SendTextMessage
void SendTextMessage(const QString &)
MythHTTPData::Create
static HTTPData Create()
Definition: mythhttpdata.cpp:4
MythHTTPSocket::NewBinaryMessage
static void NewBinaryMessage(const DataPayloads &Payloads)
Definition: mythhttpsocket.cpp:654
MythHTTPServices
Definition: mythhttpservices.h:7
MythHTTPSocket::m_socket
QTcpSocket * m_socket
Definition: mythhttpsocket.h:59
LOC
#define LOC
Definition: mythhttpsocket.cpp:26
MythWebSocketEvent::HandleTextMessage
bool HandleTextMessage(const StringPayload &Text)
Definition: mythwebsocketevent.cpp:24
MythHTTPSocket::m_socketFD
qintptr m_socketFD
Definition: mythhttpsocket.h:55
MythHTTPResponse::ErrorResponse
static HTTPResponse ErrorResponse(MythHTTPStatus Status, const QString &ServerName)
Definition: mythhttpresponse.cpp:203
HTTPConnectionClose
@ HTTPConnectionClose
Definition: mythhttptypes.h:128
MythHTTPConfig::m_handlers
HTTPHandlers m_handlers
Definition: mythhttptypes.h:72
MythWebSocket::NewBinaryMessage
void NewBinaryMessage(const DataPayloads &Payloads)
MythHTTPSocket::Disconnected
void Disconnected()
The socket was disconnected.
Definition: mythhttpsocket.cpp:150
mythhttpresponse.h
MythHTTPSocket::m_protocol
MythSocketProtocol m_protocol
Definition: mythhttpsocket.h:71
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:54
MythHTTPSocket::HostsChanged
void HostsChanged(const QStringList &Hosts)
Definition: mythhttpsocket.cpp:140
MythHTTPParser::GetRequest
HTTPRequest2 GetRequest(const MythHTTPConfig &Config, QTcpSocket *Socket)
Definition: mythhttpparser.cpp:15
MythHTTPSocket::RespondDirect
static void RespondDirect(qintptr Socket, const HTTPResponse &Response, const MythHTTPConfig &Config)
Send an (error) response directly without creating a thread.
Definition: mythhttpsocket.cpp:423
MythWebSocket::NewTextMessage
void NewTextMessage(const StringPayload &Text)
MythHTTPServices::UpdateServices
void UpdateServices(const HTTPServices &Services)
Definition: mythhttpservices.cpp:14
HTTPResponse
std::shared_ptr< MythHTTPResponse > HTTPResponse
Definition: mythhttptypes.h:39
MythHTTPSocket::m_activeServices
HTTPServicePtrs m_activeServices
Definition: mythhttpsocket.h:57
MythHTTPSocket::m_queue
HTTPQueue m_queue
Definition: mythhttpsocket.h:64
MythWebSocket::NewRawTextMessage
void NewRawTextMessage(const DataPayloads &Payloads)
MythWebSocketEvent
Definition: mythwebsocketevent.h:6
MythWebSocket::Close
void Close()
Initiate the close handshake when we are exiting.
Definition: mythwebsocket.cpp:80
MythHTTPWS::BitrateToString
static QString BitrateToString(uint64_t Rate)
Definition: mythhttpcommon.h:76
mythcorecontext.h
MythHTTPS::InitSSLSocket
static void InitSSLSocket(QSslSocket *Socket, QSslConfiguration &Config)
Definition: mythhttps.cpp:118
MythHTTPSocket::MythHTTPSocket
MythHTTPSocket(qintptr Socket, bool SSL, MythHTTPConfig Config)
Definition: mythhttpsocket.cpp:28
MythHTTPConfig::m_hosts
QStringList m_hosts
Definition: mythhttptypes.h:69
MythHTTPSocket::m_nextConnection
MythHTTPConnection m_nextConnection
Definition: mythhttpsocket.h:70
std
Definition: mythchrono.h:23
HTTPRequest2
std::shared_ptr< MythHTTPRequest > HTTPRequest2
Definition: mythhttptypes.h:38
mythwebsocket.h
MythHTTPSocket::m_stopping
bool m_stopping
Definition: mythhttpsocket.h:58
mythhttprequest.h
HTTPConnectionUpgrade
@ HTTPConnectionUpgrade
Definition: mythhttptypes.h:130
MythHTTPSocket::Respond
void Respond(const HTTPResponse &Response)
Send response to client.
Definition: mythhttpsocket.cpp:363
MythHTTPConfig::m_services
HTTPServices m_services
Definition: mythhttptypes.h:73
MythHTTPSocket::m_totalToSend
int64_t m_totalToSend
Definition: mythhttpsocket.h:65
MythHTTPSocket::OriginsChanged
void OriginsChanged(const QStringList &Origins)
Update the list of allowed Origins.
Definition: mythhttpsocket.cpp:135
mythhttpservices.h
MythWebSocket::SendTextFrame
void SendTextFrame(const QString &Text)
Definition: mythwebsocket.cpp:85
MythHTTPSocket::SetupWebSocket
void SetupWebSocket()
Transition socket to a WebSocket.
Definition: mythhttpsocket.cpp:600
HTTPServices
std::vector< HTTPService > HTTPServices
Definition: mythhttptypes.h:54
MythHTTPSocket::~MythHTTPSocket
~MythHTTPSocket() override
Definition: mythhttpsocket.cpp:100
MythHTTPConfig
Definition: mythhttptypes.h:60
MythHTTPSocket::m_parser
MythHTTPParser m_parser
Definition: mythhttpsocket.h:63
MythHTTPSocket::NewRawTextMessage
void NewRawTextMessage(const DataPayloads &Payloads)
Definition: mythhttpsocket.cpp:647
mythwebsocketevent.h
MythCoreContext::CheckSubnet
bool CheckSubnet(const QAbstractSocket *socket)
Check if a socket is connected to an approved peer.
Definition: mythcorecontext.cpp:1266
MythHTTPSocket::Stop
void Stop()
Close the socket and quit the thread.
Definition: mythhttpsocket.cpp:194
MythHTTPSocket::HandlersChanged
void HandlersChanged(const HTTPHandlers &Handlers)
Definition: mythhttpsocket.cpp:119
MythHTTPParser::Read
bool Read(QTcpSocket *Socket, bool &Ready)
Definition: mythhttpparser.cpp:42
MythHTTPSocket::m_peer
QString m_peer
Definition: mythhttpsocket.h:61
HTTPHandlers
std::vector< HTTPHandler > HTTPHandlers
Definition: mythhttptypes.h:47
MythHTTPSocket::Timeout
void Timeout()
Close the socket after a period of inactivity.
Definition: mythhttpsocket.cpp:165
DataPayloads
std::vector< DataPayload > DataPayloads
Definition: mythhttpcommon.h:37
MythHTTPConfig::m_serverName
QString m_serverName
Definition: mythhttptypes.h:66