40 #include "config.h" |
40 #include "config.h" |
41 #include "vserver.h" |
41 #include "vserver.h" |
42 #include "httplistener.h" |
42 #include "httplistener.h" |
43 #include "error.h" |
43 #include "error.h" |
44 |
44 |
45 HTTPRequest *http_request_new() { |
45 void http_request_init(HTTPRequest *req) { |
46 HTTPRequest *req = malloc(sizeof(HTTPRequest)); |
|
47 req->connection = NULL; |
46 req->connection = NULL; |
48 req->uri.ptr = NULL; |
47 req->uri.ptr = NULL; |
49 |
48 |
50 HeaderArray *hd = malloc(sizeof(HeaderArray)); |
49 HeaderArray *hd = malloc(sizeof(HeaderArray)); |
51 hd->next = NULL; |
50 hd->next = NULL; |
52 hd->len = 0; |
51 hd->len = 0; |
53 hd->headers = calloc(16, sizeof(Header)); |
52 hd->headers = calloc(16, sizeof(Header)); |
54 hd->alloc = 16; |
53 hd->alloc = 16; |
55 |
54 |
56 req->headers = hd; |
55 req->headers = hd; |
57 |
|
58 return req; |
|
59 } |
56 } |
60 |
57 |
61 int handle_request(HTTPRequest *request, threadpool_t *thrpool) { |
58 int handle_request(HTTPRequest *request, threadpool_t *thrpool) { |
62 // handle nsapi request |
59 // handle nsapi request |
63 |
60 |
64 // create pool |
61 // create pool |
65 request->pool = pool_create(); |
62 pool_handle_t *pool = pool_create(); |
66 |
63 |
67 // create nsapi data structures |
64 // create nsapi data structures |
68 NSAPISession *sn = malloc(sizeof(NSAPISession)); |
65 NSAPISession *sn = pool_malloc(pool, sizeof(NSAPISession)); |
69 if(sn == NULL) { |
66 if(sn == NULL) { |
70 /* TODO: error */ |
67 /* TODO: error */ |
71 } |
68 } |
72 NSAPIRequest *rq = malloc(sizeof(NSAPIRequest)); |
69 NSAPIRequest *rq = pool_malloc(pool, sizeof(NSAPIRequest)); |
73 if(rq == NULL) { |
70 if(rq == NULL) { |
74 /* TODO: error */ |
71 /* TODO: error */ |
75 } |
72 } |
76 request->rq = rq; |
73 request->rq = rq; |
77 rq->phase = NSAPIAuthTrans; |
74 rq->phase = NSAPIAuthTrans; |
78 |
75 |
79 // fill session structure |
76 // fill session structure |
80 sn->sys_fd = request->connection->fd; |
77 sn->connection = request->connection; |
81 sn->sn.pool = pool_create(); |
78 sn->netbuf = request->netbuf; |
82 sn->sn.csd = stream_new_from_fd(request->connection->fd); |
79 sn->sn.pool = pool; |
|
80 sn->sn.csd = stream_new_from_fd(pool, request->connection->fd); |
83 sn->sn.client = pblock_create_pool(sn->sn.pool, 8); |
81 sn->sn.client = pblock_create_pool(sn->sn.pool, 8); |
84 sn->sn.next = NULL; |
82 sn->sn.next = NULL; |
85 sn->sn.fill = 1; |
83 sn->sn.fill = 1; |
86 sn->sn.subject = NULL; |
84 sn->sn.subject = NULL; |
87 |
85 |
88 // the session needs the current server configuration |
86 // the session needs the current server configuration |
89 sn->config = request->connection->listener->cfg; // TODO: ref |
87 sn->config = request->connection->listener->cfg; // TODO: ref |
90 |
88 |
91 /* add ip to sn->client pblock */ |
89 // add ip to sn->client pblock |
92 char ip_str[INET_ADDRSTRLEN]; |
90 char ip_str[INET_ADDRSTRLEN]; |
93 if(inet_ntop( |
91 if(inet_ntop( |
94 AF_INET, |
92 AF_INET, |
95 &request->connection->address.sin_addr, |
93 &request->connection->address.sin_addr, |
96 ip_str, |
94 ip_str, |
98 { |
96 { |
99 pblock_kvinsert(pb_key_ip, ip_str, INET_ADDRSTRLEN, sn->sn.client); |
97 pblock_kvinsert(pb_key_ip, ip_str, INET_ADDRSTRLEN, sn->sn.client); |
100 } |
98 } |
101 |
99 |
102 // init NSAPI request structure |
100 // init NSAPI request structure |
103 if(request_initialize(request->pool, request, rq) != 0) { |
101 if(request_initialize(pool, request, rq) != 0) { |
104 printf("Cannot initialize request structure\n"); |
102 printf("Cannot initialize request structure\n"); |
105 return 1; |
103 return 1; |
106 } |
104 } |
107 |
105 |
108 // set default virtual server |
106 // set default virtual server |
109 rq->vs = request->connection->listener->default_vs.vs; |
107 rq->vs = request->connection->listener->default_vs.vs; |
110 |
108 |
111 /* Pass request line as "clf-request" */ |
109 // Pass request line as "clf-request" |
112 /* TODO: with or without \r\n ? */ |
110 // remove \r\n |
113 // hack to remove \r\n |
|
114 sstr_t clfreq = request->request_line; |
111 sstr_t clfreq = request->request_line; |
115 while(clfreq.ptr[clfreq.length - 1] < 33) { |
112 while(clfreq.ptr[clfreq.length - 1] < 33) { |
116 clfreq.length--; |
113 clfreq.length--; |
117 } |
114 } |
118 request->request_line = clfreq; |
115 request->request_line = clfreq; |
200 |
197 |
201 if(ha->headers[i].name[0] < 90) { |
198 if(ha->headers[i].name[0] < 90) { |
202 ha->headers[i].name[0] += 32; |
199 ha->headers[i].name[0] += 32; |
203 } |
200 } |
204 |
201 |
205 /* change to lower case */ |
202 // change to lower case |
206 char *header_name = ha->headers[i].name; |
203 char *header_name = ha->headers[i].name; |
207 for(int i=0;header_name[i]!=0;i++) { |
204 for(int i=0;header_name[i]!=0;i++) { |
208 if(header_name[i] > 64 && header_name[i] < 97) { |
205 if(header_name[i] > 64 && header_name[i] < 97) { |
209 header_name[i] += 32; |
206 header_name[i] += 32; |
210 } |
207 } |
214 ha->headers[i].name, |
211 ha->headers[i].name, |
215 ha->headers[i].value, |
212 ha->headers[i].value, |
216 rq->rq.headers); |
213 rq->rq.headers); |
217 } |
214 } |
218 |
215 |
219 /* check for request body and prepare input buffer */ |
216 // check for request body and prepare input buffer |
220 char *ctlen_str = pblock_findkeyval(pb_key_content_length, rq->rq.headers); |
217 char *ctlen_str = pblock_findkeyval(pb_key_content_length, rq->rq.headers); |
221 if(ctlen_str) { |
218 if(ctlen_str) { |
222 int ctlen = atoi(ctlen_str); |
219 int ctlen = atoi(ctlen_str); |
223 |
220 |
224 printf("request body length: %d\n", ctlen); |
221 printf("request body length: %d\n", ctlen); |
225 |
222 |
226 netbuf *nb = request->netbuf; |
223 netbuf *nb = request->netbuf; |
227 |
224 |
228 /* create new netbuf */ |
225 /* create new netbuf */ |
229 NetIOStream *net_io = (NetIOStream*)net_stream_from_fd( |
226 NetIOStream *net_io = (NetIOStream*)net_stream_from_fd( |
|
227 pool, |
230 request->connection->fd); |
228 request->connection->fd); |
231 net_io->max_read = ctlen; |
229 net_io->max_read = ctlen; |
232 |
230 |
233 sn->sn.inbuf = malloc(sizeof(netbuf)); |
231 sn->sn.inbuf = pool_malloc(pool, sizeof(netbuf)); |
234 sn->sn.inbuf->sd = net_io; |
232 sn->sn.inbuf->sd = net_io; |
235 sn->sn.inbuf->pos = 0; |
233 sn->sn.inbuf->pos = 0; |
236 |
234 |
237 /* prepare buffer */ |
235 // prepare buffer |
238 int cur_input_len = nb->cursize - nb->pos; |
236 int cur_input_len = nb->cursize - nb->pos; |
239 |
237 |
240 if(cur_input_len >= ctlen) { |
238 if(cur_input_len >= ctlen) { |
241 /* |
239 /* |
242 * all data is already in the primary input buffer |
240 * all data is already in the primary input buffer |
245 sn->sn.inbuf->maxsize = ctlen; |
243 sn->sn.inbuf->maxsize = ctlen; |
246 sn->sn.inbuf->cursize = ctlen; |
244 sn->sn.inbuf->cursize = ctlen; |
247 sn->sn.inbuf->inbuf = nb->inbuf + nb->pos; |
245 sn->sn.inbuf->inbuf = nb->inbuf + nb->pos; |
248 } else { |
246 } else { |
249 sn->sn.inbuf->maxsize = (ctlen > 2048) ? (2048) : (ctlen); |
247 sn->sn.inbuf->maxsize = (ctlen > 2048) ? (2048) : (ctlen); |
250 sn->sn.inbuf->inbuf = malloc(sn->sn.inbuf->maxsize); |
248 sn->sn.inbuf->inbuf = pool_malloc(pool, sn->sn.inbuf->maxsize); |
251 |
249 |
252 if(cur_input_len > 0) { |
250 if(cur_input_len > 0) { |
253 /* we have read a part of the request body -> copy to netbuf */ |
251 // we have read a part of the request body -> copy to netbuf |
254 memcpy(sn->sn.inbuf->inbuf, nb->inbuf+nb->pos, cur_input_len); |
252 memcpy(sn->sn.inbuf->inbuf, nb->inbuf+nb->pos, cur_input_len); |
255 } |
253 } |
256 |
254 |
257 sn->sn.inbuf->cursize = cur_input_len; |
255 sn->sn.inbuf->cursize = cur_input_len; |
258 } |
256 } |