mod_caucho.c

来自「《jsp编程起步》里面的所有源代码」· C语言 代码 · 共 884 行 · 第 1/2 页

C
884
字号
/* * Copyright (c) 1999 Caucho Technology.  All rights reserved. * * Caucho Technology permits redistribution, modification and use * of this file in source and binary form ("the Software") under the * Caucho Developer Source License ("the License").  In particular, the following * conditions must be met: * * 1. Each copy or derived work of the Software must preserve the copyright *    notice and this notice unmodified. * * 2. Redistributions of the Software in source or binary form must include  *    an unmodified copy of the License, normally in a plain ASCII text * * 3. The names "Resin" or "Caucho" are trademarks of Caucho Technology and *    may not be used to endorse products derived from this software. *    "Resin" or "Caucho" may not appear in the names of products derived *    from this software. * * 4. Caucho Technology requests that attribution be given to Resin *    in any manner possible.  We suggest using the "Resin Powered" *    button or creating a "powered by Resin(tm)" link to *    http://www.caucho.com for each page served by Resin. * * This Software is provided "AS IS," without a warranty of any kind.  * ALL EXPRESS OR IMPLIED REPRESENTATIONS AND WARRANTIES, INCLUDING ANY * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. * CAUCHO TECHNOLOGY AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES * SUFFERED BY LICENSEE OR ANY THIRD PARTY AS A RESULT OF USING OR * DISTRIBUTING SOFTWARE. IN NO EVENT WILL CAUCHO OR ITS LICENSORS BE LIABLE * FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF HE HAS BEEN ADVISED OF THE POSSIBILITY * OF SUCH DAMAGES. * * @author Scott Ferguson * * $Id: mod_caucho.c,v 1.24 2000/10/13 01:51:35 ferg Exp $ */#include "httpd.h"#include "http_config.h"#include "http_request.h"#include "http_core.h"#include "http_protocol.h"#include "http_log.h"#include "http_main.h"#include "util_script.h"#include "http_conf_globals.h"#include <stdlib.h>#include <errno.h>#include "cse.h"/* * Apache magic module declaration. */module MODULE_VAR_EXPORT caucho_module;#define BUF_LENGTH 8192#define DEFAULT_PORT 6802#define DEAD_TIME 5#define LIVE_TIME 5static int g_srun_keepalive = 1;static char *g_error_page = 0;voidcse_log(char *fmt, ...){#ifdef DEBUG  va_list args;  FILE *file = fopen("/tmp/log", "a+");    va_start(args, fmt);  vfprintf(file, fmt, args);  va_end(args);  fclose(file);#endif}char *cse_alloc(config_t *config, int length){  return ap_palloc(config->pool, length);}char *cse_strdup(config_t *config, const char *string){  return ap_pstrdup(config->pool, string);}void *cse_create_lock(){#ifdef WIN32
	return CreateMutex(0, 0, "resin");
#else
	return 0;
#endif}intcse_lock(void *lock){
#ifdef WIN32
	if (lock)
		WaitForSingleObject(lock, INFINITE);
	return 1;
#else  return 1;
#endif}voidcse_unlock(void *lock){
#ifdef WIN32
	if (lock)
		ReleaseMutex(lock);
#endif}voidcse_error(config_t *config, char *format, ...){  char buf[BUF_LENGTH];  va_list args;  va_start(args, format);  vsprintf(buf, format, args);  va_end(args);  config->error = ap_pstrdup(config->pool, buf);}voidcse_set_socket_cleanup(int socket, void *pool){  ap_note_cleanups_for_socket(pool, socket);}voidcse_kill_socket_cleanup(int socket, void *pool){  ap_kill_cleanups_for_socket(pool, socket);}void cse_free(config_t *config, void *data) {}static voidcse_module_init(struct server_rec *server, struct pool *pool){  ap_add_version_component("Resin/1.1");}static void *cse_create_server_config(pool *p, server_rec *server){  config_t *config = (config_t *) ap_palloc(p, sizeof(config_t));  srun_t *srun_list = (srun_t *) ap_palloc(p, 16 * sizeof(srun_t));  srun_t *srun;  memset(config, 0, sizeof(config_t));  memset(srun_list, 0, 16 * sizeof(srun_t));  config->server = server;  config->pool = p;  config->srun_list = srun_list;  config->srun_capacity = 16;  config->srun_size = 1;    srun = config->srun_list;  srun->port = DEFAULT_PORT;  srun->session = 0;    srun->max_sockets = 32;  return (void *) config;}/** * Retrieves the caucho configuration from Apache */static config_t *cse_get_module_config(server_rec *s){  return (config_t *) ap_get_module_config(s->module_config, &caucho_module);}/** * Parse the CauchoConfigHost configuration in the apache config file. */static const char *cse_config_file_command(cmd_parms *cmd, void *mconfig, char *value){  config_t *config = cse_get_module_config(cmd->server);   config->path = ap_server_root_relative(cmd->pool, value);  cse_init_config(config);  return config->error;}/** * Parse the CauchoHosts configuration in the apache config file. */static const char *cse_host_command(cmd_parms *cmd, void *mconfig, char *host_arg, char *port_arg){  config_t *config = cse_get_module_config(cmd->server);  int port = port_arg ? atoi(port_arg) : DEFAULT_PORT;  cse_add_host(config, host_arg, port);  return config->error;}/** * Parse the CauchoBackup configuration in the apache config file. */static const char *cse_backup_command(cmd_parms *cmd, void *mconfig,		   char *host_arg, char *port_arg){  config_t *config = cse_get_module_config(cmd->server);  int port = port_arg ? atoi(port_arg) : DEFAULT_PORT;  cse_add_backup(config, host_arg, port);  return config->error;}/** * Parse the CauchoKeepalive configuration in the apache config file. */static const char *cse_keepalive_command(cmd_parms *cmd, void *mconfig, int flag){  /* g_srun_keepalive = flag; */  return 0;}/** * Parse the CauchoHosts configuration in the apache config file. */static const char *cse_error_page_command(cmd_parms *cmd, void *mconfig, char *error_page_arg){  g_error_page = error_page_arg;  return 0;}/** * Look at the request to see if Caucho should handle it. */static intcse_dispatch(request_rec *r){  config_t *config = cse_get_module_config(r->server);  const char *host = ap_get_server_name(r);  const char *uri = r->uri;  if (config == NULL)    return DECLINED;  /* Check for exact virtual host match */  if (cse_match_request(config, host, uri)) {    ap_set_module_config(r->request_config, &caucho_module, 0);    r->handler = "caucho-request";    return OK;  }  return DECLINED;}/** * Gets the session index from the request * * Cookies have priority over the query * * @return -1 if no session */static intget_session_index(request_rec *r){  array_header *hdrs_arr = ap_table_elts(r->headers_in);  table_entry *hdrs = (table_entry *) hdrs_arr->elts;  int i;  int session;  for (i = 0; i < hdrs_arr->nelts; ++i) {    if (! hdrs[i].key || ! hdrs[i].val)      continue;    if (strcasecmp(hdrs[i].key, "Cookie"))      continue;    session = cse_session_from_string(hdrs[i].val, "jsessionid=");    if (session >= 0)      return session;  }  if (r->args) {    return cse_session_from_string(r->args, "jsessionid=");  }  return -1;}static intconnection_error(config_t *config, srun_t *srun, request_rec *r){  int fd = -1;  r->content_type = "text/html";  r->status = 503;  ap_send_http_header(r);  if (g_error_page)    fd = open(g_error_page, O_RDONLY);  if (fd >= 0) {    char buf[1025];    int len;    while ((len = read(fd, buf, sizeof(buf) - 1)) > 0) {      buf[len] = 0;      ap_rputs(buf, r);    }    close(fd);    return OK;  }  ap_rputs("<html><body bgcolor='white'>", r);  ap_rprintf(r, "<h1>Cannot contact servlet runner at %s:%d</h1>", 	     srun->hostname ? srun->hostname : "localhost",	     srun->port);  ap_rputs("</body></html>", r);  ap_kill_timeout(r);  return OK;}/** * Writes request parameters to srun. */static voidwrite_env(stream_t *s, request_rec *r){  conn_rec *c = r->connection;  const char *host;  cse_write_string(s, CSE_PROTOCOL, r->protocol);  cse_write_string(s, CSE_METHOD, r->method);  cse_write_string(s, CSE_URI, r->uri);  if (r->args)    cse_write_string(s, CSE_QUERY_STRING, r->args);  cse_write_string(s, CSE_SERVER_NAME, ap_get_server_name(r));  cse_write_string(s, CSE_SERVER_PORT,		   ap_psprintf(r->pool, "%u", ap_get_server_port(r)));  host = ap_get_remote_host(c, r->per_dir_config, REMOTE_HOST);  if (host)    cse_write_string(s, CSE_REMOTE_HOST, host);  cse_write_string(s, CSE_REMOTE_ADDR, c->remote_ip);  cse_write_string(s, CSE_REMOTE_PORT,		   ap_psprintf(r->pool, "%d", ntohs(c->remote_addr.sin_port)));    if (c->user)    cse_write_string(s, CSE_REMOTE_USER, c->user);  if (c->ap_auth_type)    cse_write_string(s, CSE_AUTH_TYPE, c->ap_auth_type);  cse_write_string(s, CSE_SESSION_GROUP,		   ap_psprintf(r->pool, "%d", s->srun->session));}/** * Writes headers to srun. */static voidwrite_headers(stream_t *s, request_rec *r){  array_header *hdrs_arr = ap_table_elts(r->headers_in);  table_entry *hdrs = (table_entry *) hdrs_arr->elts;  int i;  for (i = 0; i < hdrs_arr->nelts; ++i) {    if (! hdrs[i].key)      continue;    /*     * Content-type and Content-Length are special cased for a little     * added efficiency.     */    if (! strcasecmp(hdrs[i].key, "Content-type"))      cse_write_string(s, CSE_CONTENT_TYPE, hdrs[i].val);    else if (! strcasecmp(hdrs[i].key, "Content-length"))      cse_write_string(s, CSE_CONTENT_LENGTH, hdrs[i].val);    else {      cse_write_string(s, CSE_HEADER, hdrs[i].key);      cse_write_string(s, CSE_VALUE, hdrs[i].val);    }  }}/** * Writes a response from srun to the client */static intcse_write_response(stream_t *s, int len, request_rec *r){  while (len > 0) {    int sublen;    int writelen;    if (s->read_offset >= s->read_length && cse_fill_buffer(s) < 0)      return -1;    sublen = s->read_length - s->read_offset;    if (len < sublen)      sublen = len;    writelen = ap_rwrite(s->read_buf + s->read_offset, sublen, r);    /* XXX: Don't close here, just suck up the remaining data.    if (writelen < sublen) {      cse_log("error2 (%d) %d(%d) %d\n", s->socket, writelen, sublen, errno);      return -1;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?