📄 server.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 <sys/stat.h>#include <netinet/in.h>#include <fcntl.h>#include <unistd.h>#include <stdio.h>#include <stdlib.h>#include <stdarg.h>#include <string.h>#include <dirent.h>// probably system-dependent#include <dlfcn.h>#include <jni.h>#include <pthread.h>#include "cse.h"#include "proxy.h"#include "proxy_jni.h"typedef struct server_t { int ss; int max_conn; int conn; JNIEnv *env; jobject server_obj; int is_dead; pthread_mutex_t lock;} server_t;typedef struct t_java_req { jobject request_obj; jbyteArray uri; jcharArray header_buffer; jintArray header_offsets;} t_java_req;static voidfill_fields(JNIEnv *env, jobject server_obj, t_java_req *java_req){ jobject request_obj; request_obj = (*env)->CallObjectMethod(env, server_obj, g_java.create_request); if ((*env)->ExceptionOccurred(env)) { (*env)->ExceptionDescribe(env); exit(1); } request_obj = (*env)->NewGlobalRef(env, request_obj); java_req->request_obj = request_obj; java_req->uri = (*env)->GetObjectField(env, request_obj, g_java.f_uri); java_req->header_buffer = (*env)->GetObjectField(env, request_obj, g_java.f_header_buffer); java_req->header_offsets = (*env)->GetObjectField(env, request_obj, g_java.f_header_offsets);}static voidrequest_thread(){ /* while (1) { do_request(ss, request, response, env, &java_fields); } close(ss); */}static voiddo_request(int sock, request_t *req, response_t *res, JNIEnv *env, t_java_req *java_req){ int len; char buf[4096]; char *uri; char *ptr; short *headers; char *header_ptr; int *header_offsets; int header_start; jobject request_obj = java_req->request_obj; jint local_addr; jint local_port; jint remote_addr; jint remote_port; int i, j, k; local_addr = ntohl(req->server_addr.sin_addr.s_addr); local_port = ntohs(req->server_addr.sin_port); remote_addr = ntohl(req->remote_addr.sin_addr.s_addr); remote_port = ntohs(req->remote_addr.sin_port); do { response_start(res, sock); request_parse(req, sock); uri = (*env)->GetPrimitiveArrayCritical(env, java_req->uri, 0); ptr = req->uri; for (len = 0; ptr[len]; len++) uri[len] = ptr[len]; (*env)->ReleasePrimitiveArrayCritical(env, java_req->uri, uri, 0); (*env)->SetIntField(env, request_obj, g_java.f_uri_length, len); headers = (*env)->GetPrimitiveArrayCritical(env, java_req->header_buffer, 0); header_offsets = (*env)->GetPrimitiveArrayCritical(env, java_req->header_offsets, 0); i = 0; j = 0; header_offsets[j++] = 0; for (k = 0; req->method[k]; k++) headers[i++] = req->method[k]; header_offsets[j++] = i; for (k = 0; req->protocol[k]; k++) headers[i++] = req->protocol[k]; header_start = i; len = req->header_length; header_ptr = req->headers; for (k = 0; k < len; k++) headers[i++] = header_ptr[k]; len = req->header_size; for (k = 0; k <= len; k++) { header_offsets[j++] = header_start + req->header_keys[k]; header_offsets[j++] = header_start + req->header_values[k]; } (*env)->ReleasePrimitiveArrayCritical(env, java_req->header_buffer, headers, 0); (*env)->ReleasePrimitiveArrayCritical(env, java_req->header_offsets, header_offsets, 0); (*env)->SetIntField(env, request_obj, g_java.f_header_size, len); (*env)->CallVoidMethod(env, request_obj, g_java.dispatch, req, local_addr, local_port, remote_addr, remote_port); if ((*env)->ExceptionOccurred(env)) { (*env)->ExceptionDescribe(env); } cse_flush_request(res); } while (req->keepalive); close(sock);}static void *request_run(void *v_server){ server_t *server = v_server; request_t *req = request_create(); response_t *res = response_create(); t_java_req java_req; JNIEnv *env; int result; result = (*g_java.vm)->AttachCurrentThread(g_java.vm, (void**)&env, 0); req->response = res; res->request = req; fill_fields(env, server->server_obj, &java_req); while (! server->is_dead) { struct sockaddr_in *sin = &req->remote_addr; int len = sizeof(*sin); int sock; memset(sin, 0, sizeof(*sin)); pthread_mutex_lock(&server->lock); sock = accept(server->ss, (struct sockaddr *) sin, &len); pthread_mutex_unlock(&server->lock); if (sock < 0) { close(server->ss); // XXX: other possibilities server->is_dead = 1; break; } len = sizeof(req->server_addr); getsockname(sock, &req->server_addr, &len); do_request(sock, req, res, env, &java_req); } (*g_java.vm)->DetachCurrentThread(g_java.vm); // XXX: should free return 0;}static voidcreate_request_thread(server_t *server){ pthread_t thread1; pthread_create(&thread1, 0, request_run, server);}voidstart_server(int ss, JNIEnv *env, jobject server_obj){ server_t *server = malloc(sizeof(server_t)); int i; memset(server, 0, sizeof(server_t)); server->ss = ss; server->env = env; server->max_conn = 20; server->server_obj = server_obj; pthread_mutex_init(&server->lock, 0); for (i = 0; i < 20; i++) create_request_thread(server); while (1) { // deal with interrupts sleep(1000); } //request_run(server);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -