Преглед изворни кода

Merge branch 'master' into annotate

hewei.it пре 4 година
родитељ
комит
ea25d64df3

+ 1 - 8
CMakeLists.txt

@@ -16,9 +16,6 @@ option(WITH_HTTP "compile http" ON)
 option(WITH_HTTP_SERVER "compile http/server" ON)
 option(WITH_HTTP_CLIENT "compile http/client" ON)
 
-# WITH_CONSUL need WITH_HTTP_CLIENT=ON
-option(WITH_CONSUL "compile consul" OFF)
-
 option(ENABLE_IPV6 "ipv6" OFF)
 option(ENABLE_UDS "Unix Domain Socket" OFF)
 option(ENABLE_WINDUMP "Windows MiniDumpWriteDump" OFF)
@@ -134,7 +131,7 @@ if(ANDROID)
 endif()
 
 # see Makefile
-set(ALL_SRCDIRS . base util event protocol cpputil evpp http http/client http/server consul)
+set(ALL_SRCDIRS . base util event protocol cpputil evpp http http/client http/server)
 set(LIBHV_SRCDIRS . base util event)
 set(LIBHV_HEADERS hv.h hconfig.h hexport.h)
 set(LIBHV_HEADERS ${LIBHV_HEADERS} ${BASE_HEADERS} ${UTIL_HEADERS} ${EVENT_HEADERS})
@@ -157,10 +154,6 @@ if(WITH_EVPP)
         if(WITH_HTTP_CLIENT)
             set(LIBHV_HEADERS ${LIBHV_HEADERS} ${HTTP_CLIENT_HEADERS})
             set(LIBHV_SRCDIRS ${LIBHV_SRCDIRS} http/client)
-            if(WITH_CONSUL)
-                set(LIBHV_HEADERS ${LIBHV_HEADERS} ${CONSUL_HEADERS})
-                set(LIBHV_SRCDIRS ${LIBHV_SRCDIRS} consul)
-            endif()
         endif()
     endif()
 endif()

+ 12 - 13
Makefile

@@ -2,7 +2,7 @@ include config.mk
 include Makefile.vars
 
 MAKEF=$(MAKE) -f Makefile.in
-ALL_SRCDIRS=. base util event protocol cpputil evpp http http/client http/server consul
+ALL_SRCDIRS=. base util event protocol cpputil evpp http http/client http/server
 
 LIBHV_SRCDIRS = . base util event
 LIBHV_HEADERS = hv.h hconfig.h hexport.h
@@ -16,28 +16,28 @@ endif
 ifeq ($(WITH_EVPP), yes)
 LIBHV_HEADERS += $(CPPUTIL_HEADERS) $(EVPP_HEADERS)
 LIBHV_SRCDIRS += cpputil evpp
+
 ifeq ($(WITH_HTTP), yes)
 LIBHV_HEADERS += $(HTTP_HEADERS)
 LIBHV_SRCDIRS += http
+
 ifeq ($(WITH_HTTP_SERVER), yes)
 LIBHV_HEADERS += $(HTTP_SERVER_HEADERS)
 LIBHV_SRCDIRS += http/server
 endif
+
 ifeq ($(WITH_HTTP_CLIENT), yes)
 LIBHV_HEADERS += $(HTTP_CLIENT_HEADERS)
 LIBHV_SRCDIRS += http/client
-ifeq ($(WITH_CONSUL), yes)
-LIBHV_HEADERS += $(CONSUL_HEADERS)
-LIBHV_SRCDIRS += consul
-endif
 endif
+
 endif
 endif
 
 default: all
 all: libhv examples
 examples: hmain_test htimer_test hloop_test \
-	nc nmap httpd curl wget \
+	nc nmap httpd curl wget consul\
 	tcp_echo_server \
 	tcp_chat_server \
 	tcp_proxy_server \
@@ -46,11 +46,10 @@ examples: hmain_test htimer_test hloop_test \
 	http_server_test http_client_test \
 	websocket_server_test \
 	websocket_client_test \
-	consul_cli
 
 clean:
