cppsp_cpoll.C 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. /*
  2. This program is free software: you can redistribute it and/or modify
  3. it under the terms of the GNU General Public License as published by
  4. the Free Software Foundation, either version 3 of the License, or
  5. (at your option) any later version.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9. GNU General Public License for more details.
  10. You should have received a copy of the GNU General Public License
  11. along with this program. If not, see <http://www.gnu.org/licenses/>.
  12. * */
  13. /*
  14. * cppsp_socketd.C
  15. *
  16. * Created on: Mar 8, 2013
  17. * Author: xaxaxa
  18. */
  19. #include "include/cppsp_cpoll.H"
  20. #include <stdio.h>
  21. #include <unistd.h>
  22. #include "include/stringutils.H"
  23. using namespace CP;
  24. namespace cppsp
  25. {
  26. //static int CPollRequest::bufSize=4096;
  27. CPollRequest::CPollRequest(CP::Socket& s, CP::StringPool* sp) :
  28. Request(s, sp), _parser(&headers), s(s) {
  29. _stream.parser = &_parser;
  30. _stream.stream = &s;
  31. _stream.stream->retain();
  32. this->inputStream = &_stream;
  33. }
  34. bool CPollRequest_parseReqLine(CPollRequest* This) {
  35. uint8_t* lineBuf = (uint8_t*) This->_parser.reqLine.data();
  36. int lineBufLen = This->_parser.reqLine.length();
  37. uint8_t* tmp = (uint8_t*) memchr(lineBuf, ' ', lineBufLen);
  38. if (tmp == NULL) return false;
  39. This->method = {(char*) lineBuf, int(tmp - lineBuf)};
  40. tmp++;
  41. if (lineBuf + lineBufLen - tmp <= 0) return false;
  42. uint8_t* tmp1 = (uint8_t*) memchr(tmp, ' ', lineBuf + lineBufLen - tmp);
  43. if (tmp1 == NULL) return false;
  44. const char* path = (const char*) tmp;
  45. int pathLen = tmp1 - tmp;
  46. if (pathLen <= 0) return false;
  47. const char* q = (const char*) memchr(path, '?', pathLen);
  48. if (q == NULL) This->path = {path, pathLen};
  49. else {
  50. struct
  51. {
  52. CPollRequest* This;
  53. void operator()(const char* name, int nameLen, const char* value, int valueLen) {
  54. String n, v;
  55. n=cppsp::urlDecode(name, nameLen, *This->sp);
  56. if (value != NULL) {
  57. v=cppsp::urlDecode(value, valueLen, *This->sp);
  58. } else v= {(char*)nullptr,0};
  59. This->queryString[n] = v;
  60. }
  61. }cb {This};
  62. cppsp::parseQueryString(q + 1, path + pathLen - q - 1, &cb, false);
  63. This->path = {path, q - path};
  64. }
  65. return true;
  66. }
  67. bool CPollRequest::readRequest(const Delegate<void(bool)>& cb) {
  68. if (_parser.process()) {
  69. if (CPollRequest_parseReqLine(this)) return true;
  70. else {
  71. cb(false);
  72. return false;
  73. }
  74. } else {
  75. this->tmp_cb = cb;
  76. _parser.reset();
  77. _beginRead();
  78. return false;
  79. }
  80. }
  81. void CPollRequest::_beginRead() {
  82. String b = _parser.beginPutData(4096);
  83. _stream.stream->read(b.data(), b.length(), { &CPollRequest::_readCB, this });
  84. }
  85. void CPollRequest::_readCB(int i) {
  86. if (i <= 0) {
  87. tmp_cb(false);
  88. return;
  89. }
  90. _parser.endPutData(i);
  91. if (_parser.process()) {
  92. tmp_cb(CPollRequest_parseReqLine(this));
  93. } else {
  94. _beginRead();
  95. }
  96. }
  97. CPollRequest::~CPollRequest() {
  98. _stream.stream->release();
  99. }
  100. }