Bladeren bron

Add client example

bel2125 3 jaren geleden
bovenliggende
commit
224b5a672c
3 gewijzigde bestanden met toevoegingen van 146 en 0 verwijderingen
  1. 32 0
      examples/client/Makefile
  2. 113 0
      examples/client/client.c
  3. 1 0
      format.bat

+ 32 - 0
examples/client/Makefile

@@ -0,0 +1,32 @@
+#
+# Copyright (c) 2021 CivetWeb Developers
+# License http://opensource.org/licenses/mit-license.php MIT License
+
+TOP = ../..
+
+PROG = client
+SRC = client.c $(TOP)/src/civetweb.c
+
+CFLAGS = -I$(TOP)/include -DOPENSSL_API_1_1 -DCRYPTO_LIB=\"libcrypto.so.1.1\" -DSSL_LIB=\"libssl.so.1.1\" $(COPT)
+LIBS = -lpthread
+
+include $(TOP)/resources/Makefile.in-os
+
+ifeq ($(TARGET_OS),LINUX)
+	LIBS += -ldl
+endif
+
+all: $(PROG)
+
+$(PROG): $(CIVETWEB_LIB) $(SRC)
+	$(CC) -o $@ $(CFLAGS) $(LDFLAGS) $(SRC) $(CIVETWEB_LIB) $(LIBS)
+
+$(CIVETWEB_LIB):
+	$(MAKE) -C $(TOP) WITH_IPV6=1 clean lib
+	cp $(TOP)/$(CIVETWEB_LIB) .
+
+clean:
+	rm -f $(CIVETWEB_LIB) $(PROG)
+
+.PHONY: all clean
+

+ 113 - 0
examples/client/client.c

@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2018 the CivetWeb developers
+ * MIT License
+ */
+
+/* Simple client demo. */
+#ifdef _WIN32
+#include <windows.h>
+#else
+#include <unistd.h>
+#endif
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include "civetweb.h"
+
+
+int
+main(int argc, char *argv[])
+{
+	if (argc < 2) {
+		fprintf(stderr, "Requires server name as argument\n");
+		return EXIT_FAILURE;
+	}
+
+	/* Init libcivetweb. */
+	mg_init_library(MG_FEATURES_TLS);
+
+	if (mg_check_feature(MG_FEATURES_TLS) != MG_FEATURES_TLS) {
+		fprintf(stderr, "TLS is not available\n");
+		return EXIT_FAILURE;
+	}
+
+	/* Connect client */
+	char errbuf[256] = {0};
+	struct mg_client_options opt = {0};
+	opt.host = argv[1];
+	opt.port = 443;
+	struct mg_connection *cli =
+	    mg_connect_client_secure(&opt, errbuf, sizeof(errbuf));
+
+	/* Check return value: */
+	if (cli == NULL) {
+		fprintf(stderr, "Cannot connect client: %s\n", errbuf);
+		return EXIT_FAILURE;
+	}
+
+	printf("cli: %p\n", cli);
+
+	mg_printf(cli, "GET / HTTP/1.1\r\n");
+	mg_printf(cli, "Host: %s\r\n", opt.host);
+	mg_printf(cli, "Connection: close\r\n\r\n");
+
+	int ret = mg_get_response(cli, errbuf, sizeof(errbuf), 10000);
+	if (ret < 0) {
+		fprintf(stderr, "Download failed: %s\n", errbuf);
+		mg_close_connection(cli);
+		return EXIT_FAILURE;
+	}
+
+	const struct mg_response_info *ri = mg_get_response_info(cli);
+	if (ri == NULL) {
+		fprintf(stderr, "mg_response_info failed\n");
+		mg_close_connection(cli);
+		return EXIT_FAILURE;
+	}
+
+	printf("Status: %i %s\n", ri->status_code, ri->status_text);
+	printf("HTTP Version: %s\n", ri->http_version);
+	printf("Content-Length: %lli\n", ri->content_length);
+	printf("Headers:\n");
+	int is_chunked = 0;
+	for (int i = 0; i < ri->num_headers; i++) {
+		printf("  %s: %s\n",
+		       ri->http_headers[i].name,
+		       ri->http_headers[i].value);
+		if (!strcasecmp(ri->http_headers[i].name, "Transfer-Encoding")
+		    && !strcasecmp(ri->http_headers[i].value, "chunked")) {
+			is_chunked = 1;
+		}
+	}
+
+	long long cont = ri->content_length;
+	if (cont > 0) {
+		/* Read regular content */
+		printf("Content:\n");
+		while (cont > 0) {
+			char buf[1024];
+			int ret = mg_read(cli, buf, sizeof(buf));
+			if (ret <= 0) {
+				printf("read error\n");
+				break;
+			}
+			cont -= ret;
+			fwrite(buf, 1, ret, stdout);
+		}
+	} else if (is_chunked) {
+		/* Read chunked content (or content without content length) */
+		char buf[1024];
+		for (;;) {
+			int ret = mg_read(cli, buf, sizeof(buf));
+			if (ret <= 0)
+				break;
+			fwrite(buf, 1, ret, stdout);
+		}
+	}
+
+	mg_close_connection(cli);
+	return EXIT_SUCCESS;
+}

+ 1 - 0
format.bat

@@ -40,6 +40,7 @@ clang-format -i fuzztest/fuzzmain.c
 
 clang-format -i examples/embedded_c/embedded_c.c
 clang-format -i examples/rest/rest.c
+clang-format -i examples/client/client.c
 clang-format -i examples/embed_certificate/ec_example.c
 clang-format -i examples/ws_server/ws_server.c