mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-03 05:11:17 +00:00
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@32187 72102866-910b-0410-8b05-ffd578937521
247 lines
6.4 KiB
Objective-C
247 lines
6.4 KiB
Objective-C
#if GNUSTEP
|
|
#include <Foundation/Foundation.h>
|
|
|
|
@interface TestClass : NSObject
|
|
{
|
|
NSData *bodyData;
|
|
unsigned accum;
|
|
unsigned count;
|
|
unsigned closeFrequency;
|
|
NSArray *headers;
|
|
NSInputStream *inStream;
|
|
NSOutputStream *outStream;
|
|
}
|
|
- (int) runTest;
|
|
@end
|
|
|
|
@implementation TestClass
|
|
|
|
- (void)dealloc
|
|
{
|
|
[headers release];
|
|
[bodyData release];
|
|
[inStream release];
|
|
[outStream release];
|
|
[super dealloc];
|
|
}
|
|
|
|
- (id) init
|
|
{
|
|
return self;
|
|
}
|
|
|
|
- (int)runTest
|
|
{
|
|
NSUserDefaults *defs = [NSUserDefaults standardUserDefaults];
|
|
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
|
|
NSString *file,
|
|
*lengthHeader;
|
|
NSHost *host = [NSHost hostWithAddress: @"127.0.0.1"];
|
|
NSStream *serverStream;
|
|
int port = [[defs stringForKey: @"Port"] intValue];
|
|
int lifetime = [[defs stringForKey: @"Lifetime"] intValue];
|
|
|
|
if (0 == port) port = 4322;
|
|
if (0 == lifetime) lifetime = 30;
|
|
|
|
accum = 0;
|
|
|
|
closeFrequency = [[defs stringForKey: @"CloseFreq"] intValue];
|
|
count = [[defs stringForKey: @"Count"] intValue];
|
|
if (0 >= count) count=1;
|
|
|
|
file = [defs stringForKey: @"FileName"];
|
|
if (nil == file) file = @"ResponseBody.dat";
|
|
bodyData = [[NSData alloc] initWithContentsOfFile: file];
|
|
if (nil == bodyData)
|
|
{
|
|
NSLog(@"Unable to load data from '%@'",file);
|
|
return 1;
|
|
}
|
|
|
|
lengthHeader = [NSString stringWithFormat: @"Content-Length: %d\r\n",
|
|
[bodyData length]];
|
|
headers = [[NSArray alloc] initWithObjects: @"HTTP/1.1 200 OK\r\n",
|
|
@"Content-type: text/plain\r\n",
|
|
lengthHeader,
|
|
nil];
|
|
serverStream = [GSServerStream serverStreamToAddr: [host address] port: port];
|
|
if (nil == serverStream)
|
|
{
|
|
NSLog(@"Could not create server stream");
|
|
return 1;
|
|
}
|
|
[serverStream setDelegate: self];
|
|
[serverStream scheduleInRunLoop: runLoop forMode: NSDefaultRunLoopMode];
|
|
[serverStream open];
|
|
|
|
// only run for a fixed time anyway
|
|
[runLoop runUntilDate: [NSDate dateWithTimeIntervalSinceNow: lifetime]];
|
|
|
|
return 0;
|
|
}
|
|
|
|
// delegate method for NSStream
|
|
- (void) stream: (NSStream *)theStream handleEvent: (NSStreamEvent)streamEvent
|
|
{
|
|
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
|
|
|
|
switch (streamEvent)
|
|
{
|
|
case NSStreamEventHasBytesAvailable:
|
|
{
|
|
if (theStream != inStream)
|
|
{
|
|
if (inStream != nil)
|
|
{
|
|
[inStream close];
|
|
[inStream removeFromRunLoop: runLoop
|
|
forMode: NSDefaultRunLoopMode];
|
|
inStream = nil;
|
|
}
|
|
if (outStream != nil)
|
|
{
|
|
[outStream close];
|
|
[outStream removeFromRunLoop: runLoop
|
|
forMode: NSDefaultRunLoopMode];
|
|
outStream = nil;
|
|
}
|
|
if (accum == count)
|
|
{
|
|
[theStream close];
|
|
[theStream removeFromRunLoop: runLoop
|
|
forMode: NSDefaultRunLoopMode];
|
|
break;
|
|
}
|
|
[(GSServerStream*)theStream acceptWithInputStream: &inStream
|
|
outputStream: &outStream];
|
|
if (inStream)
|
|
{
|
|
RETAIN(inStream);
|
|
RETAIN(outStream);
|
|
[inStream scheduleInRunLoop: runLoop
|
|
forMode: NSDefaultRunLoopMode];
|
|
[inStream setDelegate: self];
|
|
[inStream open];
|
|
}
|
|
else
|
|
{
|
|
NSLog(@"Accept returned nothing");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
unsigned char buffer[BUFSIZ];
|
|
int readSize;
|
|
readSize = [inStream read: buffer maxLength: BUFSIZ];
|
|
// make outStream available for writing
|
|
[outStream scheduleInRunLoop: runLoop
|
|
forMode: NSDefaultRunLoopMode];
|
|
[outStream setDelegate: self];
|
|
[outStream open];
|
|
}
|
|
break;
|
|
}
|
|
|
|
case NSStreamEventHasSpaceAvailable:
|
|
{
|
|
NSAssert(theStream == outStream, @"Wrong stream for writing");
|
|
NSMutableData *payload = [[[NSMutableData alloc] init] autorelease];
|
|
NSMutableArray *headerArray = [[headers mutableCopy] autorelease];
|
|
NSEnumerator *headerEnumeration;
|
|
id header;
|
|
BOOL closeConnection = NO;
|
|
int written;
|
|
|
|
accum++;
|
|
if ((0 != closeFrequency) && (0 == accum % closeFrequency))
|
|
{
|
|
closeConnection = YES;
|
|
[headerArray addObject: @"Connection: close\r\n"];
|
|
}
|
|
|
|
headerEnumeration = [headerArray objectEnumerator];
|
|
|
|
while ((header = [headerEnumeration nextObject]))
|
|
[payload appendData: [header dataUsingEncoding: NSASCIIStringEncoding]];
|
|
[payload appendData: [@"\n" dataUsingEncoding: NSASCIIStringEncoding]];
|
|
[payload appendData: bodyData];
|
|
|
|
// provide the reply
|
|
written = [outStream write: [payload bytes] maxLength: [payload length]];
|
|
if (written <=0)
|
|
{
|
|
// something seriously wrong....
|
|
closeConnection = YES;
|
|
NSLog(@"Unable to write the payload!");
|
|
}
|
|
|
|
// remove from runloop, so we have to wait for another request
|
|
[outStream removeFromRunLoop: runLoop
|
|
forMode: NSDefaultRunLoopMode];
|
|
|
|
if (closeConnection)
|
|
{
|
|
[outStream close];
|
|
outStream = nil;
|
|
|
|
if (nil != inStream)
|
|
{
|
|
[inStream close];
|
|
[inStream removeFromRunLoop: runLoop
|
|
forMode: NSDefaultRunLoopMode];
|
|
inStream = nil;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
case NSStreamEventEndEncountered:
|
|
{
|
|
NSAssert(inStream == theStream || outStream == theStream,
|
|
NSInternalInconsistencyException);
|
|
[theStream close];
|
|
[theStream removeFromRunLoop: runLoop forMode: NSDefaultRunLoopMode];
|
|
if (theStream == inStream) inStream = nil;
|
|
if (theStream == outStream) outStream = nil;
|
|
break;
|
|
}
|
|
|
|
case NSStreamEventErrorOccurred:
|
|
{
|
|
int code = [[theStream streamError] code];
|
|
NSLog(@"Received error %d on stream %p", code, theStream);
|
|
[theStream close];
|
|
[theStream removeFromRunLoop: runLoop forMode: NSDefaultRunLoopMode];
|
|
if (theStream == inStream) inStream = nil;
|
|
if (theStream == outStream) outStream = nil;
|
|
break;
|
|
}
|
|
|
|
case NSStreamEventOpenCompleted:
|
|
break;
|
|
default:
|
|
NSLog(@"Unknown event %d on stream %p", streamEvent, theStream);
|
|
break;
|
|
}
|
|
}
|
|
|
|
@end
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
int result;
|
|
NSAutoreleasePool *arp = [[NSAutoreleasePool alloc] init];
|
|
|
|
result = [[[[TestClass alloc] init] autorelease] runTest];
|
|
|
|
[arp release];
|
|
return result;
|
|
}
|
|
#else
|
|
int main()
|
|
{
|
|
return 0;
|
|
}
|
|
#endif
|
|
|