From 86c26972bd2262e81295f32743968c7d8c8e4fc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=97=A0=E8=BE=9C=E7=9A=84=E7=86=8A=E6=9C=AC=E7=86=8A?= <10804640+innocent-kumamoto@user.noreply.gitee.com> Date: Wed, 8 May 2024 10:01:36 +0800 Subject: [PATCH] update --- simplehttpd.c | 373 +++++++++++++++++++++++++------------------------- test.c | 5 +- 2 files changed, 194 insertions(+), 184 deletions(-) diff --git a/simplehttpd.c b/simplehttpd.c index 74b1a34..05cb9f8 100644 --- a/simplehttpd.c +++ b/simplehttpd.c @@ -11,12 +11,13 @@ #include #include #include +#include #include "simplehttpd.h" #define ISspace(x) isspace((int)(x)) -#define SERVER_STRING "Server: jdbhttpd/0.1.0\r\n" +#define SERVER_STRING "Server: simplehttpd/0.0.1\r\n" typedef void (*PostProcessDoneCallback)(int, const char *, int); static PostProcessDoneCallback post_process_done_callback = NULL; @@ -27,87 +28,50 @@ static PrintLog HTTPD_LOG_ERROR = printf; static char log_dir_path[128] = {0}; -void *accept_request(void *arg); -void bad_request(int); -void cat(int, FILE *); -void cannot_execute(int); -int get_line(int, char *, int); -void headers(int, const char *); -void not_found(int); -void response_ok(int); -void serve_file(int, const char *); -void unimplemented(int); -void post_process(int, const char *, const char *, const char *); -void get_process(int, const char *, const char *, const char *); -int save_log_file(char *filename, char *buf, int len); - -void *accept_request(void *arg) +void response_ok(int client) { - int client = *(int *)arg; char buf[1024]; - int numchars; - char method[255]; - char url[255]; - size_t i, j; - char *query_string = NULL; - - numchars = get_line(client, buf, sizeof(buf)); - i = 0; - j = 0; - - while (!ISspace(buf[j]) && (i < sizeof(method) - 1)) - { - method[i] = buf[j]; - i++; - j++; - } - method[i] = '\0'; - - if (strcasecmp(method, "GET") && strcasecmp(method, "POST")) - { - unimplemented(client); - close(client); - return NULL; - } - - i = 0; - while (ISspace(buf[j]) && (j < sizeof(buf))) - j++; - while (!ISspace(buf[j]) && (i < sizeof(url) - 1) && (j < sizeof(buf))) - { + sprintf(buf, "HTTP/1.0 200 OK\r\n"); + send(client, buf, strlen(buf), MSG_NOSIGNAL); +} - url[i] = buf[j]; - i++; - j++; - } - url[i] = '\0'; +void not_found(int client) +{ + char buf[1024]; - if (strcasecmp(method, "GET") == 0) - { - query_string = url; - while ((*query_string != '?') && (*query_string != '\0')) - query_string++; + sprintf(buf, "HTTP/1.0 404 NOT FOUND\r\n"); + send(client, buf, strlen(buf), MSG_NOSIGNAL); - if (*query_string == '?') - { - *query_string = '\0'; - query_string++; - } - } + sprintf(buf, SERVER_STRING); + send(client, buf, strlen(buf), MSG_NOSIGNAL); + sprintf(buf, "Content-Type: text/html\r\n"); + send(client, buf, strlen(buf), MSG_NOSIGNAL); + sprintf(buf, "\r\n"); + send(client, buf, strlen(buf), MSG_NOSIGNAL); + sprintf(buf, "Not Found\r\n"); + send(client, buf, strlen(buf), MSG_NOSIGNAL); + sprintf(buf, "

The server could not fulfill\r\n"); + send(client, buf, strlen(buf), MSG_NOSIGNAL); + sprintf(buf, "your request because the resource specified\r\n"); + send(client, buf, strlen(buf), MSG_NOSIGNAL); + sprintf(buf, "is unavailable or nonexistent.\r\n"); + send(client, buf, strlen(buf), MSG_NOSIGNAL); + sprintf(buf, "\r\n"); + send(client, buf, strlen(buf), MSG_NOSIGNAL); +} - if (strcasecmp(method, "POST") == 0) - { - post_process(client, url, method, query_string); - response_ok(client); - } - else - { - get_process(client, url, method, query_string); - response_ok(client); - } +void cannot_execute(int client) +{ + char buf[1024]; - close(client); - return NULL; + sprintf(buf, "HTTP/1.0 500 Internal Server Error\r\n"); + send(client, buf, strlen(buf), MSG_NOSIGNAL); + sprintf(buf, "Content-type: text/html\r\n"); + send(client, buf, strlen(buf), MSG_NOSIGNAL); + sprintf(buf, "\r\n"); + send(client, buf, strlen(buf), MSG_NOSIGNAL); + sprintf(buf, "

