mod_caucho.c

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

C
944
字号
    for (i = 0; vars[i]; i++) {      if ((v = ap_hook_call("ap::mod_ssl::var_lookup", &var,                            r->pool, r->server, r->connection, r, vars[i]))) {        cse_write_string(s, CSE_HEADER, vars[i]);        cse_write_string(s, CSE_VALUE, var);      }    }  }#endif  }/** * 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);    }  }}static voidwrite_added_headers(stream_t *s, request_rec *r){  array_header *hdrs_arr = ap_table_elts(r->subprocess_env);  table_entry *hdrs = (table_entry *) hdrs_arr->elts;  int i;  for (i = 0; i < hdrs_arr->nelts; ++i) {    if (! hdrs[i].key)      continue;    if (! strcmp(hdrs[i].key, "HTTPS") &&	! strcmp(hdrs[i].val, "on")) {      cse_write_string(s, CSE_IS_SECURE, "");    }    else if (! r->connection->user && ! strcmp(hdrs[i].key, "SSL_CLIENT_DN"))      cse_write_string(s, CSE_REMOTE_USER, hdrs[i].val);          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;    int sentlen;    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 = sublen;    while (writelen > 0) {      sentlen = ap_rwrite(s->read_buf + s->read_offset, writelen, r);      if (sentlen < 0) {	cse_close(s, "write");	return -1;      }      writelen -= sublen;    }        s->read_offset += sublen;    len -= sublen;  }    return 1;}/** * Copy data from the JVM to the browser. */static intsend_data(stream_t *s, request_rec *r, int ack, int *keepalive){  int code = CSE_END;  char buf[8193];  char key[8193];  char value[8193];  int i;    do {    int l1, l2, l3;    int len;    ap_reset_timeout(r);        code = cse_read_byte(s);    l1 = cse_read_byte(s) & 0xff;    l2 = cse_read_byte(s) & 0xff;    l3 = cse_read_byte(s);    len = (l1 << 16) + (l2 << 8) + (l3 & 0xff);    if (s->socket < 0)      return -1;    switch (code) {    case CSE_STATUS:      cse_read_limit(s, buf, sizeof(buf), len);      for (i = 0; buf[i] && buf[i] != ' '; i++) {      }      i++;      r->status = atoi(buf + i);      r->status_line = ap_pstrdup(r->pool, buf + i);      break;    case CSE_HEADER:      cse_read_limit(s, key, sizeof(key), len);      cse_read_string(s, value, sizeof(value));      if (! strcasecmp(key, "content-type"))	r->content_type = ap_pstrdup(r->pool, value);      else if (! strcasecmp(key, "set-cookie"))	ap_table_add(r->headers_out, key, value);      else	ap_table_set(r->headers_out, key, value);      break;    case CSE_DATA:      if (cse_write_response(s, len, r) < 0)	return -1;      break;    case CSE_FLUSH:      ap_rflush(r);      break;    case CSE_KEEPALIVE:      *keepalive = 1;      break;    case CSE_SEND_HEADER:      ap_send_http_header(r);      break;    case -1:      break;    default:      cse_skip(s, len);      break;    }  } while (code > 0 && code != CSE_END && code != CSE_CLOSE && code != ack);  return code;}/** * handles a client request */static intwrite_request(stream_t *s, request_rec *r, config_t *config, int *keepalive){  int len;  int code;  write_env(s, r);  write_headers(s, r);  write_added_headers(s, r);  /* read post data */  if (ap_should_client_block(r)) {    char buf[BUF_LENGTH];    int isFirst = 1;    while ((len = ap_get_client_block(r, buf, BUF_LENGTH)) > 0) {      ap_reset_timeout(r);      if (! isFirst) {        code = send_data(s, r, CSE_ACK, keepalive);        if (code < 0 || code == CSE_END || code == CSE_CLOSE)          break;      }      cse_write_packet(s, CSE_DATA, buf, len);      isFirst = 0;    }  }  cse_write_packet(s, CSE_END, 0, 0);  code = send_data(s, r, CSE_END, keepalive);    return code == CSE_END;}#ifdef WIN32int random() { return 0; }#endif/** * Handle a request. */static intcaucho_request(request_rec *r){  config_t *config = cse_get_module_config(r->server);  stream_t s;  int retval;  int keepalive = 0;  int reuse;  int session_index;  char *ip;  int rand = random();  if ((retval = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR)))    return retval;  ap_soft_timeout("servlet request", r);  session_index = get_session_index(r);  ip = r->connection->remote_ip;   if (! cse_open_connection(&s, config, session_index, ip,                            r->request_time, rand, r->pool)) {    connection_error(config, config->srun_list, r);      ap_kill_timeout(r);    return OK;  }  reuse = write_request(&s, r, config, &keepalive);    ap_kill_timeout(r);  ap_rflush(r);  if (reuse)    cse_recycle(&s);  else    cse_close(&s, "no reuse");  return OK;}/** * Print the statistics for each JVM. */static voidjvm_status(config_t *config, request_rec *r){  int i;  stream_t s;  int code;  ap_rputs("<center><table border=2 width='80%'>\n", r);  ap_rputs("<tr><th>Host</th>\n", r);  ap_rputs("    <th>Connect<br>Timeout</th>\n", r);  ap_rputs("    <th>Live<br>Time</th>\n", r);  ap_rputs("    <th>Dead<br>Time</th>\n", r);  ap_rputs("</tr>\n", r);  for (i = 0; i < config->srun_size; i++) {    srun_t *srun = config->srun_list + i;    int port = srun->port;    ap_rputs("<tr>", r);    if (! cse_open(&s, config, srun, r->pool, 1)) {      ap_rprintf(r, "<td bgcolor='#ff6666'>%s:%d%s (down)</td>",	       srun->hostname ? srun->hostname : "localhost",	       port, srun->is_backup ? "*" : "");    }    else {      ap_rprintf(r, "<td bgcolor='#66ff66'>%s:%d%s (ok)</td>",                 srun->hostname ? srun->hostname : "localhost",                 port, srun->is_backup ? "*" : "");    }        cse_recycle(&s);        ap_rprintf(r, "<td align=right>%d</td><td align=right>%d</td><td align=right>%d</td>",               srun->connect_timeout, srun->live_time, srun->dead_time);    ap_rputs("</tr>\n", r);  }  ap_rputs("</table></center>\n", r);}/** * Print a summary of the configuration so users can understand what's * going on.  Ping the server to check that it's up. */static intcaucho_status(request_rec *r){  config_t *config = cse_get_module_config(r->server);  location_t *loc;   r->content_type = "text/html";  ap_soft_timeout("caucho status", r);  if (r->header_only) {    ap_kill_timeout(r);    return OK;  }  ap_send_http_header(r);  ap_rputs("<html><title>Status : Caucho Servlet Engine</title>\n", r);  ap_rputs("<body bgcolor=white>\n", r);  ap_rputs("<h1>Status : Caucho Servlet Engine</h1>\n", r);    jvm_status(config, r);  ap_rputs("<p><center><table border=2 cellspacing=0 cellpadding=2 width='80%'>\n", r);  ap_rputs("<tr><th>Host\n", r);  ap_rputs("    <th>url-pattern\n", r);    loc = config ? config->locations : 0;  for (; loc; loc = loc->next) {    ap_rprintf(r, "<tr bgcolor='#ffcc66'><td>%s<td>%s%s%s%s</tr>\n", 	       loc->host && loc->host[0] ? loc->host : "*",	       loc->prefix,	       ! loc->is_exact && ! loc->suffix ? "/*" : 	       loc->suffix && loc->prefix[0] ? "/" : "",	       loc->suffix ? "*" : "",	       loc->suffix ? loc->suffix : "");  }  ap_rputs("</table></center>\n", r);  ap_rputs("<hr>", r);  ap_rprintf(r, "<em>%s<em>", VERSION);  ap_rputs("</body></html>\n", r);  ap_rputs("</body></html>\n", r);  ap_kill_timeout(r);  return OK;}/** * When a child process starts, clear the srun structure so it doesn't * mistakenly think the old sockets areopen. */static voidcse_open_child(server_rec *server, pool *p){  config_t *config = cse_get_module_config(server);  int i;  LOG(("open child\n"));  for (i = 0; i < config->srun_size; i++) {    srun_t *srun = config->srun_list + i;    srun->n_sockets = 0;    srun->max_sockets = 32;    srun->is_dead = 0;    srun->last_time = 0;  }}/** * Close all the connections cleanly when the Apache child process exits. * * @param server the Apache server object * @param p the Apache memory pool for the server. */static voidcse_close_child(server_rec *server, pool *p){  config_t *config = cse_get_module_config(server);  int i;    LOG(("close child\n"));  for (i = 0; i < config->srun_size; i++) {    srun_t *srun = config->srun_list + i;    while (srun->n_sockets > 0) {      int socket = srun->sockets[--srun->n_sockets];            send(socket, "X\0\0\0", 4, 0);      closesocket(socket);    }    srun->n_sockets = 0;  }}/* * Only needed configuration is pointer to resin.conf */static command_rec caucho_commands[] = {    {"CauchoConfigFile", cse_config_file_command, NULL, RSRC_CONF, TAKE1,     "Pointer to the Caucho configuration file."},    {"CauchoHost", cse_host_command, NULL, RSRC_CONF, TAKE12,     "Servlet runner host."},    {"CauchoBackup", cse_backup_command, NULL, RSRC_CONF, TAKE12,     "Servlet runner backup."},    {"CauchoKeepalive", cse_keepalive_command, NULL, RSRC_CONF, FLAG,     "keeps srun connections alive."},    {"CauchoErrorPage", cse_error_page_command, NULL, RSRC_CONF, TAKE1,     "Error page when connections fail."},    {NULL}};/* * Caucho right has two content handlers: * caucho-status: summary information for debugging * caucho-request: dispatch a Caucho request */static const handler_rec caucho_handlers[] ={    {"caucho-status", caucho_status},    {"caucho-request", caucho_request},    {NULL}};/*  * module configuration */module caucho_module ={    STANDARD_MODULE_STUFF,    cse_module_init,            /* module initializer */    NULL,                       /* per-directory config creator */    NULL,                       /* dir config merger */    cse_create_server_config,   /* server config creator */    NULL,                       /* server config merger */    caucho_commands,            /* command table */    caucho_handlers,            /* [7] list of handlers */    NULL,                       /* [2] filename-to-URI translation */    NULL,                       /* [5] check/validate user_id */    NULL,                       /* [6] check user_id is valid *here* */    NULL,                       /* [4] check access by host address */    cse_dispatch,               /* [7] MIME type checker/setter */    NULL,                       /* [8] fixups */    NULL,                       /* [10] logger */    NULL,                       /* [3] header parser */    cse_open_child,             /* apache child process init */    cse_close_child,            /* apache child process exit/cleanup */    NULL,                       /* [1] post read_request handling */#ifdef EAPI    NULL,                       /* add_module */    NULL,                       /* del_module */    NULL,                       /* rewrite_command */    NULL,                       /* new_connection */#endif    };

⌨️ 快捷键说明

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