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