HTTPClient.h 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. #pragma once
  2. #include <memory>
  3. #include <stdexcept>
  4. #include <string>
  5. #include <string_view>
  6. #include <unordered_map>
  7. #include <variant>
  8. #include <vector>
  9. #include <cassert>
  10. #include "BellSocket.h"
  11. #include "ByteStream.h"
  12. #include "SocketStream.h"
  13. #include "URLParser.h"
  14. #include "fmt/core.h"
  15. #include "picohttpparser.h"
  16. namespace bell {
  17. class HTTPClient {
  18. public:
  19. // most basic header type, represents by a key-val
  20. typedef std::pair<std::string, std::string> ValueHeader;
  21. typedef std::vector<ValueHeader> Headers;
  22. // Helper over ValueHeader, formatting a HTTP bytes range
  23. struct RangeHeader {
  24. static ValueHeader range(int32_t from, int32_t to) {
  25. return ValueHeader{"Range", fmt::format("bytes={}-{}", from, to)};
  26. }
  27. static ValueHeader last(int32_t nbytes) {
  28. return ValueHeader{"Range", fmt::format("bytes=-{}", nbytes)};
  29. }
  30. };
  31. class Response {
  32. public:
  33. Response(){};
  34. ~Response();
  35. /**
  36. * Initializes a connection with a given url.
  37. */
  38. void connect(const std::string& url);
  39. void rawRequest(const std::string& method, const std::string& url,
  40. const std::string& content, Headers& headers);
  41. void get(const std::string& url, Headers headers = {});
  42. std::string_view body();
  43. std::vector<uint8_t> bytes();
  44. std::string_view header(const std::string& headerName);
  45. bell::SocketStream& stream() { return this->socketStream; }
  46. size_t contentLength();
  47. size_t totalLength();
  48. private:
  49. bell::URLParser urlParser;
  50. bell::SocketStream socketStream;
  51. struct phr_header phResponseHeaders[32];
  52. const size_t HTTP_BUF_SIZE = 1024;
  53. std::vector<uint8_t> httpBuffer = std::vector<uint8_t>(HTTP_BUF_SIZE);
  54. std::vector<uint8_t> rawBody = std::vector<uint8_t>();
  55. size_t httpBufferAvailable;
  56. size_t contentSize = 0;
  57. bool hasContentSize = false;
  58. Headers responseHeaders;
  59. void readResponseHeaders();
  60. void readRawBody();
  61. };
  62. enum class Method : uint8_t { GET = 0, POST = 1 };
  63. struct Request {
  64. std::string url;
  65. Method method;
  66. Headers headers;
  67. };
  68. static std::unique_ptr<Response> get(const std::string& url,
  69. Headers headers = {}) {
  70. auto response = std::make_unique<Response>();
  71. response->connect(url);
  72. response->get(url, headers);
  73. return response;
  74. }
  75. };
  76. } // namespace bell