doom3-gpl
Doom 3 GPL source release
Main Page
Related Pages
Namespaces
Classes
Files
File List
File Members
All
Classes
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Friends
Macros
Pages
neo
curl
lib
http_chunks.c
Go to the documentation of this file.
1
/***************************************************************************
2
* _ _ ____ _
3
* Project ___| | | | _ \| |
4
* / __| | | | |_) | |
5
* | (__| |_| | _ <| |___
6
* \___|\___/|_| \_\_____|
7
*
8
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
9
*
10
* This software is licensed as described in the file COPYING, which
11
* you should have received as part of this distribution. The terms
12
* are also available at http://curl.haxx.se/docs/copyright.html.
13
*
14
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
15
* copies of the Software, and permit persons to whom the Software is
16
* furnished to do so, under the terms of the COPYING file.
17
*
18
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19
* KIND, either express or implied.
20
*
21
* $Id: http_chunks.c,v 1.23 2004/03/04 15:25:06 bagder Exp $
22
***************************************************************************/
23
#include "
setup.h
"
24
25
#ifndef CURL_DISABLE_HTTP
26
/* -- WIN32 approved -- */
27
#include <stdio.h>
28
#include <string.h>
29
#include <stdarg.h>
30
#include <stdlib.h>
31
#include <ctype.h>
32
33
#include "
urldata.h
"
/* it includes http_chunks.h */
34
#include "
sendf.h
"
/* for the client write stuff */
35
36
#include "
content_encoding.h
"
/* 08/29/02 jhrg */
37
#include "
http.h
"
38
39
#define _MPRINTF_REPLACE
/* use our functions only */
40
#include <
curl/mprintf.h
>
41
42
/* The last #include file should be: */
43
#ifdef CURLDEBUG
44
#include "
memdebug.h
"
45
#endif
46
47
/*
48
* Chunk format (simplified):
49
*
50
* <HEX SIZE>[ chunk extension ] CRLF
51
* <DATA> CRLF
52
*
53
* Highlights from RFC2616 section 3.6 say:
54
55
The chunked encoding modifies the body of a message in order to
56
transfer it as a series of chunks, each with its own size indicator,
57
followed by an OPTIONAL trailer containing entity-header fields. This
58
allows dynamically produced content to be transferred along with the
59
information necessary for the recipient to verify that it has
60
received the full message.
61
62
Chunked-Body = *chunk
63
last-chunk
64
trailer
65
CRLF
66
67
chunk = chunk-size [ chunk-extension ] CRLF
68
chunk-data CRLF
69
chunk-size = 1*HEX
70
last-chunk = 1*("0") [ chunk-extension ] CRLF
71
72
chunk-extension= *( ";" chunk-ext-name [ "=" chunk-ext-val ] )
73
chunk-ext-name = token
74
chunk-ext-val = token | quoted-string
75
chunk-data = chunk-size(OCTET)
76
trailer = *(entity-header CRLF)
77
78
The chunk-size field is a string of hex digits indicating the size of
79
the chunk. The chunked encoding is ended by any chunk whose size is
80
zero, followed by the trailer, which is terminated by an empty line.
81
82
*/
83
84
85
void
Curl_httpchunk_init
(
struct
connectdata
*conn)
86
{
87
struct
Curl_chunker
*chunk = &conn->
proto
.
http
->
chunk
;
88
chunk->
hexindex
=0;
/* start at 0 */
89
chunk->
dataleft
=0;
/* no data left yet! */
90
chunk->
state
=
CHUNK_HEX
;
/* we get hex first! */
91
}
92
93
/*
94
* chunk_read() returns a OK for normal operations, or a positive return code
95
* for errors. STOP means this sequence of chunks is complete. The 'wrote'
96
* argument is set to tell the caller how many bytes we actually passed to the
97
* client (for byte-counting and whatever).
98
*
99
* The states and the state-machine is further explained in the header file.
100
*/
101
CHUNKcode
Curl_httpchunk_read
(
struct
connectdata
*conn,
102
char
*datap,
103
ssize_t
datalen,
104
ssize_t
*wrotep)
105
{
106
CURLcode
result
=
CURLE_OK
;
107
struct
Curl_chunker
*ch = &conn->
proto
.
http
->
chunk
;
108
struct
Curl_transfer_keeper
*k = &conn->
keep
;
109
size_t
piece;
110
size_t
length
= (size_t)datalen;
111
size_t
*wrote = (
size_t
*)wrotep;
112
113
*wrote = 0;
/* nothing's written yet */
114
115
while
(length) {
116
switch
(ch->
state
) {
117
case
CHUNK_HEX
:
118
if
(isxdigit((
int
)*datap)) {
119
if
(ch->
hexindex
<
MAXNUM_SIZE
) {
120
ch->
hexbuffer
[ch->
hexindex
] = *datap;
121
datap++;
122
length--;
123
ch->
hexindex
++;
124
}
125
else
{
126
return
CHUNKE_TOO_LONG_HEX
;
/* longer hex than we support */
127
}
128
}
129
else
{
130
if
(0 == ch->
hexindex
) {
131
/* This is illegal data, we received junk where we expected
132
a hexadecimal digit. */
133
return
CHUNKE_ILLEGAL_HEX
;
134
}
135
/* length and datap are unmodified */
136
ch->
hexbuffer
[ch->
hexindex
]=0;
137
ch->
datasize
=strtoul(ch->
hexbuffer
,
NULL
, 16);
138
ch->
state
=
CHUNK_POSTHEX
;
139
}
140
break
;
141
142
case
CHUNK_POSTHEX
:
143
/* In this state, we're waiting for CRLF to arrive. We support
144
this to allow so called chunk-extensions to show up here
145
before the CRLF comes. */
146
if
(*datap ==
'\r'
)
147
ch->
state
=
CHUNK_CR
;
148
length--;
149
datap++;
150
break
;
151
152
case
CHUNK_CR
:
153
/* waiting for the LF */
154
if
(*datap ==
'\n'
) {
155
/* we're now expecting data to come, unless size was zero! */
156
if
(0 == ch->
datasize
) {
157
ch->
state
=
CHUNK_STOP
;
/* stop reading! */
158
if
(1 == length) {
159
/* This was the final byte, return right now */
160
return
CHUNKE_STOP
;
161
}
162
}
163
else
164
ch->
state
=
CHUNK_DATA
;
165
}
166
else
167
/* previously we got a fake CR, go back to CR waiting! */
168
ch->
state
=
CHUNK_CR
;
169
datap++;
170
length--;
171
break
;
172
173
case
CHUNK_DATA
:
174
/* we get pure and fine data
175
176
We expect another 'datasize' of data. We have 'length' right now,
177
it can be more or less than 'datasize'. Get the smallest piece.
178
*/
179
piece = (ch->
datasize
>=
length
)?length:ch->
datasize
;
180
181
/* Write the data portion available */
182
/* Added content-encoding here; untested but almost identical to the
183
tested code in transfer.c. 08/29/02 jhrg */
184
#ifdef
HAVE_LIBZ
185
switch (conn->
keep
.
content_encoding
) {
186
case
IDENTITY
:
187
#endif
188
if
(!k->
ignorebody
)
189
result =
Curl_client_write
(conn->
data
,
CLIENTWRITE_BODY
, datap,
190
piece);
191
#ifdef HAVE_LIBZ
192
break
;
193
194
case
DEFLATE
:
195
/* update conn->keep.str to point to the chunk data. */
196
conn->
keep
.
str
= datap;
197
result =
Curl_unencode_deflate_write
(conn->
data
, &conn->
keep
, piece);
198
break
;
199
200
case
GZIP
:
201
/* update conn->keep.str to point to the chunk data. */
202
conn->
keep
.
str
= datap;
203
result =
Curl_unencode_gzip_write
(conn->
data
, &conn->
keep
, piece);
204
break
;
205
206
case
COMPRESS
:
207
default
:
208
failf
(conn->
data
,
209
"Unrecognized content encoding type. "
210
"libcurl understands `identity', `deflate' and `gzip' "
211
"content encodings."
);
212
return
CHUNKE_BAD_ENCODING
;
213
}
214
#endif
215
216
if
(result)
217
return
CHUNKE_WRITE_ERROR
;
218
219
*wrote += piece;
220
221
ch->
datasize
-= piece;
/* decrease amount left to expect */
222
datap += piece;
/* move read pointer forward */
223
length -= piece;
/* decrease space left in this round */
224
225
if
(0 == ch->
datasize
)
226
/* end of data this round, we now expect a trailing CRLF */
227
ch->
state
=
CHUNK_POSTCR
;
228
break
;
229
230
case
CHUNK_POSTCR
:
231
if
(*datap ==
'\r'
) {
232
ch->
state
=
CHUNK_POSTLF
;
233
datap++;
234
length--;
235
}
236
else
237
return
CHUNKE_BAD_CHUNK
;
238
break
;
239
240
case
CHUNK_POSTLF
:
241
if
(*datap ==
'\n'
) {
242
/*
243
* The last one before we go back to hex state and start all
244
* over.
245
*/
246
Curl_httpchunk_init
(conn);
247
datap++;
248
length--;
249
}
250
else
251
return
CHUNKE_BAD_CHUNK
;
252
break
;
253
254
case
CHUNK_STOP
:
255
/* If we arrive here, there is data left in the end of the buffer
256
even if there's no more chunks to read */
257
ch->
dataleft
=
length
;
258
return
CHUNKE_STOP
;
/* return stop */
259
default
:
260
return
CHUNKE_STATE_ERROR
;
261
}
262
}
263
return
CHUNKE_OK
;
264
}
265
#endif
/* CURL_DISABLE_HTTP */
Curl_unencode_gzip_write
CURLcode Curl_unencode_gzip_write(struct SessionHandle *data, struct Curl_transfer_keeper *k, ssize_t nread)
DEFLATE
#define DEFLATE
Definition:
urldata.h:348
CLIENTWRITE_BODY
#define CLIENTWRITE_BODY
Definition:
sendf.h:34
connectdata::keep
struct Curl_transfer_keeper keep
Definition:
urldata.h:553
connectdata::proto
union connectdata::@11 proto
Curl_unencode_deflate_write
CURLcode Curl_unencode_deflate_write(struct SessionHandle *data, struct Curl_transfer_keeper *k, ssize_t nread)
Curl_httpchunk_init
void Curl_httpchunk_init(struct connectdata *conn)
Definition:
http_chunks.c:85
COMPRESS
#define COMPRESS
Definition:
urldata.h:350
Curl_transfer_keeper::str
char * str
Definition:
urldata.h:329
GZIP
#define GZIP
Definition:
urldata.h:349
HAVE_LIBZ
#define HAVE_LIBZ
Definition:
config-amigaos.h:13
failf
#define failf
Definition:
sendf.h:32
CHUNKE_OK
Definition:
http_chunks.h:70
sendf.h
Curl_client_write
CURLcode Curl_client_write(struct SessionHandle *data, int type, char *ptr, size_t len)
Definition:
sendf.c:319
CHUNKE_ILLEGAL_HEX
Definition:
http_chunks.h:72
CURLcode
CURLcode
Definition:
curl.h:209
CHUNK_DATA
Definition:
http_chunks.h:50
Curl_chunker::dataleft
size_t dataleft
Definition:
http_chunks.h:85
setup.h
result
Boolean result
Definition:
PreferencesDialog.cpp:727
ssize_t
#define ssize_t
Definition:
config-win32.h:27
CHUNK_STOP
Definition:
http_chunks.h:63
CHUNKE_STOP
Definition:
http_chunks.h:69
content_encoding.h
CHUNKE_BAD_ENCODING
Definition:
http_chunks.h:76
connectdata::http
struct HTTP * http
Definition:
urldata.h:539
http.h
CHUNKE_TOO_LONG_HEX
Definition:
http_chunks.h:71
Curl_chunker::hexbuffer
char hexbuffer[MAXNUM_SIZE+1]
Definition:
http_chunks.h:81
Curl_transfer_keeper::ignorebody
bool ignorebody
Definition:
urldata.h:380
Curl_httpchunk_read
CHUNKcode Curl_httpchunk_read(struct connectdata *conn, char *datap, ssize_t datalen, ssize_t *wrotep)
Definition:
http_chunks.c:101
NULL
#define NULL
Definition:
Lib.h:88
mprintf.h
CHUNK_HEX
Definition:
http_chunks.h:37
CHUNKE_BAD_CHUNK
Definition:
http_chunks.h:73
CHUNK_POSTHEX
Definition:
http_chunks.h:41
CHUNKE_WRITE_ERROR
Definition:
http_chunks.h:74
CHUNKcode
CHUNKcode
Definition:
http_chunks.h:68
CHUNK_CR
Definition:
http_chunks.h:46
CURLE_OK
Definition:
curl.h:210
connectdata::data
struct SessionHandle * data
Definition:
urldata.h:403
Curl_chunker::state
ChunkyState state
Definition:
http_chunks.h:83
Curl_chunker::hexindex
int hexindex
Definition:
http_chunks.h:82
Curl_transfer_keeper
Definition:
urldata.h:312
Curl_chunker
Definition:
http_chunks.h:80
Curl_transfer_keeper::content_encoding
int content_encoding
Definition:
urldata.h:345
length
GLsizei const GLcharARB const GLint * length
Definition:
glext.h:3599
CHUNK_POSTLF
Definition:
http_chunks.h:57
Curl_chunker::datasize
size_t datasize
Definition:
http_chunks.h:84
HTTP::chunk
struct Curl_chunker chunk
Definition:
urldata.h:218
CHUNK_POSTCR
Definition:
http_chunks.h:53
urldata.h
IDENTITY
#define IDENTITY
Definition:
urldata.h:347
MAXNUM_SIZE
#define MAXNUM_SIZE
Definition:
http_chunks.h:30
memdebug.h
connectdata
Definition:
urldata.h:401
CHUNKE_STATE_ERROR
Definition:
http_chunks.h:75
This page is maintained by
Wladimir van der Laan
. Generated on Mon Nov 17 2014 12:23:15 for doom3-gpl by
1.8.6
.