1
0
mirror of https://github.com/fumiama/simple-http-server.git synced 2026-06-08 20:10:43 +08:00

add hostname check

This commit is contained in:
源文雨
2023-03-11 00:01:00 +08:00
parent a9d7b8e38a
commit 3f6bb7d384
2 changed files with 41 additions and 17 deletions

View File

@@ -22,6 +22,7 @@ A necessary subset of `HTTP 1.0` with following options of request header being
### Code ### Code
- 200 OK - 200 OK
- 400 BAD REQUEST - 400 BAD REQUEST
- 403 Forbidden
- 404 NOT FOUND - 404 NOT FOUND
- 500 Internal Server Error - 500 Internal Server Error
- 501 Method Not Implemented - 501 Method Not Implemented
@@ -46,12 +47,14 @@ make install
## Command line usage ## Command line usage
```bash ```bash
simple-http-server [-h] [-d] [-p <port|unix socket path>] [-r <rootdir>] [-u <uid>] simple-http-server [-d] [-h] [-n host.name.com:port] [-p <port|unix socket path>] [-q 16] [-r <rootdir>] [-u <uid>]
``` ```
- **-h**: display this help.
- **-d**: run as daemon. - **-d**: run as daemon.
- **-h**: display this help.
- **-n**: check hostname and port.
- **-p**: if not set, we will choose a random port. - **-p**: if not set, we will choose a random port.
- **-q**: listen queue length (defalut is 16).
- **-r**: http root dir. - **-r**: http root dir.
- **-u**: run as this uid. - **-u**: run as this uid.

View File

