Little internal changes
[MonkeyD.git] / src / request.c
blob51e81e4a6812e06cb1b71e6f4961c5140bb90528
2 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
4 /* Monkey HTTP Daemon
5 * ------------------
6 * Copyright (C) 2001-2008, Eduardo Silva P.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Library General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <sys/stat.h>
26 #include <unistd.h>
27 #include <string.h>
28 #include <sys/socket.h>
29 #include <sys/time.h>
30 #include <time.h>
31 #include <netdb.h>
32 #include <sys/wait.h>
33 #include <signal.h>
34 #include <errno.h>
36 #include <string.h>
38 #include <arpa/inet.h>
39 #include <netinet/in.h>
40 #include <sys/types.h>
42 #include "request.h"
43 #include "monkey.h"
44 #include "http.h"
45 #include "http_status.h"
46 #include "string.h"
47 #include "cgi.h"
48 #include "str.h"
49 #include "config.h"
50 #include "scheduler.h"
51 #include "epoll.h"
52 #include "socket.h"
53 #include "logfile.h"
54 #include "utils.h"
55 #include "header.h"
56 #include "deny.h"
57 #include "user.h"
58 #include "method.h"
59 #include "memory.h"
60 #include "socket.h"
61 #include "cache.h"
62 #include "clock.h"
64 struct request *mk_request_parse(struct client_request *cr)
66 int i, n, init_block=0, n_blocks=0;
67 int pipelined=FALSE;
68 struct request *cr_buf=0, *cr_search=0;
70 init_block = 0;
72 for(i=cr->first_block_end; i<=cr->body_length-mk_endblock.len; i++)
74 /* Allocating request block */
75 cr_buf = mk_request_alloc();
77 /* mk_pointer */
78 cr_buf->body.data = cr->body+init_block;
79 cr_buf->body.len = i-init_block;
81 if(i==cr->first_block_end){
82 cr_buf->method = cr->first_method;
84 else{
85 cr_buf->method = mk_http_method_get(cr_buf->body.data);
89 cr_buf->log->ip = cr->ip;
90 cr_buf->next = NULL;
92 i = init_block = i + mk_endblock.len;
94 /* Looking for POST data */
95 if(cr_buf->method == HTTP_METHOD_POST)
97 cr_buf->post_variables =
98 mk_method_post_get_vars(cr->body, i);
100 if(cr_buf->post_variables.len >= 0)
102 i = init_block = i+cr_buf->post_variables.len;
106 if(!cr->request)
108 cr->request = cr_buf;
110 else{
111 cr_search = cr->request;
112 while(cr_search)
114 if(cr_search->next==NULL)
116 cr_search->next = cr_buf;
117 break;
119 else
121 cr_search = cr_search->next;
125 n_blocks++;
126 n = mk_string_search(cr->body+i, mk_endblock.data);
127 if(n<=0)
129 break;
131 else{
132 i = i + n;
136 /* Checking pipelining connection */
137 cr_search = cr->request;
138 if(n_blocks>1)
140 pipelined = TRUE;
142 while(cr_search){
143 if(cr_search->method!=HTTP_METHOD_GET &&
144 cr_search->method!=HTTP_METHOD_HEAD)
146 pipelined = FALSE;
147 break;
149 cr_search = cr_search->next;
152 if(pipelined == FALSE){
153 /* All pipelined requests must use GET method */
154 return NULL;
156 else{
157 cr->pipelined = TRUE;
161 /* DEBUG BLOCKS
162 printf("*****************************************");
163 fflush(stdout);
164 cr_search = cr->request;
165 while(cr_search){
166 printf("\n---BLOCK---:\n%s---END BLOCK---\n\n", cr_search->body);
167 fflush(stdout);
168 cr_search = cr_search->next;
172 return cr->request;
175 int mk_handler_read(int socket)
177 int bytes, efd;
178 struct client_request *cr;
180 cr = mk_request_client_get(socket);
182 if(!cr)
184 /* Note: Linux don't set TCP_NODELAY socket flag by default,
185 * also we set the client socket on non-blocking mode
187 mk_socket_set_tcp_nodelay(socket);
188 mk_socket_set_nonblocking(socket);
190 cr = mk_request_client_create(socket);
193 bytes = read(socket, cr->body+cr->body_length,
194 MAX_REQUEST_BODY-cr->body_length);
196 if (bytes < 0) {
197 if (errno == EAGAIN) {
198 return 1;
200 else{
201 mk_request_client_remove(socket);
202 return -1;
205 if (bytes == 0){
206 mk_request_client_remove(socket);
207 return -1;
210 if(bytes > 0)
212 cr->body_length+=bytes;
213 cr->body[cr->body_length] = '\0';
215 if(mk_http_pending_request(cr)==0){
216 efd = mk_sched_get_thread_poll();
217 mk_epoll_socket_change_mode(efd, socket, MK_EPOLL_WRITE);
219 else if(cr->body_length+1 >= MAX_REQUEST_BODY)
221 /* Request is incomplete and our buffer is full,
222 * close connection
224 mk_request_client_remove(socket);
225 return -1;
229 return 0;
232 int mk_handler_write(int socket, struct client_request *cr)
234 int bytes, final_status=0;
235 struct request *p_request;
238 * Get node from schedule list node which contains
239 * the information regarding to the current thread
241 cr = mk_request_client_get(socket);
243 if(!cr)
245 return -1;
248 if(!cr->request)
250 if(!mk_request_parse(cr))
252 return -1;
256 p_request = cr->request;
258 while(p_request)
260 /* Request not processed */
261 if(p_request->bytes_to_send < 0)
263 final_status = mk_request_process(cr, p_request);
265 /* Request with data to send */
266 else if(p_request->bytes_to_send>0)
268 bytes = SendFile(socket, p_request);
269 final_status = bytes;
272 * If we got an error, we don't want to parse
273 * and send information for another pipelined request
275 if(final_status > 0)
277 return final_status;
279 else if(final_status <= 0)
281 mk_logger_write_log(p_request->log, p_request->host_conf);
283 p_request = p_request->next;
286 /* If we are here, is because all pipelined request were
287 * processed successfully, let's return 0;
289 return 0;
292 int mk_request_process(struct client_request *cr, struct request *s_request)
294 int status=0;
295 struct host *host;
297 status = mk_request_header_process(s_request);
299 if(status<0)
301 return EXIT_NORMAL;
304 switch(s_request->method)
306 case METHOD_NOT_ALLOWED:
307 mk_request_error(M_CLIENT_METHOD_NOT_ALLOWED, cr,
308 s_request, 1, s_request->log);
309 return EXIT_NORMAL;
310 case METHOD_NOT_FOUND:
311 mk_request_error(M_SERVER_NOT_IMPLEMENTED, cr,
312 s_request, 1, s_request->log);
313 return EXIT_NORMAL;
316 s_request->user_home=VAR_OFF;
317 s_request->log->method = s_request->method;
319 /* Valid request URI? */
320 if(s_request->uri_processed==NULL){
321 mk_request_error(M_CLIENT_BAD_REQUEST, cr, s_request, 1,
322 s_request->log);
323 return EXIT_NORMAL;
326 /* URL it's Allowed ? */
327 if(Deny_Check(s_request, cr->ip.data)==-1) {
328 s_request->log->final_response=M_CLIENT_FORBIDDEN;
329 mk_request_error(M_CLIENT_FORBIDDEN, cr, s_request, 1,
330 s_request->log);
331 return EXIT_NORMAL;
335 /* HTTP/1.1 needs Host header */
336 if(!s_request->host.data && s_request->protocol==HTTP_PROTOCOL_11){
337 s_request->log->final_response=M_CLIENT_BAD_REQUEST;
338 mk_request_error(M_CLIENT_BAD_REQUEST, cr, s_request,1,
339 s_request->log);
340 return EXIT_NORMAL;
343 /* Method not allowed ? */
344 if(s_request->method==METHOD_NOT_ALLOWED){
345 s_request->log->final_response=M_CLIENT_METHOD_NOT_ALLOWED;
346 mk_request_error(M_CLIENT_METHOD_NOT_ALLOWED, cr, s_request, 1,
347 s_request->log);
348 return EXIT_NORMAL;
351 /* Validating protocol version */
352 if(s_request->protocol == HTTP_PROTOCOL_UNKNOWN)
355 s_request->log->final_response=M_SERVER_HTTP_VERSION_UNSUP;
356 mk_request_error(M_SERVER_HTTP_VERSION_UNSUP, cr, s_request, 1,
357 s_request->log);
358 return EXIT_NORMAL;
361 if(s_request->host.data)
363 host=mk_config_host_find(s_request->host);
364 if(host)
366 s_request->host_conf = host;
368 else{
369 s_request->host_conf = config->hosts;
372 else{
373 s_request->host_conf = config->hosts;
375 s_request->log->host_conf = s_request->host_conf;
377 /* is requesting an user home directory ? */
378 if(strncmp(s_request->uri_processed, USER_HOME_STRING,
379 strlen(USER_HOME_STRING))==0 && config->user_dir)
381 if(User_main(cr, s_request)!=0)
382 return EXIT_NORMAL;
385 /* Handling method requested */
386 if(s_request->method==HTTP_METHOD_POST)
388 if((status=mk_method_post(cr, s_request))==-1){
389 return status;
393 status = mk_http_init(cr, s_request);
395 return status;
398 /* Return a struct with method, URI , protocol version
399 and all static headers defined here sent in request */
400 int mk_request_header_process(struct request *sr)
402 int uri_init=0, uri_end=0;
403 char *query_init=0;
404 int prot_init=0, prot_end=0, pos_sep=0;
405 int fh_limit;
406 char *str_prot=0, *port=0;
407 char *headers;
408 mk_pointer host;
410 /* If verification fails it will return always
411 * a bad request status
413 sr->log->final_response = M_CLIENT_BAD_REQUEST;
415 /* Method */
416 sr->method_p = mk_http_method_check_str(sr->method);
418 /* Request URI */
419 uri_init = (index(sr->body.data, ' ') - sr->body.data) + 1;
420 fh_limit = (index(sr->body.data, '\n') - sr->body.data);
422 uri_end = mk_string_search_r(sr->body.data, ' ',
423 fh_limit) - 1;
425 if(uri_end <= 0)
427 return -1;
430 prot_init = uri_end + 2;
432 if(uri_end < uri_init)
434 return -1;
437 /* Query String */
438 query_init = index(sr->body.data+uri_init, '?');
439 if(query_init)
441 int init, end;
443 init = (int) (query_init-(sr->body.data+uri_init)) + uri_init;
444 if(init <= uri_end)
446 end = uri_end;
447 uri_end = init - 1;
449 sr->query_string = mk_pointer_create(sr->body.data,
450 init+1, end+1);
454 /* Request URI Part 2 */
455 sr->uri = sr->log->uri = mk_pointer_create(sr->body.data,
456 uri_init, uri_end+1);
458 if(sr->uri.len<1)
460 return -1;
464 /* HTTP Version */
465 prot_end = fh_limit-1;
466 if(prot_end!=prot_init && prot_end>0){
467 str_prot = mk_string_copy_substr(sr->body.data,
468 prot_init, prot_end);
469 sr->protocol = sr->log->protocol =
470 mk_http_protocol_check(str_prot);
472 mk_mem_free(str_prot);
475 headers = sr->body.data+prot_end+mk_crlf.len;
477 /* URI processed */
478 sr->uri_processed = get_real_string(sr->uri);
480 if(!sr->uri_processed)
482 sr->uri_processed = mk_pointer_to_buf(sr->uri);
483 sr->uri_twin = VAR_ON;
486 /* Creating table of content (index) for request headers */
487 int toc_len = MK_KNOWN_HEADERS;
488 struct header_toc *toc = mk_request_header_toc_create(toc_len);
489 mk_request_header_toc_parse(toc, headers, toc_len);
491 /* Host */
492 host = mk_request_header_find(toc, toc_len, headers, mk_rh_host);
494 if(host.data)
496 if((pos_sep = mk_string_char_search(host.data, ':', host.len))>=0)
498 sr->host.data = host.data;
499 sr->host.len = pos_sep;
501 port = mk_string_copy_substr(host.data, pos_sep+1, host.len);
502 sr->port = atoi(port);
503 mk_mem_free(port);
505 else{
506 sr->host=host; /* maybe null */
507 sr->port=config->standard_port;
510 else{
511 sr->host.data=NULL;
514 /* Looking for headers */
515 sr->accept = mk_request_header_find(toc, toc_len, headers, mk_rh_accept);
516 sr->accept_charset = mk_request_header_find(toc, toc_len, headers,
517 mk_rh_accept_charset);
518 sr->accept_encoding = mk_request_header_find(toc, toc_len, headers,
519 mk_rh_accept_encoding);
522 sr->accept_language = mk_request_header_find(toc, toc_len, headers,
523 mk_rh_accept_language);
524 sr->cookies = mk_request_header_find(toc, toc_len, headers, mk_rh_cookie);
525 sr->connection = mk_request_header_find(toc, toc_len, headers,
526 mk_rh_connection);
527 sr->referer = mk_request_header_find(toc, toc_len, headers,
528 mk_rh_referer);
529 sr->user_agent = mk_request_header_find(toc, toc_len, headers,
530 mk_rh_user_agent);
531 sr->range = mk_request_header_find(toc, toc_len, headers, mk_rh_range);
532 sr->if_modified_since = mk_request_header_find(toc, toc_len, headers,
533 mk_rh_if_modified_since);
535 /* Checking keepalive */
536 sr->keep_alive=VAR_OFF;
537 if(sr->connection.data)
539 if(sr->protocol==HTTP_PROTOCOL_11 ||
540 sr->protocol==HTTP_PROTOCOL_10)
542 if(mk_string_casestr(sr->connection.data,"Keep-Alive"))
544 sr->keep_alive=VAR_ON;
549 sr->log->final_response = M_HTTP_OK;
552 mk_pointer_print(sr->method_p);
553 mk_pointer_print(sr->uri);
554 mk_pointer_print(sr->query_string);
557 return 0;
560 /* Return value of some variable sent in request */
561 mk_pointer mk_request_header_find(struct header_toc *toc, int toc_len,
562 char *request_body, mk_pointer header)
564 int i;
565 mk_pointer var;
567 var.data = NULL;
568 var.len = 0;
570 /* new code */
571 if(toc)
573 for(i=0; i<toc_len; i++)
575 if(toc[i].status == 1)
577 continue;
580 if(!toc[i].init)
581 break;
583 if(strncasecmp(toc[i].init, header.data, header.len)==0)
585 var.data = toc[i].init + header.len + 1;
586 var.len = toc[i].end - var.data;
587 toc[i].status = 1;
588 return var;
593 return var;
596 /* FIXME: IMPROVE access */
597 /* Look for some index.xxx in pathfile */
598 mk_pointer mk_request_index(char *pathfile)
600 unsigned long len;
601 char *file_aux=0;
602 mk_pointer f;
603 struct indexfile *aux_index;
605 mk_pointer_reset(&f);
607 aux_index=first_index;
609 while(aux_index) {
610 m_build_buffer(&file_aux, &len, "%s%s",
611 pathfile, aux_index->indexname);
613 if(access(file_aux,F_OK)==0)
615 f.data = file_aux;
616 f.len = len;
617 return f;
619 mk_mem_free(file_aux);
620 aux_index=aux_index->next;
623 return f;
626 /* Send error responses */
627 void mk_request_error(int num_error, struct client_request *cr,
628 struct request *s_request, int debug, struct log_info *s_log)
630 char *aux_message=0;
631 mk_pointer message, page;
632 long n;
634 if(!s_log) {
635 s_log=mk_mem_malloc(sizeof(struct log_info));
638 mk_pointer_reset(&page);
640 switch(num_error) {
641 case M_CLIENT_BAD_REQUEST:
642 mk_request_set_default_page(&page, "Bad Request",
643 s_request->uri,
644 s_request->host_conf->host_signature);
645 s_log->error_msg = request_error_msg_400;
646 break;
648 case M_CLIENT_FORBIDDEN:
649 mk_request_set_default_page(&page, "Forbidden",
650 s_request->uri,
651 s_request->host_conf->host_signature);
652 s_log->error_msg = request_error_msg_403;
653 // req s_request->uri;
654 break;
656 case M_CLIENT_NOT_FOUND:
657 m_build_buffer(&message.data, &message.len,
658 "The requested URL was not found on this server.");
659 mk_request_set_default_page(&page, "Not Found",
660 message,
661 s_request->host_conf->host_signature);
662 s_log->error_msg = request_error_msg_404;
663 // req uri;
664 mk_pointer_free(&message);
665 break;
667 case M_CLIENT_METHOD_NOT_ALLOWED:
668 mk_request_set_default_page(&page, "Method Not Allowed",
669 s_request->uri,
670 s_request->host_conf->host_signature);
672 s_log->final_response=M_CLIENT_METHOD_NOT_ALLOWED;
673 s_log->error_msg = request_error_msg_405;
674 break;
676 case M_CLIENT_REQUEST_TIMEOUT:
677 s_log->status=S_LOG_OFF;
678 s_log->error_msg = request_error_msg_408;
679 break;
681 case M_CLIENT_LENGTH_REQUIRED:
682 s_log->error_msg = request_error_msg_411;
683 break;
685 case M_SERVER_NOT_IMPLEMENTED:
686 mk_request_set_default_page(&page,
687 "Method Not Implemented",
688 s_request->uri,
689 s_request->host_conf->host_signature);
690 s_log->final_response=M_SERVER_NOT_IMPLEMENTED;
691 s_log->error_msg = request_error_msg_501;
692 break;
694 case M_SERVER_INTERNAL_ERROR:
695 m_build_buffer(&message.data, &message.len,
696 "Problems found running %s ",
697 s_request->uri);
698 mk_request_set_default_page(&page, "Internal Server Error",
699 message, s_request->host_conf->host_signature);
700 s_log->error_msg = request_error_msg_500;
702 mk_pointer_free(&message);
703 break;
705 case M_SERVER_HTTP_VERSION_UNSUP:
706 mk_pointer_reset(&message);
707 mk_request_set_default_page(&page,
708 "HTTP Version Not Supported",
709 message,
710 s_request->host_conf->host_signature);
711 s_log->error_msg = request_error_msg_505;
712 break;
715 s_log->final_response=num_error;
717 s_request->headers->status = num_error;
718 s_request->headers->content_length = page.len;
719 s_request->headers->content_length_p = mk_utils_int2mkp(page.len);
720 s_request->headers->location = NULL;
721 s_request->headers->cgi = SH_NOCGI;
722 s_request->headers->pconnections_left = 0;
723 mk_pointer_reset(&s_request->headers->last_modified);
725 if(aux_message) mk_mem_free(aux_message);
727 if(!page.data)
729 mk_pointer_reset(&s_request->headers->content_type);
731 else
733 mk_pointer_set(&s_request->headers->content_type, "text/html");
736 mk_header_send(cr->socket, cr, s_request, s_log);
738 if(debug==1){
739 n = write(cr->socket, page.data, page.len);
740 mk_pointer_free(&page);
744 /* Build error page */
745 void mk_request_set_default_page(mk_pointer *page, char *title,
746 mk_pointer message, char *signature)
748 char *temp;
750 temp = mk_pointer_to_buf(message);
751 m_build_buffer(&page->data, &page->len,
752 MK_REQUEST_DEFAULT_PAGE,
753 title, temp, signature);
754 mk_mem_free(temp);
757 /* Create a memory allocation in order to handle the request data */
758 struct request *mk_request_alloc()
760 struct request *request=0;
762 request = (struct request *) mk_mem_malloc(sizeof(struct request));
763 request->log = (struct log_info *) mk_mem_malloc(sizeof(struct log_info));
765 request->status=VAR_OFF; /* Request not processed yet */
766 request->make_log=VAR_ON; /* build log file of this request ? */
768 mk_pointer_reset(&request->body);
770 request->log->final_response=M_HTTP_OK;
771 request->log->status=S_LOG_ON;
773 mk_pointer_reset(&request->log->size_p);
774 mk_pointer_reset(&request->log->error_msg);
776 request->status=VAR_ON;
777 request->method=METHOD_NOT_FOUND;
779 mk_pointer_reset(&request->uri);
780 request->uri_processed = NULL;
781 request->uri_twin = VAR_OFF;
783 request->accept.data = NULL;
784 request->accept_language.data = NULL;
785 request->accept_encoding.data = NULL;
786 request->accept_charset.data = NULL;
787 request->content_type.data = NULL;
788 request->connection.data = NULL;
789 request->cookies.data = NULL;
790 request->host.data = NULL;
791 request->if_modified_since.data = NULL;
792 request->last_modified_since.data = NULL;
793 request->range.data = NULL;
794 request->referer.data = NULL;
795 request->resume.data = NULL;
796 request->user_agent.data = NULL;
798 request->post_variables.data = NULL;
800 request->user_uri = NULL;
801 mk_pointer_reset(&request->query_string);
803 request->virtual_user = NULL;
804 request->script_filename = NULL;
805 mk_pointer_reset(&request->real_path);
806 request->host_conf = config->hosts;
808 request->bytes_to_send = -1;
809 request->bytes_offset = 0;
810 request->fd_file = -1;
812 /* Response Headers */
813 request->headers = mk_header_create();
815 return (struct request *) request;
818 void mk_request_free_list(struct client_request *cr)
820 struct request *sr=0, *before=0;
822 /* sr = last node */
824 while(cr->request)
826 sr = before = cr->request;
828 while(sr->next)
830 sr = sr->next;
833 if(sr!=cr->request){
834 while(before->next!=sr){
835 before = before->next;
837 before->next = NULL;
839 else{
840 cr->request = NULL;
842 mk_request_free(sr);
844 cr->request = NULL;
847 void mk_request_free(struct request *sr)
849 /* I hate it, but I don't know another light way :( */
850 if(sr->fd_file>0)
852 close(sr->fd_file);
854 if(sr->headers){
855 mk_mem_free(sr->headers->location);
856 mk_pointer_free(&sr->headers->last_modified);
858 mk_mem_free(sr->headers->content_type);
859 headers->content_type never it's allocated
860 with malloc or something, so we don't need
861 to free it, the value has been freed before
862 in M_METHOD_Get_and_Head(struct request *sr)
864 this BUG was reported by gentoo team.. thanks guys XD
867 mk_mem_free(sr->headers);
871 if(sr->log){
872 //mk_mem_free(sr->log->error_msg);
873 mk_mem_free(sr->log);
876 mk_pointer_reset(&sr->body);
877 mk_pointer_reset(&sr->uri);
879 if(sr->uri_twin==VAR_ON)
881 mk_mem_free(sr->uri_processed);
884 mk_pointer_free(&sr->post_variables);
885 mk_mem_free(sr->user_uri);
886 mk_pointer_reset(&sr->query_string);
888 mk_mem_free(sr->virtual_user);
889 mk_mem_free(sr->script_filename);
890 mk_pointer_free(&sr->real_path);
891 mk_mem_free(sr);
894 /* Create a client request struct and put it on the
895 * main list
897 struct client_request *mk_request_client_create(int socket)
899 struct request_idx *request_index;
900 struct client_request *cr;
902 cr = mk_mem_malloc(sizeof(struct client_request));
904 cr->pipelined = FALSE;
905 cr->counter_connections = 0;
906 cr->socket = socket;
907 cr->request = NULL;
909 mk_pointer_set(&cr->ip, mk_socket_get_ip(socket));
911 /* creation time in unix time */
912 // cr->connection_timeout = log_current_utime + config->timeout;
914 cr->next = NULL;
915 cr->body = mk_mem_malloc(MAX_REQUEST_BODY);
916 cr->body_length = 0;
917 cr->first_block_end = -1;
918 cr->first_method = HTTP_METHOD_UNKNOWN;
920 request_index = mk_sched_get_request_index();
921 if(!request_index->first)
923 request_index->first = request_index->last = cr;
924 mk_sched_set_request_index(request_index);
926 else{
927 request_index->last->next = cr;
928 request_index->last = cr;
931 return (struct client_request *) cr;
934 struct client_request *mk_request_client_get(int socket)
936 struct request_idx *request_index;
937 struct client_request *cr=NULL;
939 request_index = mk_sched_get_request_index();
940 cr = request_index->first;
941 while(cr!=NULL)
943 if(cr->socket == socket)
945 break;
947 cr = cr->next;
950 return (struct client_request *) cr;
954 * From thread sched_list_node "list", remove the client_request
955 * struct information
957 struct client_request *mk_request_client_remove(int socket)
959 struct request_idx *request_index;
960 struct client_request *cr, *aux;
962 request_index = mk_sched_get_request_index();
963 cr = request_index->first;
965 while(cr)
967 if(cr->socket == socket)
969 if(cr==request_index->first)
971 request_index->first = cr->next;
973 else
975 aux = request_index->first;
976 while(aux->next!=cr)
978 aux = aux->next;
980 aux->next = cr->next;
981 if(!aux->next)
983 request_index->last = aux;
986 break;
988 cr = cr->next;
991 mk_pointer_free(&cr->ip);
992 mk_mem_free(cr->body);
993 mk_mem_free(cr);
995 return NULL;
998 struct header_toc *mk_request_header_toc_create(int len)
1000 int i;
1001 struct header_toc *p;
1003 p = (struct header_toc *) pthread_getspecific(mk_cache_header_toc);
1005 for(i=0; i<len; i++)
1007 p[i].init = NULL;
1008 p[i].end = NULL;
1009 p[i].status = 0;
1011 return p;
1014 void mk_request_header_toc_parse(struct header_toc *toc, char *data, int len)
1016 char *p, *l;
1017 int i;
1019 p = data;
1020 for(i=0; i<len && p; i++)
1022 l = strstr(p, MK_CRLF);
1024 if(l)
1026 toc[i].init = p;
1027 toc[i].end = l;
1029 p = l + mk_crlf.len;
1031 else
1033 break;