diff --git a/BUILD.gn b/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..b5884cb54e5a9a91e279b727298820ae0c77f736 --- /dev/null +++ b/BUILD.gn @@ -0,0 +1,53 @@ +#Copyright (c) 2019-2024 Huawei Device Co., Ltd. +#Licensed under the Apache License, Version 2.0 (the "License"); +#you may not use this file except in compliance with the License. +#You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +#Unless required by applicable law or agreed to in writing, software +#distributed under the License is distributed on an "AS IS" BASIS, +#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +#See the License for the specific language governing permissions and +#limitations under the License. + +if (defined(ohos_lite)) { + +} else { + import("//build/ohos.gni") + ohos_shared_library("simplehttpd") { + include_dirs = [ + "include", + ] + + sources = [ + "src/simplehttpd.c", + ] + + cflags = [ + "-Wall", + "-fPIC", + ] + + deps = [] + + part_name = "simplehttpd" + subsystem_name = "thirdparty" + } + + ohos_executable("simplehttpd_test") { + include_dirs = [ + "include", + ] + + sources = [ + "src/simplehttpd.c", + "example.c", + ] + + deps = [] + + part_name = "simplehttpd" + subsystem_name = "thirdparty" + } +} diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000000000000000000000000000000000000..6777dde6dc9ec636cb302d35a91ec097de1bfb46 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,3 @@ +1.0 (May 9, 2024) +===== +This is the first official versioned release of simplehttpd. Have fun! diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md new file mode 100644 index 0000000000000000000000000000000000000000..ccd16546d94cc7fa1eff94857e43c73f460c7af2 --- /dev/null +++ b/CONTRIBUTORS.md @@ -0,0 +1,9 @@ +Contributors +============ + +Author and Maintainer: +- [Innocent Kumamoto](https://gitee.com/innocent-kumamoto) +- [uoengopen](https://gitee.com/uoengopen) +- [null_628_5802](https://gitee.com/null_628_5802) + +Also thanks to all the people who reported bugs and suggested new features. diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..e421df65c1db245a5386067ea666f6d41de1ca75 --- /dev/null +++ b/LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2024 simplehttpd contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + diff --git a/README.OpenSource b/README.OpenSource new file mode 100644 index 0000000000000000000000000000000000000000..a15a2e74d59769473cc895b6388e57e03e4ea036 --- /dev/null +++ b/README.OpenSource @@ -0,0 +1,12 @@ +[ + { + "Name": "simplehttpd", + "License": "MIT License", + "License File": "LICENSE", + "Version Number": "1.0", + "Owner": "innocent-kumamoto@gitee.com", + "Upstream URL": "https://gitee.com/mhbase/third_party_simplehttpd", + "Description": "Ultra lightweight http server." + } +] + diff --git a/bundle.json b/bundle.json new file mode 100644 index 0000000000000000000000000000000000000000..20bac144ae58a8633de2e41a6b26ecebfb561fb3 --- /dev/null +++ b/bundle.json @@ -0,0 +1,30 @@ +{ + "name": "@ohos/simplehttpd", + "description": "Third-party open-source software simplehttpd | Ultra lightweight http server.", + "version": "1.0", + "license": " MIT License", + "publishAs": "code-segment", + "segment": { + "destPath": "third_party/simplehttpd" + }, + "dirs": {}, + "scripts": {}, + "component": { + "name": "simplehttpd", + "subsystem": "thirdparty", + "syscap": [], + "features": [], + "adapted_system_type": [ "mini", "small", "standard" ], + "rom": "", + "ram": "", + "deps": { + "components": [], + "third_party": [] + }, + "build": { + "sub_component": [], + "inner_kits": [], + "test": [] + } + } +} diff --git a/test.c b/example.c similarity index 100% rename from test.c rename to example.c diff --git a/simplehttpd.h b/include/simplehttpd.h similarity index 100% rename from simplehttpd.h rename to include/simplehttpd.h diff --git a/simplehttpd.c b/src/simplehttpd.c similarity index 80% rename from simplehttpd.c rename to src/simplehttpd.c index a5470b2c13d68ad41c3e3bea63ffba9db0f364db..d4b943da2ee39efca3a678214655457d50bc66ff 100644 --- a/simplehttpd.c +++ b/src/simplehttpd.c @@ -20,6 +20,7 @@ #define ISspace(x) isspace((int)(x)) #define SERVER_STRING "Server: simplehttpd/0.0.1\r\n" #define HTTP_DATA_RECV_TIMEOUT 15 +#define MAX_BUFFER_SIZE 1024 typedef void (*PostProcessDoneCallback)(PostProcessRetCode, const char *, int); static PostProcessDoneCallback post_process_done_callback = NULL; @@ -28,18 +29,18 @@ typedef int (*PrintLog)(const char *, ...); static PrintLog HTTPD_LOG_INFO = printf; static PrintLog HTTPD_LOG_ERROR = printf; -static char log_dir_path[128] = {0}; +static char log_dir_path[MAX_BUFFER_SIZE] = {0}; void response_ok(int client) { - char buf[1024]; + char buf[MAX_BUFFER_SIZE]; sprintf(buf, "HTTP/1.0 200 OK\r\n"); send(client, buf, strlen(buf), MSG_NOSIGNAL); } void not_found(int client) { - char buf[1024]; + char buf[MAX_BUFFER_SIZE]; sprintf(buf, "HTTP/1.0 404 NOT FOUND\r\n"); send(client, buf, strlen(buf), MSG_NOSIGNAL); @@ -64,7 +65,7 @@ void not_found(int client) void cannot_execute(int client) { - char buf[1024]; + char buf[MAX_BUFFER_SIZE]; sprintf(buf, "HTTP/1.0 500 Internal Server Error\r\n"); send(client, buf, strlen(buf), MSG_NOSIGNAL); @@ -78,7 +79,7 @@ void cannot_execute(int client) void bad_request(int client) { - char buf[1024]; + char buf[MAX_BUFFER_SIZE]; sprintf(buf, "HTTP/1.0 400 BAD REQUEST\r\n"); send(client, buf, sizeof(buf), MSG_NOSIGNAL); @@ -94,7 +95,7 @@ void bad_request(int client) void unimplemented(int client) { - char buf[1024]; + char buf[MAX_BUFFER_SIZE]; sprintf(buf, "HTTP/1.0 501 Method Not Implemented\r\n"); send(client, buf, strlen(buf), MSG_NOSIGNAL); @@ -114,9 +115,9 @@ void unimplemented(int client) send(client, buf, strlen(buf), MSG_NOSIGNAL); } -int save_log_file(char *filename, char *buf, int len) +int save_log_file(char *filename, char *buf, unsigned int len) { - char path[255] = {0}; + char path[2 * MAX_BUFFER_SIZE] = {0}; sprintf(path, "%s%s", log_dir_path, filename); FILE *fp = fopen(path, "ab"); if (fp == NULL) @@ -177,9 +178,9 @@ void call_post_process_done_cb(PostProcessRetCode code, const char *filename, in void post_process(int client, const char *path, const char *method, const char *query_string) { - char buf[1024]; - char boundary[1024] = {0}; - char filename[1024] = {0}; + char buf[MAX_BUFFER_SIZE]; + char boundary[MAX_BUFFER_SIZE] = {0}; + char filename[MAX_BUFFER_SIZE] = {0}; char *tmp; int i; int numchars = 1; @@ -204,7 +205,7 @@ void post_process(int client, const char *path, const char *method, const char * tmp = strstr(&buf[14], "boundary="); if (tmp != NULL) { - for (i = 0; i < 1023 && tmp[i + 9] != '\n'; i++) + for (i = 0; i < MAX_BUFFER_SIZE - 1 && tmp[i + 9] != '\n'; i++) { boundary[i] = tmp[i + 9]; } @@ -260,7 +261,7 @@ void post_process(int client, const char *path, const char *method, const char * return; } - for (i = 0; i < 1023 && tmp[i + 10] != '\"'; i++) + for (i = 0; i < MAX_BUFFER_SIZE - 1 && tmp[i + 10] != '\"'; i++) { filename[i] = tmp[i + 10]; } @@ -278,8 +279,7 @@ void post_process(int client, const char *path, const char *method, const char * } data_start = &tmp[4]; - // todo support bin file - char boundary_end[2048] = {0}; + char boundary_end[2 * MAX_BUFFER_SIZE] = {0}; sprintf(boundary_end, "--%s--", boundary); int boundary_end_len = strlen(boundary_end); int boundary_end_index = content_length - boundary_end_len - 2; @@ -295,7 +295,7 @@ void post_process(int client, const char *path, const char *method, const char * response_ok(client); - int data_len = &tmp_buf[boundary_end_index] - data_start - 2; + unsigned 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); @@ -310,27 +310,13 @@ void post_process(int client, const char *path, const char *method, const char * } } -void get_process(int client, const char *path, const char *method, const char *query_string) -{ - char buf[1024]; - int numchars = 1; - buf[0] = 'A'; - buf[1] = '\0'; - while ((numchars > 0) && strcmp("\n", buf)) - { - numchars = get_line(client, buf, sizeof(buf)); - // Todo... - } - response_ok(client); -} - void *accept_request(void *arg) { int client = *(int *)arg; - char buf[1024]; + char buf[MAX_BUFFER_SIZE]; int numchars; - char method[255]; - char url[255]; + char method[MAX_BUFFER_SIZE]; + char url[MAX_BUFFER_SIZE]; size_t i, j; char *query_string = NULL; @@ -346,7 +332,7 @@ void *accept_request(void *arg) } method[i] = '\0'; - if (strcasecmp(method, "GET") && strcasecmp(method, "POST")) + if (strcasecmp(method, "POST")) { unimplemented(client); close(client); @@ -364,84 +350,13 @@ void *accept_request(void *arg) j++; } url[i] = '\0'; - - 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); - } + + post_process(client, url, method, query_string); close(client); return NULL; } -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 headers(int client, const char *filename) -{ - char buf[1024]; - (void)filename; - - strcpy(buf, "HTTP/1.0 200 OK\r\n"); - send(client, buf, strlen(buf), MSG_NOSIGNAL); - - 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); -} - -void serve_file(int client, const char *filename) -{ - FILE *resource = NULL; - int numchars = 1; - char buf[1024]; - - buf[0] = 'A'; - buf[1] = '\0'; - while ((numchars > 0) && strcmp("\n", buf)) - numchars = get_line(client, buf, sizeof(buf)); - - resource = fopen(filename, "r"); - if (resource == NULL) - not_found(client); - else - { - headers(client, filename); - - cat(client, resource); - } - fclose(resource); -} - int RegisterPostProcessDoneCallback(PostProcessDoneCallback callback) { post_process_done_callback = callback; @@ -461,7 +376,7 @@ int RegisterLogFunc(struct PrintLogFuncSet funcSet) int SetLogSavePath(const char *path) { - if (strlen(path) >= 128) + if (strlen(path) > MAX_BUFFER_SIZE - 1) { HTTPD_LOG_ERROR("log save path is too long."); return -1; @@ -475,7 +390,7 @@ int StartHttpServerSync(const char *ip, uint16_t port) int server_sock = -1; int client_sock = -1; struct sockaddr_in client_name; - int client_name_len = sizeof(client_name); + socklen_t client_name_len = sizeof(client_name); pthread_t newthread; struct sockaddr_in name; @@ -508,7 +423,7 @@ int StartHttpServerSync(const char *ip, uint16_t port) } if (port == 0) { - int namelen = sizeof(name); + socklen_t namelen = sizeof(name); if (getsockname(server_sock, (struct sockaddr *)&name, &namelen) == -1) { HTTPD_LOG_ERROR("getsockname failed."); @@ -531,7 +446,10 @@ int StartHttpServerSync(const char *ip, uint16_t port) client_sock = accept(server_sock, (struct sockaddr *)&client_name, &client_name_len); if (client_sock == -1) { - HTTPD_LOG_ERROR("accept failed, %d, %s.", errno, strerror(errno)); + if (errno != EAGAIN) + { + HTTPD_LOG_ERROR("accept failed, %d, %s.", errno, strerror(errno)); + } continue; }