113498266Sopenharmony_ci#ifndef HEADER_CURL_HTTP_CHUNKS_H
213498266Sopenharmony_ci#define HEADER_CURL_HTTP_CHUNKS_H
313498266Sopenharmony_ci/***************************************************************************
413498266Sopenharmony_ci *                                  _   _ ____  _
513498266Sopenharmony_ci *  Project                     ___| | | |  _ \| |
613498266Sopenharmony_ci *                             / __| | | | |_) | |
713498266Sopenharmony_ci *                            | (__| |_| |  _ <| |___
813498266Sopenharmony_ci *                             \___|\___/|_| \_\_____|
913498266Sopenharmony_ci *
1013498266Sopenharmony_ci * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
1113498266Sopenharmony_ci *
1213498266Sopenharmony_ci * This software is licensed as described in the file COPYING, which
1313498266Sopenharmony_ci * you should have received as part of this distribution. The terms
1413498266Sopenharmony_ci * are also available at https://curl.se/docs/copyright.html.
1513498266Sopenharmony_ci *
1613498266Sopenharmony_ci * You may opt to use, copy, modify, merge, publish, distribute and/or sell
1713498266Sopenharmony_ci * copies of the Software, and permit persons to whom the Software is
1813498266Sopenharmony_ci * furnished to do so, under the terms of the COPYING file.
1913498266Sopenharmony_ci *
2013498266Sopenharmony_ci * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
2113498266Sopenharmony_ci * KIND, either express or implied.
2213498266Sopenharmony_ci *
2313498266Sopenharmony_ci * SPDX-License-Identifier: curl
2413498266Sopenharmony_ci *
2513498266Sopenharmony_ci ***************************************************************************/
2613498266Sopenharmony_ci
2713498266Sopenharmony_ci#ifndef CURL_DISABLE_HTTP
2813498266Sopenharmony_ci
2913498266Sopenharmony_ci#include "dynbuf.h"
3013498266Sopenharmony_ci
3113498266Sopenharmony_cistruct connectdata;
3213498266Sopenharmony_ci
3313498266Sopenharmony_ci/*
3413498266Sopenharmony_ci * The longest possible hexadecimal number we support in a chunked transfer.
3513498266Sopenharmony_ci * Neither RFC2616 nor the later HTTP specs define a maximum chunk size.
3613498266Sopenharmony_ci * For 64 bit curl_off_t we support 16 digits. For 32 bit, 8 digits.
3713498266Sopenharmony_ci */
3813498266Sopenharmony_ci#define CHUNK_MAXNUM_LEN (SIZEOF_CURL_OFF_T * 2)
3913498266Sopenharmony_ci
4013498266Sopenharmony_citypedef enum {
4113498266Sopenharmony_ci  /* await and buffer all hexadecimal digits until we get one that isn't a
4213498266Sopenharmony_ci     hexadecimal digit. When done, we go CHUNK_LF */
4313498266Sopenharmony_ci  CHUNK_HEX,
4413498266Sopenharmony_ci
4513498266Sopenharmony_ci  /* wait for LF, ignore all else */
4613498266Sopenharmony_ci  CHUNK_LF,
4713498266Sopenharmony_ci
4813498266Sopenharmony_ci  /* We eat the amount of data specified. When done, we move on to the
4913498266Sopenharmony_ci     POST_CR state. */
5013498266Sopenharmony_ci  CHUNK_DATA,
5113498266Sopenharmony_ci
5213498266Sopenharmony_ci  /* POSTLF should get a CR and then a LF and nothing else, then move back to
5313498266Sopenharmony_ci     HEX as the CRLF combination marks the end of a chunk. A missing CR is no
5413498266Sopenharmony_ci     big deal. */
5513498266Sopenharmony_ci  CHUNK_POSTLF,
5613498266Sopenharmony_ci
5713498266Sopenharmony_ci  /* Used to mark that we're out of the game.  NOTE: that there's a 'datasize'
5813498266Sopenharmony_ci     field in the struct that will tell how many bytes that were not passed to
5913498266Sopenharmony_ci     the client in the end of the last buffer! */
6013498266Sopenharmony_ci  CHUNK_STOP,
6113498266Sopenharmony_ci
6213498266Sopenharmony_ci  /* At this point optional trailer headers can be found, unless the next line
6313498266Sopenharmony_ci     is CRLF */
6413498266Sopenharmony_ci  CHUNK_TRAILER,
6513498266Sopenharmony_ci
6613498266Sopenharmony_ci  /* A trailer CR has been found - next state is CHUNK_TRAILER_POSTCR.
6713498266Sopenharmony_ci     Next char must be a LF */
6813498266Sopenharmony_ci  CHUNK_TRAILER_CR,
6913498266Sopenharmony_ci
7013498266Sopenharmony_ci  /* A trailer LF must be found now, otherwise CHUNKE_BAD_CHUNK will be
7113498266Sopenharmony_ci     signalled If this is an empty trailer CHUNKE_STOP will be signalled.
7213498266Sopenharmony_ci     Otherwise the trailer will be broadcasted via Curl_client_write() and the
7313498266Sopenharmony_ci     next state will be CHUNK_TRAILER */
7413498266Sopenharmony_ci  CHUNK_TRAILER_POSTCR,
7513498266Sopenharmony_ci
7613498266Sopenharmony_ci  /* Successfully de-chunked everything */
7713498266Sopenharmony_ci  CHUNK_DONE,
7813498266Sopenharmony_ci
7913498266Sopenharmony_ci  /* Failed on seeing a bad or not correctly terminated chunk */
8013498266Sopenharmony_ci  CHUNK_FAILED
8113498266Sopenharmony_ci} ChunkyState;
8213498266Sopenharmony_ci
8313498266Sopenharmony_citypedef enum {
8413498266Sopenharmony_ci  CHUNKE_OK = 0,
8513498266Sopenharmony_ci  CHUNKE_TOO_LONG_HEX = 1,
8613498266Sopenharmony_ci  CHUNKE_ILLEGAL_HEX,
8713498266Sopenharmony_ci  CHUNKE_BAD_CHUNK,
8813498266Sopenharmony_ci  CHUNKE_BAD_ENCODING,
8913498266Sopenharmony_ci  CHUNKE_OUT_OF_MEMORY,
9013498266Sopenharmony_ci  CHUNKE_PASSTHRU_ERROR /* Curl_httpchunk_read() returns a CURLcode to use */
9113498266Sopenharmony_ci} CHUNKcode;
9213498266Sopenharmony_ci
9313498266Sopenharmony_cistruct Curl_chunker {
9413498266Sopenharmony_ci  curl_off_t datasize;
9513498266Sopenharmony_ci  ChunkyState state;
9613498266Sopenharmony_ci  CHUNKcode last_code;
9713498266Sopenharmony_ci  struct dynbuf trailer; /* for chunked-encoded trailer */
9813498266Sopenharmony_ci  unsigned char hexindex;
9913498266Sopenharmony_ci  char hexbuffer[CHUNK_MAXNUM_LEN + 1]; /* +1 for null-terminator */
10013498266Sopenharmony_ci  BIT(ignore_body); /* never write response body data */
10113498266Sopenharmony_ci};
10213498266Sopenharmony_ci
10313498266Sopenharmony_ci/* The following functions are defined in http_chunks.c */
10413498266Sopenharmony_civoid Curl_httpchunk_init(struct Curl_easy *data, struct Curl_chunker *ch,
10513498266Sopenharmony_ci                         bool ignore_body);
10613498266Sopenharmony_civoid Curl_httpchunk_free(struct Curl_easy *data, struct Curl_chunker *ch);
10713498266Sopenharmony_civoid Curl_httpchunk_reset(struct Curl_easy *data, struct Curl_chunker *ch,
10813498266Sopenharmony_ci                          bool ignore_body);
10913498266Sopenharmony_ci
11013498266Sopenharmony_ci/*
11113498266Sopenharmony_ci * Read BODY bytes in HTTP/1.1 chunked encoding from `buf` and return
11213498266Sopenharmony_ci * the amount of bytes consumed. The actual response bytes and trailer
11313498266Sopenharmony_ci * headers are written out to the client.
11413498266Sopenharmony_ci * On success, this will consume all bytes up to the end of the response,
11513498266Sopenharmony_ci * e.g. the last chunk, has been processed.
11613498266Sopenharmony_ci * @param data   the transfer involved
11713498266Sopenharmony_ci * @param ch     the chunker instance keeping state across calls
11813498266Sopenharmony_ci * @param buf    the response data
11913498266Sopenharmony_ci * @param blen   amount of bytes in `buf`
12013498266Sopenharmony_ci * @param pconsumed  on successful return, the number of bytes in `buf`
12113498266Sopenharmony_ci *                   consumed
12213498266Sopenharmony_ci *
12313498266Sopenharmony_ci * This function always uses ASCII hex values to accommodate non-ASCII hosts.
12413498266Sopenharmony_ci * For example, 0x0d and 0x0a are used instead of '\r' and '\n'.
12513498266Sopenharmony_ci */
12613498266Sopenharmony_ciCURLcode Curl_httpchunk_read(struct Curl_easy *data, struct Curl_chunker *ch,
12713498266Sopenharmony_ci                             char *buf, size_t blen, size_t *pconsumed);
12813498266Sopenharmony_ci
12913498266Sopenharmony_ci/**
13013498266Sopenharmony_ci * @return TRUE iff chunked decoded has finished successfully.
13113498266Sopenharmony_ci */
13213498266Sopenharmony_cibool Curl_httpchunk_is_done(struct Curl_easy *data, struct Curl_chunker *ch);
13313498266Sopenharmony_ci
13413498266Sopenharmony_ciextern const struct Curl_cwtype Curl_httpchunk_unencoder;
13513498266Sopenharmony_ci
13613498266Sopenharmony_ci#endif /* !CURL_DISABLE_HTTP */
13713498266Sopenharmony_ci
13813498266Sopenharmony_ci#endif /* HEADER_CURL_HTTP_CHUNKS_H */
139