libmicrohttpd

HTTP/1.x server C library (MHD 1.x, stable)
Log | Files | Refs | Submodules | README | LICENSE

benchmark_https.c (9753B)


      1 /*
      2      This file is part of libmicrohttpd
      3      Copyright (C) 2007, 2013 Christian Grothoff (and other contributing authors)
      4      Copyright (C) 2014-2022 Evgeny Grin (Karlson2k)
      5 
      6      This library is free software; you can redistribute it and/or
      7      modify it under the terms of the GNU Lesser General Public
      8      License as published by the Free Software Foundation; either
      9      version 2.1 of the License, or (at your option) any later version.
     10 
     11      This library is distributed in the hope that it will be useful,
     12      but WITHOUT ANY WARRANTY; without even the implied warranty of
     13      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     14      Lesser General Public License for more details.
     15 
     16      You should have received a copy of the GNU Lesser General Public
     17      License along with this library; if not, write to the Free Software
     18      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
     19 */
     20 /**
     21  * @file benchmark_https.c
     22  * @brief minimal code to benchmark MHD GET performance with HTTPS
     23  * @author Christian Grothoff
     24  * @author Karlson2k (Evgeny Grin)
     25  */
     26 
     27 #include "platform.h"
     28 #include <microhttpd.h>
     29 
     30 #ifdef HAVE_INTTYPES_H
     31 #include <inttypes.h>
     32 #endif /* HAVE_INTTYPES_H */
     33 #ifndef PRIu64
     34 #define PRIu64  "llu"
     35 #endif /* ! PRIu64 */
     36 
     37 #if defined(MHD_CPU_COUNT) && (MHD_CPU_COUNT + 0) < 2
     38 #undef MHD_CPU_COUNT
     39 #endif
     40 #if ! defined(MHD_CPU_COUNT)
     41 #define MHD_CPU_COUNT 2
     42 #endif
     43 
     44 #define PAGE \
     45   "<html><head><title>libmicrohttpd demo</title></head><body>libmicrohttpd demo</body></html>"
     46 
     47 
     48 #define SMALL (1024 * 128)
     49 
     50 /**
     51  * Number of threads to run in the thread pool.  Should (roughly) match
     52  * the number of cores on your system.
     53  */
     54 #define NUMBER_OF_THREADS MHD_CPU_COUNT
     55 
     56 static unsigned int small_deltas[SMALL];
     57 
     58 static struct MHD_Response *response;
     59 
     60 
     61 /**
     62  * Signature of the callback used by MHD to notify the
     63  * application about completed requests.
     64  *
     65  * @param cls client-defined closure
     66  * @param connection connection handle
     67  * @param req_cls value as set by the last call to
     68  *        the MHD_AccessHandlerCallback
     69  * @param toe reason for request termination
     70  * @see MHD_OPTION_NOTIFY_COMPLETED
     71  */
     72 static void
     73 completed_callback (void *cls,
     74                     struct MHD_Connection *connection,
     75                     void **req_cls,
     76                     enum MHD_RequestTerminationCode toe)
     77 {
     78   struct timeval *tv = *req_cls;
     79   struct timeval tve;
     80   uint64_t delta;
     81   (void) cls;         /* Unused. Silent compiler warning. */
     82   (void) connection;  /* Unused. Silent compiler warning. */
     83   (void) toe;         /* Unused. Silent compiler warning. */
     84 
     85   if (NULL == tv)
     86     return;
     87   gettimeofday (&tve, NULL);
     88 
     89   delta = ((uint64_t) (tve.tv_sec - tv->tv_sec)) * 1000000LL
     90           + (uint64_t) tve.tv_usec - (uint64_t) tv->tv_usec;
     91   if (delta < SMALL)
     92     small_deltas[delta]++;
     93   else
     94     fprintf (stdout, "D: %" PRIu64 " 1\n", delta);
     95   free (tv);
     96 }
     97 
     98 
     99 static void *
    100 uri_logger_cb (void *cls,
    101                const char *uri)
    102 {
    103   struct timeval *tv = malloc (sizeof (struct timeval));
    104   (void) cls; /* Unused. Silent compiler warning. */
    105   (void) uri; /* Unused. Silent compiler warning. */
    106 
    107   if (NULL != tv)
    108     gettimeofday (tv, NULL);
    109   return tv;
    110 }
    111 
    112 
    113 static enum MHD_Result
    114 ahc_echo (void *cls,
    115           struct MHD_Connection *connection,
    116           const char *url,
    117           const char *method,
    118           const char *version,
    119           const char *upload_data, size_t *upload_data_size, void **req_cls)
    120 {
    121   (void) cls;               /* Unused. Silent compiler warning. */
    122   (void) url;               /* Unused. Silent compiler warning. */
    123   (void) version;           /* Unused. Silent compiler warning. */
    124   (void) upload_data;       /* Unused. Silent compiler warning. */
    125   (void) upload_data_size;  /* Unused. Silent compiler warning. */
    126   (void) req_cls;           /* Unused. Silent compiler warning. */
    127 
    128   if (0 != strcmp (method, "GET"))
    129     return MHD_NO;              /* unexpected method */
    130   return MHD_queue_response (connection, MHD_HTTP_OK, response);
    131 }
    132 
    133 
    134 /* test server key */
    135 static const char srv_signed_key_pem[] =
    136   "-----BEGIN PRIVATE KEY-----\n\
    137 MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCff7amw9zNSE+h\n\
    138 rOMhBrzbbsJluUP3gmd8nOKY5MUimoPkxmAXfp2L0il+MPZT/ZEmo11q0k6J2jfG\n\
    139 UBQ+oZW9ahNZ9gCDjbYlBblo/mqTai+LdeLO3qk53d0zrZKXvCO6sA3uKpG2WR+g\n\
    140 +sNKxfYpIHCpanqBU6O+degIV/+WKy3nQ2Fwp7K5HUNj1u0pg0QQ18yf68LTnKFU\n\
    141 HFjZmmaaopWki5wKSBieHivzQy6w+04HSTogHHRK/y/UcoJNSG7xnHmoPPo1vLT8\n\
    142 CMRIYnSSgU3wJ43XBJ80WxrC2dcoZjV2XZz+XdQwCD4ZrC1ihykcAmiQA+sauNm7\n\
    143 dztOMkGzAgMBAAECggEAIbKDzlvXDG/YkxnJqrKXt+yAmak4mNQuNP+YSCEdHSBz\n\
    144 +SOILa6MbnvqVETX5grOXdFp7SWdfjZiTj2g6VKOJkSA7iKxHRoVf2DkOTB3J8np\n\
    145 XZd8YaRdMGKVV1O2guQ20Dxd1RGdU18k9YfFNsj4Jtw5sTFTzHr1P0n9ybV9xCXp\n\
    146 znSxVfRg8U6TcMHoRDJR9EMKQMO4W3OQEmreEPoGt2/+kMuiHjclxLtbwDxKXTLP\n\
    147 pD0gdg3ibvlufk/ccKl/yAglDmd0dfW22oS7NgvRKUve7tzDxY1Q6O5v8BCnLFSW\n\
    148 D+z4hS1PzooYRXRkM0xYudvPkryPyu+1kEpw3fNsoQKBgQDRfXJo82XQvlX8WPdZ\n\
    149 Ts3PfBKKMVu3Wf8J3SYpuvYT816qR3ot6e4Ivv5ZCQkdDwzzBKe2jAv6JddMJIhx\n\
    150 pkGHc0KKOodd9HoBewOd8Td++hapJAGaGblhL5beIidLKjXDjLqtgoHRGlv5Cojo\n\
    151 zHa7Viel1eOPPcBumhp83oJ+mQKBgQDC6PmdETZdrW3QPm7ZXxRzF1vvpC55wmPg\n\
    152 pRfTRM059jzRzAk0QiBgVp3yk2a6Ob3mB2MLfQVDgzGf37h2oO07s5nspSFZTFnM\n\
    153 KgSjFy0xVOAVDLe+0VpbmLp1YUTYvdCNowaoTE7++5rpePUDu3BjAifx07/yaSB+\n\
    154 W+YPOfOuKwKBgQCGK6g5G5qcJSuBIaHZ6yTZvIdLRu2M8vDral5k3793a6m3uWvB\n\
    155 OFAh/eF9ONJDcD5E7zhTLEMHhXDs7YEN+QODMwjs6yuDu27gv97DK5j1lEsrLUpx\n\
    156 XgRjAE3KG2m7NF+WzO1K74khWZaKXHrvTvTEaxudlO3X8h7rN3u7ee9uEQKBgQC2\n\
    157 wI1zeTUZhsiFTlTPWfgppchdHPs6zUqq0wFQ5Zzr8Pa72+zxY+NJkU2NqinTCNsG\n\
    158 ePykQ/gQgk2gUrt595AYv2De40IuoYk9BlTMuql0LNniwsbykwd/BOgnsSlFdEy8\n\
    159 0RQn70zOhgmNSg2qDzDklJvxghLi7zE5aV9//V1/ewKBgFRHHZN1a8q/v8AAOeoB\n\
    160 ROuXfgDDpxNNUKbzLL5MO5odgZGi61PBZlxffrSOqyZoJkzawXycNtoBP47tcVzT\n\
    161 QPq5ZOB3kjHTcN7dRLmPWjji9h4O3eHCX67XaPVMSWiMuNtOZIg2an06+jxGFhLE\n\
    162 qdJNJ1DkyUc9dN2cliX4R+rG\n\
    163 -----END PRIVATE KEY-----";
    164 
    165 /* test server CA signed certificates */
    166 static const char srv_signed_cert_pem[] =
    167   "-----BEGIN CERTIFICATE-----\n\
    168 MIIFSzCCAzOgAwIBAgIBBDANBgkqhkiG9w0BAQsFADCBgTELMAkGA1UEBhMCUlUx\n\
    169 DzANBgNVBAgMBk1vc2NvdzEPMA0GA1UEBwwGTW9zY293MRswGQYDVQQKDBJ0ZXN0\n\
    170 LWxpYm1pY3JvaHR0cGQxITAfBgkqhkiG9w0BCQEWEm5vYm9keUBleGFtcGxlLm9y\n\
    171 ZzEQMA4GA1UEAwwHdGVzdC1DQTAgFw0yMjA0MjAxODQzMDJaGA8yMTIyMDMyNjE4\n\
    172 NDMwMlowZTELMAkGA1UEBhMCUlUxDzANBgNVBAgMBk1vc2NvdzEPMA0GA1UEBwwG\n\
    173 TW9zY293MRswGQYDVQQKDBJ0ZXN0LWxpYm1pY3JvaHR0cGQxFzAVBgNVBAMMDnRl\n\
    174 c3QtbWhkc2VydmVyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAn3+2\n\
    175 psPczUhPoazjIQa8227CZblD94JnfJzimOTFIpqD5MZgF36di9IpfjD2U/2RJqNd\n\
    176 atJOido3xlAUPqGVvWoTWfYAg422JQW5aP5qk2ovi3Xizt6pOd3dM62Sl7wjurAN\n\
    177 7iqRtlkfoPrDSsX2KSBwqWp6gVOjvnXoCFf/list50NhcKeyuR1DY9btKYNEENfM\n\
    178 n+vC05yhVBxY2ZpmmqKVpIucCkgYnh4r80MusPtOB0k6IBx0Sv8v1HKCTUhu8Zx5\n\
    179 qDz6Nby0/AjESGJ0koFN8CeN1wSfNFsawtnXKGY1dl2c/l3UMAg+GawtYocpHAJo\n\
    180 kAPrGrjZu3c7TjJBswIDAQABo4HmMIHjMAsGA1UdDwQEAwIFoDAMBgNVHRMBAf8E\n\
    181 AjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMBMDEGA1UdEQQqMCiCDnRlc3QtbWhk\n\
    182 c2VydmVyhwR/AAABhxAAAAAAAAAAAAAAAAAAAAABMB0GA1UdDgQWBBQ57Z06WJae\n\
    183 8fJIHId4QGx/HsRgDDAoBglghkgBhvhCAQ0EGxYZVGVzdCBsaWJtaWNyb2h0dHBk\n\
    184 IHNlcnZlcjARBglghkgBhvhCAQEEBAMCBkAwHwYDVR0jBBgwFoAUWHVDwKVqMcOF\n\
    185 Nd0arI3/QB3W6SwwDQYJKoZIhvcNAQELBQADggIBAI7Lggm/XzpugV93H5+KV48x\n\
    186 X+Ct8unNmPCSzCaI5hAHGeBBJpvD0KME5oiJ5p2wfCtK5Dt9zzf0S0xYdRKqU8+N\n\
    187 aKIvPoU1hFixXLwTte1qOp6TviGvA9Xn2Fc4n36dLt6e9aiqDnqPbJgBwcVO82ll\n\
    188 HJxVr3WbrAcQTB3irFUMqgAke/Cva9Bw79VZgX4ghb5EnejDzuyup4pHGzV10Myv\n\
    189 hdg+VWZbAxpCe0S4eKmstZC7mWsFCLeoRTf/9Pk1kQ6+azbTuV/9QOBNfFi8QNyb\n\
    190 18jUjmm8sc2HKo8miCGqb2sFqaGD918hfkWmR+fFkzQ3DZQrT+eYbKq2un3k0pMy\n\
    191 UySy8SRn1eadfab+GwBVb68I9TrPRMrJsIzysNXMX4iKYl2fFE/RSNnaHtPw0C8y\n\
    192 B7memyxPRl+H2xg6UjpoKYh3+8e44/XKm0rNIzXjrwA8f8gnw2TbqmMDkj1YqGnC\n\
    193 SCj5A27zUzaf2pT/YsnQXIWOJjVvbEI+YKj34wKWyTrXA093y8YI8T3mal7Kr9YM\n\
    194 WiIyPts0/aVeziM0Gunglz+8Rj1VesL52FTurobqusPgM/AME82+qb/qnxuPaCKj\n\
    195 OT1qAbIblaRuWqCsid8BzP7ZQiAnAWgMRSUg1gzDwSwRhrYQRRWAyn/Qipzec+27\n\
    196 /w0gW9EVWzFhsFeGEssi\n\
    197 -----END CERTIFICATE-----";
    198 
    199 
    200 int
    201 main (int argc, char *const *argv)
    202 {
    203   struct MHD_Daemon *d;
    204   unsigned int i;
    205   int port;
    206 
    207   if (argc != 2)
    208   {
    209     printf ("%s PORT\n", argv[0]);
    210     return 1;
    211   }
    212   port = atoi (argv[1]);
    213   if ( (1 > port) || (port > 65535) )
    214   {
    215     fprintf (stderr,
    216              "Port must be a number between 1 and 65535.\n");
    217     return 1;
    218   }
    219   response = MHD_create_response_from_buffer_static (strlen (PAGE),
    220                                                      (const void *) PAGE);
    221   d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_TLS
    222 #ifdef EPOLL_SUPPORT
    223                         | MHD_USE_EPOLL | MHD_USE_TURBO
    224 #endif
    225                         ,
    226                         (uint16_t) port,
    227                         NULL, NULL, &ahc_echo, NULL,
    228                         MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 120,
    229                         MHD_OPTION_THREAD_POOL_SIZE, (unsigned
    230                                                       int) NUMBER_OF_THREADS,
    231                         MHD_OPTION_URI_LOG_CALLBACK, &uri_logger_cb, NULL,
    232                         MHD_OPTION_NOTIFY_COMPLETED, &completed_callback, NULL,
    233                         MHD_OPTION_CONNECTION_LIMIT, (unsigned int) 1000,
    234                         /* Optionally, the gnutls_load_file() can be used to
    235                            load the key and the certificate from file. */
    236                         MHD_OPTION_HTTPS_MEM_KEY, srv_signed_key_pem,
    237                         MHD_OPTION_HTTPS_MEM_CERT, srv_signed_cert_pem,
    238                         MHD_OPTION_END);
    239   if (d == NULL)
    240     return 1;
    241   (void) getc (stdin);
    242   MHD_stop_daemon (d);
    243   MHD_destroy_response (response);
    244   for (i = 0; i < SMALL; i++)
    245     if (0 != small_deltas[i])
    246       fprintf (stdout, "D: %u %u\n", i, small_deltas[i]);
    247   return 0;
    248 }