ObjFW  Check-in [064dbe5127]

Overview
Comment:Include an exception in delegate methods

Otherwise, there would be two methods for every operation: One for
success and one for failure. It also makes it easy to forget about
handling failure, so it's better to always pass an optional exception.

Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 064dbe51276f7d8b6491e08f2c7425d357f52dee3ee095d68b17f3d787fc3d68
User & Date: js on 2018-12-11 22:57:46
Other Links: manifest | tags
Context
2018-12-18
14:14
Use OFData instead of a buffer for async writes check-in: f218986f51 user: js tags: trunk
2018-12-11
22:57
Include an exception in delegate methods check-in: 064dbe5127 user: js tags: trunk
2018-12-08
22:01
Minor fix for OFDNSResolver and OFRunLoop check-in: 6387b16864 user: js tags: trunk
Changes

Modified src/OFDNSResolver.m from [c60b82a6b2] to [15c765674a].

1867
1868
1869
1870
1871
1872
1873

1874
1875
1876
1877
1878
1879



1880
1881
1882
1883
1884
1885
1886
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890







+






+
+
+







	    nil, nil, nil, query->_context, exception);
}

-	  (bool)socket: (OF_KINDOF(OFUDPSocket *))sock
  didReceiveIntoBuffer: (void *)buffer_
		length: (size_t)length
		sender: (of_socket_address_t)sender
	     exception: (id)exception
{
	unsigned char *buffer = buffer_;
	OFDictionary *answerRecords = nil, *authorityRecords = nil;
	OFDictionary *additionalRecords = nil;
	OFNumber *ID;
	OFDNSResolverQuery *query;

	if (exception != nil)
		return true;

	if (length < 2)
		/* We can't get the ID to get the query. Ignore packet. */
		return true;

	ID = [OFNumber numberWithUInt16: (buffer[0] << 8) | buffer[1]];
	query = [[[_queries objectForKey: ID] retain] autorelease];
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2012
2013
2014
2015
2016
2017
2018







2019
2020
2021
2022
2023
2024
2025







-
-
-
-
-
-
-







	callback(query->_target, query->_selector, self, query->_domainName,
	    answerRecords, authorityRecords, additionalRecords,
	    query->_context, nil);

	return true;
}

-		   (void)socket: (OF_KINDOF(OFUDPSocket *))sock
  didFailToReceiveWithException: (id)exception
{
	[sock asyncReceiveIntoBuffer: _buffer
			      length: BUFFER_LENGTH];
}

- (void)asyncResolveSocketAddressesForHost: (OFString *)host
				    target: (id)target
				  selector: (SEL)selector
				   context: (id)context
{
	[self asyncResolveSocketAddressesForHost: host
				   addressFamily: OF_SOCKET_ADDRESS_FAMILY_ANY

Modified src/OFHTTPClient.m from [a601f5af31] to [209c55758d].

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
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







+


+
+
+
+
+
+
+
+
+
















-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-



+

+
+
+
+
+
+
+
+
+
+
+
+
+







			   forKey: key];

	return true;
}

- (bool)stream: (OF_KINDOF(OFStream *))sock
   didReadLine: (OFString *)line
     exception: (id)exception
{
	bool ret;

	if (exception != nil) {
		if ([exception isKindOfClass:
		    [OFInvalidEncodingException class]])
			exception = [OFInvalidServerReplyException exception];

		[self raiseException: exception];
		return false;
	}

	@try {
		if (_firstLine) {
			_firstLine = false;
			ret = [self handleFirstLine: line];
		} else
			ret = [self handleServerHeader: line
						socket: sock];
	} @catch (id e) {
		[self raiseException: e];
		ret = false;
	}

	return ret;
}

-		(void)stream: (OF_KINDOF(OFStream *))sock
  didFailToReadWithException: (id)exception
{
	if ([exception isKindOfClass: [OFInvalidEncodingException class]])
		exception = [OFInvalidServerReplyException exception];

	[self raiseException: exception];
}

-		 (void)stream: (OF_KINDOF(OFStream *))sock
  didFailToWriteWithException: (id)exception
{
	if ([exception isKindOfClass: [OFWriteFailedException class]] &&
	    ([exception errNo] == ECONNRESET || [exception errNo] == EPIPE)) {
		/* In case a keep-alive connection timed out */
		[self closeAndReconnect];
		return;
	}

	[self raiseException: exception];
}

- (size_t)stream: (OF_KINDOF(OFStream *))sock
  didWriteBuffer: (const void **)request
	  length: (size_t)length
       exception: (id)exception
{
	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 0;
		}

		[self raiseException: exception];
		return 0;
	}

	_firstLine = true;

	[_requestString release];
	_requestString = nil;

	if ([[_request headers] objectForKey: @"Content-Length"] != nil) {
		[sock setDelegate: nil];
620
621
622
623
624
625
626

627
628





629
630
631
632
633
634
635
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643







+


+
+
+
+
+







		return;
	}
}

-     (void)socket: (OF_KINDOF(OFTCPSocket *))sock
  didConnectToHost: (OFString *)host
	      port: (uint16_t)port
	 exception: (id)exception
{
	[(OFTCPSocket *)sock setDelegate: self];

	if (exception != nil) {
		[self raiseException: exception];
		return;
	}

	if ([_client->_delegate respondsToSelector:
	    @selector(client:didCreateSocket:request:context:)])
		[_client->_delegate client: _client
			   didCreateSocket: sock
				   request: _request
				   context: _context];

Modified src/OFHTTPServer.m from [814464cd03] to [aae9d41f78].

399
400
401
402
403
404
405

406
407

408
409
410
411
412
413
414
399
400
401
402
403
404
405
406
407

408
409
410
411
412
413
414
415







+

-
+







	[_requestBody release];

	[super dealloc];
}

- (bool)stream: (OF_KINDOF(OFStream *))sock
   didReadLine: (OFString *)line
     exception: (id)exception
{
	if (line == nil)
	if (line == nil || exception != nil)
		return false;

	@try {
		switch (_state) {
		case AWAITING_PROLOG:
			return [self parseProlog: line];
		case PARSING_HEADERS:
785
786
787
788
789
790
791

792
793












794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
786
787
788
789
790
791
792
793
794

795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814










815







+

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








-
-
-
-
-
-
-
-
-
-

	[_listeningSocket cancelAsyncRequests];
	[_listeningSocket release];
	_listeningSocket = nil;
}

-    (bool)socket: (OF_KINDOF(OFTCPSocket *))sock
  didAcceptSocket: (OF_KINDOF(OFTCPSocket *))acceptedSocket
	exception: (id)exception
{
	OFHTTPServer_Connection *connection = [[[OFHTTPServer_Connection alloc]
	OFHTTPServer_Connection *connection;

	if (exception != nil) {
		if (![_delegate respondsToSelector:
		    @selector(server:didReceiveExceptionOnListeningSocket:)])
			return false;

		return [_delegate		  server: self
		    didReceiveExceptionOnListeningSocket: exception];
	}

	connection = [[[OFHTTPServer_Connection alloc]
	    initWithSocket: acceptedSocket
		    server: self] autorelease];

	[(OFTCPSocket *)acceptedSocket setDelegate: connection];
	[acceptedSocket asyncReadLine];

	return true;
}

-		  (void)stream: (OF_KINDOF(OFStream *))stream
  didFailToAcceptWithException: (id)exception
{
	if ([_delegate respondsToSelector:
	    @selector(server:didReceiveExceptionOnListeningSocket:)])
		if ([_delegate			  server: self
		    didReceiveExceptionOnListeningSocket: exception])
			[stream asyncAccept];
}
@end

Modified src/OFRunLoop.m from [536375a07c] to [2b70c16414].

319
320
321
322
323
324
325
326
327
328
329



330
331
332
333



334
335
336
337
338

339
340
341
342
343
344
345
346
347
348
319
320
321
322
323
324
325




326
327
328
329



330
331
332





333



334
335
336
337
338
339
340







-
-
-
-
+
+
+

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







	}

# ifdef OF_HAVE_BLOCKS
	if (_block != NULL)
		return _block(object, _buffer, length, exception);
	else {
# endif
		if (exception == nil) {
			if (![_delegate respondsToSelector:
			    @selector(stream:didReadIntoBuffer:length:)])
				return false;
		if (![_delegate respondsToSelector:
		    @selector(stream:didReadIntoBuffer:length:exception:)])
			return false;

			return [_delegate stream: object
			       didReadIntoBuffer: _buffer
					  length: length];
		return [_delegate stream: object
		       didReadIntoBuffer: _buffer
				  length: length
		} else {
			if ([_delegate respondsToSelector:
			    @selector(stream:didFailToReadWithException:)])
				[_delegate		stream: object
				    didFailToReadWithException: exception];
			       exception: exception];

			return false;
		}
# ifdef OF_HAVE_BLOCKS
	}
# endif
}

# ifdef OF_HAVE_BLOCKS
- (void)dealloc
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
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







-
-
-
-
+
+
+

-
-
-
-
+
+
+
+
+

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







		if (!_block(object, _buffer, _readLength, exception))
			return false;

		_readLength = 0;
		return true;
	} else {
# endif
		if (exception == nil) {
			if (![_delegate respondsToSelector:
			    @selector(stream:didReadIntoBuffer:length:)])
				return false;
		if (![_delegate respondsToSelector:
		    @selector(stream:didReadIntoBuffer:length:exception:)])
			return false;

			if (![_delegate stream: object
			     didReadIntoBuffer: _buffer
					length: _readLength])
				return false;
		if (![_delegate stream: object
		     didReadIntoBuffer: _buffer
				length: _readLength
			     exception: exception])
			return false;

			_readLength = 0;
			return true;
		_readLength = 0;
		return true;
		} else {
			if ([_delegate respondsToSelector:
			    @selector(stream:didFailToReadWithException:)])
				[_delegate		stream: object
				    didFailToReadWithException: exception];

			return false;
		}
# ifdef OF_HAVE_BLOCKS
	}
# endif
}

