http_ex.cpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. #include "http_ex.h"
  2. #include <util/generic/buffer.h>
  3. #include <util/generic/cast.h>
  4. #include <util/stream/null.h>
  5. bool THttpClientRequestExtension::Parse(char* req, TBaseServerRequestData& rd) {
  6. rd.SetSocket(Socket());
  7. if (!rd.Parse(req)) {
  8. Output() << "HTTP/1.1 403 Forbidden\r\n"
  9. "Content-Type: text/plain\r\n"
  10. "Content-Length: 39\r\n"
  11. "\r\n"
  12. "The server cannot be used as a proxy.\r\n";
  13. return false;
  14. }
  15. return true;
  16. }
  17. bool THttpClientRequestExtension::ProcessHeaders(TBaseServerRequestData& rd, TBlob& postData) {
  18. for (const auto& header : ParsedHeaders) {
  19. rd.AddHeader(header.first, header.second);
  20. }
  21. char* s = RequestString.begin();
  22. enum EMethod {
  23. NotImplemented,
  24. Get,
  25. Post,
  26. Put,
  27. Patch,
  28. Delete,
  29. };
  30. enum EMethod foundMethod;
  31. char* urlStart;
  32. if (strnicmp(s, "GET ", 4) == 0) {
  33. foundMethod = Get;
  34. urlStart = s + 4;
  35. } else if (strnicmp(s, "POST ", 5) == 0) {
  36. foundMethod = Post;
  37. urlStart = s + 5;
  38. } else if (strnicmp(s, "PUT ", 4) == 0) {
  39. foundMethod = Put;
  40. urlStart = s + 4;
  41. } else if (strnicmp(s, "PATCH ", 6) == 0) {
  42. foundMethod = Patch;
  43. urlStart = s + 6;
  44. } else if (strnicmp(s, "DELETE ", 7) == 0) {
  45. foundMethod = Delete;
  46. urlStart = s + 7;
  47. } else {
  48. foundMethod = NotImplemented;
  49. }
  50. switch (foundMethod) {
  51. case Get:
  52. case Delete:
  53. if (!Parse(urlStart, rd)) {
  54. return false;
  55. }
  56. break;
  57. case Post:
  58. case Put:
  59. case Patch:
  60. try {
  61. ui64 contentLength = 0;
  62. if (Input().HasExpect100Continue()) {
  63. Output().SendContinue();
  64. }
  65. if (!Input().ContentEncoded() && Input().GetContentLength(contentLength)) {
  66. if (contentLength > HttpServ()->Options().MaxInputContentLength) {
  67. Output() << "HTTP/1.1 413 Payload Too Large\r\nContent-Length:0\r\n\r\n";
  68. Output().Finish();
  69. return false;
  70. }
  71. TBuffer buf(SafeIntegerCast<size_t>(contentLength));
  72. buf.Resize(Input().Load(buf.Data(), (size_t)contentLength));
  73. postData = TBlob::FromBuffer(buf);
  74. } else {
  75. postData = TBlob::FromStream(Input());
  76. }
  77. } catch (...) {
  78. Output() << "HTTP/1.1 400 Bad request\r\n\r\n";
  79. return false;
  80. }
  81. if (!Parse(urlStart, rd)) {
  82. return false;
  83. }
  84. break;
  85. case NotImplemented:
  86. Output() << "HTTP/1.1 501 Not Implemented\r\n\r\n";
  87. return false;
  88. }
  89. return true;
  90. }