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/**
18 * @file ajp.h
19 * @brief Apache Jserv Protocol
20 *
21 * @defgroup AJP_defines AJP definitions
22 * @ingroup  MOD_PROXY
23 * @{
24 */
25
26#ifndef AJP_H
27#define AJP_H
28
29#include "apr_version.h"
30#include "apr.h"
31
32#include "apr_hooks.h"
33#include "apr_lib.h"
34#include "apr_strings.h"
35#include "apr_buckets.h"
36#include "apr_md5.h"
37#include "apr_network_io.h"
38#include "apr_poll.h"
39#include "apr_pools.h"
40#include "apr_strings.h"
41#include "apr_uri.h"
42#include "apr_date.h"
43#include "apr_fnmatch.h"
44#define APR_WANT_STRFUNC
45#include "apr_want.h"
46
47#if APR_HAVE_NETINET_IN_H
48#include <netinet/in.h>
49#endif
50#if APR_HAVE_ARPA_INET_H
51#include <arpa/inet.h>
52#endif
53
54#define AJP13_DEF_HOST "127.0.0.1"
55#ifdef NETWARE
56#define AJP13_DEF_PORT 9009     /* default to 9009 since 8009 is used by OS */
57#else
58#define AJP13_DEF_PORT 8009
59#endif
60
61/* The following environment variables match mod_ssl! */
62#define AJP13_HTTPS_INDICATOR           "HTTPS"
63#define AJP13_SSL_CLIENT_CERT_INDICATOR "SSL_CLIENT_CERT"
64#define AJP13_SSL_CIPHER_INDICATOR      "SSL_CIPHER"
65#define AJP13_SSL_SESSION_INDICATOR     "SSL_SESSION_ID"
66#define AJP13_SSL_KEY_SIZE_INDICATOR    "SSL_CIPHER_USEKEYSIZE"
67
68#if APR_CHARSET_EBCDIC
69
70#define USE_CHARSET_EBCDIC
71#define ajp_xlate_to_ascii(b, l) ap_xlate_proto_to_ascii(b, l)
72#define ajp_xlate_from_ascii(b, l) ap_xlate_proto_from_ascii(b, l)
73
74#else                           /* APR_CHARSET_EBCDIC */
75
76#define ajp_xlate_to_ascii(b, l)
77#define ajp_xlate_from_ascii(b, l)
78
79#endif
80
81#ifdef AJP_USE_HTTPD_WRAP
82#include "httpd_wrap.h"
83#else
84#include "httpd.h"
85#include "http_config.h"
86#include "http_request.h"
87#include "http_core.h"
88#include "http_protocol.h"
89#include "http_main.h"
90#include "http_log.h"
91#endif
92
93#include "mod_proxy.h"
94
95
96/** AJP Specific error codes
97 */
98/** Buffer overflow exception */
99#define AJP_EOVERFLOW           (APR_OS_START_USERERR + 1)
100/** Destination Buffer is to small */
101#define AJP_ETOSMALL            (APR_OS_START_USERERR + 2)
102/** Invalid input parameters */
103#define AJP_EINVAL              (APR_OS_START_USERERR + 3)
104/** Bad message signature */
105#define AJP_EBAD_SIGNATURE      (APR_OS_START_USERERR + 4)
106/** Incoming message too bg */
107#define AJP_ETOBIG              (APR_OS_START_USERERR + 5)
108/** Missing message header */
109#define AJP_ENO_HEADER          (APR_OS_START_USERERR + 6)
110/** Bad message header */
111#define AJP_EBAD_HEADER         (APR_OS_START_USERERR + 7)
112/** Bad message */
113#define AJP_EBAD_MESSAGE        (APR_OS_START_USERERR + 8)
114/** Cant log via AJP14 */
115#define AJP_ELOGFAIL            (APR_OS_START_USERERR + 9)
116/** Bad request method */
117#define AJP_EBAD_METHOD         (APR_OS_START_USERERR + 10)
118
119
120/** A structure that represents ajp message */
121typedef struct ajp_msg ajp_msg_t;
122
123/** A structure that represents ajp message */
124struct ajp_msg
125{
126    /** The buffer holding a AJP message */
127    apr_byte_t  *buf;
128    /** The length of AJP message header (defaults to AJP_HEADER_LEN) */
129    apr_size_t  header_len;
130    /** The length of AJP message */
131    apr_size_t  len;
132    /** The current read position */
133    apr_size_t  pos;
134    /** The size of the buffer */
135    apr_size_t max_size;
136    /** Flag indicating the origing of the message */
137    int         server_side;
138};
139
140/**
141 * Signature for the messages sent from Apache to tomcat
142 */
143#define AJP13_WS_HEADER             0x1234
144#define AJP_HEADER_LEN              4
145#define AJP_HEADER_SZ_LEN           2
146#define AJP_HEADER_SZ               6
147#define AJP_MSG_BUFFER_SZ           8192
148#define AJP_MAX_BUFFER_SZ           65536
149#define AJP13_MAX_SEND_BODY_SZ      (AJP_MAX_BUFFER_SZ - AJP_HEADER_SZ)
150#define AJP_PING_PONG_SZ            128
151
152/** Send a request from web server to container*/
153#define CMD_AJP13_FORWARD_REQUEST   (unsigned char)2
154/** Write a body chunk from the servlet container to the web server */
155#define CMD_AJP13_SEND_BODY_CHUNK   (unsigned char)3
156/** Send response headers from the servlet container to the web server. */
157#define CMD_AJP13_SEND_HEADERS      (unsigned char)4
158/** Marks the end of response. */
159#define CMD_AJP13_END_RESPONSE      (unsigned char)5
160/** Get further data from the web server if it hasn't all been transferred yet. */
161#define CMD_AJP13_GET_BODY_CHUNK    (unsigned char)6
162/** The web server asks the container to shut itself down. */
163#define CMD_AJP13_SHUTDOWN          (unsigned char)7
164/** Webserver ask container to take control (logon phase) */
165#define CMD_AJP13_PING              (unsigned char)8
166/** Container response to cping request */
167#define CMD_AJP13_CPONG             (unsigned char)9
168/** Webserver check if container is alive, since container should respond by cpong */
169#define CMD_AJP13_CPING             (unsigned char)10
170
171/** @} */
172
173/**
174 * @defgroup AJP_api AJP API functions
175 * @ingroup  MOD_PROXY
176 * @{
177 */
178/**
179 * Check a new AJP Message by looking at signature and return its size
180 *
181 * @param msg       AJP Message to check
182 * @param len       Pointer to returned len
183 * @return          APR_SUCCESS or error
184 */
185apr_status_t ajp_msg_check_header(ajp_msg_t *msg, apr_size_t *len);
186
187/**
188 * Reset an AJP Message
189 *
190 * @param msg       AJP Message to reset
191 * @return          APR_SUCCESS or error
192 */
193apr_status_t ajp_msg_reset(ajp_msg_t *msg);
194
195/**
196 * Reuse an AJP Message
197 *
198 * @param msg       AJP Message to reuse
199 * @return          APR_SUCCESS or error
200 */
201apr_status_t ajp_msg_reuse(ajp_msg_t *msg);
202
203/**
204 * Mark the end of an AJP Message
205 *
206 * @param msg       AJP Message to end
207 * @return          APR_SUCCESS or error
208 */
209apr_status_t ajp_msg_end(ajp_msg_t *msg);
210
211/**
212 * Add an unsigned 32bits value to AJP Message
213 *
214 * @param msg       AJP Message to get value from
215 * @param value     value to add to AJP Message
216 * @return          APR_SUCCESS or error
217 */
218apr_status_t ajp_msg_append_uint32(ajp_msg_t *msg, apr_uint32_t value);
219
220/**
221 * Add an unsigned 16bits value to AJP Message
222 *
223 * @param msg       AJP Message to get value from
224 * @param value     value to add to AJP Message
225 * @return          APR_SUCCESS or error
226 */
227apr_status_t ajp_msg_append_uint16(ajp_msg_t *msg, apr_uint16_t value);
228
229/**
230 * Add an unsigned 8bits value to AJP Message
231 *
232 * @param msg       AJP Message to get value from
233 * @param value     value to add to AJP Message
234 * @return          APR_SUCCESS or error
235 */
236apr_status_t ajp_msg_append_uint8(ajp_msg_t *msg, apr_byte_t value);
237
238/**
239 *  Add a String in AJP message, and transform the String in ASCII
240 *  if convert is set and we're on an EBCDIC machine
241 *
242 * @param msg       AJP Message to get value from
243 * @param value     Pointer to String
244 * @param convert   When set told to convert String to ASCII
245 * @return          APR_SUCCESS or error
246 */
247apr_status_t ajp_msg_append_string_ex(ajp_msg_t *msg, const char *value,
248                                      int convert);
249/**
250 *  Add a String in AJP message, and transform
251 *  the String in ASCII if we're on an EBCDIC machine
252 */
253#define ajp_msg_append_string(m, v) ajp_msg_append_string_ex(m, v, 1)
254
255/**
256 *  Add a String in AJP message.
257 */
258#define ajp_msg_append_string_ascii(m, v) ajp_msg_append_string_ex(m, v, 0)
259
260/**
261 * Add a Byte array to AJP Message
262 *
263 * @param msg       AJP Message to get value from
264 * @param value     Pointer to Byte array
265 * @param valuelen  Byte array len
266 * @return          APR_SUCCESS or error
267 */
268apr_status_t ajp_msg_append_bytes(ajp_msg_t *msg, const apr_byte_t *value,
269                                  apr_size_t valuelen);
270
271/**
272 * Get a 32bits unsigned value from AJP Message
273 *
274 * @param msg       AJP Message to get value from
275 * @param rvalue    Pointer where value will be returned
276 * @return          APR_SUCCESS or error
277 */
278apr_status_t ajp_msg_get_uint32(ajp_msg_t *msg, apr_uint32_t *rvalue);
279
280/**
281 * Get a 16bits unsigned value from AJP Message
282 *
283 * @param msg       AJP Message to get value from
284 * @param rvalue    Pointer where value will be returned
285 * @return          APR_SUCCESS or error
286 */
287apr_status_t ajp_msg_get_uint16(ajp_msg_t *msg, apr_uint16_t *rvalue);
288
289/**
290 * Peek a 16bits unsigned value from AJP Message, position in message
291 * is not updated
292 *
293 * @param msg       AJP Message to get value from
294 * @param rvalue    Pointer where value will be returned
295 * @return          APR_SUCCESS or error
296 */
297apr_status_t ajp_msg_peek_uint16(ajp_msg_t *msg, apr_uint16_t *rvalue);
298
299/**
300 * Get a 8bits unsigned value from AJP Message
301 *
302 * @param msg       AJP Message to get value from
303 * @param rvalue    Pointer where value will be returned
304 * @return          APR_SUCCESS or error
305 */
306apr_status_t ajp_msg_get_uint8(ajp_msg_t *msg, apr_byte_t *rvalue);
307
308/**
309 * Peek a 8bits unsigned value from AJP Message, position in message
310 * is not updated
311 *
312 * @param msg       AJP Message to get value from
313 * @param rvalue    Pointer where value will be returned
314 * @return          APR_SUCCESS or error
315 */
316apr_status_t ajp_msg_peek_uint8(ajp_msg_t *msg, apr_byte_t *rvalue);
317
318/**
319 * Get a String value from AJP Message
320 *
321 * @param msg       AJP Message to get value from
322 * @param rvalue    Pointer where value will be returned
323 * @return          APR_SUCCESS or error
324 */
325apr_status_t ajp_msg_get_string(ajp_msg_t *msg, const char **rvalue);
326
327
328/**
329 * Get a Byte array from AJP Message
330 *
331 * @param msg       AJP Message to get value from
332 * @param rvalue    Pointer where value will be returned
333 * @param rvalueLen Pointer where Byte array len will be returned
334 * @return          APR_SUCCESS or error
335 */
336apr_status_t ajp_msg_get_bytes(ajp_msg_t *msg, apr_byte_t **rvalue,
337                               apr_size_t *rvalue_len);
338
339/**
340 * Create an AJP Message from pool
341 *
342 * @param pool      memory pool to allocate AJP message from
343 * @param size      size of the buffer to create
344 * @param rmsg      Pointer to newly created AJP message
345 * @return          APR_SUCCESS or error
346 */
347apr_status_t ajp_msg_create(apr_pool_t *pool, apr_size_t size, ajp_msg_t **rmsg);
348
349/**
350 * Recopy an AJP Message to another
351 *
352 * @param smsg      source AJP message
353 * @param dmsg      destination AJP message
354 * @return          APR_SUCCESS or error
355 */
356apr_status_t ajp_msg_copy(ajp_msg_t *smsg, ajp_msg_t *dmsg);
357
358/**
359 * Serialize in an AJP Message a PING command
360 *
361 * +-----------------------+
362 * | PING CMD (1 byte)     |
363 * +-----------------------+
364 *
365 * @param smsg      AJP message to put serialized message
366 * @return          APR_SUCCESS or error
367 */
368apr_status_t ajp_msg_serialize_ping(ajp_msg_t *msg);
369
370/**
371 * Serialize in an AJP Message a CPING command
372 *
373 * +-----------------------+
374 * | CPING CMD (1 byte)    |
375 * +-----------------------+
376 *
377 * @param smsg      AJP message to put serialized message
378 * @return          APR_SUCCESS or error
379 */
380apr_status_t ajp_msg_serialize_cping(ajp_msg_t *msg);
381
382/**
383 * Dump up to the first 1024 bytes on an AJP Message
384 *
385 * @param pool      pool to allocate from
386 * @param msg       AJP Message to dump
387 * @param err       error string to display
388 * @return          dump message
389 */
390char * ajp_msg_dump(apr_pool_t *pool, ajp_msg_t *msg, char *err);
391
392/**
393 * Send an AJP message to backend
394 *
395 * @param soct      backend socket
396 * @param smsg      AJP message to put serialized message
397 * @return          APR_SUCCESS or error
398 */
399apr_status_t ajp_ilink_send(apr_socket_t *sock, ajp_msg_t *msg);
400
401/**
402 * Receive an AJP message from backend
403 *
404 * @param sock      backend socket
405 * @param smsg      AJP message to put serialized message
406 * @return          APR_SUCCESS or error
407 */
408apr_status_t ajp_ilink_receive(apr_socket_t *sock, ajp_msg_t *msg);
409
410/**
411 * Build the ajp header message and send it
412 * @param sock      backend socket
413 * @param r         current request
414 * @param buffsize  max size of the AJP packet.
415 * @uri uri         requested uri
416 * @return          APR_SUCCESS or error
417 */
418apr_status_t ajp_send_header(apr_socket_t *sock, request_rec *r,
419                             apr_size_t buffsize,
420                             apr_uri_t *uri);
421
422/**
423 * Read the ajp message and return the type of the message.
424 * @param sock      backend socket
425 * @param r         current request
426 * @param buffsize  size of the buffer.
427 * @param msg       returned AJP message
428 * @return          APR_SUCCESS or error
429 */
430apr_status_t ajp_read_header(apr_socket_t *sock,
431                             request_rec  *r,
432                             apr_size_t buffsize,
433                             ajp_msg_t **msg);
434
435/**
436 * Allocate a msg to send data
437 * @param pool      pool to allocate from
438 * @param ptr       data buffer
439 * @param len       the length of allocated data buffer
440 * @param msg       returned AJP message
441 * @return          APR_SUCCESS or error
442 */
443apr_status_t  ajp_alloc_data_msg(apr_pool_t *pool, char **ptr,
444                                 apr_size_t *len, ajp_msg_t **msg);
445
446/**
447 * Send the data message
448 * @param sock      backend socket
449 * @param msg       AJP message to send
450 * @param len       AJP message length
451 * @return          APR_SUCCESS or error
452 */
453apr_status_t  ajp_send_data_msg(apr_socket_t *sock,
454                                ajp_msg_t *msg, apr_size_t len);
455
456/**
457 * Parse the message type
458 * @param r         current request
459 * @param msg       AJP message
460 * @return          AJP message type.
461 */
462int ajp_parse_type(request_rec  *r, ajp_msg_t *msg);
463
464/**
465 * Parse the header message from container
466 * @param r         current request
467 * @param msg       AJP message
468 * @return          APR_SUCCESS or error
469 */
470apr_status_t ajp_parse_header(request_rec *r, proxy_dir_conf *conf,
471                              ajp_msg_t *msg);
472
473/**
474 * Parse the message body and return data address and length
475 * @param r         current request
476 * @param msg       AJP message
477 * @param len       returned AJP message length
478 * @param ptr       returned data
479 * @return          APR_SUCCESS or error
480 */
481apr_status_t  ajp_parse_data(request_rec  *r, ajp_msg_t *msg,
482                             apr_uint16_t *len, char **ptr);
483
484
485/**
486 * Check the reuse flag in CMD_AJP13_END_RESPONSE
487 * @param r         current request
488 * @param msg       AJP message
489 * @param reuse     returned reuse flag
490 * @return          APR_SUCCESS or error
491 */
492apr_status_t ajp_parse_reuse(request_rec *r, ajp_msg_t *msg,
493                             apr_byte_t *reuse);
494
495
496/**
497 * Handle the CPING/CPONG messages
498 * @param sock      backend socket
499 * @param r         current request
500 * @param timeout   time window for receiving cpong reply
501 * @return          APR_SUCCESS or error
502 */
503apr_status_t ajp_handle_cping_cpong(apr_socket_t *sock,
504                                    request_rec *r,
505                                    apr_interval_time_t timeout);
506/** @} */
507
508#endif /* AJP_H */
509
510