Hi,

I have arranged the logic to send the request and the body to Tomcat, now it works for both chunked and not-chunked.

What is not yet working is when the Tomcat starts to send data before having all the body and then reads a little more body data.

Cheers

Jean-Frederic
Index: proxy_ajp.c
===================================================================
RCS file: /home/cvspublic/httpd-2.0/modules/proxy/proxy_ajp.c,v
retrieving revision 1.13
diff -u -r1.13 proxy_ajp.c
--- proxy_ajp.c 11 Aug 2004 23:08:04 -0000      1.13
+++ proxy_ajp.c 13 Aug 2004 16:11:00 -0000
@@ -107,6 +107,10 @@
     apr_status_t status;
     int result;
     apr_bucket_brigade *input_brigade;
+    ajp_msg_t *msg;
+    apr_size_t bufsiz;
+    char *buff;
+    const char *tenc;
 
     /*
      * Send the AJP request to the remote server
@@ -123,51 +127,59 @@
         return HTTP_SERVICE_UNAVAILABLE;
     }
 
-    /* read the first bloc of data */
-    input_brigade = apr_brigade_create(p, r->connection->bucket_alloc);
-    status = ap_get_brigade(r->input_filters, input_brigade,
-                            AP_MODE_READBYTES, APR_BLOCK_READ,
-                            AJP13_MAX_SEND_BODY_SZ);
- 
+    /* allocate an AJP message to store the data of the buckets */
+    status = ajp_alloc_data_msg(r, &buff, &bufsiz, &msg);
     if (status != APR_SUCCESS) {
         ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
-                     "proxy: ap_get_brigade failed");
-        apr_brigade_destroy(input_brigade);
-        return HTTP_INTERNAL_SERVER_ERROR;
+                     "proxy: ajp_alloc_data_msg failed");
+        return status;
     }
-
-    /* have something */
-    if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(input_brigade))) {
+    /* read the first bloc of data */
+    input_brigade = apr_brigade_create(p, r->connection->bucket_alloc);
+    tenc = apr_table_get(r->headers_in, "Transfer-Encoding");
+    if (tenc && strcasecmp(tenc, "chunked")==0) {
+         /* The AJP protocol does not want body data yet */
         ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
-                     "proxy: APR_BUCKET_IS_EOS");
-    }
-
-    if (1) { /* XXXX only when something to send ? */
-        ajp_msg_t *msg;
-        apr_size_t bufsiz;
-        char *buff;
-        status = ajp_alloc_data_msg(r, &buff, &bufsiz, &msg);
+                     "proxy: request is chunked");
+    } else {
+        status = ap_get_brigade(r->input_filters, input_brigade,
+                                AP_MODE_READBYTES, APR_BLOCK_READ,
+                                AJP13_MAX_SEND_BODY_SZ);
+ 
         if (status != APR_SUCCESS) {
-            return status;
+            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
+                         "proxy: ap_get_brigade failed");
+            apr_brigade_destroy(input_brigade);
+            return HTTP_INTERNAL_SERVER_ERROR;
         }
+
+        /* have something */
+        if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(input_brigade))) {
+            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
+                         "proxy: APR_BUCKET_IS_EOS");
+        }
+
+        /* Try to send something */
         ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
                      "proxy: data to read (max %d at %08x)", bufsiz, buff);
 
-        /* XXXX calls apr_brigade_flatten... */
         status = apr_brigade_flatten(input_brigade, buff, &bufsiz);
         if (status != APR_SUCCESS) {
-             ap_log_error(APLOG_MARK, APLOG_ERR, status, r->server,
-                     "proxy: apr_brigade_flatten");
+            apr_brigade_destroy(input_brigade);
+            ap_log_error(APLOG_MARK, APLOG_ERR, status, r->server,
+                         "proxy: apr_brigade_flatten");
             return HTTP_INTERNAL_SERVER_ERROR;
         }
