[EMAIL PROTECTED] wrote:
> 
> Author: rooneg
> Date: Sat Jan  7 13:37:40 2006
> New Revision: 366926
> 

Weird... Just yesterday I did the below, which allows us to
keep using FCGI headers where "natural" yet also resolves the
struct stuff.... I think the below is "simpler" since it
isolates things a bit.


Index: modules/proxy/fcgi_protocol.h
===================================================================
--- modules/proxy/fcgi_protocol.h       (revision 366724)
+++ modules/proxy/fcgi_protocol.h       (working copy)
@@ -77,6 +77,7 @@
     unsigned char reserved[5];
 } fcgi_begin_request_body;
 
+typedef unsigned char fcgi_array;
 
 #endif /* FCGI_PROTOCOL_H */
 /** @} */
Index: modules/proxy/mod_proxy_fcgi.c
===================================================================
--- modules/proxy/mod_proxy_fcgi.c      (revision 366724)
+++ modules/proxy/mod_proxy_fcgi.c      (working copy)
@@ -20,6 +20,47 @@
 module AP_MODULE_DECLARE_DATA proxy_fcgi_module;
 
 /*
+ * The below 3 functions serve to map the FCGI structs
+ * back and forth between an 8 byte array. We do this to avoid
+ * any potential padding issues when we send or read these
+ * structures
+ */
+static void fcgi_header_to_array(fcgi_header *h, fcgi_array a[])
+{
+    a[0] = h->version;
+    a[1] = h->type;
+    a[2] = h->requestIdB1;
+    a[3] = h->requestIdB0;
+    a[4] = h->contentLengthB1;
+    a[5] = h->contentLengthB0;
+    a[6] = h->paddingLength;
+    a[7] = h->reserved;
+}
+
+static void fcgi_header_from_array(fcgi_header *h, fcgi_array a[])
+{
+    h->version = a[0];
+    h->type = a[1];
+    h->requestIdB1 = a[2];
+    h->requestIdB0 = a[3];
+    h->contentLengthB1 = a[4];
+    h->contentLengthB0 = a[5];
+    h->paddingLength = a[6];
+    h->reserved = a[7];
+}
+
+static void fcgi_begin_request_body_to_array(fcgi_begin_request_body *h, 
fcgi_array a[])
+{
+    a[0] = h->roleB1;
+    a[1] = h->roleB0;
+    a[2] = h->flags;
+    a[3] = h->reserved[0];
+    a[4] = h->reserved[1];
+    a[5] = h->reserved[2];
+    a[6] = h->reserved[3];
+    a[7] = h->reserved[4];
+}
+/*
  * Canonicalise http-like URLs.
  * scheme is the scheme for the URL
  * url is the URL starting with the first '/'
@@ -105,7 +146,11 @@
 {
     struct iovec vec[2];
     fcgi_header header;
+    fcgi_array farray[FCGI_HEADER_LEN];
+    
     fcgi_begin_request_body brb;
+    fcgi_array abrb[FCGI_HEADER_LEN];
+    
     apr_size_t len;
 
     fill_in_header(&header, FCGI_BEGIN_REQUEST, request_id);
@@ -117,10 +162,13 @@
     brb.roleB0 = ((FCGI_RESPONDER) & 0xff); 
     brb.flags = FCGI_KEEP_CONN;
 
-    vec[0].iov_base = &header;
-    vec[0].iov_len = sizeof(header);
-    vec[1].iov_base = &brb;
-    vec[1].iov_len = sizeof(brb);
+    fcgi_header_to_array(&header, farray);
+    fcgi_begin_request_body_to_array(&brb, abrb);
+    
+    vec[0].iov_base = farray;
+    vec[0].iov_len = sizeof(farray);
+    vec[1].iov_base = abrb;
+    vec[1].iov_len = sizeof(abrb);
 
     return apr_socket_sendv(conn->sock, vec, 2, &len);
 }
@@ -132,6 +180,7 @@
     const apr_table_entry_t *elts;
     struct iovec vec[2];
     fcgi_header header;
+    fcgi_array farray[FCGI_HEADER_LEN];
     apr_size_t bodylen;
     char *body, *itr;
     apr_status_t rv;
@@ -239,8 +288,10 @@
     header.contentLengthB0 = ((bodylen) & 0xff); 
     header.paddingLength = 0;
 
-    vec[0].iov_base = &header;
-    vec[0].iov_len = sizeof(header);
+    fcgi_header_to_array(&header, farray);
+
+    vec[0].iov_base = farray;
+    vec[0].iov_len = sizeof(farray);
     vec[1].iov_base = body;
     vec[1].iov_len = bodylen;
 
@@ -254,9 +305,11 @@
     header.contentLengthB0 = 0;
     header.paddingLength = 0;
 
-    vec[0].iov_base = &header;
-    vec[0].iov_len = sizeof(header);
+    fcgi_header_to_array(&header, farray);
 
+    vec[0].iov_base = farray;
+    vec[0].iov_len = sizeof(farray);
+
     return apr_socket_sendv(conn->sock, vec, 1, &len);
 }
 
@@ -381,6 +434,8 @@
     conn_rec *c = r->connection;
     struct iovec vec[2];
     fcgi_header header;
+    fcgi_array farray[FCGI_HEADER_LEN];
+
     apr_pollfd_t pfd;
 
     fill_in_header(&header, FCGI_STDIN, request_id);
@@ -431,8 +486,10 @@
             header.contentLengthB1 = ((writebuflen >> 8) & 0xff);
             header.contentLengthB0 = ((writebuflen) & 0xff); 
 
-            vec[0].iov_base = &header;
-            vec[0].iov_len = sizeof(header);
+            fcgi_header_to_array(&header, farray);
+
+            vec[0].iov_base = farray;
+            vec[0].iov_len = sizeof(farray);
             vec[1].iov_base = writebuf;
             vec[1].iov_len = writebuflen;
 
@@ -453,9 +510,11 @@
                 header.contentLengthB1 = 0;
                 header.contentLengthB0 = 0;
 
-                vec[0].iov_base = &header;
-                vec[0].iov_len = sizeof(header);
+                fcgi_header_to_array(&header, farray);
 
+                vec[0].iov_base = farray;
+                vec[0].iov_len = sizeof(farray);
+
                 rv = apr_socket_sendv(conn->sock, vec, 1, &len);
             }
         }
@@ -470,26 +529,22 @@
             int rid, type;
             apr_bucket *b;
             char plen;
-            /*
-             * below mapped to fcgi_header layout. We
-             * use a unsigned char array to ensure the
-             * shifts are correct and avoid any potential
-             * internal padding when using structs.
-             */
-            unsigned char fheader[FCGI_HEADER_LEN];
+            fcgi_array farray[FCGI_HEADER_LEN];
+            fcgi_header fheader;
 
