1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include "http_core.h"
20 #include "util_fcgi.h"
22 /* we know core's module_index is 0 */
23 #undef APLOG_MODULE_INDEX
24 #define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX
26 AP_DECLARE(void) ap_fcgi_header_to_array(ap_fcgi_header *h,
29 a[AP_FCGI_HDR_VERSION_OFFSET] = h->version;
30 a[AP_FCGI_HDR_TYPE_OFFSET] = h->type;
31 a[AP_FCGI_HDR_REQUEST_ID_B1_OFFSET] = h->requestIdB1;
32 a[AP_FCGI_HDR_REQUEST_ID_B0_OFFSET] = h->requestIdB0;
33 a[AP_FCGI_HDR_CONTENT_LEN_B1_OFFSET] = h->contentLengthB1;
34 a[AP_FCGI_HDR_CONTENT_LEN_B0_OFFSET] = h->contentLengthB0;
35 a[AP_FCGI_HDR_PADDING_LEN_OFFSET] = h->paddingLength;
36 a[AP_FCGI_HDR_RESERVED_OFFSET] = h->reserved;
39 AP_DECLARE(void) ap_fcgi_header_from_array(ap_fcgi_header *h,
42 h->version = a[AP_FCGI_HDR_VERSION_OFFSET];
43 h->type = a[AP_FCGI_HDR_TYPE_OFFSET];
44 h->requestIdB1 = a[AP_FCGI_HDR_REQUEST_ID_B1_OFFSET];
45 h->requestIdB0 = a[AP_FCGI_HDR_REQUEST_ID_B0_OFFSET];
46 h->contentLengthB1 = a[AP_FCGI_HDR_CONTENT_LEN_B1_OFFSET];
47 h->contentLengthB0 = a[AP_FCGI_HDR_CONTENT_LEN_B0_OFFSET];
48 h->paddingLength = a[AP_FCGI_HDR_PADDING_LEN_OFFSET];
49 h->reserved = a[AP_FCGI_HDR_RESERVED_OFFSET];
52 AP_DECLARE(void) ap_fcgi_header_fields_from_array(unsigned char *version,
54 apr_uint16_t *request_id,
55 apr_uint16_t *content_len,
56 unsigned char *padding_len,
59 *version = a[AP_FCGI_HDR_VERSION_OFFSET];
60 *type = a[AP_FCGI_HDR_TYPE_OFFSET];
61 *request_id = (a[AP_FCGI_HDR_REQUEST_ID_B1_OFFSET] << 8)
62 + a[AP_FCGI_HDR_REQUEST_ID_B0_OFFSET];
63 *content_len = (a[AP_FCGI_HDR_CONTENT_LEN_B1_OFFSET] << 8)
64 + a[AP_FCGI_HDR_CONTENT_LEN_B0_OFFSET];
65 *padding_len = a[AP_FCGI_HDR_PADDING_LEN_OFFSET];
68 AP_DECLARE(void) ap_fcgi_begin_request_body_to_array(ap_fcgi_begin_request_body *h,
71 a[AP_FCGI_BRB_ROLEB1_OFFSET] = h->roleB1;
72 a[AP_FCGI_BRB_ROLEB0_OFFSET] = h->roleB0;
73 a[AP_FCGI_BRB_FLAGS_OFFSET] = h->flags;
74 a[AP_FCGI_BRB_RESERVED0_OFFSET] = h->reserved[0];
75 a[AP_FCGI_BRB_RESERVED1_OFFSET] = h->reserved[1];
76 a[AP_FCGI_BRB_RESERVED2_OFFSET] = h->reserved[2];
77 a[AP_FCGI_BRB_RESERVED3_OFFSET] = h->reserved[3];
78 a[AP_FCGI_BRB_RESERVED4_OFFSET] = h->reserved[4];
81 AP_DECLARE(void) ap_fcgi_fill_in_header(ap_fcgi_header *header,
83 apr_uint16_t request_id,
84 apr_uint16_t content_len,
85 unsigned char padding_len)
87 header->version = AP_FCGI_VERSION_1;
91 header->requestIdB1 = ((request_id >> 8) & 0xff);
92 header->requestIdB0 = ((request_id) & 0xff);
94 header->contentLengthB1 = ((content_len >> 8) & 0xff);
95 header->contentLengthB0 = ((content_len) & 0xff);
97 header->paddingLength = padding_len;
102 AP_DECLARE(void) ap_fcgi_fill_in_request_body(ap_fcgi_begin_request_body *brb,
106 brb->roleB1 = ((role >> 8) & 0xff);
107 brb->roleB0 = (role & 0xff);
109 brb->reserved[0] = 0;
110 brb->reserved[1] = 0;
111 brb->reserved[2] = 0;
112 brb->reserved[3] = 0;
113 brb->reserved[4] = 0;
116 AP_DECLARE(apr_size_t) ap_fcgi_encoded_env_len(apr_table_t *env,
120 const apr_array_header_t *envarr;
121 const apr_table_entry_t *elts;
122 apr_size_t envlen, actualenvlen;
125 if (maxlen > AP_FCGI_MAX_CONTENT_LEN) {
126 maxlen = AP_FCGI_MAX_CONTENT_LEN;
129 envarr = apr_table_elts(env);
130 elts = (const apr_table_entry_t *) envarr->elts;
132 /* envlen - speculative, may overflow the limit
133 * actualenvlen - len required without overflowing
135 envlen = actualenvlen = 0;
136 for (i = *starting_elem; i < envarr->nelts; ) {
137 apr_size_t keylen, vallen;
145 keylen = strlen(elts[i].key);
147 if (keylen >> 7 == 0) {
156 vallen = elts[i].val ? strlen(elts[i].val) : 0;
158 if (vallen >> 7 == 0) {
167 if (envlen > maxlen) {
171 actualenvlen = envlen;
179 AP_DECLARE(apr_status_t) ap_fcgi_encode_env(request_rec *r,
185 apr_status_t rv = APR_SUCCESS;
186 const apr_array_header_t *envarr;
187 const apr_table_entry_t *elts;
191 envarr = apr_table_elts(env);
192 elts = (const apr_table_entry_t *) envarr->elts;
196 for (i = *starting_elem; i < envarr->nelts; ) {
197 apr_size_t keylen, vallen;
205 keylen = strlen(elts[i].key);
207 if (keylen >> 7 == 0) {
209 rv = APR_ENOSPC; /* overflow */
212 itr[0] = keylen & 0xff;
218 rv = APR_ENOSPC; /* overflow */
221 itr[0] = ((keylen >> 24) & 0xff) | 0x80;
222 itr[1] = ((keylen >> 16) & 0xff);
223 itr[2] = ((keylen >> 8) & 0xff);
224 itr[3] = ((keylen) & 0xff);
229 vallen = elts[i].val ? strlen(elts[i].val) : 0;
231 if (vallen >> 7 == 0) {
233 rv = APR_ENOSPC; /* overflow */
236 itr[0] = vallen & 0xff;
242 rv = APR_ENOSPC; /* overflow */
245 itr[0] = ((vallen >> 24) & 0xff) | 0x80;
246 itr[1] = ((vallen >> 16) & 0xff);
247 itr[2] = ((vallen >> 8) & 0xff);
248 itr[3] = ((vallen) & 0xff);
253 if (buflen < keylen) {
254 rv = APR_ENOSPC; /* overflow */
257 memcpy(itr, elts[i].key, keylen);
261 if (buflen < vallen) {
262 rv = APR_ENOSPC; /* overflow */
267 memcpy(itr, elts[i].val, vallen);
271 if (buflen == vallen) {
274 break; /* filled up predicted space, as expected */
283 if (rv != APR_SUCCESS) {
284 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02492)
285 "ap_fcgi_encode_env: out of space "
286 "encoding environment");