1
0
mirror of https://github.com/fumiama/simple-http-server.git synced 2026-06-05 00:30:23 +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
- 200 OK
- 400 BAD REQUEST
- 403 Forbidden
- 404 NOT FOUND
- 500 Internal Server Error
- 501 Method Not Implemented
@@ -46,12 +47,14 @@ make install
## Command line usage
```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.
- **-h**: display this help.
- **-n**: check hostname and port.
- **-p**: if not set, we will choose a random port.
- **-q**: listen queue length (defalut is 16).
- **-r**: http root dir.
- **-u**: run as this uid.

View File

@@ -48,11 +48,14 @@ typedef struct HTTP_REQUEST HTTP_REQUEST;
static int server_sock = -1;
static char* hostnameport;
static void accept_request(void *);
static void bad_request(int);
static void cat(int, FILE *);
static void error_die(const char *);
static void execute_cgi(int, int, const HTTP_REQUEST*);
static void forbidden(int);
static uint32_t get_file_size(const char *, int);
static int get_line(int, char *, 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));
while((numchars > 0) && strcmp("\n", 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);
}
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);
else if(!cgi) serve_file(client, path);
@@ -171,7 +180,7 @@ static void accept_request(void *cli) {
execute_cgi(client, content_length, &request);
}
} while(0);
DISCARD_AND_CLOSE:
discard(client);
close(client);
}
@@ -203,17 +212,7 @@ static void cat(int client, FILE *resource) {
rewind(resource);
sendfile(client, fileno(resource), &len, file_size);
#endif
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.");
// printf("Sendfile: %u bytes.\n", (unsigned int)len);
}
/**********************************************************************/
@@ -321,6 +320,17 @@ CGI_CLOSE:
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. */
/* Parameters: path of the file */
@@ -409,6 +419,16 @@ static int headers(int client, const char *filepath) {
} 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. */
/**********************************************************************/
@@ -559,12 +579,12 @@ static int accept_client(int is_unix_sock) {
}
pthread_t accept_thread;
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 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 as_daemon = 0;
int queue_len = 16;
@@ -585,6 +605,7 @@ int main(int argc, char **argv) {
puts(USAGE);
exit(EXIT_SUCCESS);
}
else if(argequ("-n")) hostnameport = argv[++i];
else if(argequ("-p")) {
i++;
if(isdigit(argv[i][0])) port = (uint16_t)atoi(argv[i]);