94 void setTimeout(
int timeout_sec);
95 const std::vector<char> Get(
HttpRequest &nreq,
size_t maxTries=0);
96 const std::vector<char> Post(
HttpRequest &nreq,
const std::vector<char> &post,
size_t maxTries=0);
97 const std::vector<char> Put(
HttpRequest &nreq,
const std::vector<char> &put,
size_t maxTries=0);
98 const std::vector<char> Delete(
HttpRequest &nreq,
size_t maxTries=0);
106 size_t readBodyChunk(
char *buf,
size_t bufsize);
110 size_t readBodyChunkNonBlocking(
char *buf,
size_t bufsize);
113 bool isStreaming()
const;
118 bool waitReadable(
int timeout_ms);
122 void setMaxRedirects(
int max) { _maxRedirects = max; }
125 int lastStatusCode()
const {
return _lastStatusCode; }
128 const std::string &lastContentType()
const {
return _lastContentType; }
131 const HttpResponse *lastResponse()
const {
return _lastResponse.get(); }
134 void resetConnection();
138 static netplus::TlsSessionCache& tlsSessionCache();
140 void _ensureConnected();
141 bool tryHttp3First();
142 int readchunk(
const char *data,
int datasize,
int &pos);
145 size_t _recvBlocking(netplus::buffer &b,
int timeout_sec = 0);
147 size_t _recvNonBlocking(netplus::buffer &b);
148 void _sendAll(
const char *data,
size_t len);
149 void _sendAll(
const std::string &data);
152 std::vector<char> _h1ReadResponse(
const std::string &label);
156 bool _h2PrefaceSent =
false;
159 uint32_t _h2NextStreamId = 1;
160 std::unique_ptr<hpack::Decoder> _h2Decoder;
161 const std::vector<char> _h2Request(
const std::string &method,
163 const std::vector<char> *postBody =
nullptr);
164 const std::vector<char> _h3Request(
const std::string &method,
166 const std::vector<char> *postBody =
nullptr);
169 enum StreamMode { STREAM_NONE, STREAM_CONTENT_LENGTH, STREAM_CHUNKED, STREAM_EOF,
170 STREAM_H2, STREAM_H3 };
171 StreamMode _streamMode = STREAM_NONE;
172 size_t _streamRemaining = 0;
173 std::vector<char> _streamBuf;
174 size_t _streamBufPos = 0;
176 bool _streamChunkDone =
false;
177 size_t _streamChunkRemaining = 0;
180 uint32_t _streamH2Sid = 0;
181 bool _streamH2EndStream =
false;
182 std::vector<uint8_t> _streamH2Raw;
185 uint64_t _streamH3Sid = 0;
186 bool _streamH3EndStream =
false;
187 std::vector<uint8_t> _streamH3Raw;
188 std::vector<char> _streamH3Body;
189 size_t _streamH3BodyPos = 0;
190 bool _streamH3InDataFrame =
false;
191 uint64_t _streamH3DataRemaining = 0;
195 std::unique_ptr<netplus::socket> _cltsock;
196 netplus::socketwait _sw;
197 netplus::x509cert _cert;
198 int _recvTimeoutSec = 60;
199 int _sendTimeoutSec = 30;
203 int _lastStatusCode = 0;
204 std::string _lastLocation;
205 std::string _lastContentType;
206 std::unique_ptr<HttpResponse> _lastResponse;
207 static constexpr int MAX_REDIRECTS = 5;
208 int _maxRedirects = MAX_REDIRECTS;
296 void setState(
const std ::string &httpstate);
297 void setContentType(
const std ::string &type);
298 void setContentLength(
size_t len);
299 void setConnection(
const std ::string &type);
300 void setTransferEncoding(
const std ::string &enc);
303 const std ::string &getState()
const;
304 int getStatusCode()
const;
305 const std ::string &getContentType()
const;
306 size_t getContentLength()
const;
307 const std ::string &getConnection()
const;
308 const std ::string &getVersion()
const;
311 size_t printHeader(std::vector<char> &buffer);
314 void send(netplus::con &curconnection,
const std::string &data,
int datalen=0);
315 void send(netplus::con &curconnection,
const unsigned char *data,
int datalen);
316 void send(netplus::con &curconnection,
const std::vector<char> &data,
int datalen=0);
319 size_t parse(
const char *in,
size_t inlen);
322 bool _storeResponseInfo(netplus::con &curconnection,
int datalen);
324 std::string _State=HTTP200;
325 std::string _Version;
331 mutable std::string _ContentTypeCache;
348 size_t parseH2(
const std::vector<hpack::HeaderField> &headers, uint32_t stream_id = 0);
349 size_t parseH3(
const std::vector<qpack::HeaderField> &headers);
351 void printHeader(std::string &buffer);
352 int getRequestType();
353 const std::string &getRequestURL();
354 const std::string &getRequest();
355 size_t getRequestLength();
356 const std::string &getRequestVersion();
357 const std::string &getHost();
358 size_t getContentLength();
359 size_t getMaxUploadSize();
365 bool isChunkedRequest();
366 int decodeChunkedBody();
372 void setRequestType(
int req);
373 void setRequestURL(
const std::string &url);
374 void setRequestVersion(
const std::string &version);
376 void setRequestData(
const std::string &data,
size_t len);
377 void setMaxUploadSize(
size_t upsize);
379 void send(
const HttpUrl &dest,std::unique_ptr<netplus::socket> &sock);
388 static std::string extractPath(
const std::string &target);
390 int _RequestType = PARSEREQUEST;
391 size_t _MaxUploadSize = DEFAULT_UPLOADSIZE;
395 mutable std::string _cachedRequestURL;
396 mutable std::string _cachedRequest;
397 mutable std::string _cachedRequestVersion;
398 mutable std::string _cachedHost;
404 int _httpProtocol = 0;
406 struct H2PendingResponse {
414 struct H2StreamingResponse {
415 uint32_t streamId = 0;
416 size_t contentLength = 0;
417 size_t totalSent = 0;
418 std::string pendingData;
419 size_t pendingOffset = 0;
420 std::unique_ptr<HttpRequest> tempreq;
423 size_t emptyCount = 0;
424 unsigned int backoffMs = 1;
425 bool finished =
false;
428 struct H2PendingIncoming {
429 std::vector<hpack::HeaderField> headers;
431 std::vector<uint8_t> rawHpack;
432 bool headersComplete =
false;
433 bool endStreamOnHeaders =
false;
434 bool streaming =
false;
438 uint32_t streamId = 0;
439 bool headersSent =
false;
440 bool serverPrefaceSent =
false;
441 size_t expectedContentLength = 0;
442 size_t bodyBytesSent = 0;
443 std::deque<H2PendingResponse> pendingResponses;
444 std::map<uint32_t, H2PendingIncoming> pendingIncoming;
447 int32_t peerConnWindow = 65535;
448 int32_t peerInitialStreamWindow = 65535;
449 size_t peerMaxFrameSize = 16384;
450 std::map<uint32_t, int32_t> peerStreamWindows;
452 std::map<uint32_t, std::shared_ptr<H2StreamingResponse>> activeStreams;
456 std::unique_ptr<H2State> _h2;
460 if (!_h2) _h2 = std::make_unique<H2State>();
483 std::vector<Header> headers;
484 std::vector<Disposition> dispositions;
485 std::vector<char> value;
500 const std::string &getContentType()
const {
return _contentType; }
501 const std::string &getBoundary()
const {
return _boundary; }
502 const std::vector<MultipartEntry> &multipartData()
const {
return _multipartEntries; }
503 const std::vector<UrlEntry> &urlData()
const {
return _urlEntries; }
506 static void urlDecode(
const std::string &in, std::string &out);
507 static void urlEncode(
const std::string &in, std::string &out);
510 void _parseMultipart(
const char *data,
size_t len);
511 void _parseMultiSection(
const char *data,
size_t len,
size_t start,
size_t end);
512 void _parseUrlDecode(
const char *data,
size_t len);
514 std::string _boundary;
515 std::string _contentType;
516 std::vector<MultipartEntry> _multipartEntries;
517 std::vector<UrlEntry> _urlEntries;