-	$(MAKEF) clean SRCDIRS="$(ALL_SRCDIRS)"
-	$(RM) examples/*.o examples/httpd/*.o examples/nmap/*.o
+	$(MAKEF) clean SRCDIRS="$(ALL_SRCDIRS) examples/nmap examples/httpd examples/consul"
+	${RM} examples/*.o
 	$(RM) include/hv
 
 prepare:
@@ -96,12 +95,15 @@ nc: prepare
 	$(MAKEF) TARGET=$@ SRCDIRS=". base event" SRCS="examples/nc.c"
 
 nmap: prepare
-	$(MAKEF) TARGET=$@ SRCDIRS=". base event cpputil examples/nmap" SRCS="examples/nmap/nmap_test.cpp" DEFINES="PRINT_DEBUG"
+	$(MAKEF) TARGET=$@ SRCDIRS=". base event cpputil examples/nmap" DEFINES="PRINT_DEBUG"
 
 httpd: prepare
 	$(RM) examples/httpd/*.o
 	$(MAKEF) TARGET=$@ SRCDIRS=". base event util cpputil evpp http http/client http/server examples/httpd"
 
+consul: prepare
+	$(MAKEF) TARGET=$@ SRCDIRS=". base event util cpputil evpp http http/client examples/consul" DEFINES="PRINT_DEBUG"
+
 curl: prepare
 	$(MAKEF) TARGET=$@ SRCDIRS=". base event util cpputil evpp http http/client" SRCS="examples/curl.cpp"
 	# $(MAKEF) TARGET=$@ SRCDIRS=". base event util cpputil evpp http http/client" SRCS="examples/curl.cpp" WITH_CURL=yes
@@ -121,9 +123,6 @@ websocket_server_test: prepare
 websocket_client_test: prepare
 	$(MAKEF) TARGET=$@ SRCDIRS=". base event util cpputil evpp http http/client" SRCS="examples/websocket_client_test.cpp"
 
-consul_cli: prepare
-	$(MAKEF) TARGET=$@ SRCDIRS=". base event util cpputil evpp http http/client consul" SRCS="examples/consul_cli.cpp" DEFINES="PRINT_DEBUG"
-
 unittest: prepare
 	$(CC)  -g -Wall -O0 -std=c99   -I. -Ibase            -o bin/mkdir_p           unittest/mkdir_test.c         base/hbase.c
 	$(CC)  -g -Wall -O0 -std=c99   -I. -Ibase            -o bin/rmdir_p           unittest/rmdir_test.c         base/hbase.c

+ 0 - 2
Makefile.vars

@@ -83,5 +83,3 @@ HTTP_SERVER_HEADERS =   http/server/HttpService.h\
 						http/server/HttpServer.h\
 						http/server/HttpResponseWriter.h\
 						http/server/WebSocketServer.h\
-
-CONSUL_HEADERS = consul/consul.h

+ 8 - 1
README-CN.md

@@ -173,7 +173,6 @@ wrk -c 100 -t 4 -d 10s http://127.0.0.1:8080/
 - TCP代理服务:  [examples/tcp_proxy_server.c](examples/tcp_proxy_server.c)
 - UDP回显服务:  [examples/udp_echo_server.c](examples/udp_echo_server.c)
 - UDP代理服务:  [examples/udp_proxy_server.c](examples/udp_proxy_server.c)
-- TCP/UDP客户端: [examples/nc.c](examples/nc.c)
 
 ### c++版本
 - 事件循环: [evpp/EventLoop_test.cpp](evpp/EventLoop_test.cpp)
@@ -188,6 +187,14 @@ wrk -c 100 -t 4 -d 10s http://127.0.0.1:8080/
 - WebSocket服务端: [examples/websocket_server_test.cpp](examples/websocket_server_test.cpp)
 - WebSocket客户端: [examples/websocket_client_test.cpp](examples/websocket_client_test.cpp)
 
+### 模拟实现著名的命令行工具
+- 网络连接工具: [examples/nc](examples/nc.c)
+- 网络扫描工具: [examples/nmap](examples/nmap)
+- HTTP服务程序: [examples/httpd](examples/httpd)
+- URL请求工具: [examples/curl](examples/curl.cpp)
+- 文件下载工具: [examples/wget](examples/wget.cpp)
+- 服务注册与发现: [examples/consul](examples/consul)
+
 ## 🥇 性能测试
 ```shell
 cd echo-servers

+ 8 - 1
README.md

@@ -170,7 +170,6 @@ wrk -c 100 -t 4 -d 10s http://127.0.0.1:8080/
 - [examples/tcp_proxy_server.c](examples/tcp_proxy_server.c)
 - [examples/udp_echo_server.c](examples/udp_echo_server.c)
 - [examples/udp_proxy_server.c](examples/udp_proxy_server.c)
-- [examples/nc.c](examples/nc.c)
 
 ### c++ version
 - [evpp/EventLoop_test.cpp](evpp/EventLoop_test.cpp)
@@ -185,6 +184,14 @@ wrk -c 100 -t 4 -d 10s http://127.0.0.1:8080/
 - [examples/websocket_server_test.cpp](examples/websocket_server_test.cpp)
 - [examples/websocket_client_test.cpp](examples/websocket_client_test.cpp)
 
+### simulate well-known command line tools
+- [examples/nc](examples/nc.c)
+- [examples/nmap](examples/nmap)
+- [examples/httpd](examples/httpd)
+- [examples/curl](examples/curl.cpp)
+- [examples/wget](examples/wget.cpp)
+- [examples/consul](examples/consul)
+
 ## 🥇 Benchmark
 ```shell
 cd echo-servers

+ 0 - 1
TREE.md

@@ -7,7 +7,6 @@
 ├── build       cmake默认构建目录
 ├── cert        SSL证书存放目录
 ├── cmake       cmake脚本存放目录
-├── consul      consul服务注册与发现,使用http客户端实现
 ├── cpputil     libhv工具类,如命令行解析、json解析、ini解析
 ├── docs        文档存放目录
 ├── echo-servers 包含libevent、libev、libuv、libhv、asio、poco、muduo等多个网络库的tcp echo server写法,并做压力测试

+ 0 - 2
cmake/vars.cmake

@@ -93,5 +93,3 @@ set(HTTP_SERVER_HEADERS
     http/server/HttpResponseWriter.h
     http/server/WebSocketServer.h
 )
-
-set(CONSUL_HEADERS consul/consul.h)

+ 0 - 3
config.ini

@@ -14,9 +14,6 @@ WITH_HTTP=yes
 WITH_HTTP_SERVER=yes
 WITH_HTTP_CLIENT=yes
 
-# WITH_CONSUL need WITH_HTTP_CLIENT=yes
-WITH_CONSUL=no
-
 # features
 # base/hsocket.c: replace gethostbyname with getaddrinfo
 ENABLE_IPV6=no

+ 1 - 2
config.mk

@@ -7,7 +7,6 @@ WITH_EVPP=yes
 WITH_HTTP=yes
 WITH_HTTP_SERVER=yes
 WITH_HTTP_CLIENT=yes
-WITH_CONSUL=no
 ENABLE_IPV6=no
 ENABLE_UDS=no
 ENABLE_WINDUMP=no
@@ -16,4 +15,4 @@ WITH_CURL=no
 WITH_NGHTTP2=no
 WITH_OPENSSL=no
 WITH_MBEDTLS=no
-CONFIG_DATE=20210430
+CONFIG_DATE=20210430

+ 0 - 1
configure

@@ -23,7 +23,6 @@ modules:
   --with-http           compile http module?            (DEFAULT: $WITH_HTTP)
   --with-http-client    compile http client module?     (DEFAULT: $WITH_HTTP_CLIENT)
   --with-http-server    compile http server module?     (DEFAULT: $WITH_HTTP_SERVER)
-  --with-consul         compile consul module? default: (DEFAULT: $WITH_CONSUL)
 
 features:
   --enable-ipv6         enable IPv6?                    (DEFAULT: $ENABLE_IPV6)

+ 1 - 0
evpp/EventLoop.h

@@ -75,6 +75,7 @@ public:
 
     // Timer interfaces: setTimer, killTimer, resetTimer
     TimerID setTimer(int timeout_ms, TimerCallback cb, int repeat = INFINITE) {
+        if (loop_ == NULL) return INVALID_TIMER_ID;
         htimer_t* htimer = htimer_add(loop_, onTimer, timeout_ms, repeat);
 
         Timer timer(htimer, cb, repeat);

+ 1 - 0
evpp/TcpClient.h

@@ -149,6 +149,7 @@ public:
         loop_thread.start(wait_threads_started, std::bind(&TcpClientTmpl::startConnect, this));
     }
     void stop(bool wait_threads_stopped = true) {
+        enable_reconnect = false;
         loop_thread.stop(wait_threads_stopped);
     }
 

+ 15 - 19
examples/CMakeLists.txt

@@ -42,7 +42,7 @@ if(WITH_EVPP)
 
     aux_source_directory(nmap NMAP_SRCS)
     add_executable(nmap ${NMAP_SRCS})
-    target_compile_definitions(nmap PRIVATE -DPRINT_DEBUG)
+    target_compile_definitions(nmap PRIVATE PRINT_DEBUG)
     target_link_libraries(nmap hv)
 
     list(APPEND EXAMPLES hmain_test nmap)
@@ -80,6 +80,12 @@ if(WITH_HTTP_CLIENT)
     add_executable(wget wget.cpp)
     target_link_libraries(wget hv)
 
+    # consul
+    aux_source_directory(consul CONSUL_SRCS)
+    add_executable(consul ${CONSUL_SRCS})
+    target_compile_definitions(consul PRIVATE PRINT_DEBUG)
+    target_link_libraries(consul hv)
+
     # http_client_test
     add_executable(http_client_test http_client_test.cpp)
     target_link_libraries(http_client_test hv)
@@ -88,25 +94,15 @@ if(WITH_HTTP_CLIENT)
     add_executable(websocket_client_test websocket_client_test.cpp)
     target_link_libraries(websocket_client_test hv)
 
-    list(APPEND EXAMPLES ${CURL_TARGET_NAME} wget http_client_test websocket_client_test)
-endif()
-
-if(WITH_CONSUL)
-    include_directories(../consul)
-
-    add_executable(consul_cli consul_cli.cpp)
-    target_compile_definitions(consul_cli PRIVATE PRINT_DEBUG)
-    target_link_libraries(consul_cli hv)
+    list(APPEND EXAMPLES ${CURL_TARGET_NAME} wget consul http_client_test websocket_client_test)
 
-    list(APPEND EXAMPLES consul_cli)
-endif()
-
-if(WITH_HTTP_SERVER)
-    # httpd
-    aux_source_directory(httpd HTTPD_SRCS)
-    add_executable(httpd ${HTTPD_SRCS})
-    target_link_libraries(httpd hv)
-    list(APPEND EXAMPLES httpd)
+    if(WITH_HTTP_SERVER)
+        # httpd
+        aux_source_directory(httpd HTTPD_SRCS)
+        add_executable(httpd ${HTTPD_SRCS})
+        target_link_libraries(httpd hv)
+        list(APPEND EXAMPLES httpd)
+    endif()
 endif()
 
 endif()

+ 16 - 47
consul/consul.cpp → examples/consul/consul.cpp

@@ -5,9 +5,6 @@
 #include "json.hpp"
 using json = nlohmann::json;
 
-#include "hstring.h"
-#include "herr.h"
-
 #define PROTOCOL    "http://"
 #define API_VERSION "v1"
 
@@ -16,9 +13,7 @@ static const char url_deregister[] = "/agent/service/deregister";
 static const char url_discover[] = "/catalog/service";
 
 static string make_url(const char* ip, int port, const char* url) {
-    return asprintf(PROTOCOL "%s:%d/" API_VERSION "%s",
-            ip, port,
-            url);
+    return asprintf(PROTOCOL "%s:%d/" API_VERSION "%s", ip, port, url);
 }
 
 static string make_ServiceID(consul_service_t* service) {
@@ -60,7 +55,7 @@ int register_service(consul_node_t* node, consul_service_t* service, consul_heal
 
     json jservice;
     jservice["Name"] = service->name;
-    if (strlen(service->ip) != 0) {
+    if (*service->ip) {
         jservice["Address"] = service->ip;
     }
     jservice["Port"] = service->port;
@@ -114,55 +109,29 @@ int discover_services(consul_node_t* node, const char* service_name, std::vector
     HttpResponse res;
     printd("GET %s\n", req.url.c_str());
     int ret = http_client_send(&req, &res);
-    if (ret != 0) {
-        return ret;
-    }
+    if (ret != 0) return ret;
     printd("%s\n", res.body.c_str());
 
-    json jroot = json::parse(res.body.c_str(), NULL, false);
-    if (!jroot.is_array()) {
-        return ERR_INVALID_JSON;
-    }
-    if (jroot.size() == 0) {
-        return 0;
-    }
+    json jroot = json::parse(res.body);
+    if (!jroot.is_array()) return -1;
+    if (jroot.size() == 0) return 0;
 
     consul_service_t service;
+    std::string name, ip;
     services.clear();
     for (size_t i = 0; i < jroot.size(); ++i) {
         auto jservice = jroot[i];
-        if (!jservice.is_object()) {
+        name = jservice["ServiceName"];
+        if (jservice.contains("Address")) {
+            ip = jservice["Address"];
+        } else if (jservice.contains("ServiceAddress")) {
+            ip = jservice["ServiceAddress"];
+        } else if (jservice.contains("ServiceAddress6")) {
+            ip = jservice["ServiceAddress6"];
+        } else {
             continue;
         }
-        auto jname = jservice["ServiceName"];
-        if (!jname.is_string()) {
-            continue;
-        }
-        auto jport = jservice["ServicePort"];
-        if (!jport.is_number_integer()) {
-            continue;
-        }
-
-        string ip;
-        auto jip = jservice["Address"];
-        if (jip.is_string()) {
-            ip = jip;
-        }
-        if (ip.empty()) {
-            jip = jservice["ServiceAddress"];
-            if (jip.is_string()) {
-                ip = jip;
-            }
-        }
-        if (ip.empty()) {
-            jip = jservice["ServiceAddress6"];
-            if (jip.is_string()) {
-                ip = jip;
-            }
-        }
-
-        string name = jname;
-        int    port = jport;
+        int port = jservice["ServicePort"];
 
         strncpy(service.name, name.c_str(), sizeof(service.name));
         strncpy(service.ip, ip.c_str(), sizeof(service.ip));

+ 6 - 7
consul/consul.h → examples/consul/consul.h

@@ -4,8 +4,6 @@
 #include <vector>
 #include <string.h>
 
-#include "hexport.h"
-
 typedef struct consul_node_s {
     // node
     char ip[64];
@@ -24,8 +22,9 @@ typedef struct consul_service_s {
     int  port;
 
     consul_service_s() {
-        memset(this, 0, sizeof(consul_service_s));
+        name[0] = '\0';
         strcpy(ip, "127.0.0.1");
+        port = 0;
     }
 } consul_service_t;
 
@@ -39,16 +38,16 @@ typedef struct consul_health_s {
     int timeout;  // ms
 
     consul_health_s() {
-        memset(this, 0, sizeof(consul_health_s));
         strcpy(protocol, "TCP");
+        url[0] = '\0';
         strcpy(status, "passing");
         interval = 10000;
         timeout = 3000;
     }
 } consul_health_t;
 
-HV_EXPORT int register_service(consul_node_t* node, consul_service_t* service, consul_health_t* health);
-HV_EXPORT int deregister_service(consul_node_t* node, consul_service_t* service);
-HV_EXPORT int discover_services(consul_node_t* node, const char* service_name, std::vector<consul_service_t>& services);
+int register_service(consul_node_t* node, consul_service_t* service, consul_health_t* health);
+int deregister_service(consul_node_t* node, consul_service_t* service);
+int discover_services(consul_node_t* node, const char* service_name, std::vector<consul_service_t>& services);
 
 #endif // CONSUL_H_

+ 0 - 0
examples/consul_cli.cpp → examples/consul/main.cpp


+ 16 - 3
examples/hmain_test.cpp

@@ -2,6 +2,19 @@
 #include "hmain.h"
 #include "iniparser.h"
 
+/*
+ * @build: make examples
+ * @usage: bin/hmain_test -h
+ *         bin/hmain_test -v
+ *
+ *         bin/hmain_test -c etc/hmain_test.conf -d
+ *         ps aux | grep hmain_test
+ *
+ *         bin/hmain_test -s stop
+ *         ps aux | grep hmain_test
+ *
+ */
+
 typedef struct conf_ctx_s {
     IniParser* parser;
     int loglevel;
@@ -215,15 +228,15 @@ int main(int argc, char** argv) {
     // pidfile
     create_pidfile();
 
-    master_workers_run(worker_fn, (void*)(intptr_t)100L, g_conf_ctx.worker_processes, g_conf_ctx.worker_threads);
+    master_workers_run(worker_fn, (void*)(intptr_t)g_conf_ctx.port, g_conf_ctx.worker_processes, g_conf_ctx.worker_threads);
 
     return 0;
 }
 
 void worker_fn(void* userdata) {
-    long num = (long)(intptr_t)(userdata);
+    long port = (long)(intptr_t)(userdata);
     while (1) {
-        printf("num=%ld pid=%ld tid=%ld\n", num, hv_getpid(), hv_gettid());
+        printf("port=%ld pid=%ld tid=%ld\n", port, hv_getpid(), hv_gettid());
         hv_delay(60000);
     }
 }

+ 0 - 0
examples/nmap/nmap_test.cpp → examples/nmap/main.cpp


+ 9 - 8
examples/wget.cpp

@@ -9,6 +9,7 @@
 int main(int argc, char** argv) {
     if (argc < 2) {
         printf("Usage: %s url\n", argv[0]);
+        return -10;
     }
     const char* url = argv[1];
 
@@ -19,25 +20,25 @@ int main(int argc, char** argv) {
     } else {
         filepath = path + 1;
     }
-    printf("save file to %s ...\n", filepath.c_str());
+    printf("Save file to %s ...\n", filepath.c_str());
 
     HFile file;
     if (file.open(filepath.c_str(), "wb") != 0) {
         fprintf(stderr, "Failed to open file %s\n", filepath.c_str());
-        return -10;
+        return -20;
     }
 
     // HEAD
     requests::Request req(new HttpRequest);
     req->url = url;
     req->method = HTTP_HEAD;
-    printf("%s\n", req->Dump(true, true).c_str());
+    printd("%s", req->Dump(true, true).c_str());
     auto resp = requests::request(req);
     if (resp == NULL) {
         fprintf(stderr, "request failed!\n");
         return -1;
     }
-    printf("%s\n", resp->Dump(true, false).c_str());
+    printd("%s", resp->Dump(true, false).c_str());
 
     bool use_range = false;
     int range_bytes = 1 << 20; // 1M
@@ -53,13 +54,13 @@ int main(int argc, char** argv) {
     // GET
     req->method = HTTP_GET;
     if (!use_range) {
-        printf("%s\n", req->Dump(true, true).c_str());
+        printd("%s", req->Dump(true, true).c_str());
         resp = requests::get(url);
         if (resp == NULL) {
             fprintf(stderr, "request failed!\n");
             return -1;
         }
-        printf("%s\n", resp->Dump(true, false).c_str());
+        printd("%s", resp->Dump(true, false).c_str());
         file.write(resp->body.data(), resp->body.size());
         return 0;
     }
@@ -73,13 +74,13 @@ int main(int argc, char** argv) {
         if (to >= content_length) to = content_length - 1;
         // Range: bytes=from-to
         req->SetRange(from, to);
-        printf("%s\n", req->Dump(true, true).c_str());
+        printd("%s", req->Dump(true, true).c_str());
         int ret = http_client_send(cli, req.get(), resp.get());
         if (ret != 0) {
             fprintf(stderr, "request failed!\n");
             return -1;
         }
-        printf("%s\n", resp->Dump(true, false).c_str());
+        printd("%s", resp->Dump(true, false).c_str());
         file.write(resp->body.data(), resp->body.size());
         from = to + 1;
     }

+ 17 - 0
hexport.h

@@ -165,4 +165,21 @@ struct s
 #define END_NAMESPACE_HV    END_NAMESPACE(hv)
 #define USING_NAMESPACE_HV  USING_NAMESPACE(hv)
 
+// MSVC ports
+#ifdef _MSC_VER
+#if _MSC_VER < 1900 // < VS2015
+
+#ifndef __cplusplus
+#ifndef inline
+#define inline __inline
+#endif
+#endif
+
+#ifndef snprintf
+#define snprintf _snprintf
+#endif
+
+#endif
+#endif
+
 #endif // HV_EXPORT_H_

+ 1 - 0
unittest/sendmail_test.c

@@ -5,6 +5,7 @@
 int main(int argc, char** argv) {
     if (argc < 8) {
         printf("Usage: sendmail smtp_server username password from to subject body\n");
+        return -10;
     }
 
     const char* smtp_server = argv[1];