ObjFW  Diff

Differences From Artifact [fe26303808]:

  • File src/OFHTTPServer.m — part of check-in [d16ad96cbd] at 2018-12-07 01:33:47 on branch trunk — OFStream: Use a delegate for async operations

    The target / selector approach had several drawbacks:

    * It was inconvenient to use, as for every read or write, a target,
    selector and context would need to be specified.
    * It lacked any kind of type-safety and would not even warn about using
    a callback method with the wrong number of parameters.
    * It encouraged using a different callback method for each read or
    write call, which results in code that is hard to follow and also
    slower (as it needs to recreate the async operation with a new
    callback every time). (user: js, size: 17752) [annotate] [blame] [check-ins using]

To Artifact [abf11296e3]:


46
47
48
49
50
51
52
53

54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73

74
75
76
77
78
79
80
46
47
48
49
50
51
52

53




54
55
56
57
58
59
60
61
62
63
64
65
66
67
68

69
70
71
72
73
74
75
76







-
+
-
-
-
-















-
+







#define BUFFER_SIZE 1024

/*
 * FIXME: Key normalization replaces headers like "DNT" with "Dnt".
 * FIXME: Errors are not reported to the user.
 */

@interface OFHTTPServer ()
@interface OFHTTPServer () <OFTCPSocketDelegate>
- (bool)of_socket: (OFTCPSocket *)sock
  didAcceptSocket: (OFTCPSocket *)clientSocket
	  context: (id)context
	exception: (id)exception;
@end

@interface OFHTTPServerResponse: OFHTTPResponse <OFReadyForWritingObserving>
{
	OF_KINDOF(OFTCPSocket *) _socket;
	OFHTTPServer *_server;
	OFHTTPRequest *_request;
	bool _chunked, _headersSent;
}

- (instancetype)initWithSocket: (OF_KINDOF(OFTCPSocket *))sock
			server: (OFHTTPServer *)server
		       request: (OFHTTPRequest *)request;
@end

@interface OFHTTPServer_Connection: OFObject <OFStreamDelegate>
@interface OFHTTPServer_Connection: OFObject <OFTCPSocketDelegate>
{
@public
	OF_KINDOF(OFTCPSocket *) _socket;
	OFHTTPServer *_server;
	OFTimer *_timer;
	enum {
		AWAITING_PROLOG,
776
777
778
779
780
781
782

783

784
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
813
814

815
816
817
818


819
820
821










822
772
773
774
775
776
777
778
779

780




781
782
783
784
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







+
-
+
-
-
-
-









-
-
+
+
-
-

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


-
-
+
+



+
+
+
+
+
+
+
+
+
+

	} else
		_listeningSocket = [[OFTCPSocket alloc] init];

	_port = [_listeningSocket bindToHost: _host
					port: _port];
	[_listeningSocket listen];

	[(OFTCPSocket *)_listeningSocket setDelegate: self];
	[_listeningSocket asyncAcceptWithTarget: self
	[_listeningSocket asyncAccept];
				       selector: @selector(of_socket:
						     didAcceptSocket:context:
						     exception:)
					context: nil];
}

- (void)stop
{
	[_listeningSocket cancelAsyncRequests];
	[_listeningSocket release];
	_listeningSocket = nil;
}

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

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

		return false;
	}

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

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

	return true;
}

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