📄 proxy.c
字号:
/* * Copyright (c) 1999-2000 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 Public 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. */#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <fcntl.h>#include <stdio.h>#include <stdlib.h>#include <stdarg.h>#include <string.h>#include <pthread.h>#include "cse.h"#include "proxy.h"static config_t *g_config;static pthread_mutex_t lock;typedef struct proxy_t { int ss; cache_t *cache;} proxy_t;voidcse_log(char *fmt, ...){}void *cse_create_lock(){ return 0;}void *cse_malloc(int size){ return malloc(size);}intcse_lock(void *lock){ return 1;}voidcse_unlock(void *lock){}voidcse_error(config_t *config, char *format, ...){}void cse_free(config_t *config, void *data) {}voidcse_set_socket_cleanup(int socket, void *pool){}voidcse_kill_socket_cleanup(int socket, void *pool){}static intcse_bind(int port){ struct sockaddr_in sin; int val = 0; int sock = socket(AF_INET, SOCK_STREAM, 0); memset(&sin, 0, sizeof(sin)); sin.sin_port = htons(port); if (bind(sock, (struct sockaddr *) &sin, sizeof (sin)) < 0) { printf("bad bind\n"); return -1; } val = 1; if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0) { printf("bad set sock opt\n"); return -1; } listen(sock, 5); return sock;}static intconnection_error(config_t *config, srun_t *srun, response_t *res){ char *error_page = config->error_page; if (error_page) { cse_rprintf(res, "HTTP/1.0 302 Redirect\r\n"); cse_rprintf(res, "Location: %s\r\n", error_page); cse_rprintf(res, "\r\n"); cse_rprintf(res, "Page has moved to %s\n", error_page); return; } cse_rprintf(res, "HTTP/1.0 503 Connection Error\r\n"); cse_rprintf(res, "Content-Type: text/html\r\n"); cse_rprintf(res, "\r\n"); cse_rprintf(res, "<html><body bgcolor='white'>"); cse_rprintf(res, "<h1>Can't contact servlet runner at %s:%d</h1>", srun->hostname ? srun->hostname : "localhost", srun->port); cse_rprintf(res, "</body></html>");}/** * Writes request parameters to srun. */static voidwrite_env(stream_t *s, request_t *req){ char buf[1024]; int i; const char *host; int port; //cse_write_string(s, CSE_PROTOCOL, r->protocol); cse_write_string(s, CSE_PROTOCOL, "HTTP/1.0"); cse_write_string(s, CSE_METHOD, req->method); cse_write_string(s, CSE_URI, req->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)); port = ap_get_server_port(r); cse_write_string(s, CSE_SERVER_PORT, ap_psprintf(r->pool, "%u", port)); 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))); */}/** * Writes a response from srun to the client */static intcse_write_response(stream_t *s, int len, request_t *req, response_t *res){ 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 = cse_rwrite(res, s->read_buf + s->read_offset, writelen); 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_t *req, response_t *res, int ack){ int code = CSE_END; char buf[8193]; char key[8193]; char value[8193]; int i; do { int l1, l2, l3; int len; 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; i < len && buf[i] != ' '; i++) { } if (buf[i + 1] != '2' && res->entry) { res->entry->is_cacheable = 0; res->entry = 0; } cse_rprintf(res, "HTTP/1.0 %s\r\n", buf + i + 1); break; case CSE_HEADER: cse_read_all(s, key, len); key[len] = 0; cse_read_string(s, value, sizeof(value)); cse_add_header(res, key, value); break; case CSE_DATA: if (cse_write_response(s, len, req, res) < 0) return -1; break; case CSE_FLUSH: //ap_rflush(r); break; case CSE_SEND_HEADER: cse_flush_headers(res, -1); 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;}static intwrite_request(stream_t *s, request_t *req, response_t *res, config_t *config){ int code; write_env(s, req); cse_write_packet(s, CSE_END, 0, 0); code = send_data(s, req, res, CSE_END); return code == CSE_END;}static voidhandle_proxy(request_t *req, response_t *res, int sock){ config_t *config = g_config; stream_t s; int retval; int reuse; int session_index; char *ip; int now = 0; int rand = 0; session_index = 0; ip = "111234"; if (! cse_open_connection(&s, config, session_index, ip, now, rand, 0)) { connection_error(config, config->srun_list, res); cse_flush_request(res); return; } reuse = write_request(&s, req, res, config); cse_flush_request(res); if (reuse) cse_recycle(&s); else cse_close(&s, "no reuse");}static voidthread_main(proxy_t *proxy, request_t *req, response_t *res){ int ss = proxy->ss; struct sockaddr_in sin; int len = sizeof(sin); char buf[4096]; cache_t *cache = proxy->cache; int sock; memset(&sin, 0, sizeof(&sin)); sock = accept(ss, (struct sockaddr *) &sin, &len); if (sock < 0) { close(ss); // XXX: other possibilities return; } response_start(res, sock); request_parse(req, sock); if (! cache_fill(cache, req, res)) handle_proxy(req, res, sock); cse_flush_request(res); close(sock);}static void *thread_start(void *v_proxy){ proxy_t *proxy = v_proxy; request_t *request = request_create(); response_t *response = response_create(); while (1) { thread_main(proxy, request, response); }}/*intmain(){ int ss; config_t config; pthread_t thread1; proxy_t proxy; g_config = &config; memset(g_config, 0, sizeof(config)); memset(&proxy, 0, sizeof(proxy)); g_config->path = "/home/ferg/ws/resin/conf/test.conf"; cse_init_config(g_config); ss = cse_bind(8090); if (ss < 0) { return 1; } proxy.ss = ss; proxy.cache = cache_create(1024); pthread_mutex_init(&lock, 0); pthread_create(&thread1, 0, thread_start, &proxy); //pthread_create(0, 0, thread_start, &ss); thread_start(&proxy); printf("done\n");}*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -