]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
A first pass at the chunking filter. This is incredibly simple. As
authorRyan Bloom <rbb@apache.org>
Thu, 17 Aug 2000 00:54:03 +0000 (00:54 +0000)
committerRyan Bloom <rbb@apache.org>
Thu, 17 Aug 2000 00:54:03 +0000 (00:54 +0000)
bucket brigades are sent to this filter, it inserts the chunking header
at the front of the brigade.  When the filter sees an EOS bucket, it
adds the 0 chunking trailer.

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@86090 13f79535-47bb-0310-9956-ffa450edef68

modules/http/http_core.c
modules/http/http_protocol.c

index 0fd286e06502b662b74b88c31dfd500b2b25ab00..013f1bed19dbe271924e713b16f2a399f2cd28ca 100644 (file)
@@ -2915,6 +2915,54 @@ static int default_handler(request_rec *r)
     return OK;
 }
 
+/* This is an incredibly stupid chunking filter.  This will need to be somewhat
+ * smart about when it actually sends the data, but this implements some sort
+ * of chunking for right now.
+ */
+static int chunk_filter(ap_filter_t *f, ap_bucket_brigade *b)
+{
+    ap_bucket *dptr = b->head;
+    int len = 0;
+    int tempint = 0;
+    char lenstr[6];
+    int hit_eos = 0;
+
+    while (dptr) {
+        if (dptr->type == AP_BUCKET_EOS) {
+            hit_eos = 1;
+        } 
+        else {
+            len += dptr->length;
+        }
+        dptr = dptr->next;
+    }
+
+    apr_snprintf(lenstr, 6, "%x\r\n", len);
+    dptr = ap_bucket_transient_create(lenstr, 4, &tempint);
+    b->head->prev = dptr;
+    dptr->next = b->head;
+    b->head = dptr;
+    dptr = ap_bucket_heap_create("\r\n", 2, &tempint);
+    if (hit_eos) {
+        b->tail->prev->next = dptr;
+        dptr->prev = b->tail->prev;
+        b->tail->prev = dptr;
+        dptr->next = b->tail;
+    }
+    else {
+        ap_brigade_append_buckets(b, dptr);
+    }
+
+    if (hit_eos && len != 0) {
+        apr_snprintf(lenstr, 6, "0\r\n\r\n");
+        dptr = ap_bucket_transient_create(lenstr, 5, &tempint);
+        ap_brigade_append_buckets(b, dptr);
+    }
+        
+
+    return ap_pass_brigade(f->next, b);
+}
+
 /* Default filter.  This filter should almost always be used.  It's only job
  * is to send the headers if they haven't already been sent, and then send
  * the actual data.  To send the data, we create an iovec out of the bucket
@@ -3019,9 +3067,9 @@ static void register_hooks(void)
     /* define the CORE filter, then register a hook to insert it at
      * request-processing time.
      */
+    ap_hook_insert_filter(core_register_filter, NULL, NULL, AP_HOOK_MIDDLE);
     ap_register_filter("CORE", core_filter, AP_FTYPE_CONNECTION);
-    ap_hook_insert_filter(core_register_filter, NULL, NULL,
-                          AP_HOOK_REALLY_LAST);
+    ap_register_filter("CHUNK", chunk_filter, AP_FTYPE_CONNECTION);
 }
 
 API_VAR_EXPORT module core_module = {
index 7e6e42205131d45928a0233942fdffbf10a16b5d..4cebcce4e89c3570cf6f7168c4a58a379a183c27 100644 (file)
@@ -1863,6 +1863,7 @@ API_EXPORT(void) ap_send_http_header(request_rec *r)
     if (r->chunked) {
         apr_table_mergen(r->headers_out, "Transfer-Encoding", "chunked");
         apr_table_unset(r->headers_out, "Content-Length");
+        ap_add_filter("CHUNK", NULL, r);
     }
 
     if (r->byterange > 1)
@@ -1920,30 +1921,7 @@ API_EXPORT(void) ap_finalize_request_protocol(request_rec *r)
 {
     /* tell the filter chain there is no more content coming */
     end_output_stream(r);
-
-    if (r->chunked && !r->connection->aborted) {
-#ifdef APACHE_XLATE
-       AP_PUSH_OUTPUTCONVERSION_STATE(r->connection->client,
-                                       ap_hdrs_to_ascii);
-#endif
-        /*
-         * Turn off chunked encoding --- we can only do this once.
-         */
-        r->chunked = 0;
-        ap_bsetflag(r->connection->client, B_CHUNK, 0);
-
-        (void) checked_bputs("0" CRLF, r);
-
-        /* If we had footer "headers", we'd send them now */
-        /* ### these need to be added to allow message digests */
-
-        (void) checked_bputs(CRLF, r);
-
-#ifdef APACHE_XLATE
-       AP_POP_OUTPUTCONVERSION_STATE(r->connection->client);
-#endif /*APACHE_XLATE*/
     }
-}
 
 /* Here we deal with getting the request message body from the client.
  * Whether or not the request contains a body is signaled by the presence