subversion-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Justin Erenkrantz <jus...@erenkrantz.com>
Subject [PATCH] Have serf send Content-Length request bodies
Date Mon, 16 May 2011 10:00:31 GMT
So...at my hotel in Ljubljana, they have a silly Squid proxy that
doesn't understand chunked request bodies.  I know this has been a
huge detriment for some people with serf - so, here's a patch for serf
that will try to send C-L bodies for basic HTTP request bodies.  With
this patch, ra_serf only sends C-L...however, the hotel's version of
Squid (squid/2.7.STABLE9) doesn't understand chunked *response* bodies
either.  So, it ends up "Connection: close"-ing after *every single
request*.  Needless to say, serf's not amused - it still works just
fine; but it's pretty slow as it has to constantly re-open TCP
connections.  There's nothing serf can do about directly controlling
the server-side's logic to avoid chunking responses.

So, I'm on the fence about cleaning up and applying this patch as I
think if you're talking to a dumb HTTP proxy, you're likely going to
run into other serious issues.

Thoughts?  -- justin

Index: serf_bucket_util.h
===================================================================
--- serf_bucket_util.h	(revision 1462)
+++ serf_bucket_util.h	(working copy)
@@ -79,6 +79,10 @@ serf_bucket_t *serf_default_read_bucket(
     serf_bucket_t *bucket,
     const serf_bucket_type_t *type);

+apr_status_t serf_default_advise_length(
+    serf_bucket_t *bucket,
+    apr_size_t *len);
+
 /**
  * Default implementation of the @see destroy functionality.
  *
Index: serf.h
===================================================================
--- serf.h	(revision 1465)
+++ serf.h	(working copy)
@@ -814,6 +814,10 @@ struct serf_bucket_type_t {
                          const char **data, apr_size_t *len);

     /**
+     */
+    apr_status_t (*advise_length)(serf_bucket_t *bucket, apr_size_t *len);
+
+    /**
      * Destroy @a bucket, along with any associated resources.
      */
     void (*destroy)(serf_bucket_t *bucket);
