3 * Copyright (C) 2001-2008, Eduardo Silva P.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Library General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 #include <sys/types.h>
23 #include <sys/socket.h>
25 #include <netinet/in.h>
36 #include "http_status.h"
44 int M_METHOD_Post(struct client_request
*cr
, struct request
*s_request
)
48 char buffer[MAX_REQUEST_BODY];
49 int content_length_post=0;
51 if(!(tmp=Request_Find_Variable(s_request->body, RH_CONTENT_LENGTH))){
52 Request_Error(M_CLIENT_LENGHT_REQUIRED, cr, s_request,0,s_request->log);
56 content_length_post = (int) atoi(tmp);
59 if(content_length_post<=0 || content_length_post >=MAX_REQUEST_BODY){
60 Request_Error(M_CLIENT_BAD_REQUEST, cr, s_request, 0, s_request->log);
64 if(!(tmp = Request_Find_Variable(s_request->body, RH_CONTENT_TYPE))){
65 Request_Error(M_CLIENT_BAD_REQUEST, cr, s_request, 0, s_request->log);
69 s_request->content_type = tmp;
71 if(s_request->post_variables==NULL || strlen(s_request->post_variables)<=4) {
72 s_request->post_variables=NULL;
76 if(strlen(s_request->post_variables) < content_length_post){
77 content_length_post=strlen(buffer);
80 s_request->content_length=content_length_post;
86 /* Reuturn the POST variables sent in the request */
87 char *M_Get_POST_Vars(char *request
, int index
, char *strend
)
90 int length
, length_string_end
;
93 length
= strlen(request
);
94 length_string_end
= strlen(strend
);
95 if(length_string_end
== 2)
100 for(i
=index
; i
<=length
; i
++)
102 if(strncmp(request
+i
, strend
, length_string_end
)==0)
107 return mk_string_copy_substr(request
, index
, i
-last_byte
);
111 /* Send_Header , envia las cabeceras principales */
112 int M_METHOD_send_headers(int fd
, struct client_request
*cr
,
113 struct request
*sr
, struct log_info
*s_log
)
118 struct header_values
*sh
;
124 iov
= mk_iov_create(50);
129 mk_iov_add_entry(iov
, RESP_HTTP_OK
, LEN_RESP_HTTP_OK
,
130 MK_IOV_BREAK_LINE
, MK_IOV_NOT_FREE_BUF
);
134 mk_iov_add_entry(iov
, RESP_HTTP_PARTIAL
,
135 LEN_RESP_HTTP_PARTIAL
,
137 MK_IOV_NOT_FREE_BUF
);
141 s_log
->status
=S_LOG_OFF
;
142 mk_iov_add_entry(iov
, RESP_REDIR_MOVED
,
143 LEN_RESP_REDIR_MOVED
,
145 MK_IOV_NOT_FREE_BUF
);
148 case M_REDIR_MOVED_T
:
149 s_log
->status
=S_LOG_ON
;
150 mk_iov_add_entry(iov
, RESP_REDIR_MOVED_T
,
151 LEN_RESP_REDIR_MOVED_T
,
153 MK_IOV_NOT_FREE_BUF
);
157 s_log
->status
=S_LOG_OFF
;
158 mk_iov_add_entry(iov
, RESP_NOT_MODIFIED
,
159 LEN_RESP_NOT_MODIFIED
,
161 MK_IOV_NOT_FREE_BUF
);
164 case M_CLIENT_BAD_REQUEST
:
165 mk_iov_add_entry(iov
, RESP_CLIENT_BAD_REQUEST
,
166 LEN_RESP_CLIENT_BAD_REQUEST
,
168 MK_IOV_NOT_FREE_BUF
);
171 case M_CLIENT_FORBIDDEN
:
172 mk_iov_add_entry(iov
, RESP_CLIENT_FORBIDDEN
,
173 LEN_RESP_CLIENT_FORBIDDEN
,
175 MK_IOV_NOT_FREE_BUF
);
178 case M_CLIENT_NOT_FOUND
:
179 mk_iov_add_entry(iov
, RESP_CLIENT_NOT_FOUND
,
180 LEN_RESP_CLIENT_NOT_FOUND
,
182 MK_IOV_NOT_FREE_BUF
);
185 case M_CLIENT_METHOD_NOT_ALLOWED
:
186 mk_iov_add_entry(iov
, RESP_CLIENT_METHOD_NOT_ALLOWED
,
187 LEN_RESP_CLIENT_METHOD_NOT_ALLOWED
,
189 MK_IOV_NOT_FREE_BUF
);
192 case M_CLIENT_REQUEST_TIMEOUT
:
193 mk_iov_add_entry(iov
, RESP_CLIENT_REQUEST_TIMEOUT
,
194 LEN_RESP_CLIENT_REQUEST_TIMEOUT
,
196 MK_IOV_NOT_FREE_BUF
);
197 s_log
->status
=S_LOG_OFF
;
200 case M_CLIENT_LENGHT_REQUIRED
:
201 mk_iov_add_entry(iov
, RESP_CLIENT_LENGTH_REQUIRED
,
202 LEN_RESP_CLIENT_LENGTH_REQUIRED
,
204 MK_IOV_NOT_FREE_BUF
);
207 case M_SERVER_INTERNAL_ERROR
:
208 mk_iov_add_entry(iov
, RESP_SERVER_INTERNAL_ERROR
,
209 LEN_RESP_SERVER_INTERNAL_ERROR
,
211 MK_IOV_NOT_FREE_BUF
);
214 case M_SERVER_HTTP_VERSION_UNSUP
:
215 mk_iov_add_entry(iov
, RESP_SERVER_HTTP_VERSION_UNSUP
,
216 LEN_RESP_SERVER_HTTP_VERSION_UNSUP
,
218 MK_IOV_NOT_FREE_BUF
);
223 s_log
->final_response
= sh
->status
;
231 /* Informacion del server */
232 mk_iov_add_entry(iov
, sr
->host_conf
->header_host_signature
,
233 strlen(sr
->host_conf
->header_host_signature
),
234 MK_IOV_BREAK_LINE
, MK_IOV_NOT_FREE_BUF
);
237 date
= PutDate_string(0);
238 m_build_buffer(&buffer
, &len
, "Date: %s", date
);
239 mk_iov_add_entry(iov
, buffer
, len
,
240 MK_IOV_BREAK_LINE
, MK_IOV_FREE_BUF
);
244 if(sh
->location
!=NULL
)
252 mk_iov_add_entry(iov
, buffer
, len
,
253 MK_IOV_BREAK_LINE
, MK_IOV_FREE_BUF
);
257 if(sh
->last_modified
!=NULL
){
264 mk_iov_add_entry(iov
, buffer
, len
,
265 MK_IOV_BREAK_LINE
, MK_IOV_FREE_BUF
);
269 if(cr
->counter_connections
<config
->max_keep_alive_request
&& config
->keep_alive
==VAR_ON
){
273 "Keep-Alive: timeout=%i, max=%i",
274 config
->keep_alive_timeout
,
275 config
->max_keep_alive_request
-cr
->counter_connections
);
276 mk_iov_add_entry(iov
, buffer
, len
,
277 MK_IOV_BREAK_LINE
, MK_IOV_FREE_BUF
);
282 "Connection: Keep-Alive");
283 mk_iov_add_entry(iov
, buffer
, len
,
284 MK_IOV_BREAK_LINE
, MK_IOV_FREE_BUF
);
290 "Connection: close");
291 mk_iov_add_entry(iov
, buffer
, len
,
292 MK_IOV_BREAK_LINE
, MK_IOV_FREE_BUF
);
295 /* Tipo de contenido de la informacion */
296 if(sh
->content_type
!=NULL
){
302 mk_iov_add_entry(iov
, buffer
, len
,
303 MK_IOV_BREAK_LINE
, MK_IOV_FREE_BUF
);
310 "Accept-Ranges: bytes",
312 mk_iov_add_entry(iov
, buffer
, len
,
313 MK_IOV_BREAK_LINE
, MK_IOV_FREE_BUF
);
315 //printf("\n->sh->cl: %i", sh->content_length);
318 /* TamaƱo total de la informacion a enviar */
319 if((sh
->content_length
!=0 &&
320 (sh
->ranges
[0]>=0 || sh
->ranges
[1]>=0)) &&
321 config
->resume
==VAR_ON
){
325 if(sh
->ranges
[0]>=0 && sh
->ranges
[1]==-1){
326 length
= (unsigned int) ( sh
->content_length
- sh
->ranges
[0] );
333 mk_iov_add_entry(iov
, buffer
, len
,
334 MK_IOV_BREAK_LINE
, MK_IOV_FREE_BUF
);
342 (sh
->content_length
- 1),
344 mk_iov_add_entry(iov
, buffer
, len
,
345 MK_IOV_BREAK_LINE
, MK_IOV_FREE_BUF
);
349 if(sh
->ranges
[0]>=0 && sh
->ranges
[1]>=0){
350 length
= (unsigned int) abs(sh
->ranges
[1] - sh
->ranges
[0]) + 1;
357 mk_iov_add_entry(iov
, buffer
, len
,
358 MK_IOV_BREAK_LINE
, MK_IOV_FREE_BUF
);
369 mk_iov_add_entry(iov
, buffer
, len
,
370 MK_IOV_BREAK_LINE
, MK_IOV_FREE_BUF
);
373 if(sh
->ranges
[0]==-1 && sh
->ranges
[1]>=0){
380 mk_iov_add_entry(iov
, buffer
, len
,
381 MK_IOV_BREAK_LINE
, MK_IOV_FREE_BUF
);
388 (sh
->content_length
- sh
->ranges
[1]),
389 (sh
->content_length
- 1),
391 mk_iov_add_entry(iov
, buffer
, len
,
392 MK_IOV_BREAK_LINE
, MK_IOV_FREE_BUF
);
395 else if(sh
->content_length
>=0)
403 mk_iov_add_entry(iov
, buffer
, len
,
404 MK_IOV_BREAK_LINE
, MK_IOV_FREE_BUF
);
406 else if(sh
->status
==M_REDIR_MOVED
)
414 mk_iov_add_entry(iov
, buffer
, len
,
415 MK_IOV_BREAK_LINE
, MK_IOV_FREE_BUF
);
418 if(sh
->cgi
==SH_NOCGI
)
420 mk_iov_add_separator(iov
, MK_IOV_BREAK_LINE
);
422 mk_socket_set_cork_flag(fd
, TCP_CORK_ON
);
423 mk_iov_send(fd
, iov
);