Error occured in internal server.\r\n"); + send(client, buf, strlen(buf), MSG_NOSIGNAL); } void bad_request(int client) @@ -126,29 +90,25 @@ void bad_request(int client) send(client, buf, sizeof(buf), MSG_NOSIGNAL); } -void cat(int client, FILE *resource) -{ - char buf[1024]; - - fgets(buf, sizeof(buf), resource); - while (!feof(resource)) - { - send(client, buf, strlen(buf), MSG_NOSIGNAL); - fgets(buf, sizeof(buf), resource); - } -} - -void cannot_execute(int client) +void unimplemented(int client) { char buf[1024]; - sprintf(buf, "HTTP/1.0 500 Internal Server Error\r\n"); + sprintf(buf, "HTTP/1.0 501 Method Not Implemented\r\n"); send(client, buf, strlen(buf), MSG_NOSIGNAL); - sprintf(buf, "Content-type: text/html\r\n"); + sprintf(buf, SERVER_STRING); + send(client, buf, strlen(buf), MSG_NOSIGNAL); + sprintf(buf, "Content-Type: text/html\r\n"); send(client, buf, strlen(buf), MSG_NOSIGNAL); sprintf(buf, "\r\n"); send(client, buf, strlen(buf), MSG_NOSIGNAL); - sprintf(buf, "

Error prohibited CGI execution.\r\n"); + sprintf(buf, "Method Not Implemented\r\n"); + send(client, buf, strlen(buf), MSG_NOSIGNAL); + sprintf(buf, "\r\n"); + send(client, buf, strlen(buf), MSG_NOSIGNAL); + sprintf(buf, "