@@ -882,6 +886,7 @@ struct serf_bucket_type_t {
     SERF__RECREAD(b, (b)->type->read_for_sendfile(b,r,h,f,o,l))
 #define serf_bucket_read_bucket(b,t) ((b)->type->read_bucket(b,t))
 #define serf_bucket_peek(b,d,l) ((b)->type->peek(b,d,l))
+#define serf_bucket_advise_length(b,l) ((b)->type->advise_length(b,l))
 #define serf_bucket_destroy(b) ((b)->type->destroy(b))
 #define serf_bucket_snapshot(b) ((b)->type->snapshot(b))
 #define serf_bucket_restore_snapshot(b) ((b)->type->restore_snapshot(b))
Index: buckets/limit_buckets.c
===================================================================
--- buckets/limit_buckets.c	(revision 1462)
+++ buckets/limit_buckets.c	(working copy)
@@ -118,6 +118,7 @@ const serf_bucket_type_t serf_bucket_type_limit =
     serf_default_read_for_sendfile,
     serf_default_read_bucket,
     serf_limit_peek,
+    serf_default_advise_length,
     serf_limit_destroy,
     serf_default_snapshot,
     serf_default_restore_snapshot,
Index: buckets/file_buckets.c
===================================================================
--- buckets/file_buckets.c	(revision 1462)
+++ buckets/file_buckets.c	(working copy)
@@ -105,6 +105,22 @@ static apr_status_t serf_file_peek(serf_bucket_t *
     return serf_databuf_peek(&ctx->databuf, data, len);
 }

+static apr_status_t serf_file_advise_length(serf_bucket_t *bucket,
+                                            apr_size_t *len)
+{
+    file_context_t *ctx = bucket->data;
+    apr_finfo_t finfo;
+    apr_status_t status;
+
+    status = apr_file_info_get(&finfo, APR_FINFO_SIZE, ctx->file);
+
+    if (!status) {
+        *len = finfo.size;
+    }
+
+    return APR_SUCCESS;
+}
+
 const serf_bucket_type_t serf_bucket_type_file = {
     "FILE",
     serf_file_read,
@@ -113,6 +129,7 @@ const serf_bucket_type_t serf_bucket_type_file = {
     serf_default_read_for_sendfile,
     serf_default_read_bucket,
     serf_file_peek,
+    serf_file_advise_length,
     serf_default_destroy_and_data,
     serf_default_snapshot,
     serf_default_restore_snapshot,
Index: buckets/buckets.c
===================================================================
--- buckets/buckets.c	(revision 1462)
+++ buckets/buckets.c	(working copy)
@@ -104,6 +104,12 @@ serf_bucket_t *serf_default_read_bucket(
     return NULL;
 }

+apr_status_t serf_default_advise_length(
+    serf_bucket_t *bucket,
+    apr_size_t *len)
+{
+    return APR_ENOTIMPL;
+}

 void serf_default_destroy(serf_bucket_t *bucket)
 {
Index: buckets/dechunk_buckets.c
===================================================================
--- buckets/dechunk_buckets.c	(revision 1462)
+++ buckets/dechunk_buckets.c	(working copy)
@@ -181,6 +181,7 @@ const serf_bucket_type_t serf_bucket_type_dechunk
     serf_default_read_for_sendfile,
     serf_default_read_bucket,
     serf_dechunk_peek,
+    serf_default_advise_length,
     serf_dechunk_destroy_and_data,
     serf_default_snapshot,
     serf_default_restore_snapshot,
Index: buckets/aggregate_buckets.c
===================================================================
--- buckets/aggregate_buckets.c	(revision 1465)
+++ buckets/aggregate_buckets.c	(working copy)
@@ -370,6 +370,28 @@ static apr_status_t serf_aggregate_peek(serf_bucke
     return APR_ENOTIMPL;
 }

+static apr_status_t serf_aggregate_advise_length(serf_bucket_t *bucket,
+                                                 apr_size_t *len)
+{
+    aggregate_context_t *ctx = bucket->data;
+    bucket_list_t *l = ctx->list;
+
+    *len = 0;
+    while (l) {
+        apr_status_t status;
+        apr_size_t bucket_len;
+
+        status = serf_bucket_advise_length(l->bucket, &bucket_len);
+        if (status) {
+            return status;
+        }
+        *len += bucket_len;
+        l = l->next;
+    }
+
+    return APR_SUCCESS;
+}
+
 static serf_bucket_t * serf_aggregate_read_bucket(
     serf_bucket_t *bucket,
     const serf_bucket_type_t *type)
@@ -462,6 +484,7 @@ const serf_bucket_type_t serf_bucket_type_aggregat
     serf_default_read_for_sendfile,
     serf_aggregate_read_bucket,
     serf_aggregate_peek,
+    serf_aggregate_advise_length,
     serf_aggregate_destroy_and_data,
     serf_aggregate_snapshot,
     serf_aggregate_restore_snapshot,
Index: buckets/barrier_buckets.c
===================================================================
--- buckets/barrier_buckets.c	(revision 1462)
+++ buckets/barrier_buckets.c	(working copy)
@@ -93,6 +93,7 @@ const serf_bucket_type_t serf_bucket_type_barrier
     serf_default_read_for_sendfile,
     serf_default_read_bucket,
     serf_barrier_peek,
+    serf_default_advise_length,
     serf_barrier_destroy,
     serf_default_snapshot,
     serf_default_restore_snapshot,
Index: buckets/request_buckets.c
===================================================================
--- buckets/request_buckets.c	(revision 1462)
+++ buckets/request_buckets.c	(working copy)
@@ -112,9 +112,23 @@ static void serialize_data(serf_bucket_t *bucket)
     serf_bucket_aggregate_append(bucket, new_bucket);
     serf_bucket_aggregate_append(bucket, ctx->headers);
     if (ctx->body != NULL) {
-        /* Morph the body bucket to a chunked encoding bucket for now. */
-        serf_bucket_headers_set(ctx->headers, "Transfer-Encoding", "chunked");
-        ctx->body = serf_bucket_chunk_create(ctx->body, bucket->allocator);
+        apr_status_t body_len_status;
+        apr_size_t body_len;
+
+        body_len_status = serf_bucket_advise_length(ctx->body, &body_len);
+        if (!body_len_status) {
+            char len_hdr[20];
+            apr_size_t len_hdr_len;
+
+            len_hdr_len = apr_snprintf(len_hdr, sizeof(len_hdr),
+                                       "%" APR_SIZE_T_FMT, body_len);
+
+            serf_bucket_headers_set(ctx->headers, "Content-Length", len_hdr);
+        } else {
+            /* Morph the body bucket to a chunked encoding bucket for now. */
+            serf_bucket_headers_set(ctx->headers,
"Transfer-Encoding", "chunked");
+            ctx->body = serf_bucket_chunk_create(ctx->body, bucket->allocator);
+        }
         serf_bucket_aggregate_append(bucket, ctx->body);
     }

@@ -199,6 +213,7 @@ const serf_bucket_type_t serf_bucket_type_request
     serf_default_read_for_sendfile,
     serf_default_read_bucket,
     serf_request_peek,
+    serf_default_advise_length,
     serf_default_destroy_and_data,
     serf_default_snapshot,
     serf_default_restore_snapshot,
Index: buckets/socket_buckets.c
===================================================================
--- buckets/socket_buckets.c	(revision 1462)
+++ buckets/socket_buckets.c	(working copy)
@@ -110,6 +110,7 @@ const serf_bucket_type_t serf_bucket_type_socket =
     serf_default_read_for_sendfile,
     serf_default_read_bucket,
     serf_socket_peek,
+    serf_default_advise_length,
     serf_default_destroy_and_data,
     serf_default_snapshot,
     serf_default_restore_snapshot,
Index: buckets/simple_buckets.c
===================================================================
--- buckets/simple_buckets.c	(revision 1462)
+++ buckets/simple_buckets.c	(working copy)
@@ -122,6 +122,16 @@ static apr_status_t serf_simple_peek(serf_bucket_t
     return APR_EOF;
 }

+static apr_status_t serf_simple_advise_length(serf_bucket_t *bucket,
+                                              apr_size_t *len)
+{
+    simple_context_t *ctx = bucket->data;
+
+    *len = ctx->remaining;
+
+    return APR_SUCCESS;
+}
+
 static void serf_simple_destroy(serf_bucket_t *bucket)
 {
     simple_context_t *ctx = bucket->data;
@@ -169,6 +179,7 @@ const serf_bucket_type_t serf_bucket_type_simple =
     serf_default_read_for_sendfile,
     serf_default_read_bucket,
     serf_simple_peek,
+    serf_simple_advise_length,
     serf_simple_destroy,
     serf_simple_snapshot,
     serf_simple_restore_snapshot,
Index: buckets/mmap_buckets.c
===================================================================
--- buckets/mmap_buckets.c	(revision 1462)
+++ buckets/mmap_buckets.c	(working copy)
@@ -106,6 +106,16 @@ static apr_status_t serf_mmap_peek(serf_bucket_t *
     return APR_ENOTIMPL;
 }

+static apr_status_t serf_mmap_advise_length(serf_bucket_t *bucket,
+                                            apr_size_t *len)
+{
+    mmap_context_t *ctx = bucket->data;
+
+    *len = ctx->remaining;
+
+    return APR_SUCCESS;
+}
+
 const serf_bucket_type_t serf_bucket_type_mmap = {
     "MMAP",
     serf_mmap_read,
@@ -114,6 +124,7 @@ const serf_bucket_type_t serf_bucket_type_mmap = {
     serf_default_read_for_sendfile,
     serf_default_read_bucket,
     serf_mmap_peek,
+    serf_mmap_advise_length,
     serf_default_destroy_and_data,
     serf_default_snapshot,
     serf_default_restore_snapshot,
Index: buckets/response_buckets.c
===================================================================
--- buckets/response_buckets.c	(revision 1462)
+++ buckets/response_buckets.c	(working copy)
@@ -425,6 +425,7 @@ const serf_bucket_type_t serf_bucket_type_response
     serf_default_read_for_sendfile,
     serf_default_read_bucket,
     serf_response_peek,
+    serf_default_advise_length,
     serf_response_destroy_and_data,
     serf_default_snapshot,
     serf_default_restore_snapshot,
Index: buckets/ssl_buckets.c
===================================================================
--- buckets/ssl_buckets.c	(revision 1467)
+++ buckets/ssl_buckets.c	(working copy)
@@ -1488,6 +1488,7 @@ const serf_bucket_type_t serf_bucket_type_ssl_encr
     serf_default_read_for_sendfile,
     serf_default_read_bucket,
     serf_ssl_peek,
+    serf_default_advise_length,
     serf_ssl_encrypt_destroy_and_data,
     serf_default_snapshot,
     serf_default_restore_snapshot,
@@ -1502,6 +1503,7 @@ const serf_bucket_type_t serf_bucket_type_ssl_decr
     serf_default_read_for_sendfile,
     serf_default_read_bucket,
     serf_ssl_peek,
+    serf_default_advise_length,
     serf_ssl_decrypt_destroy_and_data,
     serf_default_snapshot,
     serf_default_restore_snapshot,
Index: buckets/deflate_buckets.c
===================================================================
--- buckets/deflate_buckets.c	(revision 1462)
+++ buckets/deflate_buckets.c	(working copy)
@@ -372,6 +372,7 @@ const serf_bucket_type_t serf_bucket_type_deflate
     serf_default_read_for_sendfile,
     serf_default_read_bucket,
     serf_deflate_peek,
+    serf_default_advise_length,
     serf_deflate_destroy_and_data,
     serf_default_snapshot,
     serf_default_restore_snapshot,
Index: buckets/iovec_buckets.c
===================================================================
--- buckets/iovec_buckets.c	(revision 1462)
+++ buckets/iovec_buckets.c	(working copy)
@@ -186,6 +186,7 @@ const serf_bucket_type_t serf_bucket_type_iovec =
     serf_default_read_for_sendfile,
     serf_default_read_bucket,
     serf_iovec_peek,
+    serf_default_advise_length,
     serf_iovec_destroy,
     serf_iovec_snapshot,
     serf_iovec_restore_snapshot,
Index: buckets/chunk_buckets.c
===================================================================
--- buckets/chunk_buckets.c	(revision 1462)
+++ buckets/chunk_buckets.c	(working copy)
@@ -231,6 +231,7 @@ const serf_bucket_type_t serf_bucket_type_chunk =
     serf_default_read_for_sendfile,
     serf_default_read_bucket,
     serf_chunk_peek,
+    serf_default_advise_length,
     serf_chunk_destroy,
     serf_default_snapshot,
     serf_default_restore_snapshot,
Index: buckets/headers_buckets.c
===================================================================
--- buckets/headers_buckets.c	(revision 1462)
+++ buckets/headers_buckets.c	(working copy)
@@ -425,6 +425,7 @@ const serf_bucket_type_t serf_bucket_type_headers
     serf_default_read_for_sendfile,
     serf_default_read_bucket,
     serf_headers_peek,
+    serf_default_advise_length,
     serf_headers_destroy_and_data,
     serf_default_snapshot,
     serf_default_restore_snapshot,
Index: buckets/bwtp_buckets.c
===================================================================
--- buckets/bwtp_buckets.c	(revision 1462)
+++ buckets/bwtp_buckets.c	(working copy)
@@ -306,6 +306,7 @@ const serf_bucket_type_t serf_bucket_type_bwtp_fra
     serf_default_read_for_sendfile,
     serf_default_read_bucket,
     serf_bwtp_frame_peek,
+    serf_default_advise_length,
     serf_default_destroy_and_data,
     serf_default_snapshot,
     serf_default_restore_snapshot,
@@ -595,6 +596,7 @@ const serf_bucket_type_t serf_bucket_type_bwtp_inc
     serf_default_read_for_sendfile,
     serf_default_read_bucket,
     bwtp_incoming_peek,
+    serf_default_advise_length,
     bwtp_incoming_destroy_and_data,
     serf_default_snapshot,
     serf_default_restore_snapshot,

Mime
View raw message