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