version 1.1, 2012/02/21 23:16:22
|
version 1.1.1.2, 2013/07/22 00:36:10
|
Line 1
|
Line 1
|
/* $Id$ */ |
/* $Id$ */ |
/* Project : miniUPnP |
/* Project : miniUPnP |
* Author : Thomas Bernard |
* Author : Thomas Bernard |
* Copyright (c) 2011 Thomas Bernard | * Copyright (c) 2011-2012 Thomas Bernard |
* This software is subject to the conditions detailed in the |
* This software is subject to the conditions detailed in the |
* LICENCE file provided in this distribution. |
* LICENCE file provided in this distribution. |
* */ |
* */ |
Line 16
|
Line 16
|
#include <netinet/in.h> |
#include <netinet/in.h> |
#include <signal.h> |
#include <signal.h> |
#include <time.h> |
#include <time.h> |
|
#include <errno.h> |
|
|
#define CRAP_LENGTH (2048) |
#define CRAP_LENGTH (2048) |
|
|
volatile int quit = 0; | volatile sig_atomic_t quit = 0; |
volatile int child_to_wait_for = 0; | volatile sig_atomic_t child_to_wait_for = 0; |
|
|
/** |
/** |
* signal handler for SIGCHLD (child status has changed) |
* signal handler for SIGCHLD (child status has changed) |
Line 129 char * build_chunked_response(int content_length, int
|
Line 130 char * build_chunked_response(int content_length, int
|
response_buffer[(*response_len)++] = '\r'; |
response_buffer[(*response_len)++] = '\r'; |
response_buffer[(*response_len)++] = '\n'; |
response_buffer[(*response_len)++] = '\n'; |
} |
} |
memcpy(response_buffer + *response_len, "0\r\n", 3); | /* the last chunk : "0\r\n" a empty body and then |
*response_len += 3; | * the final "\r\n" */ |
| memcpy(response_buffer + *response_len, "0\r\n\r\n", 5); |
| *response_len += 5; |
free(content_buffer); |
free(content_buffer); |
|
|
printf("resp_length=%d buffer_length=%d content_length=%d\n", |
printf("resp_length=%d buffer_length=%d content_length=%d\n", |
Line 161 void send_response(int c, const char * buffer, int len
|
Line 164 void send_response(int c, const char * buffer, int len
|
n = len; |
n = len; |
n = write(c, buffer, n); |
n = write(c, buffer, n); |
if(n < 0) { |
if(n < 0) { |
perror("write"); | if(errno != EINTR) { |
return; | perror("write"); |
| return; |
| } |
| /* if errno == EINTR, try again */ |
} else { |
} else { |
len -= n; |
len -= n; |
buffer += n; |
buffer += n; |
Line 190 void handle_http_connection(int c)
|
Line 196 void handle_http_connection(int c)
|
int content_length = 16*1024; |
int content_length = 16*1024; |
|
|
/* read the request */ |
/* read the request */ |
while(request_len < sizeof(request_buffer) && !headers_found) { | while(request_len < (int)sizeof(request_buffer) && !headers_found) { |
n = read(c, |
n = read(c, |
request_buffer + request_len, |
request_buffer + request_len, |
sizeof(request_buffer) - request_len); |
sizeof(request_buffer) - request_len); |
Line 218 void handle_http_connection(int c)
|
Line 224 void handle_http_connection(int c)
|
printf("headers :\n%.*s", request_len, request_buffer); |
printf("headers :\n%.*s", request_len, request_buffer); |
/* the request have been received, now parse the request line */ |
/* the request have been received, now parse the request line */ |
p = request_buffer; |
p = request_buffer; |
for(i = 0; i < sizeof(request_method) - 1; i++) { | for(i = 0; i < (int)sizeof(request_method) - 1; i++) { |
if(*p == ' ' || *p == '\r') |
if(*p == ' ' || *p == '\r') |
break; |
break; |
request_method[i] = *p; |
request_method[i] = *p; |
Line 227 void handle_http_connection(int c)
|
Line 233 void handle_http_connection(int c)
|
request_method[i] = '\0'; |
request_method[i] = '\0'; |
while(*p == ' ') |
while(*p == ' ') |
p++; |
p++; |
for(i = 0; i < sizeof(request_uri) - 1; i++) { | for(i = 0; i < (int)sizeof(request_uri) - 1; i++) { |
if(*p == ' ' || *p == '\r') |
if(*p == ' ' || *p == '\r') |
break; |
break; |
request_uri[i] = *p; |
request_uri[i] = *p; |
Line 236 void handle_http_connection(int c)
|
Line 242 void handle_http_connection(int c)
|
request_uri[i] = '\0'; |
request_uri[i] = '\0'; |
while(*p == ' ') |
while(*p == ' ') |
p++; |
p++; |
for(i = 0; i < sizeof(http_version) - 1; i++) { | for(i = 0; i < (int)sizeof(http_version) - 1; i++) { |
if(*p == ' ' || *p == '\r') |
if(*p == ' ' || *p == '\r') |
break; |
break; |
http_version[i] = *p; |
http_version[i] = *p; |
Line 249 void handle_http_connection(int c)
|
Line 255 void handle_http_connection(int c)
|
if(0 != strcmp(request_method, "GET")) { |
if(0 != strcmp(request_method, "GET")) { |
const char response405[] = "HTTP/1.1 405 Method Not Allowed\r\n" |
const char response405[] = "HTTP/1.1 405 Method Not Allowed\r\n" |
"Allow: GET\r\n\r\n"; |
"Allow: GET\r\n\r\n"; |
|
const char * pc; |
/* 405 Method Not Allowed */ |
/* 405 Method Not Allowed */ |
/* The response MUST include an Allow header containing a list |
/* The response MUST include an Allow header containing a list |
* of valid methods for the requested resource. */ |
* of valid methods for the requested resource. */ |
write(c, response405, sizeof(response405) - 1); | n = sizeof(response405) - 1; |
| pc = response405; |
| while(n > 0) { |
| i = write(c, pc, n); |
| if(i<0) { |
| if(errno != EINTR) { |
| perror("write"); |
| return; |
| } |
| } else { |
| n -= i; |
| pc += i; |
| } |
| } |
return; |
return; |
} |
} |
|
|
Line 360 int main(int argc, char * * argv) {
|
Line 380 int main(int argc, char * * argv) {
|
struct sockaddr_in6 * addr = (struct sockaddr_in6 *)&server_addr; |
struct sockaddr_in6 * addr = (struct sockaddr_in6 *)&server_addr; |
addr->sin6_family = AF_INET6; |
addr->sin6_family = AF_INET6; |
addr->sin6_port = htons(port); |
addr->sin6_port = htons(port); |
addr->sin6_addr = in6addr_any; | addr->sin6_addr = in6addr_loopback; |
} else { |
} else { |
struct sockaddr_in * addr = (struct sockaddr_in *)&server_addr; |
struct sockaddr_in * addr = (struct sockaddr_in *)&server_addr; |
addr->sin_family = AF_INET; |
addr->sin_family = AF_INET; |
addr->sin_port = htons(port); |
addr->sin_port = htons(port); |
addr->sin_addr.s_addr = htonl(INADDR_ANY); | addr->sin_addr.s_addr = htonl(INADDR_LOOPBACK); |
} |
} |
if(bind(s, (struct sockaddr *)&server_addr, |
if(bind(s, (struct sockaddr *)&server_addr, |
ipv6 ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in)) < 0) { |
ipv6 ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in)) < 0) { |
Line 400 int main(int argc, char * * argv) {
|
Line 420 int main(int argc, char * * argv) {
|
char * buffer; |
char * buffer; |
buffer = malloc(16*1024); |
buffer = malloc(16*1024); |
build_content(buffer, 16*1024); |
build_content(buffer, 16*1024); |
fwrite(buffer, 1, 16*1024, f); | i = fwrite(buffer, 1, 16*1024, f); |
| if(i != 16*1024) { |
| fprintf(stderr, "error writing to file %s : %dbytes written (out of %d)\n", expected_file_name, i, 16*1024); |
| } |
free(buffer); |
free(buffer); |
fclose(f); |
fclose(f); |
|
} else { |
|
fprintf(stderr, "error opening file %s for writing\n", expected_file_name); |
} |
} |
} |
} |
|
|