[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."