@@ -48,11 +48,14 @@ typedef struct HTTP_REQUEST HTTP_REQUEST;
static int server_sock = -1; static int server_sock = -1;
static char* hostnameport;
static void accept_request(void *); static void accept_request(void *);
static void bad_request(int); static void bad_request(int);
static void cat(int, FILE *); static void cat(int, FILE *);
static void error_die(const char *); static void error_die(const char *);
static void execute_cgi(int, int, const HTTP_REQUEST*); static void execute_cgi(int, int, const HTTP_REQUEST*);
static void forbidden(int);
static uint32_t get_file_size(const char *, int); static uint32_t get_file_size(const char *, int);
static int get_line(int, char *, int); static int get_line(int, char *, int);
static void handle_quit(int); static void handle_quit(int);
@@ -156,9 +159,15 @@ static void accept_request(void *cli) {
cgi &= ((st.st_mode & S_IXUSR) || (st.st_mode & S_IXGRP) || (st.st_mode & S_IXOTH)); cgi &= ((st.st_mode & S_IXUSR) || (st.st_mode & S_IXGRP) || (st.st_mode & S_IXOTH));
while((numchars > 0) && strcmp("\n", buf)) { while((numchars > 0) && strcmp("\n", buf)) {
numchars = get_line(client, buf, sizeof(buf)); numchars = get_line(client, buf, sizeof(buf));
if(!content_length && strcasestr(buf, "Content-Length: ")) { if(!content_length && !strncasecmp(buf, "Content-Length: ", 16)) {
content_length = atoi(buf + 16); content_length = atoi(buf + 16);
} }
else if(hostnameport && !strncasecmp(buf, "Host: ", 6)) {
if(strncasecmp(buf+6, hostnameport, strlen(hostnameport))) {
forbidden(client);
goto DISCARD_AND_CLOSE;
}
}
} }
if(method_type == POST && content_length == -1) bad_request(client); if(method_type == POST && content_length == -1) bad_request(client);
else if(!cgi) serve_file(client, path); else if(!cgi) serve_file(client, path);
@@ -171,7 +180,7 @@ static void accept_request(void *cli) {
execute_cgi(client, content_length, &request); execute_cgi(client, content_length, &request);
} }
} while(0); } while(0);
DISCARD_AND_CLOSE:
discard(client); discard(client);
close(client); close(client);
} }
@@ -203,17 +212,7 @@ static void cat(int client, FILE *resource) {
rewind(resource); rewind(resource);
sendfile(client, fileno(resource), &len, file_size); sendfile(client, fileno(resource), &len, file_size);
#endif #endif
printf("Sendfile: %u bytes.\n", (unsigned int)len); // printf("Sendfile: %u bytes.\n", (unsigned int)len);
}
/**********************************************************************/
/* Inform the client that a CGI script could not be executed.
* Parameter: the client socket descriptor. */
/**********************************************************************/
#define HTTP500 "HTTP/1.0 500 Internal Server Error\r\nContent-Type: text/html\r\n\r\n<P>Internal Server Error.\r\n"
static void internal_error(int client) {
send(client, HTTP500, sizeof(HTTP500)-1, 0);
puts("500 Internal Server Error.");
} }
/**********************************************************************/ /**********************************************************************/
@@ -321,6 +320,17 @@ CGI_CLOSE:
waitpid(pid, NULL, 0); waitpid(pid, NULL, 0);
} }
/**********************************************************************/
/* Inform the client that the server understood
the request but refuses to authorize it
* Parameters: client socket */
/**********************************************************************/
#define HTTP403 "HTTP/1.0 403 Forbidden\r\nContent-Type: text/html\r\n\r\n<P>Your access is not allowed.\r\n"
static void forbidden(int client) {
send(client, HTTP403, sizeof(HTTP403)-1, 0);
puts("403 Forbidden.");
}
/**********************************************************************/ /**********************************************************************/
/* Returns the size of a file. */ /* Returns the size of a file. */
/* Parameters: path of the file */ /* Parameters: path of the file */
@@ -409,6 +419,16 @@ static int headers(int client, const char *filepath) {
} else return 0; } else return 0;
} }
/**********************************************************************/
/* Inform the client that a CGI script could not be executed.
* Parameter: the client socket descriptor. */
/**********************************************************************/
#define HTTP500 "HTTP/1.0 500 Internal Server Error\r\nContent-Type: text/html\r\n\r\n<P>Internal Server Error.\r\n"
static void internal_error(int client) {
send(client, HTTP500, sizeof(HTTP500)-1, 0);
puts("500 Internal Server Error.");
}
/**********************************************************************/ /**********************************************************************/
/* Give a client a 404 not found status message. */ /* Give a client a 404 not found status message. */
/**********************************************************************/ /**********************************************************************/
@@ -559,12 +579,12 @@ static int accept_client(int is_unix_sock) {
} }
pthread_t accept_thread; pthread_t accept_thread;
if(pthread_create(&accept_thread, &attr, (void * (*)(void *))&accept_request, (void*)(uintptr_t)client_sock) != 0) perror("pthread_create"); if(pthread_create(&accept_thread, &attr, (void * (*)(void *))&accept_request, (void*)(uintptr_t)client_sock) != 0) perror("pthread_create");
printf("Created new thread at %p\n", (void*)accept_thread); // printf("Created new thread at %p\n", (void*)accept_thread);
} }
} }
#define argequ(arg) (*(uint16_t*)argv[i] == *(uint16_t*)(arg)) #define argequ(arg) (*(uint16_t*)argv[i] == *(uint16_t*)(arg))
#define USAGE "Usage:\tsimple-http-server [-d] [-h] [-p <port|unix socket path>] [-q 16] [-r <rootdir>] [-u <uid>]\n -d:\trun as daemon.\n -h:\tdisplay this help.\n -p:\tif not set, we will choose a random port.\n -q: listen queue length (defalut is 16)\n -r:\thttp root dir.\n -u:\trun as this uid." #define USAGE "Usage:\tsimple-http-server [-d] [-h] [-n host.name.com:port] [-p <port|unix socket path>] [-q 16] [-r <rootdir>] [-u <uid>]\n -d:\trun as daemon.\n -h:\tdisplay this help.\n -n:\tcheck hostname and port.\n -p:\tif not set, we will choose a random port.\n -q:\tlisten queue length (defalut is 16).\n -r:\thttp root dir.\n -u:\trun as this uid."
int main(int argc, char **argv) { int main(int argc, char **argv) {
int as_daemon = 0; int as_daemon = 0;
int queue_len = 16; int queue_len = 16;
@@ -585,6 +605,7 @@ int main(int argc, char **argv) {
puts(USAGE); puts(USAGE);
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
} }
else if(argequ("-n")) hostnameport = argv[++i];
else if(argequ("-p")) { else if(argequ("-p")) {
i++; i++;
if(isdigit(argv[i][0])) port = (uint16_t)atoi(argv[i]); if(isdigit(argv[i][0])) port = (uint16_t)atoi(argv[i]);