1*6236dae4SAndroid Build Coastguard Worker #ifndef HEADER_CURL_HTTP_CHUNKS_H 2*6236dae4SAndroid Build Coastguard Worker #define HEADER_CURL_HTTP_CHUNKS_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 #ifndef CURL_DISABLE_HTTP 28*6236dae4SAndroid Build Coastguard Worker 29*6236dae4SAndroid Build Coastguard Worker #include "dynbuf.h" 30*6236dae4SAndroid Build Coastguard Worker 31*6236dae4SAndroid Build Coastguard Worker struct connectdata; 32*6236dae4SAndroid Build Coastguard Worker 33*6236dae4SAndroid Build Coastguard Worker /* 34*6236dae4SAndroid Build Coastguard Worker * The longest possible hexadecimal number we support in a chunked transfer. 35*6236dae4SAndroid Build Coastguard Worker * Neither RFC2616 nor the later HTTP specs define a maximum chunk size. 36*6236dae4SAndroid Build Coastguard Worker * For 64-bit curl_off_t we support 16 digits. For 32-bit, 8 digits. 37*6236dae4SAndroid Build Coastguard Worker */ 38*6236dae4SAndroid Build Coastguard Worker #define CHUNK_MAXNUM_LEN (SIZEOF_CURL_OFF_T * 2) 39*6236dae4SAndroid Build Coastguard Worker 40*6236dae4SAndroid Build Coastguard Worker typedef enum { 41*6236dae4SAndroid Build Coastguard Worker /* await and buffer all hexadecimal digits until we get one that is not a 42*6236dae4SAndroid Build Coastguard Worker hexadecimal digit. When done, we go CHUNK_LF */ 43*6236dae4SAndroid Build Coastguard Worker CHUNK_HEX, 44*6236dae4SAndroid Build Coastguard Worker 45*6236dae4SAndroid Build Coastguard Worker /* wait for LF, ignore all else */ 46*6236dae4SAndroid Build Coastguard Worker CHUNK_LF, 47*6236dae4SAndroid Build Coastguard Worker 48*6236dae4SAndroid Build Coastguard Worker /* We eat the amount of data specified. When done, we move on to the 49*6236dae4SAndroid Build Coastguard Worker POST_CR state. */ 50*6236dae4SAndroid Build Coastguard Worker CHUNK_DATA, 51*6236dae4SAndroid Build Coastguard Worker 52*6236dae4SAndroid Build Coastguard Worker /* POSTLF should get a CR and then a LF and nothing else, then move back to 53*6236dae4SAndroid Build Coastguard Worker HEX as the CRLF combination marks the end of a chunk. A missing CR is no 54*6236dae4SAndroid Build Coastguard Worker big deal. */ 55*6236dae4SAndroid Build Coastguard Worker CHUNK_POSTLF, 56*6236dae4SAndroid Build Coastguard Worker 57*6236dae4SAndroid Build Coastguard Worker /* Used to mark that we are out of the game. NOTE: that there is a 58*6236dae4SAndroid Build Coastguard Worker 'datasize' field in the struct that will tell how many bytes that were 59*6236dae4SAndroid Build Coastguard Worker not passed to the client in the end of the last buffer! */ 60*6236dae4SAndroid Build Coastguard Worker CHUNK_STOP, 61*6236dae4SAndroid Build Coastguard Worker 62*6236dae4SAndroid Build Coastguard Worker /* At this point optional trailer headers can be found, unless the next line 63*6236dae4SAndroid Build Coastguard Worker is CRLF */ 64*6236dae4SAndroid Build Coastguard Worker CHUNK_TRAILER, 65*6236dae4SAndroid Build Coastguard Worker 66*6236dae4SAndroid Build Coastguard Worker /* A trailer CR has been found - next state is CHUNK_TRAILER_POSTCR. 67*6236dae4SAndroid Build Coastguard Worker Next char must be a LF */ 68*6236dae4SAndroid Build Coastguard Worker CHUNK_TRAILER_CR, 69*6236dae4SAndroid Build Coastguard Worker 70*6236dae4SAndroid Build Coastguard Worker /* A trailer LF must be found now, otherwise CHUNKE_BAD_CHUNK will be 71*6236dae4SAndroid Build Coastguard Worker signalled If this is an empty trailer CHUNKE_STOP will be signalled. 72*6236dae4SAndroid Build Coastguard Worker Otherwise the trailer will be broadcasted via Curl_client_write() and the 73*6236dae4SAndroid Build Coastguard Worker next state will be CHUNK_TRAILER */ 74*6236dae4SAndroid Build Coastguard Worker CHUNK_TRAILER_POSTCR, 75*6236dae4SAndroid Build Coastguard Worker 76*6236dae4SAndroid Build Coastguard Worker /* Successfully de-chunked everything */ 77*6236dae4SAndroid Build Coastguard Worker CHUNK_DONE, 78*6236dae4SAndroid Build Coastguard Worker 79*6236dae4SAndroid Build Coastguard Worker /* Failed on seeing a bad or not correctly terminated chunk */ 80*6236dae4SAndroid Build Coastguard Worker CHUNK_FAILED 81*6236dae4SAndroid Build Coastguard Worker } ChunkyState; 82*6236dae4SAndroid Build Coastguard Worker 83*6236dae4SAndroid Build Coastguard Worker typedef enum { 84*6236dae4SAndroid Build Coastguard Worker CHUNKE_OK = 0, 85*6236dae4SAndroid Build Coastguard Worker CHUNKE_TOO_LONG_HEX = 1, 86*6236dae4SAndroid Build Coastguard Worker CHUNKE_ILLEGAL_HEX, 87*6236dae4SAndroid Build Coastguard Worker CHUNKE_BAD_CHUNK, 88*6236dae4SAndroid Build Coastguard Worker CHUNKE_BAD_ENCODING, 89*6236dae4SAndroid Build Coastguard Worker CHUNKE_OUT_OF_MEMORY, 90*6236dae4SAndroid Build Coastguard Worker CHUNKE_PASSTHRU_ERROR /* Curl_httpchunk_read() returns a CURLcode to use */ 91*6236dae4SAndroid Build Coastguard Worker } CHUNKcode; 92*6236dae4SAndroid Build Coastguard Worker 93*6236dae4SAndroid Build Coastguard Worker struct Curl_chunker { 94*6236dae4SAndroid Build Coastguard Worker curl_off_t datasize; 95*6236dae4SAndroid Build Coastguard Worker ChunkyState state; 96*6236dae4SAndroid Build Coastguard Worker CHUNKcode last_code; 97*6236dae4SAndroid Build Coastguard Worker struct dynbuf trailer; /* for chunked-encoded trailer */ 98*6236dae4SAndroid Build Coastguard Worker unsigned char hexindex; 99*6236dae4SAndroid Build Coastguard Worker char hexbuffer[CHUNK_MAXNUM_LEN + 1]; /* +1 for null-terminator */ 100*6236dae4SAndroid Build Coastguard Worker BIT(ignore_body); /* never write response body data */ 101*6236dae4SAndroid Build Coastguard Worker }; 102*6236dae4SAndroid Build Coastguard Worker 103*6236dae4SAndroid Build Coastguard Worker /* The following functions are defined in http_chunks.c */ 104*6236dae4SAndroid Build Coastguard Worker void Curl_httpchunk_init(struct Curl_easy *data, struct Curl_chunker *ch, 105*6236dae4SAndroid Build Coastguard Worker bool ignore_body); 106*6236dae4SAndroid Build Coastguard Worker void Curl_httpchunk_free(struct Curl_easy *data, struct Curl_chunker *ch); 107*6236dae4SAndroid Build Coastguard Worker void Curl_httpchunk_reset(struct Curl_easy *data, struct Curl_chunker *ch, 108*6236dae4SAndroid Build Coastguard Worker bool ignore_body); 109*6236dae4SAndroid Build Coastguard Worker 110*6236dae4SAndroid Build Coastguard Worker /* 111*6236dae4SAndroid Build Coastguard Worker * Read BODY bytes in HTTP/1.1 chunked encoding from `buf` and return 112*6236dae4SAndroid Build Coastguard Worker * the amount of bytes consumed. The actual response bytes and trailer 113*6236dae4SAndroid Build Coastguard Worker * headers are written out to the client. 114*6236dae4SAndroid Build Coastguard Worker * On success, this will consume all bytes up to the end of the response, 115*6236dae4SAndroid Build Coastguard Worker * e.g. the last chunk, has been processed. 116*6236dae4SAndroid Build Coastguard Worker * @param data the transfer involved 117*6236dae4SAndroid Build Coastguard Worker * @param ch the chunker instance keeping state across calls 118*6236dae4SAndroid Build Coastguard Worker * @param buf the response data 119*6236dae4SAndroid Build Coastguard Worker * @param blen amount of bytes in `buf` 120*6236dae4SAndroid Build Coastguard Worker * @param pconsumed on successful return, the number of bytes in `buf` 121*6236dae4SAndroid Build Coastguard Worker * consumed 122*6236dae4SAndroid Build Coastguard Worker * 123*6236dae4SAndroid Build Coastguard Worker * This function always uses ASCII hex values to accommodate non-ASCII hosts. 124*6236dae4SAndroid Build Coastguard Worker * For example, 0x0d and 0x0a are used instead of '\r' and '\n'. 125*6236dae4SAndroid Build Coastguard Worker */ 126*6236dae4SAndroid Build Coastguard Worker CURLcode Curl_httpchunk_read(struct Curl_easy *data, struct Curl_chunker *ch, 127*6236dae4SAndroid Build Coastguard Worker char *buf, size_t blen, size_t *pconsumed); 128*6236dae4SAndroid Build Coastguard Worker 129*6236dae4SAndroid Build Coastguard Worker /** 130*6236dae4SAndroid Build Coastguard Worker * @return TRUE iff chunked decoded has finished successfully. 131*6236dae4SAndroid Build Coastguard Worker */ 132*6236dae4SAndroid Build Coastguard Worker bool Curl_httpchunk_is_done(struct Curl_easy *data, struct Curl_chunker *ch); 133*6236dae4SAndroid Build Coastguard Worker 134*6236dae4SAndroid Build Coastguard Worker extern const struct Curl_cwtype Curl_httpchunk_unencoder; 135*6236dae4SAndroid Build Coastguard Worker 136*6236dae4SAndroid Build Coastguard Worker extern const struct Curl_crtype Curl_httpchunk_encoder; 137*6236dae4SAndroid Build Coastguard Worker 138*6236dae4SAndroid Build Coastguard Worker /** 139*6236dae4SAndroid Build Coastguard Worker * Add a transfer-encoding "chunked" reader to the transfers reader stack 140*6236dae4SAndroid Build Coastguard Worker */ 141*6236dae4SAndroid Build Coastguard Worker CURLcode Curl_httpchunk_add_reader(struct Curl_easy *data); 142*6236dae4SAndroid Build Coastguard Worker 143*6236dae4SAndroid Build Coastguard Worker #endif /* !CURL_DISABLE_HTTP */ 144*6236dae4SAndroid Build Coastguard Worker 145*6236dae4SAndroid Build Coastguard Worker #endif /* HEADER_CURL_HTTP_CHUNKS_H */ 146