mirror of
https://github.com/gnustep/libs-sqlclient.git
synced 2025-02-21 02:41:07 +00:00
Add session timeouts.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/sqlclient/trunk@19835 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
dcdcf483f8
commit
b35b40f235
3 changed files with 110 additions and 6 deletions
|
@ -1,3 +1,7 @@
|
||||||
|
Sat Aug 07 14:25:00 2004 Richard Frith-Macdonald <rfm@gnu.org>
|
||||||
|
|
||||||
|
* WebServer.m: Add session timeouts to kill off idle sessions.
|
||||||
|
|
||||||
Tue Jul 27 17:30:00 2004 Richard Frith-Macdonald <rfm@gnu.org>
|
Tue Jul 27 17:30:00 2004 Richard Frith-Macdonald <rfm@gnu.org>
|
||||||
|
|
||||||
* configure.ac: Give more help when postgres is not found.
|
* configure.ac: Give more help when postgres is not found.
|
||||||
|
|
10
WebServer.h
10
WebServer.h
|
@ -131,6 +131,9 @@
|
||||||
NSMapTable *_sessions;
|
NSMapTable *_sessions;
|
||||||
unsigned _handled;
|
unsigned _handled;
|
||||||
NSString *_root;
|
NSString *_root;
|
||||||
|
NSTimer *_ticker;
|
||||||
|
NSTimeInterval _sessionTimeout;
|
||||||
|
NSTimeInterval _ticked;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -291,6 +294,12 @@
|
||||||
*/
|
*/
|
||||||
- (void) setRoot: (NSString*)aPath;
|
- (void) setRoot: (NSString*)aPath;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the time after which an idle session should be shut down.<br />
|
||||||
|
* Default is 30.0
|
||||||
|
*/
|
||||||
|
- (void) setSessionTimeout: (NSTimeInterval)aDelay;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets a flag to determine whether verbose logging is to be performed.<br />
|
* Sets a flag to determine whether verbose logging is to be performed.<br />
|
||||||
* If this is YES then all incming requests and their responses will
|
* If this is YES then all incming requests and their responses will
|
||||||
|
@ -320,6 +329,7 @@
|
||||||
using: (NSDictionary*)map
|
using: (NSDictionary*)map
|
||||||
into: (NSMutableString*)result
|
into: (NSMutableString*)result
|
||||||
depth: (unsigned)depth;
|
depth: (unsigned)depth;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
92
WebServer.m
92
WebServer.m
|
@ -33,16 +33,22 @@
|
||||||
GSMimeParser *parser;
|
GSMimeParser *parser;
|
||||||
NSMutableData *buffer;
|
NSMutableData *buffer;
|
||||||
unsigned byteCount;
|
unsigned byteCount;
|
||||||
|
NSTimeInterval ticked;
|
||||||
|
BOOL processing;
|
||||||
}
|
}
|
||||||
- (NSString*) address;
|
- (NSString*) address;
|
||||||
- (NSMutableData*) buffer;
|
- (NSMutableData*) buffer;
|
||||||
- (NSFileHandle*) handle;
|
- (NSFileHandle*) handle;
|
||||||
- (unsigned) moreBytes: (unsigned)count;
|
- (unsigned) moreBytes: (unsigned)count;
|
||||||
- (GSMimeParser*) parser;
|
- (GSMimeParser*) parser;
|
||||||
|
- (BOOL) processing;
|
||||||
- (void) setAddress: (NSString*)aString;
|
- (void) setAddress: (NSString*)aString;
|
||||||
- (void) setBuffer: (NSMutableData*)aBuffer;
|
- (void) setBuffer: (NSMutableData*)aBuffer;
|
||||||
- (void) setHandle: (NSFileHandle*)aHandle;
|
- (void) setHandle: (NSFileHandle*)aHandle;
|
||||||
- (void) setParser: (GSMimeParser*)aParser;
|
- (void) setParser: (GSMimeParser*)aParser;
|
||||||
|
- (void) setProcessing: (BOOL)aFlag;
|
||||||
|
- (void) setTicked: (NSTimeInterval)when;
|
||||||
|
- (NSTimeInterval) ticked;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation WebServerSession
|
@implementation WebServerSession
|
||||||
|
@ -88,6 +94,11 @@
|
||||||
return parser;
|
return parser;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (BOOL) processing
|
||||||
|
{
|
||||||
|
return processing;
|
||||||
|
}
|
||||||
|
|
||||||
- (void) setAddress: (NSString*)aString
|
- (void) setAddress: (NSString*)aString
|
||||||
{
|
{
|
||||||
ASSIGN(address, aString);
|
ASSIGN(address, aString);
|
||||||
|
@ -107,6 +118,21 @@
|
||||||
{
|
{
|
||||||
ASSIGN(parser, aParser);
|
ASSIGN(parser, aParser);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void) setProcessing: (BOOL)aFlag
|
||||||
|
{
|
||||||
|
processing = aFlag;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) setTicked: (NSTimeInterval)when
|
||||||
|
{
|
||||||
|
ticked = when;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSTimeInterval) ticked
|
||||||
|
{
|
||||||
|
return ticked;
|
||||||
|
}
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface WebServer (Private)
|
@interface WebServer (Private)
|
||||||
|
@ -116,12 +142,18 @@
|
||||||
- (void) _didWrite: (NSNotification*)notification;
|
- (void) _didWrite: (NSNotification*)notification;
|
||||||
- (void) _endSession: (WebServerSession*)session;
|
- (void) _endSession: (WebServerSession*)session;
|
||||||
- (void) _process: (WebServerSession*)session;
|
- (void) _process: (WebServerSession*)session;
|
||||||
|
- (void) _ticker: (NSTimer*)timer;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation WebServer
|
@implementation WebServer
|
||||||
|
|
||||||
- (void) dealloc
|
- (void) dealloc
|
||||||
{
|
{
|
||||||
|
if (_ticker != nil)
|
||||||
|
{
|
||||||
|
[_ticker invalidate];
|
||||||
|
_ticker = nil;
|
||||||
|
}
|
||||||
[self setPort: nil secure: nil];
|
[self setPort: nil secure: nil];
|
||||||
DESTROY(_nc);
|
DESTROY(_nc);
|
||||||
DESTROY(_root);
|
DESTROY(_root);
|
||||||
|
@ -300,12 +332,18 @@ unescapeData(const unsigned char* bytes, unsigned length, unsigned char *buf)
|
||||||
- (id) init
|
- (id) init
|
||||||
{
|
{
|
||||||
_nc = RETAIN([NSNotificationCenter defaultCenter]);
|
_nc = RETAIN([NSNotificationCenter defaultCenter]);
|
||||||
|
_sessionTimeout = 30.0;
|
||||||
_maxSess = 32;
|
_maxSess = 32;
|
||||||
_maxBodySize = 8*1024;
|
_maxBodySize = 8*1024;
|
||||||
_maxRequestSize = 4*1024*1024;
|
_maxRequestSize = 4*1024*1024;
|
||||||
_substitutionLimit = 4;
|
_substitutionLimit = 4;
|
||||||
_sessions = NSCreateMapTable(NSNonOwnedPointerMapKeyCallBacks,
|
_sessions = NSCreateMapTable(NSNonOwnedPointerMapKeyCallBacks,
|
||||||
NSObjectMapValueCallBacks, 0);
|
NSObjectMapValueCallBacks, 0);
|
||||||
|
_ticker = [NSTimer scheduledTimerWithTimeInterval: 0.8
|
||||||
|
target: self
|
||||||
|
selector: @selector(_timeout:)
|
||||||
|
userInfo: 0
|
||||||
|
repeats: YES];
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -597,6 +635,11 @@ unescapeData(const unsigned char* bytes, unsigned length, unsigned char *buf)
|
||||||
ASSIGN(_root, aPath);
|
ASSIGN(_root, aPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void) setSessionTimeout: (NSTimeInterval)aDelay
|
||||||
|
{
|
||||||
|
_sessionTimeout = aDelay;
|
||||||
|
}
|
||||||
|
|
||||||
- (void) setSubstitutionLimit: (unsigned)depth
|
- (void) setSubstitutionLimit: (unsigned)depth
|
||||||
{
|
{
|
||||||
_substitutionLimit = depth;
|
_substitutionLimit = depth;
|
||||||
|
@ -838,6 +881,9 @@ unescapeData(const unsigned char* bytes, unsigned length, unsigned char *buf)
|
||||||
}
|
}
|
||||||
// NSLog(@"Data read on %@ ... %@", session, d);
|
// NSLog(@"Data read on %@ ... %@", session, d);
|
||||||
|
|
||||||
|
// Mark session as having had I/O ... not idle.
|
||||||
|
[session setTicked: _ticked];
|
||||||
|
|
||||||
if (parser == nil)
|
if (parser == nil)
|
||||||
{
|
{
|
||||||
unsigned char *bytes;
|
unsigned char *bytes;
|
||||||
|
@ -1082,7 +1128,7 @@ unescapeData(const unsigned char* bytes, unsigned length, unsigned char *buf)
|
||||||
|
|
||||||
- (void) _process: (WebServerSession*)session
|
- (void) _process: (WebServerSession*)session
|
||||||
{
|
{
|
||||||
GSMimeDocument *request = [[session parser] mimeDocument];
|
GSMimeDocument *request;
|
||||||
GSMimeDocument *response;
|
GSMimeDocument *response;
|
||||||
BOOL responded = NO;
|
BOOL responded = NO;
|
||||||
NSMutableData *raw;
|
NSMutableData *raw;
|
||||||
|
@ -1094,6 +1140,8 @@ unescapeData(const unsigned char* bytes, unsigned length, unsigned char *buf)
|
||||||
NSEnumerator *enumerator;
|
NSEnumerator *enumerator;
|
||||||
GSMimeHeader *hdr;
|
GSMimeHeader *hdr;
|
||||||
|
|
||||||
|
AUTORELEASE(RETAIN(session));
|
||||||
|
request = [[session parser] mimeDocument];
|
||||||
response = AUTORELEASE([GSMimeDocument new]);
|
response = AUTORELEASE([GSMimeDocument new]);
|
||||||
[response setContent: [NSData data] type: @"text/plain" name: nil];
|
[response setContent: [NSData data] type: @"text/plain" name: nil];
|
||||||
[request setHeader: @"x-remote-address"
|
[request setHeader: @"x-remote-address"
|
||||||
|
@ -1103,12 +1151,18 @@ unescapeData(const unsigned char* bytes, unsigned length, unsigned char *buf)
|
||||||
if (_verbose == YES) NSLog(@"Request %@ - %@", session, request);
|
if (_verbose == YES) NSLog(@"Request %@ - %@", session, request);
|
||||||
NS_DURING
|
NS_DURING
|
||||||
{
|
{
|
||||||
|
[session setProcessing: YES];
|
||||||
|
[session setTicked: _ticked];
|
||||||
responded = [_delegate processRequest: request
|
responded = [_delegate processRequest: request
|
||||||
response: response
|
response: response
|
||||||
for: self];
|
for: self];
|
||||||
|
_ticked = [NSDate timeIntervalSinceReferenceDate];
|
||||||
|
[session setTicked: _ticked];
|
||||||
|
[session setProcessing: NO];
|
||||||
}
|
}
|
||||||
NS_HANDLER
|
NS_HANDLER
|
||||||
{
|
{
|
||||||
|
[session setProcessing: NO];
|
||||||
[self _alert: @"Exception %@, processing %@", localException, request];
|
[self _alert: @"Exception %@, processing %@", localException, request];
|
||||||
[response setHeader: @"http"
|
[response setHeader: @"http"
|
||||||
value: @"HTTP/1.0 500 Internal Server Error"
|
value: @"HTTP/1.0 500 Internal Server Error"
|
||||||
|
@ -1190,5 +1244,41 @@ unescapeData(const unsigned char* bytes, unsigned length, unsigned char *buf)
|
||||||
if (_verbose == YES) NSLog(@"Response %@ - %@", session, out);
|
if (_verbose == YES) NSLog(@"Response %@ - %@", session, out);
|
||||||
[[session handle] writeInBackgroundAndNotify: out];
|
[[session handle] writeInBackgroundAndNotify: out];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void) _ticker: (NSTimer*)timer
|
||||||
|
{
|
||||||
|
unsigned count;
|
||||||
|
|
||||||
|
_ticked = [NSDate timeIntervalSinceReferenceDate];
|
||||||
|
|
||||||
|
count = NSCountMapTable(_sessions);
|
||||||
|
if (count > 0)
|
||||||
|
{
|
||||||
|
NSMapEnumerator enumerator;
|
||||||
|
WebServerSession *session;
|
||||||
|
NSFileHandle *handle;
|
||||||
|
NSMutableArray *array;
|
||||||
|
|
||||||
|
array = [NSMutableArray arrayWithCapacity: count];
|
||||||
|
enumerator = NSEnumerateMapTable(_sessions);
|
||||||
|
while (NSNextMapEnumeratorPair(&enumerator,
|
||||||
|
(void **)(&handle), (void**)(&session)))
|
||||||
|
{
|
||||||
|
if (_ticked - [session ticked] > _sessionTimeout
|
||||||
|
&& [session processing] == NO)
|
||||||
|
{
|
||||||
|
[array addObject: session];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
NSEndMapTableEnumeration(&enumerator);
|
||||||
|
while ([array count] > 0)
|
||||||
|
{
|
||||||
|
session = [array objectAtIndex: 0];
|
||||||
|
[self _alert: @"Session timed out - %@", session];
|
||||||
|
[self _endSession: session];
|
||||||
|
[array removeObjectAtIndex: 0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue