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  static const QRegularExpression validChars {
213  R"(^([a-zA-Z]|_|\$)(\w|\$)+$)",
214  QRegularExpression::UseUnicodePropertiesOption };
215 
216  QVariantMap params;
217  QString prevArrayName = "";
218  QVariantMap array;
219  for (auto it = mapParams.cbegin(); it != mapParams.cend(); ++it)
220  {
221  const QString& key = it.key();
222  QVariant value = QVariant(it.value());
223 
224  // PHP Style parameter array
225  if (key.contains("["))
226  {
227  QString arrayName = key.section('[',0,0);
228  QString arrayKey = key.section('[',1,1);
229  arrayKey.chop(1); // Remove trailing ]
230  if (prevArrayName != arrayName) // New or different array
231  {
232  if (!array.isEmpty())
233  {
234  params.insert(prevArrayName, QVariant(array));
235  array.clear();
236  }
237  prevArrayName = arrayName;
238  }
239 
240  auto match = validChars.match(arrayKey);
241  if (!match.hasMatch()) // Discard anything that isn't valid for now
242  continue;
243 
244  array.insert(arrayKey, value);
245 
246  if ((it + 1) != mapParams.cend())
247  continue;
248  }
249 
250  if (!array.isEmpty())
251  {
252  params.insert(prevArrayName, QVariant(array));
253  array.clear();
254  }
255  // End Array handling
256 
257  auto match = validChars.match(key);
258  if (!match.hasMatch()) // Discard anything that isn't valid for now
259  continue;
260 
261  params.insert(key, value);
262 
263  }
264 
265  // ------------------------------------------------------------------
266  // Build array of request headers
267  // ------------------------------------------------------------------
268 
269  QStringMap mapHeaders = pRequest->m_mapHeaders;
270 
271  QVariantMap requestHeaders;
272  for (auto it = mapHeaders.begin(); it != mapHeaders.end(); ++it)
273  {
274  QString key = it.key();
275  key = key.replace('-', '_'); // May be other valid chars in a request header that we need to replace
276  QVariant value = QVariant(it.value());
277 
278  auto match = validChars.match(key);
279  if (!match.hasMatch()) // Discard anything that isn't valid for now
280  continue;
281 
282  requestHeaders.insert(key, value);
283  }
284 
285  // ------------------------------------------------------------------
286  // Build array of cookies
287  // ------------------------------------------------------------------
288 
289  QStringMap mapCookies = pRequest->m_mapCookies;
290 
291  QVariantMap requestCookies;
292  for (auto it = mapCookies.begin(); it != mapCookies.end(); ++it)
293  {
294  QString key = it.key();
295  key = key.replace('-', '_'); // May be other valid chars in a request header that we need to replace
296  QVariant value = QVariant(it.value());
297 
298  auto match = validChars.match(key);
299  if (!match.hasMatch()) // Discard anything that isn't valid for now
300  continue;
301 
302  requestCookies.insert(key, value);
303  }
304 
305  // ------------------------------------------------------------------
306  // Build array of information from the server e.g. client IP
307  // See RFC 3875 - The Common Gateway Interface
308  // ------------------------------------------------------------------
309 
310  QVariantMap serverVars;
311  //serverVars.insert("QUERY_STRING", QVariant())
312  serverVars.insert("REQUEST_METHOD", QVariant(pRequest->GetRequestType()));
313  serverVars.insert("SCRIPT_NAME", QVariant(sFileName));
314  serverVars.insert("REMOTE_ADDR", QVariant(pRequest->GetPeerAddress()));
315  serverVars.insert("SERVER_NAME", QVariant(pRequest->GetHostName()));
316  serverVars.insert("SERVER_PORT", QVariant(pRequest->GetHostPort()));
317  serverVars.insert("SERVER_PROTOCOL", QVariant(pRequest->GetRequestProtocol()));
318  serverVars.insert("SERVER_SOFTWARE", QVariant(HttpServer::GetServerVersion()));
319 
320  QHostAddress clientIP = QHostAddress(pRequest->GetPeerAddress());
321  QHostAddress serverIP = QHostAddress(pRequest->GetHostAddress());
322  if (clientIP.protocol() == QAbstractSocket::IPv4Protocol)
323  {
324  serverVars.insert("IP_PROTOCOL", "IPv4");
325  }
326  else if (clientIP.protocol() == QAbstractSocket::IPv6Protocol)
327  {
328  serverVars.insert("IP_PROTOCOL", "IPv6");
329  }
330 
331  if (((clientIP.protocol() == QAbstractSocket::IPv4Protocol) &&
332  (clientIP.isInSubnet(QHostAddress("172.16.0.0"), 12) ||
333  clientIP.isInSubnet(QHostAddress("192.168.0.0"), 16) ||
334  clientIP.isInSubnet(QHostAddress("10.0.0.0"), 8))) ||
335  ((clientIP.protocol() == QAbstractSocket::IPv6Protocol) &&
336  clientIP.isInSubnet(serverIP, 64))) // default subnet size is assumed to be /64
337  {
338  serverVars.insert("CLIENT_NETWORK", "local");
339  }
340  else
341  {
342  serverVars.insert("CLIENT_NETWORK", "remote");
343  }
344 
345  // ------------------------------------------------------------------
346  // User Session information
347  //
348  // SECURITY
349  // The session token and password digest are considered sensitive on
350  // unencrypted connections and therefore must never be included in the
351  // HTML. An intercepted session token or password digest can be used
352  // to login or hijack an existing session.
353  // ------------------------------------------------------------------
354  MythUserSession session = pRequest->m_userSession;
355  QVariantMap sessionVars;
356  sessionVars.insert("username", session.GetUserName());
357  sessionVars.insert("userid", session.GetUserId());
358  sessionVars.insert("created", session.GetSessionCreated());
359  sessionVars.insert("lastactive", session.GetSessionLastActive());
360  sessionVars.insert("expires", session.GetSessionExpires());
361 
362  // ------------------------------------------------------------------
363  // Add the arrays (objects) we've just created to the global scope
364  // They may be accessed as 'Server.REMOTE_ADDR'
365  // ------------------------------------------------------------------
366 
367  m_engine.globalObject().setProperty("Parameters",
368  m_engine.toScriptValue(params));
369  m_engine.globalObject().setProperty("RequestHeaders",
370  m_engine.toScriptValue(requestHeaders));
371  QVariantMap respHeaderMap;
372  m_engine.globalObject().setProperty("ResponseHeaders",
373  m_engine.toScriptValue(respHeaderMap));
374  m_engine.globalObject().setProperty("Server",
375  m_engine.toScriptValue(serverVars));
376  m_engine.globalObject().setProperty("Session",
377  m_engine.toScriptValue(sessionVars));
378  QScriptValue qsCspToken = m_engine.toScriptValue(cspToken);
379  m_engine.globalObject().setProperty("CSP_NONCE", qsCspToken);
380 
381 
382  // ------------------------------------------------------------------
383  // Execute function to render output
384  // ------------------------------------------------------------------
385 
386  OutputStream outStream( pOutStream );
387 
388  QScriptValueList args;
389  args << m_engine.newQObject( &outStream );
390  args << m_engine.toScriptValue(params);
391 
392  QScriptValue ret = pInfo->m_oFunc.call( QScriptValue(), args );
393 
394  if (ret.isError())
395  {
396  QScriptValue lineNo = ret.property( "lineNumber" );
397 
398  LOG(VB_GENERAL, LOG_ERR,
399  QString("Error calling QSP File: %1(%2) - %3")
400  .arg(sFileName)
401  .arg( lineNo.toInt32 () )
402  .arg( ret .toString() ));
403  Unlock();
404  return false;
405 
406  }
407 
408  if (m_engine.hasUncaughtException())
409  {
410  LOG(VB_GENERAL, LOG_ERR,
411  QString("Uncaught exception calling QSP File: %1(%2) - %3")
412  .arg(sFileName)
413  .arg(m_engine.uncaughtExceptionLineNumber() )
414  .arg(m_engine.uncaughtException().toString()));
415  Unlock();
416  return false;
417  }
418  Unlock();
419  }
420  catch(...)
421  {
422  LOG(VB_GENERAL, LOG_ERR,
423  QString("Exception while evaluating QSP File: %1") .arg(sFileName));
424 
425  Unlock();
426  return false;
427  }
428 
429  // Apply any custom headers defined by the script
430  QVariantMap responseHeaders;
431  responseHeaders = m_engine.fromScriptValue< QVariantMap >
432  (m_engine.globalObject().property("ResponseHeaders"));
433  QVariantMap::iterator it;
434  for (it = responseHeaders.begin(); it != responseHeaders.end(); ++it)
435  {
436  pRequest->SetResponseHeader(it.key(), it.value().toString(), true);
437  }
438 
439  return true;
440 }
441 
443 //
445 
446 QString ServerSideScripting::CreateMethodFromFile( const QString &sFileName ) const
447 {
448  bool bInCode = false;
449  QString sBuffer;
450  QTextStream sCode( &sBuffer );
451 
452  QFile scriptFile( sFileName );
453 
454  if (!scriptFile.open( QIODevice::ReadOnly ))
455  throw "Unable to open file";
456 
457  try
458  {
459  QTextStream stream( &scriptFile );
460  QString sTransBuffer;
461 
462  sCode << "(function( os, ARGS ) {\n";
463  sCode << "try {\n";
464 
465  while( !stream.atEnd() )
466  {
467  QString sLine = stream.readLine();
468 
469  bInCode = ProcessLine( sCode, sLine, bInCode, sTransBuffer );
470  }
471 
472  sCode << "} catch( err ) { return err; }\n";
473  sCode << "})";
474  }
475  catch(...)
476  {
477  LOG(VB_GENERAL, LOG_ERR,
478  QString("Exception while reading QSP File: %1") .arg(sFileName));
479  }
480 
481  scriptFile.close();
482 
483  sCode.flush();
484 
485  return sBuffer;
486 }
487 
489 //
491 
492 QString ServerSideScripting::ReadFileContents( const QString &sFileName )
493 {
494  QString sCode;
495  QFile scriptFile( sFileName );
496 
497  if (!scriptFile.open( QIODevice::ReadOnly ))
498  throw "Unable to open file";
499 
500  try
501  {
502  QTextStream stream( &scriptFile );
503 
504  sCode = stream.readAll();
505  }
506  catch(...)
507  {
508  LOG(VB_GENERAL, LOG_ERR,
509  QString("Exception while Reading File Contents File: %1") .arg(sFileName));
510  }
511 
512  scriptFile.close();
513 
514  return sCode;
515 }
516 
518 //
520 
521 bool ServerSideScripting::ProcessLine( QTextStream &sCode,
522  QString &sLine,
523  bool bInCode,
524  QString &sTransBuffer ) const
525 {
526  QString sLowerLine = sLine.toLower();
527 
528  if (!sTransBuffer.isEmpty())
529  {
530  int nEndTransPos = sLowerLine.indexOf("</i18n>");
531 
532  if (nEndTransPos == -1)
533  {
534  sTransBuffer.append(" ");
535  sTransBuffer.append(sLine);
536  return bInCode;
537  }
538 
539  if (nEndTransPos > 0)
540  sTransBuffer.append(" ");
541 
542  sTransBuffer.append(sLine.left(nEndTransPos).trimmed());
543  QString trStr =
544  QCoreApplication::translate("HtmlUI", sTransBuffer.trimmed().toLocal8Bit().data());
545  trStr.replace( '"', "\\\"" );
546  sCode << "os.write( \"" << trStr << "\" );\n";
547  sTransBuffer = "";
548 
549  if (nEndTransPos == (sLine.length() - 7))
550  return bInCode;
551 
552  sLine = sLine.right(sLine.length() - (nEndTransPos + 7));
553  }
554 
555  int nStartTransPos = sLowerLine.indexOf("<i18n>");
556  if (nStartTransPos != -1)
557  {
558  int nEndTransPos = sLowerLine.indexOf("</i18n>");
559  if (nEndTransPos != -1)
560  {
561  QString patStr = sLine.mid(nStartTransPos,
562  (nEndTransPos + 7 - nStartTransPos));
563  QString repStr = patStr.mid(6, patStr.length() - 13).trimmed();
564  sLine.replace(patStr, QCoreApplication::translate("HtmlUI", repStr.toLocal8Bit().data()));
565  return ProcessLine(sCode, sLine, bInCode, sTransBuffer);
566  }
567 
568  sTransBuffer = " ";
569  sTransBuffer.append(sLine.mid(nStartTransPos + 6).trimmed());
570  sLine = sLine.left(nStartTransPos);
571  }
572 
573  int nStartPos = 0;
574  int nEndPos = 0;
575  int nMatchPos = 0;
576  bool bMatchFound = false;
577 
578  QString sExpecting = bInCode ? "%>" : "<%";
579  bool bNewLine = !(sLine.startsWith( sExpecting ));
580 
581  while (nStartPos < sLine.length())
582  {
583  nEndPos = sLine.length() - 1;
584 
585  sExpecting = bInCode ? "%>" : "<%";
586  nMatchPos = sLine.indexOf( sExpecting, nStartPos );
587 
588  // ------------------------------------------------------------------
589  // If not found, Adjust to Save entire line
590  // ------------------------------------------------------------------
591 
592  if (nMatchPos < 0)
593  {
594  nMatchPos = nEndPos + 1;
595  bMatchFound = false;
596  }
597  else
598  bMatchFound = true;
599 
600  // ------------------------------------------------------------------
601  // Add Code or Text to Line
602  // ------------------------------------------------------------------
603 
604  QString sSegment = sLine.mid( nStartPos, nMatchPos - nStartPos );
605 
606  if ( !sSegment.isEmpty())
607  {
608  if (bInCode)
609  {
610  // Add Code
611 
612  if (sSegment.startsWith( "=" ))
613  {
614  // Evaluate statement and render results.
615 
616  sCode << "os.write( " << sSegment.mid( 1 ) << " ); "
617  << "\n";
618  }
619  else if (sSegment.startsWith( "import" ))
620  {
621  // Loads supplied path as script file.
622  //
623  // Syntax: import "/relative/path/to/script.js"
624  // - must be at start of line (no leading spaces)
625  //
626 
627  // Extract filename (remove quotes)
628 
629 #if QT_VERSION < QT_VERSION_CHECK(5,14,0)
630  QStringList sParts = sSegment.split( ' ', QString::SkipEmptyParts );
631 #else
632  QStringList sParts = sSegment.split( ' ', Qt::SkipEmptyParts );
633 #endif
634 
635  if (sParts.length() > 1 )
636  {
637  QString sFileName = sParts[1].mid( 1, sParts[1].length() - 2 );
638 
639  QFileInfo oInfo( m_sResRootPath + sFileName );
640 
641  if (oInfo.exists())
642  {
643  sCode << ReadFileContents( oInfo.canonicalFilePath() )
644  << "\n";
645  }
646  else
647  {
648  LOG(VB_GENERAL, LOG_ERR,
649  QString("ServerSideScripting::ProcessLine 'import' - File not found: %1%2")
650  .arg(m_sResRootPath, sFileName));
651  }
652  }
653  else
654  {
655  LOG(VB_GENERAL, LOG_ERR,
656  QString("ServerSideScripting::ProcessLine 'import' - Malformed [%1]")
657  .arg( sSegment ));
658  }
659 
660  }
661  else
662  sCode << sSegment << "\n";
663 
664  if (bMatchFound)
665  bInCode = false;
666  }
667  else
668  {
669  // Add Text
670 
671  sSegment.replace( '"', "\\\"" );
672 
673  sCode << "os.write( \"" << sSegment << "\" );\n";
674 
675  if (bMatchFound)
676  bInCode = true;
677  }
678  }
679  else
680  {
681  if (bMatchFound)
682  bInCode = !bInCode;
683  }
684 
685  nStartPos = nMatchPos + 2;
686  }
687 
688  if ((bNewLine) && !bInCode )
689  sCode << "os.writeln( \"\" );\n";
690 
691  return bInCode;
692 }
ScriptInfo::m_dtTimeStamp
QDateTime m_dtTimeStamp
Definition: serverSideScripting.h:40
build_compdb.args
args
Definition: build_compdb.py:11
HTTPRequest
Definition: httprequest.h:108
HTTPRequest::GetHostPort
virtual quint16 GetHostPort()=0
HttpServer::GetServerVersion
static QString GetServerVersion(void)
Definition: httpserver.cpp:285
ScriptInfo::m_oFunc
QScriptValue m_oFunc
Definition: serverSideScripting.h:39
HTTPRequest::GetPeerAddress
virtual QString GetPeerAddress()=0
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:161
formatStr
QScriptValue formatStr(QScriptContext *context, QScriptEngine *interpreter)
Definition: serverSideScripting.cpp:30
ServerSideScripting::ReadFileContents
static QString ReadFileContents(const QString &sFileName)
Definition: serverSideScripting.cpp:492
ServerSideScripting::m_engine
QScriptEngine m_engine
Definition: serverSideScripting.h:53
MythUserSession
Definition: mythsession.h:16
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:130
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::m_mapHeaders
QStringMultiMap m_mapHeaders
Definition: httprequest.h:131
HTTPRequest::GetHostName
virtual QString GetHostName()
Definition: httprequest.cpp:2216
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:2162
OutputStream
Definition: serverSideScripting.h:93
HTTPRequest::GetRequestProtocol
QString GetRequestProtocol() const
Definition: httprequest.cpp:911
ServerSideScripting::SetResourceRootPath
QString SetResourceRootPath(const QString &path)
Definition: serverSideScripting.cpp:101
ServerSideScripting::Lock
void Lock()
Definition: serverSideScripting.h:77
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:36
HTTPRequest::GetHostAddress
virtual QString GetHostAddress()=0
ServerSideScripting::ProcessLine
bool ProcessLine(QTextStream &sCode, QString &sLine, bool bInCode, QString &sTransBuffer) const
Definition: serverSideScripting.cpp:521
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:2242
ServerSideScripting::CreateMethodFromFile
QString CreateMethodFromFile(const QString &sFileName) const
Definition: serverSideScripting.cpp:446
HTTPRequest::m_mapCookies
QStringMap m_mapCookies
Definition: httprequest.h:132