-            memset(fheader, 0, FCGI_HEADER_LEN);
+
+            memset(farray, 0, FCGI_HEADER_LEN);
             memset(readbuf, 0, sizeof(readbuf));
 
             /* First, we grab the header... */
             readbuflen = FCGI_HEADER_LEN;
 
-            rv = apr_socket_recv(conn->sock, (char *) fheader, &readbuflen);
+            rv = apr_socket_recv(conn->sock, (char *) farray, &readbuflen);
             if (rv != APR_SUCCESS) {
                 break;
             }
 
-            dump_header_to_log(r, fheader, readbuflen);
+            dump_header_to_log(r, farray, readbuflen);
 
             if (readbuflen != FCGI_HEADER_LEN) {
                 ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
@@ -500,17 +555,19 @@
                 break;
             }
 
-            if (fheader[0] != FCGI_VERSION) {
+            fcgi_header_from_array(&fheader, farray);
+
+            if (fheader.version != FCGI_VERSION) {
                 ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
                              "proxy: FCGI: Got bogus version %d",
-                             (int) fheader[0]);
+                             (int) fheader.version);
                 rv = APR_EINVAL;
                 break;
             }
 
-            type = fheader[1];
+            type = fheader.type;
 
-            rid = (fheader[2] << 8) | fheader[3];
+            rid = (fheader.requestIdB1 << 8) | fheader.requestIdB0;
 
             if (rid != request_id) {
                 ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
@@ -522,9 +579,9 @@
 #endif
             }
 
-            clen = (fheader[4] << 8) | fheader[5];
+            clen = (fheader.contentLengthB1 << 8) | fheader.contentLengthB0;
 
-            plen = fheader[6];
+            plen = fheader.paddingLength;
 
 recv_again:
             if (clen > sizeof(readbuf) - 1) {
-- 
===========================================================================
   Jim Jagielski   [|]   [EMAIL PROTECTED]   [|]   http://www.jaguNET.com/
            "If you can dodge a wrench, you can dodge a ball."

Reply via email to