]> granicus.if.org Git - curl/commitdiff
NTLM: re-use existing connection better
authorJoe Mason <jmason@rim.com>
Mon, 20 Aug 2012 21:00:40 +0000 (17:00 -0400)
committerDaniel Stenberg <daniel@haxx.se>
Fri, 31 Aug 2012 20:54:23 +0000 (22:54 +0200)
If we need an NTLM connection and one already exists, always choose that
one.

lib/url.c

index c2f488280669671849f07d2fa5436c28592fd542..c05c50e62ff1c34be2009a056d27417599659d6b 100644 (file)
--- a/lib/url.c
+++ b/lib/url.c
@@ -2928,10 +2928,14 @@ ConnectionExists(struct SessionHandle *data,
 {
   long i;
   struct connectdata *check;
+  struct connectdata *chosen = 0;
   bool canPipeline = IsPipeliningPossible(data, needle);
+  bool wantNTLM = (data->state.authhost.want==CURLAUTH_NTLM) ||
+                  (data->state.authhost.want==CURLAUTH_NTLM_WB);
 
   for(i=0; i< data->state.connc->num; i++) {
     bool match = FALSE;
+    bool credentialsMatch = FALSE;
     size_t pipeLen = 0;
     /*
      * Note that if we use a HTTP proxy, we check connections to that
@@ -3102,9 +3106,7 @@ ConnectionExists(struct SessionHandle *data,
           }
         }
         if((needle->handler->protocol & CURLPROTO_FTP) ||
-           ((needle->handler->protocol & CURLPROTO_HTTP) &&
-            ((data->state.authhost.want==CURLAUTH_NTLM) ||
-             (data->state.authhost.want==CURLAUTH_NTLM_WB)))) {
+           ((needle->handler->protocol & CURLPROTO_HTTP) && wantNTLM)) {
           /* This is FTP or HTTP+NTLM, verify that we're using the same name
              and password as well */
           if(!strequal(needle->user, check->user) ||
@@ -3112,6 +3114,7 @@ ConnectionExists(struct SessionHandle *data,
             /* one of them was different */
             continue;
           }
+          credentialsMatch = TRUE;
         }
         match = TRUE;
       }
@@ -3129,14 +3132,29 @@ ConnectionExists(struct SessionHandle *data,
     }
 
     if(match) {
-      check->inuse = TRUE; /* mark this as being in use so that no other
-                              handle in a multi stack may nick it */
+      chosen = check;
 
-      *usethis = check;
-      return TRUE; /* yes, we found one to use! */
+      /* If we are not looking for an NTLM connection, we can choose this one
+         immediately. */
+      if(!wantNTLM)
+        break;
+
+      /* Otherwise, check if this is already authenticating with the right
+         credentials. If not, keep looking so that we can reuse NTLM
+         connections if possible. (Especially we must reuse the same
+         connection if partway through a handshake!) */
+      if(credentialsMatch && chosen->ntlm.state != NTLMSTATE_NONE)
+        break;
     }
   }
 
+  if(chosen) {
+    chosen->inuse = TRUE; /* mark this as being in use so that no other
+                            handle in a multi stack may nick it */
+    *usethis = chosen;
+    return TRUE; /* yes, we found one to use! */
+  }
+
   return FALSE; /* no matching connecting exists */
 }