123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 |
- /*
- * 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;
- }
|