You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

134 lines
3.8 KiB

4 months ago
  1. /*
  2. * IXHttp.h
  3. * Author: Benjamin Sergeant
  4. * Copyright (c) 2019 Machine Zone, Inc. All rights reserved.
  5. */
  6. #pragma once
  7. #include "IXProgressCallback.h"
  8. #include "IXWebSocketHttpHeaders.h"
  9. #include <atomic>
  10. #include <tuple>
  11. #include <unordered_map>
  12. namespace ix
  13. {
  14. enum class HttpErrorCode : int
  15. {
  16. Ok = 0,
  17. CannotConnect = 1,
  18. Timeout = 2,
  19. Gzip = 3,
  20. UrlMalformed = 4,
  21. CannotCreateSocket = 5,
  22. SendError = 6,
  23. ReadError = 7,
  24. CannotReadStatusLine = 8,
  25. MissingStatus = 9,
  26. HeaderParsingError = 10,
  27. MissingLocation = 11,
  28. TooManyRedirects = 12,
  29. ChunkReadError = 13,
  30. CannotReadBody = 14,
  31. Cancelled = 15,
  32. Invalid = 100
  33. };
  34. struct HttpResponse
  35. {
  36. int statusCode;
  37. std::string description;
  38. HttpErrorCode errorCode;
  39. WebSocketHttpHeaders headers;
  40. std::string body;
  41. std::string errorMsg;
  42. uint64_t uploadSize;
  43. uint64_t downloadSize;
  44. HttpResponse(int s = 0,
  45. const std::string& des = std::string(),
  46. const HttpErrorCode& c = HttpErrorCode::Ok,
  47. const WebSocketHttpHeaders& h = WebSocketHttpHeaders(),
  48. const std::string& b = std::string(),
  49. const std::string& e = std::string(),
  50. uint64_t u = 0,
  51. uint64_t d = 0)
  52. : statusCode(s)
  53. , description(des)
  54. , errorCode(c)
  55. , headers(h)
  56. , body(b)
  57. , errorMsg(e)
  58. , uploadSize(u)
  59. , downloadSize(d)
  60. {
  61. ;
  62. }
  63. };
  64. using HttpResponsePtr = std::shared_ptr<HttpResponse>;
  65. using HttpParameters = std::unordered_map<std::string, std::string>;
  66. using HttpFormDataParameters = std::unordered_map<std::string, std::string>;
  67. using Logger = std::function<void(const std::string&)>;
  68. using OnResponseCallback = std::function<void(const HttpResponsePtr&)>;
  69. struct HttpRequestArgs
  70. {
  71. std::string url;
  72. std::string verb;
  73. WebSocketHttpHeaders extraHeaders;
  74. std::string body;
  75. std::string multipartBoundary;
  76. int connectTimeout = 60;
  77. int transferTimeout = 1800;
  78. bool followRedirects = true;
  79. int maxRedirects = 5;
  80. bool verbose = false;
  81. bool compress = true;
  82. bool compressRequest = false;
  83. Logger logger;
  84. OnProgressCallback onProgressCallback;
  85. OnChunkCallback onChunkCallback;
  86. std::atomic<bool> cancel;
  87. };
  88. using HttpRequestArgsPtr = std::shared_ptr<HttpRequestArgs>;
  89. struct HttpRequest
  90. {
  91. std::string uri;
  92. std::string method;
  93. std::string version;
  94. std::string body;
  95. WebSocketHttpHeaders headers;
  96. HttpRequest(const std::string& u,
  97. const std::string& m,
  98. const std::string& v,
  99. const std::string& b,
  100. const WebSocketHttpHeaders& h = WebSocketHttpHeaders())
  101. : uri(u)
  102. , method(m)
  103. , version(v)
  104. , body(b)
  105. , headers(h)
  106. {
  107. }
  108. };
  109. using HttpRequestPtr = std::shared_ptr<HttpRequest>;
  110. class Http
  111. {
  112. public:
  113. static std::tuple<bool, std::string, HttpRequestPtr> parseRequest(
  114. std::unique_ptr<Socket>& socket, int timeoutSecs);
  115. static bool sendResponse(HttpResponsePtr response, std::unique_ptr<Socket>& socket);
  116. static std::pair<std::string, int> parseStatusLine(const std::string& line);
  117. static std::tuple<std::string, std::string, std::string> parseRequestLine(
  118. const std::string& line);
  119. static std::string trim(const std::string& str);
  120. };
  121. } // namespace ix