util_script.c revision 886cd69ebf69e990dbc365be87ff8ea7cd681904
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny/* ====================================================================
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny * The Apache Software License, Version 1.1
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny *
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny * Copyright (c) 2000 The Apache Software Foundation. All rights
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny * reserved.
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny *
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny * Redistribution and use in source and binary forms, with or without
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny * modification, are permitted provided that the following conditions
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny * are met:
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny *
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny * 1. Redistributions of source code must retain the above copyright
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny * notice, this list of conditions and the following disclaimer.
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny *
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny * 2. Redistributions in binary form must reproduce the above copyright
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny * notice, this list of conditions and the following disclaimer in
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny * the documentation and/or other materials provided with the
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny * distribution.
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny *
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny * 3. The end-user documentation included with the redistribution,
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny * if any, must include the following acknowledgment:
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny * "This product includes software developed by the
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny * Apache Software Foundation (http://www.apache.org/)."
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny * Alternately, this acknowledgment may appear in the software itself,
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny * if and wherever such third-party acknowledgments normally appear.
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny *
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * 4. The names "Apache" and "Apache Software Foundation" must
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * not be used to endorse or promote products derived from this
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * software without prior written permission. For written
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * permission, please contact apache@apache.org.
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek *
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * 5. Products derived from this software may not be called "Apache",
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * nor may "Apache" appear in their name, without prior written
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * permission of the Apache Software Foundation.
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek *
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * SUCH DAMAGE.
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * ====================================================================
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek *
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * This software consists of voluntary contributions made by many
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * individuals on behalf of the Apache Software Foundation. For more
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * information on the Apache Software Foundation, please see
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * <http://www.apache.org/>.
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek *
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * Portions of this software are based upon public domain software
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * originally written at the National Center for Supercomputing Applications,
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * University of Illinois, Urbana-Champaign.
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek */
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek#define CORE_PRIVATE
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek#include "ap_config.h"
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek#include "apr_strings.h"
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek#include "httpd.h"
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek#include "http_config.h"
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek#include "http_main.h"
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek#include "http_log.h"
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek#include "http_core.h"
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek#include "http_protocol.h"
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek#include "http_request.h" /* for sub_req_lookup_uri() */
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek#include "util_script.h"
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek#include "util_date.h" /* For parseHTTPdate() */
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek#include "util_ebcdic.h"
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek#ifdef HAVE_STDLIB_H
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek#include <stdlib.h>
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek#endif
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek#ifdef HAVE_STRING_H
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek#include <string.h>
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek#endif
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek#ifdef HAVE_STRINGS_H
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek#include <strings.h>
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek#endif
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek#ifdef HAVE_ARPA_INET_H
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek#include <arpa/inet.h>
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek#endif
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek#ifdef OS2
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek#define INCL_DOS
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek#include <os2.h>
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek#endif
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek/*
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * Various utility functions which are common to a whole lot of
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * script-type extensions mechanisms, and might as well be gathered
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * in one place (if only to avoid creating inter-module dependancies
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek * where there don't have to be).
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek */
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek#define MALFORMED_MESSAGE "malformed header from script. Bad header="
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek#define MALFORMED_HEADER_LENGTH_TO_SHOW 30
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozekstatic char *http2env(apr_pool_t *a, char *w)
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek{
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek char *res = apr_pstrcat(a, "HTTP_", w, NULL);
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek char *cp = res;
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek while (*++cp) {
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek if (!apr_isalnum(*cp) && *cp != '_') {
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek *cp = '_';
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek }
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek else {
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek *cp = apr_toupper(*cp);
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek }
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek }
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek
b5825c74b6bf7a99ae2172392dbecb51179013a6Jakub Hrozek return res;
b5825c74b6bf7a99ae2172392dbecb51179013a6Jakub Hrozek}
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek
50936fc7230a9b3f01e285e72c4182013542f53eJakub HrozekAP_DECLARE(char **) ap_create_environment(apr_pool_t *p, apr_table_t *t)
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek{
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek apr_array_header_t *env_arr = apr_table_elts(t);
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek apr_table_entry_t *elts = (apr_table_entry_t *) env_arr->elts;
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek char **env = (char **) apr_palloc(p, (env_arr->nelts + 2) * sizeof(char *));
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek int i, j;
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek char *tz;
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek char *whack;
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek j = 0;
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek if (!apr_table_get(t, "TZ")) {
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek tz = getenv("TZ");
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek if (tz != NULL) {
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek env[j++] = apr_pstrcat(p, "TZ=", tz, NULL);
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek }
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek }
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek for (i = 0; i < env_arr->nelts; ++i) {
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek if (!elts[i].key) {
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek continue;
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek }
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek env[j] = apr_pstrcat(p, elts[i].key, "=", elts[i].val, NULL);
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek whack = env[j];
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek if (apr_isdigit(*whack)) {
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek *whack++ = '_';
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek }
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek while (*whack != '=') {
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek if (!apr_isalnum(*whack) && *whack != '_') {
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek *whack = '_';
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek }
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek ++whack;
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek }
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek ++j;
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek }
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek env[j] = NULL;
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek return env;
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek}
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek
50936fc7230a9b3f01e285e72c4182013542f53eJakub HrozekAP_DECLARE(void) ap_add_common_vars(request_rec *r)
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek{
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek apr_table_t *e;
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek server_rec *s = r->server;
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek conn_rec *c = r->connection;
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek const char *rem_logname;
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek char *env_path;
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek#if defined(WIN32) || defined(OS2)
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek char *env_temp;
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek#endif
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek const char *host;
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek apr_array_header_t *hdrs_arr = apr_table_elts(r->headers_in);
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek apr_table_entry_t *hdrs = (apr_table_entry_t *) hdrs_arr->elts;
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek int i;
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek apr_port_t rport;
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek apr_sockaddr_t *remotesa;
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek /* use a temporary apr_table_t which we'll overlap onto
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek * r->subprocess_env later
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek */
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek e = apr_make_table(r->pool, 25 + hdrs_arr->nelts);
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek /* First, add environment vars from headers... this is as per
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek * CGI specs, though other sorts of scripting interfaces see
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek * the same vars...
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek */
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek for (i = 0; i < hdrs_arr->nelts; ++i) {
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek if (!hdrs[i].key) {
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek continue;
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek }
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek /* A few headers are special cased --- Authorization to prevent
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek * rogue scripts from capturing passwords; content-type and -length
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek * for no particular reason.
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek */
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek if (!strcasecmp(hdrs[i].key, "Content-type")) {
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek apr_table_addn(e, "CONTENT_TYPE", hdrs[i].val);
877b92e80bde510d5cd9f03dbf01e2bcf73ab072Michal Židek }
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek else if (!strcasecmp(hdrs[i].key, "Content-length")) {
877b92e80bde510d5cd9f03dbf01e2bcf73ab072Michal Židek apr_table_addn(e, "CONTENT_LENGTH", hdrs[i].val);
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek }
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek /*
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek * You really don't want to disable this check, since it leaves you
877b92e80bde510d5cd9f03dbf01e2bcf73ab072Michal Židek * wide open to CGIs stealing passwords and people viewing them
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek * in the environment with "ps -e". But, if you must...
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek */
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek#ifndef SECURITY_HOLE_PASS_AUTHORIZATION
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek else if (!strcasecmp(hdrs[i].key, "Authorization")
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek || !strcasecmp(hdrs[i].key, "Proxy-Authorization")) {
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek continue;
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek }
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek#endif
877b92e80bde510d5cd9f03dbf01e2bcf73ab072Michal Židek else {
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek apr_table_addn(e, http2env(r->pool, hdrs[i].key), hdrs[i].val);
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek }
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek }
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek if (!(env_path = getenv("PATH"))) {
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek env_path = DEFAULT_PATH;
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek }
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek apr_table_addn(e, "PATH", apr_pstrdup(r->pool, env_path));
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek#ifdef WIN32
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek if (env_temp = getenv("SystemRoot")) {
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek apr_table_addn(e, "SystemRoot", env_temp);
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek }
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek if (env_temp = getenv("COMSPEC")) {
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek apr_table_addn(e, "COMSPEC", env_temp);
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek }
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce if (env_temp = getenv("WINDIR")) {
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny apr_table_addn(e, "WINDIR", env_temp);
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny }
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny#endif
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny#ifdef OS2
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny if ((env_temp = getenv("COMSPEC")) != NULL) {
204cfc89a076fd32bf34f2abb3f809304aaa88abSimo Sorce apr_table_addn(e, "COMSPEC", env_temp);
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny }
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny if ((env_temp = getenv("ETC")) != NULL) {
9822d4d468ec74e4e173f5adf0db12d02974cd18Sumit Bose apr_table_addn(e, "ETC", env_temp);
a6cca9c284724fafd670a3163812f248ba53ad97Jakub Hrozek }
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit Bose if ((env_temp = getenv("DPATH")) != NULL) {
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek apr_table_addn(e, "DPATH", env_temp);
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny }
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce if ((env_temp = getenv("PERLLIB_PREFIX")) != NULL) {
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny apr_table_addn(e, "PERLLIB_PREFIX", env_temp);
9822d4d468ec74e4e173f5adf0db12d02974cd18Sumit Bose }
9822d4d468ec74e4e173f5adf0db12d02974cd18Sumit Bose#endif
9822d4d468ec74e4e173f5adf0db12d02974cd18Sumit Bose
9822d4d468ec74e4e173f5adf0db12d02974cd18Sumit Bose apr_table_addn(e, "SERVER_SIGNATURE", ap_psignature("", r));
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit Bose apr_table_addn(e, "SERVER_SOFTWARE", ap_get_server_version());
9822d4d468ec74e4e173f5adf0db12d02974cd18Sumit Bose apr_table_addn(e, "SERVER_NAME", ap_get_server_name(r));
a6cca9c284724fafd670a3163812f248ba53ad97Jakub Hrozek apr_table_addn(e, "SERVER_ADDR", r->connection->local_ip); /* Apache */
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek apr_table_addn(e, "SERVER_PORT",
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny apr_psprintf(r->pool, "%u", ap_get_server_port(r)));
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny host = ap_get_remote_host(c, r->per_dir_config, REMOTE_HOST);
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny if (host) {
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny apr_table_addn(e, "REMOTE_HOST", host);
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny }
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny apr_table_addn(e, "REMOTE_ADDR", c->remote_ip);
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny apr_table_addn(e, "DOCUMENT_ROOT", ap_document_root(r)); /* Apache */
aab938c5975f0e3b85c7c79a5d718e5fefed7217Simo Sorce apr_table_addn(e, "SERVER_ADMIN", s->server_admin); /* Apache */
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny apr_table_addn(e, "SCRIPT_FILENAME", r->filename); /* Apache */
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny apr_get_sockaddr(&remotesa, APR_REMOTE, c->client_socket);
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny apr_get_port(&rport, remotesa);
aab938c5975f0e3b85c7c79a5d718e5fefed7217Simo Sorce apr_table_addn(e, "REMOTE_PORT", apr_psprintf(r->pool, "%d", rport));
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny if (r->user) {
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny apr_table_addn(e, "REMOTE_USER", r->user);
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny }
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny if (r->ap_auth_type) {
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny apr_table_addn(e, "AUTH_TYPE", r->ap_auth_type);
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny }
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce rem_logname = ap_get_remote_logname(r);
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce if (rem_logname) {
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce apr_table_addn(e, "REMOTE_IDENT", apr_pstrdup(r->pool, rem_logname));
b5825c74b6bf7a99ae2172392dbecb51179013a6Jakub Hrozek }
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce /* Apache custom error responses. If we have redirected set two new vars */
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce if (r->prev) {
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny if (r->prev->args) {
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny apr_table_addn(e, "REDIRECT_QUERY_STRING", r->prev->args);
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny }
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny if (r->prev->uri) {
aab938c5975f0e3b85c7c79a5d718e5fefed7217Simo Sorce apr_table_addn(e, "REDIRECT_URL", r->prev->uri);
aab938c5975f0e3b85c7c79a5d718e5fefed7217Simo Sorce }
aab938c5975f0e3b85c7c79a5d718e5fefed7217Simo Sorce }
7fe69bb6ec70bce439c6b975a9a0044c98ff502bSimo Sorce
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov apr_overlap_tables(r->subprocess_env, e, APR_OVERLAP_TABLES_SET);
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov}
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny/* This "cute" little function comes about because the path info on
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny * filenames and URLs aren't always the same. So we take the two,
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny * and find as much of the two that match as possible.
aab938c5975f0e3b85c7c79a5d718e5fefed7217Simo Sorce */
aab938c5975f0e3b85c7c79a5d718e5fefed7217Simo Sorce
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan ZelenyAP_DECLARE(int) ap_find_path_info(const char *uri, const char *path_info)
aab938c5975f0e3b85c7c79a5d718e5fefed7217Simo Sorce{
aab938c5975f0e3b85c7c79a5d718e5fefed7217Simo Sorce int lu = strlen(uri);
204cfc89a076fd32bf34f2abb3f809304aaa88abSimo Sorce int lp = strlen(path_info);
aab938c5975f0e3b85c7c79a5d718e5fefed7217Simo Sorce
aab938c5975f0e3b85c7c79a5d718e5fefed7217Simo Sorce while (lu-- && lp-- && uri[lu] == path_info[lp]);
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny
9822d4d468ec74e4e173f5adf0db12d02974cd18Sumit Bose if (lu == -1) {
9822d4d468ec74e4e173f5adf0db12d02974cd18Sumit Bose lu = 0;
9822d4d468ec74e4e173f5adf0db12d02974cd18Sumit Bose }
a6cca9c284724fafd670a3163812f248ba53ad97Jakub Hrozek
a6cca9c284724fafd670a3163812f248ba53ad97Jakub Hrozek while (uri[lu] != '\0' && uri[lu] != '/') {
a6cca9c284724fafd670a3163812f248ba53ad97Jakub Hrozek lu++;
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit Bose }
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit Bose return lu;
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit Bose}
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek
ea224c3813a537639778f91ac762732b3c289603Jakub HrozekAP_DECLARE(void) ap_add_cgi_vars(request_rec *r)
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek{
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek apr_table_t *e = r->subprocess_env;
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce apr_table_setn(e, "GATEWAY_INTERFACE", "CGI/1.1");
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce apr_table_setn(e, "SERVER_PROTOCOL", r->protocol);
b5825c74b6bf7a99ae2172392dbecb51179013a6Jakub Hrozek apr_table_setn(e, "REQUEST_METHOD", r->method);
b5825c74b6bf7a99ae2172392dbecb51179013a6Jakub Hrozek apr_table_setn(e, "QUERY_STRING", r->args ? r->args : "");
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce apr_table_setn(e, "REQUEST_URI", r->unparsed_uri);
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce /* Note that the code below special-cases scripts run from includes,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov * because it "knows" that the sub_request has been hacked to have the
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov * args and path_info of the original request, and not any that may have
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce * come with the script URI in the include command. Ugh.
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce */
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce if (!strcmp(r->protocol, "INCLUDED")) {
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce apr_table_setn(e, "SCRIPT_NAME", r->uri);
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce if (r->path_info && *r->path_info) {
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce apr_table_setn(e, "PATH_INFO", r->path_info);
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce }
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce }
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov else if (!r->path_info || !*r->path_info) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov apr_table_setn(e, "SCRIPT_NAME", r->uri);
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce }
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce else {
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce int path_info_start = ap_find_path_info(r->uri, r->path_info);
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce apr_table_setn(e, "SCRIPT_NAME",
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce apr_pstrndup(r->pool, r->uri, path_info_start));
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce apr_table_setn(e, "PATH_INFO", r->path_info);
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce }
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov if (r->path_info && r->path_info[0]) {
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce /*
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce * To get PATH_TRANSLATED, treat PATH_INFO as a URI path.
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce * Need to re-escape it for this, since the entire URI was
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce * un-escaped before we determined where the PATH_INFO began.
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce */
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce request_rec *pa_req;
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce
9822d4d468ec74e4e173f5adf0db12d02974cd18Sumit Bose pa_req = ap_sub_req_lookup_uri(ap_escape_uri(r->pool, r->path_info), r,
9822d4d468ec74e4e173f5adf0db12d02974cd18Sumit Bose NULL);
9822d4d468ec74e4e173f5adf0db12d02974cd18Sumit Bose
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov if (pa_req->filename) {
9822d4d468ec74e4e173f5adf0db12d02974cd18Sumit Bose#ifdef WIN32
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov char buffer[HUGE_STRING_LEN];
9822d4d468ec74e4e173f5adf0db12d02974cd18Sumit Bose#endif
9822d4d468ec74e4e173f5adf0db12d02974cd18Sumit Bose char *pt = apr_pstrcat(r->pool, pa_req->filename, pa_req->path_info,
9822d4d468ec74e4e173f5adf0db12d02974cd18Sumit Bose NULL);
a6cca9c284724fafd670a3163812f248ba53ad97Jakub Hrozek#ifdef WIN32
a6cca9c284724fafd670a3163812f248ba53ad97Jakub Hrozek /* We need to make this a real Windows path name */
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek GetFullPathName(pt, HUGE_STRING_LEN, buffer, NULL);
a6cca9c284724fafd670a3163812f248ba53ad97Jakub Hrozek apr_table_setn(e, "PATH_TRANSLATED", apr_pstrdup(r->pool, buffer));
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov#else
a6cca9c284724fafd670a3163812f248ba53ad97Jakub Hrozek apr_table_setn(e, "PATH_TRANSLATED", pt);
a6cca9c284724fafd670a3163812f248ba53ad97Jakub Hrozek#endif
a6cca9c284724fafd670a3163812f248ba53ad97Jakub Hrozek }
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit Bose ap_destroy_sub_req(pa_req);
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit Bose }
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit Bose}
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit Bose
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashovstatic int set_cookie_doo_doo(void *v, const char *key, const char *val)
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit Bose{
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit Bose apr_table_addn(v, key, val);
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit Bose return 1;
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit Bose}
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit Bose
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit BoseAP_DECLARE(int) ap_scan_script_header_err_core(request_rec *r, char *buffer,
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit Bose int (*getsfunc) (char *, int, void *),
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit Bose void *getsfunc_data)
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose{
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose char x[MAX_STRING_LEN];
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose char *w, *l;
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose int p;
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose int cgi_status = HTTP_OK;
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose apr_table_t *merge;
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose apr_table_t *cookie_table;
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose if (buffer) {
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose *buffer = '\0';
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose }
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose w = buffer ? buffer : x;
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose /* temporary place to hold headers to merge in later */
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose merge = apr_make_table(r->pool, 10);
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose /* The HTTP specification says that it is legal to merge duplicate
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose * headers into one. Some browsers that support Cookies don't like
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose * merged headers and prefer that each Set-Cookie header is sent
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose * separately. Lets humour those browsers by not merging.
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose * Oh what a pain it is.
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose */
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose cookie_table = apr_make_table(r->pool, 2);
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose apr_table_do(set_cookie_doo_doo, cookie_table, r->err_headers_out, "Set-Cookie", NULL);
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose while (1) {
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose if ((*getsfunc) (w, MAX_STRING_LEN - 1, getsfunc_data) == 0) {
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r,
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek "Premature end of script headers: %s", r->filename);
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek return HTTP_INTERNAL_SERVER_ERROR;
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek }
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek /* Delete terminal (CR?)LF */
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek p = strlen(w);
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce /* Indeed, the host's '\n':
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce '\012' for UNIX; '\015' for MacOS; '\025' for OS/390
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce -- whatever the script generates.
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce */
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce if (p > 0 && w[p - 1] == '\n') {
a6cca9c284724fafd670a3163812f248ba53ad97Jakub Hrozek if (p > 1 && w[p - 2] == CR) {
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek w[p - 2] = '\0';
ea224c3813a537639778f91ac762732b3c289603Jakub Hrozek }
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce else {
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce w[p - 1] = '\0';
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce }
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce }
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny /*
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny * If we've finished reading the headers, check to make sure any
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny * HTTP/1.1 conditions are met. If so, we're done; normal processing
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek * will handle the script's output. If not, just return the error.
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek * The appropriate thing to do would be to send the script process a
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny * SIGPIPE to let it know we're ignoring it, close the channel to the
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny * script process, and *then* return the failed-to-meet-condition
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny * error. Otherwise we'd be waiting for the script to finish
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny * blithering before telling the client the output was no good.
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny * However, we don't have the information to do that, so we have to
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny * leave it to an upper layer.
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny */
65393a294e635822c1d7a15fe5853dc457ad8a2aSimo Sorce if (w[0] == '\0') {
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny int cond_status = OK;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny if ((cgi_status == HTTP_OK) && (r->method_number == M_GET)) {
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny cond_status = ap_meets_conditions(r);
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny }
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny apr_overlap_tables(r->err_headers_out, merge,
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny APR_OVERLAP_TABLES_MERGE);
204cfc89a076fd32bf34f2abb3f809304aaa88abSimo Sorce if (!apr_is_empty_table(cookie_table)) {
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny /* the cookies have already been copied to the cookie_table */
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny apr_table_unset(r->err_headers_out, "Set-Cookie");
17195241500e46272018d7897d6e87249870caf2Pavel Reichl r->err_headers_out = apr_overlay_tables(r->pool,
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny r->err_headers_out, cookie_table);
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose }
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny return cond_status;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny }
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny /* if we see a bogus header don't ignore it. Shout and scream */
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny#ifdef AP_CHARSET_EBCDIC
65393a294e635822c1d7a15fe5853dc457ad8a2aSimo Sorce /* Chances are that we received an ASCII header text instead of
65393a294e635822c1d7a15fe5853dc457ad8a2aSimo Sorce * the expected EBCDIC header lines. Try to auto-detect:
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny */
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny if (!(l = strchr(w, ':'))) {
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny int maybeASCII = 0, maybeEBCDIC = 0;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny unsigned char *cp, native;
65393a294e635822c1d7a15fe5853dc457ad8a2aSimo Sorce apr_size_t inbytes_left, outbytes_left;
65393a294e635822c1d7a15fe5853dc457ad8a2aSimo Sorce
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny for (cp = w; *cp != '\0'; ++cp) {
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny native = apr_xlate_conv_byte(ap_hdrs_from_ascii, *cp);
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny if (isprint(*cp) && !isprint(native))
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny ++maybeEBCDIC;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny if (!isprint(*cp) && isprint(native))
cb388d52f49f54963379cc20a25e14d17fe6e9a3Simo Sorce ++maybeASCII;
cb388d52f49f54963379cc20a25e14d17fe6e9a3Simo Sorce }
cb388d52f49f54963379cc20a25e14d17fe6e9a3Simo Sorce if (maybeASCII > maybeEBCDIC) {
cb388d52f49f54963379cc20a25e14d17fe6e9a3Simo Sorce ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r->server,
cb388d52f49f54963379cc20a25e14d17fe6e9a3Simo Sorce "CGI Interface Error: Script headers apparently ASCII: (CGI = %s)",
cb388d52f49f54963379cc20a25e14d17fe6e9a3Simo Sorce r->filename);
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov inbytes_left = outbytes_left = cp - w;
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov apr_xlate_conv_buffer(ap_hdrs_from_ascii,
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny w, &inbytes_left, w, &outbytes_left);
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny }
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny }
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny#endif /*AP_CHARSET_EBCDIC*/
204cfc89a076fd32bf34f2abb3f809304aaa88abSimo Sorce if (!(l = strchr(w, ':'))) {
204cfc89a076fd32bf34f2abb3f809304aaa88abSimo Sorce char malformed[(sizeof MALFORMED_MESSAGE) + 1
65393a294e635822c1d7a15fe5853dc457ad8a2aSimo Sorce + MALFORMED_HEADER_LENGTH_TO_SHOW];
65393a294e635822c1d7a15fe5853dc457ad8a2aSimo Sorce
65393a294e635822c1d7a15fe5853dc457ad8a2aSimo Sorce strcpy(malformed, MALFORMED_MESSAGE);
65393a294e635822c1d7a15fe5853dc457ad8a2aSimo Sorce strncat(malformed, w, MALFORMED_HEADER_LENGTH_TO_SHOW);
65393a294e635822c1d7a15fe5853dc457ad8a2aSimo Sorce
204cfc89a076fd32bf34f2abb3f809304aaa88abSimo Sorce if (!buffer) {
204cfc89a076fd32bf34f2abb3f809304aaa88abSimo Sorce /* Soak up all the script output - may save an outright kill */
204cfc89a076fd32bf34f2abb3f809304aaa88abSimo Sorce while ((*getsfunc) (w, MAX_STRING_LEN - 1, getsfunc_data)) {
204cfc89a076fd32bf34f2abb3f809304aaa88abSimo Sorce continue;
204cfc89a076fd32bf34f2abb3f809304aaa88abSimo Sorce }
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny }
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny
65393a294e635822c1d7a15fe5853dc457ad8a2aSimo Sorce ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r,
65393a294e635822c1d7a15fe5853dc457ad8a2aSimo Sorce "%s: %s", malformed, r->filename);
65393a294e635822c1d7a15fe5853dc457ad8a2aSimo Sorce return HTTP_INTERNAL_SERVER_ERROR;
65393a294e635822c1d7a15fe5853dc457ad8a2aSimo Sorce }
65393a294e635822c1d7a15fe5853dc457ad8a2aSimo Sorce
65393a294e635822c1d7a15fe5853dc457ad8a2aSimo Sorce *l++ = '\0';
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny while (*l && apr_isspace(*l)) {
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny ++l;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny }
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny if (!strcasecmp(w, "Content-type")) {
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny char *tmp;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny
65393a294e635822c1d7a15fe5853dc457ad8a2aSimo Sorce /* Nuke trailing whitespace */
65393a294e635822c1d7a15fe5853dc457ad8a2aSimo Sorce
65393a294e635822c1d7a15fe5853dc457ad8a2aSimo Sorce char *endp = l + strlen(l) - 1;
65393a294e635822c1d7a15fe5853dc457ad8a2aSimo Sorce while (endp > l && apr_isspace(*endp)) {
65393a294e635822c1d7a15fe5853dc457ad8a2aSimo Sorce *endp-- = '\0';
65393a294e635822c1d7a15fe5853dc457ad8a2aSimo Sorce }
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny tmp = apr_pstrdup(r->pool, l);
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny ap_content_type_tolower(tmp);
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny r->content_type = tmp;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny }
17195241500e46272018d7897d6e87249870caf2Pavel Reichl /*
17195241500e46272018d7897d6e87249870caf2Pavel Reichl * If the script returned a specific status, that's what
17195241500e46272018d7897d6e87249870caf2Pavel Reichl * we'll use - otherwise we assume 200 OK.
17195241500e46272018d7897d6e87249870caf2Pavel Reichl */
17195241500e46272018d7897d6e87249870caf2Pavel Reichl else if (!strcasecmp(w, "Status")) {
17195241500e46272018d7897d6e87249870caf2Pavel Reichl r->status = cgi_status = atoi(l);
17195241500e46272018d7897d6e87249870caf2Pavel Reichl r->status_line = apr_pstrdup(r->pool, l);
17195241500e46272018d7897d6e87249870caf2Pavel Reichl }
17195241500e46272018d7897d6e87249870caf2Pavel Reichl else if (!strcasecmp(w, "Location")) {
17195241500e46272018d7897d6e87249870caf2Pavel Reichl apr_table_set(r->headers_out, w, l);
17195241500e46272018d7897d6e87249870caf2Pavel Reichl }
17195241500e46272018d7897d6e87249870caf2Pavel Reichl else if (!strcasecmp(w, "Content-Length")) {
17195241500e46272018d7897d6e87249870caf2Pavel Reichl apr_table_set(r->headers_out, w, l);
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose }
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose else if (!strcasecmp(w, "Transfer-Encoding")) {
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose apr_table_set(r->headers_out, w, l);
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose }
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose /*
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose * If the script gave us a Last-Modified header, we can't just
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose * pass it on blindly because of restrictions on future values.
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose */
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose else if (!strcasecmp(w, "Last-Modified")) {
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose ap_update_mtime(r, ap_parseHTTPdate(l));
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose ap_set_last_modified(r);
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose }
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose else if (!strcasecmp(w, "Set-Cookie")) {
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose apr_table_add(cookie_table, w, l);
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose }
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose else {
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose apr_table_add(merge, w, l);
9ac2a33f4cdc4941fa63118dcffe8058854f33c4Michal Židek }
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose }
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose}
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bosestatic int getsfunc_FILE(char *buf, int len, void *f)
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose{
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose return apr_fgets(buf, len, (apr_file_t *) f) == APR_SUCCESS;
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose}
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit BoseAP_DECLARE(int) ap_scan_script_header_err(request_rec *r, apr_file_t *f,
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose char *buffer)
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose{
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose return ap_scan_script_header_err_core(r, buffer, getsfunc_FILE, f);
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose}
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bosestruct vastrs {
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose va_list args;
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose int arg;
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose const char *curpos;
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose};
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bosestatic int getsfunc_STRING(char *w, int len, void *pvastrs)
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose{
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose struct vastrs *strs = (struct vastrs*) pvastrs;
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose const char *p;
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose int t;
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose if (!strs->curpos || !*strs->curpos)
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose return 0;
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose p = ap_strchr_c(strs->curpos, '\n');
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose if (p)
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose ++p;
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose else
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose p = ap_strchr_c(strs->curpos, '\0');
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose t = p - strs->curpos;
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose if (t > len)
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose t = len;
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose strncpy (w, strs->curpos, t);
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose w[t] = '\0';
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose if (!strs->curpos[t]) {
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose ++strs->arg;
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose strs->curpos = va_arg(strs->args, const char *);
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose }
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose else
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose strs->curpos += t;
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose return t;
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose}
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose/* ap_scan_script_header_err_strs() accepts additional const char* args...
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose * each is treated as one or more header lines, and the first non-header
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose * character is returned to **arg, **data. (The first optional arg is
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose * counted as 0.)
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose */
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit BoseAP_DECLARE_NONSTD(int) ap_scan_script_header_err_strs(request_rec *r,
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose char *buffer,
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose const char **termch,
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose int *termarg, ...)
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose{
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose struct vastrs strs;
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose int res;
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose va_start(strs.args, termarg);
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose strs.arg = 0;
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose strs.curpos = va_arg(strs.args, char*);
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose res = ap_scan_script_header_err_core(r, buffer, getsfunc_STRING, (void *) &strs);
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose if (termch)
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose *termch = strs.curpos;
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose if (termarg)
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny *termarg = strs.arg;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny va_end(strs.args);
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny return res;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny}
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny
3912262270a6449ebe1d3e92c27c217b4044f894Simo SorceAP_DECLARE(void) ap_send_size(apr_ssize_t size, request_rec *r)
9af86b9c936d07cff9d0c2054acde908749ea522Jakub Hrozek{
9af86b9c936d07cff9d0c2054acde908749ea522Jakub Hrozek /* XXX: this -1 thing is a gross hack */
9af86b9c936d07cff9d0c2054acde908749ea522Jakub Hrozek if (size == (apr_ssize_t)-1) {
17195241500e46272018d7897d6e87249870caf2Pavel Reichl ap_rputs(" -", r);
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny }
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny else if (!size) {
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny ap_rputs(" 0k", r);
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny }
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny else if (size < 1024) {
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny ap_rputs(" 1k", r);
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny }
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny else if (size < 1048576) {
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny ap_rprintf(r, "%4" APR_SSIZE_T_FMT "k", (size + 512) / 1024);
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny }
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny else if (size < 103809024) {
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny ap_rprintf(r, "%4.1fM", size / 1048576.0);
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny }
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny else {
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny ap_rprintf(r, "%4" APR_SSIZE_T_FMT "M", (size + 524288) / 1048576);
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny }
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny}
3912262270a6449ebe1d3e92c27c217b4044f894Simo Sorce
0754ff886f909f0404038eb9c99dd61be1acf5b9Simo Sorce