ObjFW  Diff

Differences From Artifact [e745036a39]:

To Artifact [d946419431]:


327
328
329
330
331
332
333
334

335
336
337
338
339
340
341
327
328
329
330
331
332
333

334
335
336
337
338
339
340
341







-
+







	void *pool = objc_autoreleasePoolPush();
	OFURL *URL = [request URL];
	OFString *scheme = [URL scheme];
	of_http_request_method_t method = [request method];
	OFMutableString *requestString;
	OFString *user, *password;
	OFDictionary *headers = [request headers];
	OFDataArray *entity = [request entity];
	OFDataArray *body = [request body];
	OFTCPSocket *socket;
	OFHTTPClientResponse *response;
	OFString *line, *version, *redirect, *connectionHeader;
	bool keepAlive;
	OFMutableDictionary *serverHeaders;
	OFEnumerator *keyEnumerator, *objectEnumerator;
	OFString *key, *object;
420
421
422
423
424
425
426
427

428
429
430
431

432
433
434
435
436
437
438
420
421
422
423
424
425
426

427
428
429
430

431
432
433
434
435
436
437
438







-
+



-
+







	}

	if ([headers objectForKey: @"User-Agent"] == nil)
		[requestString appendString:
		    @"User-Agent: Something using ObjFW "
		    @"<https://webkeks.org/objfw>\r\n"];

	if (entity != nil) {
	if (body != nil) {
		if ([headers objectForKey: @"Content-Length"] == nil)
			[requestString appendFormat:
			    @"Content-Length: %zd\r\n",
			    [entity itemSize] * [entity count]];
			    [body itemSize] * [body count]];

		if ([headers objectForKey: @"Content-Type"] == nil)
			[requestString appendString:
			    @"Content-Type: application/x-www-form-urlencoded; "
			    @"charset=UTF-8\r\n"];
	}

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
488
489
490
491
492
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
488
489
490
491
492







-
-
-
+
+
+
















-
-
-
-
+
+
+
+







			@throw e;

		/* Reconnect in case a keep-alive connection timed out */
		socket = [self OF_closeAndCreateSocketForRequest: request];
		[socket writeString: requestString];
	}

	if (entity != nil)
		[socket writeBuffer: [entity items]
			     length: [entity count] * [entity itemSize]];
	if (body != nil)
		[socket writeBuffer: [body items]
			     length: [body count] * [body itemSize]];

	@try {
		line = [socket readLine];
	} @catch (OFInvalidEncodingException *e) {
		@throw [OFInvalidServerReplyException exception];
	}

	/*
	 * It's possible that the write succeeds on a connection that is
	 * keep-alive, but the connection has already been closed by the remote
	 * end due to a timeout. In this case, we need to reconnect.
	 */
	if (line == nil) {
		socket = [self OF_closeAndCreateSocketForRequest: request];
		[socket writeString: requestString];

		if (entity != nil)
			[socket writeBuffer: [entity items]
				     length: [entity count] *
					     [entity itemSize]];
		if (body != nil)
			[socket writeBuffer: [body items]
				     length: [body count] *
					     [body itemSize]];

		@try {
			line = [socket readLine];
		} @catch (OFInvalidEncodingException *e) {
			@throw [OFInvalidServerReplyException exception];
		}
	}
630
631
632
633
634
635
636
637

638
639
640
641
642
643
644
630
631
632
633
634
635
636

637
638
639
640
641
642
643
644







-
+








		if (follow) {
			OFHTTPRequest *newRequest;

			newRequest = [OFHTTPRequest requestWithURL: newURL];
			[newRequest setMethod: method];
			[newRequest setHeaders: headers];
			[newRequest setEntity: entity];
			[newRequest setBody: body];

			/*
			 * 303 means the request should be converted to a GET
			 * request before redirection. This also means stripping
			 * the entity of the request.
			 */
			if (status == 303) {
656
657
658
659
660
661
662
663

664
665
666
667
668
669
670
656
657
658
659
660
661
662

663
664
665
666
667
668
669
670







-
+







					if (![key hasPrefix: @"Content-"])
						[newHeaders setObject: object
							       forKey: key];

				[newRequest
				    setMethod: OF_HTTP_REQUEST_METHOD_GET];
				[newRequest setHeaders: newHeaders];
				[newRequest setEntity: nil];
				[newRequest setBody: nil];
			}

			[newRequest retain];
			objc_autoreleasePoolPop(pool);
			[newRequest autorelease];

			return [self performRequest: newRequest