📄 nsapi.c
字号:
/* * Copyright (c) 1998-2002 Caucho Technology -- all rights reserved * * Caucho Technology permits modification and use of this file in * source and binary form ("the Software") subject to the Caucho * Developer Source License 1.1 ("the License") which accompanies * this file. The License is also available at * http://www.caucho.com/download/cdsl1-1.xtp * * In addition to the terms of the License, 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. Each copy of the Software in source or binary form must include * an unmodified copy of the License in a plain ASCII text file named * LICENSE. * * 3. Caucho reserves all rights to its names, trademarks and logos. * In particular, the names "Resin" and "Caucho" are trademarks of * Caucho and may not be used to endorse products derived from * this software. "Resin" and "Caucho" may not appear in the names * of products derived from this software. * * 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 */#ifdef WIN32#define XP_WIN32#define NSAPI_PUBLIC __declspec(dllexport)#else#define XP_UNIX#define NSAPI_PUBLIC#endif#include <ctype.h>#include <string.h>#include <fcntl.h>#include "nsapi.h"#include "../common/cse.h"static config_t g_static_config;static config_t *g_config;static char *g_hostname;static CRITICAL g_lock;voidcse_log(char *fmt, ...){#ifdef DEBUG va_list args; FILE *file = fopen("/tmp/log", "a+"); if (file) { va_start(args, fmt); vfprintf(file, fmt, args); va_end(args); fclose(file); }#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 = cse_strdup(config->p, buf);}void *cse_malloc(int size){ return PERM_MALLOC((size));}void cse_free(void *data) {}voidcse_set_socket_cleanup(int socket, void *pool){}voidcse_kill_socket_cleanup(int socket, void *pool){}void *cse_create_lock(config_t *config){ return crit_init();}intcse_lock(void *lock){ if (lock) crit_enter((CRITICAL) lock); return 1;}voidcse_unlock(void *lock){ if (lock) crit_exit((CRITICAL) lock);}static voidwrite_env(stream_t *s, Session *sn, Request *rq){ char buf[1024]; char *host; char *query = 0; char *user; char *auth_type; cse_write_string(s, CSE_PROTOCOL, pblock_findval("protocol", rq->reqpb)); cse_write_string(s, CSE_METHOD, pblock_findval("method", rq->reqpb)); cse_write_string(s, CSE_URI, pblock_findval("uri", rq->reqpb)); /* XXX: problems with post */ cse_write_string(s, CSE_QUERY_STRING, pblock_findval("query", rq->reqpb)); if (request_header("host", &host, sn, rq) == REQ_PROCEED && host) { char *p; strcpy(buf, host); p = strchr(buf, ':'); if (p) { *p = 0; cse_write_string(s, CSE_SERVER_NAME, buf); cse_write_string(s, CSE_SERVER_PORT, p + 1); } else { cse_write_string(s, CSE_SERVER_NAME, host); sprintf(buf, "%d", conf_getglobals()->Vport); cse_write_string(s, CSE_SERVER_PORT, buf); } } else { if (! g_hostname) g_hostname = strdup(util_hostname()); cse_write_string(s, CSE_SERVER_NAME, g_hostname); sprintf(buf, "%d", conf_getglobals()->Vport); cse_write_string(s, CSE_SERVER_PORT, buf); } /* Can the user configure this so DNS lookups don't occur? if (session_dns(sn)) cse_write_string(s, CSE_REMOTE_HOST, session_dns(sn)); */ cse_write_string(s, CSE_REMOTE_ADDR, pblock_findval("ip", sn->client)); cse_write_string(s, CSE_REMOTE_USER, pblock_findval("auth-user", rq->vars)); cse_write_string(s, CSE_AUTH_TYPE, pblock_findval("auth-type", rq->vars)); sprintf(buf, "%d", s->srun->session); cse_write_string(s, CSE_SESSION_GROUP, buf); /* SSL */ if (security_active) { char *keysize; char *cert; cse_write_string(s, CSE_IS_SECURE, ""); cse_write_string(s, CSE_HEADER, "HTTPS"); cse_write_string(s, CSE_VALUE, "on"); keysize = pblock_findval("keysize", sn->client); if (keysize) { cse_write_string(s, CSE_HEADER, "HTTPS_KEYSIZE"); cse_write_string(s, CSE_VALUE, keysize); } keysize = pblock_findval("secret-keysize", sn->client); if (keysize) { cse_write_string(s, CSE_HEADER, "HTTPS_SECRETKEYSIZE"); cse_write_string(s, CSE_VALUE, keysize); } cert = pblock_findval("auth-cert", rq->vars); if (cert) { cse_write_string(s, CSE_CLIENT_CERT, cert); cse_write_string(s, CSE_HEADER, "SSL_CLIENT_CERT"); cse_write_string(s, CSE_VALUE, cert); } } }/** * Writes headers to srun. */static voidwrite_headers(stream_t *s, Session *sn, Request *rs, int *content_length){ int i; *content_length = -1; if (! rs->headers) return; for (i = 0; i < rs->headers->hsize; i++) { struct pb_entry *entry = rs->headers->ht[i]; for (; entry; entry = entry->next) { char *name = entry->param->name; char *value = entry->param->value; if (! strcasecmp(name, "Content-type")) cse_write_string(s, CSE_CONTENT_TYPE, value); else if (! strcasecmp(name, "Content-length")) { cse_write_string(s, CSE_CONTENT_LENGTH, value); *content_length = atoi(value); } else { cse_write_string(s, CSE_HEADER, name); cse_write_string(s, CSE_VALUE, value); } } }}static intcse_write_response(stream_t *s, int len, Session *sn, Request *rq){ 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 = net_write(sn->csd, s->read_buf + s->read_offset, sublen); /* 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;}static intsend_data(stream_t *s, Session *sn, Request *rq, int ack){ int code = CSE_END; char buf[8193]; char key[8193]; char value[8193]; int status; 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++) { } if (buf[i]) i++; status = atoi(buf + i); for (; buf[i] && buf[i] != ' '; i++) { } if (buf[i]) i++; protocol_status(sn, rq, status, buf + i); break; case CSE_HEADER: cse_read_all(s, key, len); key[len] = 0; cse_read_string(s, value, sizeof(value)); key[0] = toupper(key[0]); for (i = 1; key[i]; i++) key[i] = tolower(key[i]); pblock_nvinsert(key, value, rq->srvhdrs); break; case CSE_DATA: if (cse_write_response(s, len, sn, rq) < 0) return -1; break; case CSE_SEND_HEADER: protocol_start_response(sn, rq); break; case -1: return -1; default: cse_read_all(s, buf, len); break; } } while (code > 0 && code != CSE_END && code != CSE_CLOSE && code != ack); return code;}static int
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -