Commits

Tuukka Norri committed da772a2

Even more work on SSL support (references #6)
- Connection will now be retried without SSL in case SSL mode is set to preferred and the user has accepted the certificate but the secure connection fails for some reason.
- Notifications get sent after connecting.
- There is some glitch when using tables with strange names but this will hopefully be fixed.

Comments (0)

Files changed (6)

Framework/Sources/PGTSAdditions.h

 @interface NSCalendarDate (PGTSAdditions)
 @end
 
+@interface NSURL (PGTSAdditions)
+- (NSMutableDictionary *) PGTSConnectionDictionary;
+@end
+
 @interface PGTSAbstractClass : NSObject
 {
 }

Framework/Sources/PGTSAdditions.m

     return rval;    
 }
 @end
+
+
+@implementation NSURL (PGTSAdditions)
+#define SetIf( VALUE, KEY ) if ((VALUE)) [connectionDict setObject: VALUE forKey: KEY];
+- (NSMutableDictionary *) PGTSConnectionDictionary
+{
+	NSMutableDictionary* connectionDict = nil;
+	if (0 == [@"pgsql" caseInsensitiveCompare: [self scheme]])
+	{
+		connectionDict = [NSMutableDictionary dictionary];    
+		
+		NSString* relativePath = [self relativePath];
+		if (1 <= [relativePath length])
+			SetIf ([relativePath substringFromIndex: 1], kPGTSDatabaseNameKey);
+		
+		SetIf ([self host], kPGTSHostKey);
+		SetIf ([self user], kPGTSUserNameKey);
+		SetIf ([self password], kPGTSPasswordKey);
+		SetIf ([self port], kPGTSPortKey);
+	}
+	return connectionDict;
+}
+@end

Framework/Sources/PGTSConnection.m

 {
     BOOL rval = NO;
     CheckExceptionTable (self, kPGTSRaiseForConnectAsync, messageDelegateAfterConnecting);
-    if (NULL == connection)
-    {
-        const char* conninfo = [connectionString UTF8String];
-        if ((connection = PQconnectStart (conninfo)))
-        {
-            rval = YES;
-            [workerProxy workerPollConnectionResetting: NO];
-        }
-    }
+
+	[connectionLock lock];
+	if (NULL != connection)
+	{
+		PQfinish (connection);
+		connection = NULL;
+	}
+	[connectionLock unlock];
+	
+	const char* conninfo = [connectionString UTF8String];
+	if ((connection = PQconnectStart (conninfo)))
+	{
+		rval = YES;
+		[workerProxy workerPollConnectionResetting: NO];
+	}
     return rval;
 }
 
        [[PGTSConnectionPool sharedInstance] removeConnection: self];
        
        [connectionLock lock];
-       [socket closeFile];
-       [socket release];
-       socket = nil;
-       if (NULL != cancelRequest)
-           PQfreeCancel (cancelRequest);
-       PQfinish (connection);
-       connection = NULL;
-       
+	   [self disconnectAndCleanup];       
        [connectionLock unlock];
        [nc postNotificationName: kPGTSDidDisconnectNotification object: self];
    }
  * Connection variables.
  */
 //@{
-#define SetIf( VALUE, KEY ) if ((VALUE)) [connectionDict setObject: VALUE forKey: KEY];
 - (BOOL) setConnectionURL: (NSURL *) url
 {
     log4Debug (@"Connection URL: %@", url);
-    BOOL rval = NO;
-    if (0 == [@"pgsql" caseInsensitiveCompare: [url scheme]])
-    {
-        rval = YES;
-        NSMutableDictionary* connectionDict = [NSMutableDictionary dictionary];    
-        
-        NSString* relativePath = [url relativePath];
-        if (1 <= [relativePath length])
-            SetIf ([relativePath substringFromIndex: 1], kPGTSDatabaseNameKey);
-
-        SetIf ([url host], kPGTSHostKey);
-        SetIf ([url user], kPGTSUserNameKey);
-        SetIf ([url password], kPGTSPasswordKey);
-        SetIf ([url port], kPGTSPortKey);
-        [self setConnectionDictionary: connectionDict];
-    }
+	BOOL rval = NO;
+	NSDictionary* connectionDict = [url PGTSConnectionDictionary];
+	if (nil != connectionDict)
+	{
+		[self setConnectionDictionary: connectionDict];
+		rval = YES;
+	}	
     return rval;
 }
 
 
 - (BOOL) connected
 {
-    return (NULL != connection && CONNECTION_BAD != [self connectionStatus]);
+	ConnStatusType status = [self connectionStatus];
+    return (NULL != connection && CONNECTION_OK == status);
 }
 
 - (NSString *) databaseName

