]> granicus.if.org Git - apache/commitdiff
Handle the pathological case of a connect
authorRainer Jung <rjung@apache.org>
Sun, 14 Feb 2010 23:45:59 +0000 (23:45 +0000)
committerRainer Jung <rjung@apache.org>
Sun, 14 Feb 2010 23:45:59 +0000 (23:45 +0000)
backend that sends us an unexpectedly huge response.

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

modules/proxy/proxy_util.c

index ca44d073f6c56c312eb119b2780a5e55e6b20fb7..b3c5cb4e61d070607bb3169ebdddced6bf651b8f 100644 (file)
@@ -2301,7 +2301,10 @@ static apr_status_t send_http_connect(proxy_conn_rec *backend,
 {
     int status;
     apr_size_t nbytes;
+    apr_size_t left;
+    int complete = 0;
     char buffer[HUGE_STRING_LEN];
+    char drain_buffer[HUGE_STRING_LEN];
     forward_info *forward = (forward_info *)backend->forward;
     int len = 0;
 
@@ -2327,16 +2330,31 @@ static apr_status_t send_http_connect(proxy_conn_rec *backend,
     apr_socket_send(backend->sock, buffer, &nbytes);
 
     /* Receive the whole CONNECT response */
-    nbytes = sizeof(buffer) - 1;
-    status = apr_socket_recv(backend->sock, buffer, &nbytes);
-    while (status == APR_SUCCESS) {
+    left = sizeof(buffer) - 1;
+    /* Read until we find the end of the headers or run out of buffer */
+    do {
+        nbytes = left;
+        status = apr_socket_recv(backend->sock, buffer + len, &nbytes);
         len += nbytes;
+        left -= nbytes;
         buffer[len] = '\0';
-        if (strstr(buffer, "\r\n\r\n") != NULL) {
+        if (strstr(buffer + len - nbytes, "\r\n\r\n") != NULL) {
+            complete = 1;
             break;
         }
-        nbytes = sizeof(buffer) - 1 - len;
-        status = apr_socket_recv(backend->sock, buffer + len, &nbytes);
+    } while (status == APR_SUCCESS && left > 0);
+    /* Drain what's left */
+    if (!complete) {
+        nbytes = sizeof(drain_buffer) - 1;
+        while (status == APR_SUCCESS && nbytes) {
+            status = apr_socket_recv(backend->sock, drain_buffer, &nbytes);
+            buffer[nbytes] = '\0';
+            nbytes = sizeof(drain_buffer) - 1;
+            if (strstr(drain_buffer, "\r\n\r\n") != NULL) {
+                complete = 1;
+                break;
+            }
+        }
     }
 
     /* Check for HTTP_OK response status */