Home | History | Annotate | Download | only in examples
      1 /*
      2      This file is part of libmicrohttpd
      3      Copyright (C) 2007, 2013 Christian Grothoff (and other contributing authors)
      4 
      5      This library is free software; you can redistribute it and/or
      6      modify it under the terms of the GNU Lesser General Public
      7      License as published by the Free Software Foundation; either
      8      version 2.1 of the License, or (at your option) any later version.
      9 
     10      This library is distributed in the hope that it will be useful,
     11      but WITHOUT ANY WARRANTY; without even the implied warranty of
     12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     13      Lesser General Public License for more details.
     14 
     15      You should have received a copy of the GNU Lesser General Public
     16      License along with this library; if not, write to the Free Software
     17      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
     18 */
     19 /**
     20  * @file benchmark_https.c
     21  * @brief minimal code to benchmark MHD GET performance with HTTPS
     22  * @author Christian Grothoff
     23  */
     24 
     25 #include "platform.h"
     26 #include <microhttpd.h>
     27 
     28 #if defined(CPU_COUNT) && (CPU_COUNT+0) < 2
     29 #undef CPU_COUNT
     30 #endif
     31 #if !defined(CPU_COUNT)
     32 #define CPU_COUNT 2
     33 #endif
     34 
     35 #define PAGE "<html><head><title>libmicrohttpd demo</title></head><body>libmicrohttpd demo</body></html>"
     36 
     37 
     38 #define SMALL (1024 * 128)
     39 
     40 /**
     41  * Number of threads to run in the thread pool.  Should (roughly) match
     42  * the number of cores on your system.
     43  */
     44 #define NUMBER_OF_THREADS CPU_COUNT
     45 
     46 static unsigned int small_deltas[SMALL];
     47 
     48 static struct MHD_Response *response;
     49 
     50 
     51 
     52 /**
     53  * Signature of the callback used by MHD to notify the
     54  * application about completed requests.
     55  *
     56  * @param cls client-defined closure
     57  * @param connection connection handle
     58  * @param con_cls value as set by the last call to
     59  *        the MHD_AccessHandlerCallback
     60  * @param toe reason for request termination
     61  * @see MHD_OPTION_NOTIFY_COMPLETED
     62  */
     63 static void
     64 completed_callback (void *cls,
     65 		    struct MHD_Connection *connection,
     66 		    void **con_cls,
     67 		    enum MHD_RequestTerminationCode toe)
     68 {
     69   struct timeval *tv = *con_cls;
     70   struct timeval tve;
     71   uint64_t delta;
     72 
     73   if (NULL == tv)
     74     return;
     75   gettimeofday (&tve, NULL);
     76 
     77   delta = 0;
     78   if (tve.tv_usec >= tv->tv_usec)
     79     delta += (tve.tv_sec - tv->tv_sec) * 1000000LL
     80       + (tve.tv_usec - tv->tv_usec);
     81   else
     82     delta += (tve.tv_sec - tv->tv_sec) * 1000000LL
     83       - tv->tv_usec + tve.tv_usec;
     84   if (delta < SMALL)
     85     small_deltas[delta]++;
     86   else
     87     fprintf (stdout, "D: %llu 1\n", (unsigned long long) delta);
     88   free (tv);
     89 }
     90 
     91 
     92 static void *
     93 uri_logger_cb (void *cls,
     94 	       const char *uri)
     95 {
     96   struct timeval *tv = malloc (sizeof (struct timeval));
     97 
     98   if (NULL != tv)
     99     gettimeofday (tv, NULL);
    100   return tv;
    101 }
    102 
    103 
    104 static int
    105 ahc_echo (void *cls,
    106           struct MHD_Connection *connection,
    107           const char *url,
    108           const char *method,
    109           const char *version,
    110           const char *upload_data, size_t *upload_data_size, void **ptr)
    111 {
    112   if (0 != strcmp (method, "GET"))
    113     return MHD_NO;              /* unexpected method */
    114   return MHD_queue_response (connection, MHD_HTTP_OK, response);
    115 }
    116 
    117 
    118 /* test server key */
    119 const char srv_signed_key_pem[] = "-----BEGIN RSA PRIVATE KEY-----\n"
    120   "MIIEowIBAAKCAQEAvfTdv+3fgvVTKRnP/HVNG81cr8TrUP/iiyuve/THMzvFXhCW\n"
    121   "+K03KwEku55QvnUndwBfU/ROzLlv+5hotgiDRNFT3HxurmhouySBrJNJv7qWp8IL\n"
    122   "q4sw32vo0fbMu5BZF49bUXK9L3kW2PdhTtSQPWHEzNrCxO+YgCilKHkY3vQNfdJ0\n"
    123   "20Q5EAAEseD1YtWCIpRvJzYlZMpjYB1ubTl24kwrgOKUJYKqM4jmF4DVQp4oOK/6\n"
    124   "QYGGh1QmHRPAy3CBII6sbb+sZT9cAqU6GYQVB35lm4XAgibXV6KgmpVxVQQ69U6x\n"
    125   "yoOl204xuekZOaG9RUPId74Rtmwfi1TLbBzo2wIDAQABAoIBADu09WSICNq5cMe4\n"
    126   "+NKCLlgAT1NiQpLls1gKRbDhKiHU9j8QWNvWWkJWrCya4QdUfLCfeddCMeiQmv3K\n"
    127   "lJMvDs+5OjJSHFoOsGiuW2Ias7IjnIojaJalfBml6frhJ84G27IXmdz6gzOiTIer\n"
    128   "DjeAgcwBaKH5WwIay2TxIaScl7AwHBauQkrLcyb4hTmZuQh6ArVIN6+pzoVuORXM\n"
    129   "bpeNWl2l/HSN3VtUN6aCAKbN/X3o0GavCCMn5Fa85uJFsab4ss/uP+2PusU71+zP\n"
    130   "sBm6p/2IbGvF5k3VPDA7X5YX61sukRjRBihY8xSnNYx1UcoOsX6AiPnbhifD8+xQ\n"
    131   "Tlf8oJUCgYEA0BTfzqNpr9Wxw5/QXaSdw7S/0eP5a0C/nwURvmfSzuTD4equzbEN\n"
    132   "d+dI/s2JMxrdj/I4uoAfUXRGaabevQIjFzC9uyE3LaOyR2zhuvAzX+vVcs6bSXeU\n"
    133   "pKpCAcN+3Z3evMaX2f+z/nfSUAl2i4J2R+/LQAWJW4KwRky/m+cxpfUCgYEA6bN1\n"
    134   "b73bMgM8wpNt6+fcmS+5n0iZihygQ2U2DEud8nZJL4Nrm1dwTnfZfJBnkGj6+0Q0\n"
    135   "cOwj2KS0/wcEdJBP0jucU4v60VMhp75AQeHqidIde0bTViSRo3HWKXHBIFGYoU3T\n"
    136   "LyPyKndbqsOObnsFXHn56Nwhr2HLf6nw4taGQY8CgYBoSW36FLCNbd6QGvLFXBGt\n"
    137   "2lMhEM8az/K58kJ4WXSwOLtr6MD/WjNT2tkcy0puEJLm6BFCd6A6pLn9jaKou/92\n"
    138   "SfltZjJPb3GUlp9zn5tAAeSSi7YMViBrfuFiHObij5LorefBXISLjuYbMwL03MgH\n"
    139   "Ocl2JtA2ywMp2KFXs8GQWQKBgFyIVv5ogQrbZ0pvj31xr9HjqK6d01VxIi+tOmpB\n"
    140   "4ocnOLEcaxX12BzprW55ytfOCVpF1jHD/imAhb3YrHXu0fwe6DXYXfZV4SSG2vB7\n"
    141   "IB9z14KBN5qLHjNGFpMQXHSMek+b/ftTU0ZnPh9uEM5D3YqRLVd7GcdUhHvG8P8Q\n"
    142   "C9aXAoGBAJtID6h8wOGMP0XYX5YYnhlC7dOLfk8UYrzlp3xhqVkzKthTQTj6wx9R\n"
    143   "GtC4k7U1ki8oJsfcIlBNXd768fqDVWjYju5rzShMpo8OCTS6ipAblKjCxPPVhIpv\n"
    144   "tWPlbSn1qj6wylstJ5/3Z+ZW5H4wIKp5jmLiioDhcP0L/Ex3Zx8O\n"
    145   "-----END RSA PRIVATE KEY-----\n";
    146 
    147 /* test server CA signed certificates */
    148 const char srv_signed_cert_pem[] = "-----BEGIN CERTIFICATE-----\n"
    149   "MIIDGzCCAgWgAwIBAgIES0KCvTALBgkqhkiG9w0BAQUwFzEVMBMGA1UEAxMMdGVz\n"
    150   "dF9jYV9jZXJ0MB4XDTEwMDEwNTAwMDcyNVoXDTQ1MDMxMjAwMDcyNVowFzEVMBMG\n"
    151   "A1UEAxMMdGVzdF9jYV9jZXJ0MIIBHzALBgkqhkiG9w0BAQEDggEOADCCAQkCggEA\n"
    152   "vfTdv+3fgvVTKRnP/HVNG81cr8TrUP/iiyuve/THMzvFXhCW+K03KwEku55QvnUn\n"
    153   "dwBfU/ROzLlv+5hotgiDRNFT3HxurmhouySBrJNJv7qWp8ILq4sw32vo0fbMu5BZ\n"
    154   "F49bUXK9L3kW2PdhTtSQPWHEzNrCxO+YgCilKHkY3vQNfdJ020Q5EAAEseD1YtWC\n"
    155   "IpRvJzYlZMpjYB1ubTl24kwrgOKUJYKqM4jmF4DVQp4oOK/6QYGGh1QmHRPAy3CB\n"
    156   "II6sbb+sZT9cAqU6GYQVB35lm4XAgibXV6KgmpVxVQQ69U6xyoOl204xuekZOaG9\n"
    157   "RUPId74Rtmwfi1TLbBzo2wIDAQABo3YwdDAMBgNVHRMBAf8EAjAAMBMGA1UdJQQM\n"
    158   "MAoGCCsGAQUFBwMBMA8GA1UdDwEB/wQFAwMHIAAwHQYDVR0OBBYEFOFi4ilKOP1d\n"
    159   "XHlWCMwmVKr7mgy8MB8GA1UdIwQYMBaAFP2olB4s2T/xuoQ5pT2RKojFwZo2MAsG\n"
    160   "CSqGSIb3DQEBBQOCAQEAHVWPxazupbOkG7Did+dY9z2z6RjTzYvurTtEKQgzM2Vz\n"
    161   "GQBA+3pZ3c5mS97fPIs9hZXfnQeelMeZ2XP1a+9vp35bJjZBBhVH+pqxjCgiUflg\n"
    162   "A3Zqy0XwwVCgQLE2HyaU3DLUD/aeIFK5gJaOSdNTXZLv43K8kl4cqDbMeRpVTbkt\n"
    163   "YmG4AyEOYRNKGTqMEJXJoxD5E3rBUNrVI/XyTjYrulxbNPcMWEHKNeeqWpKDYTFo\n"
    164   "Bb01PCthGXiq/4A2RLAFosadzRa8SBpoSjPPfZ0b2w4MJpReHqKbR5+T2t6hzml6\n"
    165   "4ToyOKPDmamiTuN5KzLN3cw7DQlvWMvqSOChPLnA3Q==\n"
    166   "-----END CERTIFICATE-----\n";
    167 
    168 
    169 int
    170 main (int argc, char *const *argv)
    171 {
    172   struct MHD_Daemon *d;
    173   unsigned int i;
    174 
    175   if (argc != 2)
    176     {
    177       printf ("%s PORT\n", argv[0]);
    178       return 1;
    179     }
    180   response = MHD_create_response_from_buffer (strlen (PAGE),
    181 					      (void *) PAGE,
    182 					      MHD_RESPMEM_PERSISTENT);
    183   d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_SSL
    184 #if EPOLL_SUPPORT
    185 			| MHD_USE_EPOLL_LINUX_ONLY  | MHD_USE_EPOLL_TURBO
    186 #endif
    187 			,
    188                         atoi (argv[1]),
    189                         NULL, NULL, &ahc_echo, NULL,
    190 			MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 120,
    191 			MHD_OPTION_THREAD_POOL_SIZE, (unsigned int) NUMBER_OF_THREADS,
    192 			MHD_OPTION_URI_LOG_CALLBACK, &uri_logger_cb, NULL,
    193 			MHD_OPTION_NOTIFY_COMPLETED, &completed_callback, NULL,
    194 			MHD_OPTION_CONNECTION_LIMIT, (unsigned int) 1000,
    195                         MHD_OPTION_HTTPS_MEM_KEY, srv_signed_key_pem,
    196                         MHD_OPTION_HTTPS_MEM_CERT, srv_signed_cert_pem,
    197 			MHD_OPTION_END);
    198   if (d == NULL)
    199     return 1;
    200   (void) getc (stdin);
    201   MHD_stop_daemon (d);
    202   MHD_destroy_response (response);
    203   for (i=0;i<SMALL;i++)
    204     if (0 != small_deltas[i])
    205       fprintf (stdout, "D: %d %u\n", i, small_deltas[i]);
    206   return 0;
    207 }
    208