|
Packit |
90a5c9 |
/* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
Packit |
90a5c9 |
* contributor license agreements. See the NOTICE file distributed with
|
|
Packit |
90a5c9 |
* this work for additional information regarding copyright ownership.
|
|
Packit |
90a5c9 |
* The ASF licenses this file to You under the Apache License, Version 2.0
|
|
Packit |
90a5c9 |
* (the "License"); you may not use this file except in compliance with
|
|
Packit |
90a5c9 |
* the License. You may obtain a copy of the License at
|
|
Packit |
90a5c9 |
*
|
|
Packit |
90a5c9 |
* http://www.apache.org/licenses/LICENSE-2.0
|
|
Packit |
90a5c9 |
*
|
|
Packit |
90a5c9 |
* Unless required by applicable law or agreed to in writing, software
|
|
Packit |
90a5c9 |
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
Packit |
90a5c9 |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
Packit |
90a5c9 |
* See the License for the specific language governing permissions and
|
|
Packit |
90a5c9 |
* limitations under the License.
|
|
Packit |
90a5c9 |
*/
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
#include "httpd.h"
|
|
Packit |
90a5c9 |
#include "http_core.h"
|
|
Packit |
90a5c9 |
#include "http_log.h"
|
|
Packit |
90a5c9 |
#include "util_fcgi.h"
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
/* we know core's module_index is 0 */
|
|
Packit |
90a5c9 |
#undef APLOG_MODULE_INDEX
|
|
Packit |
90a5c9 |
#define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
AP_DECLARE(void) ap_fcgi_header_to_array(ap_fcgi_header *h,
|
|
Packit |
90a5c9 |
unsigned char a[])
|
|
Packit |
90a5c9 |
{
|
|
Packit |
90a5c9 |
a[AP_FCGI_HDR_VERSION_OFFSET] = h->version;
|
|
Packit |
90a5c9 |
a[AP_FCGI_HDR_TYPE_OFFSET] = h->type;
|
|
Packit |
90a5c9 |
a[AP_FCGI_HDR_REQUEST_ID_B1_OFFSET] = h->requestIdB1;
|
|
Packit |
90a5c9 |
a[AP_FCGI_HDR_REQUEST_ID_B0_OFFSET] = h->requestIdB0;
|
|
Packit |
90a5c9 |
a[AP_FCGI_HDR_CONTENT_LEN_B1_OFFSET] = h->contentLengthB1;
|
|
Packit |
90a5c9 |
a[AP_FCGI_HDR_CONTENT_LEN_B0_OFFSET] = h->contentLengthB0;
|
|
Packit |
90a5c9 |
a[AP_FCGI_HDR_PADDING_LEN_OFFSET] = h->paddingLength;
|
|
Packit |
90a5c9 |
a[AP_FCGI_HDR_RESERVED_OFFSET] = h->reserved;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
AP_DECLARE(void) ap_fcgi_header_from_array(ap_fcgi_header *h,
|
|
Packit |
90a5c9 |
unsigned char a[])
|
|
Packit |
90a5c9 |
{
|
|
Packit |
90a5c9 |
h->version = a[AP_FCGI_HDR_VERSION_OFFSET];
|
|
Packit |
90a5c9 |
h->type = a[AP_FCGI_HDR_TYPE_OFFSET];
|
|
Packit |
90a5c9 |
h->requestIdB1 = a[AP_FCGI_HDR_REQUEST_ID_B1_OFFSET];
|
|
Packit |
90a5c9 |
h->requestIdB0 = a[AP_FCGI_HDR_REQUEST_ID_B0_OFFSET];
|
|
Packit |
90a5c9 |
h->contentLengthB1 = a[AP_FCGI_HDR_CONTENT_LEN_B1_OFFSET];
|
|
Packit |
90a5c9 |
h->contentLengthB0 = a[AP_FCGI_HDR_CONTENT_LEN_B0_OFFSET];
|
|
Packit |
90a5c9 |
h->paddingLength = a[AP_FCGI_HDR_PADDING_LEN_OFFSET];
|
|
Packit |
90a5c9 |
h->reserved = a[AP_FCGI_HDR_RESERVED_OFFSET];
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
AP_DECLARE(void) ap_fcgi_header_fields_from_array(unsigned char *version,
|
|
Packit |
90a5c9 |
unsigned char *type,
|
|
Packit |
90a5c9 |
apr_uint16_t *request_id,
|
|
Packit |
90a5c9 |
apr_uint16_t *content_len,
|
|
Packit |
90a5c9 |
unsigned char *padding_len,
|
|
Packit |
90a5c9 |
unsigned char a[])
|
|
Packit |
90a5c9 |
{
|
|
Packit |
90a5c9 |
*version = a[AP_FCGI_HDR_VERSION_OFFSET];
|
|
Packit |
90a5c9 |
*type = a[AP_FCGI_HDR_TYPE_OFFSET];
|
|
Packit |
90a5c9 |
*request_id = (a[AP_FCGI_HDR_REQUEST_ID_B1_OFFSET] << 8)
|
|
Packit |
90a5c9 |
+ a[AP_FCGI_HDR_REQUEST_ID_B0_OFFSET];
|
|
Packit |
90a5c9 |
*content_len = (a[AP_FCGI_HDR_CONTENT_LEN_B1_OFFSET] << 8)
|
|
Packit |
90a5c9 |
+ a[AP_FCGI_HDR_CONTENT_LEN_B0_OFFSET];
|
|
Packit |
90a5c9 |
*padding_len = a[AP_FCGI_HDR_PADDING_LEN_OFFSET];
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
AP_DECLARE(void) ap_fcgi_begin_request_body_to_array(ap_fcgi_begin_request_body *h,
|
|
Packit |
90a5c9 |
unsigned char a[])
|
|
Packit |
90a5c9 |
{
|
|
Packit |
90a5c9 |
a[AP_FCGI_BRB_ROLEB1_OFFSET] = h->roleB1;
|
|
Packit |
90a5c9 |
a[AP_FCGI_BRB_ROLEB0_OFFSET] = h->roleB0;
|
|
Packit |
90a5c9 |
a[AP_FCGI_BRB_FLAGS_OFFSET] = h->flags;
|
|
Packit |
90a5c9 |
a[AP_FCGI_BRB_RESERVED0_OFFSET] = h->reserved[0];
|
|
Packit |
90a5c9 |
a[AP_FCGI_BRB_RESERVED1_OFFSET] = h->reserved[1];
|
|
Packit |
90a5c9 |
a[AP_FCGI_BRB_RESERVED2_OFFSET] = h->reserved[2];
|
|
Packit |
90a5c9 |
a[AP_FCGI_BRB_RESERVED3_OFFSET] = h->reserved[3];
|
|
Packit |
90a5c9 |
a[AP_FCGI_BRB_RESERVED4_OFFSET] = h->reserved[4];
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
AP_DECLARE(void) ap_fcgi_fill_in_header(ap_fcgi_header *header,
|
|
Packit |
90a5c9 |
unsigned char type,
|
|
Packit |
90a5c9 |
apr_uint16_t request_id,
|
|
Packit |
90a5c9 |
apr_uint16_t content_len,
|
|
Packit |
90a5c9 |
unsigned char padding_len)
|
|
Packit |
90a5c9 |
{
|
|
Packit |
90a5c9 |
header->version = AP_FCGI_VERSION_1;
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
header->type = type;
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
header->requestIdB1 = ((request_id >> 8) & 0xff);
|
|
Packit |
90a5c9 |
header->requestIdB0 = ((request_id) & 0xff);
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
header->contentLengthB1 = ((content_len >> 8) & 0xff);
|
|
Packit |
90a5c9 |
header->contentLengthB0 = ((content_len) & 0xff);
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
header->paddingLength = padding_len;
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
header->reserved = 0;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
AP_DECLARE(void) ap_fcgi_fill_in_request_body(ap_fcgi_begin_request_body *brb,
|
|
Packit |
90a5c9 |
int role,
|
|
Packit |
90a5c9 |
unsigned char flags)
|
|
Packit |
90a5c9 |
{
|
|
Packit |
90a5c9 |
brb->roleB1 = ((role >> 8) & 0xff);
|
|
Packit |
90a5c9 |
brb->roleB0 = (role & 0xff);
|
|
Packit |
90a5c9 |
brb->flags = flags;
|
|
Packit |
90a5c9 |
brb->reserved[0] = 0;
|
|
Packit |
90a5c9 |
brb->reserved[1] = 0;
|
|
Packit |
90a5c9 |
brb->reserved[2] = 0;
|
|
Packit |
90a5c9 |
brb->reserved[3] = 0;
|
|
Packit |
90a5c9 |
brb->reserved[4] = 0;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
AP_DECLARE(apr_size_t) ap_fcgi_encoded_env_len(apr_table_t *env,
|
|
Packit |
90a5c9 |
apr_size_t maxlen,
|
|
Packit |
90a5c9 |
int *starting_elem)
|
|
Packit |
90a5c9 |
{
|
|
Packit |
90a5c9 |
const apr_array_header_t *envarr;
|
|
Packit |
90a5c9 |
const apr_table_entry_t *elts;
|
|
Packit |
90a5c9 |
apr_size_t envlen, actualenvlen;
|
|
Packit |
90a5c9 |
int i;
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
if (maxlen > AP_FCGI_MAX_CONTENT_LEN) {
|
|
Packit |
90a5c9 |
maxlen = AP_FCGI_MAX_CONTENT_LEN;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
envarr = apr_table_elts(env);
|
|
Packit |
90a5c9 |
elts = (const apr_table_entry_t *) envarr->elts;
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
/* envlen - speculative, may overflow the limit
|
|
Packit |
90a5c9 |
* actualenvlen - len required without overflowing
|
|
Packit |
90a5c9 |
*/
|
|
Packit |
90a5c9 |
envlen = actualenvlen = 0;
|
|
Packit |
90a5c9 |
for (i = *starting_elem; i < envarr->nelts; ) {
|
|
Packit |
90a5c9 |
apr_size_t keylen, vallen;
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
if (!elts[i].key) {
|
|
Packit |
90a5c9 |
(*starting_elem)++;
|
|
Packit |
90a5c9 |
i++;
|
|
Packit |
90a5c9 |
continue;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
keylen = strlen(elts[i].key);
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
if (keylen >> 7 == 0) {
|
|
Packit |
90a5c9 |
envlen += 1;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
else {
|
|
Packit |
90a5c9 |
envlen += 4;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
envlen += keylen;
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
vallen = elts[i].val ? strlen(elts[i].val) : 0;
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
if (vallen >> 7 == 0) {
|
|
Packit |
90a5c9 |
envlen += 1;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
else {
|
|
Packit |
90a5c9 |
envlen += 4;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
envlen += vallen;
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
if (envlen > maxlen) {
|
|
Packit |
90a5c9 |
break;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
actualenvlen = envlen;
|
|
Packit |
90a5c9 |
(*starting_elem)++;
|
|
Packit |
90a5c9 |
i++;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
return actualenvlen;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
AP_DECLARE(apr_status_t) ap_fcgi_encode_env(request_rec *r,
|
|
Packit |
90a5c9 |
apr_table_t *env,
|
|
Packit |
90a5c9 |
void *buffer,
|
|
Packit |
90a5c9 |
apr_size_t buflen,
|
|
Packit |
90a5c9 |
int *starting_elem)
|
|
Packit |
90a5c9 |
{
|
|
Packit |
90a5c9 |
apr_status_t rv = APR_SUCCESS;
|
|
Packit |
90a5c9 |
const apr_array_header_t *envarr;
|
|
Packit |
90a5c9 |
const apr_table_entry_t *elts;
|
|
Packit |
90a5c9 |
char *itr;
|
|
Packit |
90a5c9 |
int i;
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
envarr = apr_table_elts(env);
|
|
Packit |
90a5c9 |
elts = (const apr_table_entry_t *) envarr->elts;
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
itr = buffer;
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
for (i = *starting_elem; i < envarr->nelts; ) {
|
|
Packit |
90a5c9 |
apr_size_t keylen, vallen;
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
if (!elts[i].key) {
|
|
Packit |
90a5c9 |
(*starting_elem)++;
|
|
Packit |
90a5c9 |
i++;
|
|
Packit |
90a5c9 |
continue;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
keylen = strlen(elts[i].key);
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
if (keylen >> 7 == 0) {
|
|
Packit |
90a5c9 |
if (buflen < 1) {
|
|
Packit |
90a5c9 |
rv = APR_ENOSPC; /* overflow */
|
|
Packit |
90a5c9 |
break;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
itr[0] = keylen & 0xff;
|
|
Packit |
90a5c9 |
itr += 1;
|
|
Packit |
90a5c9 |
buflen -= 1;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
else {
|
|
Packit |
90a5c9 |
if (buflen < 4) {
|
|
Packit |
90a5c9 |
rv = APR_ENOSPC; /* overflow */
|
|
Packit |
90a5c9 |
break;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
itr[0] = ((keylen >> 24) & 0xff) | 0x80;
|
|
Packit |
90a5c9 |
itr[1] = ((keylen >> 16) & 0xff);
|
|
Packit |
90a5c9 |
itr[2] = ((keylen >> 8) & 0xff);
|
|
Packit |
90a5c9 |
itr[3] = ((keylen) & 0xff);
|
|
Packit |
90a5c9 |
itr += 4;
|
|
Packit |
90a5c9 |
buflen -= 4;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
vallen = elts[i].val ? strlen(elts[i].val) : 0;
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
if (vallen >> 7 == 0) {
|
|
Packit |
90a5c9 |
if (buflen < 1) {
|
|
Packit |
90a5c9 |
rv = APR_ENOSPC; /* overflow */
|
|
Packit |
90a5c9 |
break;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
itr[0] = vallen & 0xff;
|
|
Packit |
90a5c9 |
itr += 1;
|
|
Packit |
90a5c9 |
buflen -= 1;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
else {
|
|
Packit |
90a5c9 |
if (buflen < 4) {
|
|
Packit |
90a5c9 |
rv = APR_ENOSPC; /* overflow */
|
|
Packit |
90a5c9 |
break;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
itr[0] = ((vallen >> 24) & 0xff) | 0x80;
|
|
Packit |
90a5c9 |
itr[1] = ((vallen >> 16) & 0xff);
|
|
Packit |
90a5c9 |
itr[2] = ((vallen >> 8) & 0xff);
|
|
Packit |
90a5c9 |
itr[3] = ((vallen) & 0xff);
|
|
Packit |
90a5c9 |
itr += 4;
|
|
Packit |
90a5c9 |
buflen -= 4;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
if (buflen < keylen) {
|
|
Packit |
90a5c9 |
rv = APR_ENOSPC; /* overflow */
|
|
Packit |
90a5c9 |
break;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
memcpy(itr, elts[i].key, keylen);
|
|
Packit |
90a5c9 |
itr += keylen;
|
|
Packit |
90a5c9 |
buflen -= keylen;
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
if (buflen < vallen) {
|
|
Packit |
90a5c9 |
rv = APR_ENOSPC; /* overflow */
|
|
Packit |
90a5c9 |
break;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
if (elts[i].val) {
|
|
Packit |
90a5c9 |
memcpy(itr, elts[i].val, vallen);
|
|
Packit |
90a5c9 |
itr += vallen;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
if (buflen == vallen) {
|
|
Packit |
90a5c9 |
(*starting_elem)++;
|
|
Packit |
90a5c9 |
i++;
|
|
Packit |
90a5c9 |
break; /* filled up predicted space, as expected */
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
buflen -= vallen;
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
(*starting_elem)++;
|
|
Packit |
90a5c9 |
i++;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
if (rv != APR_SUCCESS) {
|
|
Packit |
90a5c9 |
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02492)
|
|
Packit |
90a5c9 |
"ap_fcgi_encode_env: out of space "
|
|
Packit |
90a5c9 |
"encoding environment");
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
return rv;
|
|
Packit |
90a5c9 |
}
|