+        apr_brigade_cleanup(input_brigade);
 
         ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
                      "proxy: got %d byte of data", bufsiz);
         if (bufsiz > 0) {
             status = ajp_send_data_msg(conn->sock, r, msg, bufsiz);
             if (status != APR_SUCCESS) {
+                apr_brigade_destroy(input_brigade);
                 ap_log_error(APLOG_MARK, APLOG_ERR, status, r->server,
-                             "proxy: request failed to %pI (%s)",
+                             "proxy: send failed to %pI (%s)",
                              conn->worker->cp->addr,
                              conn->worker->hostname);
                 return HTTP_SERVICE_UNAVAILABLE;
@@ -179,8 +191,9 @@
     status = ajp_read_header(conn->sock, r,
                              (ajp_msg_t **)&(conn->data));
     if (status != APR_SUCCESS) {
+        apr_brigade_destroy(input_brigade);
         ap_log_error(APLOG_MARK, APLOG_ERR, status, r->server,
-                     "proxy: request failed to %pI (%s)",
+                     "proxy: read response failed from %pI (%s)",
                      conn->worker->cp->addr,
                      conn->worker->hostname);
         return HTTP_SERVICE_UNAVAILABLE;
@@ -188,26 +201,76 @@
 
     /* parse the reponse */
     result = ajp_parse_type(r, conn->data);
+    
+    bufsiz = AJP13_MAX_SEND_BODY_SZ;
+    while (result == CMD_AJP13_GET_BODY_CHUNK && bufsiz != 0) {
+        if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(input_brigade))) {
+            /* That is the end */
+            bufsiz = 0;
+            ap_log_error(APLOG_MARK, APLOG_DEBUG, status, r->server,
+                         "proxy: APR_BUCKET_IS_EOS");
+        } else {
+            status = ap_get_brigade(r->input_filters, input_brigade,
+                                    AP_MODE_READBYTES, APR_BLOCK_READ,
+                                    AJP13_MAX_SEND_BODY_SZ);
+            if (status != APR_SUCCESS) {
+                ap_log_error(APLOG_MARK, APLOG_DEBUG, status, r->server,
+                             "ap_get_brigade failed");
+                break;
+            }
+            bufsiz = AJP13_MAX_SEND_BODY_SZ;
+            status = apr_brigade_flatten(input_brigade, buff, &bufsiz);
+            apr_brigade_cleanup(input_brigade);
+            if (status != APR_SUCCESS) {
+                ap_log_error(APLOG_MARK, APLOG_DEBUG, status, r->server,
+                             "apr_brigade_flatten failed");
+                break;
+            }
+        }
+
+        ajp_msg_reset(msg); /* will go in ajp_send_data_msg */
+        status = ajp_send_data_msg(conn->sock, r, msg, bufsiz);
+        if (status != APR_SUCCESS) {
+            ap_log_error(APLOG_MARK, APLOG_DEBUG, status, r->server,
+                         "ajp_send_data_msg failed");
+            break;
+        }
+        /* read the response */
+        status = ajp_read_header(conn->sock, r,
+                                 (ajp_msg_t **)&(conn->data));
+        if (status != APR_SUCCESS) {
+            ap_log_error(APLOG_MARK, APLOG_DEBUG, status, r->server,
+                         "ajp_read_header failed");
+            break;
+        }
+       result = ajp_parse_type(r, conn->data);
+    }
+    apr_brigade_destroy(input_brigade);
+
+    if (status != APR_SUCCESS) {
+        ap_log_error(APLOG_MARK, APLOG_ERR, status, r->server,
+                     "proxy: send body failed to %pI (%s)",
+                     conn->worker->cp->addr,
+                     conn->worker->hostname);
+        return HTTP_SERVICE_UNAVAILABLE;
+    }
+
+    /* Nice we have answer to send to the client */
     if (result == CMD_AJP13_SEND_HEADERS) {
         ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
                      "proxy: got response from %pI (%s)",
                      conn->worker->cp->addr,
                      conn->worker->hostname);
-        return HTTP_SERVICE_UNAVAILABLE;
+        return OK;
     }
 
-    /* XXXX: need logic to send the rest of the data */
-/*
-    status = ajp_send_data(p_conn->sock,r);
-    if (status != APR_SUCCESS) {
-        ap_log_error(APLOG_MARK, APLOG_ERR, status, r->server,
-                     "proxy: request failed to %pI (%s)",
-                     p_conn->addr, p_conn->name);
-        return status;
-    }
- */
+    ap_log_error(APLOG_MARK, APLOG_ERR, status, r->server,
+                 "proxy: got bad response (%d) from %pI (%s)",
+                 result,
+                 conn->worker->cp->addr,
+                 conn->worker->hostname);
 
-    return OK;
+    return HTTP_SERVICE_UNAVAILABLE;
 }
 
 /*
@@ -261,7 +324,7 @@
     if (status != APR_SUCCESS) {
         ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                       "proxy: error reading headers from remote "
-                      "server %s:%d",
+                      "server %pI:%s",
                       backend->worker->cp->addr,
                       backend->worker->hostname);
         return ap_proxyerror(r, HTTP_BAD_GATEWAY,

Reply via email to