HTTP request method not supported.\r\n"); + send(client, buf, strlen(buf), MSG_NOSIGNAL); + sprintf(buf, "\r\n"); send(client, buf, strlen(buf), MSG_NOSIGNAL); } @@ -156,25 +116,63 @@ int save_log_file(char *filename, char *buf, int len) { char path[255] = {0}; sprintf(path, "%s%s", log_dir_path, filename); - FILE *fp = fopen(path, "a"); + FILE *fp = fopen(path, "ab"); if (fp == NULL) { - HTTPD_LOG_ERROR("open log file %s failed.", path); + HTTPD_LOG_ERROR("open log file %s failed, %d, %s.", path, errno, strerror(errno)); return -1; } if (fwrite(buf, 1, len, fp) != len) { - HTTPD_LOG_ERROR("write log file %s failed.", path); + HTTPD_LOG_ERROR("write log file %s failed, %d, %s.", path, errno, strerror(errno)); return -1; } if (fclose(fp) != 0) { - HTTPD_LOG_ERROR("close log file %s failed.", path); + HTTPD_LOG_ERROR("close log file %s failed, %d, %s.", path, errno, strerror(errno)); return -1; } return 0; } +int get_line(int sock, char *buf, int size) +{ + int i = 0; + char c = '\0'; + int n; + + while ((i < size - 1) && (c != '\n')) + { + n = recv(sock, &c, 1, 0); + if (n > 0) + { + if (c == '\r') + { + n = recv(sock, &c, 1, MSG_PEEK); + if ((n > 0) && (c == '\n')) + recv(sock, &c, 1, 0); + else + c = '\n'; + } + buf[i] = c; + i++; + } + else + c = '\n'; + } + buf[i] = '\0'; + + return (i); +} + +void call_post_process_done_cb(int ret, const char *filename, int datalen) +{ + if (post_process_done_callback != NULL) + { + post_process_done_callback(ret, filename, datalen); + } +} + void post_process(int client, const char *path, const char *method, const char *query_string) { char buf[1024]; @@ -214,9 +212,12 @@ void post_process(int client, const char *path, const char *method, const char * buf[13] = tmp_char; numchars = get_line(client, buf, sizeof(buf)); } + if (content_length == -1 || boundary[0] == '\0') { + HTTPD_LOG_ERROR("bad http post request."); bad_request(client); + call_post_process_done_cb(-1, NULL, -1); return; } @@ -224,6 +225,8 @@ void post_process(int client, const char *path, const char *method, const char * if (tmp_buf == NULL) { HTTPD_LOG_ERROR("malloc buffer failed."); + cannot_execute(client); + call_post_process_done_cb(-1, NULL, -1); return; } memset(tmp_buf, 0, 4096 * 1024); @@ -234,7 +237,9 @@ void post_process(int client, const char *path, const char *method, const char * if (n < 0) { HTTPD_LOG_ERROR("recv data failed."); + cannot_execute(client); free(tmp_buf); + call_post_process_done_cb(-1, NULL, -1); return; } total += n; @@ -248,7 +253,9 @@ void post_process(int client, const char *path, const char *method, const char * if (tmp == NULL) { HTTPD_LOG_ERROR("log filename not found."); + bad_request(client); free(tmp_buf); + call_post_process_done_cb(-1, NULL, -1); return; } @@ -262,34 +269,38 @@ void post_process(int client, const char *path, const char *method, const char * tmp = strstr(tmp_buf, "\r\n\r\n"); if (tmp == NULL) { - HTTPD_LOG_ERROR("log file data start flag failed."); + HTTPD_LOG_ERROR("log file data start flag not found."); + bad_request(client); free(tmp_buf); + call_post_process_done_cb(-1, filename, -1); return; } data_start = &tmp[4]; + // todo support bin file char boundary_end[2048] = {0}; sprintf(boundary_end, "--%s--", boundary); - char *data_end; - data_end = strstr(tmp_buf, boundary_end); - int data_len; - if (data_end == NULL) + int boundary_end_len = strlen(boundary_end); + int boundary_end_index = content_length - boundary_end_len - 2; + + if (strstr(&tmp_buf[boundary_end_index], boundary_end) == NULL) { - HTTPD_LOG_ERROR("log file data end flag failed."); + HTTPD_LOG_ERROR("log file data end flag not found."); + bad_request(client); free(tmp_buf); + call_post_process_done_cb(-1, filename, -1); return; } - data_len = data_end - data_start - 2; - HTTPD_LOG_INFO("recv log file datalen: %d.", data_len); - int ret = save_log_file(filename, data_start, data_len); + response_ok(client); - if (post_process_done_callback != NULL) - { - post_process_done_callback(ret, filename, data_len); - } + int data_len = &tmp_buf[boundary_end_index] - data_start - 2; + HTTPD_LOG_INFO("recv log file datalen: %d.", data_len); + int ret = save_log_file(filename, data_start, data_len); free(tmp_buf); + + call_post_process_done_cb(ret, filename, data_len); } void get_process(int client, const char *path, const char *method, const char *query_string) @@ -303,83 +314,101 @@ void get_process(int client, const char *path, const char *method, const char *q numchars = get_line(client, buf, sizeof(buf)); // Todo... } + response_ok(client); } -int get_line(int sock, char *buf, int size) +void *accept_request(void *arg) { - int i = 0; - char c = '\0'; - int n; + int client = *(int *)arg; + char buf[1024]; + int numchars; + char method[255]; + char url[255]; + size_t i, j; + char *query_string = NULL; - while ((i < size - 1) && (c != '\n')) + numchars = get_line(client, buf, sizeof(buf)); + i = 0; + j = 0; + + while (!ISspace(buf[j]) && (i < sizeof(method) - 1)) { - n = recv(sock, &c, 1, 0); - if (n > 0) - { - if (c == '\r') - { - n = recv(sock, &c, 1, MSG_PEEK); - if ((n > 0) && (c == '\n')) - recv(sock, &c, 1, 0); - else - c = '\n'; - } - buf[i] = c; - i++; - } - else - c = '\n'; + method[i] = buf[j]; + i++; + j++; } - buf[i] = '\0'; + method[i] = '\0'; - return (i); -} + if (strcasecmp(method, "GET") && strcasecmp(method, "POST")) + { + unimplemented(client); + close(client); + return NULL; + } -void headers(int client, const char *filename) -{ - char buf[1024]; - (void)filename; + i = 0; + while (ISspace(buf[j]) && (j < sizeof(buf))) + j++; + while (!ISspace(buf[j]) && (i < sizeof(url) - 1) && (j < sizeof(buf))) + { - strcpy(buf, "HTTP/1.0 200 OK\r\n"); - send(client, buf, strlen(buf), MSG_NOSIGNAL); + url[i] = buf[j]; + i++; + j++; + } + url[i] = '\0'; - strcpy(buf, SERVER_STRING); - send(client, buf, strlen(buf), MSG_NOSIGNAL); - sprintf(buf, "Content-Type: text/html\r\n"); - send(client, buf, strlen(buf), MSG_NOSIGNAL); - strcpy(buf, "\r\n"); - send(client, buf, strlen(buf), MSG_NOSIGNAL); + if (strcasecmp(method, "GET") == 0) + { + query_string = url; + while ((*query_string != '?') && (*query_string != '\0')) + query_string++; + + if (*query_string == '?') + { + *query_string = '\0'; + query_string++; + } + } + + if (strcasecmp(method, "POST") == 0) + { + post_process(client, url, method, query_string); + } + else + { + get_process(client, url, method, query_string); + } + + close(client); + return NULL; } -void response_ok(int client) +void cat(int client, FILE *resource) { char buf[1024]; - sprintf(buf, "HTTP/1.0 200 OK\r\n"); - send(client, buf, strlen(buf), MSG_NOSIGNAL); + + fgets(buf, sizeof(buf), resource); + while (!feof(resource)) + { + send(client, buf, strlen(buf), MSG_NOSIGNAL); + fgets(buf, sizeof(buf), resource); + } } -void not_found(int client) +void headers(int client, const char *filename) { char buf[1024]; + (void)filename; - sprintf(buf, "HTTP/1.0 404 NOT FOUND\r\n"); + strcpy(buf, "HTTP/1.0 200 OK\r\n"); send(client, buf, strlen(buf), MSG_NOSIGNAL); - sprintf(buf, SERVER_STRING); + strcpy(buf, SERVER_STRING); send(client, buf, strlen(buf), MSG_NOSIGNAL); sprintf(buf, "Content-Type: text/html\r\n"); send(client, buf, strlen(buf), MSG_NOSIGNAL); - sprintf(buf, "\r\n"); - send(client, buf, strlen(buf), MSG_NOSIGNAL); - sprintf(buf, "Not Found\r\n"); - send(client, buf, strlen(buf), MSG_NOSIGNAL); - sprintf(buf, "

The server could not fulfill\r\n"); - send(client, buf, strlen(buf), MSG_NOSIGNAL); - sprintf(buf, "your request because the resource specified\r\n"); - send(client, buf, strlen(buf), MSG_NOSIGNAL); - sprintf(buf, "is unavailable or nonexistent.\r\n"); - send(client, buf, strlen(buf), MSG_NOSIGNAL); - sprintf(buf, "\r\n"); + strcpy(buf, "\r\n"); send(client, buf, strlen(buf), MSG_NOSIGNAL); } @@ -406,28 +435,6 @@ void serve_file(int client, const char *filename) fclose(resource); } -void unimplemented(int client) -{ - char buf[1024]; - - sprintf(buf, "HTTP/1.0 501 Method Not Implemented\r\n"); - send(client, buf, strlen(buf), MSG_NOSIGNAL); - sprintf(buf, SERVER_STRING); - send(client, buf, strlen(buf), MSG_NOSIGNAL); - sprintf(buf, "Content-Type: text/html\r\n"); - send(client, buf, strlen(buf), MSG_NOSIGNAL); - sprintf(buf, "\r\n"); - send(client, buf, strlen(buf), MSG_NOSIGNAL); - sprintf(buf, "Method Not Implemented\r\n"); - send(client, buf, strlen(buf), MSG_NOSIGNAL); - sprintf(buf, "\r\n"); - send(client, buf, strlen(buf), MSG_NOSIGNAL); - sprintf(buf, "

HTTP request method not supported.\r\n"); - send(client, buf, strlen(buf), MSG_NOSIGNAL); - sprintf(buf, "\r\n"); - send(client, buf, strlen(buf), MSG_NOSIGNAL); -} - int RegisterPostProcessDoneCallback(PostProcessDoneCallback callback) { post_process_done_callback = callback; diff --git a/test.c b/test.c index f32a540..79589f8 100644 --- a/test.c +++ b/test.c @@ -10,11 +10,14 @@ void ProcessDoneCallback(int code, const char *filename, int datalen) int main() { + struct PrintLogFuncSet set = {printf, printf}; int ret; ret = RegisterPostProcessDoneCallback(ProcessDoneCallback); printf("RegisterPostProcessDoneCallback ret=%d\n", ret); - ret = SetLogSavePath("/home/tongkang/"); + ret = SetLogSavePath("/home/admin/"); printf("SetLogSavePath ret=%d\n", ret); + ret = RegisterLogFunc(set); + printf("RegisterLogFunc ret=%d\n", ret); ret = StartHttpServerSync(9999); return 0; } \ No newline at end of file -- Gitee