Apache HTTPD
mod_proxy_ajp.c
Go to the documentation of this file.
1/* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17/* AJP routines for Apache proxy */
18
19#include "mod_proxy.h"
20#include "ajp.h"
21
22module AP_MODULE_DECLARE_DATA proxy_ajp_module;
23
24/*
25 * Canonicalise http-like URLs.
26 * scheme is the scheme for the URL
27 * url is the URL starting with the first '/'
28 * def_port is the default port for this scheme.
29 */
30static int proxy_ajp_canon(request_rec *r, char *url)
31{
32 char *host, *path, sport[7];
33 char *search = NULL;
34 const char *err;
36
37 /* ap_port_of_scheme() */
38 if (ap_cstr_casecmpn(url, "ajp:", 4) == 0) {
39 url += 4;
40 }
41 else {
42 return DECLINED;
43 }
44
45 ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "canonicalising URL %s", url);
46
47 /*
48 * do syntactic check.
49 * We break the URL into host, port, path, search
50 */
52
54 if (err) {
55 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00867) "error parsing URL %s: %s",
56 url, err);
57 return HTTP_BAD_REQUEST;
58 }
59
60 /*
61 * now parse path/search args, according to rfc1738:
62 * process the path. With proxy-nocanon set (by
63 * mod_proxy) we use the raw, unparsed uri
64 */
65 if (apr_table_get(r->notes, "proxy-nocanon")) {
66 path = url; /* this is the raw path */
67 }
68 else if (apr_table_get(r->notes, "proxy-noencode")) {
69 path = url; /* this is the encoded path already */
70 search = r->args;
71 }
72 else {
74 int flags = d->allow_encoded_slashes && !d->decode_encoded_slashes ? PROXY_CANONENC_NOENCODEDSLASHENCODING : 0;
75
77 r->proxyreq);
78 if (!path) {
79 return HTTP_BAD_REQUEST;
80 }
81 search = r->args;
82 }
83 /*
84 * If we have a raw control character or a ' ' in nocanon path or
85 * r->args, correct encoding was missed.
86 */
87 if (path == url && *ap_scan_vchar_obstext(path)) {
89 "To be forwarded path contains control "
90 "characters or spaces");
91 return HTTP_FORBIDDEN;
92 }
95 "To be forwarded query string contains control "
96 "characters or spaces");
97 return HTTP_FORBIDDEN;
98 }
99
100 if (port != def_port)
101 apr_snprintf(sport, sizeof(sport), ":%d", port);
102 else
103 sport[0] = '\0';
104
105 if (ap_strchr_c(host, ':')) {
106 /* if literal IPv6 address */
107 host = apr_pstrcat(r->pool, "[", host, "]", NULL);
108 }
109 r->filename = apr_pstrcat(r->pool, "proxy:ajp://", host, sport,
110 "/", path, (search) ? "?" : "",
111 (search) ? search : "", NULL);
112 return OK;
113}
114
115#define METHOD_NON_IDEMPOTENT 0
116#define METHOD_IDEMPOTENT 1
117#define METHOD_IDEMPOTENT_WITH_ARGS 2
118
120{
121 /*
122 * RFC2616 (9.1.2): GET, HEAD, PUT, DELETE, OPTIONS, TRACE are considered
123 * idempotent. Hint: HEAD requests use M_GET as method number as well.
124 */
125 switch (r->method_number) {
126 case M_GET:
127 case M_DELETE:
128 case M_PUT:
129 case M_OPTIONS:
130 case M_TRACE:
131 /*
132 * If the request has arguments it might have side-effects and thus
133 * it might be undesirable to resend it to a backend again
134 * automatically.
135 */
136 if (r->args) {
138 }
139 return METHOD_IDEMPOTENT;
140 /* Everything else is not considered idempotent. */
141 default:
143 }
144}
145
147{
148 apr_off_t len = 0;
149
150 if (r->main == NULL) {
151 const char *clp = apr_table_get(r->headers_in, "Content-Length");
152
153 if (clp && !ap_parse_strict_length(&len, clp)) {
154 len = -1; /* parse error */
155 }
156 }
157
158 return len;
159}
160
161/*
162 * XXX: AJP Auto Flushing
163 *
164 * When processing CMD_AJP13_SEND_BODY_CHUNK AJP messages we will do a poll
165 * with FLUSH_WAIT milliseconds timeout to determine if more data is currently
166 * available at the backend. If there is no more data available, we flush
167 * the data to the client by adding a flush bucket to the brigade we pass
168 * up the filter chain.
169 * This is only a bandaid to fix the AJP/1.3 protocol shortcoming of not
170 * sending (actually not having defined) a flush message, when the data
171 * should be flushed to the client. As soon as this protocol shortcoming is
172 * fixed this code should be removed.
173 *
174 * For further discussion see PR37100.
175 * http://issues.apache.org/bugzilla/show_bug.cgi?id=37100
176 */
177
178/*
179 * process the request and write the response.
180 */
182 proxy_conn_rec *conn,
183 conn_rec *origin,
184 proxy_dir_conf *conf,
185 apr_uri_t *uri,
186 char *url, char *server_portstr)
187{
189 int result;
190 apr_bucket *e;
191 apr_bucket_brigade *input_brigade;
193 ajp_msg_t *msg;
194 apr_size_t bufsiz = 0;
195 char *buff;
199 const char *tenc;
200 int havebody = 1;
201 int client_failed = 0;
202 int backend_failed = 0;
204 int data_sent = 0;
205 int request_ended = 0;
206 int headers_sent = 0;
207 int rv = OK;
211 ap_get_module_config(r->server->module_config, &proxy_module);
213 int send_body = 0;
214 apr_off_t content_length = 0;
215 int original_status = r->status;
216 const char *original_status_line = r->status_line;
217 const char *secret = NULL;
218
219 if (psf->io_buffer_size_set)
220 maxsize = psf->io_buffer_size;
223 else if (maxsize < AJP_MSG_BUFFER_SZ)
225 maxsize = APR_ALIGN(maxsize, 1024);
226
227 if (*conn->worker->s->secret)
228 secret = conn->worker->s->secret;
229
230 /*
231 * Send the AJP request to the remote server
232 */
233
234 /* send request headers */
236 if (status != APR_SUCCESS) {
237 conn->close = 1;
239 "request failed to %pI (%s:%hu)",
240 conn->addr, conn->hostname, conn->port);
241 if (status == AJP_EOVERFLOW)
242 return HTTP_BAD_REQUEST;
243 else if (status == AJP_EBAD_METHOD) {
245 } else {
246 /*
247 * This is only non fatal when the method is idempotent. In this
248 * case we can dare to retry it with a different worker if we are
249 * a balancer member.
250 */
253 }
255 }
256 }
257
258 /* allocate an AJP message to store the data of the buckets */
259 bufsiz = maxsize;
261 if (status != APR_SUCCESS) {
262 /* We had a failure: Close connection to backend */
263 conn->close = 1;
265 "ajp_alloc_data_msg failed");
267 }
268
269 /* read the first block of data */
270 input_brigade = apr_brigade_create(p, r->connection->bucket_alloc);
271 tenc = apr_table_get(r->headers_in, "Transfer-Encoding");
272 if (tenc) {
273 if (ap_cstr_casecmp(tenc, "chunked") == 0) {
274 /* The AJP protocol does not want body data yet */
276 "request is chunked");
277 }
278 else {
280 "%s Transfer-Encoding is not supported",
281 tenc);
282 /* We had a failure: Close connection to backend */
283 conn->close = 1;
285 }
286 } else {
287 /* Get client provided Content-Length header */
288 content_length = get_content_length(r);
289 if (content_length < 0) {
291 }
292 else {
293 status = ap_get_brigade(r->input_filters, input_brigade,
296 }
297 if (status != APR_SUCCESS) {
298 /* We had a failure: Close connection to backend */
299 conn->close = 1;
301 "ap_get_brigade failed");
302 apr_brigade_destroy(input_brigade);
304 }
305
306 /* have something */
307 if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(input_brigade))) {
308 ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00872) "APR_BUCKET_IS_EOS");
309 }
310
311 /* Try to send something */
313 "data to read (max %" APR_SIZE_T_FMT
314 " at %" APR_SIZE_T_FMT ")", bufsiz, msg->pos);
315
316 status = apr_brigade_flatten(input_brigade, buff, &bufsiz);
317 if (status != APR_SUCCESS) {
318 /* We had a failure: Close connection to backend */
319 conn->close = 1;
320 apr_brigade_destroy(input_brigade);
322 "apr_brigade_flatten");
324 }
325 apr_brigade_cleanup(input_brigade);
326
328 "got %" APR_SIZE_T_FMT " bytes of data", bufsiz);
329 if (bufsiz > 0) {
330 status = ajp_send_data_msg(conn->sock, msg, bufsiz);
331 ajp_msg_log(r, msg, "First ajp_send_data_msg: ajp_ilink_send packet dump");
332 if (status != APR_SUCCESS) {
333 /* We had a failure: Close connection to backend */
334 conn->close = 1;
335 apr_brigade_destroy(input_brigade);
337 "send failed to %pI (%s:%hu)",
338 conn->addr, conn->hostname, conn->port);
339 /*
340 * It is fatal when we failed to send a (part) of the request
341 * body.
342 */
344 }
345 conn->worker->s->transferred += bufsiz;
346 send_body = 1;
347 }
348 else if (content_length > 0) {
350 "read zero bytes, expecting"
351 " %" APR_OFF_T_FMT " bytes",
352 content_length);
353 /*
354 * We can only get here if the client closed the connection
355 * to us without sending the body.
356 * Now the connection is in the wrong state on the backend.
357 * Sending an empty data msg doesn't help either as it does
358 * not move this connection to the correct state on the backend
359 * for later resusage by the next request again.
360 * Close it to clean things up.
361 */
362 conn->close = 1;
363 apr_brigade_destroy(input_brigade);
364 return HTTP_BAD_REQUEST;
365 }
366 }
367
368 /* read the response */
369 conn->data = NULL;
371 (ajp_msg_t **)&(conn->data));
372 if (status != APR_SUCCESS) {
373 /* We had a failure: Close connection to backend */
374 conn->close = 1;
375 apr_brigade_destroy(input_brigade);
377 "read response failed from %pI (%s:%hu)",
378 conn->addr, conn->hostname, conn->port);
379
380 /* If we had a successful cping/cpong and then a timeout
381 * we assume it is a request that cause a back-end timeout,
382 * but doesn't affect the whole worker.
383 */
385 conn->worker->s->ping_timeout_set) {
387 }
388
389 /*
390 * This is only non fatal when we have not sent (parts) of a possible
391 * request body so far (we do not store it and thus cannot send it
392 * again) and the method is idempotent. In this case we can dare to
393 * retry it with a different worker if we are a balancer member.
394 */
397 }
399 }
400 /* parse the response */
401 result = ajp_parse_type(r, conn->data);
403
404 /*
405 * Prepare apr_pollfd_t struct for possible later check if there is currently
406 * data available from the backend (do not flush response to client)
407 * or not (flush response to client)
408 */
410 conn_poll->reqevents = APR_POLLIN;
411 conn_poll->desc_type = APR_POLL_SOCKET;
412 conn_poll->desc.s = conn->sock;
413
414 bufsiz = maxsize;
415 for (;;) {
416 switch (result) {
418 if (havebody) {
419 if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(input_brigade))) {
420 /* This is the end */
421 bufsiz = 0;
422 havebody = 0;
424 "APR_BUCKET_IS_EOS");
425 } else {
426 status = ap_get_brigade(r->input_filters, input_brigade,
430 if (status != APR_SUCCESS) {
432 "ap_get_brigade failed");
435 }
436 else if (status == AP_FILTER_ERROR) {
437 rv = AP_FILTER_ERROR;
438 }
439 client_failed = 1;
440 break;
441 }
442 bufsiz = maxsize;
443 status = apr_brigade_flatten(input_brigade, buff,
444 &bufsiz);
445 apr_brigade_cleanup(input_brigade);
446 if (status != APR_SUCCESS) {
448 "apr_brigade_flatten failed");
450 client_failed = 1;
451 break;
452 }
453 }
454
455 ajp_msg_reset(msg);
456 /* will go in ajp_send_data_msg */
457 status = ajp_send_data_msg(conn->sock, msg, bufsiz);
458 ajp_msg_log(r, msg, "ajp_send_data_msg after CMD_AJP13_GET_BODY_CHUNK: ajp_ilink_send packet dump");
459 if (status != APR_SUCCESS) {
461 "ajp_send_data_msg failed");
462 backend_failed = 1;
463 break;
464 }
465 conn->worker->s->transferred += bufsiz;
466 } else {
467 /*
468 * something is wrong TC asks for more body but we are
469 * already at the end of the body data
470 */
472 "ap_proxy_ajp_request error read after end");
473 backend_failed = 1;
474 }
475 break;
477 if (headers_sent) {
478 /* Do not send anything to the client.
479 * Backend already send us the headers.
480 */
481 backend_failed = 1;
483 "Backend sent headers twice.");
484 break;
485 }
486 /* AJP13_SEND_HEADERS: process them */
487 status = ajp_parse_header(r, conf, conn->data);
488 if (status != APR_SUCCESS) {
489 backend_failed = 1;
490 }
491 else if ((r->status == 401) && conf->error_override) {
492 const char *buf;
493 const char *wa = "WWW-Authenticate";
494 if ((buf = apr_table_get(r->headers_out, wa))) {
496 } else {
498 "ap_proxy_ajp_request: origin server "
499 "sent 401 without WWW-Authenticate header");
500 }
501 }
502 headers_sent = 1;
503 break;
505 /* AJP13_SEND_BODY_CHUNK: piece of data */
507 if (status == APR_SUCCESS) {
508 /* If we are overriding the errors, we can't put the content
509 * of the page into the brigade.
510 */
511 if (!ap_proxy_should_override(conf, r->status)) {
512 /* AJP13_SEND_BODY_CHUNK with zero length
513 * is explicit flush message
514 */
515 if (size == 0) {
516 if (headers_sent) {
519 }
520 else {
522 "Ignoring flush message "
523 "received before headers");
524 }
525 }
526 else {
527 apr_status_t rv;
528
529 /* Handle the case where the error document is itself reverse
530 * proxied and was successful. We must maintain any previous
531 * error status so that an underlying error (eg HTTP_NOT_FOUND)
532 * doesn't become an HTTP_OK.
533 */
537 }
538
542
543 if ((conn->worker->s->flush_packets == flush_on) ||
544 ((conn->worker->s->flush_packets == flush_auto) &&
545 ((rv = apr_poll(conn_poll, 1, &conn_poll_fd,
546 conn->worker->s->flush_wait))
547 != APR_SUCCESS) &&
551 }
553 if (bb_len != -1)
554 conn->worker->s->read += bb_len;
555 }
556 if (headers_sent) {
560 "error processing body.%s",
562 " Client aborted connection." : "");
563 client_failed = 1;
564 }
565 data_sent = 1;
567 }
568 }
569 }
570 else {
571 backend_failed = 1;
572 }
573 break;
575 /* If we are overriding the errors, we must not send anything to
576 * the client, especially as the brigade already contains headers.
577 * So do nothing here, and it will be cleaned up below.
578 */
580 if (status != APR_SUCCESS) {
581 backend_failed = 1;
582 }
583 if (!ap_proxy_should_override(conf, r->status)) {
589 "error processing end");
590 client_failed = 1;
591 }
592 /* XXX: what about flush here? See mod_jk */
593 data_sent = 1;
594 }
595 request_ended = 1;
596 break;
597 default:
598 backend_failed = 1;
599 break;
600 }
601
602 /*
603 * If connection has been aborted by client: Stop working.
604 * Pretend we are done (data_sent) to avoid further processing.
605 */
606 if (r->connection->aborted) {
608 "client connection aborted");
609 /* no response yet (or ever), set status for access log */
610 if (!headers_sent) {
612 }
613 client_failed = 1;
614 /* return DONE */
615 data_sent = 1;
616 break;
617 }
618
619 /*
620 * We either have finished successfully or we failed.
621 * So bail out
622 */
625 break;
626
627 /* read the response */
629 (ajp_msg_t **)&(conn->data));
630 if (status != APR_SUCCESS) {
631 backend_failed = 1;
633 "ajp_read_header failed");
634 break;
635 }
636 result = ajp_parse_type(r, conn->data);
637 }
638 apr_brigade_destroy(input_brigade);
639
640 /*
641 * Clear output_brigade to remove possible buckets that remained there
642 * after an error.
643 */
645
648 "Processing of request failed backend: %i, client: %i",
650 /* We had a failure: Close connection to backend */
651 conn->close = 1;
652 if (data_sent) {
653 /* Return DONE to avoid error messages being added to the stream */
654 rv = DONE;
655 }
656 }
657 else if (!request_ended) {
659 "Processing of request didn't terminate cleanly");
660 /* We had a failure: Close connection to backend */
661 conn->close = 1;
662 backend_failed = 1;
663 if (data_sent) {
664 /* Return DONE to avoid error messages being added to the stream */
665 rv = DONE;
666 }
667 }
668 else if (!conn_reuse) {
669 /* Our backend signalled connection close */
670 conn->close = 1;
671 }
672 else {
674 "got response from %pI (%s:%hu)",
675 conn->addr, conn->hostname, conn->port);
676
677 if (ap_proxy_should_override(conf, r->status)) {
678 /* clear r->status for override error, otherwise ErrorDocument
679 * thinks that this is a recursive error, and doesn't find the
680 * custom error page
681 */
682 rv = r->status;
683 r->status = HTTP_OK;
684 /*
685 * prevent proxy_handler() from treating this as an
686 * internal error.
687 */
688 apr_table_setn(r->notes, "proxy-error-override", "1");
689 }
690 else {
691 rv = OK;
692 }
693 }
694
695 if (backend_failed) {
697 "dialog to %pI (%s:%hu) failed",
698 conn->addr, conn->hostname, conn->port);
699 /*
700 * If we already send data, signal a broken backend connection
701 * upwards in the chain.
702 */
703 if (data_sent) {
705 } else if (!send_body && (is_idempotent(r) == METHOD_IDEMPOTENT)) {
706 /*
707 * This is only non fatal when we have not send (parts) of a possible
708 * request body so far (we do not store it and thus cannot send it
709 * again) and the method is idempotent. In this case we can dare to
710 * retry it with a different worker if we are a balancer member.
711 */
713 } else {
714 /* If we had a successful cping/cpong and then a timeout
715 * we assume it is a request that cause a back-end timeout,
716 * but doesn't affect the whole worker.
717 */
719 conn->worker->s->ping_timeout_set) {
720 apr_table_setn(r->notes, "proxy_timedout", "1");
722 }
723 else {
725 }
726 }
727 }
728 else if (client_failed) {
729 int level = (r->connection->aborted) ? APLOG_DEBUG : APLOG_ERR;
730 ap_log_rerror(APLOG_MARK, level, status, r, APLOGNO(02822)
731 "dialog with client %pI failed",
733 if (rv == OK) {
734 rv = HTTP_BAD_REQUEST;
735 }
736 }
737
738 /*
739 * Ensure that we sent an EOS bucket thru the filter chain, if we already
740 * have sent some data. Maybe ap_proxy_backend_broke was called and added
741 * one to the brigade already (no longer making it empty). So we should
742 * not do this in this case.
743 */
744 if (data_sent && !r->eos_sent && !r->connection->aborted
748 }
749
750 /* If we have added something to the brigade above, send it */
753 rv = AP_FILTER_ERROR;
754 }
755
757
758 if (apr_table_get(r->subprocess_env, "proxy-nokeepalive")) {
759 conn->close = 1;
760 }
761
762 return rv;
763}
764
765/*
766 * This handles ajp:// URLs
767 */
769 proxy_server_conf *conf,
770 char *url, const char *proxyname,
772{
773 int status;
774 char server_portstr[32];
775 conn_rec *origin = NULL;
776 proxy_conn_rec *backend = NULL;
777 const char *scheme = "AJP";
778 int retry;
780 &proxy_module);
781 apr_pool_t *p = r->pool;
782 apr_uri_t *uri;
783
784 if (ap_cstr_casecmpn(url, "ajp:", 4) != 0) {
785 ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00894) "declining URL %s", url);
786 return DECLINED;
787 }
788
789 uri = apr_palloc(p, sizeof(*uri));
790 ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00895) "serving URL %s", url);
791
792 /* create space for state information */
793 status = ap_proxy_acquire_connection(scheme, &backend, worker,
794 r->server);
795 if (status != OK) {
796 if (backend) {
797 backend->close = 1;
798 ap_proxy_release_connection(scheme, backend, r->server);
799 }
800 return status;
801 }
802
803 backend->is_ssl = 0;
804 backend->close = 0;
805
806 retry = 0;
807 while (retry < 2) {
808 char *locurl = url;
809 /* Step One: Determine Who To Connect To */
810 status = ap_proxy_determine_connection(p, r, conf, worker, backend,
812 server_portstr,
813 sizeof(server_portstr));
814
815 if (status != OK)
816 break;
817
818 /* Step Two: Make the Connection */
819 if (ap_proxy_check_connection(scheme, backend, r->server, 0,
821 && ap_proxy_connect_backend(scheme, backend, worker,
822 r->server)) {
824 "failed to make connection to backend: %s",
825 backend->hostname);
827 break;
828 }
829
830 /* Handle CPING/CPONG */
831 if (worker->s->ping_timeout_set) {
833 worker->s->ping_timeout);
834 /*
835 * In case the CPING / CPONG failed for the first time we might be
836 * just out of luck and got a faulty backend connection, but the
837 * backend might be healthy nevertheless. So ensure that the backend
838 * TCP connection gets closed and try it once again.
839 */
840 if (status != APR_SUCCESS) {
841 backend->close = 1;
843 "cping/cpong failed to %pI (%s:%hu)",
844 backend->addr, backend->hostname, backend->port);
846 retry++;
847 continue;
848 }
849 }
850 /* Step Three: Process the Request */
851 status = ap_proxy_ajp_request(p, r, backend, origin, dconf, uri, locurl,
852 server_portstr);
853 break;
854 }
855
856 /* Do not close the socket */
857 ap_proxy_release_connection(scheme, backend, r->server);
858 return status;
859}
860
867
870 NULL, /* create per-directory config structure */
871 NULL, /* merge per-directory config structures */
872 NULL, /* create per-server config structure */
873 NULL, /* merge per-server config structures */
874 NULL, /* command apr_table_t */
875 ap_proxy_http_register_hook /* register hooks */
876};
877
Apache Jserv Protocol.
const char * buff
Definition ap_regex.h:186
const char apr_size_t len
Definition ap_regex.h:187
apr_size_t const unsigned char unsigned int unsigned int d
Definition apr_siphash.h:72
apr_status_t ajp_send_header(apr_socket_t *sock, request_rec *r, apr_size_t buffsize, apr_uri_t *uri, const char *secret)
Definition ajp_header.c:688
apr_status_t ajp_parse_reuse(request_rec *r, ajp_msg_t *msg, apr_byte_t *reuse)
Definition ajp_header.c:850
int ajp_parse_type(request_rec *r, ajp_msg_t *msg)
Definition ajp_header.c:770
apr_status_t ajp_parse_data(request_rec *r, ajp_msg_t *msg, apr_uint16_t *len, char **ptr)
Definition ajp_header.c:804
apr_status_t ajp_alloc_data_msg(apr_pool_t *pool, char **ptr, apr_size_t *len, ajp_msg_t **msg)
Definition ajp_header.c:875
apr_status_t ajp_msg_log(request_rec *r, ajp_msg_t *msg, char *err)
Definition ajp_msg.c:115
apr_status_t ajp_send_data_msg(apr_socket_t *sock, ajp_msg_t *msg, apr_size_t len)
Definition ajp_header.c:892
apr_status_t ajp_msg_reset(ajp_msg_t *msg)
Definition ajp_msg.c:190
apr_status_t ajp_parse_header(request_rec *r, proxy_dir_conf *conf, ajp_msg_t *msg)
Definition ajp_header.c:781
apr_status_t ajp_read_header(apr_socket_t *sock, request_rec *r, apr_size_t buffsize, ajp_msg_t **msg)
Definition ajp_header.c:725
#define AJP_MAX_BUFFER_SZ
Definition ajp.h:136
#define CMD_AJP13_GET_BODY_CHUNK
Definition ajp.h:149
#define AJP_EBAD_METHOD
Definition ajp.h:105
#define AJP_HEADER_SZ
Definition ajp.h:134
#define CMD_AJP13_SEND_HEADERS
Definition ajp.h:145
#define CMD_AJP13_END_RESPONSE
Definition ajp.h:147
#define AJP_MSG_BUFFER_SZ
Definition ajp.h:135
#define AJP_EOVERFLOW
Definition ajp.h:87
#define CMD_AJP13_SEND_BODY_CHUNK
Definition ajp.h:143
#define ap_get_module_config(v, m)
#define AP_DECLARE_MODULE(foo)
request_rec int int apr_table_t const char * path
request_rec * r
#define AP_FILTER_ERROR
Definition httpd.h:473
#define DECLINED
Definition httpd.h:457
#define OK
Definition httpd.h:456
#define DONE
Definition httpd.h:458
apr_status_t ap_pass_brigade(ap_filter_t *filter, apr_bucket_brigade *bucket)
apr_status_t ap_get_brigade(ap_filter_t *filter, apr_bucket_brigade *bucket, ap_input_mode_t mode, apr_read_type_e block, apr_off_t readbytes)
#define ap_get_core_module_config(v)
Definition http_core.h:383
#define APLOGNO(n)
Definition http_log.h:117
#define ap_log_rerror
Definition http_log.h:454
#define APLOG_ERR
Definition http_log.h:67
#define APLOG_MARK
Definition http_log.h:283
#define APLOG_TRACE1
Definition http_log.h:72
#define APLOG_DEBUG
Definition http_log.h:71
const unsigned char * buf
Definition util_md5.h:50
int ap_map_http_request_error(apr_status_t rv, int status)
const char apr_port_t port
Definition http_vhost.h:125
const char * host
Definition http_vhost.h:124
#define APR_EINVAL
Definition apr_errno.h:711
#define APR_STATUS_IS_TIMEUP(s)
Definition apr_errno.h:534
#define APR_BRIGADE_LAST(b)
#define APR_BRIGADE_INSERT_TAIL(b, e)
apr_bucket * e
#define APR_BRIGADE_EMPTY(b)
#define APR_BUCKET_IS_EOS(e)
@ APR_BLOCK_READ
Definition apr_buckets.h:58
const char apr_ssize_t int flags
Definition apr_encode.h:168
const char * url
Definition apr_escape.h:120
#define APR_HOOK_FIRST
Definition apr_hooks.h:301
#define APR_REGISTER_OPTIONAL_FN(name)
const char * uri
Definition apr_uri.h:159
#define HTTP_OK
Definition httpd.h:490
#define HTTP_BAD_REQUEST
Definition httpd.h:508
#define HTTP_SERVICE_UNAVAILABLE
Definition httpd.h:538
#define HTTP_REQUEST_TIME_OUT
Definition httpd.h:516
#define HTTP_INTERNAL_SERVER_ERROR
Definition httpd.h:535
#define HTTP_FORBIDDEN
Definition httpd.h:511
#define HTTP_GATEWAY_TIME_OUT
Definition httpd.h:539
#define HTTP_NOT_IMPLEMENTED
Definition httpd.h:536
#define PROXY_CHECK_CONN_EMPTY
Definition mod_proxy.h:1135
int ap_proxy_connect_backend(const char *proxy_function, proxy_conn_rec *conn, proxy_worker *worker, server_rec *s)
int ap_proxy_should_override(proxy_dir_conf *conf, int code)
char * ap_proxy_canon_netloc(apr_pool_t *p, char **const urlp, char **userp, char **passwordp, char **hostp, apr_port_t *port)
Definition proxy_util.c:342
int ap_proxy_release_connection(const char *proxy_function, proxy_conn_rec *conn, server_rec *s)
int ap_proxy_acquire_connection(const char *proxy_function, proxy_conn_rec **conn, proxy_worker *worker, server_rec *s)
char * ap_proxy_canonenc_ex(apr_pool_t *p, const char *x, int len, enum enctype t, int flags, int proxyreq)
Definition proxy_util.c:220
void ap_proxy_backend_broke(request_rec *r, apr_bucket_brigade *brigade)
apr_status_t ap_proxy_check_connection(const char *scheme, proxy_conn_rec *conn, server_rec *server, unsigned max_blank_lines, int flags)
#define PROXY_CANONENC_NOENCODEDSLASHENCODING
Definition mod_proxy.h:81
void proxy_hook_canon_handler(proxy_HOOK_canon_handler_t *pf, const char *const *aszPre, const char *const *aszSucc, int nOrder)
Definition mod_proxy.c:3412
apr_port_t ap_proxy_port_of_scheme(const char *scheme)
int ap_proxy_determine_connection(apr_pool_t *p, request_rec *r, proxy_server_conf *conf, proxy_worker *worker, proxy_conn_rec *conn, apr_uri_t *uri, char **url, const char *proxyname, apr_port_t proxyport, char *server_portstr, int server_portstr_size)
void proxy_hook_scheme_handler(proxy_HOOK_scheme_handler_t *pf, const char *const *aszPre, const char *const *aszSucc, int nOrder)
Definition mod_proxy.c:3406
@ enc_path
Definition mod_proxy.h:76
#define M_PUT
Definition httpd.h:593
#define M_OPTIONS
Definition httpd.h:597
#define M_TRACE
Definition httpd.h:598
#define M_GET
Definition httpd.h:592
#define M_DELETE
Definition httpd.h:595
#define STANDARD20_MODULE_STUFF
int ap_cstr_casecmp(const char *s1, const char *s2)
Definition util.c:3542
#define ap_strchr_c(s, c)
Definition httpd.h:2353
const char * ap_scan_vchar_obstext(const char *ptr)
Definition util.c:1674
int ap_cstr_casecmpn(const char *s1, const char *s2, apr_size_t n)
Definition util.c:3559
int ap_parse_strict_length(apr_off_t *len, const char *str)
Definition util.c:2683
apr_size_t size
#define APR_SUCCESS
Definition apr_errno.h:225
int apr_status_t
Definition apr_errno.h:44
apr_array_header_t ** result
#define APR_ALIGN(size, boundary)
apr_uint16_t apr_port_t
@ APR_POLL_SOCKET
Definition apr_poll.h:93
#define apr_pcalloc(p, size)
Definition apr_pools.h:465
apr_int32_t apr_int32_t apr_int32_t err
int int status
#define APR_POLLIN
Definition apr_poll.h:49
apr_pool_t * p
Definition md_event.c:32
static unsigned char * secret
Proxy Extension Module for Apache.
#define METHOD_IDEMPOTENT
static int proxy_ajp_handler(request_rec *r, proxy_worker *worker, proxy_server_conf *conf, char *url, const char *proxyname, apr_port_t proxyport)
#define METHOD_NON_IDEMPOTENT
static int proxy_ajp_canon(request_rec *r, char *url)
static int is_idempotent(request_rec *r)
#define METHOD_IDEMPOTENT_WITH_ARGS
static void ap_proxy_http_register_hook(apr_pool_t *p)
static apr_off_t get_content_length(request_rec *r)
static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r, proxy_conn_rec *conn, conn_rec *origin, proxy_dir_conf *conf, apr_uri_t *uri, char *url, char *server_portstr)
static apr_OFN_ajp_handle_cping_cpong_t * ajp_handle_cping_cpong
return NULL
Definition mod_so.c:359
static sed_label_t * search(sed_commands_t *commands)
Definition sed0.c:907
Definition ajp.h:113
apr_size_t pos
Definition ajp.h:121
Structure to store things which are per connection.
Definition httpd.h:1152
apr_sockaddr_t * client_addr
Definition httpd.h:1166
struct apr_bucket_alloc_t * bucket_alloc
Definition httpd.h:1201
unsigned aborted
Definition httpd.h:1219
Per-directory configuration.
Definition http_core.h:527
const char * hostname
Definition mod_proxy.h:275
apr_sockaddr_t * addr
Definition mod_proxy.h:276
apr_socket_t * sock
Definition mod_proxy.h:278
proxy_worker * worker
Definition mod_proxy.h:273
apr_port_t port
Definition mod_proxy.h:282
unsigned int is_ssl
Definition mod_proxy.h:283
unsigned int close
Definition mod_proxy.h:284
unsigned int error_override
Definition mod_proxy.h:241
apr_off_t transferred
Definition mod_proxy.h:462
unsigned int ping_timeout_set
Definition mod_proxy.h:471
enum proxy_worker_shared::@35 flush_packets
apr_interval_time_t ping_timeout
Definition mod_proxy.h:455
proxy_worker_shared * s
Definition mod_proxy.h:505
A structure that represents the current request.
Definition httpd.h:845
int status
Definition httpd.h:891
int eos_sent
Definition httpd.h:1039
struct ap_filter_t * output_filters
Definition httpd.h:1070
apr_table_t * notes
Definition httpd.h:985
int method_number
Definition httpd.h:898
apr_pool_t * pool
Definition httpd.h:847
char * filename
Definition httpd.h:1018
int proxyreq
Definition httpd.h:873
conn_rec * connection
Definition httpd.h:849
apr_table_t * err_headers_out
Definition httpd.h:981
struct ap_filter_t * input_filters
Definition httpd.h:1072
apr_table_t * headers_in
Definition httpd.h:976
request_rec * main
Definition httpd.h:860
apr_table_t * subprocess_env
Definition httpd.h:983
server_rec * server
Definition httpd.h:851
struct ap_conf_vector_t * per_dir_config
Definition httpd.h:1047
const char * status_line
Definition httpd.h:889
char * args
Definition httpd.h:1026
apr_table_t * headers_out
Definition httpd.h:978
struct ap_conf_vector_t * module_config
Definition httpd.h:1341
@ AP_MODE_READBYTES
Definition util_filter.h:43