request.cpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. /*
  2. Copyright 2017 Herik Lima de Castro and Marcelo Medeiros Eler
  3. Distributed under MIT license, or public domain if desired and
  4. recognized in your jurisdiction.
  5. See file LICENSE for detail.
  6. */
  7. #include "request.h"
  8. #include <QUuid>
  9. #include "constants.h"
  10. #include "metaclassparser.h"
  11. #include "response.h"
  12. #include "urlencoder.h"
  13. // clazy:excludeall=connect-not-normalized
  14. CWF_BEGIN_NAMESPACE
  15. Request::Request(QTcpSocket &socket,
  16. QMapThreadSafety<QString, Session *> &sessions,
  17. const Configuration &configuration)
  18. : socket(socket)
  19. , sessions(sessions)
  20. , configuration(configuration)
  21. {}
  22. Request::~Request() noexcept
  23. {
  24. delete requestDispatcher;
  25. }
  26. void Request::fillQObject(QObject *object, bool urlDecode, bool replacePlusForSpace)
  27. {
  28. fillQObject(object, httpParser->getParameters(), urlDecode, replacePlusForSpace);
  29. }
  30. void Request::fillQObject(QObject *object,
  31. const QMap<QByteArray, QByteArray> &parameters,
  32. bool urlDecode,
  33. bool replacePlusForSpace)
  34. {
  35. MetaClassParser meta(object);
  36. for (QMap<QByteArray, QByteArray>::const_iterator it = parameters.constBegin();
  37. it != parameters.constEnd();
  38. ++it) {
  39. QString method = it.key();
  40. if (method.size() > 0) {
  41. QString value = it.value();
  42. method[0] = method[0].toUpper();
  43. method = GET_SET::SET_LOWER + method;
  44. QString parameterType(meta.getParameterType(method));
  45. if (parameterType == CSTL::SUPPORTED_TYPES::QSTRING) {
  46. if (urlDecode)
  47. value = URLEncoder::paramDecode(value.toUtf8(), replacePlusForSpace);
  48. QMetaObject::invokeMethod(object,
  49. method.toStdString().data(),
  50. Q_ARG(QString, value));
  51. } else if (parameterType == CSTL::SUPPORTED_TYPES::STD_STRING) {
  52. if (urlDecode)
  53. value = URLEncoder::paramDecode(value.toUtf8(), replacePlusForSpace);
  54. QMetaObject::invokeMethod(object,
  55. method.toStdString().data(),
  56. Q_ARG(std::string, value.toStdString()));
  57. } else if (parameterType == CSTL::SUPPORTED_TYPES::BOOL) {
  58. QMetaObject::invokeMethod(object,
  59. method.toStdString().data(),
  60. Q_ARG(bool, value.toInt() == 0));
  61. } else if (parameterType == CSTL::SUPPORTED_TYPES::CHAR) {
  62. if (value.isEmpty())
  63. value.push_back(' ');
  64. QMetaObject::invokeMethod(object,
  65. method.toStdString().data(),
  66. Q_ARG(char, value.toStdString()[0]));
  67. } else if (parameterType == CSTL::SUPPORTED_TYPES::UNSIGNED_CHAR) {
  68. if (value.isEmpty())
  69. value.push_back(' ');
  70. QMetaObject::invokeMethod(object,
  71. method.toStdString().data(),
  72. Q_ARG(unsigned char,
  73. static_cast<unsigned char>(value.toStdString()[0])));
  74. } else if (parameterType == CSTL::SUPPORTED_TYPES::SHORT) {
  75. QMetaObject::invokeMethod(object,
  76. method.toStdString().data(),
  77. Q_ARG(short, static_cast<short>(value.toInt())));
  78. } else if (parameterType == CSTL::SUPPORTED_TYPES::UNSIGNED_SHORT) {
  79. QMetaObject::invokeMethod(object,
  80. method.toStdString().data(),
  81. Q_ARG(unsigned short,
  82. static_cast<unsigned short>(value.toInt())));
  83. } else if (parameterType == CSTL::SUPPORTED_TYPES::INT) {
  84. QMetaObject::invokeMethod(object,
  85. method.toStdString().data(),
  86. Q_ARG(int, value.toInt()));
  87. } else if (parameterType == CSTL::SUPPORTED_TYPES::UNSIGNED_INT) {
  88. QMetaObject::invokeMethod(object,
  89. method.toStdString().data(),
  90. Q_ARG(unsigned int, value.toUInt()));
  91. } else if (parameterType == CSTL::SUPPORTED_TYPES::LONG) {
  92. QMetaObject::invokeMethod(object,
  93. method.toStdString().data(),
  94. Q_ARG(long, value.toLong()));
  95. } else if (parameterType == CSTL::SUPPORTED_TYPES::UNSIGNED_LONG) {
  96. QMetaObject::invokeMethod(object,
  97. method.toStdString().data(),
  98. Q_ARG(unsigned long, value.toULong()));
  99. } else if (parameterType == CSTL::SUPPORTED_TYPES::LONG_LONG) {
  100. QMetaObject::invokeMethod(object,
  101. method.toStdString().data(),
  102. Q_ARG(long long, value.toLongLong()));
  103. } else if (parameterType == CSTL::SUPPORTED_TYPES::UNSIGNED_LONG_LONG) {
  104. QMetaObject::invokeMethod(object,
  105. method.toStdString().data(),
  106. Q_ARG(unsigned long long, value.toULongLong()));
  107. } else if (parameterType == CSTL::SUPPORTED_TYPES::FLOAT) {
  108. QMetaObject::invokeMethod(object,
  109. method.toStdString().data(),
  110. Q_ARG(float, value.toFloat()));
  111. } else if (parameterType == CSTL::SUPPORTED_TYPES::DOUBLE) {
  112. QMetaObject::invokeMethod(object,
  113. method.toStdString().data(),
  114. Q_ARG(double, value.toDouble()));
  115. }
  116. }
  117. }
  118. }
  119. RequestDispatcher &Request::getRequestDispatcher(const QString &page)
  120. {
  121. delete requestDispatcher;
  122. requestDispatcher = new RequestDispatcher(configuration.getPath() + page);
  123. return *requestDispatcher;
  124. }
  125. Session &Request::getSession()
  126. {
  127. static QMutex mutex;
  128. QMutexLocker locker(&mutex);
  129. qint64 currentTimeInt = QDateTime::currentMSecsSinceEpoch();
  130. qint64 expiration = configuration.getSessionExpirationTime();
  131. if (!session) {
  132. QByteArray sessionId = httpParser->getSessionId();
  133. if (sessionId.isEmpty() || !sessions.contains(sessionId)) {
  134. sessionId = QUuid::createUuid().toString().toLocal8Bit();
  135. response->addCookie(QNetworkCookie(HTTP::SESSION_ID, sessionId));
  136. session = new Session(sessionId, expiration);
  137. session->creationTime = currentTimeInt;
  138. session->sessionExpirationTime = (currentTimeInt + expiration);
  139. sessions.insert(session->getId(), session);
  140. } else {
  141. session = sessions[sessionId];
  142. }
  143. }
  144. session->expired = (currentTimeInt >= session->sessionExpirationTime);
  145. session->lastAccessedTime = currentTimeInt;
  146. if (!session->expired) {
  147. session->sessionExpirationTime = (currentTimeInt + expiration);
  148. }
  149. return *session;
  150. }
  151. CWF_END_NAMESPACE