httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From pque...@apache.org
Subject svn commit: r645594 [23/28] - in /httpd/sandbox/amsterdam/d: ./ build/ docs/conf/ docs/conf/extra/ docs/man/ docs/manual/ docs/manual/developer/ docs/manual/faq/ docs/manual/howto/ docs/manual/misc/ docs/manual/mod/ docs/manual/platform/ docs/manual/pr...
Date Mon, 07 Apr 2008 16:31:24 GMT
Modified: httpd/sandbox/amsterdam/d/modules/filters/mod_include.c
URL: http://svn.apache.org/viewvc/httpd/sandbox/amsterdam/d/modules/filters/mod_include.c?rev=645594&r1=645593&r2=645594&view=diff
==============================================================================
--- httpd/sandbox/amsterdam/d/modules/filters/mod_include.c (original)
+++ httpd/sandbox/amsterdam/d/modules/filters/mod_include.c Mon Apr  7 09:28:58 2008
@@ -39,6 +39,7 @@
 #include "util_script.h"
 #include "http_core.h"
 #include "mod_include.h"
+#include "ap_expr.h"
 
 /* helper for Latin1 <-> entity encoding */
 #if APR_CHARSET_EBCDIC
@@ -65,45 +66,6 @@
     const char *string;
 } result_item_t;
 
-/* conditional expression parser stuff */
-typedef enum {
-    TOKEN_STRING,
-    TOKEN_RE,
-    TOKEN_AND,
-    TOKEN_OR,
-    TOKEN_NOT,
-    TOKEN_EQ,
-    TOKEN_NE,
-    TOKEN_RBRACE,
-    TOKEN_LBRACE,
-    TOKEN_GROUP,
-    TOKEN_GE,
-    TOKEN_LE,
-    TOKEN_GT,
-    TOKEN_LT,
-    TOKEN_ACCESS
-} token_type_t;
-
-typedef struct {
-    token_type_t  type;
-    const char   *value;
-#ifdef DEBUG_INCLUDE
-    const char   *s;
-#endif
-} token_t;
-
-typedef struct parse_node {
-    struct parse_node *parent;
-    struct parse_node *left;
-    struct parse_node *right;
-    token_t token;
-    int value;
-    int done;
-#ifdef DEBUG_INCLUDE
-    int dump_done;
-#endif
-} parse_node_t;
-
 typedef enum {
     XBITHACK_OFF,
     XBITHACK_ON,
@@ -154,13 +116,6 @@
 } arg_item_t;
 
 typedef struct {
-    const char *source;
-    const char *rexp;
-    apr_size_t  nsub;
-    ap_regmatch_t match[AP_MAX_REG_MATCH];
-} backref_t;
-
-typedef struct {
     unsigned int T[256];
     unsigned int x;
     apr_size_t pattern_len;
@@ -192,8 +147,10 @@
     const char   *undefined_echo;
     apr_size_t    undefined_echo_len;
 
-    int         accessenable;    /* is using the access tests allowed? */
+    opt_func_t  access_func;    /* is using the access tests allowed? */
 
+    /* breadcrumb to track whether child request should have parent's env */
+    request_rec *kludge_child;
 #ifdef DEBUG_INCLUDE
     struct {
         ap_filter_t *f;
@@ -909,633 +866,53 @@
     return ret;
 }
 
-
-/*
- * +-------------------------------------------------------+
- * |                                                       |
- * |              Conditional Expression Parser
- * |                                                       |
- * +-------------------------------------------------------+
- */
-
-static APR_INLINE int re_check(include_ctx_t *ctx, const char *string,
-                               const char *rexp)
-{
-    ap_regex_t *compiled;
-    backref_t *re = ctx->intern->re;
-    int rc;
-
-    compiled = ap_pregcomp(ctx->dpool, rexp, AP_REG_EXTENDED);
-    if (!compiled) {
-        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, ctx->intern->r, "unable to "
-                      "compile pattern \"%s\"", rexp);
-        return -1;
-    }
-
-    if (!re) {
-        re = ctx->intern->re = apr_palloc(ctx->pool, sizeof(*re));
-    }
-
-    re->source = apr_pstrdup(ctx->pool, string);
-    re->rexp = apr_pstrdup(ctx->pool, rexp);
-    re->nsub = compiled->re_nsub;
-    rc = !ap_regexec(compiled, string, AP_MAX_REG_MATCH, re->match, 0);
-
-    ap_pregfree(ctx->dpool, compiled);
-    return rc;
-}
-
-static int get_ptoken(include_ctx_t *ctx, const char **parse, token_t *token, token_t *previous)
+static const char *ssi_parse_string(request_rec *r, const char *in)
 {
-    const char *p;
-    apr_size_t shift;
-    int unmatched;
-
-    token->value = NULL;
-
-    if (!*parse) {
-        return 0;
-    }
-
-    /* Skip leading white space */
-    while (apr_isspace(**parse)) {
-        ++*parse;
-    }
-
-    if (!**parse) {
-        *parse = NULL;
-        return 0;
-    }
-
-    TYPE_TOKEN(token, TOKEN_STRING); /* the default type */
-    p = *parse;
-    unmatched = 0;
-
-    switch (*(*parse)++) {
-    case '(':
-        TYPE_TOKEN(token, TOKEN_LBRACE);
-        return 0;
-    case ')':
-        TYPE_TOKEN(token, TOKEN_RBRACE);
-        return 0;
-    case '=':
-        if (**parse == '=') ++*parse;
-        TYPE_TOKEN(token, TOKEN_EQ);
-        return 0;
-    case '!':
-        if (**parse == '=') {
-            TYPE_TOKEN(token, TOKEN_NE);
-            ++*parse;
-            return 0;
-        }
-        TYPE_TOKEN(token, TOKEN_NOT);
-        return 0;
-    case '\'':
-        unmatched = '\'';
-        break;
-    case '/':
-        /* if last token was ACCESS, this token is STRING */
-        if (previous != NULL && TOKEN_ACCESS == previous->type) {
-            break;
-        }
-        TYPE_TOKEN(token, TOKEN_RE);
-        unmatched = '/';
-        break;
-    case '|':
-        if (**parse == '|') {
-            TYPE_TOKEN(token, TOKEN_OR);
-            ++*parse;
-            return 0;
-        }
-        break;
-    case '&':
-        if (**parse == '&') {
-            TYPE_TOKEN(token, TOKEN_AND);
-            ++*parse;
-            return 0;
-        }
-        break;
-    case '>':
-        if (**parse == '=') {
-            TYPE_TOKEN(token, TOKEN_GE);
-            ++*parse;
-            return 0;
-        }
-        TYPE_TOKEN(token, TOKEN_GT);
-        return 0;
-    case '<':
-        if (**parse == '=') {
-            TYPE_TOKEN(token, TOKEN_LE);
-            ++*parse;
-            return 0;
-        }
-        TYPE_TOKEN(token, TOKEN_LT);
-        return 0;
-    case '-':
-        if (**parse == 'A' && (ctx->intern->accessenable)) {
-            TYPE_TOKEN(token, TOKEN_ACCESS);
-            ++*parse;
-            return 0;
-        }
-        break;
-    }
-
-    /* It's a string or regex token
-     * Now search for the next token, which finishes this string
-     */
-    shift = 0;
-    p = *parse = token->value = unmatched ? *parse : p;
-
-    for (; **parse; p = ++*parse) {
-        if (**parse == '\\') {
-            if (!*(++*parse)) {
-                p = *parse;
-                break;
-            }
-
-            ++shift;
-        }
-        else {
-            if (unmatched) {
-                if (**parse == unmatched) {
-                    unmatched = 0;
-                    ++*parse;
-                    break;
-                }
-            } else if (apr_isspace(**parse)) {
-                break;
-            }
-            else {
-                int found = 0;
-
-                switch (**parse) {
-                case '(':
-                case ')':
-                case '=':
-                case '!':
-                case '<':
-                case '>':
-                    ++found;
-                    break;
-
-                case '|':
-                case '&':
-                    if ((*parse)[1] == **parse) {
-                        ++found;
-                    }
-                    break;
-                }
-
-                if (found) {
-                    break;
-                }
-            }
-        }
-    }
-
-    if (unmatched) {
-        token->value = apr_pstrdup(ctx->dpool, "");
+    include_ctx_t *ctx = ap_get_module_config(r->request_config,
+                                              &include_module);
+    return ap_ssi_parse_string(ctx, in, NULL, 0, SSI_EXPAND_DROP_NAME);
+}
+static int ssi_access(request_rec *r, ap_parse_node_t *current,
+                      string_func_t parse_string)
+{
+    request_rec *rr;
+    include_ctx_t *ctx = ap_get_module_config(r->request_config,
+                                              &include_module);
+
+    /* if this arg isn't -A, just return */
+    if (current->token.type != TOKEN_ACCESS || current->token.value[0] != 'A') {
+        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+                      "Unsupported option -%s in file %s",
+                      current->token.value, r->filename);
+        return 1;
+    }
+    if (current->left || !current->right ||
+        (current->right->token.type != TOKEN_STRING &&
+         current->right->token.type != TOKEN_RE)) {
+        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+                    "Invalid expression in file %s: Token '-A' must be followed by a URI string.",
+                    r->filename);
+        return 1;    /* was_error */
+    }
+    current->right->token.value =
+        ap_ssi_parse_string(ctx, current->right->token.value, NULL, 0,
+                            SSI_EXPAND_DROP_NAME);
+    rr = ap_sub_req_lookup_uri(current->right->token.value, r, NULL);
+    /* 400 and higher are considered access denied */
+    if (rr->status < HTTP_BAD_REQUEST) {
+        current->value = 1;
     }
     else {
-        apr_size_t len = p - token->value - shift;
-        char *c = apr_palloc(ctx->dpool, len + 1);
-
-        p = token->value;
-        token->value = c;
-
-        while (shift--) {
-            const char *e = ap_strchr_c(p, '\\');
-
-            memcpy(c, p, e-p);
-            c   += e-p;
-            *c++ = *++e;
-            len -= e-p;
-            p    = e+1;
-        }
-
-        if (len) {
-            memcpy(c, p, len);
-        }
-        c[len] = '\0';
-    }
-
-    return unmatched;
-}
-
-static int parse_expr(include_ctx_t *ctx, const char *expr, int *was_error)
-{
-    parse_node_t *new, *root = NULL, *current = NULL;
-    request_rec *r = ctx->intern->r;
-    request_rec *rr = NULL;
-    const char *error = "Invalid expression \"%s\" in file %s";
-    const char *parse = expr;
-    int was_unmatched = 0;
-    unsigned regex = 0;
-
-    *was_error = 0;
-
-    if (!parse) {
-        return 0;
+        current->value = 0;
+        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rr->status, r, 
+                      "mod_include: The tested "
+                      "subrequest -A \"%s\" returned an error code.",
+                      current->right->token.value);
     }
