ObjFW  Diff

Differences From Artifact [f0a87a8790]:

To Artifact [ad2a18a279]:


309
310
311
312
313
314
315
316

317
318
319
320
321
322

323
324
325
326
327
328
329
309
310
311
312
313
314
315

316
317
318
319
320
321

322
323
324
325
326
327
328
329







-
+





-
+







{
	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];
	OFMutableDictionary OF_GENERIC(OFString*, OFString*) *headers;
	OFDataArray *body = [request body];
	OFTCPSocket *socket;
	OFHTTPClientResponse *response;
	OFString *line, *version, *redirect, *connectionHeader;
	bool keepAlive;
	OFMutableDictionary *serverHeaders;
	OFMutableDictionary OF_GENERIC(OFString*, OFString*) *serverHeaders;
	OFEnumerator *keyEnumerator, *objectEnumerator;
	OFString *key, *object;
	int status;

	if (![scheme isEqual: @"http"] && ![scheme isEqual: @"https"])
		@throw [OFUnsupportedProtocolException exceptionWithURL: URL];

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
429
430
431
432
433
434
435
436
437
438
439
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
429
430



431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447




448
449
450
451
452
453
454








+
+
+
+

-
-
-
-
-
+
+
+
+
+
+
+
+
+





-
+
+

-
-
-
-
-
+
+
+
+
+

+
+
-
-
-
+
+
+



-
-
-
+
+
+


-
-
+
+
-
-
+

+
+
+
+

-
-
-
+
+
+

+
+
+
+
+








-
-
-
-







		    of_http_request_method_to_string(method), [URL path],
		    [URL query], [request protocolVersionString]];
	else
		requestString = [OFMutableString stringWithFormat:
		    @"%s /%@ HTTP/%@\r\n",
		    of_http_request_method_to_string(method), [URL path],
		    [request protocolVersionString]];

	headers = [[[request headers] mutableCopy] autorelease];
	if (headers == nil)
		headers = [OFMutableDictionary dictionary];

	if (([scheme isEqual: @"http"] && [URL port] != 80) ||
	    ([scheme isEqual: @"https"] && [URL port] != 443))
		[requestString appendFormat: @"Host: %@:%d\r\n",
					     [URL host], [URL port]];
	else
		[requestString appendFormat: @"Host: %@\r\n", [URL host]];
	    ([scheme isEqual: @"https"] && [URL port] != 443)) {
		OFString *host = [OFString stringWithFormat:
		    @"%@:%d", [URL host], [URL port]];

		[headers setObject: host
			    forKey: @"Host"];
	} else
		[headers setObject: [URL host]
			    forKey: @"Host"];

	user = [URL user];
	password = [URL password];

	if ([user length] > 0 || [password length] > 0) {
		OFDataArray *authorization = [OFDataArray dataArray];
		OFDataArray *authorizationData = [OFDataArray dataArray];
		OFString *authorization;

		[authorization addItems: [user UTF8String]
				  count: [user UTF8StringLength]];
		[authorization addItem: ":"];
		[authorization addItems: [password UTF8String]
				  count: [password UTF8StringLength]];
		[authorizationData addItems: [user UTF8String]
				      count: [user UTF8StringLength]];
		[authorizationData addItem: ":"];
		[authorizationData addItems: [password UTF8String]
				      count: [password UTF8StringLength]];

		authorization = [OFString stringWithFormat:
		    @"Basic %@", [authorizationData stringByBase64Encoding]];
		[requestString appendFormat:
		    @"Authorization: Basic %@\r\n",
		    [authorization stringByBase64Encoding]];

		[headers setObject: authorization
			    forKey: @"Authorization"];
	}

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

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

			[headers setObject: contentLength
				    forKey: @"Content-Length"];
		}

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

	if ([request protocolVersion].major == 1 &&
	    [request protocolVersion].minor == 0)
		[headers setObject: @"keep-alive"
			    forKey: @"Connection"];

	keyEnumerator = [headers keyEnumerator];
	objectEnumerator = [headers objectEnumerator];

	while ((key = [keyEnumerator nextObject]) != nil &&
	    (object = [objectEnumerator nextObject]) != nil)
		[requestString appendFormat: @"%@: %@\r\n", key, object];

	if ([request protocolVersion].major == 1 &&
	    [request protocolVersion].minor == 0)
		[requestString appendString: @"Connection: keep-alive\r\n"];

	[requestString appendString: @"\r\n"];

	@try {
		[socket writeString: requestString];
	} @catch (OFWriteFailedException *e) {
		if ([e errNo] != ECONNRESET && [e errNo] != EPIPE)
			@throw e;