Peter Sylvester's patch was applied that introduces the following:
authorDaniel Stenberg <daniel@haxx.se>
Fri, 4 Jul 2003 16:29:23 +0000 (16:29 +0000)
committerDaniel Stenberg <daniel@haxx.se>
Fri, 4 Jul 2003 16:29:23 +0000 (16:29 +0000)
   CURLOPT_SSL_CTX_FUNCTION to set a callback that gets called with the
   OpenSSL's ssl_ctx pointer passed in and allow a callback to act on it. If
   anything but CURLE_OK is returned, that will also be returned by libcurl
   all the way back. If this function changes the CURLOPT_URL, libcurl will
   detect this and instead go use the new URL.

   CURLOPT_SSL_CTX_DATA is a pointer you set to get passed to the callback set
   with CURLOPT_SSL_CTX_FUNCTION.

include/curl/curl.h
lib/http.c
lib/ssluse.c
lib/transfer.c
lib/url.c
lib/urldata.h

index 00074d561f125e9e57d882c57cadcac3abedb4fd..ae73c1ddea280c9722a871538d82fae2719c191e 100644 (file)
@@ -147,7 +147,7 @@ typedef int (*curl_debug_callback)
         curl_infotype type, /* what kind of data */
         char *data,        /* points to the data */
         size_t size,       /* size of the data pointed to */
-        void *userp);      /* whatever the user please */
+        void *userptr);    /* whatever the user please */
   
 /* All possible error codes from all sorts of curl functions. Future versions
    may return other values, stay prepared.
@@ -224,6 +224,11 @@ typedef enum {
   CURL_LAST /* never use! */
 } CURLcode;
 
+typedef CURLcode (*curl_ssl_ctx_callback)(CURL *curl,    /* easy handle */
+                                          void *ssl_ctx, /* actually an
+                                                            OpenSSL SSL_CTX */
+                                          void *userptr);
+
 /* Make a spelling correction for the operation timed-out define */
 #define CURLE_OPERATION_TIMEDOUT CURLE_OPERATION_TIMEOUTED
 #define CURLE_HTTP_NOT_FOUND CURLE_HTTP_RETURNED_ERROR
@@ -659,6 +664,15 @@ typedef enum {
      Note that setting multiple bits may cause extra network round-trips. */
   CINIT(HTTPAUTH, LONG, 107),
 
+  /* Set the ssl context callback function, currently only for OpenSSL ssl_ctx
+     in second argument. The function must be matching the
+     curl_ssl_ctx_callback proto. */
+  CINIT(SSL_CTX_FUNCTION, FUNCTIONPOINT, 108),
+
+  /* Set the userdata for the ssl context callback function's third
+     argument */
+  CINIT(SSL_CTX_DATA, OBJECTPOINT, 109),
+
   CURLOPT_LASTENTRY /* the last unused */
 } CURLoption;
 
index aa5a64dc039245b238ad62ade0c3e8a377d65662..d710ff5f4da568a9aab1bd68a87e706eacfc5d13 100644 (file)
@@ -617,6 +617,9 @@ CURLcode Curl_http_done(struct connectdata *conn)
   conn->fread = data->set.fread; /* restore */
   conn->fread_in = data->set.in; /* restore */
 
