98 void setTimeout(
int timeout_sec);
99 const std::vector<char> Get(
HttpRequest &nreq,
size_t maxTries=0);
100 const std::vector<char> Post(
HttpRequest &nreq,
const std::vector<char> &post,
size_t maxTries=0);
101 const std::vector<char> Put(
HttpRequest &nreq,
const std::vector<char> &put,
size_t maxTries=0);
102 const std::vector<char> Delete(
HttpRequest &nreq,
size_t maxTries=0);
118 size_t readBodyChunk(
char *buf,
size_t bufsize);
122 size_t readBodyChunkNonBlocking(
char *buf,
size_t bufsize);
125 bool isStreaming()
const;
130 bool waitReadable(
int timeout_ms);
134 void setMaxRedirects(
int max) { _maxRedirects = max; }
137 int lastStatusCode()
const {
return _lastStatusCode; }
140 const std::string &lastContentType()
const {
return _lastContentType; }
143 const HttpResponse *lastResponse()
const {
return _lastResponse.get(); }
146 void resetConnection();
150 static netplus::TlsSessionCache& tlsSessionCache();
152 void _ensureConnected();
155 void _connectTcp(netplus::tcp &sock);
156 bool tryHttp3First();
157 int readchunk(
const char *data,
int datasize,
int &pos);
160 size_t _recvBlocking(netplus::buffer &b,
int timeout_sec = 0);
162 size_t _recvNonBlocking(netplus::buffer &b);
163 void _sendAll(
const char *data,
size_t len);
164 void _sendAll(
const std::string &data);
167 std::vector<char> _h1ReadResponse(
const std::string &label);
171 bool _h2PrefaceSent =
false;
174 uint32_t _h2NextStreamId = 1;
175 std::unique_ptr<hpack::Decoder> _h2Decoder;
176 const std::vector<char> _h2Request(
const std::string &method,
178 const std::vector<char> *postBody =
nullptr);
179 const std::vector<char> _h3Request(
const std::string &method,
181 const std::vector<char> *postBody =
nullptr);
184 enum StreamMode { STREAM_NONE, STREAM_CONTENT_LENGTH, STREAM_CHUNKED, STREAM_EOF,
185 STREAM_H2, STREAM_H3 };
186 StreamMode _streamMode = STREAM_NONE;
187 size_t _streamRemaining = 0;
188 std::vector<char> _streamBuf;
189 size_t _streamBufPos = 0;
191 bool _streamChunkDone =
false;
192 size_t _streamChunkRemaining = 0;
195 uint32_t _streamH2Sid = 0;
196 bool _streamH2EndStream =
false;
197 std::vector<uint8_t> _streamH2Raw;
200 uint64_t _streamH3Sid = 0;
201 bool _streamH3EndStream =
false;
202 std::vector<uint8_t> _streamH3Raw;
203 std::vector<char> _streamH3Body;
204 size_t _streamH3BodyPos = 0;
205 bool _streamH3InDataFrame =
false;
206 uint64_t _streamH3DataRemaining = 0;
210 std::unique_ptr<netplus::socket> _cltsock;
211 netplus::socketwait _sw;
212 netplus::x509cert _cert;
213 int _recvTimeoutSec = 60;
214 int _sendTimeoutSec = 30;
218 int _lastStatusCode = 0;
219 std::string _lastLocation;
220 std::string _lastContentType;
221 std::unique_ptr<HttpResponse> _lastResponse;
222 static constexpr int MAX_REDIRECTS = 5;
223 int _maxRedirects = MAX_REDIRECTS;
311 void setState(
const std ::string &httpstate);
312 void setContentType(
const std ::string &type);
313 void setContentLength(
size_t len);
314 void setConnection(
const std ::string &type);
315 void setTransferEncoding(
const std ::string &enc);
318 const std ::string &getState()
const;
319 int getStatusCode()
const;
320 const std ::string &getContentType()
const;
321 size_t getContentLength()
const;
322 const std ::string &getConnection()
const;
323 const std ::string &getVersion()
const;
326 size_t printHeader(std::vector<char> &buffer);
329 void send(netplus::con &curconnection,
const std::string &data,
int datalen=0);
330 void send(netplus::con &curconnection,
const unsigned char *data,
int datalen);
331 void send(netplus::con &curconnection,
const std::vector<char> &data,
int datalen=0);
338 void sendChunkedHeaders(netplus::con &curconnection);
339 void sendChunk(netplus::con &curconnection,
const char *data,
size_t len);
340 void endChunked(netplus::con &curconnection);
343 size_t parse(
const char *in,
size_t inlen);
346 bool _storeResponseInfo(netplus::con &curconnection,
int datalen);
348 std::string _State=HTTP200;
349 std::string _Version;
355 mutable std::string _ContentTypeCache;
372 size_t parseH2(
const std::vector<hpack::HeaderField> &headers, uint32_t stream_id = 0);
373 size_t parseH3(
const std::vector<qpack::HeaderField> &headers);
375 void printHeader(std::string &buffer);
376 int getRequestType();
377 const std::string &getRequestURL();
378 const std::string &getRequest();
379 size_t getRequestLength();
380 const std::string &getRequestVersion();
381 const std::string &getHost();
382 size_t getContentLength();
383 size_t getMaxUploadSize();
389 bool isChunkedRequest();
390 int decodeChunkedBody();
396 void setRequestType(
int req);
397 void setRequestURL(
const std::string &url);
398 void setRequestVersion(
const std::string &version);
400 void setRequestData(
const std::string &data,
size_t len);
401 void setMaxUploadSize(
size_t upsize);
403 void send(
const HttpUrl &dest,std::unique_ptr<netplus::socket> &sock);
412 static std::string extractPath(
const std::string &target);
414 int _RequestType = PARSEREQUEST;
415 size_t _MaxUploadSize = DEFAULT_UPLOADSIZE;
419 mutable std::string _cachedRequestURL;
420 mutable std::string _cachedRequest;
421 mutable std::string _cachedRequestVersion;
422 mutable std::string _cachedHost;
428 int _httpProtocol = 0;
430 struct H2PendingResponse {
438 struct H2StreamingResponse {
439 uint32_t streamId = 0;
440 size_t contentLength = 0;
441 size_t totalSent = 0;
442 std::string pendingData;
443 size_t pendingOffset = 0;
444 std::unique_ptr<HttpRequest> tempreq;
447 size_t emptyCount = 0;
448 unsigned int backoffMs = 1;
449 bool finished =
false;
452 struct H2PendingIncoming {
453 std::vector<hpack::HeaderField> headers;
455 std::vector<uint8_t> rawHpack;
456 bool headersComplete =
false;
457 bool endStreamOnHeaders =
false;
458 bool streaming =
false;
462 uint32_t streamId = 0;
463 bool headersSent =
false;
464 bool serverPrefaceSent =
false;
465 size_t expectedContentLength = 0;
466 size_t bodyBytesSent = 0;
467 std::deque<H2PendingResponse> pendingResponses;
468 std::map<uint32_t, H2PendingIncoming> pendingIncoming;
471 int32_t peerConnWindow = 65535;
472 int32_t peerInitialStreamWindow = 65535;
473 size_t peerMaxFrameSize = 16384;
474 std::map<uint32_t, int32_t> peerStreamWindows;
476 std::map<uint32_t, std::shared_ptr<H2StreamingResponse>> activeStreams;
480 std::unique_ptr<H2State> _h2;
484 if (!_h2) _h2 = std::make_unique<H2State>();
507 std::vector<Header> headers;
508 std::vector<Disposition> dispositions;
509 std::vector<char> value;
524 const std::string &getContentType()
const {
return _contentType; }
525 const std::string &getBoundary()
const {
return _boundary; }
526 const std::vector<MultipartEntry> &multipartData()
const {
return _multipartEntries; }
527 const std::vector<UrlEntry> &urlData()
const {
return _urlEntries; }
530 static void urlDecode(
const std::string &in, std::string &out);
531 static void urlEncode(
const std::string &in, std::string &out);
534 void _parseMultipart(
const char *data,
size_t len);
535 void _parseMultiSection(
const char *data,
size_t len,
size_t start,
size_t end);
536 void _parseUrlDecode(
const char *data,
size_t len);
538 std::string _boundary;
539 std::string _contentType;
540 std::vector<MultipartEntry> _multipartEntries;
541 std::vector<UrlEntry> _urlEntries;