util_script.c revision 886cd69ebf69e990dbc365be87ff8ea7cd681904
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny/* ====================================================================
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny * The Apache Software License, Version 1.1
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny * Copyright (c) 2000 The Apache Software Foundation. All rights
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 * 1. Redistributions of source code must retain the above copyright
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny * notice, this list of conditions and the following disclaimer.
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 * 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.
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 * 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 * 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 * 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 * 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#include "http_request.h" /* for sub_req_lookup_uri() */
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek#include "util_date.h" /* For parseHTTPdate() */
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#define MALFORMED_MESSAGE "malformed header from script. Bad header="
50936fc7230a9b3f01e285e72c4182013542f53eJakub Hrozek while (*++cp) {
50936fc7230a9b3f01e285e72c4182013542f53eJakub HrozekAP_DECLARE(char **) ap_create_environment(apr_pool_t *p, apr_table_t *t)
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 env[j] = apr_pstrcat(p, elts[i].key, "=", elts[i].val, NULL);
50936fc7230a9b3f01e285e72c4182013542f53eJakub HrozekAP_DECLARE(void) ap_add_common_vars(request_rec *r)
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 /* use a temporary apr_table_t which we'll overlap onto
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek * r->subprocess_env later
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek e = apr_make_table(r->pool, 25 + hdrs_arr->nelts);
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 /* 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 if (!strcasecmp(hdrs[i].key, "Content-type")) {
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek apr_table_addn(e, "CONTENT_TYPE", hdrs[i].val);
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek else if (!strcasecmp(hdrs[i].key, "Content-length")) {
877b92e80bde510d5cd9f03dbf01e2bcf73ab072Michal Židek apr_table_addn(e, "CONTENT_LENGTH", hdrs[i].val);
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 else if (!strcasecmp(hdrs[i].key, "Authorization")
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek || !strcasecmp(hdrs[i].key, "Proxy-Authorization")) {
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek apr_table_addn(e, http2env(r->pool, hdrs[i].key), hdrs[i].val);
b50baee36c9ba9e1dd3f6b9c1356482aecd08128Jakub Hrozek apr_table_addn(e, "PATH", apr_pstrdup(r->pool, env_path));
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce if ((env_temp = getenv("PERLLIB_PREFIX")) != NULL) {
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 */
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 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 apr_get_sockaddr(&remotesa, APR_REMOTE, c->client_socket);
aab938c5975f0e3b85c7c79a5d718e5fefed7217Simo Sorce apr_table_addn(e, "REMOTE_PORT", apr_psprintf(r->pool, "%d", rport));
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce apr_table_addn(e, "REMOTE_IDENT", apr_pstrdup(r->pool, rem_logname));
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce /* Apache custom error responses. If we have redirected set two new vars */
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan Zeleny apr_table_addn(e, "REDIRECT_QUERY_STRING", r->prev->args);
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov apr_overlap_tables(r->subprocess_env, e, APR_OVERLAP_TABLES_SET);
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.
e76d78338026fa47dca32eaf7f5c15eabb1b951aJan ZelenyAP_DECLARE(int) ap_find_path_info(const char *uri, const char *path_info)
aab938c5975f0e3b85c7c79a5d718e5fefed7217Simo Sorce while (lu-- && lp-- && uri[lu] == path_info[lp]);
ea224c3813a537639778f91ac762732b3c289603Jakub HrozekAP_DECLARE(void) ap_add_cgi_vars(request_rec *r)
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 /* 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.
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov else if (!r->path_info || !*r->path_info) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov apr_table_setn(e, "SCRIPT_NAME", r->uri);
bba1a5fd62cffcae076d1351df5a83fbc4a6ec17Simo Sorce int path_info_start = ap_find_path_info(r->uri, r->path_info);
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.
9822d4d468ec74e4e173f5adf0db12d02974cd18Sumit Bose pa_req = ap_sub_req_lookup_uri(ap_escape_uri(r->pool, r->path_info), r,
9822d4d468ec74e4e173f5adf0db12d02974cd18Sumit Bose char *pt = apr_pstrcat(r->pool, pa_req->filename, pa_req->path_info,
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 Kondrashovstatic int set_cookie_doo_doo(void *v, const char *key, const char *val)
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit BoseAP_DECLARE(int) ap_scan_script_header_err_core(request_rec *r, char *buffer,
c5711b0279ea85d69fe3c77dfb194360c346e1d7Sumit Bose int (*getsfunc) (char *, int, void *),
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose char *w, *l;
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose /* temporary place to hold headers to merge in later */
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 apr_table_do(set_cookie_doo_doo, cookie_table, r->err_headers_out, "Set-Cookie", NULL);
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 /* Delete terminal (CR?)LF */
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.
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.
65393a294e635822c1d7a15fe5853dc457ad8a2aSimo Sorce if (w[0] == '\0') {
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny if ((cgi_status == HTTP_OK) && (r->method_number == M_GET)) {
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 /* if we see a bogus header don't ignore it. Shout and scream */
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 native = apr_xlate_conv_byte(ap_hdrs_from_ascii, *cp);
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)",
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov apr_xlate_conv_buffer(ap_hdrs_from_ascii,
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny#endif /*AP_CHARSET_EBCDIC*/
65393a294e635822c1d7a15fe5853dc457ad8a2aSimo Sorce strncat(malformed, w, MALFORMED_HEADER_LENGTH_TO_SHOW);
204cfc89a076fd32bf34f2abb3f809304aaa88abSimo Sorce /* Soak up all the script output - may save an outright kill */
204cfc89a076fd32bf34f2abb3f809304aaa88abSimo Sorce while ((*getsfunc) (w, MAX_STRING_LEN - 1, getsfunc_data)) {
65393a294e635822c1d7a15fe5853dc457ad8a2aSimo Sorce ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r,
65393a294e635822c1d7a15fe5853dc457ad8a2aSimo Sorce *l++ = '\0';
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny while (*l && apr_isspace(*l)) {
65393a294e635822c1d7a15fe5853dc457ad8a2aSimo Sorce /* Nuke trailing whitespace */
17195241500e46272018d7897d6e87249870caf2Pavel Reichl * If the script returned a specific status, that's what
17195241500e46272018d7897d6e87249870caf2Pavel Reichl * we'll use - otherwise we assume 200 OK.
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 Bosestatic int getsfunc_FILE(char *buf, int len, void *f)
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose return apr_fgets(buf, len, (apr_file_t *) f) == APR_SUCCESS;
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit BoseAP_DECLARE(int) ap_scan_script_header_err(request_rec *r, apr_file_t *f,
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose return ap_scan_script_header_err_core(r, buffer, getsfunc_FILE, f);
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose const char *curpos;
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bosestatic int getsfunc_STRING(char *w, int len, void *pvastrs)
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose const char *p;
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose w[t] = '\0';
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 BoseAP_DECLARE_NONSTD(int) ap_scan_script_header_err_strs(request_rec *r,
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose const char **termch,
9f734d4c122e37cc3080974342ed9586d05d5f83Sumit Bose res = ap_scan_script_header_err_core(r, buffer, getsfunc_STRING, (void *) &strs);
3912262270a6449ebe1d3e92c27c217b4044f894Simo SorceAP_DECLARE(void) ap_send_size(apr_ssize_t size, request_rec *r)
9af86b9c936d07cff9d0c2054acde908749ea522Jakub Hrozek /* XXX: this -1 thing is a gross hack */
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny else if (!size) {
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny ap_rprintf(r, "%4" APR_SSIZE_T_FMT "k", (size + 512) / 1024);
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny ap_rprintf(r, "%4" APR_SSIZE_T_FMT "M", (size + 524288) / 1048576);