📄 jk_dsapi_plugin.c
字号:
const char *limit = hdrs + hdrsz;
const char *name, *nameEnd;
const char *value, *valueEnd;
while (hdrs < limit) {
/* Skip line *before* doing anything, cos we want to lose the first line which
* contains the request.
*/
while (hdrs < limit && (*hdrs != '\n' && *hdrs != '\r'))
hdrs++;
while (hdrs < limit && (*hdrs == '\n' || *hdrs == '\r'))
hdrs++;
if (hdrs >= limit)
break;
name = nameEnd = value = valueEnd = NULL;
name = hdrs;
while (hdrs < limit && *hdrs >= ' ' && *hdrs != ':')
hdrs++;
nameEnd = hdrs;
if (hdrs < limit && *hdrs == ':') {
hdrs++;
while (hdrs < limit && (*hdrs == ' ' || *hdrs == '\t'))
hdrs++;
value = hdrs;
while (hdrs < limit && *hdrs >= ' ')
hdrs++;
valueEnd = hdrs;
}
if (s->headers_names != NULL && s->headers_values != NULL) {
s->headers_names[hdrCount] = MemDup(ws, name, nameEnd);
s->headers_values[hdrCount] = MemDup(ws, value, valueEnd);
DEBUG(("%s = %s\n", s->headers_names[hdrCount],
s->headers_values[hdrCount]));
}
hdrCount++;
}
return hdrCount;
}
/* Set up all the necessary jk_* workspace based on the current HTTP request.
*/
static int InitService(private_ws_t * ws, jk_ws_service_t *s)
{
/* This is the only fixed size buffer left. It won't be overflowed
* because the Domino API that reads into the buffer accepts a length
* constraint, and it's unlikely ever to be exhausted because the
* strings being will typically be short, but it's still aesthetically
* troublesome.
*/
char workBuf[16 * 1024];
FilterRequest fr;
char *hdrs, *qp;
int hdrsz;
int errID;
int hdrCount;
int rc /*, dummy */ ;
static char *methodName[] =
{ "", "HEAD", "GET", "POST", "PUT", "DELETE" };
rc = ws->context->GetRequest(ws->context, &fr, &errID);
s->jvm_route = NULL;
s->start_response = StartResponse;
s->read = Read;
s->write = Write;
s->req_uri = jk_pool_strdup(&ws->p, fr.URL);
s->query_string = NULL;
if (qp = strchr(s->req_uri, '?'), qp != NULL) {
*qp++ = '\0';
if (strlen(qp))
s->query_string = qp;
}
GETVARIABLE("AUTH_TYPE", &s->auth_type, "");
GETVARIABLE("REMOTE_USER", &s->remote_user, "");
GETVARIABLE("SERVER_PROTOCOL", &s->protocol, "");
GETVARIABLE("REMOTE_HOST", &s->remote_host, "");
GETVARIABLE("REMOTE_ADDR", &s->remote_addr, "");
GETVARIABLE("SERVER_NAME", &s->server_name, "");
GETVARIABLEINT("SERVER_PORT", &s->server_port, 80);
GETVARIABLE("SERVER_SOFTWARE", &s->server_software, SERVERDFLT);
GETVARIABLEINT("CONTENT_LENGTH", &s->content_length, 0);
/* SSL Support
*/
GETVARIABLEBOOL("HTTPS", &s->is_ssl, 0);
if (ws->reqData->requestMethod < 0 ||
ws->reqData->requestMethod >=
sizeof(methodName) / sizeof(methodName[0]))
return JK_FALSE;
s->method = methodName[ws->reqData->requestMethod];
s->headers_names = NULL;
s->headers_values = NULL;
s->num_headers = 0;
s->ssl_cert_len = fr.clientCertLen;
s->ssl_cert = fr.clientCert;
s->ssl_cipher = NULL; /* required by Servlet 2.3 Api */
s->ssl_session = NULL;
#if defined(JK_VERSION) && JK_VERSION >= MAKEVERSION(1, 2, 0, 1)
s->ssl_key_size = -1; /* required by Servlet 2.3 Api, added in jtc */
#endif
if (s->is_ssl) {
int dummy;
#if 0
char *sslNames[] = {
"CERT_ISSUER", "CERT_SUBJECT", "CERT_COOKIE", "CERT_FLAGS",
"CERT_SERIALNUMBER",
"HTTPS_SERVER_SUBJECT", "HTTPS_SECRETKEYSIZE",
"HTTPS_SERVER_ISSUER", "HTTPS_KEYSIZE"
};
char *sslValues[] = {
NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL
};
unsigned i, varCount = 0;
#endif
DEBUG(("SSL request\n"));
#if defined(JK_VERSION) && JK_VERSION >= MAKEVERSION(1, 2, 0, 1)
/* Read the variable into a dummy variable: we do this for the side effect of
* reading it into workBuf.
*/
GETVARIABLEINT("HTTPS_KEYSIZE", &dummy, 0);
if (workBuf[0] == '[')
s->ssl_key_size = atoi(workBuf + 1);
#else
(void)dummy;
#endif
#if 0
for (i = 0; i < sizeof(sslNames) / sizeof(sslNames[0]); i++) {
GETVARIABLE(sslNames[i], &sslValues[i], NULL);
if (sslValues[i])
varCount++;
}
/* Andy, some SSL vars must be mapped directly in s->ssl_cipher,
* ssl->session and s->ssl_key_size
* ie:
* Cipher could be "RC4-MD5"
* KeySize 128 (bits)
* SessionID a string containing the UniqID used in SSL dialogue
*/
if (varCount > 0) {
unsigned j;
s->attributes_names =
jk_pool_alloc(&ws->p, varCount * sizeof(char *));
s->attributes_values =
jk_pool_alloc(&ws->p, varCount * sizeof(char *));
j = 0;
for (i = 0; i < sizeof(sslNames) / sizeof(sslNames[0]); i++) {
if (sslValues[i]) {
s->attributes_names[j] = sslNames[i];
s->attributes_values[j] = sslValues[i];
j++;
}
}
s->num_attributes = varCount;
}
#endif
}
/* Duplicate all the headers now */
hdrsz = ws->reqData->GetAllHeaders(ws->context, &hdrs, &errID);
DEBUG(("\nGot headers (length %d)\n--------\n%s\n--------\n\n", hdrsz,
hdrs));
s->headers_names = s->headers_values = NULL;
hdrCount = ParseHeaders(ws, hdrs, hdrsz, s);
DEBUG(("Found %d headers\n", hdrCount));
s->num_headers = hdrCount;
s->headers_names = jk_pool_alloc(&ws->p, hdrCount * sizeof(char *));
s->headers_values = jk_pool_alloc(&ws->p, hdrCount * sizeof(char *));
hdrCount = ParseHeaders(ws, hdrs, hdrsz, s);
return JK_TRUE;
}
/* Handle an HTTP request. Works out whether Tomcat will be interested then either
* despatches it to Tomcat or passes it back to Domino.
*/
static unsigned int ParsedRequest(FilterContext * context,
FilterParsedRequest * reqData)
{
unsigned int errID;
int rc;
FilterRequest fr;
int result = kFilterNotHandled;
DEBUG(("\nParsedRequest starting\n"));
rc = context->GetRequest(context, &fr, &errID);
if (fr.URL && strlen(fr.URL)) {
char *uri = fr.URL;
char *workerName, *qp, *turi;
if (!initDone) {
/* One time initialisation which is deferred so that we have the name of
* the server software to plug into worker_env
*/
int ok = JK_FALSE;
jk_map_t *map = NULL;
DEBUG(("Initialising worker map\n"));
if (jk_map_alloc(&map)) {
if (jk_map_read_properties(map, workerMountFile))
if (uri_worker_map_alloc(&uw_map, map, logger))
ok = JK_TRUE;
jk_map_free(&map);
}
DEBUG(("Got the URI worker map\n"));
if (ok) {
ok = JK_FALSE;
DEBUG(("About to allocate map\n"));
if (jk_map_alloc(&map)) {
DEBUG(("About to read %s\n", workerFile));
if (jk_map_read_properties(map, workerFile)) {
#if defined(JK_VERSION) && JK_VERSION >= MAKEVERSION(1, 2, 0, 1)
char server[256];
worker_env.uri_to_worker = uw_map;
if (context->
GetServerVariable(context, "SERVER_SOFTWARE",
server, sizeof(server) - 1,
&errID))
worker_env.server_name =
jk_pool_strdup(&cfgPool, server);
else
worker_env.server_name = SERVERDFLT;
DEBUG(("Server name %s\n", worker_env.server_name));
if (wc_open(map, &worker_env, logger))
ok = JK_TRUE;
#else
if (wc_open(map, logger))
ok = JK_TRUE;
#endif
DEBUG(("OK = %d\n", ok));
}
DEBUG(("Read %s, OK = %d\n", workerFile, ok));
jk_map_free(&map);
}
}
if (!ok)
return kFilterError;
initDone = JK_TRUE;
}
turi = strdup(uri);
if (qp = strchr(turi, '?'), tqp != NULL)
*qp = '\0';
workerName = map_uri_to_worker(uw_map, turi, logger);
free(turi);
DEBUG(("Worker for this URL is %s\n", workerName));
if (NULL != workerName) {
private_ws_t ws;
jk_ws_service_t s;
jk_pool_atom_t buf[SMALL_POOL_SIZE];
if (BadURI(uri))
return RejectBadURI(context);
/* Go dispatch the call */
jk_init_ws_service(&s);
jk_open_pool(&ws.p, buf, sizeof(buf));
ws.responseStarted = JK_FALSE;
ws.context = context;
ws.reqData = reqData;
ws.reqSize =
context->GetRequestContents(context, &ws.reqBuffer, &errID);
s.ws_private = &ws;
s.pool = &ws.p;
if (InitService(&ws, &s)) {
jk_worker_t *worker =
wc_get_worker_for_name(workerName, logger);
jk_log(logger, JK_LOG_DEBUG,
"HttpExtensionProc %s a worker for name %s\n",
worker ? "got" : "could not get", workerName);
if (worker) {
jk_endpoint_t *e = NULL;
if (worker->get_endpoint(worker, &e, logger)) {
int recover = JK_FALSE;
if (e->service(e, &s, logger, &recover)) {
result = kFilterHandledRequest;
jk_log(logger, JK_LOG_DEBUG,
"HttpExtensionProc service() returned OK\n");
DEBUG(("HttpExtensionProc service() returned OK\n"));
}
else {
result = kFilterError;
jk_log(logger, JK_LOG_ERROR,
"HttpExtensionProc error, service() failed\n");
DEBUG(("HttpExtensionProc error, service() failed\n"));
}
e->done(&e, logger);
}
}
else {
jk_log(logger, JK_LOG_ERROR,
"HttpExtensionProc error, could not get a worker for name %s\n",
workerName);
}
}
jk_close_pool(&ws.p);
}
}
return result;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -