︙ | | |
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
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
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
|
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
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
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
|
+
+
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
|
#import "OFData.h"
#import "OFDate.h"
#import "OFDictionary.h"
#import "OFHTTPRequest.h"
#import "OFHTTPResponse.h"
#import "OFNumber.h"
#import "OFTCPSocket.h"
#import "OFTLSSocket.h"
#import "OFTimer.h"
#import "OFURL.h"
#import "OFAlreadyConnectedException.h"
#import "OFInvalidArgumentException.h"
#import "OFInvalidFormatException.h"
#import "OFNotOpenException.h"
#import "OFOutOfMemoryException.h"
#import "OFOutOfRangeException.h"
#import "OFUnsupportedProtocolException.h"
#import "OFWriteFailedException.h"
#import "socket_helpers.h"
#define BUFFER_SIZE 1024
/*
* FIXME: Key normalization replaces headers like "DNT" with "Dnt".
* FIXME: Errors are not reported to the user.
*/
@interface OFHTTPServer ()
- (bool)of_socket: (OFTCPSocket *)sock
didAcceptSocket: (OFTCPSocket *)clientSocket
- (bool)of_socket: (OF_KINDOF(OFTCPSocket *))sock
didAcceptSocket: (OF_KINDOF(OFTCPSocket *))clientSocket
context: (id)context
exception: (id)exception;
@end
@interface OFHTTPServerResponse: OFHTTPResponse <OFReadyForWritingObserving>
{
OFTCPSocket *_socket;
OF_KINDOF(OFTCPSocket *) _socket;
OFHTTPServer *_server;
OFHTTPRequest *_request;
bool _chunked, _headersSent;
}
- (instancetype)initWithSocket: (OFTCPSocket *)sock
- (instancetype)initWithSocket: (OF_KINDOF(OFTCPSocket *))sock
server: (OFHTTPServer *)server
request: (OFHTTPRequest *)request;
@end
@interface OFHTTPServer_Connection: OFObject
{
@public
OFTCPSocket *_socket;
OF_KINDOF(OFTCPSocket *) _socket;
OFHTTPServer *_server;
OFTimer *_timer;
enum {
AWAITING_PROLOG,
PARSING_HEADERS,
SEND_RESPONSE
} _state;
uint8_t _HTTPMinorVersion;
of_http_request_method_t _method;
OFString *_host, *_path;
uint16_t _port;
OFMutableDictionary *_headers;
size_t _contentLength;
OFStream *_requestBody;
}
- (instancetype)initWithSocket: (OFTCPSocket *)sock
- (instancetype)initWithSocket: (OF_KINDOF(OFTCPSocket *))sock
server: (OFHTTPServer *)server;
- (bool)socket: (OFTCPSocket *)sock
- (bool)socket: (OF_KINDOF(OFTCPSocket *))sock
didReadLine: (OFString *)line
context: (id)context
exception: (id)exception;
- (bool)parseProlog: (OFString *)line;
- (bool)parseHeaders: (OFString *)line;
- (bool)sendErrorAndClose: (short)statusCode;
- (void)createResponse;
@end
@interface OFHTTPServerRequestBodyStream: OFStream <OFReadyForReadingObserving>
{
OFTCPSocket *_socket;
OF_KINDOF(OFTCPSocket *) _socket;
uintmax_t _toRead;
bool _atEndOfStream;
}
- (instancetype)initWithSocket: (OFTCPSocket *)sock
- (instancetype)initWithSocket: (OF_KINDOF(OFTCPSocket *))sock
contentLength: (uintmax_t)contentLength;
@end
static const char *
statusCodeToString(short code)
{
switch (code) {
|
︙ | | |
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
|
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
|
-
+
|
}
return [OFString stringWithUTF8StringNoCopy: cString
freeWhenDone: true];
}
@implementation OFHTTPServerResponse
- (instancetype)initWithSocket: (OFTCPSocket *)sock
- (instancetype)initWithSocket: (OF_KINDOF(OFTCPSocket *))sock
server: (OFHTTPServer *)server
request: (OFHTTPRequest *)request
{
self = [super init];
_statusCode = 500;
_socket = [sock retain];
|
︙ | | |
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
|
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
|
-
+
|
return -1;
return [_socket fileDescriptorForWriting];
}
@end
@implementation OFHTTPServer_Connection
- (instancetype)initWithSocket: (OFTCPSocket *)sock
- (instancetype)initWithSocket: (OF_KINDOF(OFTCPSocket *))sock
server: (OFHTTPServer *)server
{
self = [super init];
@try {
_socket = [sock retain];
_server = [server retain];
|
︙ | | |
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
|
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
|
-
+
|
[_path release];
[_headers release];
[_requestBody release];
[super dealloc];
}
- (bool)socket: (OFTCPSocket *)sock
- (bool)socket: (OF_KINDOF(OFTCPSocket *))sock
didReadLine: (OFString *)line
context: (id)context
exception: (id)exception
{
if (line == nil || exception != nil)
return false;
|
︙ | | |
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
|
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
|
-
-
+
+
|
response: response];
objc_autoreleasePoolPop(pool);
}
@end
@implementation OFHTTPServerRequestBodyStream
- (instancetype)initWithSocket: (OFTCPSocket *)sock
contentLength: (uintmax_t)contentLength
- (instancetype)initWithSocket: (OF_KINDOF(OFTCPSocket *))sock
contentLength: (uintmax_t)contentLength
{
self = [super init];
@try {
_socket = [sock retain];
_toRead = contentLength;
} @catch (id e) {
|
︙ | | |
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
|
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
|
-
+
+
+
+
+
|
{
[_socket release];
_socket = nil;
}
@end
@implementation OFHTTPServer
@synthesize host = _host, port = _port, delegate = _delegate, name = _name;
@synthesize host = _host, port = _port, usesTLS = _usesTLS;
@synthesize certificateFile = _certificateFile;
@synthesize privateKeyFile = _privateKeyFile;
@synthesize privateKeyPassphrase = _privateKeyPassphrase, delegate = _delegate;
@synthesize name = _name;
+ (instancetype)server
{
return [[[self alloc] init] autorelease];
}
- (instancetype)init
|
︙ | | |
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
|
762
763
764
765
766
767
768
769
770
771
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
|
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
-
-
+
+
|
{
if (_host == nil)
@throw [OFInvalidArgumentException exception];
if (_listeningSocket != nil)
@throw [OFAlreadyConnectedException exception];
if (_usesTLS) {
id <OFTLSSocket> listeningSocket;
if (of_tls_socket_class == Nil)
@throw [OFUnsupportedProtocolException exception];
_listeningSocket = [[of_tls_socket_class alloc] init];
listeningSocket = _listeningSocket;
[listeningSocket setCertificateFile: _certificateFile];
[listeningSocket setPrivateKeyFile: _privateKeyFile];
[listeningSocket
setPrivateKeyPassphrase: _privateKeyPassphrase];
} else
_listeningSocket = [[OFTCPSocket alloc] init];
_listeningSocket = [[OFTCPSocket alloc] init];
_port = [_listeningSocket bindToHost: _host
port: _port];
[_listeningSocket listen];
[_listeningSocket asyncAcceptWithTarget: self
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)of_socket: (OF_KINDOF(OFTCPSocket *))sock
didAcceptSocket: (OF_KINDOF(OFTCPSocket *))clientSocket
context: (id)context
exception: (id)exception
{
OFHTTPServer_Connection *connection;
if (exception != nil) {
if ([_delegate respondsToSelector:
|
︙ | | |