mod_proxy_ajp.c revision db9143eba1badc5e5ddf5fac58d705d332f1873d
11178d20048abeee671d0cdb2aab6dfbaa36293bjvergara/* Licensed to the Apache Software Foundation (ASF) under one or more
11178d20048abeee671d0cdb2aab6dfbaa36293bjvergara * contributor license agreements. See the NOTICE file distributed with
11178d20048abeee671d0cdb2aab6dfbaa36293bjvergara * this work for additional information regarding copyright ownership.
11178d20048abeee671d0cdb2aab6dfbaa36293bjvergara * The ASF licenses this file to You under the Apache License, Version 2.0
11178d20048abeee671d0cdb2aab6dfbaa36293bjvergara * (the "License"); you may not use this file except in compliance with
11178d20048abeee671d0cdb2aab6dfbaa36293bjvergara * the License. You may obtain a copy of the License at
11178d20048abeee671d0cdb2aab6dfbaa36293bjvergara * Unless required by applicable law or agreed to in writing, software
11178d20048abeee671d0cdb2aab6dfbaa36293bjvergara * distributed under the License is distributed on an "AS IS" BASIS,
11178d20048abeee671d0cdb2aab6dfbaa36293bjvergara * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11178d20048abeee671d0cdb2aab6dfbaa36293bjvergara * See the License for the specific language governing permissions and
11178d20048abeee671d0cdb2aab6dfbaa36293bjvergara * limitations under the License.
11178d20048abeee671d0cdb2aab6dfbaa36293bjvergara/* AJP routines for Apache proxy */
11178d20048abeee671d0cdb2aab6dfbaa36293bjvergara * Canonicalise http-like URLs.
11178d20048abeee671d0cdb2aab6dfbaa36293bjvergara * scheme is the scheme for the URL
11178d20048abeee671d0cdb2aab6dfbaa36293bjvergara * url is the URL starting with the first '/'
11178d20048abeee671d0cdb2aab6dfbaa36293bjvergara * def_port is the default port for this scheme.
11178d20048abeee671d0cdb2aab6dfbaa36293bjvergarastatic int proxy_ajp_canon(request_rec *r, char *url)
11178d20048abeee671d0cdb2aab6dfbaa36293bjvergara const char *err;
11178d20048abeee671d0cdb2aab6dfbaa36293bjvergara /* ap_port_of_scheme() */
11178d20048abeee671d0cdb2aab6dfbaa36293bjvergara ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
11178d20048abeee671d0cdb2aab6dfbaa36293bjvergara * do syntactic check.
11178d20048abeee671d0cdb2aab6dfbaa36293bjvergara * We break the URL into host, port, path, search
11178d20048abeee671d0cdb2aab6dfbaa36293bjvergara err = ap_proxy_canon_netloc(r->pool, &url, NULL, NULL, &host, &port);
11178d20048abeee671d0cdb2aab6dfbaa36293bjvergara "error parsing URL %s: %s",
11178d20048abeee671d0cdb2aab6dfbaa36293bjvergara * now parse path/search args, according to rfc1738:
11178d20048abeee671d0cdb2aab6dfbaa36293bjvergara * process the path. With proxy-nocanon set (by
11178d20048abeee671d0cdb2aab6dfbaa36293bjvergara * mod_proxy) we use the raw, unparsed uri
11178d20048abeee671d0cdb2aab6dfbaa36293bjvergara path = ap_proxy_canonenc(r->pool, url, strlen(url), enc_path, 0,
11178d20048abeee671d0cdb2aab6dfbaa36293bjvergara /* if literal IPv6 address */
11178d20048abeee671d0cdb2aab6dfbaa36293bjvergara r->filename = apr_pstrcat(r->pool, "proxy:ajp://", host, sport,
11178d20048abeee671d0cdb2aab6dfbaa36293bjvergara * RFC2616 (9.1.2): GET, HEAD, PUT, DELETE, OPTIONS, TRACE are considered
11178d20048abeee671d0cdb2aab6dfbaa36293bjvergara * idempotent. Hint: HEAD requests use M_GET as method number as well.
11178d20048abeee671d0cdb2aab6dfbaa36293bjvergara * If the request has arguments it might have side-effects and thus
11178d20048abeee671d0cdb2aab6dfbaa36293bjvergara * it might be undesirable to resent it to a backend again
11178d20048abeee671d0cdb2aab6dfbaa36293bjvergara * automatically.
11178d20048abeee671d0cdb2aab6dfbaa36293bjvergara /* Everything else is not considered idempotent. */
11178d20048abeee671d0cdb2aab6dfbaa36293bjvergarastatic apr_off_t get_content_length(request_rec * r)
11178d20048abeee671d0cdb2aab6dfbaa36293bjvergara if (r->clength > 0) {
11178d20048abeee671d0cdb2aab6dfbaa36293bjvergara const char *clp = apr_table_get(r->headers_in, "Content-Length");
11178d20048abeee671d0cdb2aab6dfbaa36293bjvergara if (apr_strtoff(&len, clp, &errp, 10) || *errp || len < 0) {
int result;
apr_bucket *e;
char *buff;
char *send_body_chunk_buff;
const char *tenc;
int output_failed = 0;
int backend_failed = 0;
int data_sent = 0;
int request_ended = 0;
int headers_sent = 0;
int rv = 0;
int send_body = 0;
return HTTP_BAD_REQUEST;
return HTTP_SERVICE_UNAVAILABLE;
return HTTP_INTERNAL_SERVER_ERROR;
return HTTP_INTERNAL_SERVER_ERROR;
return HTTP_BAD_REQUEST;
return HTTP_INTERNAL_SERVER_ERROR;
if (bufsiz > 0) {
return HTTP_INTERNAL_SERVER_ERROR;
else if (content_length > 0) {
return HTTP_BAD_REQUEST;
return HTTP_SERVICE_UNAVAILABLE;
return HTTP_INTERNAL_SERVER_ERROR;
switch (result) {
case CMD_AJP13_GET_BODY_CHUNK:
if (havebody) {
bufsiz = 0;
havebody = 0;
r->server,
&bufsiz);
r->server,
case CMD_AJP13_SEND_HEADERS:
if (headers_sent) {
if (size == 0) {
if (headers_sent) {
== APR_TIMEUP) ) ) {
case CMD_AJP13_END_RESPONSE:
output_failed = 0;
|| output_failed)
if (data_sent) {
else if (!request_ended) {
if (data_sent) {
if (backend_failed) {
if (data_sent) {
return rv;
int status;
int retry;
&proxy_module);
return DECLINED;
r->server);
if (backend) {
return status;
retry = 0;
sizeof(server_portstr));
retry++;
return status;