Hello community,

here is the log from the commit of package libserf for openSUSE:Factory checked 
in at 2014-02-11 10:36:47
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/libserf (Old)
 and      /work/SRC/openSUSE:Factory/.libserf.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "libserf"

Changes:
--------
--- /work/SRC/openSUSE:Factory/libserf/libserf.changes  2013-12-10 
17:43:41.000000000 +0100
+++ /work/SRC/openSUSE:Factory/.libserf.new/libserf.changes     2014-02-11 
10:36:48.000000000 +0100
@@ -1,0 +2,11 @@
+Sun Feb  9 10:57:25 UTC 2014 - andreas.stie...@gmx.de
+
+- Serf 1.3.4
+  This release fixes a race condition during OpenSSL initialisation
+  and two ssl tunnel setup failures
+  * Endless loop during ssl tunnel setup with Negotiate authn
+  * Can't setup ssl tunnel which sends Connection close header
+  * race condition when initializing OpenSSL from multiple threads
+  * Incorrect pkg-config file when GSSAPI isn't configured
+
+-------------------------------------------------------------------

Old:
----
  serf-1.3.3.tar.bz2

New:
----
  serf-1.3.4.tar.bz2

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ libserf.spec ++++++
--- /var/tmp/diff_new_pack.riXUTW/_old  2014-02-11 10:36:48.000000000 +0100
+++ /var/tmp/diff_new_pack.riXUTW/_new  2014-02-11 10:36:48.000000000 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package libserf
 #
-# Copyright (c) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany.
+# Copyright (c) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -24,12 +24,12 @@
 %define major  1
 %define minor  3
 %define SHLIBVER %major.%minor.0
-Version:        1.3.3
+Version:        1.3.4
 Release:        0
 Summary:        High-Performance Asynchronous HTTP Client Library
 License:        Apache-2.0
 Group:          System/Libraries
-Source:         https://serf.googlecode.com/files/serf-%{version}.tar.bz2
+Source:         
https://serf.googlecode.com/svn/src_releases/serf-%version.tar.bz2
 Url:            https://serf.googlecode.com
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
 BuildRequires:  gcc

++++++ serf-1.3.3.tar.bz2 -> serf-1.3.4.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/serf-1.3.3/CHANGES new/serf-1.3.4/CHANGES
--- old/serf-1.3.3/CHANGES      2013-12-09 20:43:10.000000000 +0100
+++ new/serf-1.3.4/CHANGES      2014-02-08 20:56:40.000000000 +0100
@@ -1,4 +1,11 @@
-Serf 1.3.3 [2013-12-09, from /tags/1.3.3, r????]
+Serf 1.3.4 [2014-02-08, from /tags/1.3.4, rxxxx]
+  Fix issue #119: Endless loop during ssl tunnel setup with Negotiate authn
+  Fix issue #123: Can't setup ssl tunnel which sends Connection close header
+  Fix a race condition when initializing OpenSSL from multiple threads (r2263)
+  Fix issue #138: Incorrect pkg-config file when GSSAPI isn't configured
+
+
+Serf 1.3.3 [2013-12-09, from /tags/1.3.3, r2242]
   Fix issue 129: Try more addresses of multihomed servers
   Handle X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE correctly (r2225)
   Return APR_TIMEUP from poll() to enable detecting connection timeouts (r2183)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/serf-1.3.3/SConstruct new/serf-1.3.4/SConstruct
--- old/serf-1.3.3/SConstruct   2013-10-04 17:11:04.000000000 +0200
+++ new/serf-1.3.4/SConstruct   2014-02-04 21:11:10.000000000 +0100
@@ -382,7 +382,7 @@
                            '@INCLUDE_SUBDIR@': 'serf-%d' % (MAJOR,),
                            '@VERSION@': '%d.%d.%d' % (MAJOR, MINOR, PATCH),
                            '@LIBS@': '%s %s %s -lz' % (apu_libs, apr_libs,
-                                                       env.get('GSSAPI_LIBS')),
+                                                       env.get('GSSAPI_LIBS', 
'')),
                            })
 
 env.Default(lib_static, lib_shared, pkgconfig)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/serf-1.3.3/auth/auth_spnego.c 
