📄 jk_ajp_common.c
字号:
/*
* Copyright 1999-2004 The Apache Software Foundation
*
* Licensed 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.
*/
/***************************************************************************
* Description: common stuff for bi-directional protocols ajp13/ajp14. *
* Author: Gal Shachor <shachor@il.ibm.com> *
* Author: Henri Gomez <hgomez@apache.org> *
* Version: $Revision: 386288 $ *
***************************************************************************/
#include "jk_global.h"
#include "jk_util.h"
#include "jk_ajp13.h"
#include "jk_ajp14.h"
#include "jk_ajp_common.h"
#include "jk_connect.h"
#ifdef AS400
#include "util_ebcdic.h"
#endif
#if defined(NETWARE) && defined(__NOVELL_LIBC__)
#include "novsock2.h"
#endif
/* Sleep for 100ms */
void jk_sleep_def(void)
{
#ifdef OS2
DosSleep(100);
#elif defined(BEOS)
snooze(100 * 1000);
#elif defined(NETWARE)
delay(100);
#elif defined(WIN32)
Sleep(100);
#else
struct timeval tv;
tv.tv_usec = 100 * 1000;
tv.tv_sec = 0;
select(0, NULL, NULL, NULL, &tv);
#endif
}
const char *response_trans_headers[] = {
"Content-Type",
"Content-Language",
"Content-Length",
"Date",
"Last-Modified",
"Location",
"Set-Cookie",
"Set-Cookie2",
"Servlet-Engine",
"Status",
"WWW-Authenticate"
};
static const char *long_res_header_for_sc(int sc)
{
const char *rc = NULL;
sc = sc & 0X00FF;
if (sc <= SC_RES_HEADERS_NUM && sc > 0) {
rc = response_trans_headers[sc - 1];
}
return rc;
}
#define UNKNOWN_METHOD (-1)
static int sc_for_req_method(const char *method, size_t len)
{
/* Note: the following code was generated by the "shilka" tool from
the "cocom" parsing/compilation toolkit. It is an optimized lookup
based on analysis of the input keywords. Postprocessing was done
on the shilka output, but the basic structure and analysis is
from there. Should new HTTP methods be added, then manual insertion
into this code is fine, or simply re-running the shilka tool on
the appropriate input. */
/* Note: it is also quite reasonable to just use our method_registry,
but I'm assuming (probably incorrectly) we want more speed here
(based on the optimizations the previous code was doing). */
switch (len)
{
case 3:
switch (method[0])
{
case 'A':
return (method[1] == 'C'
&& method[2] == 'L'
? SC_M_ACL : UNKNOWN_METHOD);
case 'P':
return (method[1] == 'U'
&& method[2] == 'T'
? SC_M_PUT : UNKNOWN_METHOD);
case 'G':
return (method[1] == 'E'
&& method[2] == 'T'
? SC_M_GET : UNKNOWN_METHOD);
default:
return UNKNOWN_METHOD;
}
case 4:
switch (method[0])
{
case 'H':
return (method[1] == 'E'
&& method[2] == 'A'
&& method[3] == 'D'
? SC_M_HEAD : UNKNOWN_METHOD);
case 'P':
return (method[1] == 'O'
&& method[2] == 'S'
&& method[3] == 'T'
? SC_M_POST : UNKNOWN_METHOD);
case 'M':
return (method[1] == 'O'
&& method[2] == 'V'
&& method[3] == 'E'
? SC_M_MOVE : UNKNOWN_METHOD);
case 'L':
return (method[1] == 'O'
&& method[2] == 'C'
&& method[3] == 'K'
? SC_M_LOCK : UNKNOWN_METHOD);
case 'C':
return (method[1] == 'O'
&& method[2] == 'P'
&& method[3] == 'Y'
? SC_M_COPY : UNKNOWN_METHOD);
default:
return UNKNOWN_METHOD;
}
case 5:
switch (method[2])
{
case 'R':
return (memcmp(method, "MERGE", 5) == 0
? SC_M_MERGE : UNKNOWN_METHOD);
case 'C':
return (memcmp(method, "MKCOL", 5) == 0
? SC_M_MKCOL : UNKNOWN_METHOD);
case 'B':
return (memcmp(method, "LABEL", 5) == 0
? SC_M_LABEL : UNKNOWN_METHOD);
case 'A':
return (memcmp(method, "TRACE", 5) == 0
? SC_M_TRACE : UNKNOWN_METHOD);
default:
return UNKNOWN_METHOD;
}
case 6:
switch (method[0])
{
case 'U':
switch (method[5])
{
case 'K':
return (memcmp(method, "UNLOCK", 6) == 0
? SC_M_UNLOCK : UNKNOWN_METHOD);
case 'E':
return (memcmp(method, "UPDATE", 6) == 0
? SC_M_UPDATE : UNKNOWN_METHOD);
default:
return UNKNOWN_METHOD;
}
case 'R':
return (memcmp(method, "REPORT", 6) == 0
? SC_M_REPORT : UNKNOWN_METHOD);
case 'S':
return (memcmp(method, "SEARCH", 6) == 0
? SC_M_SEARCH : UNKNOWN_METHOD);
case 'D':
return (memcmp(method, "DELETE", 6) == 0
? SC_M_DELETE : UNKNOWN_METHOD);
default:
return UNKNOWN_METHOD;
}
case 7:
switch (method[1])
{
case 'P':
return (memcmp(method, "OPTIONS", 7) == 0
? SC_M_OPTIONS : UNKNOWN_METHOD);
case 'H':
return (memcmp(method, "CHECKIN", 7) == 0
? SC_M_CHECKIN : UNKNOWN_METHOD);
default:
return UNKNOWN_METHOD;
}
case 8:
switch (method[0])
{
case 'P':
return (memcmp(method, "PROPFIND", 8) == 0
? SC_M_PROPFIND : UNKNOWN_METHOD);
case 'C':
return (memcmp(method, "CHECKOUT", 8) == 0
? SC_M_CHECKOUT : UNKNOWN_METHOD);
default:
return UNKNOWN_METHOD;
}
case 9:
return (memcmp(method, "PROPPATCH", 9) == 0
? SC_M_PROPPATCH : UNKNOWN_METHOD);
case 10:
switch (method[0])
{
case 'U':
return (memcmp(method, "UNCHECKOUT", 10) == 0
? SC_M_UNCHECKOUT : UNKNOWN_METHOD);
case 'M':
return (memcmp(method, "MKACTIVITY", 10) == 0
? SC_M_MKACTIVITY : UNKNOWN_METHOD);
default:
return UNKNOWN_METHOD;
}
case 11:
return (memcmp(method, "MKWORKSPACE", 11) == 0
? SC_M_MKWORKSPACE : UNKNOWN_METHOD);
case 15:
return (memcmp(method, "VERSION-CONTROL", 15) == 0
? SC_M_VERSION_CONTROL : UNKNOWN_METHOD);
case 16:
return (memcmp(method, "BASELINE-CONTROL", 16) == 0
? SC_M_BASELINE_CONTROL : UNKNOWN_METHOD);
default:
return UNKNOWN_METHOD;
}
/* NOTREACHED */
}
static int sc_for_req_header(const char *header_name)
{
char header[16];
size_t len = strlen(header_name);
const char *p = header_name;
int i = 0;
/* ACCEPT-LANGUAGE is the longest headeer
* that is of interest.
*/
if (len < 4 || len > 15)
return UNKNOWN_METHOD;
while (*p)
header[i++] = toupper((unsigned char)*p++);
header[i] = '\0';
p = &header[1];
switch (header[0]) {
case 'A':
if (memcmp(p, "CCEPT", 5) == 0) {
if (!header[6])
return SC_ACCEPT;
else if (header[6] == '-') {
p += 6;
if (memcmp(p, "CHARSET", 7) == 0)
return SC_ACCEPT_CHARSET;
else if (memcmp(p, "ENCODING", 8) == 0)
return SC_ACCEPT_ENCODING;
else if (memcmp(p, "LANGUAGE", 8) == 0)
return SC_ACCEPT_LANGUAGE;
else
return UNKNOWN_METHOD;
}
else
return UNKNOWN_METHOD;
}
else if (memcmp(p, "UTHORIZATION", 12) == 0)
return SC_AUTHORIZATION;
else
return UNKNOWN_METHOD;
break;
case 'C':
if(memcmp(p, "OOKIE2", 6) == 0)
return SC_COOKIE2;
else if (memcmp(p, "OOKIE", 5) == 0)
return SC_COOKIE;
else if(memcmp(p, "ONNECTION", 9) == 0)
return SC_CONNECTION;
else if(memcmp(p, "ONTENT-TYPE", 11) == 0)
return SC_CONTENT_TYPE;
else if(memcmp(p, "ONTENT-LENGTH", 13) == 0)
return SC_CONTENT_LENGTH;
else
return UNKNOWN_METHOD;
break;
case 'H':
if(memcmp(p, "OST", 3) == 0)
return SC_HOST;
else
return UNKNOWN_METHOD;
break;
case 'P':
if(memcmp(p, "RAGMA", 5) == 0)
return SC_PRAGMA;
else
return UNKNOWN_METHOD;
break;
case 'R':
if(memcmp(p, "EFERER", 6) == 0)
return SC_REFERER;
else
return UNKNOWN_METHOD;
break;
case 'U':
if(memcmp(p, "SER-AGENT", 9) == 0)
return SC_USER_AGENT;
else
return UNKNOWN_METHOD;
break;
default:
return UNKNOWN_METHOD;
}
/* NOTREACHED */
}
/*
* Message structure
*
*
AJPV13_REQUEST/AJPV14_REQUEST=
request_prefix (1) (byte)
method (byte)
protocol (string)
req_uri (string)
remote_addr (string)
remote_host (string)
server_name (string)
server_port (short)
is_ssl (boolean)
num_headers (short)
num_headers*(req_header_name header_value)
?context (byte)(string)
?servlet_path (byte)(string)
?remote_user (byte)(string)
?auth_type (byte)(string)
?query_string (byte)(string)
?jvm_route (byte)(string)
?ssl_cert (byte)(string)
?ssl_cipher (byte)(string)
?ssl_session (byte)(string)
?ssl_key_size (byte)(int) via JkOptions +ForwardKeySize
request_terminator (byte)
?body content_length*(var binary)
*/
static int ajp_marshal_into_msgb(jk_msg_buf_t *msg,
jk_ws_service_t *s,
jk_logger_t *l, ajp_endpoint_t * ae)
{
int method;
unsigned int i;
JK_TRACE_ENTER(l);
if ((method = sc_for_req_method(s->method,
strlen(s->method))) == UNKNOWN_METHOD)
method = SC_M_JK_STORED;
if (jk_b_append_byte(msg, JK_AJP13_FORWARD_REQUEST) ||
jk_b_append_byte(msg, (unsigned char)method) ||
jk_b_append_string(msg, s->protocol) ||
jk_b_append_string(msg, s->req_uri) ||
jk_b_append_string(msg, s->remote_addr) ||
jk_b_append_string(msg, s->remote_host) ||
jk_b_append_string(msg, s->server_name) ||
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -