123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229 |
- #ifndef HEADER_CURL_REQUEST_H
- #define HEADER_CURL_REQUEST_H
- /***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at https://curl.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * SPDX-License-Identifier: curl
- *
- ***************************************************************************/
- /* This file is for lib internal stuff */
- #include "curl_setup.h"
- #include "bufq.h"
- /* forward declarations */
- struct UserDefined;
- enum expect100 {
- EXP100_SEND_DATA, /* enough waiting, just send the body now */
- EXP100_AWAITING_CONTINUE, /* waiting for the 100 Continue header */
- EXP100_SENDING_REQUEST, /* still sending the request but will wait for
- the 100 header once done with the request */
- EXP100_FAILED /* used on 417 Expectation Failed */
- };
- enum upgrade101 {
- UPGR101_INIT, /* default state */
- UPGR101_WS, /* upgrade to WebSockets requested */
- UPGR101_H2, /* upgrade to HTTP/2 requested */
- UPGR101_RECEIVED, /* 101 response received */
- UPGR101_WORKING /* talking upgraded protocol */
- };
- /*
- * Request specific data in the easy handle (Curl_easy). Previously,
- * these members were on the connectdata struct but since a conn struct may
- * now be shared between different Curl_easys, we store connection-specific
- * data here. This struct only keeps stuff that is interesting for *this*
- * request, as it will be cleared between multiple ones
- */
- struct SingleRequest {
- curl_off_t size; /* -1 if unknown at this point */
- curl_off_t maxdownload; /* in bytes, the maximum amount of data to fetch,
- -1 means unlimited */
- curl_off_t bytecount; /* total number of bytes read */
- curl_off_t writebytecount; /* number of bytes written */
- struct curltime start; /* transfer started at this time */
- unsigned int headerbytecount; /* received server headers (not CONNECT
- headers) */
- unsigned int allheadercount; /* all received headers (server + CONNECT) */
- unsigned int deductheadercount; /* this amount of bytes does not count when
- we check if anything has been transferred
- at the end of a connection. We use this
- counter to make only a 100 reply (without
- a following second response code) result
- in a CURLE_GOT_NOTHING error code */
- int headerline; /* counts header lines to better track the
- first one */
- curl_off_t offset; /* possible resume offset read from the
- Content-Range: header */
- int httpversion; /* Version in response (09, 10, 11, etc.) */
- int httpcode; /* error code from the 'HTTP/1.? XXX' or
- 'RTSP/1.? XXX' line */
- int keepon;
- enum upgrade101 upgr101; /* 101 upgrade state */
- /* Client Writer stack, handles transfer- and content-encodings, protocol
- * checks, pausing by client callbacks. */
- struct Curl_cwriter *writer_stack;
- /* Client Reader stack, handles transfer- and content-encodings, protocol
- * checks, pausing by client callbacks. */
- struct Curl_creader *reader_stack;
- struct bufq sendbuf; /* data which needs to be send to the server */
- size_t sendbuf_hds_len; /* amount of header bytes in sendbuf */
- time_t timeofdoc;
- char *location; /* This points to an allocated version of the Location:
- header data */
- char *newurl; /* Set to the new URL to use when a redirect or a retry is
- wanted */
- /* Allocated protocol-specific data. Each protocol handler makes sure this
- points to data it needs. */
- union {
- struct FILEPROTO *file;
- struct FTP *ftp;
- struct IMAP *imap;
- struct ldapreqinfo *ldap;
- struct MQTT *mqtt;
- struct POP3 *pop3;
- struct RTSP *rtsp;
- struct smb_request *smb;
- struct SMTP *smtp;
- struct SSHPROTO *ssh;
- struct TELNET *telnet;
- } p;
- #ifndef CURL_DISABLE_DOH
- struct dohdata *doh; /* DoH specific data for this request */
- #endif
- #ifndef CURL_DISABLE_COOKIES
- unsigned char setcookies;
- #endif
- BIT(header); /* incoming data has HTTP header */
- BIT(done); /* request is done, e.g. no more send/recv should
- * happen. This can be TRUE before `upload_done` or
- * `download_done` is TRUE. */
- BIT(content_range); /* set TRUE if Content-Range: was found */
- BIT(download_done); /* set to TRUE when download is complete */
- BIT(eos_written); /* iff EOS has been written to client */
- BIT(eos_read); /* iff EOS has been read from the client */
- BIT(rewind_read); /* iff reader needs rewind at next start */
- BIT(upload_done); /* set to TRUE when all request data has been sent */
- BIT(upload_aborted); /* set to TRUE when upload was aborted. Will also
- * show `upload_done` as TRUE. */
- BIT(ignorebody); /* we read a response-body but we ignore it! */
- BIT(http_bodyless); /* HTTP response status code is between 100 and 199,
- 204 or 304 */
- BIT(chunk); /* if set, this is a chunked transfer-encoding */
- BIT(ignore_cl); /* ignore content-length */
- BIT(upload_chunky); /* set TRUE if we are doing chunked transfer-encoding
- on upload */
- BIT(getheader); /* TRUE if header parsing is wanted */
- BIT(no_body); /* the response has no body */
- BIT(authneg); /* TRUE when the auth phase has started, which means
- that we are creating a request with an auth header,
- but it is not the final request in the auth
- negotiation. */
- BIT(sendbuf_init); /* sendbuf is initialized */
- BIT(shutdown); /* request end will shutdown connection */
- #ifdef USE_HYPER
- BIT(bodywritten);
- #endif
- };
- /**
- * Initialize the state of the request for first use.
- */
- void Curl_req_init(struct SingleRequest *req);
- /**
- * The request is about to start. Record time and do a soft reset.
- */
- CURLcode Curl_req_start(struct SingleRequest *req,
- struct Curl_easy *data);
- /**
- * The request may continue with a follow up. Reset
- * members, but keep start time for overall duration calc.
- */
- CURLcode Curl_req_soft_reset(struct SingleRequest *req,
- struct Curl_easy *data);
- /**
- * The request is done. If not aborted, make sure that buffers are
- * flushed to the client.
- * @param req the request
- * @param data the transfer
- * @param aborted TRUE iff the request was aborted/errored
- */
- CURLcode Curl_req_done(struct SingleRequest *req,
- struct Curl_easy *data, bool aborted);
- /**
- * Free the state of the request, not usable afterwards.
- */
- void Curl_req_free(struct SingleRequest *req, struct Curl_easy *data);
- /**
- * Hard reset the state of the request to virgin state base on
- * transfer settings.
- */
- void Curl_req_hard_reset(struct SingleRequest *req, struct Curl_easy *data);
- #ifndef USE_HYPER
- /**
- * Send request headers. If not all could be sent
- * they will be buffered. Use `Curl_req_flush()` to make sure
- * bytes are really send.
- * @param data the transfer making the request
- * @param buf the complete header bytes, no body
- * @return CURLE_OK (on blocking with *pnwritten == 0) or error.
- */
- CURLcode Curl_req_send(struct Curl_easy *data, struct dynbuf *buf);
- #endif /* !USE_HYPER */
- /**
- * TRUE iff the request has sent all request headers and data.
- */
- bool Curl_req_done_sending(struct Curl_easy *data);
- /*
- * Read more from client and flush all buffered request bytes.
- * @return CURLE_OK on success or the error on the sending.
- * Never returns CURLE_AGAIN.
- */
- CURLcode Curl_req_send_more(struct Curl_easy *data);
- /**
- * TRUE iff the request wants to send, e.g. has buffered bytes.
- */
- bool Curl_req_want_send(struct Curl_easy *data);
- /**
- * Stop sending any more request data to the server.
- * Will clear the send buffer and mark request sending as done.
- */
- CURLcode Curl_req_abort_sending(struct Curl_easy *data);
- #endif /* HEADER_CURL_REQUEST_H */
|