ObjFW  Check-in [27120e14ca]

Overview
Comment:OFHTTPServer: Add a timeout.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 27120e14ca571019f20203a5db6bb1fddc2fee2494788d1a9b82df8dbf2141a2
User & Date: js on 2012-12-20 14:24:02
Other Links: manifest | tags
Context
2012-12-20
15:11
OFHTTPRequestResult: Fix a missing release. check-in: 4d636a1d00 user: js tags: trunk
14:24
OFHTTPServer: Add a timeout. check-in: 27120e14ca user: js tags: trunk
14:20
OFTimer: Release target in -[invalidate]. check-in: a86271a67a user: js tags: trunk
Changes

Modified src/OFHTTPServer.m from [862d84b05e] to [91602836ad].

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