121 const netplus::TlsTrustPolicy &trustPolicy = noVerifyTrustPolicy());
124 void setTimeout(
int timeout_sec);
125 const std::vector<char> Get(
HttpRequest &nreq,
size_t maxTries=0);
126 const std::vector<char> Post(
HttpRequest &nreq,
const std::vector<char> &post,
size_t maxTries=0);
127 const std::vector<char> Put(
HttpRequest &nreq,
const std::vector<char> &put,
size_t maxTries=0);
128 const std::vector<char> Delete(
HttpRequest &nreq,
size_t maxTries=0);
129 const std::vector<char> Options(
HttpRequest &nreq,
size_t maxTries=0);
130 const std::vector<char> Head(
HttpRequest &nreq,
size_t maxTries=0);
131 const std::vector<char> Patch(
HttpRequest &nreq,
const std::vector<char> &patch,
size_t maxTries=0);
147 size_t readBodyChunk(
char *buf,
size_t bufsize);
151 size_t readBodyChunkNonBlocking(
char *buf,
size_t bufsize);
154 bool isStreaming()
const;
161 bool wantsClose()
const {
return _peerWantsClose; }
166 bool waitReadable(
int timeout_ms);
170 void setMaxRedirects(
int max) { _maxRedirects = max; }
173 int lastStatusCode()
const {
return _lastStatusCode; }
176 const std::string &lastContentType()
const {
return _lastContentType; }
179 const HttpResponse *lastResponse()
const {
return _lastResponse.get(); }
182 void resetConnection();
186 static netplus::TlsSessionCache& tlsSessionCache();
188 netplus::TlsTrustPolicy _trustPolicy;
190 void _ensureConnected();
193 void _connectTcp(netplus::tcp &sock);
194 bool tryHttp3First();
197 size_t _recvBlocking(netplus::buffer &b,
int timeout_sec = 0);
199 size_t _recvNonBlocking(netplus::buffer &b);
200 void _sendAll(
const char *data,
size_t len);
201 void _sendAll(
const std::string &data);
204 std::vector<char> _h1ReadResponse(
const std::string &label);
214 bool _streamRecvMore(
bool blocking,
bool &eof);
215 size_t _streamReadChunked(
char *buf,
size_t bufsize,
bool blocking);
216 size_t _streamReadEof(
char *buf,
size_t bufsize,
bool blocking);
225 size_t _streamReadH2(
char *buf,
size_t bufsize,
bool blocking);
232 size_t _streamReadH3(
char *buf,
size_t bufsize,
bool blocking);
239 const std::vector<char> _doH1Request(
const std::string &method,
int requestType,
241 size_t maxTries,
bool followRedirects);
246 bool _h2PrefaceSent =
false;
249 uint32_t _h2NextStreamId = 1;
250 std::unique_ptr<hpack::Decoder> _h2Decoder;
251 const std::vector<char> _h2Request(
const std::string &method,
253 const std::vector<char> *postBody =
nullptr);
254 const std::vector<char> _h3Request(
const std::string &method,
256 const std::vector<char> *postBody =
nullptr);
259 enum StreamMode { STREAM_NONE, STREAM_CONTENT_LENGTH, STREAM_CHUNKED, STREAM_EOF,
260 STREAM_H2, STREAM_H3 };
261 StreamMode _streamMode = STREAM_NONE;
262 size_t _streamRemaining = 0;
263 std::vector<char> _streamBuf;
264 size_t _streamBufPos = 0;
266 bool _streamChunkDone =
false;
267 size_t _streamChunkRemaining = 0;
270 uint32_t _streamH2Sid = 0;
271 bool _streamH2EndStream =
false;
272 std::vector<uint8_t> _streamH2Raw;
275 uint64_t _streamH3Sid = 0;
276 bool _streamH3EndStream =
false;
277 std::vector<uint8_t> _streamH3Raw;
278 std::vector<char> _streamH3Body;
279 size_t _streamH3BodyPos = 0;
280 bool _streamH3InDataFrame =
false;
281 uint64_t _streamH3DataRemaining = 0;
285 std::unique_ptr<netplus::socket> _cltsock;
286 netplus::socketwait _sw;
287 netplus::x509cert _cert;
297 netplus::buffer _recvScratch{CHUNKSIZE};
298 int _recvTimeoutSec = 60;
299 int _sendTimeoutSec = 30;
305 bool _peerWantsClose =
false;
308 int _lastStatusCode = 0;
309 std::string _lastLocation;
310 std::string _lastContentType;
311 std::unique_ptr<HttpResponse> _lastResponse;
312 static constexpr int MAX_REDIRECTS = 5;
313 int _maxRedirects = MAX_REDIRECTS;
412 void setState(
const std ::string &httpstate);
413 void setContentType(
const std ::string &type);
414 void setContentLength(
size_t len);
415 void setConnection(
const std ::string &type);
416 void setTransferEncoding(
const std ::string &enc);
419 const std ::string &getState()
const;
420 int getStatusCode()
const;
421 const std ::string &getContentType()
const;
422 size_t getContentLength()
const;
423 const std ::string &getConnection()
const;
424 const std ::string &getVersion()
const;
427 size_t printHeader(std::vector<char> &buffer);
430 void send(netplus::con &curconnection,
const std::string &data,
int datalen=0);
431 void send(netplus::con &curconnection,
const unsigned char *data,
int datalen);
432 void send(netplus::con &curconnection,
const std::vector<char> &data,
int datalen=0);
439 void sendChunkedHeaders(netplus::con &curconnection);
440 void sendChunk(netplus::con &curconnection,
const char *data,
size_t len);
441 void endChunked(netplus::con &curconnection);
444 size_t parse(
const char *in,
size_t inlen);
453 size_t parseH2(
const std::vector<hpack::HeaderField> &headers);
454 size_t parseH3(
const std::vector<qpack::HeaderField> &headers);
457 bool _storeResponseInfo(netplus::con &curconnection,
int datalen);
459 std::string _State=HTTP200;
460 std::string _Version;
466 mutable std::string _ContentTypeCache;
483 size_t parseH2(
const std::vector<hpack::HeaderField> &headers, uint32_t stream_id = 0);
484 size_t parseH3(
const std::vector<qpack::HeaderField> &headers);
486 void printHeader(std::string &buffer);
487 int getRequestType();
488 const std::string &getRequestURL();
489 const std::string &getRequest();
490 size_t getRequestLength();
491 const std::string &getRequestVersion();
492 const std::string &getHost();
493 size_t getContentLength();
494 size_t getMaxUploadSize();
500 bool isChunkedRequest();
501 int decodeChunkedBody();
516 void setPeerAddress(
const std::string &addr);
517 const std::string &getPeerAddress()
const;
520 void setRequestType(
int req);
521 void setRequestURL(
const std::string &url);
522 void setRequestVersion(
const std::string &version);
524 void setRequestData(
const std::string &data,
size_t len);
525 void setMaxUploadSize(
size_t upsize);
527 void send(
const HttpUrl &dest,std::unique_ptr<netplus::socket> &sock);
536 static std::string extractPath(
const std::string &target);
538 int _RequestType = PARSEREQUEST;
539 size_t _MaxUploadSize = DEFAULT_UPLOADSIZE;
543 mutable std::string _cachedRequestURL;
544 mutable std::string _cachedRequest;
545 mutable std::string _cachedRequestVersion;
546 mutable std::string _cachedHost;
547 std::string _peerAddress;
553 int _httpProtocol = 0;
555 struct H2PendingResponse {
563 struct H2StreamingResponse {
564 uint32_t streamId = 0;
565 size_t contentLength = 0;
566 size_t totalSent = 0;
567 std::string pendingData;
568 size_t pendingOffset = 0;
569 std::unique_ptr<HttpRequest> tempreq;
572 size_t emptyCount = 0;
573 unsigned int backoffMs = 1;
574 bool finished =
false;
581 bool windowBlocked =
false;
582 std::chrono::steady_clock::time_point blockedSince{};
585 struct H2PendingIncoming {
586 std::vector<hpack::HeaderField> headers;
588 std::vector<uint8_t> rawHpack;
589 bool headersComplete =
false;
590 bool endStreamOnHeaders =
false;
591 bool streaming =
false;
595 uint32_t streamId = 0;
596 bool headersSent =
false;
597 bool serverPrefaceSent =
false;
598 size_t expectedContentLength = 0;
599 size_t bodyBytesSent = 0;
600 std::deque<H2PendingResponse> pendingResponses;
601 std::map<uint32_t, H2PendingIncoming> pendingIncoming;
604 int32_t peerConnWindow = 65535;
605 int32_t peerInitialStreamWindow = 65535;
606 size_t peerMaxFrameSize = 16384;
607 std::map<uint32_t, int32_t> peerStreamWindows;
609 std::map<uint32_t, std::shared_ptr<H2StreamingResponse>> activeStreams;
613 std::unique_ptr<H2State> _h2;
617 if (!_h2) _h2 = std::make_unique<H2State>();
640 std::vector<Header> headers;
641 std::vector<Disposition> dispositions;
642 std::vector<char> value;
657 const std::string &getContentType()
const {
return _contentType; }
658 const std::string &getBoundary()
const {
return _boundary; }
659 const std::vector<MultipartEntry> &multipartData()
const {
return _multipartEntries; }
660 const std::vector<UrlEntry> &urlData()
const {
return _urlEntries; }
663 static void urlDecode(
const std::string &in, std::string &out);
664 static void urlEncode(
const std::string &in, std::string &out);
667 void _parseMultipart(
const char *data,
size_t len);
668 void _parseMultiSection(
const char *data,
size_t len,
size_t start,
size_t end);
669 void _parseUrlDecode(
const char *data,
size_t len);
671 std::string _boundary;
672 std::string _contentType;
673 std::vector<MultipartEntry> _multipartEntries;
674 std::vector<UrlEntry> _urlEntries;