1*6236dae4SAndroid Build Coastguard Worker #ifndef HEADER_CURL_REQUEST_H 2*6236dae4SAndroid Build Coastguard Worker #define HEADER_CURL_REQUEST_H 3*6236dae4SAndroid Build Coastguard Worker /*************************************************************************** 4*6236dae4SAndroid Build Coastguard Worker * _ _ ____ _ 5*6236dae4SAndroid Build Coastguard Worker * Project ___| | | | _ \| | 6*6236dae4SAndroid Build Coastguard Worker * / __| | | | |_) | | 7*6236dae4SAndroid Build Coastguard Worker * | (__| |_| | _ <| |___ 8*6236dae4SAndroid Build Coastguard Worker * \___|\___/|_| \_\_____| 9*6236dae4SAndroid Build Coastguard Worker * 10*6236dae4SAndroid Build Coastguard Worker * Copyright (C) Daniel Stenberg, <[email protected]>, et al. 11*6236dae4SAndroid Build Coastguard Worker * 12*6236dae4SAndroid Build Coastguard Worker * This software is licensed as described in the file COPYING, which 13*6236dae4SAndroid Build Coastguard Worker * you should have received as part of this distribution. The terms 14*6236dae4SAndroid Build Coastguard Worker * are also available at https://curl.se/docs/copyright.html. 15*6236dae4SAndroid Build Coastguard Worker * 16*6236dae4SAndroid Build Coastguard Worker * You may opt to use, copy, modify, merge, publish, distribute and/or sell 17*6236dae4SAndroid Build Coastguard Worker * copies of the Software, and permit persons to whom the Software is 18*6236dae4SAndroid Build Coastguard Worker * furnished to do so, under the terms of the COPYING file. 19*6236dae4SAndroid Build Coastguard Worker * 20*6236dae4SAndroid Build Coastguard Worker * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 21*6236dae4SAndroid Build Coastguard Worker * KIND, either express or implied. 22*6236dae4SAndroid Build Coastguard Worker * 23*6236dae4SAndroid Build Coastguard Worker * SPDX-License-Identifier: curl 24*6236dae4SAndroid Build Coastguard Worker * 25*6236dae4SAndroid Build Coastguard Worker ***************************************************************************/ 26*6236dae4SAndroid Build Coastguard Worker 27*6236dae4SAndroid Build Coastguard Worker /* This file is for lib internal stuff */ 28*6236dae4SAndroid Build Coastguard Worker 29*6236dae4SAndroid Build Coastguard Worker #include "curl_setup.h" 30*6236dae4SAndroid Build Coastguard Worker 31*6236dae4SAndroid Build Coastguard Worker #include "bufq.h" 32*6236dae4SAndroid Build Coastguard Worker 33*6236dae4SAndroid Build Coastguard Worker /* forward declarations */ 34*6236dae4SAndroid Build Coastguard Worker struct UserDefined; 35*6236dae4SAndroid Build Coastguard Worker #ifndef CURL_DISABLE_DOH 36*6236dae4SAndroid Build Coastguard Worker struct doh_probes; 37*6236dae4SAndroid Build Coastguard Worker #endif 38*6236dae4SAndroid Build Coastguard Worker 39*6236dae4SAndroid Build Coastguard Worker enum expect100 { 40*6236dae4SAndroid Build Coastguard Worker EXP100_SEND_DATA, /* enough waiting, just send the body now */ 41*6236dae4SAndroid Build Coastguard Worker EXP100_AWAITING_CONTINUE, /* waiting for the 100 Continue header */ 42*6236dae4SAndroid Build Coastguard Worker EXP100_SENDING_REQUEST, /* still sending the request but will wait for 43*6236dae4SAndroid Build Coastguard Worker the 100 header once done with the request */ 44*6236dae4SAndroid Build Coastguard Worker EXP100_FAILED /* used on 417 Expectation Failed */ 45*6236dae4SAndroid Build Coastguard Worker }; 46*6236dae4SAndroid Build Coastguard Worker 47*6236dae4SAndroid Build Coastguard Worker enum upgrade101 { 48*6236dae4SAndroid Build Coastguard Worker UPGR101_INIT, /* default state */ 49*6236dae4SAndroid Build Coastguard Worker UPGR101_WS, /* upgrade to WebSockets requested */ 50*6236dae4SAndroid Build Coastguard Worker UPGR101_H2, /* upgrade to HTTP/2 requested */ 51*6236dae4SAndroid Build Coastguard Worker UPGR101_RECEIVED, /* 101 response received */ 52*6236dae4SAndroid Build Coastguard Worker UPGR101_WORKING /* talking upgraded protocol */ 53*6236dae4SAndroid Build Coastguard Worker }; 54*6236dae4SAndroid Build Coastguard Worker 55*6236dae4SAndroid Build Coastguard Worker 56*6236dae4SAndroid Build Coastguard Worker /* 57*6236dae4SAndroid Build Coastguard Worker * Request specific data in the easy handle (Curl_easy). Previously, 58*6236dae4SAndroid Build Coastguard Worker * these members were on the connectdata struct but since a conn struct may 59*6236dae4SAndroid Build Coastguard Worker * now be shared between different Curl_easys, we store connection-specific 60*6236dae4SAndroid Build Coastguard Worker * data here. This struct only keeps stuff that is interesting for *this* 61*6236dae4SAndroid Build Coastguard Worker * request, as it will be cleared between multiple ones 62*6236dae4SAndroid Build Coastguard Worker */ 63*6236dae4SAndroid Build Coastguard Worker struct SingleRequest { 64*6236dae4SAndroid Build Coastguard Worker curl_off_t size; /* -1 if unknown at this point */ 65*6236dae4SAndroid Build Coastguard Worker curl_off_t maxdownload; /* in bytes, the maximum amount of data to fetch, 66*6236dae4SAndroid Build Coastguard Worker -1 means unlimited */ 67*6236dae4SAndroid Build Coastguard Worker curl_off_t bytecount; /* total number of bytes read */ 68*6236dae4SAndroid Build Coastguard Worker curl_off_t writebytecount; /* number of bytes written */ 69*6236dae4SAndroid Build Coastguard Worker 70*6236dae4SAndroid Build Coastguard Worker struct curltime start; /* transfer started at this time */ 71*6236dae4SAndroid Build Coastguard Worker unsigned int headerbytecount; /* received server headers (not CONNECT 72*6236dae4SAndroid Build Coastguard Worker headers) */ 73*6236dae4SAndroid Build Coastguard Worker unsigned int allheadercount; /* all received headers (server + CONNECT) */ 74*6236dae4SAndroid Build Coastguard Worker unsigned int deductheadercount; /* this amount of bytes does not count when 75*6236dae4SAndroid Build Coastguard Worker we check if anything has been transferred 76*6236dae4SAndroid Build Coastguard Worker at the end of a connection. We use this 77*6236dae4SAndroid Build Coastguard Worker counter to make only a 100 reply (without 78*6236dae4SAndroid Build Coastguard Worker a following second response code) result 79*6236dae4SAndroid Build Coastguard Worker in a CURLE_GOT_NOTHING error code */ 80*6236dae4SAndroid Build Coastguard Worker int headerline; /* counts header lines to better track the 81*6236dae4SAndroid Build Coastguard Worker first one */ 82*6236dae4SAndroid Build Coastguard Worker curl_off_t offset; /* possible resume offset read from the 83*6236dae4SAndroid Build Coastguard Worker Content-Range: header */ 84*6236dae4SAndroid Build Coastguard Worker int httpversion; /* Version in response (09, 10, 11, etc.) */ 85*6236dae4SAndroid Build Coastguard Worker int httpcode; /* error code from the 'HTTP/1.? XXX' or 86*6236dae4SAndroid Build Coastguard Worker 'RTSP/1.? XXX' line */ 87*6236dae4SAndroid Build Coastguard Worker int keepon; 88*6236dae4SAndroid Build Coastguard Worker enum upgrade101 upgr101; /* 101 upgrade state */ 89*6236dae4SAndroid Build Coastguard Worker 90*6236dae4SAndroid Build Coastguard Worker /* Client Writer stack, handles transfer- and content-encodings, protocol 91*6236dae4SAndroid Build Coastguard Worker * checks, pausing by client callbacks. */ 92*6236dae4SAndroid Build Coastguard Worker struct Curl_cwriter *writer_stack; 93*6236dae4SAndroid Build Coastguard Worker /* Client Reader stack, handles transfer- and content-encodings, protocol 94*6236dae4SAndroid Build Coastguard Worker * checks, pausing by client callbacks. */ 95*6236dae4SAndroid Build Coastguard Worker struct Curl_creader *reader_stack; 96*6236dae4SAndroid Build Coastguard Worker struct bufq sendbuf; /* data which needs to be send to the server */ 97*6236dae4SAndroid Build Coastguard Worker size_t sendbuf_hds_len; /* amount of header bytes in sendbuf */ 98*6236dae4SAndroid Build Coastguard Worker time_t timeofdoc; 99*6236dae4SAndroid Build Coastguard Worker char *location; /* This points to an allocated version of the Location: 100*6236dae4SAndroid Build Coastguard Worker header data */ 101*6236dae4SAndroid Build Coastguard Worker char *newurl; /* Set to the new URL to use when a redirect or a retry is 102*6236dae4SAndroid Build Coastguard Worker wanted */ 103*6236dae4SAndroid Build Coastguard Worker 104*6236dae4SAndroid Build Coastguard Worker /* Allocated protocol-specific data. Each protocol handler makes sure this 105*6236dae4SAndroid Build Coastguard Worker points to data it needs. */ 106*6236dae4SAndroid Build Coastguard Worker union { 107*6236dae4SAndroid Build Coastguard Worker struct FILEPROTO *file; 108*6236dae4SAndroid Build Coastguard Worker struct FTP *ftp; 109*6236dae4SAndroid Build Coastguard Worker struct IMAP *imap; 110*6236dae4SAndroid Build Coastguard Worker struct ldapreqinfo *ldap; 111*6236dae4SAndroid Build Coastguard Worker struct MQTT *mqtt; 112*6236dae4SAndroid Build Coastguard Worker struct POP3 *pop3; 113*6236dae4SAndroid Build Coastguard Worker struct RTSP *rtsp; 114*6236dae4SAndroid Build Coastguard Worker struct smb_request *smb; 115*6236dae4SAndroid Build Coastguard Worker struct SMTP *smtp; 116*6236dae4SAndroid Build Coastguard Worker struct SSHPROTO *ssh; 117*6236dae4SAndroid Build Coastguard Worker struct TELNET *telnet; 118*6236dae4SAndroid Build Coastguard Worker } p; 119*6236dae4SAndroid Build Coastguard Worker #ifndef CURL_DISABLE_DOH 120*6236dae4SAndroid Build Coastguard Worker struct doh_probes *doh; /* DoH specific data for this request */ 121*6236dae4SAndroid Build Coastguard Worker #endif 122*6236dae4SAndroid Build Coastguard Worker #ifndef CURL_DISABLE_COOKIES 123*6236dae4SAndroid Build Coastguard Worker unsigned char setcookies; 124*6236dae4SAndroid Build Coastguard Worker #endif 125*6236dae4SAndroid Build Coastguard Worker BIT(header); /* incoming data has HTTP header */ 126*6236dae4SAndroid Build Coastguard Worker BIT(done); /* request is done, e.g. no more send/recv should 127*6236dae4SAndroid Build Coastguard Worker * happen. This can be TRUE before `upload_done` or 128*6236dae4SAndroid Build Coastguard Worker * `download_done` is TRUE. */ 129*6236dae4SAndroid Build Coastguard Worker BIT(content_range); /* set TRUE if Content-Range: was found */ 130*6236dae4SAndroid Build Coastguard Worker BIT(download_done); /* set to TRUE when download is complete */ 131*6236dae4SAndroid Build Coastguard Worker BIT(eos_written); /* iff EOS has been written to client */ 132*6236dae4SAndroid Build Coastguard Worker BIT(eos_read); /* iff EOS has been read from the client */ 133*6236dae4SAndroid Build Coastguard Worker BIT(eos_sent); /* iff EOS has been sent to the server */ 134*6236dae4SAndroid Build Coastguard Worker BIT(rewind_read); /* iff reader needs rewind at next start */ 135*6236dae4SAndroid Build Coastguard Worker BIT(upload_done); /* set to TRUE when all request data has been sent */ 136*6236dae4SAndroid Build Coastguard Worker BIT(upload_aborted); /* set to TRUE when upload was aborted. Will also 137*6236dae4SAndroid Build Coastguard Worker * show `upload_done` as TRUE. */ 138*6236dae4SAndroid Build Coastguard Worker BIT(ignorebody); /* we read a response-body but we ignore it! */ 139*6236dae4SAndroid Build Coastguard Worker BIT(http_bodyless); /* HTTP response status code is between 100 and 199, 140*6236dae4SAndroid Build Coastguard Worker 204 or 304 */ 141*6236dae4SAndroid Build Coastguard Worker BIT(chunk); /* if set, this is a chunked transfer-encoding */ 142*6236dae4SAndroid Build Coastguard Worker BIT(resp_trailer); /* response carried 'Trailer:' header field */ 143*6236dae4SAndroid Build Coastguard Worker BIT(ignore_cl); /* ignore content-length */ 144*6236dae4SAndroid Build Coastguard Worker BIT(upload_chunky); /* set TRUE if we are doing chunked transfer-encoding 145*6236dae4SAndroid Build Coastguard Worker on upload */ 146*6236dae4SAndroid Build Coastguard Worker BIT(getheader); /* TRUE if header parsing is wanted */ 147*6236dae4SAndroid Build Coastguard Worker BIT(no_body); /* the response has no body */ 148*6236dae4SAndroid Build Coastguard Worker BIT(authneg); /* TRUE when the auth phase has started, which means 149*6236dae4SAndroid Build Coastguard Worker that we are creating a request with an auth header, 150*6236dae4SAndroid Build Coastguard Worker but it is not the final request in the auth 151*6236dae4SAndroid Build Coastguard Worker negotiation. */ 152*6236dae4SAndroid Build Coastguard Worker BIT(sendbuf_init); /* sendbuf is initialized */ 153*6236dae4SAndroid Build Coastguard Worker BIT(shutdown); /* request end will shutdown connection */ 154*6236dae4SAndroid Build Coastguard Worker BIT(shutdown_err_ignore); /* errors in shutdown will not fail request */ 155*6236dae4SAndroid Build Coastguard Worker #ifdef USE_HYPER 156*6236dae4SAndroid Build Coastguard Worker BIT(bodywritten); 157*6236dae4SAndroid Build Coastguard Worker #endif 158*6236dae4SAndroid Build Coastguard Worker }; 159*6236dae4SAndroid Build Coastguard Worker 160*6236dae4SAndroid Build Coastguard Worker /** 161*6236dae4SAndroid Build Coastguard Worker * Initialize the state of the request for first use. 162*6236dae4SAndroid Build Coastguard Worker */ 163*6236dae4SAndroid Build Coastguard Worker void Curl_req_init(struct SingleRequest *req); 164*6236dae4SAndroid Build Coastguard Worker 165*6236dae4SAndroid Build Coastguard Worker /** 166*6236dae4SAndroid Build Coastguard Worker * The request is about to start. Record time and do a soft reset. 167*6236dae4SAndroid Build Coastguard Worker */ 168*6236dae4SAndroid Build Coastguard Worker CURLcode Curl_req_start(struct SingleRequest *req, 169*6236dae4SAndroid Build Coastguard Worker struct Curl_easy *data); 170*6236dae4SAndroid Build Coastguard Worker 171*6236dae4SAndroid Build Coastguard Worker /** 172*6236dae4SAndroid Build Coastguard Worker * The request may continue with a follow up. Reset 173*6236dae4SAndroid Build Coastguard Worker * members, but keep start time for overall duration calc. 174*6236dae4SAndroid Build Coastguard Worker */ 175*6236dae4SAndroid Build Coastguard Worker CURLcode Curl_req_soft_reset(struct SingleRequest *req, 176*6236dae4SAndroid Build Coastguard Worker struct Curl_easy *data); 177*6236dae4SAndroid Build Coastguard Worker 178*6236dae4SAndroid Build Coastguard Worker /** 179*6236dae4SAndroid Build Coastguard Worker * The request is done. If not aborted, make sure that buffers are 180*6236dae4SAndroid Build Coastguard Worker * flushed to the client. 181*6236dae4SAndroid Build Coastguard Worker * @param req the request 182*6236dae4SAndroid Build Coastguard Worker * @param data the transfer 183*6236dae4SAndroid Build Coastguard Worker * @param aborted TRUE iff the request was aborted/errored 184*6236dae4SAndroid Build Coastguard Worker */ 185*6236dae4SAndroid Build Coastguard Worker CURLcode Curl_req_done(struct SingleRequest *req, 186*6236dae4SAndroid Build Coastguard Worker struct Curl_easy *data, bool aborted); 187*6236dae4SAndroid Build Coastguard Worker 188*6236dae4SAndroid Build Coastguard Worker /** 189*6236dae4SAndroid Build Coastguard Worker * Free the state of the request, not usable afterwards. 190*6236dae4SAndroid Build Coastguard Worker */ 191*6236dae4SAndroid Build Coastguard Worker void Curl_req_free(struct SingleRequest *req, struct Curl_easy *data); 192*6236dae4SAndroid Build Coastguard Worker 193*6236dae4SAndroid Build Coastguard Worker /** 194*6236dae4SAndroid Build Coastguard Worker * Hard reset the state of the request to virgin state base on 195*6236dae4SAndroid Build Coastguard Worker * transfer settings. 196*6236dae4SAndroid Build Coastguard Worker */ 197*6236dae4SAndroid Build Coastguard Worker void Curl_req_hard_reset(struct SingleRequest *req, struct Curl_easy *data); 198*6236dae4SAndroid Build Coastguard Worker 199*6236dae4SAndroid Build Coastguard Worker #ifndef USE_HYPER 200*6236dae4SAndroid Build Coastguard Worker /** 201*6236dae4SAndroid Build Coastguard Worker * Send request headers. If not all could be sent 202*6236dae4SAndroid Build Coastguard Worker * they will be buffered. Use `Curl_req_flush()` to make sure 203*6236dae4SAndroid Build Coastguard Worker * bytes are really send. 204*6236dae4SAndroid Build Coastguard Worker * @param data the transfer making the request 205*6236dae4SAndroid Build Coastguard Worker * @param buf the complete header bytes, no body 206*6236dae4SAndroid Build Coastguard Worker * @return CURLE_OK (on blocking with *pnwritten == 0) or error. 207*6236dae4SAndroid Build Coastguard Worker */ 208*6236dae4SAndroid Build Coastguard Worker CURLcode Curl_req_send(struct Curl_easy *data, struct dynbuf *buf); 209*6236dae4SAndroid Build Coastguard Worker 210*6236dae4SAndroid Build Coastguard Worker #endif /* !USE_HYPER */ 211*6236dae4SAndroid Build Coastguard Worker 212*6236dae4SAndroid Build Coastguard Worker /** 213*6236dae4SAndroid Build Coastguard Worker * TRUE iff the request has sent all request headers and data. 214*6236dae4SAndroid Build Coastguard Worker */ 215*6236dae4SAndroid Build Coastguard Worker bool Curl_req_done_sending(struct Curl_easy *data); 216*6236dae4SAndroid Build Coastguard Worker 217*6236dae4SAndroid Build Coastguard Worker /* 218*6236dae4SAndroid Build Coastguard Worker * Read more from client and flush all buffered request bytes. 219*6236dae4SAndroid Build Coastguard Worker * @return CURLE_OK on success or the error on the sending. 220*6236dae4SAndroid Build Coastguard Worker * Never returns CURLE_AGAIN. 221*6236dae4SAndroid Build Coastguard Worker */ 222*6236dae4SAndroid Build Coastguard Worker CURLcode Curl_req_send_more(struct Curl_easy *data); 223*6236dae4SAndroid Build Coastguard Worker 224*6236dae4SAndroid Build Coastguard Worker /** 225*6236dae4SAndroid Build Coastguard Worker * TRUE iff the request wants to send, e.g. has buffered bytes. 226*6236dae4SAndroid Build Coastguard Worker */ 227*6236dae4SAndroid Build Coastguard Worker bool Curl_req_want_send(struct Curl_easy *data); 228*6236dae4SAndroid Build Coastguard Worker 229*6236dae4SAndroid Build Coastguard Worker /** 230*6236dae4SAndroid Build Coastguard Worker * TRUE iff the request has no buffered bytes yet to send. 231*6236dae4SAndroid Build Coastguard Worker */ 232*6236dae4SAndroid Build Coastguard Worker bool Curl_req_sendbuf_empty(struct Curl_easy *data); 233*6236dae4SAndroid Build Coastguard Worker 234*6236dae4SAndroid Build Coastguard Worker /** 235*6236dae4SAndroid Build Coastguard Worker * Stop sending any more request data to the server. 236*6236dae4SAndroid Build Coastguard Worker * Will clear the send buffer and mark request sending as done. 237*6236dae4SAndroid Build Coastguard Worker */ 238*6236dae4SAndroid Build Coastguard Worker CURLcode Curl_req_abort_sending(struct Curl_easy *data); 239*6236dae4SAndroid Build Coastguard Worker 240*6236dae4SAndroid Build Coastguard Worker /** 241*6236dae4SAndroid Build Coastguard Worker * Stop sending and receiving any more request data. 242*6236dae4SAndroid Build Coastguard Worker * Will abort sending if not done. 243*6236dae4SAndroid Build Coastguard Worker */ 244*6236dae4SAndroid Build Coastguard Worker CURLcode Curl_req_stop_send_recv(struct Curl_easy *data); 245*6236dae4SAndroid Build Coastguard Worker 246*6236dae4SAndroid Build Coastguard Worker /** 247*6236dae4SAndroid Build Coastguard Worker * Invoked when all request data has been uploaded. 248*6236dae4SAndroid Build Coastguard Worker */ 249*6236dae4SAndroid Build Coastguard Worker CURLcode Curl_req_set_upload_done(struct Curl_easy *data); 250*6236dae4SAndroid Build Coastguard Worker 251*6236dae4SAndroid Build Coastguard Worker #endif /* HEADER_CURL_REQUEST_H */ 252