benchmark_https.c 9.5 KB

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