aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2003-07-04 16:29:23 +0000
committerDaniel Stenberg <daniel@haxx.se>2003-07-04 16:29:23 +0000
commit45fc760985fa11ef98149418cbad02dadf748f31 (patch)
tree5e9e1c097cac271dd1f0504c2ea844bf57dc56f4
parent7968e3c2de56b035081f30ddcc9b60be2d75f396 (diff)
Peter Sylvester's patch was applied that introduces the following:
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.
-rw-r--r--include/curl/curl.h16
-rw-r--r--lib/http.c3
-rw-r--r--lib/ssluse.c9
-rw-r--r--lib/transfer.c26
-rw-r--r--lib/url.c13
-rw-r--r--lib/urldata.h6
6 files changed, 69 insertions, 4 deletions
diff --git a/include/curl/curl.h b/include/curl/curl.h
index 00074d561..ae73c1dde 100644
--- a/include/curl/curl.h
+++ b/include/curl/curl.h
@@ -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;
diff --git a/lib/http.c b/lib/http.c
index aa5a64dc0..d710ff5f4 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -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;
diff --git a/lib/ssluse.c b/lib/ssluse.c
index b4af2ba0d..8e8f5eeb2 100644
--- a/lib/ssluse.c
+++ b/lib/ssluse.c
@@ -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);
diff --git a/lib/transfer.c b/lib/transfer.c
index e98e1e01b..98cf70c1d 100644
--- a/lib/transfer.c
+++ b/lib/transfer.c
@@ -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);
diff --git a/lib/url.c b/lib/url.c
index 9ec92dfab..3b6a73b90 100644
--- 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
diff --git a/lib/urldata.h b/lib/urldata.h
index f892968e9..dab214ce3 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -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 */