1 | #ifndef HEADER_CURL_HTTP_CHUNKS_H |
2 | #define |
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 | struct connectdata; |
28 | |
29 | /* |
30 | * The longest possible hexadecimal number we support in a chunked transfer. |
31 | * Neither RFC2616 nor the later HTTP specs define a maximum chunk size. |
32 | * For 64 bit curl_off_t we support 16 digits. For 32 bit, 8 digits. |
33 | */ |
34 | #define CHUNK_MAXNUM_LEN (SIZEOF_CURL_OFF_T * 2) |
35 | |
36 | typedef enum { |
37 | /* await and buffer all hexadecimal digits until we get one that isn't a |
38 | hexadecimal digit. When done, we go CHUNK_LF */ |
39 | CHUNK_HEX, |
40 | |
41 | /* wait for LF, ignore all else */ |
42 | CHUNK_LF, |
43 | |
44 | /* We eat the amount of data specified. When done, we move on to the |
45 | POST_CR state. */ |
46 | CHUNK_DATA, |
47 | |
48 | /* POSTLF should get a CR and then a LF and nothing else, then move back to |
49 | HEX as the CRLF combination marks the end of a chunk. A missing CR is no |
50 | big deal. */ |
51 | CHUNK_POSTLF, |
52 | |
53 | /* Used to mark that we're out of the game. NOTE: that there's a 'datasize' |
54 | field in the struct that will tell how many bytes that were not passed to |
55 | the client in the end of the last buffer! */ |
56 | CHUNK_STOP, |
57 | |
58 | /* At this point optional trailer headers can be found, unless the next line |
59 | is CRLF */ |
60 | CHUNK_TRAILER, |
61 | |
62 | /* A trailer CR has been found - next state is CHUNK_TRAILER_POSTCR. |
63 | Next char must be a LF */ |
64 | CHUNK_TRAILER_CR, |
65 | |
66 | /* A trailer LF must be found now, otherwise CHUNKE_BAD_CHUNK will be |
67 | signalled If this is an empty trailer CHUNKE_STOP will be signalled. |
68 | Otherwise the trailer will be broadcasted via Curl_client_write() and the |
69 | next state will be CHUNK_TRAILER */ |
70 | CHUNK_TRAILER_POSTCR |
71 | } ChunkyState; |
72 | |
73 | typedef enum { |
74 | CHUNKE_STOP = -1, |
75 | CHUNKE_OK = 0, |
76 | CHUNKE_TOO_LONG_HEX = 1, |
77 | CHUNKE_ILLEGAL_HEX, |
78 | CHUNKE_BAD_CHUNK, |
79 | CHUNKE_BAD_ENCODING, |
80 | CHUNKE_OUT_OF_MEMORY, |
81 | CHUNKE_PASSTHRU_ERROR, /* Curl_httpchunk_read() returns a CURLcode to use */ |
82 | CHUNKE_LAST |
83 | } CHUNKcode; |
84 | |
85 | const char *Curl_chunked_strerror(CHUNKcode code); |
86 | |
87 | struct Curl_chunker { |
88 | curl_off_t datasize; |
89 | ChunkyState state; |
90 | unsigned char hexindex; |
91 | char hexbuffer[ CHUNK_MAXNUM_LEN + 1]; /* +1 for null-terminator */ |
92 | }; |
93 | |
94 | /* The following functions are defined in http_chunks.c */ |
95 | void Curl_httpchunk_init(struct Curl_easy *data); |
96 | CHUNKcode Curl_httpchunk_read(struct Curl_easy *data, char *datap, |
97 | ssize_t length, ssize_t *wrote, |
98 | CURLcode *passthru); |
99 | |
100 | #endif /* HEADER_CURL_HTTP_CHUNKS_H */ |
101 | |