📄 protocol.c
字号:
/* * 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.19 1999/12/07 01:39:24 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>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);}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);}void cse_free(config_t *config, void *data) {}/** * 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 get_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; } */ s->read_offset += sublen; len -= sublen; } ap_rflush(r); 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_all(s, buf, len); buf[len] = 0; 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_all(s, key, len); key[len] = 0; 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_KEEPALIVE: *keepalive = 1; break; case CSE_SEND_HEADER: ap_send_http_header(r); break; case -1: break; default: cse_read_all(s, buf, 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)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -