Index: Source/GSSocketStream.m
===================================================================
--- Source/GSSocketStream.m	(revision 38140)
+++ Source/GSSocketStream.m	(working copy)
@@ -354,6 +354,17 @@
 @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 @@
     }
 }
 
++ (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'", _cmd);
+    }
+}
+
 + (void) tryInput: (GSSocketInputStream*)i output: (GSSocketOutputStream*)o
 {
   NSString      *tls;
@@ -537,10 +579,11 @@
 {
   NSString              *str;
   NSMutableDictionary   *opts;
-  NSUInteger            count;
+  //  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 +623,10 @@
    * 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)
@@ -2550,6 +2587,11 @@
 - (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 +2631,31 @@
        * 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)
     {
Index: Tests/base/NSURL/Helpers/capture.m
===================================================================
--- Tests/base/NSURL/Helpers/capture.m	(revision 38140)
+++ Tests/base/NSURL/Helpers/capture.m	(working copy)
@@ -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,16 +25,29 @@
   RELEASE(capture);
   RELEASE(op);
   RELEASE(ip);
+  DESTROY(file);
   [super dealloc];
 }
 
-- (id) init
+- (id)initWithSecure:(BOOL)flag
 {
-  capture = [NSMutableData new];
+  if((self = [super init]) != nil)
+    {
+      isSecure = flag;
+      capture = [NSMutableData new];
+      doRespond = NO;
+      done = NO;
+      file = nil;
+    }
 
-  return self;
+ return self;
 }
 
+- (id) init
+{
+  return [self initWithSecure: NO];
+}
+
 - (int) runTest
 {
   NSUserDefaults	*defs = [NSUserDefaults standardUserDefaults];
@@ -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);
Index: Tests/base/NSURL/test02.m
===================================================================
--- Tests/base/NSURL/test02.m	(revision 0)
+++ Tests/base/NSURL/test02.m	(working copy)
@@ -0,0 +1,120 @@
+#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;
+}
Index: Tests/base/NSURL/testCert.pem
===================================================================
--- Tests/base/NSURL/testCert.pem	(revision 0)
+++ Tests/base/NSURL/testCert.pem	(working copy)
@@ -0,0 +1,23 @@
+-----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-----
Index: Tests/base/NSURL/testKey.pem
===================================================================
--- Tests/base/NSURL/testKey.pem	(revision 0)
+++ Tests/base/NSURL/testKey.pem	(working copy)
@@ -0,0 +1,27 @@
+-----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-----