-
-    /* Create Parse Tree */
-    while (1) {
-        /* uncomment this to see how the tree a built:
-         *
-         * DEBUG_DUMP_TREE(ctx, root);
-         */
-        CREATE_NODE(ctx, new);
-
-        was_unmatched = get_ptoken(ctx, &parse, &new->token,
-                         (current != NULL ? &current->token : NULL));
-        if (!parse) {
-            break;
-        }
-
-        DEBUG_DUMP_UNMATCHED(ctx, was_unmatched);
-        DEBUG_DUMP_TOKEN(ctx, &new->token);
-
-        if (!current) {
-            switch (new->token.type) {
-            case TOKEN_STRING:
-            case TOKEN_NOT:
-            case TOKEN_ACCESS:
-            case TOKEN_LBRACE:
-                root = current = new;
-                continue;
-
-            default:
-                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, error, expr,
-                              r->filename);
-                *was_error = 1;
-                return 0;
-            }
-        }
-
-        switch (new->token.type) {
-        case TOKEN_STRING:
-            switch (current->token.type) {
-            case TOKEN_STRING:
-                current->token.value =
-                    apr_pstrcat(ctx->dpool, current->token.value,
-                                *current->token.value ? " " : "",
-                                new->token.value, NULL);
-                continue;
-
-            case TOKEN_RE:
-            case TOKEN_RBRACE:
-            case TOKEN_GROUP:
-                break;
-
-            default:
-                new->parent = current;
-                current = current->right = new;
-                continue;
-            }
-            break;
-
-        case TOKEN_RE:
-            switch (current->token.type) {
-            case TOKEN_EQ:
-            case TOKEN_NE:
-                new->parent = current;
-                current = current->right = new;
-                ++regex;
-                continue;
-
-            default:
-                break;
-            }
-            break;
-
-        case TOKEN_AND:
-        case TOKEN_OR:
-            switch (current->token.type) {
-            case TOKEN_STRING:
-            case TOKEN_RE:
-            case TOKEN_GROUP:
-                current = current->parent;
-
-                while (current) {
-                    switch (current->token.type) {
-                    case TOKEN_AND:
-                    case TOKEN_OR:
-                    case TOKEN_LBRACE:
-                        break;
-
-                    default:
-                        current = current->parent;
-                        continue;
-                    }
-                    break;
-                }
-
-                if (!current) {
-                    new->left = root;
-                    root->parent = new;
-                    current = root = new;
-                    continue;
-                }
-
-                new->left = current->right;
-                new->left->parent = new;
-                new->parent = current;
-                current = current->right = new;
-                continue;
-
-            default:
-                break;
-            }
-            break;
-
-        case TOKEN_EQ:
-        case TOKEN_NE:
-        case TOKEN_GE:
-        case TOKEN_GT:
-        case TOKEN_LE:
-        case TOKEN_LT:
-            if (current->token.type == TOKEN_STRING) {
-                current = current->parent;
-
-                if (!current) {
-                    new->left = root;
-                    root->parent = new;
-                    current = root = new;
-                    continue;
-                }
-
-                switch (current->token.type) {
-                case TOKEN_LBRACE:
-                case TOKEN_AND:
-                case TOKEN_OR:
-                    new->left = current->right;
-                    new->left->parent = new;
-                    new->parent = current;
-                    current = current->right = new;
-                    continue;
-
-                default:
-                    break;
-                }
-            }
-            break;
-
-        case TOKEN_RBRACE:
-            while (current && current->token.type != TOKEN_LBRACE) {
-                current = current->parent;
-            }
-
-            if (current) {
-                TYPE_TOKEN(&current->token, TOKEN_GROUP);
-                continue;
-            }
-
-            error = "Unmatched ')' in \"%s\" in file %s";
-            break;
-
-        case TOKEN_NOT:
-        case TOKEN_ACCESS:
-        case TOKEN_LBRACE:
-            switch (current->token.type) {
-            case TOKEN_STRING:
-            case TOKEN_RE:
-            case TOKEN_RBRACE:
-            case TOKEN_GROUP:
-                break;
-
-            default:
-                current->right = new;
-                new->parent = current;
-                current = new;
-                continue;
-            }
-            break;
-
-        default:
-            break;
-        }
-
-        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, error, expr, r->filename);
-        *was_error = 1;
-        return 0;
-    }
-
-    DEBUG_DUMP_TREE(ctx, root);
-
-    /* Evaluate Parse Tree */
-    current = root;
-    error = NULL;
-    while (current) {
-        switch (current->token.type) {
-        case TOKEN_STRING:
-            current->token.value =
-                ap_ssi_parse_string(ctx, current->token.value, NULL, 0,
-                                    SSI_EXPAND_DROP_NAME);
-            current->value = !!*current->token.value;
-            break;
-
-        case TOKEN_AND:
-        case TOKEN_OR:
-            if (!current->left || !current->right) {
-                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
-                              "Invalid expression \"%s\" in file %s",
-                              expr, r->filename);
-                *was_error = 1;
-                return 0;
-            }
-
-            if (!current->left->done) {
-                switch (current->left->token.type) {
-                case TOKEN_STRING:
-                    current->left->token.value =
-                        ap_ssi_parse_string(ctx, current->left->token.value,
-                                            NULL, 0, SSI_EXPAND_DROP_NAME);
-                    current->left->value = !!*current->left->token.value;
-                    DEBUG_DUMP_EVAL(ctx, current->left);
-                    current->left->done = 1;
-                    break;
-
-                default:
-                    current = current->left;
-                    continue;
-                }
-            }
-
-            /* short circuit evaluation */
-            if (!current->right->done && !regex &&
-                ((current->token.type == TOKEN_AND && !current->left->value) ||
-                (current->token.type == TOKEN_OR && current->left->value))) {
-                current->value = current->left->value;
-            }
-            else {
-                if (!current->right->done) {
-                    switch (current->right->token.type) {
-                    case TOKEN_STRING:
-                        current->right->token.value =
-                            ap_ssi_parse_string(ctx,current->right->token.value,
-                                                NULL, 0, SSI_EXPAND_DROP_NAME);
-                        current->right->value = !!*current->right->token.value;
-                        DEBUG_DUMP_EVAL(ctx, current->right);
-                        current->right->done = 1;
-                        break;
-
-                    default:
-                        current = current->right;
-                        continue;
-                    }
-                }
-
-                if (current->token.type == TOKEN_AND) {
-                    current->value = current->left->value &&
-                                     current->right->value;
-                }
-                else {
-                    current->value = current->left->value ||
-                                     current->right->value;
-                }
-            }
-            break;
-
-        case TOKEN_EQ:
-        case TOKEN_NE:
-            if (!current->left || !current->right ||
-                current->left->token.type != TOKEN_STRING ||
-                (current->right->token.type != TOKEN_STRING &&
-                 current->right->token.type != TOKEN_RE)) {
-                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
-                            "Invalid expression \"%s\" in file %s",
-                            expr, r->filename);
-                *was_error = 1;
-                return 0;
-            }
-            current->left->token.value =
-                ap_ssi_parse_string(ctx, current->left->token.value, NULL, 0,
-                                    SSI_EXPAND_DROP_NAME);
-            current->right->token.value =
-                ap_ssi_parse_string(ctx, current->right->token.value, NULL, 0,
-                                    SSI_EXPAND_DROP_NAME);
-
-            if (current->right->token.type == TOKEN_RE) {
-                current->value = re_check(ctx, current->left->token.value,
-                                          current->right->token.value);
-                --regex;
-            }
-            else {
-                current->value = !strcmp(current->left->token.value,
-                                         current->right->token.value);
-            }
-
-            if (current->token.type == TOKEN_NE) {
-                current->value = !current->value;
-            }
-            break;
-
-        case TOKEN_GE:
-        case TOKEN_GT:
-        case TOKEN_LE:
-        case TOKEN_LT:
-            if (!current->left || !current->right ||
-                current->left->token.type != TOKEN_STRING ||
-                current->right->token.type != TOKEN_STRING) {
-                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
-                              "Invalid expression \"%s\" in file %s",
-                              expr, r->filename);
-                *was_error = 1;
-                return 0;
-            }
-
-            current->left->token.value =
-                ap_ssi_parse_string(ctx, current->left->token.value, NULL, 0,
-                                    SSI_EXPAND_DROP_NAME);
-            current->right->token.value =
-                ap_ssi_parse_string(ctx, current->right->token.value, NULL, 0,
-                                    SSI_EXPAND_DROP_NAME);
-
-            current->value = strcmp(current->left->token.value,
-                                    current->right->token.value);
-
-            switch (current->token.type) {
-            case TOKEN_GE: current->value = current->value >= 0; break;
-            case TOKEN_GT: current->value = current->value >  0; break;
-            case TOKEN_LE: current->value = current->value <= 0; break;
-            case TOKEN_LT: current->value = current->value <  0; break;
-            default: current->value = 0; break; /* should not happen */
-            }
-            break;
-
-        case TOKEN_NOT:
-        case TOKEN_GROUP:
-            if (current->right) {
-                if (!current->right->done) {
-                    current = current->right;
-                    continue;
-                }
-                current->value = current->right->value;
-            }
-            else {
-                current->value = 1;
-            }
-
-            if (current->token.type == TOKEN_NOT) {
-                current->value = !current->value;
-            }
-            break;
-
-        case TOKEN_ACCESS:
-            if (current->left || !current->right ||
-                (current->right->token.type != TOKEN_STRING &&
-                 current->right->token.type != TOKEN_RE)) {
-                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
-                            "Invalid expression \"%s\" in file %s: Token '-A' must be followed by a URI string.",
-                            expr, r->filename);
-                *was_error = 1;
-                return 0;
-            }
-            current->right->token.value =
-                ap_ssi_parse_string(ctx, current->right->token.value, NULL, 0,
-                                    SSI_EXPAND_DROP_NAME);
-            rr = ap_sub_req_lookup_uri(current->right->token.value, r, NULL);
-            /* 400 and higher are considered access denied */
-            if (rr->status < HTTP_BAD_REQUEST) {
-                current->value = 1;
-            }
-            else {
-                current->value = 0;
-                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rr->status, r, 
-                              "mod_include: The tested "
-                              "subrequest -A \"%s\" returned an error code.",
-                              current->right->token.value);
-            }
-            ap_destroy_sub_req(rr);
-            break;
-
-        case TOKEN_RE:
-            if (!error) {
-                error = "No operator before regex in expr \"%s\" in file %s";
-            }
-        case TOKEN_LBRACE:
-            if (!error) {
-                error = "Unmatched '(' in \"%s\" in file %s";
-            }
-        default:
-            if (!error) {
-                error = "internal parser error in \"%s\" in file %s";
-            }
-
-            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, error, expr,r->filename);
-            *was_error = 1;
-            return 0;
-        }
-
-        DEBUG_DUMP_EVAL(ctx, current);
-        current->done = 1;
-        current = current->parent;
-    }
-
-    return (root ? root->value : 0);
+    ap_destroy_sub_req(rr);
+    return 0;
 }
 
