︙ | | | ︙ | |
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
#import "OFUnsupportedProtocolException.h"
#import "macros.h"
Class of_http_request_tls_socket_class = Nil;
static OF_INLINE void
normalize_key(OFString *key)
{
uint8_t *str = (uint8_t*)[key UTF8String];
BOOL firstLetter = YES;
while (*str != '\0') {
if (!isalnum(*str)) {
firstLetter = YES;
|
|
|
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
#import "OFUnsupportedProtocolException.h"
#import "macros.h"
Class of_http_request_tls_socket_class = Nil;
static OF_INLINE void
normalizeKey(OFString *key)
{
uint8_t *str = (uint8_t*)[key UTF8String];
BOOL firstLetter = YES;
while (*str != '\0') {
if (!isalnum(*str)) {
firstLetter = YES;
|
︙ | | | ︙ | |
191
192
193
194
195
196
197
198
199
200
201
202
203
204
|
OFString *line, *path;
OFMutableDictionary *serverHeaders;
OFDataArray *data;
OFEnumerator *keyEnumerator, *objectEnumerator;
OFString *key, *object, *contentLengthHeader;
int status;
const char *type = NULL;
char *buffer;
size_t bytesReceived;
if (![scheme isEqual: @"http"] && ![scheme isEqual: @"https"])
@throw [OFUnsupportedProtocolException exceptionWithClass: isa
URL: URL];
|
>
|
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
|
OFString *line, *path;
OFMutableDictionary *serverHeaders;
OFDataArray *data;
OFEnumerator *keyEnumerator, *objectEnumerator;
OFString *key, *object, *contentLengthHeader;
int status;
const char *type = NULL;
BOOL chunked;
char *buffer;
size_t bytesReceived;
if (![scheme isEqual: @"http"] && ![scheme isEqual: @"https"])
@throw [OFUnsupportedProtocolException exceptionWithClass: isa
URL: URL];
|
︙ | | | ︙ | |
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
|
if (requestType == OF_HTTP_REQUEST_TYPE_POST)
type = "POST";
if ([(path = [URL path]) isEqual: @""])
path = @"/";
if ([URL query] != nil)
[sock writeFormat: @"%s %@?%@ HTTP/1.0\r\n",
type, path, [URL query]];
else
[sock writeFormat: @"%s %@ HTTP/1.0\r\n", type, path];
if ([URL port] == 80)
[sock writeFormat: @"Host: %@\r\n", [URL host]];
else
[sock writeFormat: @"Host: %@:%d\r\n", [URL host],
[URL port]];
|
|
|
|
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
|
if (requestType == OF_HTTP_REQUEST_TYPE_POST)
type = "POST";
if ([(path = [URL path]) isEqual: @""])
path = @"/";
if ([URL query] != nil)
[sock writeFormat: @"%s %@?%@ HTTP/1.1\r\n",
type, path, [URL query]];
else
[sock writeFormat: @"%s %@ HTTP/1.1\r\n", type, path];
if ([URL port] == 80)
[sock writeFormat: @"Host: %@\r\n", [URL host]];
else
[sock writeFormat: @"Host: %@:%d\r\n", [URL host],
[URL port]];
|
︙ | | | ︙ | |
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
|
/* Work around a bug in lighttpd, see above */
[sock flushWriteBuffer];
[sock setBuffersWrites: NO];
if (requestType == OF_HTTP_REQUEST_TYPE_POST)
[sock writeString: queryString];
/*
* We also need to check for HTTP/1.1 since Apache always declares the
* reply to be HTTP/1.1.
*/
line = [sock readLine];
if (![line hasPrefix: @"HTTP/1.0 "] && ![line hasPrefix: @"HTTP/1.1 "])
@throw [OFInvalidServerReplyException exceptionWithClass: isa];
status = (int)[[line substringWithRange: of_range(9, 3)] decimalValue];
serverHeaders = [OFMutableDictionary dictionary];
|
<
<
<
<
|
272
273
274
275
276
277
278
279
280
281
282
283
284
285
|
/* Work around a bug in lighttpd, see above */
[sock flushWriteBuffer];
[sock setBuffersWrites: NO];
if (requestType == OF_HTTP_REQUEST_TYPE_POST)
[sock writeString: queryString];
line = [sock readLine];
if (![line hasPrefix: @"HTTP/1.0 "] && ![line hasPrefix: @"HTTP/1.1 "])
@throw [OFInvalidServerReplyException exceptionWithClass: isa];
status = (int)[[line substringWithRange: of_range(9, 3)] decimalValue];
serverHeaders = [OFMutableDictionary dictionary];
|
︙ | | | ︙ | |
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
|
if ((tmp = strchr(line_c, ':')) == NULL)
@throw [OFInvalidServerReplyException
exceptionWithClass: isa];
key = [OFString stringWithUTF8String: line_c
length: tmp - line_c];
normalize_key(key);
do {
tmp++;
} while (*tmp == ' ');
value = [OFString stringWithUTF8String: tmp];
|
|
|
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
|
if ((tmp = strchr(line_c, ':')) == NULL)
@throw [OFInvalidServerReplyException
exceptionWithClass: isa];
key = [OFString stringWithUTF8String: line_c
length: tmp - line_c];
normalizeKey(key);
do {
tmp++;
} while (*tmp == ' ');
value = [OFString stringWithUTF8String: tmp];
|
︙ | | | ︙ | |
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
|
}
[delegate request: self
didReceiveHeaders: serverHeaders
withStatusCode: status];
data = (storesData ? [OFDataArray dataArray] : nil);
buffer = [self allocMemoryWithSize: of_pagesize];
bytesReceived = 0;
@try {
size_t len;
while ((len = [sock readNBytes: of_pagesize
intoBuffer: buffer]) > 0) {
[delegate request: self
didReceiveData: buffer
withLength: len];
bytesReceived += len;
[data addNItems: len
fromCArray: buffer];
}
} @finally {
[self freeMemory: buffer];
}
if ((contentLengthHeader =
[serverHeaders objectForKey: @"Content-Length"]) != nil) {
intmax_t cl = [contentLengthHeader decimalValue];
if (cl > SIZE_MAX)
@throw [OFOutOfRangeException exceptionWithClass: isa];
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
|
|
|
>
|
|
|
|
>
>
>
>
>
|
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
|
}
[delegate request: self
didReceiveHeaders: serverHeaders
withStatusCode: status];
data = (storesData ? [OFDataArray dataArray] : nil);
chunked = [[serverHeaders objectForKey: @"Transfer-Encoding"]
isEqual: @"chunked"];
buffer = [self allocMemoryWithSize: of_pagesize];
bytesReceived = 0;
@try {
OFAutoreleasePool *pool2 = [[OFAutoreleasePool alloc] init];
if (chunked) {
for (;;) {
size_t pos, toRead;
line = [sock readLine];
pos = [line
indexOfFirstOccurrenceOfString: @";"];
if (pos != OF_INVALID_INDEX)
line = [line substringWithRange:
of_range(0, pos)];
toRead = (size_t)[line hexadecimalValue];
if (toRead == 0)
break;
while (toRead > 0) {
size_t length = (toRead < of_pagesize
? toRead : of_pagesize);
length = [sock readNBytes: length
intoBuffer: buffer];
[delegate request: self
didReceiveData: buffer
withLength: length];
bytesReceived += length;
[data addNItems: length
fromCArray: buffer];
toRead -= length;
}
if (![[sock readLine] isEqual: @""])
@throw [OFInvalidServerReplyException
exceptionWithClass: isa];
[pool2 releaseObjects];
}
} else {
size_t length;
while ((length = [sock readNBytes: of_pagesize
intoBuffer: buffer]) > 0) {
[delegate request: self
didReceiveData: buffer
withLength: length];
[pool2 releaseObjects];
bytesReceived += length;
[data addNItems: length
fromCArray: buffer];
}
}
[pool2 release];
} @finally {
[self freeMemory: buffer];
}
[sock close];
if ((contentLengthHeader =
[serverHeaders objectForKey: @"Content-Length"]) != nil) {
intmax_t cl = [contentLengthHeader decimalValue];
if (cl > SIZE_MAX)
@throw [OFOutOfRangeException exceptionWithClass: isa];
|
︙ | | | ︙ | |