+  if (http == NULL) 
+    return CURLE_OK;
+
   if(http->send_buffer) {
     send_buffer *buff = http->send_buffer;
     
index b4af2ba0d72e8a7b58830b4ef5b1e3edf8443537..8e8f5eeb2c84dcd582e513b60fdd33d569d3b793 100644 (file)
@@ -831,6 +831,15 @@ Curl_SSLConnect(struct connectdata *conn)
   else
     SSL_CTX_set_verify(conn->ssl.ctx, SSL_VERIFY_NONE, cert_verify_callback);
 
+  /* give application a chance to interfere with SSL set up. */
+  if (data->set.ssl.fsslctx) {
+    CURLcode callbackresult = (*data->set.ssl.fsslctx)(data, conn->ssl.ctx,
+                                                       data->set.ssl.fsslctxp);
+    if (callbackresult != CURLE_OK) {
+      failf(data,"error signaled by ssl ctx callback");
+      return callbackresult;
+    }
+  }
 
   /* Lets make an SSL structure */
   conn->ssl.handle = SSL_new (conn->ssl.ctx);
index e98e1e01b8fed8461a5fdf45750fb5f30eb881ea..98cf70c1dd43a0e50fccec790ee2720a2a458905 100644 (file)
@@ -1889,9 +1889,29 @@ CURLcode Curl_perform(struct SessionHandle *data)
    * performed after this do-while loop.
    */
 
-  do {
-    Curl_pgrsTime(data, TIMER_STARTSINGLE);
-    res = Curl_connect(data, &conn);
+  do {  
+    int urlchanged = FALSE;
+    do {
+      Curl_pgrsTime(data, TIMER_STARTSINGLE);
+      data->change.url_changed = FALSE;
+      res = Curl_connect(data, &conn);
+
+      /* If a callback (or something) has altered the URL we should use within
+         the Curl_connect(), we detect it here and act as if we are redirected
+         to the new URL */
+      urlchanged = data->change.url_changed;
+      if ((CURLE_OK == res) && urlchanged) {
+        char *newurl;
+        res = Curl_done(conn);
+        if(CURLE_OK == res) {
+          newurl = strdup(data->change.url);
+          res = Curl_follow(data, newurl);
+          if(res)
+            free(newurl);
+        }
+      }
+    } while (urlchanged && res == CURLE_OK) ; 
+
     if(res == CURLE_OK) {
       res = Curl_do(&conn);
 
index 9ec92dfab887fbea791134f983927caf65179140..3b6a73b9089a3a4ee938151cbbca1d6443bac66c 100644 (file)
--- a/lib/url.c
+++ b/lib/url.c
@@ -723,6 +723,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
     }
     data->set.set_url = va_arg(param, char *);
     data->change.url = data->set.set_url;
+    data->change.url_changed = TRUE;
     break;
   case CURLOPT_PORT:
     /*
@@ -1091,6 +1092,18 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
      */
     data->set.ssl.verifyhost = va_arg(param, long);
     break;
+  case CURLOPT_SSL_CTX_FUNCTION:
+    /*
+     * Set a SSL_CTX callback
+     */
+       data->set.ssl.fsslctx = va_arg(param, curl_ssl_ctx_callback);
+    break;
+  case CURLOPT_SSL_CTX_DATA:
+    /*
+     * Set a SSL_CTX callback parameter pointer
+     */
+    data->set.ssl.fsslctxp = va_arg(param, void *);
+    break;
   case CURLOPT_CAINFO:
     /*
      * Set CA info for SSL connection. Specify file name of the CA certificate
index f892968e9ff20447feaa16752e2b69155797c4d2..dab214ce37150969f69db3e9fc6d4fa68f7a25ae 100644 (file)
@@ -145,6 +145,8 @@ struct ssl_config_data {
   char *egdsocket;       /* path to file containing the EGD daemon socket */
   char *cipher_list;     /* list of ciphers to use */
   long numsessions;      /* SSL session id cache size */
+  curl_ssl_ctx_callback fsslctx;       /* function to initialize ssl ctx */
+  void *fsslctxp;      /*parameter for call back */
 };
 
 /* information stored about one single SSL session */
@@ -677,6 +679,10 @@ struct UrlState {
 struct DynamicStatic {
   char *url;        /* work URL, copied from UserDefined */
   bool url_alloc;   /* URL string is malloc()'ed */
+  bool url_changed; /* set on CURL_OPT_URL, used to detect if the URL was
+                       changed after the connect phase, as we allow callback
+                       to change it and if so, we reconnect to use the new 
+                       URL instead */
   char *proxy;      /* work proxy, copied from UserDefined */
   bool proxy_alloc; /* http proxy string is malloc()'ed */
   char *referer;    /* referer string */