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