📄 response.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 <time.h>#include <pthread.h>#include "cse.h"#include "proxy.h"static time_t last_time;static char timebuf[1024];response_t *response_create(){ response_t *res = (response_t *) malloc(sizeof(response_t)); memset(res, 0, sizeof(response_t)); res->sock = 0; res->length = 0; return res;}voidresponse_start(response_t *res, int sock){ res->sock = sock; res->length = 0; res->offset = 0; res->entry = 0; res->after_headers = 0; res->chunked = 0;}intcse_rwrite(response_t *res, char *buf, int length){ if (res->length + length >= 8192) { write(res->sock, res->buffer, res->length); res->length = 0; if (length > 8192) { write(res->sock, buf, length); return; } } memcpy(res->buffer + res->length, buf, length); res->length += length; res->buffer[res->length] = 0; return length;}voidcse_rprintf(response_t *res, char *fmt, ...){ char buf[8192]; int len; va_list list; va_start(list, fmt); len = vsprintf(buf, fmt, list); cse_rwrite(res, buf, len); va_end(list);}voidcse_add_header(response_t *res, char *key, char *value){ cache_entry_t *entry = res->entry; cse_rprintf(res, "%s: %s\r\n", key, value); if (entry) { if (! entry->headers) { entry->header_capacity = 1024; entry->headers = cse_malloc(entry->header_capacity); } sprintf(entry->headers + entry->header_size, "%s: %s\r\n", key, value); entry->header_size = strlen(entry->headers); }}voidcse_flush_headers(response_t *res, int length){ time_t now; struct tm *tm; cache_entry_t *entry = res->entry; time(&now); if (now != last_time) { last_time = now; strftime(timebuf, sizeof(timebuf), "%a, %d %b %Y %H:%M:%S GMT", gmtime(&now)); } cse_rprintf(res, "Server: Resin/1.2\r\n"); cse_rprintf(res, "Date: %s\r\n\r\n", timebuf); if (entry) { if (! entry->headers) { entry->header_capacity = 256; entry->headers = cse_malloc(entry->header_capacity); } entry->header_size = strlen(entry->headers); entry->cache_file = "/tmp/mycache.tmp"; entry->fd = creat(entry->cache_file, 0664); }}intresponse_send_headers(response_t *res, char *buf, int length){ request_t *req = res->request; time_t now; struct tm *tm; int i; int status; res->chunked = req->keepalive; status = (buf[0] - '0') * 100 + (buf[1] - '0') * 10 + buf[2] - '0'; for (i = 0; i < length && buf[i] != '\n'; i++) { } if (req->version >= HTTP_1_1) cse_rprintf(res, "HTTP/1.1 "); else if (req->version >= HTTP_1_0) { cse_rprintf(res, "HTTP/1.0 "); } cse_rwrite(res, buf, i); time(&now); if (now != last_time) { last_time = now; strftime(timebuf, sizeof(timebuf), "%a, %d %b %Y %H:%M:%S GMT", gmtime(&now)); } for (i++; i < length; i++) { char *key = buf + i; char *value; int code; if (*key == '\n') { i++; break; } for (; i < length && buf[i] != ':'; i++) { } buf[i] = 0; value = buf + i + 1; for (; i < length && buf[i] != '\n'; i++) { } buf[i] = 0; code = int_map_get(g_header_map, key); if (code == CONTENT_LENGTH) res->chunked = 0; cse_rprintf(res, "\r\n%s: %s", key, value); } if (! req->keepalive) res->chunked = 0; if (res->chunked) cse_rprintf(res, "\r\nDate: %s\r\n", timebuf); else cse_rprintf(res, "\r\nDate: %s\r\n\r\n", timebuf); return i;}intresponse_write_chunk(response_t *res, char *buf, int length){ if (res->chunked) cse_rprintf(res, "\r\n%x\r\n", length); cse_rwrite(res, buf, length);}intcse_flush_request(response_t *res){ if (res->chunked) cse_rprintf(res, "\r\n0\r\n"); write(res->sock, res->buffer, res->length); res->length = 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -