123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145 |
- #ifndef HEADER_CURL_HTTP_CHUNKS_H
- #define HEADER_CURL_HTTP_CHUNKS_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
- *
- ***************************************************************************/
- #ifndef CURL_DISABLE_HTTP
- #include "dynbuf.h"
- struct connectdata;
- /*
- * The longest possible hexadecimal number we support in a chunked transfer.
- * Neither RFC2616 nor the later HTTP specs define a maximum chunk size.
- * For 64 bit curl_off_t we support 16 digits. For 32 bit, 8 digits.
- */
- #define CHUNK_MAXNUM_LEN (SIZEOF_CURL_OFF_T * 2)
- typedef enum {
- /* await and buffer all hexadecimal digits until we get one that isn't a
- hexadecimal digit. When done, we go CHUNK_LF */
- CHUNK_HEX,
- /* wait for LF, ignore all else */
- CHUNK_LF,
- /* We eat the amount of data specified. When done, we move on to the
- POST_CR state. */
- CHUNK_DATA,
- /* POSTLF should get a CR and then a LF and nothing else, then move back to
- HEX as the CRLF combination marks the end of a chunk. A missing CR is no
- big deal. */
- CHUNK_POSTLF,
- /* Used to mark that we're out of the game. NOTE: that there's a 'datasize'
- field in the struct that will tell how many bytes that were not passed to
- the client in the end of the last buffer! */
- CHUNK_STOP,
- /* At this point optional trailer headers can be found, unless the next line
- is CRLF */
- CHUNK_TRAILER,
- /* A trailer CR has been found - next state is CHUNK_TRAILER_POSTCR.
- Next char must be a LF */
- CHUNK_TRAILER_CR,
- /* A trailer LF must be found now, otherwise CHUNKE_BAD_CHUNK will be
- signalled If this is an empty trailer CHUNKE_STOP will be signalled.
- Otherwise the trailer will be broadcasted via Curl_client_write() and the
- next state will be CHUNK_TRAILER */
- CHUNK_TRAILER_POSTCR,
- /* Successfully de-chunked everything */
- CHUNK_DONE,
- /* Failed on seeing a bad or not correctly terminated chunk */
- CHUNK_FAILED
- } ChunkyState;
- typedef enum {
- CHUNKE_OK = 0,
- CHUNKE_TOO_LONG_HEX = 1,
- CHUNKE_ILLEGAL_HEX,
- CHUNKE_BAD_CHUNK,
- CHUNKE_BAD_ENCODING,
- CHUNKE_OUT_OF_MEMORY,
- CHUNKE_PASSTHRU_ERROR /* Curl_httpchunk_read() returns a CURLcode to use */
- } CHUNKcode;
- struct Curl_chunker {
- curl_off_t datasize;
- ChunkyState state;
- CHUNKcode last_code;
- struct dynbuf trailer; /* for chunked-encoded trailer */
- unsigned char hexindex;
- char hexbuffer[CHUNK_MAXNUM_LEN + 1]; /* +1 for null-terminator */
- BIT(ignore_body); /* never write response body data */
- };
- /* The following functions are defined in http_chunks.c */
- void Curl_httpchunk_init(struct Curl_easy *data, struct Curl_chunker *ch,
- bool ignore_body);
- void Curl_httpchunk_free(struct Curl_easy *data, struct Curl_chunker *ch);
- void Curl_httpchunk_reset(struct Curl_easy *data, struct Curl_chunker *ch,
- bool ignore_body);
- /*
- * Read BODY bytes in HTTP/1.1 chunked encoding from `buf` and return
- * the amount of bytes consumed. The actual response bytes and trailer
- * headers are written out to the client.
- * On success, this will consume all bytes up to the end of the response,
- * e.g. the last chunk, has been processed.
- * @param data the transfer involved
- * @param ch the chunker instance keeping state across calls
- * @param buf the response data
- * @param blen amount of bytes in `buf`
- * @param pconsumed on successful return, the number of bytes in `buf`
- * consumed
- *
- * This function always uses ASCII hex values to accommodate non-ASCII hosts.
- * For example, 0x0d and 0x0a are used instead of '\r' and '\n'.
- */
- CURLcode Curl_httpchunk_read(struct Curl_easy *data, struct Curl_chunker *ch,
- char *buf, size_t blen, size_t *pconsumed);
- /**
- * @return TRUE iff chunked decoded has finished successfully.
- */
- bool Curl_httpchunk_is_done(struct Curl_easy *data, struct Curl_chunker *ch);
- extern const struct Curl_cwtype Curl_httpchunk_unencoder;
- extern const struct Curl_crtype Curl_httpchunk_encoder;
- /**
- * Add a transfer-encoding "chunked" reader to the transfers reader stack
- */
- CURLcode Curl_httpchunk_add_reader(struct Curl_easy *data);
- #endif /* !CURL_DISABLE_HTTP */
- #endif /* HEADER_CURL_HTTP_CHUNKS_H */
|