client.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. /*
  2. client.c - Load tester using threads to issue multiple HTTP requests.
  3. This sample demonstrates retrieving content using the HTTP GET method with threads.
  4. Copyright (c) All Rights Reserved. See copyright notice at the bottom of the file.
  5. */
  6. /***************************** Includes *******************************/
  7. #include "appweb.h"
  8. /*
  9. Please change this to a local URL to test against
  10. */
  11. #define TEST_URL "http://example.com/index.html"
  12. #define TEST_THREADS 1
  13. #define TEST_ITERATIONS 1
  14. #define TEST_METHOD "POST"
  15. #define TEST_DATA "Hello Post"
  16. static int threadCount = 0;
  17. /******************************** Forwards ****************************/
  18. static int request(HttpStream *stream);
  19. static void threadMain(void *data, MprThread *thread);
  20. /********************************* Code *******************************/
  21. MAIN(simpleClient, int argc, char **argv, char **envp)
  22. {
  23. MprThread *tp;
  24. int i;
  25. /*
  26. Create the Multithreaded Portable Runtime and start it.
  27. Initialize the HTTP subsystem for client requests
  28. */
  29. mprCreate(argc, argv, MPR_USER_EVENTS_THREAD);
  30. httpCreate(HTTP_CLIENT_SIDE);
  31. /*
  32. Enable if you would like logging and request tracing
  33. mprStartLogging("stdout:6", 0);
  34. httpStartTracing("stdout:6");
  35. */
  36. mprStart();
  37. /*
  38. Create and start the threads. Each thread will issue one http request.
  39. */
  40. for (i = 0; i < TEST_THREADS; i++) {
  41. tp = mprCreateThread("test-thread", threadMain, NULL, 0);
  42. mprStartThread(tp);
  43. }
  44. /*
  45. Service requests until instructed to exit by the call to mprShutdown
  46. */
  47. mprServiceEvents(-1, 0);
  48. mprDestroy();
  49. return 0;
  50. }
  51. /*
  52. Main program for each thread
  53. */
  54. static void threadMain(void *data, MprThread *thread)
  55. {
  56. MprDispatcher *dispatcher;
  57. HttpNet *net;
  58. HttpStream *stream;
  59. int i;
  60. if ((dispatcher = mprCreateDispatcher("httpRequest", 0)) == 0) {
  61. mprError("Cannot create dispatcher");
  62. return;
  63. }
  64. mprStartDispatcher(dispatcher);
  65. /*
  66. Create a network object for the network connection for this thread.
  67. */
  68. if ((net = httpCreateNet(dispatcher, NULL, 1, 0)) == 0) {
  69. mprError("Cannot create net");
  70. mprDestroyDispatcher(dispatcher);
  71. return;
  72. }
  73. if ((stream = httpCreateStream(net, 0)) == 0) {
  74. mprError("Cannot create stream");
  75. return;
  76. }
  77. for (i = 0; i < TEST_ITERATIONS; i++) {
  78. if (request(stream) < 0) {
  79. mprError("Can't get URL");
  80. return;
  81. }
  82. }
  83. httpDestroyStream(stream);
  84. httpDestroyNet(net);
  85. mprDestroyDispatcher(dispatcher);
  86. /*
  87. All threads run in parallel, so need a mutex here so threadCount will be accurate.
  88. */
  89. mprGlobalLock();
  90. if (--threadCount <= 0) {
  91. mprShutdown(MPR_EXIT_NORMAL, 0, 0);
  92. }
  93. mprGlobalUnlock();
  94. }
  95. /*
  96. Issue a test request on a thread
  97. */
  98. static int request(HttpStream *stream)
  99. {
  100. cchar *data;
  101. ssize len;
  102. /*
  103. Connect and issue the request. Then finalize the request output - this forces the request out.
  104. */
  105. if (httpConnect(stream, TEST_METHOD, TEST_URL, NULL) < 0) {
  106. mprError("Cannot connect to %s", TEST_URL);
  107. return MPR_ERR_CANT_CONNECT;
  108. }
  109. data = TEST_DATA;
  110. if (data) {
  111. len = slen(data);
  112. if (httpWriteBlock(stream->writeq, data, len, HTTP_BLOCK) != len) {
  113. mprError("Cannot write request body data");
  114. return MPR_ERR_CANT_WRITE;
  115. }
  116. }
  117. httpFinalizeOutput(stream);
  118. if (httpWait(stream, HTTP_STATE_CONTENT, MPR_MAX_TIMEOUT) < 0) {
  119. mprError("No response");
  120. return MPR_ERR_BAD_STATE;
  121. }
  122. if (httpGetStatus(stream) != 200) {
  123. mprError("Server responded with status %d\n", httpGetStatus(stream));
  124. return MPR_ERR_BAD_STATE;
  125. }
  126. mprPrintf("%s\n", httpReadString(conn));
  127. return 0;
  128. }
  129. /*
  130. Copyright (c) Embedthis Software. All Rights Reserved.
  131. This software is distributed under commercial and open source licenses.
  132. You may use the Embedthis Open Source license or you may acquire a
  133. commercial license from Embedthis Software. You agree to be fully bound
  134. by the terms of either license. Consult the LICENSE.md distributed with
  135. this software for full details and other copyrights.
  136. */