MythTV  master
serverSideScripting.cpp
Go to the documentation of this file.
1 // Program Name: serverSideScripting.cpp
3 // Created : Mar. 22, 2011
4 //
5 // Purpose : Server Side Scripting support for Html Server
6 //
7 // Copyright (c) 2011 David Blain <dblain@mythtv.org>
8 //
9 // Licensed under the GPL v2 or later, see COPYING for details
10 //
12 
13 #include <QCoreApplication>
14 #include <QFile>
15 #include <QFileInfo>
16 #include <QVariant>
17 #include <QVariantMap>
18 
19 #include "serverSideScripting.h"
20 #include "mythlogging.h"
21 #include <mythsession.h>
22 #include "httpserver.h"
23 
24 QScriptValue formatStr(QScriptContext *context, QScriptEngine *interpreter);
25 
27 //
29 
30 QScriptValue formatStr(QScriptContext *context, QScriptEngine *interpreter)
31 {
32  unsigned int count = context->argumentCount();
33 
34  if (count == 0)
35  return QScriptValue(interpreter, QString());
36 
37  if (count == 1)
38  return QScriptValue(interpreter, context->argument(0).toString());
39 
40  QString result = context->argument(0).toString();
41  for (unsigned int i = 1; i < count; i++)
42  result.replace(QString("%%1").arg(i), context->argument(i).toString());
43 
44  return QScriptValue(interpreter, result);
45 }
46 
48 //
50 
52 {
53  Lock();
54 
55 #ifdef _WIN32
56  m_debugger.attachTo( &m_engine );
57 #endif
58 
59  // ----------------------------------------------------------------------
60  // Enable Translation functions
61  // ----------------------------------------------------------------------
62 
63  m_engine.installTranslatorFunctions();
64 
65  // ----------------------------------------------------------------------
66  // Register C++ functions
67  // ----------------------------------------------------------------------
68 
69  QScriptValue qsFormatStr = m_engine.newFunction(formatStr);
70  m_engine.globalObject().setProperty("formatStr", qsFormatStr);
71 
72  // ----------------------------------------------------------------------
73  // Add Scriptable Objects
74  // ----------------------------------------------------------------------
75 
76  // Q_SCRIPT_DECLARE_QMETAOBJECT( DTC::MythService, QObject*)
77  // QScriptValue oClass = engine.scriptValueFromQMetaObject< DTC::MythService >();
78  // engine.globalObject().setProperty("Myth", oClass);
79  Unlock();
80 }
81 
83 //
85 
87 {
88  Lock();
89 
90  for (const auto *script : qAsConst(m_mapScripts))
91  delete script;
92 
93  m_mapScripts.clear();
94  Unlock();
95 }
96 
98 //
100 
101 QString ServerSideScripting::SetResourceRootPath( const QString &path )
102 {
103  Lock();
104  QString sOrig = m_sResRootPath;
105 
106  m_sResRootPath = path;
107  Unlock();
108 
109  return sOrig;
110 }
111 
113 //
115 
117  const QMetaObject *pMetaObject,
118  QScriptEngine::FunctionSignature pFunction)
119 {
120  Lock();
121  QScriptValue ctor = m_engine.newFunction( pFunction );
122 
123  QScriptValue metaObject = m_engine.newQMetaObject( pMetaObject, ctor );
124  m_engine.globalObject().setProperty( sName, metaObject );
125  Unlock();
126 }
127 
129 //
131 
133 {
134  ScriptInfo *pInfo = nullptr;
135 
136  Lock();
137 
138  if ( m_mapScripts.contains( sFileName ) )
139  pInfo = m_mapScripts[ sFileName ];
140 
141  Unlock();
142 
143  return pInfo;
144 }
145 
147 //
149 
150 bool ServerSideScripting::EvaluatePage( QTextStream *pOutStream, const QString &sFileName,
151  HTTPRequest *pRequest, const QByteArray &cspToken)
152 {
153  try
154  {
155 
156  ScriptInfo *pInfo = nullptr;
157 
158  // ------------------------------------------------------------------
159  // See if page has already been loaded
160  // ------------------------------------------------------------------
161 
162  pInfo = GetLoadedScript( sFileName );
163 
164  // ------------------------------------------------------------------
165  // Load Script File and Create Function
166  // ------------------------------------------------------------------
167 
168  QFileInfo fileInfo ( sFileName );
169  QDateTime dtLastModified = fileInfo.lastModified();
170 
171  Lock();
172  if ((pInfo == nullptr) || (pInfo->m_dtTimeStamp != dtLastModified ))
173  {
174  QString sCode = CreateMethodFromFile( sFileName );
175 
176  QScriptValue func = m_engine.evaluate( sCode, sFileName );
177 
178  if ( m_engine.hasUncaughtException() )
179  {
180  LOG(VB_GENERAL, LOG_ERR,
181  QString("Uncaught exception loading QSP File: %1 - (line %2) %3")
182  .arg(sFileName)
183  .arg(m_engine.uncaughtExceptionLineNumber())
184  .arg(m_engine.uncaughtException().toString()));
185 
186  Unlock();
187  return false;
188  }
189 
190  if (pInfo != nullptr)
191  {
192  pInfo->m_oFunc = func;
193  pInfo->m_dtTimeStamp = dtLastModified;
194  }
195  else
196  {
197  pInfo = new ScriptInfo( func, dtLastModified );
198  m_mapScripts[ sFileName ] = pInfo;
199  }
200  }
201 
202  // ------------------------------------------------------------------
203  // Build array of arguments passed to script
204  // ------------------------------------------------------------------
205 
206  QStringMap mapParams = pRequest->m_mapParams;
207 
208  // Valid characters for object property names must contain only
209  // word characters and numbers, _ and $
210  // They must not start with a number - to simplify the regexp, we
211  // restrict the first character to the English alphabet
212  QRegExp validChars = QRegExp(R"(^([a-zA-Z]|_|\$)(\w|\$)+$)");
213 
214  QVariantMap params;
215  QString prevArrayName = "";
216  QVariantMap array;
217  for (auto it = mapParams.cbegin(); it != mapParams.cend(); ++it)
218  {
219  const QString& key = it.key();
220  QVariant value = QVariant(it.value());
221 
222  // PHP Style parameter array
223  if (key.contains("["))
224  {
225  QString arrayName = key.section('[',0,0);
226  QString arrayKey = key.section('[',1,1);
227  arrayKey.chop(1); // Remove trailing ]
228  if (prevArrayName != arrayName) // New or different array
229  {
230  if (!array.isEmpty())
231  {
232  params.insert(prevArrayName, QVariant(array));
233  array.clear();
234  }
235  prevArrayName = arrayName;
236  }
237 
238  if (!validChars.exactMatch(arrayKey)) // Discard anything that isn't valid for now
239  continue;
240 
241  array.insert(arrayKey, value);
242 
243  if ((it + 1) != mapParams.cend())
244  continue;
245  }
246 
247  if (!array.isEmpty())
248  {
249  params.insert(prevArrayName, QVariant(array));
250  array.clear();
251  }
252  // End Array handling
253 
254  if (!validChars.exactMatch(key)) // Discard anything that isn't valid for now
255  continue;
256 
257  params.insert(key, value);
258 
259  }
260 
261  // ------------------------------------------------------------------
262  // Build array of request headers
263  // ------------------------------------------------------------------
264 
265  QStringMap mapHeaders = pRequest->m_mapHeaders;
266 
267  QVariantMap requestHeaders;
268  for (auto it = mapHeaders.begin(); it != mapHeaders.end(); ++it)
269  {
270  QString key = it.key();
271  key = key.replace('-', '_'); // May be other valid chars in a request header that we need to replace
272  QVariant value = QVariant(it.value());
273 
274  if (!validChars.exactMatch(key)) // Discard anything that isn't valid for now
275  continue;
276 
277  requestHeaders.insert(key, value);
278  }
279 
280  // ------------------------------------------------------------------
281  // Build array of cookies
282  // ------------------------------------------------------------------
283 
284  QStringMap mapCookies = pRequest->m_mapCookies;
285 
286  QVariantMap requestCookies;
287  for (auto it = mapCookies.begin(); it != mapCookies.end(); ++it)
288  {
289  QString key = it.key();
290  key = key.replace('-', '_'); // May be other valid chars in a request header that we need to replace
291  QVariant value = QVariant(it.value());
292 
293  if (!validChars.exactMatch(key)) // Discard anything that isn't valid for now
294  continue;
295 
296  requestCookies.insert(key, value);
297  }
298 
299  // ------------------------------------------------------------------
300  // Build array of information from the server e.g. client IP
301  // See RFC 3875 - The Common Gateway Interface
302  // ------------------------------------------------------------------
303 
304  QVariantMap serverVars;
305  //serverVars.insert("QUERY_STRING", QVariant())
306  serverVars.insert("REQUEST_METHOD", QVariant(pRequest->GetRequestType()));
307  serverVars.insert("SCRIPT_NAME", QVariant(sFileName));
308  serverVars.insert("REMOTE_ADDR", QVariant(pRequest->GetPeerAddress()));
309  serverVars.insert("SERVER_NAME", QVariant(pRequest->GetHostName()));
310  serverVars.insert("SERVER_PORT", QVariant(pRequest->GetHostPort()));
311  serverVars.insert("SERVER_PROTOCOL", QVariant(pRequest->GetRequestProtocol()));
312  serverVars.insert("SERVER_SOFTWARE", QVariant(HttpServer::GetServerVersion()));
313 
314  QHostAddress clientIP = QHostAddress(pRequest->GetPeerAddress());
315  QHostAddress serverIP = QHostAddress(pRequest->GetHostAddress());
316  if (clientIP.protocol() == QAbstractSocket::IPv4Protocol)
317  {
318  serverVars.insert("IP_PROTOCOL", "IPv4");
319  }
320  else if (clientIP.protocol() == QAbstractSocket::IPv6Protocol)
321  {
322  serverVars.insert("IP_PROTOCOL", "IPv6");
323  }
324 
325  if (((clientIP.protocol() == QAbstractSocket::IPv4Protocol) &&
326  (clientIP.isInSubnet(QHostAddress("172.16.0.0"), 12) ||
327  clientIP.isInSubnet(QHostAddress("192.168.0.0"), 16) ||
328  clientIP.isInSubnet(QHostAddress("10.0.0.0"), 8))) ||
329  ((clientIP.protocol() == QAbstractSocket::IPv6Protocol) &&
330  clientIP.isInSubnet(serverIP, 64))) // default subnet size is assumed to be /64
331  {
332  serverVars.insert("CLIENT_NETWORK", "local");
333  }
334  else
335  {
336  serverVars.insert("CLIENT_NETWORK", "remote");
337  }
338 
339  // ------------------------------------------------------------------
340  // User Session information
341  //
342  // SECURITY
343  // The session token and password digest are considered sensitive on
344  // unencrypted connections and therefore must never be included in the
345  // HTML. An intercepted session token or password digest can be used
346  // to login or hijack an existing session.
347  // ------------------------------------------------------------------
348  MythUserSession session = pRequest->m_userSession;
349  QVariantMap sessionVars;
350  sessionVars.insert("username", session.GetUserName());
351  sessionVars.insert("userid", session.GetUserId());
352  sessionVars.insert("created", session.GetSessionCreated());
353  sessionVars.insert("lastactive", session.GetSessionLastActive());
354  sessionVars.insert("expires", session.GetSessionExpires());
355 
356  // ------------------------------------------------------------------
357  // Add the arrays (objects) we've just created to the global scope
358  // They may be accessed as 'Server.REMOTE_ADDR'
359  // ------------------------------------------------------------------
360 
361  m_engine.globalObject().setProperty("Parameters",
362  m_engine.toScriptValue(params));
363  m_engine.globalObject().setProperty("RequestHeaders",
364  m_engine.toScriptValue(requestHeaders));
365  QVariantMap respHeaderMap;
366  m_engine.globalObject().setProperty("ResponseHeaders",
367  m_engine.toScriptValue(respHeaderMap));
368  m_engine.globalObject().setProperty("Server",
369  m_engine.toScriptValue(serverVars));
370  m_engine.globalObject().setProperty("Session",
371  m_engine.toScriptValue(sessionVars));
372  QScriptValue qsCspToken = m_engine.toScriptValue(cspToken);
373  m_engine.globalObject().setProperty("CSP_NONCE", qsCspToken);
374 
375 
376  // ------------------------------------------------------------------
377  // Execute function to render output
378  // ------------------------------------------------------------------
379 
380  OutputStream outStream( pOutStream );
381 
382  QScriptValueList args;
383  args << m_engine.newQObject( &outStream );
384  args << m_engine.toScriptValue(params);
385 
386  QScriptValue ret = pInfo->m_oFunc.call( QScriptValue(), args );
387 
388  if (ret.isError())
389  {
390  QScriptValue lineNo = ret.property( "lineNumber" );
391 
392  LOG(VB_GENERAL, LOG_ERR,
393  QString("Error calling QSP File: %1(%2) - %3")
394  .arg(sFileName)
395  .arg( lineNo.toInt32 () )
396  .arg( ret .toString() ));
397  Unlock();
398  return false;
399 
400  }
401 
402  if (m_engine.hasUncaughtException())
403  {
404  LOG(VB_GENERAL, LOG_ERR,
405  QString("Uncaught exception calling QSP File: %1(%2) - %3")
406  .arg(sFileName)
407  .arg(m_engine.uncaughtExceptionLineNumber() )
408  .arg(m_engine.uncaughtException().toString()));
409  Unlock();
410  return false;
411  }
412  Unlock();
413  }
414  catch(...)
415  {
416  LOG(VB_GENERAL, LOG_ERR,
417  QString("Exception while evaluating QSP File: %1") .arg(sFileName));
418 
419  Unlock();
420  return false;
421  }
422 
423  // Apply any custom headers defined by the script
424  QVariantMap responseHeaders;
425  responseHeaders = m_engine.fromScriptValue< QVariantMap >
426  (m_engine.globalObject().property("ResponseHeaders"));
427  QVariantMap::iterator it;
428  for (it = responseHeaders.begin(); it != responseHeaders.end(); ++it)
429  {
430  pRequest->SetResponseHeader(it.key(), it.value().toString(), true);
431  }
432 
433  return true;
434 }
435 
437 //
439 
440 QString ServerSideScripting::CreateMethodFromFile( const QString &sFileName ) const
441 {
442  bool bInCode = false;
443  QString sBuffer;
444  QTextStream sCode( &sBuffer );
445 
446  QFile scriptFile( sFileName );
447 
448  if (!scriptFile.open( QIODevice::ReadOnly ))
449  throw "Unable to open file";
450 
451  try
452  {
453  QTextStream stream( &scriptFile );
454  QString sTransBuffer;
455 
456  sCode << "(function( os, ARGS ) {\n";
457  sCode << "try {\n";
458 
459  while( !stream.atEnd() )
460  {
461  QString sLine = stream.readLine();
462 
463  bInCode = ProcessLine( sCode, sLine, bInCode, sTransBuffer );
464  }
465 
466  sCode << "} catch( err ) { return err; }\n";
467  sCode << "})";
468  }
469  catch(...)
470  {
471  LOG(VB_GENERAL, LOG_ERR,
472  QString("Exception while reading QSP File: %1") .arg(sFileName));
473  }
474 
475  scriptFile.close();
476 
477  sCode.flush();
478 
479  return sBuffer;
480 }
481 
483 //
485 
486 QString ServerSideScripting::ReadFileContents( const QString &sFileName )
487 {
488  QString sCode;
489  QFile scriptFile( sFileName );
490 
491  if (!scriptFile.open( QIODevice::ReadOnly ))
492  throw "Unable to open file";
493 
494  try
495  {
496  QTextStream stream( &scriptFile );
497 
498  sCode = stream.readAll();
499  }
500  catch(...)
501  {
502  LOG(VB_GENERAL, LOG_ERR,
503  QString("Exception while Reading File Contents File: %1") .arg(sFileName));
504  }
505 
506  scriptFile.close();
507 
508  return sCode;
509 }
510 
512 //
514 
515 bool ServerSideScripting::ProcessLine( QTextStream &sCode,
516  QString &sLine,
517  bool bInCode,
518  QString &sTransBuffer ) const
519 {
520  QString sLowerLine = sLine.toLower();
521 
522  if (!sTransBuffer.isEmpty())
523  {
524  int nEndTransPos = sLowerLine.indexOf("</i18n>");
525 
526  if (nEndTransPos == -1)
527  {
528  sTransBuffer.append(" ");
529  sTransBuffer.append(sLine);
530  return bInCode;
531  }
532 
533  if (nEndTransPos > 0)
534  sTransBuffer.append(" ");
535 
536  sTransBuffer.append(sLine.left(nEndTransPos).trimmed());
537  QString trStr =
538  QCoreApplication::translate("HtmlUI", sTransBuffer.trimmed().toLocal8Bit().data());
539  trStr.replace( '"', "\\\"" );
540  sCode << "os.write( \"" << trStr << "\" );\n";
541  sTransBuffer = "";
542 
543  if (nEndTransPos == (sLine.length() - 7))
544  return bInCode;
545 
546  sLine = sLine.right(sLine.length() - (nEndTransPos + 7));
547  }
548 
549  int nStartTransPos = sLowerLine.indexOf("<i18n>");
550  if (nStartTransPos != -1)
551  {
552  int nEndTransPos = sLowerLine.indexOf("</i18n>");
553  if (nEndTransPos != -1)
554  {
555  QString patStr = sLine.mid(nStartTransPos,
556  (nEndTransPos + 7 - nStartTransPos));
557  QString repStr = patStr.mid(6, patStr.length() - 13).trimmed();
558  sLine.replace(patStr, QCoreApplication::translate("HtmlUI", repStr.toLocal8Bit().data()));
559  return ProcessLine(sCode, sLine, bInCode, sTransBuffer);
560  }
561 
562  sTransBuffer = " ";
563  sTransBuffer.append(sLine.mid(nStartTransPos + 6).trimmed());
564  sLine = sLine.left(nStartTransPos);
565  }
566 
567  int nStartPos = 0;
568  int nEndPos = 0;
569  int nMatchPos = 0;
570  bool bMatchFound = false;
571 
572  QString sExpecting = bInCode ? "%>" : "<%";
573  bool bNewLine = !(sLine.startsWith( sExpecting ));
574 
575  while (nStartPos < sLine.length())
576  {
577  nEndPos = sLine.length() - 1;
578 
579  sExpecting = bInCode ? "%>" : "<%";
580  nMatchPos = sLine.indexOf( sExpecting, nStartPos );
581 
582  // ------------------------------------------------------------------
583  // If not found, Adjust to Save entire line
584  // ------------------------------------------------------------------
585 
586  if (nMatchPos < 0)
587  {
588  nMatchPos = nEndPos + 1;
589  bMatchFound = false;
590  }
591  else
592  bMatchFound = true;
593 
594  // ------------------------------------------------------------------
595  // Add Code or Text to Line
596  // ------------------------------------------------------------------
597 
598  QString sSegment = sLine.mid( nStartPos, nMatchPos - nStartPos );
599 
600  if ( !sSegment.isEmpty())
601  {
602  if (bInCode)
603  {
604  // Add Code
605 
606  if (sSegment.startsWith( "=" ))
607  {
608  // Evaluate statement and render results.
609 
610  sCode << "os.write( " << sSegment.mid( 1 ) << " ); "
611  << "\n";
612  }
613  else if (sSegment.startsWith( "import" ))
614  {
615  // Loads supplied path as script file.
616  //
617  // Syntax: import "/relative/path/to/script.js"
618  // - must be at start of line (no leading spaces)
619  //
620 
621  // Extract filename (remove quotes)
622 
623 #if QT_VERSION < QT_VERSION_CHECK(5,14,0)
624  QStringList sParts = sSegment.split( ' ', QString::SkipEmptyParts );
625 #else
626  QStringList sParts = sSegment.split( ' ', Qt::SkipEmptyParts );
627 #endif
628 
629  if (sParts.length() > 1 )
630  {
631  QString sFileName = sParts[1].mid( 1, sParts[1].length() - 2 );
632 
633  QFileInfo oInfo( m_sResRootPath + sFileName );
634 
635  if (oInfo.exists())
636  {
637  sCode << ReadFileContents( oInfo.canonicalFilePath() )
638  << "\n";
639  }
640  else
641  {
642  LOG(VB_GENERAL, LOG_ERR,
643  QString("ServerSideScripting::ProcessLine 'import' - File not found: %1%2")
645  .arg(sFileName));
646  }
647  }
648  else
649  {
650  LOG(VB_GENERAL, LOG_ERR,
651  QString("ServerSideScripting::ProcessLine 'import' - Malformed [%1]")
652  .arg( sSegment ));
653  }
654 
655  }
656  else
657  sCode << sSegment << "\n";
658 
659  if (bMatchFound)
660  bInCode = false;
661  }
662  else
663  {
664  // Add Text
665 
666  sSegment.replace( '"', "\\\"" );
667 
668  sCode << "os.write( \"" << sSegment << "\" );\n";
669 
670  if (bMatchFound)
671  bInCode = true;
672  }
673  }
674  else
675  {
676  if (bMatchFound)
677  bInCode = !bInCode;
678  }
679 
680  nStartPos = nMatchPos + 2;
681  }
682 
683  if ((bNewLine) && !bInCode )
684  sCode << "os.writeln( \"\" );\n";
685 
686  return bInCode;
687 }
ScriptInfo::m_dtTimeStamp
QDateTime m_dtTimeStamp
Definition: serverSideScripting.h:40
build_compdb.args
args
Definition: build_compdb.py:11
fileInfo
QFileInfo fileInfo(filename)
HTTPRequest
Definition: httprequest.h:108
HTTPRequest::GetHostPort
virtual quint16 GetHostPort()=0
HttpServer::GetServerVersion
static QString GetServerVersion(void)
Definition: httpserver.cpp:288
ScriptInfo::m_oFunc
QScriptValue m_oFunc
Definition: serverSideScripting.h:39
HTTPRequest::GetPeerAddress
virtual QString GetPeerAddress()=0
arg
arg(title).arg(filename).arg(doDelete))
ServerSideScripting::m_sResRootPath
QString m_sResRootPath
Definition: serverSideScripting.h:75
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23
HTTPRequest::m_userSession
MythUserSession m_userSession
Definition: httprequest.h:160
formatStr
QScriptValue formatStr(QScriptContext *context, QScriptEngine *interpreter)
Definition: serverSideScripting.cpp:30
ServerSideScripting::ReadFileContents
static QString ReadFileContents(const QString &sFileName)
Definition: serverSideScripting.cpp:486
ServerSideScripting::m_engine
QScriptEngine m_engine
Definition: serverSideScripting.h:53
MythUserSession
Definition: mythsession.h:17
mythlogging.h
MythUserSession::GetUserId
uint GetUserId(void) const
Definition: mythsession.h:36
ServerSideScripting::ServerSideScripting
ServerSideScripting()
Definition: serverSideScripting.cpp:51
HTTPRequest::m_mapParams
QStringMap m_mapParams
Definition: httprequest.h:129
QStringMap
QMap< QString, QString > QStringMap
Definition: upnputil.h:44
serverSideScripting.h
ServerSideScripting::GetLoadedScript
ScriptInfo * GetLoadedScript(const QString &sFileName)
Definition: serverSideScripting.cpp:132
ServerSideScripting::RegisterMetaObjectType
void RegisterMetaObjectType(const QString &sName, const QMetaObject *pMetaObject, QScriptEngine::FunctionSignature pFunction)
Definition: serverSideScripting.cpp:116
MythUserSession::GetSessionLastActive
QDateTime GetSessionLastActive() const
Definition: mythsession.h:42
HTTPRequest::GetHostName
virtual QString GetHostName()
Definition: httprequest.cpp:2194
MythUserSession::GetSessionExpires
QDateTime GetSessionExpires() const
Definition: mythsession.h:43
ServerSideScripting::~ServerSideScripting
~ServerSideScripting()
Definition: serverSideScripting.cpp:86
ServerSideScripting::m_debugger
QScriptEngineDebugger m_debugger
Definition: serverSideScripting.h:56
MythUserSession::GetSessionCreated
QDateTime GetSessionCreated() const
Definition: mythsession.h:41
HTTPRequest::SetResponseHeader
void SetResponseHeader(const QString &sKey, const QString &sValue, bool replace=false)
Definition: httprequest.cpp:2140
OutputStream
Definition: serverSideScripting.h:94
HTTPRequest::GetRequestProtocol
QString GetRequestProtocol() const
Definition: httprequest.cpp:892
ServerSideScripting::SetResourceRootPath
QString SetResourceRootPath(const QString &path)
Definition: serverSideScripting.cpp:101
ServerSideScripting::Lock
void Lock()
Definition: serverSideScripting.h:77
HTTPRequest::m_mapHeaders
QStringMap m_mapHeaders
Definition: httprequest.h:130
ServerSideScripting::EvaluatePage
bool EvaluatePage(QTextStream *pOutStream, const QString &sFileName, HTTPRequest *pRequest, const QByteArray &cspToken)
Definition: serverSideScripting.cpp:150
ServerSideScripting::Unlock
void Unlock()
Definition: serverSideScripting.h:78
httpserver.h
ScriptInfo
Definition: serverSideScripting.h:37
HTTPRequest::GetHostAddress
virtual QString GetHostAddress()=0
ServerSideScripting::ProcessLine
bool ProcessLine(QTextStream &sCode, QString &sLine, bool bInCode, QString &sTransBuffer) const
Definition: serverSideScripting.cpp:515
MythUserSession::GetUserName
QString GetUserName(void) const
Definition: mythsession.h:35
mythsession.h
ServerSideScripting::m_mapScripts
QMap< QString, ScriptInfo * > m_mapScripts
Definition: serverSideScripting.h:74
HTTPRequest::GetRequestType
QString GetRequestType() const
Definition: httprequest.cpp:2220
ServerSideScripting::CreateMethodFromFile
QString CreateMethodFromFile(const QString &sFileName) const
Definition: serverSideScripting.cpp:440
HTTPRequest::m_mapCookies
QStringMap m_mapCookies
Definition: httprequest.h:131