↑ 1 #include <string.h>
↑ 2 #include <stdio.h>
↑ 3 #include "client.h"
↑ 4 #include "server.h"
↑ 5 #include "rh_event.h"
↑ 6 #include "http_request.h"
↑ 7 #include "handler.h"
↑ 8 #include "memcache.h"
↑ 9
↑ 10 static void http_request_init (http_request_t *request, struct client *client)
↑ 11 {
↑ 12 // TYPE_ZERO (request);
↑ 13 rh_bzero (request, sizeof(*request));
↑ 14
↑ 15 http_header_init (&request->header_in, 0);
↑ 16 http_header_init (&request->header_out, 0);
↑ 17
↑ 18 rh_chunk_init (&request->chunk_header);
↑ 19 rh_chunk_init (&request->chunk_content);
↑ 20
↑ 21 request->gmtime = client->server->gmtime;
↑ 22 rh_gmtime_update (&request->gmtime, client->server->ev_base->time);
↑ 23
↑ 24 request->chunk_current = &request->chunk_header;
↑ 25
↑ 26 request->client = client;
↑ 27
↑ 28 handler_base_init (&request->handler, client->server->config);
↑ 29 #if 0
↑ 30 SIMPLEQ_INIT(&request->sub_request);
↑ 31 #endif
↑ 32 }
↑ 33
↑ 34 http_request_t * http_request_alloc (struct client *client)
↑ 35 {
↑ 36 http_request_t *request;
↑ 37
↑ 38 request = memcache_pop (client->server->memcache, sizeof(*request));
↑ 39 if (NULL == request)
↑ 40 return NULL;
↑ 41
↑ 42 http_request_init (request, client);
↑ 43 HTTP_REQUEST_PUSH (&client->request, request);
↑ 44
↑ 45 if (0 != handler_base_dup (&request->handler,
↑ 46 client->server->handler_base))
↑ 47 {
↑ 48 http_request_free (request);
↑ 49 return NULL;
↑ 50 }
↑ 51
↑ 52 return request;
↑ 53 }
↑ 54
↑ 55 http_request_t * http_sub_request_alloc (http_request_t *parent)
↑ 56 {
↑ 57 #if 0
↑ 58 http_request_t *request;
↑ 59
↑ 60 request = memcache_pop (parent->client->server->memcache, sizeof(*request));
↑ 61 if (NULL == request)
↑ 62 return NULL;
↑ 63
↑ 64 http_request_init (request, parent->client);
↑ 65
↑ 66 request->parent = parent;
↑ 67
↑ 68 return request;
↑ 69 #endif
↑ 70 return NULL;
↑ 71 }
↑ 72
↑ 73 void http_request_destroy (http_request_t *request)
↑ 74 {
↑ 75 handler_t *handler;
↑ 76
↑ 77 #if 0
↑ 78 for (;;) {
↑ 79 http_request_t *sub;
↑ 80
↑ 81 sub = SIMPLEQ_FIRST(&request->sub_request);
↑ 82
↑ 83 if (NULL == sub)
↑ 84 break;
↑ 85
↑ 86 SIMPLEQ_REMOVE_HEAD(&request->sub_request,sub, request);
↑ 87
↑ 88 http_request_destroy(sub);
↑ 89 }
↑ 90 if (!request->sub_request_number) {
↑ 91 #endif
↑ 92 handler = request->client->server->handler_accesslog;
↑ 93 if (handler) {
↑ 94 handler->request = request;
↑ 95 HANDLER_CALL_MAYBE (handler, exec);
↑ 96 }
↑ 97
↑ 98 if (request->st) {
↑ 99 rh_stat_push (request->st);
↑100 request->st = NULL;
↑101 }
↑102
↑103 handler_base_destroy(&request->handler);
↑104
↑105 http_header_destroy (&request->header_in);
↑106 http_header_destroy (&request->header_out);
↑107
↑108 rh_chunk_destroy (&request->chunk_header);
↑109 rh_chunk_destroy (&request->chunk_content);
↑110
↑111 }
↑112
↑113 void http_request_reset (http_request_t *request)
↑114 {
↑115 struct client *client = request->client;
↑116
↑117 http_request_destroy (request);
↑118 http_request_init (request, client);
↑119 }
↑120
↑121 void http_request_free (http_request_t *request)
↑122 {
↑123 http_request_destroy (request);
↑124
↑125 memcache_push (request->client->server->memcache,
↑126 request, sizeof(*request));
↑127 }
↑128
↑129 void http_request_stat (http_request_t *request)
↑130 {
↑131 if (request->st)
↑132 rh_stat_push (request->st);
↑133
↑134 request->st = rh_stat_pop (
↑135 request->client->server->stat_cache,
↑136 &request->header_in.uri.filename );
↑137 }
↑138
↑139 /*
↑140 * tests if the requested filename is inside the server path
↑141 *
↑142 */
↑143 int http_request_stat_symlink (http_request_t *request)
↑144 {
↑145 if (request->st)
↑146 rh_stat_push (request->st);
↑147
↑148 request->st = rh_stat_pop (
↑149 request->client->server->stat_cache,
↑150 &request->header_in.uri.filename );
↑151
↑152 return 0;
↑153 }
↑154
↑155 int http_request_write_setup (http_request_t *request)
↑156 {
↑157 if (request->have_write_setup)
↑158 return 0;
↑159
↑160 if (HTTP_METHOD_HEAD == request->header_in.method) {
↑161 rh_chunk_reset (&request->chunk_content);
↑162 }
↑163
↑164 request->have_write_setup = 1;
↑165
↑166 if (0 == request->header_out.status)
↑167 request->header_out.status = 500;
↑168
↑169 /* Keep-Alive: timeout=15, max=17 */
↑170
↑171 if (!HTTP_HEADER_KEY_ISSET(&request->header_out, SERVER)) {
↑172 HTTP_HEADER_KEY_DEFAULT (&request->header_out, SERVER);
↑173 }
↑174
↑175 if (!HTTP_HEADER_KEY_ISSET(&request->header_out, DATE)) {
↑176 HTTP_HEADER_KEY_SET_CONST_BUFFER (
↑177 &request->header_out,
↑178 DATE,
↑179 &request->gmtime);
↑180 }
↑181
↑182 if (!HTTP_HEADER_KEY_ISSET(&request->header_out, RESPONSE)) {
↑183 HTTP_HEADER_KEY_DEFAULT (&request->header_out, RESPONSE);
↑184 }
↑185
↑186 if (304 != request->header_out.status) {
↑187 if (!HTTP_HEADER_KEY_ISSET(&request->header_out,
↑188 ACCEPT_RANGES))
↑189 {
↑190 HTTP_HEADER_KEY_DEFAULT (&request->header_out,
↑191 ACCEPT_RANGES);
↑192 }
↑193
↑194 if (!HTTP_HEADER_KEY_ISSET(&request->header_out,
↑195 CONTENT_LENGTH))
↑196 {
↑197 http_header_key_set_content_length (
↑198 &request->header_out,
↑199 request->chunk_content.size_in);
↑200 }
↑201 }
↑202
↑203 if (request->keepalive) {
↑204 /* no keepalive if bad status */
↑205 switch ((int)request->header_out.status) {
↑206 case 400:
↑207 case 405:
↑208 case 413:
↑209 case 414:
↑210 case 500:
↑211 case 501:
↑212 case 505:
↑213 request->keepalive = 0;
↑214 }
↑215 }
↑216
↑217 http_header_key_set_keepalive (
↑218 &request->header_out,
↑219 request->keepalive);
↑220
↑221 http_header_into_chunk (&request->header_out,
↑222 &request->chunk_header, 1);
↑223
↑224 return 0;
↑225 }
syntax highlighted by Code2HTML, v. 0.9.1