# ifdef OF_HAVE_BLOCKS
- (void)dealloc
435
436
437
438
439
440
441
442
443
444
445



446
447
448


449
450
451
452
453

454
455
456
457
458
459
460
461
462
463
419
420
421
422
423
424
425




426
427
428
429


430
431





432



433
434
435
436
437
438
439







-
-
-
-
+
+
+

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







		return true;

# ifdef OF_HAVE_BLOCKS
	if (_block != NULL)
		return _block(object, line, exception);
	else {
# endif
		if (exception == nil) {
			if (![_delegate respondsToSelector:
			    @selector(stream:didReadLine:)])
				return false;
		if (![_delegate respondsToSelector:
		    @selector(stream:didReadLine:exception:)])
			return false;

			return [_delegate stream: object
				     didReadLine: line];
		return [_delegate stream: object
			     didReadLine: line
		} else {
			if ([_delegate respondsToSelector:
			    @selector(stream:didFailToReadWithException:)])
				[_delegate		stream: object
				    didFailToReadWithException: exception];
			       exception: exception];

			return false;
		}
# ifdef OF_HAVE_BLOCKS
	}
# endif
}

# ifdef OF_HAVE_BLOCKS
- (void)dealloc
495
496
497
498
499
500
501
502
503
504
505



506
507
508
509




510
511
512


513
514
515


516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
471
472
473
474
475
476
477




478
479
480
481



482
483
484
485
486


487
488
489


490
491








492
493
494
495
496
497
498







-
-
-
-
+
+
+

-
-
-
+
+
+
+

-
-
+
+

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







		if (_length == 0)
			return false;

		_writtenLength = 0;
		return true;
	} else {
# endif
		if (exception == nil) {
			if (![_delegate respondsToSelector:
			    @selector(stream:didWriteBuffer:length:)])
				return false;
		if (![_delegate respondsToSelector:
		    @selector(stream:didWriteBuffer:length:exception:)])
			return false;

			_length = [_delegate stream: object
				     didWriteBuffer: &_buffer
					     length: _length];
		_length = [_delegate stream: object
			     didWriteBuffer: &_buffer
				     length: _length
				  exception: exception];

			if (_length == 0)
				return false;
		if (_length == 0)
			return false;

			_writtenLength = 0;
			return true;
		_writtenLength = 0;
		return true;
		} else {
			if ([_delegate respondsToSelector:
			    @selector(stream:didFailToWriteWithException:)])
				[_delegate		 stream: object
				    didFailToWriteWithException: exception];

			return false;
		}
# ifdef OF_HAVE_BLOCKS
	}
# endif
}

# ifdef OF_HAVE_BLOCKS
- (void)dealloc
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
540
541
542
543
544
545
546




547
548
549
550


551
552





553



554
555
556
557
558
559
560







-
-
-
-
+
+
+

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







	}

# ifdef OF_HAVE_BLOCKS
	if (_block != NULL)
		return _block(object, acceptedSocket, exception);
	else {
# endif
		if (exception == nil) {
			if (![_delegate respondsToSelector:
			    @selector(socket:didAcceptSocket:)])
				return false;
		if (![_delegate respondsToSelector:
		    @selector(socket:didAcceptSocket:exception:)])
			return false;

			return [_delegate socket: object
				 didAcceptSocket: acceptedSocket];
		return [_delegate socket: object
			 didAcceptSocket: acceptedSocket
		} else {
			if ([_delegate respondsToSelector:
			    @selector(socket:didFailToAcceptWithException:)])
				[_delegate		  socket: object
				    didFailToAcceptWithException: exception];
			       exception: exception];

			return false;
		}
# ifdef OF_HAVE_BLOCKS
	}
# endif
}

# ifdef OF_HAVE_BLOCKS
- (void)dealloc
623
624
625
626
627
628
629
630
631
632
633



634
635
636
637
638




639
640
641
642
643

644
645
646
647
648
649
650
651
652
653
583
584
585
586
587
588
589




590
591
592
593




594
595
596
597





598



599
600
601
602
603
604
605







-
-
-
-
+
+
+

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







	}

# ifdef OF_HAVE_BLOCKS
	if (_block != NULL)
		return _block(object, _buffer, length, address, exception);
	else {
# endif
		if (exception == nil) {
			if (![_delegate respondsToSelector: @selector(socket:
			    didReceiveIntoBuffer:length:sender:)])
				return false;
		if (![_delegate respondsToSelector: @selector(
		    socket:didReceiveIntoBuffer:length:sender:exception:)])
			return false;

			return [_delegate socket: object
			    didReceiveIntoBuffer: _buffer
					  length: length
					  sender: address];
		return [_delegate socket: object
		    didReceiveIntoBuffer: _buffer
				  length: length
				  sender: address
		} else {
			if ([_delegate respondsToSelector:
			    @selector(socket:didFailToReceiveWithException:)])
				[_delegate		   socket: object
				    didFailToReceiveWithException: exception];
			       exception: exception];

			return false;
		}
# ifdef OF_HAVE_BLOCKS
	}
# endif
}

# ifdef OF_HAVE_BLOCKS
- (void)dealloc
676
677
678
679
680
681
682
683
684
685
686



687
688
689
690
691




692
693
694
695
696
697
698

699
700

701
702
703
704
705
706
707
708
628
629
630
631
632
633
634




635
636
637
638




639
640
641
642







643
644

645

646
647
648
649
650
651
652







-
-
-
-
+
+
+

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

-
+
-







	if (_block != NULL) {
		_length = _block(object, &_buffer,
		    (exception == nil ? _length : 0), &_receiver, exception);

		return (_length > 0);
	} else {
# endif
		if (exception == nil) {
			if (![_delegate respondsToSelector:
			    @selector(socket:didSendBuffer:length:receiver:)])
				return false;
		if (![_delegate respondsToSelector:
		    @selector(socket:didSendBuffer:length:receiver:exception:)])
			return false;

			_length = [_delegate socket: object
				      didSendBuffer: &_buffer
					     length: _length
					   receiver: &_receiver];
		_length = [_delegate socket: object
			      didSendBuffer: &_buffer
				     length: (exception == nil ? _length : 0)
				   receiver: &_receiver

			return (_length > 0);
		} else {
			if ([_delegate respondsToSelector:
			    @selector(socket:didFailToSendWithException:)])
				[_delegate		socket: object
				    didFailToSendWithException: exception];
				  exception: exception];

			return false;
		return (_length > 0);
		}
# ifdef OF_HAVE_BLOCKS
	}
# endif
}

# ifdef OF_HAVE_BLOCKS
- (void)dealloc

Modified src/OFStream.h from [ea19b2f833] to [ba57cd6e80].

99
100
101
102
103
104
105

106
107
108
109
110


111
112
113
114
115
116
117
118

119
120
121
122


123
124
125
126
127
128
129
130
131
132

133
134
135
136
137
138
139
140


141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
99
100
101
102
103
104
105
106
107
108
109
110

111
112
113
114
115
116
117
118
119
120
121
122
123
124

125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143


144
145



















146
147
148
149
150
151
152







+




-
+
+








+



-
+
+










+






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







/*!
 * @brief This method is called when data was read asynchronously from a
 *	  stream.
 *
 * @param stream The stream on which data was read
 * @param buffer A buffer with the data that has been read
 * @param length The length of the data that has been read
 * @param exception An exception that occurred while reading, or nil on success
 * @return A bool whether the read should be repeated
 */
-      (bool)stream: (OF_KINDOF(OFStream *))stream
  didReadIntoBuffer: (void *)buffer
	     length: (size_t)length;
	     length: (size_t)length
	  exception: (nullable id)exception;

/*!
 * @brief This method is called when a line was read asynchronously from a
 *	  stream.
 *
 * @param stream The stream on which a line was read
 * @param line The line which has been read or `nil` when the end of stream
 *	       occurred
 * @param exception An exception that occurred while reading, or nil on success
 * @return A bool whether the read should be repeated
 */
- (bool)stream: (OF_KINDOF(OFStream *))stream
   didReadLine: (nullable OFString *)line;
   didReadLine: (nullable OFString *)line
     exception: (nullable id)exception;

/*!
 * @brief This method is called when data was written asynchronously to a
 *	  stream.
 *
 * @param stream The stream to which data was written
 * @param buffer A pointer to the buffer which was written to the stream. This
 *		 can be changed to point to a different buffer to be used on the
 *		 next write.
 * @param length The length of the buffer that has been written
 * @param exception An exception that occurred while writing, or nil on success
 * @return The length to repeat the write with or 0 if it should not repeat.
 *	   The buffer may be changed, so that every time a new buffer and
 *	   length can be specified
 */
- (size_t)stream: (OF_KINDOF(OFStream *))stream
  didWriteBuffer: (const void *_Nonnull *_Nonnull)buffer
	  length: (size_t)length;

	  length: (size_t)length
       exception: (nullable id)exception;
/*!
 * @brief This method is called when an exception occurred during an
 *	  asynchronous read on a stream.
 *
 * @param stream The stream for which an exception occurred
 * @param exception The exception which occurred for the stream
 */
-		(void)stream: (OF_KINDOF(OFStream *))stream
  didFailToReadWithException: (id)exception;

/*!
 * @brief This method is called when an exception occurred during an
 *	  asynchronous write on a stream.
 *
 * @param stream The stream for which an exception occurred
 * @param exception The exception which occurred for the stream
 */
-		 (void)stream: (OF_KINDOF(OFStream *))stream
  didFailToWriteWithException: (id)exception;
@end

/*!
 * @class OFStream OFStream.h ObjFW/OFStream.h
 *
 * @brief A base class for different types of streams.
 *

Modified src/OFTCPSocket.h from [077e4589a5] to [e932bc199a].

60
61
62
63
64
65
66




67
68
69
70


71
72
73
74
75
76


77
78
79
80
81


82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
60
61
62
63
64
65
66
67
68
69
70
71
72
73

74
75
76
77
78
79
80
81
82
83
84
85
86


87
88























89
90
91
92
93
94
95







+
+
+
+



-
+
+






+
+



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







 */
@protocol OFTCPSocketDelegate <OFStreamDelegate>
@optional
/*!
 * @brief A method which is called when a socket connected.
 *
 * @param socket The socket which connected
 * @param host The host connected to
 * @param port The port on the host connected to
 * @param exception An exception that occurred while connecting, or nil on
 *		    success
 */
-     (void)socket: (OF_KINDOF(OFTCPSocket *))socket
  didConnectToHost: (OFString *)host
	      port: (uint16_t)port;
	      port: (uint16_t)port
	 exception: (nullable id)exception;

/*!
 * @brief A method which is called when a socket accepted a connection.
 *
 * @param socket The socket which accepted the connection
 * @param acceptedSocket The socket which has been accepted
 * @param exception An exception that occurred while accepting, or nil on
 *		    success
 * @return A bool whether to accept the next incoming connection
 */
-    (bool)socket: (OF_KINDOF(OFTCPSocket *))socket
  didAcceptSocket: (OF_KINDOF(OFTCPSocket *))acceptedSocket;

  didAcceptSocket: (OF_KINDOF(OFTCPSocket *))acceptedSocket
	exception: (nullable id)exception;
/*!
 * @brief This method is called when an exception occurred during an
 *	  asynchronous connect.
 *
 * @param socket The socket for which an exception occurred
 * @param exception The exception which occurred for the stream
 * @param host The host to which the connection failed
 * @param port The port on the host to which the connection failed
 */
-		   (void)socket: (OF_KINDOF(OFTCPSocket *))socket
  didFailToConnectWithException: (id)exception
			   host: (OFString *)host
			   port: (uint16_t)port;

/*!
 * @brief This method is called when an exception occurred during an
 *	  asynchronous accept.
 *
 * @param socket The socket for which an exception occurred
 * @param exception The exception which occurred for the stream
 */
-		  (void)socket: (OF_KINDOF(OFTCPSocket *))socket
  didFailToAcceptWithException: (id)exception;
@end

/*!
 * @class OFTCPSocket OFTCPSocket.h ObjFW/OFTCPSocket.h
 *
 * @brief A class which provides methods to create and use TCP sockets.
 *

Modified src/OFTCPSocket.m from [349339a041] to [dd4630f033].

208
209
210
211
212
213
214
215
216
217
218
219
220





221
222
223
224
225

226
227
228
229
230
231
232
233
234
235
208
209
210
211
212
213
214






215
216
217
218
219





220



221
222
223
224
225
226
227







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







#ifdef OF_HAVE_BLOCKS
	if (_block != NULL)
		_block(_socket, _exception);
	else {
#endif
		[_socket setDelegate: _delegate];

		if (_exception == nil) {
			if ([_delegate respondsToSelector:
			    @selector(socket:didConnectToHost:port:)])
				[_delegate    socket: _socket
				    didConnectToHost: _host
						port: _port];
		if ([_delegate respondsToSelector:
		    @selector(socket:didConnectToHost:port:exception:)])
			[_delegate    socket: _socket
			    didConnectToHost: _host
					port: _port
		} else {
			if ([_delegate respondsToSelector: @selector(socket:
			    didFailToConnectWithException:host:port:)])
				[_delegate		   socket: _socket
				    didFailToConnectWithException: _exception
				   exception: _exception];
							     host: _host
							     port: _port];
		}
#ifdef OF_HAVE_BLOCKS
	}
#endif
}

- (void)of_socketDidConnect: (OF_KINDOF(OFTCPSocket *))sock
		  exception: (id)exception
376
377
378
379
380
381
382

383
384

385
386
387
388
389
390








391
392
393
394
395
396
397
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







+

-
+
-





+
+
+
+
+
+
+
+







			   length: 3
		      runLoopMode: [[OFRunLoop currentRunLoop] currentMode]];
}

-      (bool)stream: (OF_KINDOF(OFStream *))sock
  didReadIntoBuffer: (void *)buffer
	     length: (size_t)length
	  exception: (id)exception
{
	of_run_loop_mode_t runLoopMode =
	of_run_loop_mode_t runLoopMode;
	    [[OFRunLoop currentRunLoop] currentMode];
	unsigned char *SOCKSVersion;
	uint8_t hostLength;
	unsigned char port[2];
	unsigned char *response, *addressLength;

	if (exception != nil) {
		_exception = [exception retain];
		[self didConnect];
		return false;
	}

	runLoopMode = [[OFRunLoop currentRunLoop] currentMode];

	switch (_SOCKS5State) {
	case SOCKS5_STATE_READ_VERSION:
		SOCKSVersion = buffer;

		if (SOCKSVersion[0] != 5 || SOCKSVersion[1] != 0) {
			_exception = [[OFConnectionFailedException alloc]
			    initWithHost: _host
522
523
524
525
526
527
528

529
530
531









532
533
534
535
536
537
538
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







+

-
-
+
+
+
+
+
+
+
+
+







		return false;
	}
}

- (size_t)stream: (OF_KINDOF(OFStream *))sock
  didWriteBuffer: (const void **)buffer
	  length: (size_t)length
       exception: (id)exception
{
	of_run_loop_mode_t runLoopMode =
	    [[OFRunLoop currentRunLoop] currentMode];
	of_run_loop_mode_t runLoopMode;

	if (exception != nil) {
		_exception = [exception retain];
		[self didConnect];
		return 0;
	}

	runLoopMode = [[OFRunLoop currentRunLoop] currentMode];

	switch (_SOCKS5State) {
	case SOCKS5_STATE_SEND_AUTHENTICATION:
		_SOCKS5State = SOCKS5_STATE_READ_VERSION;
		[_socket asyncReadIntoBuffer: _buffer
				 exactLength: 2
				 runLoopMode: runLoopMode];
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
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







-
-
-
-
-
-
-
-
-
-
-
-
-
-













-
-
-
-
-
-
+







				 runLoopMode: runLoopMode];
		return 0;
	default:
		assert(0);
		return 0;
	}
}

-		(void)stream: (OF_KINDOF(OFStream *))sock
  didFailToReadWithException: (id)exception
{
	_exception = [exception retain];
	[self didConnect];
}

-		 (void)stream: (OF_KINDOF(OFStream *))sock
  didFailToWriteWithException: (id)exception
{
	_exception = [exception retain];
	[self didConnect];
}
@end

@implementation OFTCPSocket_ConnectDelegate
- (void)dealloc
{
	[_exception release];

	[super dealloc];
}

-     (void)socket: (OF_KINDOF(OFTCPSocket *))sock
  didConnectToHost: (OFString *)host
	      port: (uint16_t)port
{
	_done = true;
}

-		   (void)socket: (OF_KINDOF(OFTCPSocket *))sock
  didFailToConnectWithException: (id)exception
	 exception: (id)exception
{
	_done = true;
	_exception = [exception retain];
}
@end

@implementation OFTCPSocket

Modified src/OFUDPSocket.h from [6654ade8b5] to [ab6554e3b4].

76
77
78
79
80
81
82


83
84
85
86
87
88


89
90
91
92
93
94
95
96
97
98

99
100
101
102
103
104
105
106
107
108


109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
76
77
78
79
80
81
82
83
84
85
86
87
88
89

90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110


111
112



















113
114
115
116
117
118
119







+
+





-
+
+










+








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







/*!
 * @brief This method is called when a packet has been received.
 *
 * @param socket The UDP socket which received a packet
 * @param buffer The buffer the packet has been written to
 * @param length The length of the packet
 * @param sender The address of the sender of the packet
 * @param exception An exception that occurred while receiving, or nil on
 *		    success
 * @return A bool whether the same block should be used for the next receive
 */
-	  (bool)socket: (OF_KINDOF(OFUDPSocket *))socket
  didReceiveIntoBuffer: (void *)buffer
		length: (size_t)length
		sender: (of_socket_address_t)sender;
		sender: (of_socket_address_t)sender
	     exception: (nullable id)exception;

