diff options
Diffstat (limited to '')
-rw-r--r-- | modules/proxy/ajp.h | 520 |
1 files changed, 520 insertions, 0 deletions
diff --git a/modules/proxy/ajp.h b/modules/proxy/ajp.h new file mode 100644 index 0000000..c119a7e --- /dev/null +++ b/modules/proxy/ajp.h @@ -0,0 +1,520 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file ajp.h + * @brief Apache Jserv Protocol + * + * @defgroup AJP_defines mod_proxy AJP definitions + * @ingroup APACHE_INTERNAL + * @{ + */ + +#ifndef AJP_H +#define AJP_H + +#include "apr_version.h" +#include "apr.h" + +#include "apr_hooks.h" +#include "apr_lib.h" +#include "apr_strings.h" +#include "apr_buckets.h" +#include "apr_md5.h" +#include "apr_network_io.h" +#include "apr_poll.h" +#include "apr_pools.h" +#include "apr_strings.h" +#include "apr_uri.h" +#include "apr_date.h" +#include "apr_fnmatch.h" +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#if APR_HAVE_NETINET_IN_H +#include <netinet/in.h> +#endif +#if APR_HAVE_ARPA_INET_H +#include <arpa/inet.h> +#endif + +#define AJP13_DEF_HOST "127.0.0.1" +#ifdef NETWARE +#define AJP13_DEF_PORT 9009 /* default to 9009 since 8009 is used by OS */ +#else +#define AJP13_DEF_PORT 8009 +#endif + +/* The following environment variables match mod_ssl! */ +#define AJP13_HTTPS_INDICATOR "HTTPS" +#define AJP13_SSL_PROTOCOL_INDICATOR "SSL_PROTOCOL" +#define AJP13_SSL_CLIENT_CERT_INDICATOR "SSL_CLIENT_CERT" +#define AJP13_SSL_CIPHER_INDICATOR "SSL_CIPHER" +#define AJP13_SSL_SESSION_INDICATOR "SSL_SESSION_ID" +#define AJP13_SSL_KEY_SIZE_INDICATOR "SSL_CIPHER_USEKEYSIZE" + +#ifdef AJP_USE_HTTPD_WRAP +#include "httpd_wrap.h" +#else +#include "httpd.h" +#include "http_config.h" +#include "http_request.h" +#include "http_core.h" +#include "http_protocol.h" +#include "http_main.h" +#include "http_log.h" +#endif + +#include "mod_proxy.h" +#include "util_ebcdic.h" + +/** AJP Specific error codes + */ +/** Buffer overflow exception */ +#define AJP_EOVERFLOW (APR_OS_START_USERERR + 1) +/** Destination Buffer is to small */ +#define AJP_ETOSMALL (APR_OS_START_USERERR + 2) +/** Invalid input parameters */ +#define AJP_EINVAL (APR_OS_START_USERERR + 3) +/** Bad message signature */ +#define AJP_EBAD_SIGNATURE (APR_OS_START_USERERR + 4) +/** Incoming message too bg */ +#define AJP_ETOBIG (APR_OS_START_USERERR + 5) +/** Missing message header */ +#define AJP_ENO_HEADER (APR_OS_START_USERERR + 6) +/** Bad message header */ +#define AJP_EBAD_HEADER (APR_OS_START_USERERR + 7) +/** Bad message */ +#define AJP_EBAD_MESSAGE (APR_OS_START_USERERR + 8) +/** Cant log via AJP14 */ +#define AJP_ELOGFAIL (APR_OS_START_USERERR + 9) +/** Bad request method */ +#define AJP_EBAD_METHOD (APR_OS_START_USERERR + 10) + + +/** A structure that represents ajp message */ +typedef struct ajp_msg ajp_msg_t; + +/** A structure that represents ajp message */ +struct ajp_msg +{ + /** The buffer holding a AJP message */ + apr_byte_t *buf; + /** The length of AJP message header (defaults to AJP_HEADER_LEN) */ + apr_size_t header_len; + /** The length of AJP message */ + apr_size_t len; + /** The current read position */ + apr_size_t pos; + /** Flag indicating the origing of the message */ + int server_side; + /** The size of the buffer */ + apr_size_t max_size; +}; + +/** + * Signature for the messages sent from Apache to tomcat + */ +#define AJP13_WS_HEADER 0x1234 +#define AJP_HEADER_LEN 4 +#define AJP_HEADER_SZ_LEN 2 +#define AJP_HEADER_SZ 6 +#define AJP_MSG_BUFFER_SZ 8192 +#define AJP_MAX_BUFFER_SZ 65536 +#define AJP13_MAX_SEND_BODY_SZ (AJP_MAX_BUFFER_SZ - AJP_HEADER_SZ) +#define AJP_PING_PONG_SZ 128 + +/** Send a request from web server to container*/ +#define CMD_AJP13_FORWARD_REQUEST (unsigned char)2 +/** Write a body chunk from the servlet container to the web server */ +#define CMD_AJP13_SEND_BODY_CHUNK (unsigned char)3 +/** Send response headers from the servlet container to the web server. */ +#define CMD_AJP13_SEND_HEADERS (unsigned char)4 +/** Marks the end of response. */ +#define CMD_AJP13_END_RESPONSE (unsigned char)5 +/** Get further data from the web server if it hasn't all been transferred yet. */ +#define CMD_AJP13_GET_BODY_CHUNK (unsigned char)6 +/** The web server asks the container to shut itself down. */ +#define CMD_AJP13_SHUTDOWN (unsigned char)7 +/** Webserver ask container to take control (logon phase) */ +#define CMD_AJP13_PING (unsigned char)8 +/** Container response to cping request */ +#define CMD_AJP13_CPONG (unsigned char)9 +/** Webserver check if container is alive, since container should respond by cpong */ +#define CMD_AJP13_CPING (unsigned char)10 + +/** @} */ + +/** + * @defgroup AJP_api AJP API functions + * @ingroup MOD_PROXY + * @{ + */ +/** + * Check a new AJP Message by looking at signature and return its size + * + * @param msg AJP Message to check + * @param len Pointer to returned len + * @return APR_SUCCESS or error + */ +apr_status_t ajp_msg_check_header(ajp_msg_t *msg, apr_size_t *len); + +/** + * Reset an AJP Message + * + * @param msg AJP Message to reset + * @return APR_SUCCESS or error + */ +apr_status_t ajp_msg_reset(ajp_msg_t *msg); + +/** + * Reuse an AJP Message + * + * @param msg AJP Message to reuse + * @return APR_SUCCESS or error + */ +apr_status_t ajp_msg_reuse(ajp_msg_t *msg); + +/** + * Mark the end of an AJP Message + * + * @param msg AJP Message to end + * @return APR_SUCCESS or error + */ +apr_status_t ajp_msg_end(ajp_msg_t *msg); + +/** + * Add an unsigned 32bits value to AJP Message + * + * @param msg AJP Message to get value from + * @param value value to add to AJP Message + * @return APR_SUCCESS or error + */ +apr_status_t ajp_msg_append_uint32(ajp_msg_t *msg, apr_uint32_t value); + +/** + * Add an unsigned 16bits value to AJP Message + * + * @param msg AJP Message to get value from + * @param value value to add to AJP Message + * @return APR_SUCCESS or error + */ +apr_status_t ajp_msg_append_uint16(ajp_msg_t *msg, apr_uint16_t value); + +/** + * Add an unsigned 8bits value to AJP Message + * + * @param msg AJP Message to get value from + * @param value value to add to AJP Message + * @return APR_SUCCESS or error + */ +apr_status_t ajp_msg_append_uint8(ajp_msg_t *msg, apr_byte_t value); + +/** + * Add a String in AJP message, and transform the String in ASCII + * if convert is set and we're on an EBCDIC machine + * + * @param msg AJP Message to get value from + * @param value Pointer to String + * @param convert When set told to convert String to ASCII + * @return APR_SUCCESS or error + */ +apr_status_t ajp_msg_append_string_ex(ajp_msg_t *msg, const char *value, + int convert); +/** + * Add a String in AJP message, and transform + * the String in ASCII if we're on an EBCDIC machine + */ +#define ajp_msg_append_string(m, v) ajp_msg_append_string_ex(m, v, 1) + +/** + * Add a String in AJP message. + */ +#define ajp_msg_append_string_ascii(m, v) ajp_msg_append_string_ex(m, v, 0) + +/** + * Add a Byte array to AJP Message + * + * @param msg AJP Message to get value from + * @param value Pointer to Byte array + * @param valuelen Byte array len + * @return APR_SUCCESS or error + */ +apr_status_t ajp_msg_append_bytes(ajp_msg_t *msg, const apr_byte_t *value, + apr_size_t valuelen); + +/** + * Get a 32bits unsigned value from AJP Message + * + * @param msg AJP Message to get value from + * @param rvalue Pointer where value will be returned + * @return APR_SUCCESS or error + */ +apr_status_t ajp_msg_get_uint32(ajp_msg_t *msg, apr_uint32_t *rvalue); + +/** + * Get a 16bits unsigned value from AJP Message + * + * @param msg AJP Message to get value from + * @param rvalue Pointer where value will be returned + * @return APR_SUCCESS or error + */ +apr_status_t ajp_msg_get_uint16(ajp_msg_t *msg, apr_uint16_t *rvalue); + +/** + * Peek a 16bits unsigned value from AJP Message, position in message + * is not updated + * + * @param msg AJP Message to get value from + * @param rvalue Pointer where value will be returned + * @return APR_SUCCESS or error + */ +apr_status_t ajp_msg_peek_uint16(ajp_msg_t *msg, apr_uint16_t *rvalue); + +/** + * Get a 8bits unsigned value from AJP Message + * + * @param msg AJP Message to get value from + * @param rvalue Pointer where value will be returned + * @return APR_SUCCESS or error + */ +apr_status_t ajp_msg_get_uint8(ajp_msg_t *msg, apr_byte_t *rvalue); + +/** + * Peek a 8bits unsigned value from AJP Message, position in message + * is not updated + * + * @param msg AJP Message to get value from + * @param rvalue Pointer where value will be returned + * @return APR_SUCCESS or error + */ +apr_status_t ajp_msg_peek_uint8(ajp_msg_t *msg, apr_byte_t *rvalue); + +/** + * Get a String value from AJP Message + * + * @param msg AJP Message to get value from + * @param rvalue Pointer where value will be returned + * @return APR_SUCCESS or error + */ +apr_status_t ajp_msg_get_string(ajp_msg_t *msg, const char **rvalue); + + +/** + * Get a Byte array from AJP Message + * + * @param msg AJP Message to get value from + * @param rvalue Pointer where value will be returned + * @param rvalue_len Pointer where Byte array len will be returned + * @return APR_SUCCESS or error + */ +apr_status_t ajp_msg_get_bytes(ajp_msg_t *msg, apr_byte_t **rvalue, + apr_size_t *rvalue_len); + +/** + * Create an AJP Message from pool + * + * @param pool memory pool to allocate AJP message from + * @param size size of the buffer to create + * @param rmsg Pointer to newly created AJP message + * @return APR_SUCCESS or error + */ +apr_status_t ajp_msg_create(apr_pool_t *pool, apr_size_t size, ajp_msg_t **rmsg); + +/** + * Recopy an AJP Message to another + * + * @param smsg source AJP message + * @param dmsg destination AJP message + * @return APR_SUCCESS or error + */ +apr_status_t ajp_msg_copy(ajp_msg_t *smsg, ajp_msg_t *dmsg); + +/** + * Serialize in an AJP Message a PING command + * + * +-----------------------+ + * | PING CMD (1 byte) | + * +-----------------------+ + * + * @param msg AJP message to put serialized message + * @return APR_SUCCESS or error + */ +apr_status_t ajp_msg_serialize_ping(ajp_msg_t *msg); + +/** + * Serialize in an AJP Message a CPING command + * + * +-----------------------+ + * | CPING CMD (1 byte) | + * +-----------------------+ + * + * @param msg AJP message to put serialized message + * @return APR_SUCCESS or error + */ +apr_status_t ajp_msg_serialize_cping(ajp_msg_t *msg); + +/** + * Dump up to the first 1024 bytes on an AJP Message + * + * @param pool pool to allocate from + * @param msg AJP Message to dump + * @param err error string to display + * @param count the number of bytes to dump + * @param buf buffer pointer for dump message + * @return APR_SUCCESS or error + */ +apr_status_t ajp_msg_dump(apr_pool_t *pool, ajp_msg_t *msg, char *err, + apr_size_t count, char **buf); + +/** + * Log an AJP message + * + * @param r The current request + * @param msg AJP Message to dump + * @param err error string to display + * @return APR_SUCCESS or error + */ +apr_status_t ajp_msg_log(request_rec *r, ajp_msg_t *msg, char *err); + +/** + * Send an AJP message to backend + * + * @param sock backend socket + * @param msg AJP message to put serialized message + * @return APR_SUCCESS or error + */ +apr_status_t ajp_ilink_send(apr_socket_t *sock, ajp_msg_t *msg); + +/** + * Receive an AJP message from backend + * + * @param sock backend socket + * @param msg AJP message to put serialized message + * @return APR_SUCCESS or error + */ +apr_status_t ajp_ilink_receive(apr_socket_t *sock, ajp_msg_t *msg); + +/** + * Build the ajp header message and send it + * @param sock backend socket + * @param r current request + * @param buffsize max size of the AJP packet. + * @param uri requested uri + * @return APR_SUCCESS or error + */ +apr_status_t ajp_send_header(apr_socket_t *sock, request_rec *r, + apr_size_t buffsize, + apr_uri_t *uri); + +/** + * Read the ajp message and return the type of the message. + * @param sock backend socket + * @param r current request + * @param buffsize size of the buffer. + * @param msg returned AJP message + * @return APR_SUCCESS or error + */ +apr_status_t ajp_read_header(apr_socket_t *sock, + request_rec *r, + apr_size_t buffsize, + ajp_msg_t **msg); + +/** + * Allocate a msg to send data + * @param pool pool to allocate from + * @param ptr data buffer + * @param len the length of allocated data buffer + * @param msg returned AJP message + * @return APR_SUCCESS or error + */ +apr_status_t ajp_alloc_data_msg(apr_pool_t *pool, char **ptr, + apr_size_t *len, ajp_msg_t **msg); + +/** + * Send the data message + * @param sock backend socket + * @param msg AJP message to send + * @param len AJP message length + * @return APR_SUCCESS or error + */ +apr_status_t ajp_send_data_msg(apr_socket_t *sock, + ajp_msg_t *msg, apr_size_t len); + +/** + * Parse the message type + * @param r current request + * @param msg AJP message + * @return AJP message type. + */ +int ajp_parse_type(request_rec *r, ajp_msg_t *msg); + +/** + * Parse the header message from container + * @param r current request + * @param conf proxy config + * @param msg AJP message + * @return APR_SUCCESS or error + */ +apr_status_t ajp_parse_header(request_rec *r, proxy_dir_conf *conf, + ajp_msg_t *msg); + +/** + * Parse the message body and return data address and length + * @param r current request + * @param msg AJP message + * @param len returned AJP message length + * @param ptr returned data + * @return APR_SUCCESS or error + */ +apr_status_t ajp_parse_data(request_rec *r, ajp_msg_t *msg, + apr_uint16_t *len, char **ptr); + + +/** + * Check the reuse flag in CMD_AJP13_END_RESPONSE + * @param r current request + * @param msg AJP message + * @param reuse returned reuse flag + * @return APR_SUCCESS or error + */ +apr_status_t ajp_parse_reuse(request_rec *r, ajp_msg_t *msg, + apr_byte_t *reuse); + + +/** + * Handle the CPING/CPONG messages + * @param sock backend socket + * @param r current request + * @param timeout time window for receiving cpong reply + * @return APR_SUCCESS or error + */ +apr_status_t ajp_handle_cping_cpong(apr_socket_t *sock, + request_rec *r, + apr_interval_time_t timeout); + + +/** + * Convert numeric message type into string + * @param type AJP message type + * @return AJP message type as a string + */ +const char *ajp_type_str(int type); + +/** @} */ + +#endif /* AJP_H */ + |