Framework/Sources/PGTSConnectionPrivate.h

 - (PGTSResultSet *) resultFromProxy: (volatile PGTSConnection *) proxy status: (int) status;
 - (int) sendResultsToDelegate: (int) status;
 - (void) handleFailedQuery;
+- (void) disconnectAndCleanup;
 @end
 
 

Framework/Sources/PGTSConnectionPrivate.m

             else
                 [delegate PGTSConnectionEstablished: self];
         }
-        
         else
         {
             [delegate PGTSConnectionFailed: self];
     }    
 }
 
+- (void) disconnectAndCleanup
+{
+	//N.B. No locking
+	[socket closeFile];
+	[socket release];
+	socket = nil;
+	if (NULL != cancelRequest)
+	{
+		PQfreeCancel (cancelRequest);
+		cancelRequest = NULL;
+	}
+	PQfinish (connection);
+	connection = NULL;
+}	
 @end
 
 

Framework/libpq.patch

-
- libpq.patch
- BaseTen
-
- Copyright (C) 2006 Marko Karppinen & Co. LLC.
-
- Before using this software, please review the available licensing options
- by visiting http://www.karppinen.fi/baseten/licensing/ or by contacting
- us at sales@karppinen.fi. Without an additional license, this software
- may be distributed only in compliance with the GNU General Public License.
-
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License, version 2.0,
- as published by the Free Software Foundation.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
- $Id$
-
 diff -urN postgresql-8.2.1/src/interfaces/libpq/fe-connect.c postgresql-8.2.1-tsnorri/src/interfaces/libpq/fe-connect.c
 --- postgresql-8.2.1/src/interfaces/libpq/fe-connect.c	2006-11-21 18:28:00.000000000 +0200
 +++ postgresql-8.2.1-tsnorri/src/interfaces/libpq/fe-connect.c	2007-01-25 11:52:27.000000000 +0200
  					/* SSL handshake done, ready to send startup packet */
 diff -urN postgresql-8.2.1/src/interfaces/libpq/fe-secure.c postgresql-8.2.1-tsnorri/src/interfaces/libpq/fe-secure.c
 --- postgresql-8.2.1/src/interfaces/libpq/fe-secure.c	2006-10-06 20:14:01.000000000 +0300
-+++ postgresql-8.2.1-tsnorri/src/interfaces/libpq/fe-secure.c	2007-01-25 11:21:24.000000000 +0200
++++ postgresql-8.2.1-tsnorri/src/interfaces/libpq/fe-secure.c	2007-02-01 14:35:46.000000000 +0200
 @@ -193,10 +193,10 @@
  }
  
  	/* Begin or continue the actual handshake */
  	return open_client_SSL(conn);
  #else
+@@ -851,6 +865,7 @@
+ 	if (r <= 0)
+ 	{
+ 		int			err = SSL_get_error(conn->ssl, r);
++        printf ("SSL error: %d\n", err);
+ 
+ 		switch (err)
+ 		{
 diff -urN postgresql-8.2.1/src/interfaces/libpq/libpq-fe.h postgresql-8.2.1-tsnorri/src/interfaces/libpq/libpq-fe.h
 --- postgresql-8.2.1/src/interfaces/libpq/libpq-fe.h	2006-10-04 03:30:13.000000000 +0300
 +++ postgresql-8.2.1-tsnorri/src/interfaces/libpq/libpq-fe.h	2007-01-23 16:36:58.000000000 +0200
  extern PostgresPollingStatusType pqsecure_open_client(PGconn *);
  extern void pqsecure_close(PGconn *);
  extern ssize_t pqsecure_read(PGconn *, void *ptr, size_t len);
-