ObjFW  Check-in [502a688f3d]

Overview
Comment:OFHTTPClient: Use asynchronous writes
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 502a688f3d756868a905f4fcefeed78a1d9c204e093b00b7bb167d83d3678154
User & Date: js on 2017-09-24 13:31:19
Other Links: manifest | tags
Context
2017-09-24
15:13
OFStream: More flexible repeating async writes check-in: 1084b23ef7 user: js tags: trunk
13:31
OFHTTPClient: Use asynchronous writes check-in: 502a688f3d user: js tags: trunk
13:15
Return a bool from async write handlers check-in: 47db5636d7 user: js tags: trunk
Changes

Modified src/OFHTTPClient.m from [038d53e9bb] to [efcbdf0935].

515
516
517
518
519
520
521




















































522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548

549
550


551
552
553

554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
	} @catch (id e) {
		[_client->_delegate client: _client
		     didEncounterException: e
				forRequest: _request];
		return false;
	}
}





















































- (void)handleSocket: (OFTCPSocket *)socket
{
	/*
	 * As a work around for a bug with split packets in lighttpd when using
	 * HTTPS, we construct the complete request in a buffer string and then
	 * send it all at once.
	 *
	 * We do not use the socket's write buffer in case we need to resend
	 * the entire request (e.g. in case a keep-alive connection timed out).
	 */

	@try {
		OFData *body;

		@try {
			/* TODO: Do this asynchronously */
			[socket writeString: constructRequestString(_request)];
		} @catch (OFWriteFailedException *e) {
			if ([e errNo] != ECONNRESET && [e errNo] == EPIPE)
				@throw e;

			/*
			 * Reconnect in case a keep-alive connection timed out.
			 */
			[self closeAndReconnect];
			return;

		}



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

	} @catch (id e) {
		[_client->_delegate client: _client
		     didEncounterException: e
				forRequest: _request];
		return;
	}

	[socket asyncReadLineWithTarget: self
			       selector: @selector(socket:didReadLine:context:
					      exception:)
				context: nil];
}

- (void)socketDidConnect: (OFTCPSocket *)socket
		 context: (id)context
	       exception: (id)exception
{
	if ([_client->_delegate respondsToSelector:







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>













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






<
<
<
<
<







515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586




587



588





589
590
591
592
593
594

595
596
597
598
599
600
601
602





603
604
605
606
607
608
609
	} @catch (id e) {
		[_client->_delegate client: _client
		     didEncounterException: e
				forRequest: _request];
		return false;
	}
}

-    (bool)socket: (OFTCPSocket *)socket
  didWriteRequest: (const void *)request
	   length: (size_t)length
	  context: (id)context
	exception: (id)exception
{
	OFData *body;

	if (exception != nil) {
		if ([exception isKindOfClass: [OFWriteFailedException class]] &&
		    ([exception errNo] == ECONNRESET ||
		    [exception errNo] == EPIPE)) {
			/* In case a keep-alive connection timed out */
			[self closeAndReconnect];
			return false;
		}

		[_client->_delegate client: _client
		     didEncounterException: exception
				forRequest: _request];
		return false;
	}

	if ((body = [_request body]) != nil) {
		[socket asyncWriteBuffer: [body items]
				  length: [body count] * [body itemSize]
				  target: self
				selector: @selector(socket:didWriteBody:length:
					      context:exception:)
				 context: nil];
		return false;
	} else
		return [self socket: socket
		       didWriteBody: NULL
			     length: 0
			    context: nil
			  exception: nil];
}

- (bool)socket: (OFTCPSocket *)socket
  didWriteBody: (const void *)body
	length: (size_t)length
       context: (id)context
     exception: (id)exception
{
	[socket asyncReadLineWithTarget: self
			       selector: @selector(socket:didReadLine:context:
					      exception:)
				context: nil];
	return false;
}

- (void)handleSocket: (OFTCPSocket *)socket
{
	/*
	 * As a work around for a bug with split packets in lighttpd when using
	 * HTTPS, we construct the complete request in a buffer string and then
	 * send it all at once.
	 *
	 * We do not use the socket's write buffer in case we need to resend
	 * the entire request (e.g. in case a keep-alive connection timed out).
	 */

	@try {




		OFString *requestString = constructRequestString(_request);



		const char *UTF8String = [requestString UTF8String];





		size_t UTF8StringLength = [requestString UTF8StringLength];

		[socket asyncWriteBuffer: UTF8String
				  length: UTF8StringLength
				  target: self
				selector: @selector(socket:didWriteRequest:

					      length:context:exception:)
				 context: nil];
	} @catch (id e) {
		[_client->_delegate client: _client
		     didEncounterException: e
				forRequest: _request];
		return;
	}





}

- (void)socketDidConnect: (OFTCPSocket *)socket
		 context: (id)context
	       exception: (id)exception
{
	if ([_client->_delegate respondsToSelector: