mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-22 16:33:29 +00:00
Patches by Sergei Golovin
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@38188 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
bc50e26e2a
commit
8127f31ca3
6 changed files with 639 additions and 47 deletions
15
ChangeLog
15
ChangeLog
|
@ -1,3 +1,18 @@
|
|||
2014-11-20 Sergei Golovin <Golovin.SV@gmail.com>
|
||||
|
||||
* Source/GSSocketStream.m:
|
||||
* Tests/base/NSURL/Helpers/capture.m:
|
||||
* Tests/base/NSURL/testKey.pem:
|
||||
* Tests/base/NSURL/test02.m:
|
||||
* Tests/base/NSURL/testCert.pem:
|
||||
Implement TLS on server socket and make use of it in HTTPS URL helper
|
||||
code. Also, permit NSStream zero length write (it seems OSX allows
|
||||
it).
|
||||
|
||||
2014-11-20 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* Source/NSRunLoop.m: Avoinf some unnecessary retain/release cycles.
|
||||
|
||||
2014-11-05 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* Source/GSTLS.m: If a user default value is removed while running,
|
||||
|
|
|
@ -354,6 +354,17 @@ GSPrivateSockaddrSetup(NSString *machine, uint16_t port,
|
|||
@public
|
||||
GSTLSSession *session;
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates the dictionary 'dict', copying in all the properties
|
||||
* of the supplied streams. If a property is set for both then
|
||||
* the output stream's one has precedence.
|
||||
*/
|
||||
+ (void) populateProperties: (NSMutableDictionary**)dict
|
||||
withTLSPriority: (NSString*)pri
|
||||
fromInputStream: (NSStream*)i
|
||||
orOutputStream: (NSStream*)o;
|
||||
|
||||
@end
|
||||
|
||||
/* Callback to allow the TLS code to pull data from the remote system.
|
||||
|
@ -443,6 +454,37 @@ static NSArray *keys = nil;
|
|||
}
|
||||
}
|
||||
|
||||
+ (void) populateProperties: (NSMutableDictionary**)dict
|
||||
withTLSPriority: (NSString*)pri
|
||||
fromInputStream: (NSStream*)i
|
||||
orOutputStream: (NSStream*)o
|
||||
{
|
||||
NSString *str;
|
||||
NSMutableDictionary *opts = *dict;
|
||||
NSUInteger count;
|
||||
|
||||
if (NULL != dict)
|
||||
{
|
||||
if (nil != pri)
|
||||
{
|
||||
[opts setObject: pri forKey: GSTLSPriority];
|
||||
}
|
||||
count = [keys count];
|
||||
while (count-- > 0)
|
||||
{
|
||||
NSString *key = [keys objectAtIndex: count];
|
||||
|
||||
str = [o propertyForKey: key];
|
||||
if (nil == str) str = [i propertyForKey: key];
|
||||
if (nil != str) [opts setObject: str forKey: key];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NSWarnLog(@"%@ requires not nil 'dict'", NSStringFromSelector(_cmd));
|
||||
}
|
||||
}
|
||||
|
||||
+ (void) tryInput: (GSSocketInputStream*)i output: (GSSocketOutputStream*)o
|
||||
{
|
||||
NSString *tls;
|
||||
|
@ -537,10 +579,10 @@ static NSArray *keys = nil;
|
|||
{
|
||||
NSString *str;
|
||||
NSMutableDictionary *opts;
|
||||
NSUInteger count;
|
||||
BOOL server;
|
||||
|
||||
server = [[o propertyForKey: @"IsServer"] boolValue];
|
||||
// Check whether the input stream has been accepted by a listening socket
|
||||
server = [[i propertyForKey: @"IsServer"] boolValue];
|
||||
|
||||
str = [o propertyForKey: NSStreamSocketSecurityLevelKey];
|
||||
if (nil == str) str = [i propertyForKey: NSStreamSocketSecurityLevelKey];
|
||||
|
@ -580,16 +622,10 @@ static NSArray *keys = nil;
|
|||
* properties. GSTLSPriority overrides NSStreamSocketSecurityLevelKey.
|
||||
*/
|
||||
opts = [NSMutableDictionary new];
|
||||
if (nil != str) [opts setObject: str forKey: GSTLSPriority];
|
||||
count = [keys count];
|
||||
while (count-- > 0)
|
||||
{
|
||||
NSString *key = [keys objectAtIndex: count];
|
||||
|
||||
str = [o propertyForKey: key];
|
||||
if (nil == str) str = [i propertyForKey: key];
|
||||
if (nil != str) [opts setObject: str forKey: key];
|
||||
}
|
||||
[[self class] populateProperties: &opts
|
||||
withTLSPriority: str
|
||||
fromInputStream: i
|
||||
orOutputStream: o];
|
||||
|
||||
session = [[GSTLSSession alloc] initWithOptions: opts
|
||||
direction: (server ? NO : YES)
|
||||
|
@ -2244,16 +2280,32 @@ setNonBlocking(SOCKET fd)
|
|||
|
||||
- (NSInteger) write: (const uint8_t *)buffer maxLength: (NSUInteger)len
|
||||
{
|
||||
if (len == 0)
|
||||
{
|
||||
/*
|
||||
* The method allows the 'len' equal to 0. In this case the 'buffer'
|
||||
* is ignored. This can be useful if there is a necessity to postpone
|
||||
* actual writing (for no data are ready for example) without leaving
|
||||
* the stream in the state of unhandled NSStreamEventHasSpaceAvailable
|
||||
* (to keep receiving of that event from a runloop).
|
||||
* The delegate's -[stream:handleEvent:] would keep calling of
|
||||
* -[write: NULL maxLength: 0] until the delegate's state allows it
|
||||
* to write actual bytes.
|
||||
* The downside of that is that it produces a busy wait ... with the
|
||||
* run loop immediately notifying the stream that it has space to
|
||||
* write, so care should be taken to ensure that the delegate has a
|
||||
* near constant supply of data to write, or has some mechanism to
|
||||
* detect that no more data is arriving, and shut down.
|
||||
*/
|
||||
_events &= ~NSStreamEventHasSpaceAvailable;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (buffer == 0)
|
||||
{
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"null pointer for buffer"];
|
||||
}
|
||||
if (len == 0)
|
||||
{
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"zero byte length write requested"];
|
||||
}
|
||||
|
||||
if (_handler == nil)
|
||||
return [self _write: buffer maxLength: len];
|
||||
|
@ -2550,6 +2602,11 @@ setNonBlocking(SOCKET fd)
|
|||
- (void) acceptWithInputStream: (NSInputStream **)inputStream
|
||||
outputStream: (NSOutputStream **)outputStream
|
||||
{
|
||||
NSArray *keys;
|
||||
NSUInteger count;
|
||||
NSMutableDictionary *opts;
|
||||
NSString *str;
|
||||
|
||||
GSSocketStream *ins = AUTORELEASE([[self _inputStreamClass] new]);
|
||||
GSSocketStream *outs = AUTORELEASE([[self _outputStreamClass] new]);
|
||||
/* Align on a 2 byte boundary for a 16bit port number in the sockaddr
|
||||
|
@ -2589,6 +2646,31 @@ setNonBlocking(SOCKET fd)
|
|||
* connection (client).
|
||||
*/
|
||||
[ins setProperty: @"YES" forKey: @"IsServer"];
|
||||
|
||||
str = [self propertyForKey: NSStreamSocketSecurityLevelKey];
|
||||
if(nil != str)
|
||||
{
|
||||
opts = [NSMutableDictionary new];
|
||||
[opts setObject: str forKey: NSStreamSocketSecurityLevelKey];
|
||||
// copy the properties in the 'opts'
|
||||
[GSTLSHandler populateProperties: &opts
|
||||
withTLSPriority: str
|
||||
fromInputStream: self
|
||||
orOutputStream: nil];
|
||||
// and set the input/output streams's properties from the 'opts'
|
||||
keys = [opts allKeys];
|
||||
count = [keys count];
|
||||
while(count-- > 0)
|
||||
{
|
||||
NSString *key = [keys objectAtIndex: count];
|
||||
str = [opts objectForKey: key];
|
||||
[ins setProperty: str forKey: key];
|
||||
[outs setProperty: str forKey: key];
|
||||
}
|
||||
|
||||
[GSTLSHandler tryInput: (GSSocketInputStream *)ins output: (GSSocketOutputStream *)outs];
|
||||
DESTROY(opts);
|
||||
}
|
||||
}
|
||||
if (inputStream)
|
||||
{
|
||||
|
|
|
@ -9,7 +9,12 @@
|
|||
unsigned written;
|
||||
BOOL readable;
|
||||
BOOL writable;
|
||||
BOOL isSecure; /* whether to use a secure TLS/SSL connection */
|
||||
BOOL doRespond; /* the request is read */
|
||||
BOOL done; /* the response is written */
|
||||
NSString *file; /* the file to write the captured request */
|
||||
}
|
||||
- (id)initWithSecure:(BOOL)flag;
|
||||
- (int) runTest;
|
||||
@end
|
||||
|
||||
|
@ -20,14 +25,27 @@
|
|||
RELEASE(capture);
|
||||
RELEASE(op);
|
||||
RELEASE(ip);
|
||||
DESTROY(file);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (id)initWithSecure:(BOOL)flag
|
||||
{
|
||||
if((self = [super init]) != nil)
|
||||
{
|
||||
isSecure = flag;
|
||||
capture = [NSMutableData new];
|
||||
doRespond = NO;
|
||||
done = NO;
|
||||
file = nil;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id) init
|
||||
{
|
||||
capture = [NSMutableData new];
|
||||
|
||||
return self;
|
||||
return [self initWithSecure: NO];
|
||||
}
|
||||
|
||||
- (int) runTest
|
||||
|
@ -36,12 +54,14 @@
|
|||
NSRunLoop *rl = [NSRunLoop currentRunLoop];
|
||||
NSHost *host = [NSHost hostWithName: @"localhost"];
|
||||
NSStream *serverStream;
|
||||
NSString *file;
|
||||
int port = [[defs stringForKey: @"Port"] intValue];
|
||||
|
||||
isSecure = [[defs stringForKey: @"Secure"] boolValue];
|
||||
|
||||
if (port == 0) port = 54321;
|
||||
|
||||
file = [defs stringForKey: @"FileName"];
|
||||
RETAIN(file);
|
||||
if (file == nil) file = @"Capture.dat";
|
||||
|
||||
serverStream = [GSServerStream serverStreamToAddr: [host address] port: port];
|
||||
|
@ -50,16 +70,20 @@
|
|||
NSLog(@"Failed to create server stream");
|
||||
return 1;
|
||||
}
|
||||
if(isSecure)
|
||||
{
|
||||
[serverStream setProperty: NSStreamSocketSecurityLevelTLSv1 forKey: NSStreamSocketSecurityLevelKey];
|
||||
[serverStream setProperty: @"testCert.pem" forKey: GSTLSCertificateFile];
|
||||
[serverStream setProperty: @"testKey.pem" forKey: GSTLSCertificateKeyFile];
|
||||
}
|
||||
|
||||
[serverStream setDelegate: self];
|
||||
[serverStream scheduleInRunLoop: rl forMode: NSDefaultRunLoopMode];
|
||||
[serverStream open];
|
||||
|
||||
[rl runUntilDate: [NSDate dateWithTimeIntervalSinceNow: 30]];
|
||||
|
||||
if ([capture writeToFile: file atomically: YES] == NO)
|
||||
while(!done)
|
||||
{
|
||||
NSLog(@"Unable to write captured data to '%@'", file);
|
||||
return 1;
|
||||
[rl runUntilDate: [NSDate dateWithTimeIntervalSinceNow: 0.1]];
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -68,8 +92,7 @@
|
|||
- (void) stream: (NSStream *)theStream handleEvent: (NSStreamEvent)streamEvent
|
||||
{
|
||||
NSRunLoop *rl = [NSRunLoop currentRunLoop];
|
||||
NSString *resp = @"HTTP/1.0 204 Empty success response\r\n\r\n";
|
||||
|
||||
NSString *resp = @"HTTP/1.0 204 Empty success response\r\n\r\n";
|
||||
// NSLog(@"Event %p %d", theStream, streamEvent);
|
||||
|
||||
switch (streamEvent)
|
||||
|
@ -97,6 +120,13 @@
|
|||
}
|
||||
if (theStream == ip)
|
||||
{
|
||||
NSRange r1;
|
||||
NSRange r2;
|
||||
NSString *headers;
|
||||
NSString *tmp1;
|
||||
NSString *tmp2;
|
||||
NSUInteger contentLength;
|
||||
|
||||
readable = YES;
|
||||
while (readable == YES)
|
||||
{
|
||||
|
@ -113,39 +143,84 @@
|
|||
[capture appendBytes: buffer length: readSize];
|
||||
}
|
||||
}
|
||||
|
||||
// the following chunk ensures that the captured data are written only
|
||||
// when all request's bytes are read... it waits for full headers and
|
||||
// reads the Content-Length's value then waits for the number of bytes
|
||||
// equal to that value is read
|
||||
tmp1 = [[NSString alloc] initWithData: capture
|
||||
encoding: NSUTF8StringEncoding];
|
||||
// whether the headers are read
|
||||
if((r1 = [tmp1 rangeOfString: @"\r\n\r\n"]).location != NSNotFound)
|
||||
{
|
||||
headers = [tmp1 substringToIndex: r1.location + 2];
|
||||
if((r2 = [[headers lowercaseString] rangeOfString: @"content-length:"]).location != NSNotFound)
|
||||
{
|
||||
tmp2 = [headers substringFromIndex: r2.location + r2.length]; // content-length:<tmp2><end of headers>
|
||||
if((r2 = [tmp2 rangeOfString: @"\r\n"]).location != NSNotFound)
|
||||
{
|
||||
// full line with content-length is present
|
||||
tmp2 = [tmp2 substringToIndex: r2.location]; // number of content's bytes
|
||||
contentLength = [tmp2 intValue];
|
||||
if(r1.location + 4 + contentLength == [capture length]) // Did we get headers + body?
|
||||
{
|
||||
// full request is read so write it
|
||||
if ([capture writeToFile: file atomically: YES] == NO)
|
||||
{
|
||||
NSLog(@"Unable to write captured data to '%@'", file);
|
||||
}
|
||||
|
||||
doRespond = YES; // allows to write the response
|
||||
theStream = op;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
DESTROY(tmp1);
|
||||
}
|
||||
break;
|
||||
if(!doRespond) break;
|
||||
}
|
||||
case NSStreamEventHasSpaceAvailable:
|
||||
{
|
||||
NSData *data;
|
||||
|
||||
NSAssert(theStream == op, @"Wrong stream for writing");
|
||||
writable = YES;
|
||||
data = [resp dataUsingEncoding: NSASCIIStringEncoding];
|
||||
while (writable == YES && written < [data length])
|
||||
if(doRespond)
|
||||
{
|
||||
int result = [op write: [data bytes] + written
|
||||
maxLength: [data length] - written];
|
||||
// if we have read all request's bytes
|
||||
NSData *data;
|
||||
|
||||
if (result <= 0)
|
||||
NSAssert(theStream == op, @"Wrong stream for writing");
|
||||
writable = YES;
|
||||
|
||||
data = [resp dataUsingEncoding: NSASCIIStringEncoding];
|
||||
while (writable == YES && written < [data length])
|
||||
{
|
||||
writable = NO;
|
||||
int result = [op write: [data bytes] + written
|
||||
maxLength: [data length] - written];
|
||||
|
||||
if (result <= 0)
|
||||
{
|
||||
writable = NO;
|
||||
}
|
||||
else
|
||||
{
|
||||
written += result;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (written == [data length])
|
||||
{
|
||||
written += result;
|
||||
[ip close];
|
||||
[ip removeFromRunLoop: rl forMode: NSDefaultRunLoopMode];
|
||||
|
||||
[op close];
|
||||
[op removeFromRunLoop: rl forMode: NSDefaultRunLoopMode];
|
||||
|
||||
done = YES;
|
||||
}
|
||||
}
|
||||
if (written == [data length])
|
||||
{
|
||||
[op close];
|
||||
[op removeFromRunLoop: rl forMode: NSDefaultRunLoopMode];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case NSStreamEventEndEncountered:
|
||||
{
|
||||
{
|
||||
[theStream close];
|
||||
[theStream removeFromRunLoop: rl forMode: NSDefaultRunLoopMode];
|
||||
NSLog(@"Server close %p", theStream);
|
||||
|
|
320
Tests/base/NSURL/test02.m
Normal file
320
Tests/base/NSURL/test02.m
Normal file
|
@ -0,0 +1,320 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
#import "Testing.h"
|
||||
#import "ObjectTesting.h"
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
#if GNUSTEP
|
||||
NSAutoreleasePool *arp = [NSAutoreleasePool new];
|
||||
unsigned i;
|
||||
NSURL *url;
|
||||
NSMutableString *m;
|
||||
NSData *data;
|
||||
NSString *str;
|
||||
NSTask *t;
|
||||
NSString *helpers;
|
||||
NSString *capture;
|
||||
NSMutableURLRequest *request;
|
||||
NSHTTPURLResponse *response = nil;
|
||||
NSError *error = nil;
|
||||
NSFileManager *fm;
|
||||
NSRange r;
|
||||
NSString *file = @"Capture.dat";
|
||||
|
||||
fm = [NSFileManager defaultManager];
|
||||
helpers = [fm currentDirectoryPath];
|
||||
helpers = [helpers stringByAppendingPathComponent: @"Helpers"];
|
||||
helpers = [helpers stringByAppendingPathComponent: @"obj"];
|
||||
capture = [helpers stringByAppendingPathComponent: @"capture"];
|
||||
|
||||
m = [NSMutableString stringWithCapacity: 2048];
|
||||
for (i = 0; i < 128; i++)
|
||||
{
|
||||
[m appendFormat: @"Hello %d\r\n", i];
|
||||
}
|
||||
|
||||
t = [NSTask launchedTaskWithLaunchPath: capture
|
||||
arguments: [NSArray arrayWithObjects:
|
||||
nil]];
|
||||
if (t != nil)
|
||||
{
|
||||
// Pause to allow server subtask to set up.
|
||||
[NSThread sleepUntilDate: [NSDate dateWithTimeIntervalSinceNow: 0.5]];
|
||||
// remove the captured data from a possible previous run
|
||||
[fm removeItemAtPath: file error: NULL];
|
||||
// making a POST request
|
||||
url = [NSURL URLWithString: @"http://localhost:54321/"];
|
||||
request = [NSMutableURLRequest requestWithURL: url];
|
||||
data = [m dataUsingEncoding: NSUTF8StringEncoding];
|
||||
[request setHTTPBody: data];
|
||||
[request setHTTPMethod: @"POST"];
|
||||
|
||||
// sending the request
|
||||
[NSURLConnection sendSynchronousRequest: request
|
||||
returningResponse: &response
|
||||
error: &error];
|
||||
|
||||
// analyzing the response
|
||||
PASS(response != nil && [response statusCode] == 204,
|
||||
"NSURLConnection synchronous load returns a response");
|
||||
|
||||
data = [NSData dataWithContentsOfFile: @"Capture.dat"];
|
||||
str = [[NSString alloc] initWithData: data
|
||||
encoding: NSUTF8StringEncoding];
|
||||
r = [str rangeOfString: m];
|
||||
PASS(r.location != NSNotFound,
|
||||
"NSURLConnection capture test OK");
|
||||
|
||||
// Wait for server termination
|
||||
[t terminate];
|
||||
[t waitUntilExit];
|
||||
DESTROY(str);
|
||||
response = nil;
|
||||
error = nil;
|
||||
}
|
||||
|
||||
// the same but with secure connection (HTTPS)
|
||||
t = [NSTask launchedTaskWithLaunchPath: capture
|
||||
arguments: [NSArray arrayWithObjects:
|
||||
@"-Secure", @"YES",
|
||||
nil]];
|
||||
if (t != nil)
|
||||
{
|
||||
// Pause to allow server subtask to set up.
|
||||
[NSThread sleepUntilDate: [NSDate dateWithTimeIntervalSinceNow: 0.5]];
|
||||
// remove the captured data from a possible previous run
|
||||
[fm removeItemAtPath: file error: NULL];
|
||||
// making a POST request
|
||||
url = [NSURL URLWithString: @"https://localhost:54321/"];
|
||||
request = [NSMutableURLRequest requestWithURL: url];
|
||||
data = [m dataUsingEncoding: NSUTF8StringEncoding];
|
||||
[request setHTTPBody: data];
|
||||
[request setHTTPMethod: @"POST"];
|
||||
|
||||
// sending the request
|
||||
[NSURLConnection sendSynchronousRequest: request
|
||||
returningResponse: &response
|
||||
error: &error];
|
||||
|
||||
// sending the request
|
||||
PASS(response != nil && [response statusCode] == 204,
|
||||
"NSURLConnection synchronous load returns a response");
|
||||
|
||||
data = [NSData dataWithContentsOfFile: @"Capture.dat"];
|
||||
str = [[NSString alloc] initWithData: data
|
||||
encoding: NSUTF8StringEncoding];
|
||||
r = [str rangeOfString: m];
|
||||
PASS(r.location != NSNotFound,
|
||||
"NSURLConnection capture test OK");
|
||||
|
||||
// Wait for server termination
|
||||
[t terminate];
|
||||
[t waitUntilExit];
|
||||
DESTROY(str);
|
||||
}
|
||||
|
||||
[arp release]; arp = nil;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "Testing.h"
|
||||
#import "ObjectTesting.h"
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
#if GNUSTEP
|
||||
NSAutoreleasePool *arp = [NSAutoreleasePool new];
|
||||
unsigned i;
|
||||
NSURL *url;
|
||||
NSMutableString *m;
|
||||
NSData *data;
|
||||
NSString *str;
|
||||
NSTask *t;
|
||||
NSString *helpers;
|
||||
NSString *capture;
|
||||
NSMutableURLRequest *request;
|
||||
NSHTTPURLResponse *response = nil;
|
||||
NSError *error = nil;
|
||||
NSFileManager *fm;
|
||||
NSRange r;
|
||||
NSString *file = @"Capture.dat";
|
||||
|
||||
fm = [NSFileManager defaultManager];
|
||||
helpers = [fm currentDirectoryPath];
|
||||
helpers = [helpers stringByAppendingPathComponent: @"Helpers"];
|
||||
helpers = [helpers stringByAppendingPathComponent: @"obj"];
|
||||
capture = [helpers stringByAppendingPathComponent: @"capture"];
|
||||
|
||||
m = [NSMutableString stringWithCapacity: 2048];
|
||||
for (i = 0; i < 128; i++)
|
||||
{
|
||||
[m appendFormat: @"Hello %d\r\n", i];
|
||||
}
|
||||
|
||||
t = [NSTask launchedTaskWithLaunchPath: capture
|
||||
arguments: [NSArray arrayWithObjects:
|
||||
nil]];
|
||||
if (t != nil)
|
||||
{
|
||||
// Pause to allow server subtask to set up.
|
||||
[NSThread sleepUntilDate: [NSDate dateWithTimeIntervalSinceNow: 0.5]];
|
||||
// remove the captured data from a possible previous run
|
||||
[fm removeItemAtPath: file error: NULL];
|
||||
// making a POST request
|
||||
url = [NSURL URLWithString: @"http://localhost:54321/"];
|
||||
request = [NSMutableURLRequest requestWithURL: url];
|
||||
data = [m dataUsingEncoding: NSUTF8StringEncoding];
|
||||
[request setHTTPBody: data];
|
||||
[request setHTTPMethod: @"POST"];
|
||||
|
||||
// sending the request
|
||||
[NSURLConnection sendSynchronousRequest: request
|
||||
returningResponse: &response
|
||||
error: &error];
|
||||
|
||||
// analyzing the response
|
||||
PASS(response != nil && [response statusCode] == 204,
|
||||
"NSURLConnection synchronous load returns a response");
|
||||
|
||||
data = [NSData dataWithContentsOfFile: @"Capture.dat"];
|
||||
str = [[NSString alloc] initWithData: data
|
||||
encoding: NSUTF8StringEncoding];
|
||||
r = [str rangeOfString: m];
|
||||
PASS(r.location != NSNotFound,
|
||||
"NSURLConnection capture test OK");
|
||||
|
||||
// Wait for server termination
|
||||
[t terminate];
|
||||
[t waitUntilExit];
|
||||
DESTROY(str);
|
||||
response = nil;
|
||||
error = nil;
|
||||
}
|
||||
|
||||
// the same but with secure connection (HTTPS)
|
||||
t = [NSTask launchedTaskWithLaunchPath: capture
|
||||
arguments: [NSArray arrayWithObjects:
|
||||
@"-Secure", @"YES",
|
||||
nil]];
|
||||
if (t != nil)
|
||||
{
|
||||
// Pause to allow server subtask to set up.
|
||||
[NSThread sleepUntilDate: [NSDate dateWithTimeIntervalSinceNow: 0.5]];
|
||||
// remove the captured data from a possible previous run
|
||||
[fm removeItemAtPath: file error: NULL];
|
||||
// making a POST request
|
||||
url = [NSURL URLWithString: @"https://localhost:54321/"];
|
||||
request = [NSMutableURLRequest requestWithURL: url];
|
||||
data = [m dataUsingEncoding: NSUTF8StringEncoding];
|
||||
[request setHTTPBody: data];
|
||||
[request setHTTPMethod: @"POST"];
|
||||
|
||||
// sending the request
|
||||
[NSURLConnection sendSynchronousRequest: request
|
||||
returningResponse: &response
|
||||
error: &error];
|
||||
|
||||
// sending the request
|
||||
PASS(response != nil && [response statusCode] == 204,
|
||||
"NSURLConnection synchronous load returns a response");
|
||||
|
||||
data = [NSData dataWithContentsOfFile: @"Capture.dat"];
|
||||
str = [[NSString alloc] initWithData: data
|
||||
encoding: NSUTF8StringEncoding];
|
||||
r = [str rangeOfString: m];
|
||||
PASS(r.location != NSNotFound,
|
||||
"NSURLConnection capture test OK");
|
||||
|
||||
// Wait for server termination
|
||||
[t terminate];
|
||||
[t waitUntilExit];
|
||||
DESTROY(str);
|
||||
}
|
||||
|
||||
[arp release]; arp = nil;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "Testing.h"
|
||||
#import "ObjectTesting.h"
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
#if GNUSTEP
|
||||
NSAutoreleasePool *arp = [NSAutoreleasePool new];
|
||||
unsigned i;
|
||||
NSURL *url;
|
||||
NSMutableString *body;
|
||||
NSData *data;
|
||||
NSString *str;
|
||||
NSTask *t;
|
||||
NSString *helpers;
|
||||
NSString *capture;
|
||||
NSMutableURLRequest *request;
|
||||
NSHTTPURLResponse *response = nil;
|
||||
NSError *error = nil;
|
||||
NSFileManager *fm;
|
||||
NSRange r;
|
||||
NSString *file = @"Capture.dat";
|
||||
|
||||
fm = [NSFileManager defaultManager];
|
||||
helpers = [fm currentDirectoryPath];
|
||||
helpers = [helpers stringByAppendingPathComponent: @"Helpers"];
|
||||
helpers = [helpers stringByAppendingPathComponent: @"obj"];
|
||||
capture = [helpers stringByAppendingPathComponent: @"capture"];
|
||||
|
||||
body = [NSMutableString stringWithCapacity: 2048];
|
||||
for (i = 0; i < 128; i++)
|
||||
{
|
||||
[body appendFormat: @"Hello %d\r\n", i];
|
||||
}
|
||||
|
||||
t = [NSTask launchedTaskWithLaunchPath: capture
|
||||
arguments: [NSArray arrayWithObjects:
|
||||
nil]];
|
||||
if (t != nil)
|
||||
{
|
||||
// Pause to allow server subtask to set up.
|
||||
[NSThread sleepUntilDate: [NSDate dateWithTimeIntervalSinceNow: 0.5]];
|
||||
// remove the captured data from a possible previous run
|
||||
[fm removeItemAtPath: file error: NULL];
|
||||
// making a POST request
|
||||
url = [NSURL URLWithString: @"http://localhost:54321/"];
|
||||
request = [NSMutableURLRequest requestWithURL: url];
|
||||
data = [body dataUsingEncoding: NSUTF8StringEncoding];
|
||||
[request setHTTPBody: data];
|
||||
[request setHTTPMethod: @"POST"];
|
||||
|
||||
// sending the request
|
||||
[NSURLConnection sendSynchronousRequest: request
|
||||
returningResponse: &response
|
||||
error: &error];
|
||||
|
||||
// analyzing the response
|
||||
PASS(response != nil && [response statusCode] == 204,
|
||||
"NSURLConnection synchronous load returns a response");
|
||||
|
||||
data = [NSData dataWithContentsOfFile: @"Capture.dat"];
|
||||
str = [[NSString alloc] initWithData: data
|
||||
encoding: NSUTF8StringEncoding];
|
||||
r = [str rangeOfString: body];
|
||||
PASS(r.location != NSNotFound,
|
||||
"NSURLConnection capture test OK");
|
||||
|
||||
// Wait for server termination
|
||||
[t terminate];
|
||||
[t waitUntilExit];
|
||||
DESTROY(str);
|
||||
response = nil;
|
||||
error = nil;
|
||||
}
|
||||
|
||||
[arp release]; arp = nil;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
46
Tests/base/NSURL/testCert.pem
Normal file
46
Tests/base/NSURL/testCert.pem
Normal file
|
@ -0,0 +1,46 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIID6TCCAtGgAwIBAgIJAP02s2/x3i8ZMA0GCSqGSIb3DQEBCwUAMIGKMQswCQYD
|
||||
VQQGEwJYWDEOMAwGA1UECAwFV29ybGQxEDAOBgNVBAcMB0dOVXN0ZXAxITAfBgNV
|
||||
BAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDESMBAGA1UEAwwJbG9jYWxob3N0
|
||||
MSIwIAYJKoZIhvcNAQkBFhNnbnVzdGVwLWRldkBnbnUub3JnMB4XDTE0MDgwNzEx
|
||||
MTIxN1oXDTI0MDgwNDExMTIxN1owgYoxCzAJBgNVBAYTAlhYMQ4wDAYDVQQIDAVX
|
||||
b3JsZDEQMA4GA1UEBwwHR05Vc3RlcDEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0
|
||||
cyBQdHkgTHRkMRIwEAYDVQQDDAlsb2NhbGhvc3QxIjAgBgkqhkiG9w0BCQEWE2du
|
||||
dXN0ZXAtZGV2QGdudS5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
|
||||
AQDxFVEHh137hyl0juYvbXuAOUIXRSVwk92mAGJIIn0g0Dm6KIAJW1EGR5LeHY3L
|
||||
vrkxEAvGxb7Ypqtg1F4OcwoZE/1Y0xKjHBnqtMJcw7DgN9F1dIkQ9HxHkYPiHzTF
|
||||
d7floomsjyt0BcqAqE1Qf0ahsnveq9E6KTIYRTZ91RGHQrAW4KBxFM30ieHYQYdn
|
||||
2vDgH/8wyLjwQ+89P5SrBJdt+eKHPjHvjs1WZe0i660hvLa19l/DQ5ZxlV5LJ6tZ
|
||||
yjvr+OjT9tE86r9n34vk+ZZBCQwvzZ+dHwLpufz3VgPap54bCCLY21BZj15nqITN
|
||||
k+8XJz+aavFe3zdMvT9cGiZNAgMBAAGjUDBOMB0GA1UdDgQWBBRB6fstnCsIvg3r
|
||||
9f3EmiZhLS867TAfBgNVHSMEGDAWgBRB6fstnCsIvg3r9f3EmiZhLS867TAMBgNV
|
||||
HRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQC0fy/lWgBZRTXfAUOfZp5sWJcQ
|
||||
mQKQiPfXYxiUALq6iI1SyQq90kJ1DyLEGJJ9HEaP3s3jyFQgLXoi1J/8qyOESUDy
|
||||
ogC8nIod6vfA9g8eWcFeOEd6YnNWykPjGCqA/mzrzN3abFkERap8ivx4RWVYX9bP
|
||||
ZNhJVxcoqVCjtFmIh6ATNG/0+xfxax4U4GitcHNYD0Ij+qdXqNJHym67uVponLYE
|
||||
SnxxF3lZ6FzB51SyKtJF5j4/fEeyDXR8Uy3zJdrb6mhSUJNX5RYcrdiR9RflrfGy
|
||||
qYOXFtWmFv/+w/OaqugXQfx9By8uI49U9BG8Q7xSsZSXmoEuMGYt+UwE7UP+
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIID6TCCAtGgAwIBAgIJAP02s2/x3i8ZMA0GCSqGSIb3DQEBCwUAMIGKMQswCQYD
|
||||
VQQGEwJYWDEOMAwGA1UECAwFV29ybGQxEDAOBgNVBAcMB0dOVXN0ZXAxITAfBgNV
|
||||
BAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDESMBAGA1UEAwwJbG9jYWxob3N0
|
||||
MSIwIAYJKoZIhvcNAQkBFhNnbnVzdGVwLWRldkBnbnUub3JnMB4XDTE0MDgwNzEx
|
||||
MTIxN1oXDTI0MDgwNDExMTIxN1owgYoxCzAJBgNVBAYTAlhYMQ4wDAYDVQQIDAVX
|
||||
b3JsZDEQMA4GA1UEBwwHR05Vc3RlcDEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0
|
||||
cyBQdHkgTHRkMRIwEAYDVQQDDAlsb2NhbGhvc3QxIjAgBgkqhkiG9w0BCQEWE2du
|
||||
dXN0ZXAtZGV2QGdudS5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
|
||||
AQDxFVEHh137hyl0juYvbXuAOUIXRSVwk92mAGJIIn0g0Dm6KIAJW1EGR5LeHY3L
|
||||
vrkxEAvGxb7Ypqtg1F4OcwoZE/1Y0xKjHBnqtMJcw7DgN9F1dIkQ9HxHkYPiHzTF
|
||||
d7floomsjyt0BcqAqE1Qf0ahsnveq9E6KTIYRTZ91RGHQrAW4KBxFM30ieHYQYdn
|
||||
2vDgH/8wyLjwQ+89P5SrBJdt+eKHPjHvjs1WZe0i660hvLa19l/DQ5ZxlV5LJ6tZ
|
||||
yjvr+OjT9tE86r9n34vk+ZZBCQwvzZ+dHwLpufz3VgPap54bCCLY21BZj15nqITN
|
||||
k+8XJz+aavFe3zdMvT9cGiZNAgMBAAGjUDBOMB0GA1UdDgQWBBRB6fstnCsIvg3r
|
||||
9f3EmiZhLS867TAfBgNVHSMEGDAWgBRB6fstnCsIvg3r9f3EmiZhLS867TAMBgNV
|
||||
HRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQC0fy/lWgBZRTXfAUOfZp5sWJcQ
|
||||
mQKQiPfXYxiUALq6iI1SyQq90kJ1DyLEGJJ9HEaP3s3jyFQgLXoi1J/8qyOESUDy
|
||||
ogC8nIod6vfA9g8eWcFeOEd6YnNWykPjGCqA/mzrzN3abFkERap8ivx4RWVYX9bP
|
||||
ZNhJVxcoqVCjtFmIh6ATNG/0+xfxax4U4GitcHNYD0Ij+qdXqNJHym67uVponLYE
|
||||
SnxxF3lZ6FzB51SyKtJF5j4/fEeyDXR8Uy3zJdrb6mhSUJNX5RYcrdiR9RflrfGy
|
||||
qYOXFtWmFv/+w/OaqugXQfx9By8uI49U9BG8Q7xSsZSXmoEuMGYt+UwE7UP+
|
||||
-----END CERTIFICATE-----
|
54
Tests/base/NSURL/testKey.pem
Normal file
54
Tests/base/NSURL/testKey.pem
Normal file
|
@ -0,0 +1,54 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEA8RVRB4dd+4cpdI7mL217gDlCF0UlcJPdpgBiSCJ9INA5uiiA
|
||||
CVtRBkeS3h2Ny765MRALxsW+2KarYNReDnMKGRP9WNMSoxwZ6rTCXMOw4DfRdXSJ
|
||||
EPR8R5GD4h80xXe35aKJrI8rdAXKgKhNUH9GobJ73qvROikyGEU2fdURh0KwFuCg
|
||||
cRTN9Inh2EGHZ9rw4B//MMi48EPvPT+UqwSXbfnihz4x747NVmXtIuutIby2tfZf
|
||||
w0OWcZVeSyerWco76/jo0/bRPOq/Z9+L5PmWQQkML82fnR8C6bn891YD2qeeGwgi
|
||||
2NtQWY9eZ6iEzZPvFyc/mmrxXt83TL0/XBomTQIDAQABAoIBAAZmlnwor+oZsJQT
|
||||
pzDjK0BAROzxPQk8I8pggDuCDuhsHtw+bwfQkNol1FRpXHZoXepbjrR8U5DU+//a
|
||||
I5UmoMIBsdxF3lzORjHhErf7yhpp4PnJWkpE83fC+Ulroq8LeqpyIk2ej3zJGpNH
|
||||
5KWae3mXj4pd7XQp29ahH80/dvOsWGZyYOXqh7jO6UdXfhPHKIhLN6wd9nzmRy44
|
||||
PLFcQYo/nTM19ackz9joovyGPy87BGsj3+rALRXd+GMPVtRFFPMtm6PnSTsMsoDg
|
||||
HEsm76CygnmL7/ywIXSVY/rfomm73SV9FgFalkUSpNWdLqiXiLICVTKC2P1ZUCdg
|
||||
eL/A59ECgYEA/nfw/9Vh86LVQ6Vqfp9W/pAut9ik8SecqodOptBSVV2YBYcfBejL
|
||||
dqksW3LaARabGMJh1z5tHfIw+buF7tl8OIy+TNYRNdrUlsNpI7lWVCVp5F4Znr3c
|
||||
a7GsGE82/XA3eiEZhUfaQeCctOMXoPnZO32mdDal3rYYQ7yKMvAO8gsCgYEA8ojA
|
||||
pK80FURe+kM0Zd/ftTAzMkGJNWnKkSSqd+sI7iCwzd9KAX3d+EM4/vqguMXzw+MP
|
||||
FMkXOv4PUP0iV1XyBt1hn+OSdfax4mD9ALOyJoCHvLPsRjlIv7iEsD2oi84mJ07v
|
||||
3fFuku+xDrPwMBJgeIWjC2ml9J3YYrB5ppPRmAcCgYEA+64/Y5l1ttW/XpeVm8UW
|
||||
8tJCEr2obYfDMPqAtQZn2FyohhcdfOfBjQxHfe87ZUYpgjSHNq9clvi6rdVl41Wh
|
||||
wgCaGz7CaOSVzMNbEuU1WCZk9GSJrHKWNsHUt3pppgK+LAHezu7BFNUFyPauoR1c
|
||||
WLWu01RVe8/Yce5hNX4vGf8CgYEA5w7pmPthfzFX2szTyopyMcftvl85PK3A0m5A
|
||||
CWbdZx+10Sx88Nbc9Xv1fNWA8QeFqIVVBNRfUVBhfyLp6JJ0tZ2LOCwyiDeyWJ1V
|
||||
66lGe+/PYTN4UZ6ZdC1yHAVh4W9QYfqOAr/UPCAman96wBGB3tBR+Ll55YXLdJn0
|
||||
C4KgF1kCgYAHjE0j82DF+6sKw+ggUcMgLM0z6HcYE975T/c4KNqb11Mu2+38CQvY
|
||||
pvlzOgQxzbjq59reek3gRtj3u0UCaXzTnIvgLl+sC0/l4f4qEVwcEcnMiJyUAIsR
|
||||
VR7Mw874clbF8TK8tLlcgCipmDmWxFlrgxOPs1ikcObvTOR/oxacUQ==
|
||||
-----END RSA PRIVATE KEY-----
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEA8RVRB4dd+4cpdI7mL217gDlCF0UlcJPdpgBiSCJ9INA5uiiA
|
||||
CVtRBkeS3h2Ny765MRALxsW+2KarYNReDnMKGRP9WNMSoxwZ6rTCXMOw4DfRdXSJ
|
||||
EPR8R5GD4h80xXe35aKJrI8rdAXKgKhNUH9GobJ73qvROikyGEU2fdURh0KwFuCg
|
||||
cRTN9Inh2EGHZ9rw4B//MMi48EPvPT+UqwSXbfnihz4x747NVmXtIuutIby2tfZf
|
||||
w0OWcZVeSyerWco76/jo0/bRPOq/Z9+L5PmWQQkML82fnR8C6bn891YD2qeeGwgi
|
||||
2NtQWY9eZ6iEzZPvFyc/mmrxXt83TL0/XBomTQIDAQABAoIBAAZmlnwor+oZsJQT
|
||||
pzDjK0BAROzxPQk8I8pggDuCDuhsHtw+bwfQkNol1FRpXHZoXepbjrR8U5DU+//a
|
||||
I5UmoMIBsdxF3lzORjHhErf7yhpp4PnJWkpE83fC+Ulroq8LeqpyIk2ej3zJGpNH
|
||||
5KWae3mXj4pd7XQp29ahH80/dvOsWGZyYOXqh7jO6UdXfhPHKIhLN6wd9nzmRy44
|
||||
PLFcQYo/nTM19ackz9joovyGPy87BGsj3+rALRXd+GMPVtRFFPMtm6PnSTsMsoDg
|
||||
HEsm76CygnmL7/ywIXSVY/rfomm73SV9FgFalkUSpNWdLqiXiLICVTKC2P1ZUCdg
|
||||
eL/A59ECgYEA/nfw/9Vh86LVQ6Vqfp9W/pAut9ik8SecqodOptBSVV2YBYcfBejL
|
||||
dqksW3LaARabGMJh1z5tHfIw+buF7tl8OIy+TNYRNdrUlsNpI7lWVCVp5F4Znr3c
|
||||
a7GsGE82/XA3eiEZhUfaQeCctOMXoPnZO32mdDal3rYYQ7yKMvAO8gsCgYEA8ojA
|
||||
pK80FURe+kM0Zd/ftTAzMkGJNWnKkSSqd+sI7iCwzd9KAX3d+EM4/vqguMXzw+MP
|
||||
FMkXOv4PUP0iV1XyBt1hn+OSdfax4mD9ALOyJoCHvLPsRjlIv7iEsD2oi84mJ07v
|
||||
3fFuku+xDrPwMBJgeIWjC2ml9J3YYrB5ppPRmAcCgYEA+64/Y5l1ttW/XpeVm8UW
|
||||
8tJCEr2obYfDMPqAtQZn2FyohhcdfOfBjQxHfe87ZUYpgjSHNq9clvi6rdVl41Wh
|
||||
wgCaGz7CaOSVzMNbEuU1WCZk9GSJrHKWNsHUt3pppgK+LAHezu7BFNUFyPauoR1c
|
||||
WLWu01RVe8/Yce5hNX4vGf8CgYEA5w7pmPthfzFX2szTyopyMcftvl85PK3A0m5A
|
||||
CWbdZx+10Sx88Nbc9Xv1fNWA8QeFqIVVBNRfUVBhfyLp6JJ0tZ2LOCwyiDeyWJ1V
|
||||
66lGe+/PYTN4UZ6ZdC1yHAVh4W9QYfqOAr/UPCAman96wBGB3tBR+Ll55YXLdJn0
|
||||
C4KgF1kCgYAHjE0j82DF+6sKw+ggUcMgLM0z6HcYE975T/c4KNqb11Mu2+38CQvY
|
||||
pvlzOgQxzbjq59reek3gRtj3u0UCaXzTnIvgLl+sC0/l4f4qEVwcEcnMiJyUAIsR
|
||||
VR7Mw874clbF8TK8tLlcgCipmDmWxFlrgxOPs1ikcObvTOR/oxacUQ==
|
||||
-----END RSA PRIVATE KEY-----
|
Loading…
Reference in a new issue