︙ | | | ︙ | |
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
|
#import "OFHTTPServer.h"
#import "OFDataArray.h"
#import "OFDate.h"
#import "OFDictionary.h"
#import "OFURL.h"
#import "OFHTTPRequest.h"
#import "OFTCPSocket.h"
#import "OFAlreadyConnectedException.h"
#import "OFInvalidArgumentException.h"
#import "OFInvalidFormatException.h"
#import "OFNotImplementedException.h"
#import "OFOutOfMemoryException.h"
#import "OFOutOfRangeException.h"
#import "OFWriteFailedException.h"
#import "macros.h"
#define BUFFER_SIZE 1024
/*
* FIXME: Currently, connections never time out, which means a DoS is possible.
* TODO: Add support for chunked transfer encoding.
* FIXME: Key normalization replaces headers like "DNT" with "Dnt".
* FIXME: Errors are not reported to the user.
*/
static const char*
status_code_to_string(short code)
|
>
<
|
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
|
#import "OFHTTPServer.h"
#import "OFDataArray.h"
#import "OFDate.h"
#import "OFDictionary.h"
#import "OFURL.h"
#import "OFHTTPRequest.h"
#import "OFTCPSocket.h"
#import "OFTimer.h"
#import "OFAlreadyConnectedException.h"
#import "OFInvalidArgumentException.h"
#import "OFInvalidFormatException.h"
#import "OFNotImplementedException.h"
#import "OFOutOfMemoryException.h"
#import "OFOutOfRangeException.h"
#import "OFWriteFailedException.h"
#import "macros.h"
#define BUFFER_SIZE 1024
/*
* TODO: Add support for chunked transfer encoding.
* FIXME: Key normalization replaces headers like "DNT" with "Dnt".
* FIXME: Errors are not reported to the user.
*/
static const char*
status_code_to_string(short code)
|
︙ | | | ︙ | |
166
167
168
169
170
171
172
173
174
175
176
177
178
179
|
freeWhenDone: YES];
}
@interface OFHTTPServer_Connection: OFObject
{
OFTCPSocket *sock;
OFHTTPServer *server;
enum {
AWAITING_PROLOG,
PARSING_HEADERS,
SEND_REPLY
} state;
uint8_t HTTPMinorVersion;
of_http_request_type_t requestType;
|
>
|
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
|
freeWhenDone: YES];
}
@interface OFHTTPServer_Connection: OFObject
{
OFTCPSocket *sock;
OFHTTPServer *server;
OFTimer *timer;
enum {
AWAITING_PROLOG,
PARSING_HEADERS,
SEND_REPLY
} state;
uint8_t HTTPMinorVersion;
of_http_request_type_t requestType;
|
︙ | | | ︙ | |
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
|
@implementation OFHTTPServer_Connection
- initWithSocket: (OFTCPSocket*)sock_
server: (OFHTTPServer*)server_
{
self = [super init];
sock = [sock_ retain];
server = [server_ retain];
state = AWAITING_PROLOG;
return self;
}
- (void)dealloc
{
[sock release];
[server release];
[host release];
[path release];
[headers release];
[POSTData release];
[super dealloc];
}
|
>
|
|
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
|
202
203
204
205
206
207
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
236
237
238
239
240
241
|
@implementation OFHTTPServer_Connection
- initWithSocket: (OFTCPSocket*)sock_
server: (OFHTTPServer*)server_
{
self = [super init];
@try {
sock = [sock_ retain];
server = [server_ retain];
timer = [[OFTimer
scheduledTimerWithTimeInterval: 10
target: sock
selector: @selector(
cancelAsyncRequests)
repeats: NO] retain];
state = AWAITING_PROLOG;
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[sock release];
[server release];
[timer invalidate];
[timer release];
[host release];
[path release];
[headers release];
[POSTData release];
[super dealloc];
}
|
︙ | | | ︙ | |
336
337
338
339
340
341
342
343
344
345
346
347
348
349
|
[sock asyncReadIntoBuffer: buffer
length: BUFFER_SIZE
target: self
selector: @selector(socket:
didReadIntoBuffer:
length:exception:)];
return NO;
}
return YES;
}
|
>
>
|
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
|
[sock asyncReadIntoBuffer: buffer
length: BUFFER_SIZE
target: self
selector: @selector(socket:
didReadIntoBuffer:
length:exception:)];
[timer setFireDate:
[OFDate dateWithTimeIntervalSinceNow: 5]];
return NO;
}
return YES;
}
|
︙ | | | ︙ | |
411
412
413
414
415
416
417
418
419
420
421
422
423
424
|
} @catch (OFWriteFailedException *e) {
return NO;
}
return NO;
}
return YES;
}
- (BOOL)sendErrorAndClose: (short)statusCode
{
OFString *date = [[OFDate date]
dateStringWithFormat: @"%a, %d %b %Y %H:%M:%S GMT"];
|
>
>
|
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
|
} @catch (OFWriteFailedException *e) {
return NO;
}
return NO;
}
[timer setFireDate: [OFDate dateWithTimeIntervalSinceNow: 5]];
return YES;
}
- (BOOL)sendErrorAndClose: (short)statusCode
{
OFString *date = [[OFDate date]
dateStringWithFormat: @"%a, %d %b %Y %H:%M:%S GMT"];
|
︙ | | | ︙ | |
439
440
441
442
443
444
445
446
447
448
449
450
451
452
|
OFURL *URL;
OFHTTPRequest *request;
OFHTTPRequestResult *reply;
OFDictionary *replyHeaders;
OFDataArray *replyData;
OFEnumerator *keyEnumerator, *valueEnumerator;
OFString *key, *value;
if (host == nil || port == 0) {
if (HTTPMinorVersion > 0) {
[self sendErrorAndClose: 400];
return;
}
|
>
>
>
>
|
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
|
OFURL *URL;
OFHTTPRequest *request;
OFHTTPRequestResult *reply;
OFDictionary *replyHeaders;
OFDataArray *replyData;
OFEnumerator *keyEnumerator, *valueEnumerator;
OFString *key, *value;
[timer invalidate];
[timer release];
timer = nil;
if (host == nil || port == 0) {
if (HTTPMinorVersion > 0) {
[self sendErrorAndClose: 400];
return;
}
|
︙ | | | ︙ | |
612
613
614
615
616
617
618
619
620
621
622
623
624
625
|
if (exception != nil)
return NO;
connection = [[[OFHTTPServer_Connection alloc]
initWithSocket: clientSocket
server: self] autorelease];
[clientSocket asyncReadLineWithTarget: connection
selector: @selector(socket:didReadLine:
exception:)];
return YES;
}
@end
|
>
|
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
|
if (exception != nil)
return NO;
connection = [[[OFHTTPServer_Connection alloc]
initWithSocket: clientSocket
server: self] autorelease];
[clientSocket asyncReadLineWithTarget: connection
selector: @selector(socket:didReadLine:
exception:)];
return YES;
}
@end
|
︙ | | | ︙ | |