ObjFW  Check-in [77b8ffc1e0]

Overview
Comment:OFHTTPRequest: Always close the connection after we received everything.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 77b8ffc1e02dd7de397cada7d34b82c5f0c23a58b4fb188e3b8daf5c85063c08
User & Date: js on 2012-03-12 12:58:04
Other Links: manifest | tags
Context
2012-03-12
14:04
OFHTTPRequest: Add Connection: close to the request headers. check-in: ffb4484d97 user: js tags: trunk
12:58
OFHTTPRequest: Always close the connection after we received everything. check-in: 77b8ffc1e0 user: js tags: trunk
12:18
Make dictionary literals work. check-in: 6428a08de1 user: js tags: trunk
Changes

Modified src/OFHTTPRequest.m from [65e7fe1190] to [2f0fcffd8a].

193
194
195
196
197
198
199

200
201
202
203
204
205
206
	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];







>







193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
	OFString *line, *path;
	OFMutableDictionary *serverHeaders;
	OFDataArray *data;
	OFEnumerator *keyEnumerator, *objectEnumerator;
	OFString *key, *object, *contentLengthHeader;
	int status;
	const char *type = NULL;
	size_t contentLength;
	BOOL chunked;
	char *buffer;
	size_t bytesReceived;

	if (![scheme isEqual: @"http"] && ![scheme isEqual: @"https"])
		@throw [OFUnsupportedProtocolException exceptionWithClass: isa
								      URL: URL];
368
369
370
371
372
373
374









375
376
377
378
379
380
381
	[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) {







>
>
>
>
>
>
>
>
>







369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
	[delegate request: self
	didReceiveHeaders: serverHeaders
	   withStatusCode: status];

	data = (storesData ? [OFDataArray dataArray] : nil);
	chunked = [[serverHeaders objectForKey: @"Transfer-Encoding"]
	    isEqual: @"chunked"];

	contentLengthHeader = [serverHeaders objectForKey: @"Content-Length"];

	if (contentLengthHeader != nil) {
		contentLength = (size_t)[contentLengthHeader decimalValue];

		if (contentLength > SIZE_MAX)
			@throw [OFOutOfRangeException exceptionWithClass: isa];
	}

	buffer = [self allocMemoryWithSize: of_pagesize];
	bytesReceived = 0;
	@try {
		OFAutoreleasePool *pool2 = [[OFAutoreleasePool alloc] init];

		if (chunked) {
399
400
401
402
403
404
405
406


407
408
409
410
411
412
413
					toRead =
					    (size_t)[line hexadecimalValue];
				} @catch (OFInvalidFormatException *e) {
					@throw [OFInvalidServerReplyException
					    exceptionWithClass: isa];
				}

				if (toRead == 0)


					break;

				while (toRead > 0) {
					size_t length = (toRead < of_pagesize
					    ? toRead : of_pagesize);

					length = [sock readNBytes: length







|
>
>







409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
					toRead =
					    (size_t)[line hexadecimalValue];
				} @catch (OFInvalidFormatException *e) {
					@throw [OFInvalidServerReplyException
					    exceptionWithClass: isa];
				}

				if (toRead == 0 ||
				    (contentLengthHeader != nil &&
				    contentLength >= bytesReceived))
					break;

				while (toRead > 0) {
					size_t length = (toRead < of_pagesize
					    ? toRead : of_pagesize);

					length = [sock readNBytes: length
447
448
449
450
451
452
453




454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475

476
477
478
479
480
481
482
483
484
485
486
487
				   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];

		/*
		 * We only want to throw on these status codes as we will throw
		 * an OFHTTPRequestFailedException for all other status codes
		 * later.
		 */

		if (cl != bytesReceived && (status == 200 || status == 301 ||
		    status == 302 || status == 303))
			@throw [OFTruncatedDataException
			    exceptionWithClass: isa];
	}

	[serverHeaders makeImmutable];

	result = [[OFHTTPRequestResult alloc] initWithStatusCode: status
							 headers: serverHeaders
							    data: data];








>
>
>
>










<
<
<
<
<
<
<
|
|
|
<
|
>
|
|
|
<
<







459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479







480
481
482

483
484
485
486
487


488
489
490
491
492
493
494
				   didReceiveData: buffer
				       withLength: length];
				[pool2 releaseObjects];

				bytesReceived += length;
				[data addNItems: length
				     fromCArray: buffer];

				if (contentLengthHeader != nil &&
				    bytesReceived >= contentLength)
					break;
			}
		}

		[pool2 release];
	} @finally {
		[self freeMemory: buffer];
	}

	[sock close];








	/*
	 * We only want to throw on these status codes as we will throw an
	 * OFHTTPRequestFailedException for all other status codes later.

	 */
	if (contentLengthHeader != nil && contentLength != bytesReceived &&
	    (status == 200 || status == 301 || status == 302 || status == 303 ||
	    status == 307))
		@throw [OFTruncatedDataException exceptionWithClass: isa];



	[serverHeaders makeImmutable];

	result = [[OFHTTPRequestResult alloc] initWithStatusCode: status
							 headers: serverHeaders
							    data: data];