new/serf-1.3.4/auth/auth_spnego.c
--- old/serf-1.3.3/auth/auth_spnego.c   2013-08-15 11:00:57.000000000 +0200
+++ new/serf-1.3.4/auth/auth_spnego.c   2014-02-04 21:01:07.000000000 +0100
@@ -181,7 +181,8 @@
    claim to be. The session key can only be used with the HTTP service
    on the target host. */
 static apr_status_t
-gss_api_get_credentials(char *token, apr_size_t token_len,
+gss_api_get_credentials(serf_connection_t *conn,
+                        char *token, apr_size_t token_len,
                         const char *hostname,
                         const char **buf, apr_size_t *buf_len,
                         gss_authn_info_t *gss_info)
@@ -202,6 +203,7 @@
 
     /* Establish a security context to the server. */
     status = serf__spnego_init_sec_context(
+         conn,
          gss_info->gss_ctx,
          KRB_HTTP_SERVICE, hostname,
          &input_buf,
@@ -327,14 +329,16 @@
     }
 
     if (peer == HOST) {
-        status = gss_api_get_credentials(token, token_len,
+        status = gss_api_get_credentials(conn,
+                                         token, token_len,
                                          conn->host_info.hostname,
                                          &tmp, &tmp_len,
                                          gss_info);
     } else {
         char *proxy_host;
         apr_getnameinfo(&proxy_host, conn->ctx->proxy_address, 0);
-        status = gss_api_get_credentials(token, token_len, proxy_host,
+        status = gss_api_get_credentials(conn,
+                                         token, token_len, proxy_host,
                                          &tmp, &tmp_len,
                                          gss_info);
     }
@@ -370,24 +374,32 @@
                              serf_connection_t *conn,
                              apr_pool_t *pool)
 {
-    gss_authn_info_t *gss_info;
-    apr_status_t status;
-
-    gss_info = apr_pcalloc(conn->pool, sizeof(*gss_info));
-    gss_info->pool = conn->pool;
-    gss_info->state = gss_api_auth_not_started;
-    gss_info->pstate = pstate_init;
-    status = serf__spnego_create_sec_context(&gss_info->gss_ctx, scheme,
-                                             gss_info->pool, pool);
-
-    if (status) {
-        return status;
-    }
+    serf_context_t *ctx = conn->ctx;
+    serf__authn_info_t *authn_info;
+    gss_authn_info_t *gss_info = NULL;
 
+    /* For proxy authentication, reuse the gss context for all connections. 
+       For server authentication, create a new gss context per connection. */
     if (code == 401) {
-        conn->authn_baton = gss_info;
+        authn_info = &conn->authn_info;
     } else {
-        conn->proxy_authn_baton = gss_info;
+        authn_info = &ctx->proxy_authn_info;
+    }
+    gss_info = authn_info->baton;
+
+    if (!gss_info) {
+        apr_status_t status;
+
+        gss_info = apr_pcalloc(conn->pool, sizeof(*gss_info));
+        gss_info->pool = conn->pool;
+        gss_info->state = gss_api_auth_not_started;
+        gss_info->pstate = pstate_init;
+        status = serf__spnego_create_sec_context(&gss_info->gss_ctx, scheme,
+                                                 gss_info->pool, pool);
+        if (status) {
+            return status;
+        }
+        authn_info->baton = gss_info;
     }
 
     /* Make serf send the initial requests one by one */
@@ -410,8 +422,9 @@
                          apr_pool_t *pool)
 {
     serf_connection_t *conn = request->conn;
-    gss_authn_info_t *gss_info = (code == 401) ? conn->authn_baton :
-        conn->proxy_authn_baton;
+    serf_context_t *ctx = conn->ctx;
+    gss_authn_info_t *gss_info = (code == 401) ? conn->authn_info.baton :
+                                                 ctx->proxy_authn_info.baton;
 
     return do_auth(code == 401 ? HOST : PROXY,
                    code,
@@ -432,8 +445,9 @@
                                 const char *uri,
                                 serf_bucket_t *hdrs_bkt)
 {
-    gss_authn_info_t *gss_info = (peer == HOST) ? conn->authn_baton :
-        conn->proxy_authn_baton;
+    serf_context_t *ctx = conn->ctx;
+    gss_authn_info_t *gss_info = (peer == HOST) ? conn->authn_info.baton :
+                                                  ctx->proxy_authn_info.baton;
 
     /* If we have an ongoing authentication handshake, the handler of the
        previous response will have created the authn headers for this request
@@ -573,6 +587,7 @@
                                     serf_bucket_t *response,
                                     apr_pool_t *pool)
 {
+    serf_context_t *ctx = conn->ctx;
     gss_authn_info_t *gss_info;
     const char *auth_hdr_name;
 
@@ -585,10 +600,10 @@
                   "Validate Negotiate response header.\n");
 
     if (peer == HOST) {
-        gss_info = conn->authn_baton;
+        gss_info = conn->authn_info.baton;
         auth_hdr_name = "WWW-Authenticate";
     } else {
-        gss_info = conn->proxy_authn_baton;
+        gss_info = ctx->proxy_authn_info.baton;
         auth_hdr_name = "Proxy-Authenticate";
     }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/serf-1.3.3/auth/auth_spnego.h 
new/serf-1.3.4/auth/auth_spnego.h
--- old/serf-1.3.3/auth/auth_spnego.h   2013-06-29 00:40:48.000000000 +0200
+++ new/serf-1.3.4/auth/auth_spnego.h   2014-02-04 20:41:14.000000000 +0100
@@ -88,14 +88,15 @@
  * Other returns values indicates error.
  */
 apr_status_t
-serf__spnego_init_sec_context(serf__spnego_context_t *ctx,
-                             const char *service,
-                             const char *hostname,
-                             serf__spnego_buffer_t *input_buf,
-                             serf__spnego_buffer_t *output_buf,
-                             apr_pool_t *result_pool,
-                             apr_pool_t *scratch_pool
-                             );
+serf__spnego_init_sec_context(serf_connection_t *conn,
+                              serf__spnego_context_t *ctx,
+                              const char *service,
+                              const char *hostname,
+                              serf__spnego_buffer_t *input_buf,
+                              serf__spnego_buffer_t *output_buf,
+                              apr_pool_t *result_pool,
+                              apr_pool_t *scratch_pool
+                              );
 
 /*
  * Reset a previously created security context so we can start with a new one.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/serf-1.3.3/auth/auth_spnego_gss.c 
new/serf-1.3.4/auth/auth_spnego_gss.c
--- old/serf-1.3.3/auth/auth_spnego_gss.c       2013-06-29 00:40:48.000000000 
+0200
+++ new/serf-1.3.4/auth/auth_spnego_gss.c       2014-02-04 20:41:14.000000000 
+0100
@@ -43,7 +43,7 @@
 };
 
 static void
-log_error(int verbose_flag, const char *filename,
+log_error(int verbose_flag, apr_socket_t *skt,
           serf__spnego_context_t *ctx,
           OM_uint32 err_maj_stat,
           OM_uint32 err_min_stat,
@@ -70,7 +70,7 @@
                                           &stat_buff);
         }
 
-        serf__log(verbose_flag, filename,
+        serf__log_skt(verbose_flag, __FILE__, skt,
                   "%s (%x,%d): %s\n", msg,
                   err_maj_stat, err_min_stat, stat_buff.value);
     }
@@ -89,7 +89,7 @@
         gss_maj_stat = gss_delete_sec_context(&gss_min_stat, &ctx->gss_ctx,
                                               GSS_C_NO_BUFFER);
         if(GSS_ERROR(gss_maj_stat)) {
-            log_error(AUTH_VERBOSE, __FILE__, ctx,
+            log_error(AUTH_VERBOSE, NULL, ctx,
                       gss_maj_stat, gss_min_stat,
                       "Error cleaning up GSS security context");
             return SERF_ERROR_AUTHN_FAILED;
@@ -146,7 +146,8 @@
 }
 
 apr_status_t
-serf__spnego_init_sec_context(serf__spnego_context_t *ctx,
+serf__spnego_init_sec_context(serf_connection_t *conn,
+                              serf__spnego_context_t *ctx,
                               const char *service,
                               const char *hostname,
                               serf__spnego_buffer_t *input_buf,
@@ -166,12 +167,13 @@
     /* TODO: should be shared between multiple requests. */
     bufdesc.value = apr_pstrcat(scratch_pool, service, "@", hostname, NULL);
     bufdesc.length = strlen(bufdesc.value);
-    serf__log(AUTH_VERBOSE, __FILE__, "Get principal for %s\n", bufdesc.value);
+    serf__log_skt(AUTH_VERBOSE, __FILE__, conn->skt,
+                  "Get principal for %s\n", bufdesc.value);
     gss_maj_stat = gss_import_name (&gss_min_stat, &bufdesc,
                                     GSS_C_NT_HOSTBASED_SERVICE,
                                     &host_gss_name);
     if(GSS_ERROR(gss_maj_stat)) {
-        log_error(AUTH_VERBOSE, __FILE__, ctx,
+        log_error(AUTH_VERBOSE, conn->skt, ctx,
                   gss_maj_stat, gss_min_stat,
                   "Error converting principal name to GSS internal format ");
         return SERF_ERROR_AUTHN_FAILED;
@@ -214,7 +216,7 @@
     case GSS_S_CONTINUE_NEEDED:
         return APR_EAGAIN;
     default:
-        log_error(AUTH_VERBOSE, __FILE__, ctx,
+        log_error(AUTH_VERBOSE, conn->skt, ctx,
                   gss_maj_stat, gss_min_stat,
                   "Error during Kerberos handshake");
         return SERF_ERROR_AUTHN_FAILED;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/serf-1.3.3/auth/auth_spnego_sspi.c 
new/serf-1.3.4/auth/auth_spnego_sspi.c
--- old/serf-1.3.3/auth/auth_spnego_sspi.c      2013-06-29 00:40:48.000000000 
+0200
+++ new/serf-1.3.4/auth/auth_spnego_sspi.c      2014-02-04 20:41:14.000000000 
+0100
@@ -192,7 +192,8 @@
 }
 
 apr_status_t
-serf__spnego_init_sec_context(serf__spnego_context_t *ctx,
+serf__spnego_init_sec_context(serf_connection_t *conn,
+                              serf__spnego_context_t *ctx,
                               const char *service,
                               const char *hostname,
                               serf__spnego_buffer_t *input_buf,
@@ -219,8 +220,8 @@
         ctx->target_name = apr_pstrcat(scratch_pool, service, "/", canonname,
                                        NULL);
 
-        serf__log(AUTH_VERBOSE, __FILE__,
-                  "Using SPN '%s' for '%s'\n", ctx->target_name, hostname);
+        serf__log_skt(AUTH_VERBOSE, __FILE__, conn->skt,
+                      "Using SPN '%s' for '%s'\n", ctx->target_name, hostname);
     }
     else if (ctx->authn_type == SERF_AUTHN_NTLM)
     {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/serf-1.3.3/buckets/headers_buckets.c 
new/serf-1.3.4/buckets/headers_buckets.c
--- old/serf-1.3.3/buckets/headers_buckets.c    2013-07-21 16:27:03.000000000 
+0200
+++ new/serf-1.3.4/buckets/headers_buckets.c    2014-02-04 20:41:14.000000000 
+0100
@@ -20,6 +20,8 @@
 #include "serf.h"
 #include "serf_bucket_util.h"
 
+#include "serf_private.h" /* for serf__bucket_headers_remove */
+
 
 typedef struct header_list {
     const char *header;
@@ -37,6 +39,7 @@
 
 typedef struct {
     header_list_t *list;
+    header_list_t *last;
 
     header_list_t *cur_read;
     enum {
@@ -60,6 +63,7 @@
 
     ctx = serf_bucket_mem_alloc(allocator, sizeof(*ctx));
     ctx->list = NULL;
+    ctx->last = NULL;
     ctx->state = READ_START;
 
     return serf_bucket_create(&serf_bucket_type_headers, allocator, ctx);
@@ -71,7 +75,6 @@
     const char *value, apr_size_t value_size, int value_copy)
 {
     headers_context_t *ctx = bkt->data;
-    header_list_t *iter = ctx->list;
     header_list_t *hdr;
 
 #if 0
@@ -105,13 +108,12 @@
     }
 
     /* Add the new header at the end of the list. */
-    while (iter && iter->next) {
-        iter = iter->next;
-    }
-    if (iter)
-        iter->next = hdr;
+    if (ctx->last)
+        ctx->last->next = hdr;
     else
         ctx->list = hdr;
+
+    ctx->last = hdr;
 }
 
 void serf_bucket_headers_set(
@@ -191,6 +193,29 @@
     return val;
 }
 
+void serf__bucket_headers_remove(serf_bucket_t *bucket, const char *header)
+{
+    headers_context_t *ctx = bucket->data;
+    header_list_t *scan = ctx->list, *prev = NULL;
+
+    /* Find and delete all items with the same header (case insensitive) */
+    while (scan) {
+        if (strcasecmp(scan->header, header) == 0) {
+            if (prev) {
+                prev->next = scan->next;
+            } else {
+                ctx->list = scan->next;
+            }
+            if (ctx->last == scan) {
+                ctx->last = NULL;
+            }
+        } else {
+            prev = scan;
+        }
+        scan = scan->next;
+    }
+}
+
 void serf_bucket_headers_do(
     serf_bucket_t *headers_bucket,
     serf_bucket_headers_do_callback_fn_t func,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/serf-1.3.3/buckets/ssl_buckets.c 
new/serf-1.3.4/buckets/ssl_buckets.c
--- old/serf-1.3.3/buckets/ssl_buckets.c        2013-11-29 22:22:42.000000000 
+0100
+++ new/serf-1.3.4/buckets/ssl_buckets.c        2014-02-04 20:41:14.000000000 
+0100
@@ -959,16 +959,24 @@
 
 #endif
 
-static apr_uint32_t have_init_ssl = 0;
+#if !APR_VERSION_AT_LEAST(1,0,0)
+#define apr_atomic_cas32(mem, with, cmp) apr_atomic_cas(mem, with, cmp)
+#endif
+
+enum ssl_init_e
+{
+   INIT_UNINITIALIZED = 0,
+   INIT_BUSY = 1,
+   INIT_DONE = 2
+};
+
+static volatile apr_uint32_t have_init_ssl = INIT_UNINITIALIZED;
 
 static void init_ssl_libraries(void)
 {
     apr_uint32_t val;
-#if APR_VERSION_AT_LEAST(1,0,0)
-    val = apr_atomic_xchg32(&have_init_ssl, 1);
-#else
-    val = apr_atomic_cas(&have_init_ssl, 1, 0);
-#endif
+
+    val = apr_atomic_cas32(&have_init_ssl, INIT_BUSY, INIT_UNINITIALIZED);
 
     if (!val) {
 #if APR_HAS_THREADS
@@ -1016,6 +1024,19 @@
 
         apr_pool_cleanup_register(ssl_pool, NULL, cleanup_ssl, cleanup_ssl);
 #endif
+        apr_atomic_cas32(&have_init_ssl, INIT_DONE, INIT_BUSY);
+    }
+  else
+    {
+        /* Make sure we don't continue before the initialization in another
+           thread has completed */
+        while (val != INIT_DONE) {
+            apr_sleep(APR_USEC_PER_SEC / 1000);
+      
+            val = apr_atomic_cas32(&have_init_ssl,
+                                   INIT_UNINITIALIZED,
+                                   INIT_UNINITIALIZED);            
+        }
     }
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/serf-1.3.3/outgoing.c new/serf-1.3.4/outgoing.c
--- old/serf-1.3.3/outgoing.c   2013-11-29 21:56:28.000000000 +0100
+++ new/serf-1.3.4/outgoing.c   2014-02-04 20:41:14.000000000 +0100
@@ -432,8 +432,8 @@
 {
     /* Note that we should hold new requests until we open our new socket. */
     conn->state = SERF_CONN_CLOSING;
-    serf__log(CONN_VERBOSE, __FILE__, "stop writing on conn 0x%x\n",
-              conn);
+    serf__log_skt(CONN_VERBOSE, __FILE__, conn->skt,
+                  "stop writing on conn 0x%x\n", conn);
 
     /* Clear our iovec. */
     conn->vec_len = 0;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/serf-1.3.3/serf.h new/serf-1.3.4/serf.h
--- old/serf-1.3.3/serf.h       2013-11-29 21:36:01.000000000 +0100
+++ new/serf-1.3.4/serf.h       2014-02-04 19:57:39.000000000 +0100
@@ -1062,7 +1062,7 @@
 /* Version info */
 #define SERF_MAJOR_VERSION 1
 #define SERF_MINOR_VERSION 3
-#define SERF_PATCH_VERSION 3
+#define SERF_PATCH_VERSION 4
 
 /* Version number string */
 #define SERF_VERSION_STRING APR_STRINGIFY(SERF_MAJOR_VERSION) "." \
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/serf-1.3.3/serf_private.h 
new/serf-1.3.4/serf_private.h
--- old/serf-1.3.3/serf_private.h       2013-09-29 08:37:46.000000000 +0200
+++ new/serf-1.3.4/serf_private.h       2014-02-04 20:41:14.000000000 +0100
@@ -270,9 +270,8 @@
        port values are filled in. */
     apr_uri_t host_info;
 
-    /* connection and authentication scheme specific information */ 
-    void *authn_baton;
-    void *proxy_authn_baton;
+    /* authentication info for this connection. */
+    serf__authn_info_t authn_info;
 
     /* Time marker when connection begins. */
     apr_time_t connect_time;
@@ -296,6 +295,12 @@
  */
 apr_status_t serf_response_full_become_aggregate(serf_bucket_t *bucket);
 
+/**
+ * Remove the header from the list, do nothing if the header wasn't added.
+ */
+void serf__bucket_headers_remove(serf_bucket_t *headers_bucket,
+                                 const char *header);
+
 /*** Authentication handler declarations ***/
 
 typedef enum { PROXY, HOST } peer_t;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/serf-1.3.3/ssltunnel.c new/serf-1.3.4/ssltunnel.c
--- old/serf-1.3.3/ssltunnel.c  2013-07-04 21:58:40.000000000 +0200
+++ new/serf-1.3.4/ssltunnel.c  2014-02-04 20:41:14.000000000 +0100
@@ -68,9 +68,10 @@
     apr_status_t status;
     serf_status_line sl;
     req_ctx_t *ctx = handler_baton;
+    serf_connection_t *conn = request->conn;
 
     if (! response) {
-        serf_connection_request_create(request->conn,
+        serf_connection_request_create(conn,
                                        setup_request,
                                        ctx);
         return APR_SUCCESS;
@@ -97,17 +98,34 @@
        connection.
     */
     if (sl.code >= 200 && sl.code < 300) {
-        request->conn->state = SERF_CONN_CONNECTED;
+        serf_bucket_t *hdrs;
+        const char *val;
+
+        conn->state = SERF_CONN_CONNECTED;
 
         /* Body is supposed to be empty. */
         apr_pool_destroy(ctx->pool);
-        serf_bucket_destroy(request->conn->ssltunnel_ostream);
-        request->conn->stream = NULL;
+        serf_bucket_destroy(conn->ssltunnel_ostream);
+        serf_bucket_destroy(conn->stream);
+        conn->stream = NULL;
         ctx = NULL;
 
-        serf__log(CONN_VERBOSE, __FILE__,
-                  "successfully set up ssl tunnel on connection 0x%x\n",
-                  request->conn);
+        serf__log_skt(CONN_VERBOSE, __FILE__, conn->skt,
+                      "successfully set up ssl tunnel.\n");
+
+        /* Fix for issue #123: ignore the "Connection: close" header here,
+           leaving the header in place would make the serf's main context
+           loop close this connection immediately after reading the 200 OK
+           response. */
+
+        hdrs = serf_bucket_response_get_headers(response);
+        val = serf_bucket_headers_get(hdrs, "Connection");
+        if (val && strcasecmp("close", val) == 0) {
+            serf__log_skt(CONN_VERBOSE, __FILE__, conn->skt,
+                      "Ignore Connection: close header on this reponse, don't "
+                      "close the connection now that the tunnel is set up.\n");
+            serf__bucket_headers_remove(hdrs, "Connection");
+        }
 
         return APR_EOF;
     }
@@ -171,8 +189,8 @@
                                    ctx);
 
     conn->state = SERF_CONN_SETUP_SSLTUNNEL;
-    serf__log(CONN_VERBOSE, __FILE__,
-              "setting up ssl tunnel on connection 0x%x\n", conn);
+    serf__log_skt(CONN_VERBOSE, __FILE__, conn->skt,
+                  "setting up ssl tunnel on connection.\n");
 
     return APR_SUCCESS;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/serf-1.3.3/test/test_context.c 
new/serf-1.3.4/test/test_context.c
--- old/serf-1.3.3/test/test_context.c  2013-11-29 22:22:42.000000000 +0100
+++ new/serf-1.3.4/test/test_context.c  2014-02-04 20:41:14.000000000 +0100
@@ -1971,7 +1971,8 @@
    tunnel. Retry the authentication a few times to test requeueing of the 
    CONNECT request. */
 static void ssltunnel_basic_auth(CuTest *tc, const char *server_resp_hdrs,
-                                 const char *proxy_resp_hdrs)
+                                 const char *proxy_407_resp_hdrs,
+                                 const char *proxy_200_resp_hdrs)
 {
     test_baton_t *tb;
     handler_baton_t handler_ctx[1];
@@ -2012,7 +2013,7 @@
         "%s"
         CRLF
         "1" CRLF CRLF
-        "0" CRLF CRLF, proxy_resp_hdrs);
+        "0" CRLF CRLF, proxy_407_resp_hdrs);
     action_list_proxy[1].kind = SERVER_RESPOND;
     action_list_proxy[1].text = apr_psprintf(test_pool,
         "HTTP/1.1 407 Unauthorized" CRLF
@@ -2021,7 +2022,7 @@
         "%s"
         CRLF
         "1" CRLF CRLF
-        "0" CRLF CRLF, proxy_resp_hdrs);
+        "0" CRLF CRLF, proxy_407_resp_hdrs);
 
     action_list_proxy[2].kind = SERVER_RESPOND;
     action_list_proxy[2].text = apr_psprintf(test_pool,
@@ -2031,10 +2032,13 @@
         "%s"
         CRLF
         "1" CRLF CRLF
-        "0" CRLF CRLF, proxy_resp_hdrs);
+        "0" CRLF CRLF, proxy_407_resp_hdrs);
 
     action_list_proxy[3].kind = SERVER_RESPOND;
-    action_list_proxy[3].text = CHUNKED_EMPTY_RESPONSE;
+    action_list_proxy[3].text = apr_psprintf(test_pool,
+        "HTTP/1.1 200 Connection Established" CRLF
+        "%s"
+        CRLF, proxy_200_resp_hdrs);
     /* Forward the remainder of the data to the server without validation */
     action_list_proxy[4].kind = PROXY_FORWARD;
     action_list_proxy[4].text = "https://localhost:"; SERV_PORT_STR;
@@ -2120,19 +2124,25 @@
 static void test_ssltunnel_basic_auth(CuTest *tc)
 {
     /* KeepAlive On for both proxy and server */
-    ssltunnel_basic_auth(tc, "", "");
+    ssltunnel_basic_auth(tc, "", "", "");
 }
 
 static void test_ssltunnel_basic_auth_server_has_keepalive_off(CuTest *tc)
 {
     /* Add Connection:Close header to server response */
-    ssltunnel_basic_auth(tc, "Connection: close" CRLF, "");
+    ssltunnel_basic_auth(tc, "Connection: close" CRLF, "", "");
 }
 
 static void test_ssltunnel_basic_auth_proxy_has_keepalive_off(CuTest *tc)
 {
-    /* Add Connection:Close header to proxy response */
-    ssltunnel_basic_auth(tc, "", "Connection: close" CRLF);
+    /* Add Connection:Close header to proxy 407 response */
+    ssltunnel_basic_auth(tc, "", "Connection: close" CRLF, "");
+}
+
+static void test_ssltunnel_basic_auth_proxy_close_conn_on_200resp(CuTest *tc)
+{
+    /* Add Connection:Close header to proxy 200 Conn. Establ. response  */
+    ssltunnel_basic_auth(tc, "", "", "Connection: close" CRLF);
 }
 
 static apr_status_t
@@ -2285,6 +2295,7 @@
     SUITE_ADD_TEST(suite, test_ssltunnel_basic_auth);
     SUITE_ADD_TEST(suite, test_ssltunnel_basic_auth_server_has_keepalive_off);
     SUITE_ADD_TEST(suite, test_ssltunnel_basic_auth_proxy_has_keepalive_off);
+    SUITE_ADD_TEST(suite, 
test_ssltunnel_basic_auth_proxy_close_conn_on_200resp);
     SUITE_ADD_TEST(suite, test_ssltunnel_digest_auth);
 
     return suite;

-- 
To unsubscribe, e-mail: opensuse-commit+unsubscr...@opensuse.org
For additional commands, e-mail: opensuse-commit+h...@opensuse.org

Reply via email to