/*!
 * @brief This which is called when a packet has been sent.
 *
 * @param socket The UDP socket which sent a packet
 * @param buffer A pointer to the buffer which was sent. This can be changed to
 *		 point to a different buffer to be used on the next send.
 * @param length The length of the buffer that has been sent
 * @param receiver The receiver for the UDP packet. This may be set to a new
 *		   receiver to which the next packet is sent.
 * @param exception An exception that occurred while sending, or nil on success
 * @return The length to repeat the send with or 0 if it should not repeat.
 *	   The buffer and receiver may be changed, so that every time a new
 *	   buffer, length and receiver can be specified while the callback
 *	   stays the same.
 */
- (size_t)socket: (OF_KINDOF(OFUDPSocket *))socket
   didSendBuffer: (const void *_Nonnull *_Nonnull)buffer
	  length: (size_t)length
	receiver: (of_socket_address_t *_Nonnull)receiver;

	receiver: (of_socket_address_t *_Nonnull)receiver
       exception: (nullable id)exception;
/*!
 * @brief This method is called when an exception occurred during an
 *	  asynchronous receive on the socket.
 *
 * @param socket The socket for which an exception occurred
 * @param exception The exception which occurred for the socket
 */
-		   (void)socket: (OF_KINDOF(OFUDPSocket *))socket
  didFailToReceiveWithException: (id)exception;

/*!
 * @brief This method is called when an exception occurred during an
 *	  asynchronous send on the socket.
 *
 * @param socket The socket for which an exception occurred
 * @param exception The exception which occurred for the socket
 */
-		(void)socket: (OF_KINDOF(OFUDPSocket *))socket
  didFailToSendWithException: (id)exception;
@end

/*!
 * @class OFUDPSocket OFUDPSocket.h ObjFW/OFUDPSocket.h
 *
 * @brief A class which provides methods to create and use UDP sockets.
 *

Modified utils/ofhttp/OFHTTP.m from [31817d3b24] to [c4c7ef8326].

652
653
654
655
656
657
658

659

























660
661
662
663
664
665
666
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692







+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







	[self performSelector: @selector(downloadNextURL)
		   afterDelay: 0];
}

-      (bool)stream: (OF_KINDOF(OFStream *))response
  didReadIntoBuffer: (void *)buffer
	     length: (size_t)length
	  exception: (id)exception
{
	if (exception != nil) {
		OFString *URL;

		[_progressBar stop];
		[_progressBar draw];
		[_progressBar release];
		_progressBar = nil;

		if (!_quiet)
			[of_stdout writeString: @"\n  Error!\n"];

		URL = [_URLs objectAtIndex: _URLIndex - 1];
		[of_stderr writeLine: OF_LOCALIZED(
		    @"download_failed_exception",
		    @"%[prog]: Failed to download <%[url]>: %[exception]",
		    @"prog", [OFApplication programName],
		    @"url", URL,
		    @"exception", exception)];

		_errorCode = 1;
		[self performSelector: @selector(downloadNextURL)
			   afterDelay: 0];
		return false;
	}

	_received += length;

	[_output writeBuffer: buffer
		      length: length];

	[_progressBar setReceived: _received];

681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
707
708
709
710
711
712
713


























714
715
716
717
718
719
720







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







			   afterDelay: 0];
		return false;
	}

	return true;
}

-	  (void)stream: (OF_KINDOF(OFStream *))response
  didFailWithException: (id)exception
{
	OFString *URL;

	[_progressBar stop];
	[_progressBar draw];
	[_progressBar release];
	_progressBar = nil;

	if (!_quiet)
		[of_stdout writeString: @"\n  Error!\n"];

	URL = [_URLs objectAtIndex: _URLIndex - 1];
	[of_stderr writeLine: OF_LOCALIZED(
	    @"download_failed_exception",
	    @"%[prog]: Failed to download <%[url]>: %[exception]",
	    @"prog", [OFApplication programName],
	    @"url", URL,
	    @"exception", exception)];

	_errorCode = 1;
	[self performSelector: @selector(downloadNextURL)
		   afterDelay: 0];
}

-      (void)client: (OFHTTPClient *)client
  didReceiveHeaders: (OFDictionary OF_GENERIC(OFString *, OFString *) *)headers
	 statusCode: (int)statusCode
	    request: (OFHTTPRequest *)request
	    context: (id)context
{
	if (!_quiet) {