00001 #ifndef HEADER_CURL_HTTP_CHUNKS_H 00002 #define HEADER_CURL_HTTP_CHUNKS_H 00003 /*************************************************************************** 00004 * _ _ ____ _ 00005 * Project ___| | | | _ \| | 00006 * / __| | | | |_) | | 00007 * | (__| |_| | _ <| |___ 00008 * \___|\___/|_| \_\_____| 00009 * 00010 * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al. 00011 * 00012 * This software is licensed as described in the file COPYING, which 00013 * you should have received as part of this distribution. The terms 00014 * are also available at https://curl.haxx.se/docs/copyright.html. 00015 * 00016 * You may opt to use, copy, modify, merge, publish, distribute and/or sell 00017 * copies of the Software, and permit persons to whom the Software is 00018 * furnished to do so, under the terms of the COPYING file. 00019 * 00020 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 00021 * KIND, either express or implied. 00022 * 00023 ***************************************************************************/ 00024 /* 00025 * The longest possible hexadecimal number we support in a chunked transfer. 00026 * Weird enough, RFC2616 doesn't set a maximum size! Since we use strtoul() 00027 * to convert it, we "only" support 2^32 bytes chunk data. 00028 */ 00029 #define MAXNUM_SIZE 16 00030 00031 typedef enum { 00032 /* await and buffer all hexadecimal digits until we get one that isn't a 00033 hexadecimal digit. When done, we go CHUNK_LF */ 00034 CHUNK_HEX, 00035 00036 /* wait for LF, ignore all else */ 00037 CHUNK_LF, 00038 00039 /* We eat the amount of data specified. When done, we move on to the 00040 POST_CR state. */ 00041 CHUNK_DATA, 00042 00043 /* POSTLF should get a CR and then a LF and nothing else, then move back to 00044 HEX as the CRLF combination marks the end of a chunk. A missing CR is no 00045 big deal. */ 00046 CHUNK_POSTLF, 00047 00048 /* Used to mark that we're out of the game. NOTE: that there's a 'dataleft' 00049 field in the struct that will tell how many bytes that were not passed to 00050 the client in the end of the last buffer! */ 00051 CHUNK_STOP, 00052 00053 /* At this point optional trailer headers can be found, unless the next line 00054 is CRLF */ 00055 CHUNK_TRAILER, 00056 00057 /* A trailer CR has been found - next state is CHUNK_TRAILER_POSTCR. 00058 Next char must be a LF */ 00059 CHUNK_TRAILER_CR, 00060 00061 /* A trailer LF must be found now, otherwise CHUNKE_BAD_CHUNK will be 00062 signalled If this is an empty trailer CHUNKE_STOP will be signalled. 00063 Otherwise the trailer will be broadcasted via Curl_client_write() and the 00064 next state will be CHUNK_TRAILER */ 00065 CHUNK_TRAILER_POSTCR 00066 } ChunkyState; 00067 00068 typedef enum { 00069 CHUNKE_STOP = -1, 00070 CHUNKE_OK = 0, 00071 CHUNKE_TOO_LONG_HEX = 1, 00072 CHUNKE_ILLEGAL_HEX, 00073 CHUNKE_BAD_CHUNK, 00074 CHUNKE_WRITE_ERROR, 00075 CHUNKE_BAD_ENCODING, 00076 CHUNKE_OUT_OF_MEMORY, 00077 CHUNKE_LAST 00078 } CHUNKcode; 00079 00080 const char *Curl_chunked_strerror(CHUNKcode code); 00081 00082 struct Curl_chunker { 00083 char hexbuffer[ MAXNUM_SIZE + 1]; 00084 int hexindex; 00085 ChunkyState state; 00086 curl_off_t datasize; 00087 size_t dataleft; /* untouched data amount at the end of the last buffer */ 00088 }; 00089 00090 #endif /* HEADER_CURL_HTTP_CHUNKS_H */ 00091