-
 /*
  * +-------------------------------------------------------+
  * |                                                       |
@@ -1735,9 +1112,7 @@
          * Basically, it puts a bread crumb in here, then looks
          * for the crumb later to see if its been here.
          */
-        if (rr) {
-            ap_set_module_config(rr->request_config, &include_module, r);
-        }
+        ctx->intern->kludge_child = rr;
 
         if (!error_fmt && ap_run_sub_req(rr)) {
             error_fmt = "unable to include \"%s\" in parsed file %s";
@@ -2144,7 +1519,8 @@
 
     DEBUG_PRINTF((ctx, "****    if expr=\"%s\"\n", expr));
 
-    expr_ret = parse_expr(ctx, expr, &was_error);
+    expr_ret = ap_expr_evalstring(r, expr, &was_error, &ctx->intern->re,
+                                  ssi_parse_string, ctx->intern->access_func);
 
     if (was_error) {
         SSI_CREATE_ERROR_BUCKET(ctx, f, bb);
@@ -2218,7 +1594,8 @@
         return APR_SUCCESS;
     }
 
-    expr_ret = parse_expr(ctx, expr, &was_error);
+    expr_ret = ap_expr_evalstring(r, expr, &was_error, &ctx->intern->re,
+                                  ssi_parse_string, ctx->intern->access_func);
 
     if (was_error) {
         SSI_CREATE_ERROR_BUCKET(ctx, f, bb);
@@ -3312,6 +2689,7 @@
             if (store) {
                 if (index) {
                     APR_BUCKET_REMOVE(b);
+                    apr_bucket_setaside(b, r->pool);
                     APR_BRIGADE_INSERT_TAIL(intern->tmp_bb, b);
                     b = newb;
                 }
@@ -3364,6 +2742,7 @@
             if (store) {
                 if (index) {
                     APR_BUCKET_REMOVE(b);
+                    apr_bucket_setaside(b, r->pool);
                     APR_BRIGADE_INSERT_TAIL(intern->tmp_bb, b);
                     b = newb;
                 }
@@ -3404,6 +2783,7 @@
             default:             /* partial match */
                 newb = APR_BUCKET_NEXT(b);
                 APR_BUCKET_REMOVE(b);
+                apr_bucket_setaside(b, r->pool);
                 APR_BRIGADE_INSERT_TAIL(intern->tmp_bb, b);
                 b = newb;
                 break;
@@ -3546,7 +2926,6 @@
 {
     request_rec *r = f->r;
     include_ctx_t *ctx = f->ctx;
-    request_rec *parent;
     include_dir_config *conf = ap_get_module_config(r->per_dir_config,
                                                     &include_module);
 
@@ -3578,7 +2957,7 @@
         if (ap_allow_options(r) & OPT_INCNOEXEC) {
             ctx->flags |= SSI_FLAG_NO_EXEC;
         }
-        intern->accessenable = conf->accessenable;
+        intern->access_func = conf->accessenable ? ssi_access : NULL;
 
         ctx->if_nesting_level = 0;
         intern->re = NULL;
@@ -3592,9 +2971,24 @@
         intern->end_seq_len = strlen(intern->end_seq);
         intern->undefined_echo = conf->undefined_echo;
         intern->undefined_echo_len = strlen(conf->undefined_echo);
+        /* breadcrumb */
+        intern->kludge_child = NULL;
+        if (r->main != NULL) {
+            include_ctx_t *parent_ctx;
+            parent_ctx = ap_get_module_config(r->main->request_config,
+                                              &include_module);
+            /* if the subreq was created by mod_include then parent_ctx
+             * is not null.  If not ... well, we need to check.
+             */
+            if (parent_ctx) {
+                intern->kludge_child = parent_ctx->intern->kludge_child;
+            }
+        }
+        /* we need to be able to look up ctx in r for ssi_parse_string */
+        ap_set_module_config(r->request_config, &include_module, ctx);
     }
 
-    if ((parent = ap_get_module_config(r->request_config, &include_module))) {
+    if (ctx->intern->kludge_child == r) {
         /* Kludge --- for nested includes, we want to keep the subprocess
          * environment of the base document (for compatibility); that means
          * torquing our own last_modified date as well so that the

Modified: httpd/sandbox/amsterdam/d/modules/generators/mod_autoindex.c
URL: http://svn.apache.org/viewvc/httpd/sandbox/amsterdam/d/modules/generators/mod_autoindex.c?rev=645594&r1=645593&r2=645594&view=diff
==============================================================================
--- httpd/sandbox/amsterdam/d/modules/generators/mod_autoindex.c (original)
+++ httpd/sandbox/amsterdam/d/modules/generators/mod_autoindex.c Mon Apr  7 09:28:58 2008
@@ -162,14 +162,14 @@
 
     if (xhtml) {
         ap_rvputs(r, DOCTYPE_XHTML_1_0T,
-		  "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n"
-		  "<head>\n  <title>Index of ", title,
-		  "</title>\n", NULL);
+                  "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n"
+                  " <head>\n  <title>Index of ", title,
+                  "</title>\n", NULL);
     } else {
         ap_rvputs(r, DOCTYPE_HTML_3_2,
-		  "<html>\n <head>\n"
-		  "<title>Index of ", title,
-		  "</title>\n", NULL);
+                  "<html>\n <head>\n"
+                  "  <title>Index of ", title,
+                  "</title>\n", NULL);
     }
 
     if (d->style_sheet != NULL) {

Modified: httpd/sandbox/amsterdam/d/modules/generators/mod_cgi.c
URL: http://svn.apache.org/viewvc/httpd/sandbox/amsterdam/d/modules/generators/mod_cgi.c?rev=645594&r1=645593&r2=645594&view=diff
==============================================================================
--- httpd/sandbox/amsterdam/d/modules/generators/mod_cgi.c (original)
+++ httpd/sandbox/amsterdam/d/modules/generators/mod_cgi.c Mon Apr  7 09:28:58 2008
@@ -39,8 +39,6 @@
 #define APR_WANT_MEMFUNC
 #include "apr_want.h"
 
-#define CORE_PRIVATE
-
 #include "util_filter.h"
 #include "ap_config.h"
 #include "httpd.h"

Modified: httpd/sandbox/amsterdam/d/modules/generators/mod_cgid.c
URL: http://svn.apache.org/viewvc/httpd/sandbox/amsterdam/d/modules/generators/mod_cgid.c?rev=645594&r1=645593&r2=645594&view=diff
==============================================================================
--- httpd/sandbox/amsterdam/d/modules/generators/mod_cgid.c (original)
+++ httpd/sandbox/amsterdam/d/modules/generators/mod_cgid.c Mon Apr  7 09:28:58 2008
@@ -49,8 +49,6 @@
 #include <sys/types.h>
 #endif
 
-#define CORE_PRIVATE
-
 #include "util_filter.h"
 #include "httpd.h"
 #include "http_config.h"

Modified: httpd/sandbox/amsterdam/d/modules/generators/mod_info.c
URL: http://svn.apache.org/viewvc/httpd/sandbox/amsterdam/d/modules/generators/mod_info.c?rev=645594&r1=645593&r2=645594&view=diff
==============================================================================
--- httpd/sandbox/amsterdam/d/modules/generators/mod_info.c (original)
+++ httpd/sandbox/amsterdam/d/modules/generators/mod_info.c Mon Apr  7 09:28:58 2008
@@ -47,8 +47,6 @@
 #define APR_WANT_STRFUNC
 #include "apr_want.h"
 
-#define CORE_PRIVATE
-
 #include "httpd.h"
 #include "http_config.h"
 #include "http_core.h"
@@ -608,7 +606,7 @@
     if (r->method_number != M_GET)
         return DECLINED;
 
-    ap_set_content_type(r, "text/html");
+    ap_set_content_type(r, "text/html; charset=ISO-8859-1");
 
     ap_rputs(DOCTYPE_XHTML_1_0T
              "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n"

Modified: httpd/sandbox/amsterdam/d/modules/generators/mod_status.c
URL: http://svn.apache.org/viewvc/httpd/sandbox/amsterdam/d/modules/generators/mod_status.c?rev=645594&r1=645593&r2=645594&view=diff
==============================================================================
--- httpd/sandbox/amsterdam/d/modules/generators/mod_status.c (original)
+++ httpd/sandbox/amsterdam/d/modules/generators/mod_status.c Mon Apr  7 09:28:58 2008
@@ -54,7 +54,6 @@
  *          [Jim J.]
  */
 
-#define CORE_PRIVATE
 #include "httpd.h"
 #include "http_config.h"
 #include "http_core.h"
@@ -71,6 +70,7 @@
 #endif
 #define APR_WANT_STRFUNC
 #include "apr_want.h"
+#include "apr_strings.h"
 
 #ifdef NEXT
 #if (NX_CURRENT_COMPILER_RELEASE == 410)
@@ -296,19 +296,18 @@
             if ((loc = ap_strstr_c(r->args,
                                    status_options[i].form_data_str)) != NULL) {
                 switch (status_options[i].id) {
-                case STAT_OPT_REFRESH:
-                    if (*(loc + strlen(status_options[i].form_data_str)) == '='
-                        && atol(loc + strlen(status_options[i].form_data_str)
-                                + 1) > 0)
-                        apr_table_set(r->headers_out,
-                                      status_options[i].hdr_out_str,
-                                      loc +
-                                      strlen(status_options[i].hdr_out_str) +
-                                      1);
-                    else
-                        apr_table_set(r->headers_out,
-                                      status_options[i].hdr_out_str, "1");
+                case STAT_OPT_REFRESH: {
+                    apr_size_t len = strlen(status_options[i].form_data_str);
+                    long t = 0;
+
+                    if (*(loc + len ) == '=') {
+                        t = atol(loc + len + 1);
+                    }
+                    apr_table_set(r->headers_out,
+                                  status_options[i].hdr_out_str,
+                                  apr_ltoa(r->pool, t < 1 ? 10 : t));
                     break;
+                }
                 case STAT_OPT_NOTABLE:
                     no_table_report = 1;
                     break;

Modified: httpd/sandbox/amsterdam/d/modules/generators/mod_suexec.c
URL: http://svn.apache.org/viewvc/httpd/sandbox/amsterdam/d/modules/generators/mod_suexec.c?rev=645594&r1=645593&r2=645594&view=diff
==============================================================================
--- httpd/sandbox/amsterdam/d/modules/generators/mod_suexec.c (original)
+++ httpd/sandbox/amsterdam/d/modules/generators/mod_suexec.c Mon Apr  7 09:28:58 2008
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-#define CORE_PRIVATE
 #include "httpd.h"
 #include "http_config.h"
 #include "http_core.h"
@@ -60,7 +59,7 @@
                                    const char *uid, const char *gid)
 {
     suexec_config_t *cfg = (suexec_config_t *) mconfig;
-    const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT);
+    const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE);
 
     if (err != NULL) {
         return err;

Modified: httpd/sandbox/amsterdam/d/modules/http/byterange_filter.c
URL: http://svn.apache.org/viewvc/httpd/sandbox/amsterdam/d/modules/http/byterange_filter.c?rev=645594&r1=645593&r2=645594&view=diff
==============================================================================
--- httpd/sandbox/amsterdam/d/modules/http/byterange_filter.c (original)
+++ httpd/sandbox/amsterdam/d/modules/http/byterange_filter.c Mon Apr  7 09:28:58 2008
@@ -29,7 +29,6 @@
 #define APR_WANT_MEMFUNC
 #include "apr_want.h"
 
-#define CORE_PRIVATE
 #include "util_filter.h"
 #include "ap_config.h"
 #include "httpd.h"

Modified: httpd/sandbox/amsterdam/d/modules/http/chunk_filter.c
URL: http://svn.apache.org/viewvc/httpd/sandbox/amsterdam/d/modules/http/chunk_filter.c?rev=645594&r1=645593&r2=645594&view=diff
==============================================================================
--- httpd/sandbox/amsterdam/d/modules/http/chunk_filter.c (original)
+++ httpd/sandbox/amsterdam/d/modules/http/chunk_filter.c Mon Apr  7 09:28:58 2008
@@ -24,7 +24,6 @@
 #define APR_WANT_STRFUNC
 #include "apr_want.h"
 
-#define CORE_PRIVATE
 #include "httpd.h"
 #include "http_config.h"
 #include "http_connection.h"
@@ -85,7 +84,9 @@
             }
             if (APR_BUCKET_IS_FLUSH(e)) {
                 flush = e;
-                more = apr_brigade_split(b, APR_BUCKET_NEXT(e));
+                if (e != APR_BRIGADE_LAST(b)) {
+                    more = apr_brigade_split(b, APR_BUCKET_NEXT(e));
+                }
                 break;
             }
             else if (e->length == (apr_size_t)-1) {

Modified: httpd/sandbox/amsterdam/d/modules/http/http_core.c
URL: http://svn.apache.org/viewvc/httpd/sandbox/amsterdam/d/modules/http/http_core.c?rev=645594&r1=645593&r2=645594&view=diff
==============================================================================
--- httpd/sandbox/amsterdam/d/modules/http/http_core.c (original)
+++ httpd/sandbox/amsterdam/d/modules/http/http_core.c Mon Apr  7 09:28:58 2008
@@ -20,7 +20,6 @@
 #define APR_WANT_STRFUNC
 #include "apr_want.h"
 
-#define CORE_PRIVATE
 #include "httpd.h"
 #include "http_config.h"
 #include "http_connection.h"
@@ -49,7 +48,7 @@
 static const char *set_keep_alive_timeout(cmd_parms *cmd, void *dummy,
                                           const char *arg)
 {
-    const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT);
+    const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE);
     if (err != NULL) {
         return err;
     }
@@ -61,7 +60,7 @@
 static const char *set_keep_alive(cmd_parms *cmd, void *dummy,
                                   const char *arg)
 {
-    const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT);
+    const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE);
     if (err != NULL) {
         return err;
     }
@@ -81,7 +80,7 @@
 static const char *set_keep_alive_max(cmd_parms *cmd, void *dummy,
                                       const char *arg)
 {
-    const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT);
+    const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE);
     if (err != NULL) {
         return err;
     }
@@ -221,8 +220,14 @@
 
         ap_update_child_status(c->sbh, SERVER_BUSY_KEEPALIVE, NULL);
 
-        if (ap_graceful_stop_signalled())
+        int mpm_state = 0;
+        if (ap_mpm_query(AP_MPMQ_MPM_STATE, &mpm_state)) {
             break;
+        }
+
+        if (mpm_state == AP_MPMQ_STOPPING) {
+          break;
+        }
 
         if (!csd) {
             csd = ap_get_module_config(c->conn_config, &core_module);

Modified: httpd/sandbox/amsterdam/d/modules/http/http_etag.c
URL: http://svn.apache.org/viewvc/httpd/sandbox/amsterdam/d/modules/http/http_etag.c?rev=645594&r1=645593&r2=645594&view=diff
==============================================================================
--- httpd/sandbox/amsterdam/d/modules/http/http_etag.c (original)
+++ httpd/sandbox/amsterdam/d/modules/http/http_etag.c Mon Apr  7 09:28:58 2008
@@ -20,7 +20,6 @@
 #define APR_WANT_STRFUNC
 #include "apr_want.h"
 
-#define CORE_PRIVATE
 #include "httpd.h"
 #include "http_config.h"
 #include "http_connection.h"

Modified: httpd/sandbox/amsterdam/d/modules/http/http_filters.c
URL: http://svn.apache.org/viewvc/httpd/sandbox/amsterdam/d/modules/http/http_filters.c?rev=645594&r1=645593&r2=645594&view=diff
==============================================================================
--- httpd/sandbox/amsterdam/d/modules/http/http_filters.c (original)
+++ httpd/sandbox/amsterdam/d/modules/http/http_filters.c Mon Apr  7 09:28:58 2008
@@ -29,7 +29,6 @@
 #define APR_WANT_MEMFUNC
 #include "apr_want.h"
 
-#define CORE_PRIVATE
 #include "util_filter.h"
 #include "ap_config.h"
 #include "httpd.h"
@@ -55,6 +54,8 @@
 #include <unistd.h>
 #endif
 
+#define INVALID_CHAR -2
+
 extern module AP_MODULE_DECLARE_DATA http_module;
 
 static long get_chunk_size(char *);
@@ -70,8 +71,141 @@
         BODY_CHUNK_PART
     } state;
     int eos_sent;
+    char chunk_ln[32];
+    char *pos;
+    apr_off_t linesize;
+    apr_bucket_brigade *bb;
 } http_ctx_t;
 
+static apr_status_t bail_out_on_error(http_ctx_t *ctx,
+                                      ap_filter_t *f,
+                                      int http_error)
+{
+    apr_bucket *e;
+    apr_bucket_brigade *bb = ctx->bb;
+
+    apr_brigade_cleanup(bb);
+    e = ap_bucket_error_create(http_error,
+                               NULL, f->r->pool,
+                               f->c->bucket_alloc);
+    APR_BRIGADE_INSERT_TAIL(bb, e);
+    e = apr_bucket_eos_create(f->c->bucket_alloc);
+    APR_BRIGADE_INSERT_TAIL(bb, e);
+    ctx->eos_sent = 1;
+    return ap_pass_brigade(f->r->output_filters, bb);
+}
+
+static apr_status_t get_remaining_chunk_line(http_ctx_t *ctx,
+                                             apr_bucket_brigade *b,
+                                             int linelimit)
+{
+    apr_status_t rv;
+    apr_off_t brigade_length;
+    apr_bucket *e;
+    const char *lineend;
+    apr_size_t len;
+
+    /*
+     * As the brigade b should have been requested in mode AP_MODE_GETLINE
+     * all buckets in this brigade are already some type of memory
+     * buckets (due to the needed scanning for LF in mode AP_MODE_GETLINE)
+     * or META buckets.
+     */
+    rv = apr_brigade_length(b, 0, &brigade_length);
+    if (rv != APR_SUCCESS) {
+        return rv;
+    }
+    /* Sanity check. Should never happen. See above. */
+    if (brigade_length == -1) {
+        return APR_EGENERAL;
+    }
+    if (!brigade_length) {
+        return APR_EAGAIN;
+    }
+    ctx->linesize += brigade_length;
+    if (ctx->linesize > linelimit) {
+        return APR_ENOSPC;
+    }
+    /*
+     * As all buckets are already some type of memory buckets or META buckets
+     * (see above), we only need to check the last byte in the last data bucket.
+     */
+    for (e = APR_BRIGADE_LAST(b);
+         e != APR_BRIGADE_SENTINEL(b);
+         e = APR_BUCKET_PREV(e)) {
+
+        if (APR_BUCKET_IS_METADATA(e)) {
+            continue;
+        }
+        rv = apr_bucket_read(e, &lineend, &len, APR_BLOCK_READ);
+        if (rv != APR_SUCCESS) {
+            return rv;
+        }
+        if (len > 0) {
+            break;  /* we got the data we want */
+        }
+        /* If we got a zero-length data bucket, we try the next one */
+    }
+    /* We had no data in this brigade */
+    if (!len || e == APR_BRIGADE_SENTINEL(b)) {
+        return APR_EAGAIN;
+    }
+    if (lineend[len - 1] != APR_ASCII_LF) {
+        return APR_EAGAIN;
+    }
+    /* Line is complete. So reset ctx->linesize for next round. */
+    ctx->linesize = 0;
+    return APR_SUCCESS;
+}
+
+static apr_status_t get_chunk_line(http_ctx_t *ctx, apr_bucket_brigade *b,
+                                   int linelimit)
+{
+    apr_size_t len;
+    int tmp_len;
+    apr_status_t rv;
+
+    tmp_len = sizeof(ctx->chunk_ln) - (ctx->pos - ctx->chunk_ln) - 1;
+    /* Saveguard ourselves against underflows */
+    if (tmp_len < 0) {
+        len = 0;
+    }
+    else {
+        len = (apr_size_t) tmp_len;
+    }
+    /*
+     * Check if there is space left in ctx->chunk_ln. If not, then either
+     * the chunk size is insane or we have chunk-extensions. Ignore both
+     * by discarding the remaining part of the line via
+     * get_remaining_chunk_line. Only bail out if the line is too long.
+     */
+    if (len > 0) {
+        rv = apr_brigade_flatten(b, ctx->pos, &len);
+        if (rv != APR_SUCCESS) {
+            return rv;
+        }
+        ctx->pos += len;
+        ctx->linesize += len;
+        *(ctx->pos) = '\0';
+        /*
+         * Check if we really got a full line. If yes the
+         * last char in the just read buffer must be LF.
+         * If not advance the buffer and return APR_EAGAIN.
+         * We do not start processing until we have the
+         * full line.
+         */
+        if (ctx->pos[-1] != APR_ASCII_LF) {
+            /* Check if the remaining data in the brigade has the LF */
+            return get_remaining_chunk_line(ctx, b, linelimit);
+        }
+        /* Line is complete. So reset ctx->pos for next round. */
+        ctx->pos = ctx->chunk_ln;
+        return APR_SUCCESS;
+    }
+    return get_remaining_chunk_line(ctx, b, linelimit);
+}
+
+
 /* This is the HTTP_INPUT filter for HTTP requests and responses from
  * proxied servers (mod_proxy).  It handles chunked and content-length
  * bodies.  This can only be inserted/used after the headers
@@ -85,6 +219,8 @@
     http_ctx_t *ctx = f->ctx;
     apr_status_t rv;
     apr_off_t totalread;
+    int http_error = HTTP_REQUEST_ENTITY_TOO_LARGE;
+    apr_bucket_brigade *bb;
 
     /* just get out of the way of things we don't want. */
     if (mode != AP_MODE_READBYTES && mode != AP_MODE_GETLINE) {
@@ -93,11 +229,11 @@
 
     if (!ctx) {
         const char *tenc, *lenp;
-        f->ctx = ctx = apr_palloc(f->r->pool, sizeof(*ctx));
+        f->ctx = ctx = apr_pcalloc(f->r->pool, sizeof(*ctx));
         ctx->state = BODY_NONE;
-        ctx->remaining = 0;
-        ctx->limit_used = 0;
-        ctx->eos_sent = 0;
+        ctx->pos = ctx->chunk_ln;
+        ctx->bb = apr_brigade_create(f->r->pool, f->c->bucket_alloc);
+        bb = ctx->bb;
 
         /* LimitRequestBody does not apply to proxied responses.
          * Consider implementing this check in its own filter.
@@ -118,8 +254,22 @@
             if (!strcasecmp(tenc, "chunked")) {
                 ctx->state = BODY_CHUNK;
             }
+            /* test lenp, because it gives another case we can handle */
+            else if (!lenp) {
+                /* Something that isn't in HTTP, unless some future
+                 * edition defines new transfer ecodings, is unsupported.
+                 */
+                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, f->r,
+                              "Unknown Transfer-Encoding: %s", tenc);
+                return bail_out_on_error(ctx, f, HTTP_NOT_IMPLEMENTED);
+            }
+            else {
+                ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, f->r,
+                  "Unknown Transfer-Encoding: %s; using Content-Length", tenc);
+                tenc = NULL;
+            }
         }
-        else if (lenp) {
+        if (lenp && !tenc) {
             char *endstr;
 
             ctx->state = BODY_LENGTH;
@@ -130,39 +280,23 @@
              * and a negative number. */
             if (apr_strtoff(&ctx->remaining, lenp, &endstr, 10)
                 || endstr == lenp || *endstr || ctx->remaining < 0) {
-                apr_bucket_brigade *bb;
 
                 ctx->remaining = 0;
                 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, f->r,
                               "Invalid Content-Length");
 
-                bb = apr_brigade_create(f->r->pool, f->c->bucket_alloc);
-                e = ap_bucket_error_create(HTTP_REQUEST_ENTITY_TOO_LARGE, NULL,
-                                           f->r->pool, f->c->bucket_alloc);
-                APR_BRIGADE_INSERT_TAIL(bb, e);
-                e = apr_bucket_eos_create(f->c->bucket_alloc);
-                APR_BRIGADE_INSERT_TAIL(bb, e);
-                ctx->eos_sent = 1;
-                return ap_pass_brigade(f->r->output_filters, bb);
+                return bail_out_on_error(ctx, f, HTTP_REQUEST_ENTITY_TOO_LARGE);
             }
 
             /* If we have a limit in effect and we know the C-L ahead of
              * time, stop it here if it is invalid.
              */
             if (ctx->limit && ctx->limit < ctx->remaining) {
-                apr_bucket_brigade *bb;
                 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, f->r,
                           "Requested content-length of %" APR_OFF_T_FMT
                           " is larger than the configured limit"
                           " of %" APR_OFF_T_FMT, ctx->remaining, ctx->limit);
-                bb = apr_brigade_create(f->r->pool, f->c->bucket_alloc);
-                e = ap_bucket_error_create(HTTP_REQUEST_ENTITY_TOO_LARGE, NULL,
-                                           f->r->pool, f->c->bucket_alloc);
-                APR_BRIGADE_INSERT_TAIL(bb, e);
-                e = apr_bucket_eos_create(f->c->bucket_alloc);
-                APR_BRIGADE_INSERT_TAIL(bb, e);
-                ctx->eos_sent = 1;
-                return ap_pass_brigade(f->r->output_filters, bb);
+                return bail_out_on_error(ctx, f, HTTP_REQUEST_ENTITY_TOO_LARGE);
             }
         }
 
@@ -190,29 +324,28 @@
             (ctx->state == BODY_LENGTH && ctx->remaining > 0)) &&
             f->r->expecting_100 && f->r->proto_num >= HTTP_VERSION(1,1) &&
             !(f->r->eos_sent || f->r->bytes_sent)) {
-            char *tmp;
-            apr_bucket_brigade *bb;
+            if (ap_is_HTTP_CLIENT_ERROR(f->r->status)) {
+                ctx->state = BODY_NONE;
+                ctx->eos_sent = 1;
+            } else {
+                char *tmp;
 
-            tmp = apr_pstrcat(f->r->pool, AP_SERVER_PROTOCOL, " ",
-                              ap_get_status_line(100), CRLF CRLF, NULL);
-            bb = apr_brigade_create(f->r->pool, f->c->bucket_alloc);
-            e = apr_bucket_pool_create(tmp, strlen(tmp), f->r->pool,
-                                       f->c->bucket_alloc);
-            APR_BRIGADE_INSERT_HEAD(bb, e);
-            e = apr_bucket_flush_create(f->c->bucket_alloc);
-            APR_BRIGADE_INSERT_TAIL(bb, e);
+                tmp = apr_pstrcat(f->r->pool, AP_SERVER_PROTOCOL, " ",
+                                  ap_get_status_line(100), CRLF CRLF, NULL);
+                apr_brigade_cleanup(bb);
+                e = apr_bucket_pool_create(tmp, strlen(tmp), f->r->pool,
+                                           f->c->bucket_alloc);
+                APR_BRIGADE_INSERT_HEAD(bb, e);
+                e = apr_bucket_flush_create(f->c->bucket_alloc);
+                APR_BRIGADE_INSERT_TAIL(bb, e);
 
-            ap_pass_brigade(f->c->output_filters, bb);
+                ap_pass_brigade(f->c->output_filters, bb);
+            }
         }
 
         /* We can't read the chunk until after sending 100 if required. */
         if (ctx->state == BODY_CHUNK) {
-            char line[30];
-            apr_bucket_brigade *bb;
-            apr_size_t len = 30;
-            apr_off_t brigade_length;
-
-            bb = apr_brigade_create(f->r->pool, f->c->bucket_alloc);
+            apr_brigade_cleanup(bb);
 
             rv = ap_get_brigade(f->next, bb, AP_MODE_GETLINE,
                                 block, 0);
@@ -221,23 +354,22 @@
             if (block == APR_NONBLOCK_READ &&
                 ( (rv == APR_SUCCESS && APR_BRIGADE_EMPTY(bb)) ||
                   (APR_STATUS_IS_EAGAIN(rv)) )) {
+                ctx->state = BODY_CHUNK_PART;
                 return APR_EAGAIN;
             }
 
             if (rv == APR_SUCCESS) {
-                /* We have to check the length of the brigade we got back.
-                 * We will not accept partial or blank lines.
-                 */
-                rv = apr_brigade_length(bb, 1, &brigade_length);
-                if (rv == APR_SUCCESS
-                    && (!brigade_length ||
-                        brigade_length > f->r->server->limit_req_line)) {
-                    rv = APR_ENOSPC;
+                rv = get_chunk_line(ctx, bb, f->r->server->limit_req_line);
+                if (APR_STATUS_IS_EAGAIN(rv)) {
+                    apr_brigade_cleanup(bb);
+                    ctx->state = BODY_CHUNK_PART;
+                    return rv;
                 }
                 if (rv == APR_SUCCESS) {
-                    rv = apr_brigade_flatten(bb, line, &len);
-                    if (rv == APR_SUCCESS) {
-                        ctx->remaining = get_chunk_size(line);
+                    ctx->remaining = get_chunk_size(ctx->chunk_ln);
+                    if (ctx->remaining == INVALID_CHAR) {
+                        rv = APR_EGENERAL;
+                        http_error = HTTP_SERVICE_UNAVAILABLE;
                     }
                 }
             }
@@ -247,14 +379,7 @@
             if (rv != APR_SUCCESS || ctx->remaining < 0) {
                 ctx->remaining = 0; /* Reset it in case we have to
                                      * come back here later */
-                e = ap_bucket_error_create(HTTP_REQUEST_ENTITY_TOO_LARGE, NULL,
-                                           f->r->pool,
-                                           f->c->bucket_alloc);
-                APR_BRIGADE_INSERT_TAIL(bb, e);
-                e = apr_bucket_eos_create(f->c->bucket_alloc);
-                APR_BRIGADE_INSERT_TAIL(bb, e);
-                ctx->eos_sent = 1;
-                return ap_pass_brigade(f->r->output_filters, bb);
+                return bail_out_on_error(ctx, f, http_error);
             }
 
             if (!ctx->remaining) {
@@ -268,6 +393,9 @@
             }
         }
     }
+    else {
+        bb = ctx->bb;
+    }
 
     if (ctx->eos_sent) {
         e = apr_bucket_eos_create(f->c->bucket_alloc);
@@ -284,24 +412,36 @@
             APR_BRIGADE_INSERT_TAIL(b, e);
             ctx->eos_sent = 1;
             return APR_SUCCESS;
-        case BODY_CHUNK: case BODY_CHUNK_PART:
+        case BODY_CHUNK:
+        case BODY_CHUNK_PART:
             {
-                char line[30];
-                apr_bucket_brigade *bb;
-                apr_size_t len = 30;
-                apr_status_t http_error = HTTP_REQUEST_ENTITY_TOO_LARGE;
-
-                bb = apr_brigade_create(f->r->pool, f->c->bucket_alloc);
+                apr_brigade_cleanup(bb);
 
                 /* We need to read the CRLF after the chunk.  */
                 if (ctx->state == BODY_CHUNK) {
                     rv = ap_get_brigade(f->next, bb, AP_MODE_GETLINE,
                                         block, 0);
-                    apr_brigade_cleanup(bb);
                     if (block == APR_NONBLOCK_READ &&
-                        (APR_STATUS_IS_EAGAIN(rv))) {
+                        ( (rv == APR_SUCCESS && APR_BRIGADE_EMPTY(bb)) ||
+                          (APR_STATUS_IS_EAGAIN(rv)) )) {
                         return APR_EAGAIN;
                     }
+                    /* If we get an error, then leave */
+                    if (rv != APR_SUCCESS) {
+                        return rv;
+                    }
+                    /*
+                     * We really don't care whats on this line. If it is RFC
+                     * compliant it should be only \r\n. If there is more
+                     * before we just ignore it as long as we do not get over
+                     * the limit for request lines.
+                     */
+                    rv = get_remaining_chunk_line(ctx, bb,
+                                                  f->r->server->limit_req_line);
+                    apr_brigade_cleanup(bb);
+                    if (APR_STATUS_IS_EAGAIN(rv)) {
+                        return rv;
+                    }
                 } else {
                     rv = APR_SUCCESS;
                 }
@@ -319,16 +459,18 @@
                     }
                     ctx->state = BODY_CHUNK;
                     if (rv == APR_SUCCESS) {
-                        rv = apr_brigade_flatten(bb, line, &len);
+                        rv = get_chunk_line(ctx, bb, f->r->server->limit_req_line);
+                        if (APR_STATUS_IS_EAGAIN(rv)) {
+                            ctx->state = BODY_CHUNK_PART;
+                            apr_brigade_cleanup(bb);
+                            return rv;
+                        }
                         if (rv == APR_SUCCESS) {
-                            /* Wait a sec, that's a blank line!  Oh no. */
-                            if (!len) {
+                            ctx->remaining = get_chunk_size(ctx->chunk_ln);
+                            if (ctx->remaining == INVALID_CHAR) {
                                 rv = APR_EGENERAL;
                                 http_error = HTTP_SERVICE_UNAVAILABLE;
                             }
-                            else {
-                                ctx->remaining = get_chunk_size(line);
-                            }
                         }
                     }
                     apr_brigade_cleanup(bb);
@@ -336,18 +478,9 @@
 
                 /* Detect chunksize error (such as overflow) */
                 if (rv != APR_SUCCESS || ctx->remaining < 0) {
-                    apr_status_t out_error;
-
                     ctx->remaining = 0; /* Reset it in case we have to
                                          * come back here later */
-                    e = ap_bucket_error_create(http_error,
-                                               NULL, f->r->pool,
-                                               f->c->bucket_alloc);
-                    APR_BRIGADE_INSERT_TAIL(bb, e);
-                    e = apr_bucket_eos_create(f->c->bucket_alloc);
-                    APR_BRIGADE_INSERT_TAIL(bb, e);
-                    ctx->eos_sent = 1;
-                    out_error = ap_pass_brigade(f->r->output_filters, bb);
+                    bail_out_on_error(ctx, f, http_error);
                     return rv;
                 }
 
@@ -405,12 +538,11 @@
          * really count.  This seems to be up for interpretation.  */
         ctx->limit_used += totalread;
         if (ctx->limit < ctx->limit_used) {
-            apr_bucket_brigade *bb;
             ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, f->r,
                           "Read content-length of %" APR_OFF_T_FMT
                           " is larger than the configured limit"
                           " of %" APR_OFF_T_FMT, ctx->limit_used, ctx->limit);
-            bb = apr_brigade_create(f->r->pool, f->c->bucket_alloc);
+            apr_brigade_cleanup(bb);
             e = ap_bucket_error_create(HTTP_REQUEST_ENTITY_TOO_LARGE, NULL,
                                        f->r->pool,
                                        f->c->bucket_alloc);
@@ -441,6 +573,13 @@
 
     ap_xlate_proto_from_ascii(b, strlen(b));
 
+    if (!apr_isxdigit(*b)) {
+        /*
+         * Detect invalid character at beginning. This also works for empty
+         * chunk size lines.
+         */
+        return INVALID_CHAR;
+    }
     /* Skip leading zeros */
     while (*b == '0') {
         ++b;
@@ -1042,10 +1181,22 @@
 
     if (!apr_is_empty_array(r->content_languages)) {
         int i;
+        char *token;
         char **languages = (char **)(r->content_languages->elts);
-        for (i = 0; i < r->content_languages->nelts; ++i) {
-            apr_table_mergen(r->headers_out, "Content-Language", languages[i]);
+        const char *field = apr_table_get(r->headers_out, "Content-Language");
+
+        while (field && (token = ap_get_list_item(r->pool, &field)) != NULL) {
+            for (i = 0; i < r->content_languages->nelts; ++i) {
+                if (!strcasecmp(token, languages[i]))
+                    break;
+            }
+            if (i == r->content_languages->nelts) {
+                *((char **) apr_array_push(r->content_languages)) = token;
+            }
         }
+
+        field = apr_array_pstrcat(r->pool, r->content_languages, ',');
+        apr_table_setn(r->headers_out, "Content-Language", field);
     }
 
     /*
@@ -1151,7 +1302,7 @@
     apr_bucket *e;
     int rv, seen_eos;
     core_dir_conf *dconf;
-    apr_size_t left = 0;
+    apr_off_t left = 0;
 
     /* Sometimes we'll get in a state where the input handling has
      * detected an error where we want to drop the connection, so if

Modified: httpd/sandbox/amsterdam/d/modules/http/http_protocol.c
URL: http://svn.apache.org/viewvc/httpd/sandbox/amsterdam/d/modules/http/http_protocol.c?rev=645594&r1=645593&r2=645594&view=diff
==============================================================================
--- httpd/sandbox/amsterdam/d/modules/http/http_protocol.c (original)
+++ httpd/sandbox/amsterdam/d/modules/http/http_protocol.c Mon Apr  7 09:28:58 2008
@@ -32,7 +32,6 @@
 #define APR_WANT_MEMFUNC
 #include "apr_want.h"
 
-#define CORE_PRIVATE
 #include "util_filter.h"
 #include "ap_config.h"
 #include "httpd.h"
@@ -48,6 +47,7 @@
 #include "util_charset.h"
 #include "util_ebcdic.h"
 #include "util_time.h"
+#include "ap_mpm.h"
 
 #include "mod_core.h"
 
@@ -157,6 +157,21 @@
  */
 #define METHOD_NUMBER_LAST  62
 
+static int is_mpm_running(void)
+{
+    int mpm_state = 0;
+
+    if (ap_mpm_query(AP_MPMQ_MPM_STATE, &mpm_state)) {
+      return 0;
+    }
+  
+    if (mpm_state == AP_MPMQ_STOPPING) {
+      return 0;
+    }
+
+    return 1;
+}
+
 
 AP_DECLARE(int) ap_set_keepalive(request_rec *r)
 {
@@ -187,6 +202,7 @@
      *       or they're a buggy twit coming through a HTTP/1.1 proxy
      *   and    the client is requesting an HTTP/1.0-style keep-alive
      *       or the client claims to be HTTP/1.1 compliant (perhaps a proxy);
+     *   and this MPM process is not already exiting
      *   THEN we can be persistent, which requires more headers be output.
      *
      * Note that the condition evaluation order is extremely important.
@@ -212,7 +228,8 @@
         && (!apr_table_get(r->subprocess_env, "nokeepalive")
             || apr_table_get(r->headers_in, "Via"))
         && ((ka_sent = ap_find_token(r->pool, conn, "keep-alive"))
-            || (r->proto_num >= HTTP_VERSION(1,1)))) {
+            || (r->proto_num >= HTTP_VERSION(1,1)))
+        && is_mpm_running()) {
         int left = r->server->keep_alive_max - r->connection->keepalives;
 
         r->connection->keepalive = AP_CONN_KEEPALIVE;
@@ -910,7 +927,8 @@
                            NULL));
     case HTTP_METHOD_NOT_ALLOWED:
         return(apr_pstrcat(p,
-                           "<p>The requested method ", r->method,
+                           "<p>The requested method ",
+                           ap_escape_html(r->pool, r->method),
                            " is not allowed for the URL ",
                            ap_escape_html(r->pool, r->uri),
                            ".</p>\n",
@@ -928,7 +946,7 @@
     case HTTP_LENGTH_REQUIRED:
         s1 = apr_pstrcat(p,
                          "<p>A request of the requested method ",
-                         r->method,
+                         ap_escape_html(r->pool, r->method),
                          " requires a valid Content-length.<br />\n",
                          NULL);
         return(add_optional_notes(r, s1, "error-notes", "</p>\n"));
@@ -975,7 +993,7 @@
                            "The requested resource<br />",
                            ap_escape_html(r->pool, r->uri), "<br />\n",
                            "does not allow request data with ",
-                           r->method,
+                           ap_escape_html(r->pool, r->method),
                            " requests, or the amount of data provided in\n"
                            "the request exceeds the capacity limit.\n",
                            NULL));

Modified: httpd/sandbox/amsterdam/d/modules/http/http_request.c
URL: http://svn.apache.org/viewvc/httpd/sandbox/amsterdam/d/modules/http/http_request.c?rev=645594&r1=645593&r2=645594&view=diff
==============================================================================
--- httpd/sandbox/amsterdam/d/modules/http/http_request.c (original)
+++ httpd/sandbox/amsterdam/d/modules/http/http_request.c Mon Apr  7 09:28:58 2008
@@ -31,7 +31,6 @@
 #define APR_WANT_STRFUNC
 #include "apr_want.h"
 
-#define CORE_PRIVATE
 #include "ap_config.h"
 #include "httpd.h"
 #include "http_config.h"

Modified: httpd/sandbox/amsterdam/d/modules/ldap/README.ldap
URL: http://svn.apache.org/viewvc/httpd/sandbox/amsterdam/d/modules/ldap/README.ldap?rev=645594&r1=645593&r2=645594&view=diff
==============================================================================
--- httpd/sandbox/amsterdam/d/modules/ldap/README.ldap (original)
+++ httpd/sandbox/amsterdam/d/modules/ldap/README.ldap Mon Apr  7 09:28:58 2008
@@ -38,7 +38,7 @@
 3. Compile the two modules util_ldap and mod_authnz_ldap using the dsp files
 4. You get a mod_authnz_ldap.so and a mod_ldap.so module
 5. Put them in the modules directory, don't forget to copy the
-   nsldap32v50.dll somewhere where apache.exe will find it
+   nsldap32v50.dll somewhere where httpd.exe will find it
 6. Load the two modules in your httpd.conf, like below:
    LoadModule ldap_module modules/mod_ldap.so
    LoadModule authnz_ldap_module modules/mod_authnz_ldap.so



Mime
View raw message