diff options
author | Christian Grothoff <christian@grothoff.org> | 2007-12-06 05:26:14 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2007-12-06 05:26:14 +0000 |
commit | 44bbd99901f6c70c8c4e498380de738cc5ada34d (patch) | |
tree | 02b5c3a5c2c6ce8af36f5d27e621bcea3ab1b384 | |
parent | 0826971bfb9887de4d29394470b3da5407a1b741 (diff) | |
download | libmicrohttpd-44bbd99901f6c70c8c4e498380de738cc5ada34d.tar.gz libmicrohttpd-44bbd99901f6c70c8c4e498380de738cc5ada34d.zip |
fixing 1296 and other bugs
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | configure.ac | 4 | ||||
-rw-r--r-- | src/daemon/Makefile.am | 18 | ||||
-rw-r--r-- | src/daemon/connection.c | 46 | ||||
-rw-r--r-- | src/daemon/daemon.c | 17 | ||||
-rw-r--r-- | src/daemon/daemontest_post_loop.c | 79 |
6 files changed, 124 insertions, 46 deletions
@@ -1,3 +1,9 @@ | |||
1 | Wed Dec 5 21:39:35 MST 2007 | ||
2 | Fixed race in multi-threaded server mode. | ||
3 | Fixed handling of POST data when receiving a | ||
4 | "Connection: close" header (#1296). | ||
5 | Releasing libmicrohttpd 0.1.2. - CG | ||
6 | |||
1 | Sat Nov 17 00:55:24 MST 2007 | 7 | Sat Nov 17 00:55:24 MST 2007 |
2 | Fixed off-by-one in error message string matching. | 8 | Fixed off-by-one in error message string matching. |
3 | Added code to avoid generating SIGPIPE on platforms | 9 | Added code to avoid generating SIGPIPE on platforms |
diff --git a/configure.ac b/configure.ac index f7110260..adc1e3ca 100644 --- a/configure.ac +++ b/configure.ac | |||
@@ -21,8 +21,8 @@ | |||
21 | # | 21 | # |
22 | # | 22 | # |
23 | AC_PREREQ(2.57) | 23 | AC_PREREQ(2.57) |
24 | AC_INIT([libmicrohttpd], [0.1.1],[libmicrohttpd@gnunet.org]) | 24 | AC_INIT([libmicrohttpd], [0.1.2],[libmicrohttpd@gnunet.org]) |
25 | AM_INIT_AUTOMAKE([libmicrohttpd], [0.1.1]) | 25 | AM_INIT_AUTOMAKE([libmicrohttpd], [0.1.2]) |
26 | AM_CONFIG_HEADER([config.h]) | 26 | AM_CONFIG_HEADER([config.h]) |
27 | 27 | ||
28 | AH_TOP([#define _GNU_SOURCE 1]) | 28 | AH_TOP([#define _GNU_SOURCE 1]) |
diff --git a/src/daemon/Makefile.am b/src/daemon/Makefile.am index b35b45d7..3ac9f312 100644 --- a/src/daemon/Makefile.am +++ b/src/daemon/Makefile.am | |||
@@ -3,7 +3,7 @@ SUBDIRS = . | |||
3 | INCLUDES = -I$(top_srcdir)/src/include | 3 | INCLUDES = -I$(top_srcdir)/src/include |
4 | 4 | ||
5 | if HAVE_GNU_LD | 5 | if HAVE_GNU_LD |
6 | retaincommand=-Wl,--retain-symbols-file -Wl,SYMBOLS | 6 | retaincommand=-Wl,--retain-symbols-file -Wl,$(srcdir)/SYMBOLS |
7 | endif | 7 | endif |
8 | 8 | ||
9 | EXTRA_DIST = SYMBOLS | 9 | EXTRA_DIST = SYMBOLS |
@@ -12,7 +12,7 @@ lib_LTLIBRARIES = \ | |||
12 | libmicrohttpd.la | 12 | libmicrohttpd.la |
13 | 13 | ||
14 | libmicrohttpd_la_LDFLAGS = \ | 14 | libmicrohttpd_la_LDFLAGS = \ |
15 | -export-dynamic -version-info 2:0:0 $(retaincommand) | 15 | -export-dynamic -version-info 2:1:1 $(retaincommand) |
16 | libmicrohttpd_la_SOURCES = \ | 16 | libmicrohttpd_la_SOURCES = \ |
17 | connection.c connection.h \ | 17 | connection.c connection.h \ |
18 | reason_phrase.c reason_phrase.h \ | 18 | reason_phrase.c reason_phrase.h \ |
@@ -46,11 +46,13 @@ check_PROGRAMS = \ | |||
46 | daemontest_get \ | 46 | daemontest_get \ |
47 | daemontest_post \ | 47 | daemontest_post \ |
48 | daemontest_postform \ | 48 | daemontest_postform \ |
49 | daemontest_post_loop \ | ||
49 | daemontest_put \ | 50 | daemontest_put \ |
50 | daemontest_large_put \ | 51 | daemontest_large_put \ |
51 | daemontest_get11 \ | 52 | daemontest_get11 \ |
52 | daemontest_post11 \ | 53 | daemontest_post11 \ |
53 | daemontest_postform11 \ | 54 | daemontest_postform11 \ |
55 | daemontest_post_loop11 \ | ||
54 | daemontest_put11 \ | 56 | daemontest_put11 \ |
55 | daemontest_large_put11 \ | 57 | daemontest_large_put11 \ |
56 | daemontest_long_header | 58 | daemontest_long_header |
@@ -80,6 +82,12 @@ daemontest_postform_LDADD = \ | |||
80 | $(top_builddir)/src/daemon/libmicrohttpd.la \ | 82 | $(top_builddir)/src/daemon/libmicrohttpd.la \ |
81 | @LIBCURL@ | 83 | @LIBCURL@ |
82 | 84 | ||
85 | daemontest_post_loop_SOURCES = \ | ||
86 | daemontest_post_loop.c | ||
87 | daemontest_post_loop_LDADD = \ | ||
88 | $(top_builddir)/src/daemon/libmicrohttpd.la \ | ||
89 | @LIBCURL@ | ||
90 | |||
83 | daemontest_put_SOURCES = \ | 91 | daemontest_put_SOURCES = \ |
84 | daemontest_put.c | 92 | daemontest_put.c |
85 | daemontest_put_LDADD = \ | 93 | daemontest_put_LDADD = \ |
@@ -104,6 +112,12 @@ daemontest_postform11_LDADD = \ | |||
104 | $(top_builddir)/src/daemon/libmicrohttpd.la \ | 112 | $(top_builddir)/src/daemon/libmicrohttpd.la \ |
105 | @LIBCURL@ | 113 | @LIBCURL@ |
106 | 114 | ||
115 | daemontest_post_loop11_SOURCES = \ | ||
116 | daemontest_post_loop.c | ||
117 | daemontest_post_loop11_LDADD = \ | ||
118 | $(top_builddir)/src/daemon/libmicrohttpd.la \ | ||
119 | @LIBCURL@ | ||
120 | |||
107 | daemontest_put11_SOURCES = \ | 121 | daemontest_put11_SOURCES = \ |
108 | daemontest_put.c | 122 | daemontest_put.c |
109 | daemontest_put11_LDADD = \ | 123 | daemontest_put11_LDADD = \ |
diff --git a/src/daemon/connection.c b/src/daemon/connection.c index 8217932e..39e00dd7 100644 --- a/src/daemon/connection.c +++ b/src/daemon/connection.c | |||
@@ -66,13 +66,12 @@ | |||
66 | * Add extra debug messages with reasons for closing connections | 66 | * Add extra debug messages with reasons for closing connections |
67 | * (non-error reasons). | 67 | * (non-error reasons). |
68 | */ | 68 | */ |
69 | #define DEBUG_CLOSE 0 | 69 | #define DEBUG_CLOSE MHD_NO |
70 | |||
71 | 70 | ||
72 | /** | 71 | /** |
73 | * Should all data send be printed to stderr? | 72 | * Should all data send be printed to stderr? |
74 | */ | 73 | */ |
75 | #define DEBUG_SEND_DATA 0 | 74 | #define DEBUG_SEND_DATA MHD_NO |
76 | 75 | ||
77 | 76 | ||
78 | /** | 77 | /** |
@@ -604,11 +603,11 @@ MHD_parse_connection_headers (struct MHD_Connection *connection) | |||
604 | char *colon; | 603 | char *colon; |
605 | char *tmp; | 604 | char *tmp; |
606 | const char *clen; | 605 | const char *clen; |
607 | const char *end; | ||
608 | unsigned long long cval; | 606 | unsigned long long cval; |
609 | struct MHD_Response *response; | 607 | struct MHD_Response *response; |
610 | 608 | ||
611 | if (connection->bodyReceived == MHD_YES) | 609 | if ( (connection->bodyReceived == MHD_YES) || |
610 | (connection->headersReceived == MHD_YES) ) | ||
612 | abort (); | 611 | abort (); |
613 | colon = NULL; /* make gcc happy */ | 612 | colon = NULL; /* make gcc happy */ |
614 | last = NULL; | 613 | last = NULL; |
@@ -691,17 +690,6 @@ MHD_parse_connection_headers (struct MHD_Connection *connection) | |||
691 | connection->bodyReceived = MHD_NO; | 690 | connection->bodyReceived = MHD_NO; |
692 | } | 691 | } |
693 | } | 692 | } |
694 | end = MHD_lookup_connection_value (connection, | ||
695 | MHD_HEADER_KIND, | ||
696 | MHD_HTTP_HEADER_CONNECTION); | ||
697 | if ((end != NULL) && (0 == strcasecmp (end, "close"))) | ||
698 | { | ||
699 | /* other side explicitly requested | ||
700 | that we close the connection after | ||
701 | this request */ | ||
702 | connection->read_close = MHD_YES; | ||
703 | } | ||
704 | |||
705 | if ((0 != (MHD_USE_PEDANTIC_CHECKS & connection->daemon->options)) | 693 | if ((0 != (MHD_USE_PEDANTIC_CHECKS & connection->daemon->options)) |
706 | && (NULL != connection->version) | 694 | && (NULL != connection->version) |
707 | && (0 == strcasecmp (MHD_HTTP_VERSION_1_1, connection->version)) | 695 | && (0 == strcasecmp (MHD_HTTP_VERSION_1_1, connection->version)) |
@@ -724,7 +712,6 @@ MHD_parse_connection_headers (struct MHD_Connection *connection) | |||
724 | MHD_queue_response (connection, MHD_HTTP_BAD_REQUEST, response); | 712 | MHD_queue_response (connection, MHD_HTTP_BAD_REQUEST, response); |
725 | MHD_destroy_response (response); | 713 | MHD_destroy_response (response); |
726 | } | 714 | } |
727 | |||
728 | break; | 715 | break; |
729 | } | 716 | } |
730 | /* line should be normal header line, find colon */ | 717 | /* line should be normal header line, find colon */ |
@@ -808,7 +795,7 @@ MHD_call_connection_handler (struct MHD_Connection *connection) | |||
808 | connection->read_buffer, &processed, | 795 | connection->read_buffer, &processed, |
809 | &connection->client_context)) | 796 | &connection->client_context)) |
810 | { | 797 | { |
811 | /* serios internal error, close connection */ | 798 | /* serious internal error, close connection */ |
812 | #if HAVE_MESSAGES | 799 | #if HAVE_MESSAGES |
813 | MHD_DLOG (connection->daemon, | 800 | MHD_DLOG (connection->daemon, |
814 | "Internal application error, closing connection.\n"); | 801 | "Internal application error, closing connection.\n"); |
@@ -820,8 +807,8 @@ MHD_call_connection_handler (struct MHD_Connection *connection) | |||
820 | memmove (connection->read_buffer, | 807 | memmove (connection->read_buffer, |
821 | &connection->read_buffer[connection->readLoc - processed], | 808 | &connection->read_buffer[connection->readLoc - processed], |
822 | processed); | 809 | processed); |
823 | if (connection->uploadSize != -1) | 810 | if (connection->uploadSize != -1) |
824 | connection->uploadSize -= (connection->readLoc - processed); | 811 | connection->uploadSize -= (connection->readLoc - processed); |
825 | connection->readLoc = processed; | 812 | connection->readLoc = processed; |
826 | if ((connection->uploadSize == 0) || | 813 | if ((connection->uploadSize == 0) || |
827 | ((connection->readLoc == 0) && | 814 | ((connection->readLoc == 0) && |
@@ -921,6 +908,12 @@ MHD_connection_handle_read (struct MHD_Connection *connection) | |||
921 | #endif | 908 | #endif |
922 | #endif | 909 | #endif |
923 | shutdown (connection->socket_fd, SHUT_RD); | 910 | shutdown (connection->socket_fd, SHUT_RD); |
911 | if ( (connection->headersReceived == MHD_NO) || | ||
912 | (connection->bodyReceived == MHD_NO) ) { | ||
913 | /* no request => no response! */ | ||
914 | CLOSE (connection->socket_fd); | ||
915 | connection->socket_fd = -1; | ||
916 | } | ||
924 | return MHD_YES; | 917 | return MHD_YES; |
925 | } | 918 | } |
926 | connection->readLoc += bytes_read; | 919 | connection->readLoc += bytes_read; |
@@ -1059,6 +1052,7 @@ MHD_connection_handle_write (struct MHD_Connection *connection) | |||
1059 | { | 1052 | { |
1060 | struct MHD_Response *response; | 1053 | struct MHD_Response *response; |
1061 | int ret; | 1054 | int ret; |
1055 | const char * end; | ||
1062 | 1056 | ||
1063 | if (MHD_need_100_continue (connection)) | 1057 | if (MHD_need_100_continue (connection)) |
1064 | { | 1058 | { |
@@ -1194,6 +1188,9 @@ MHD_connection_handle_write (struct MHD_Connection *connection) | |||
1194 | connection, | 1188 | connection, |
1195 | &connection->client_context, | 1189 | &connection->client_context, |
1196 | MHD_REQUEST_TERMINATED_COMPLETED_OK); | 1190 | MHD_REQUEST_TERMINATED_COMPLETED_OK); |
1191 | end = MHD_lookup_connection_value (connection, | ||
1192 | MHD_HEADER_KIND, | ||
1193 | MHD_HTTP_HEADER_CONNECTION); | ||
1197 | connection->client_context = NULL; | 1194 | connection->client_context = NULL; |
1198 | connection->continuePos = 0; | 1195 | connection->continuePos = 0; |
1199 | connection->responseCode = 0; | 1196 | connection->responseCode = 0; |
@@ -1204,7 +1201,14 @@ MHD_connection_handle_write (struct MHD_Connection *connection) | |||
1204 | connection->bodyReceived = MHD_NO; | 1201 | connection->bodyReceived = MHD_NO; |
1205 | connection->messagePos = 0; | 1202 | connection->messagePos = 0; |
1206 | connection->method = NULL; | 1203 | connection->method = NULL; |
1207 | connection->url = NULL; | 1204 | connection->url = NULL; |
1205 | if ((end != NULL) && (0 == strcasecmp (end, "close"))) | ||
1206 | { | ||
1207 | /* other side explicitly requested | ||
1208 | that we close the connection after | ||
1209 | this request */ | ||
1210 | connection->read_close = MHD_YES; | ||
1211 | } | ||
1208 | if ((connection->read_close == MHD_YES) || | 1212 | if ((connection->read_close == MHD_YES) || |
1209 | (0 != strcasecmp (MHD_HTTP_VERSION_1_1, connection->version))) | 1213 | (0 != strcasecmp (MHD_HTTP_VERSION_1_1, connection->version))) |
1210 | { | 1214 | { |
diff --git a/src/daemon/daemon.c b/src/daemon/daemon.c index e5317c04..b7c66c8d 100644 --- a/src/daemon/daemon.c +++ b/src/daemon/daemon.c | |||
@@ -44,7 +44,13 @@ | |||
44 | * Print extra messages with reasons for closing | 44 | * Print extra messages with reasons for closing |
45 | * sockets? (only adds non-error messages). | 45 | * sockets? (only adds non-error messages). |
46 | */ | 46 | */ |
47 | #define DEBUG_CLOSE 0 | 47 | #define DEBUG_CLOSE MHD_NO |
48 | |||
49 | /** | ||
50 | * Print extra messages when establishing | ||
51 | * connections? (only adds non-error messages). | ||
52 | */ | ||
53 | #define DEBUG_CONNECT MHD_NO | ||
48 | 54 | ||
49 | /** | 55 | /** |
50 | * Register an access handler for all URIs beginning with uri_prefix. | 56 | * Register an access handler for all URIs beginning with uri_prefix. |
@@ -163,6 +169,9 @@ MHD_get_fdset (struct MHD_Daemon *daemon, | |||
163 | return MHD_NO; | 169 | return MHD_NO; |
164 | pos = pos->next; | 170 | pos = pos->next; |
165 | } | 171 | } |
172 | #if DEBUG_CONNECT | ||
173 | MHD_DLOG (daemon, "Maximum socket in select set: %d\n", *max_fd); | ||
174 | #endif | ||
166 | return MHD_YES; | 175 | return MHD_YES; |
167 | } | 176 | } |
168 | 177 | ||
@@ -276,6 +285,9 @@ MHD_accept_connection (struct MHD_Daemon *daemon) | |||
276 | } | 285 | } |
277 | return MHD_NO; | 286 | return MHD_NO; |
278 | } | 287 | } |
288 | #if DEBUG_CONNECT | ||
289 | MHD_DLOG (daemon, "Accepted connection on socket %d\n", s); | ||
290 | #endif | ||
279 | if (daemon->max_connections == 0) | 291 | if (daemon->max_connections == 0) |
280 | { | 292 | { |
281 | /* above connection limit - reject */ | 293 | /* above connection limit - reject */ |
@@ -425,7 +437,8 @@ MHD_cleanup_connections (struct MHD_Daemon *daemon) | |||
425 | continue; | 437 | continue; |
426 | } | 438 | } |
427 | 439 | ||
428 | if ((pos->headersReceived == MHD_YES) && (pos->response == NULL)) | 440 | if ( (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && |
441 | ((pos->headersReceived == MHD_YES) && (pos->response == NULL)) ) | ||
429 | MHD_call_connection_handler (pos); | 442 | MHD_call_connection_handler (pos); |
430 | 443 | ||
431 | prev = pos; | 444 | prev = pos; |
diff --git a/src/daemon/daemontest_post_loop.c b/src/daemon/daemontest_post_loop.c index c24dcf52..8fbc1f70 100644 --- a/src/daemon/daemontest_post_loop.c +++ b/src/daemon/daemontest_post_loop.c | |||
@@ -37,7 +37,7 @@ | |||
37 | 37 | ||
38 | #define POST_DATA "<?xml version='1.0' ?>\n<xml>\n<data-id>1</data-id>\n</xml>\n" | 38 | #define POST_DATA "<?xml version='1.0' ?>\n<xml>\n<data-id>1</data-id>\n</xml>\n" |
39 | 39 | ||
40 | #define LOOPCOUNT 100 | 40 | #define LOOPCOUNT 10 |
41 | 41 | ||
42 | static int oneone; | 42 | static int oneone; |
43 | 43 | ||
@@ -67,8 +67,9 @@ ahc_echo (void *cls, | |||
67 | const char *method, | 67 | const char *method, |
68 | const char *version, | 68 | const char *version, |
69 | const char *upload_data, unsigned int *upload_data_size, | 69 | const char *upload_data, unsigned int *upload_data_size, |
70 | void **unused) | 70 | void **mptr) |
71 | { | 71 | { |
72 | static int marker; | ||
72 | struct MHD_Response *response; | 73 | struct MHD_Response *response; |
73 | int ret; | 74 | int ret; |
74 | 75 | ||
@@ -77,15 +78,23 @@ ahc_echo (void *cls, | |||
77 | printf ("METHOD: %s\n", method); | 78 | printf ("METHOD: %s\n", method); |
78 | return MHD_NO; /* unexpected method */ | 79 | return MHD_NO; /* unexpected method */ |
79 | } | 80 | } |
81 | if ( (*mptr != NULL) && | ||
82 | (0 == *upload_data_size) ) { | ||
83 | if (*mptr != &marker) | ||
84 | abort(); | ||
85 | response = MHD_create_response_from_data (2, | ||
86 | "OK", | ||
87 | MHD_NO, MHD_NO); | ||
88 | ret = MHD_queue_response (connection, MHD_HTTP_OK, response); | ||
89 | MHD_destroy_response (response); | ||
90 | *mptr = NULL; | ||
91 | return ret; | ||
92 | } | ||
80 | if (strlen(POST_DATA) != *upload_data_size) | 93 | if (strlen(POST_DATA) != *upload_data_size) |
81 | return MHD_NO; | 94 | return MHD_YES; |
82 | *upload_data_size = 0; | 95 | *upload_data_size = 0; |
83 | response = MHD_create_response_from_data (2, | 96 | *mptr = ▮ |
84 | "OK", | 97 | return MHD_YES; |
85 | MHD_NO, MHD_NO); | ||
86 | ret = MHD_queue_response (connection, MHD_HTTP_OK, response); | ||
87 | MHD_destroy_response (response); | ||
88 | return ret; | ||
89 | } | 98 | } |
90 | 99 | ||
91 | 100 | ||
@@ -98,18 +107,22 @@ testInternalPost () | |||
98 | struct CBC cbc; | 107 | struct CBC cbc; |
99 | CURLcode errornum; | 108 | CURLcode errornum; |
100 | int i; | 109 | int i; |
110 | char url[1024]; | ||
101 | 111 | ||
102 | cbc.buf = buf; | 112 | cbc.buf = buf; |
103 | cbc.size = 2048; | 113 | cbc.size = 2048; |
104 | d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG, | 114 | d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG, |
105 | 8008, NULL, NULL, &ahc_echo, NULL, MHD_OPTION_END); | 115 | 1080, NULL, NULL, &ahc_echo, NULL, MHD_OPTION_END); |
106 | if (d == NULL) | 116 | if (d == NULL) |
107 | return 1; | 117 | return 1; |
108 | for (i=0;i<LOOPCOUNT;i++) { | 118 | for (i=0;i<LOOPCOUNT;i++) { |
119 | if (0 == i % 100) | ||
120 | fprintf(stderr, "."); | ||
109 | c = curl_easy_init (); | 121 | c = curl_easy_init (); |
110 | cbc.pos = 0; | 122 | cbc.pos = 0; |
111 | buf[0] = '\0'; | 123 | buf[0] = '\0'; |
112 | curl_easy_setopt (c, CURLOPT_URL, "http://localhost:1080/hello_world"); | 124 | sprintf(url, "http://localhost:1080/hw%d", i); |
125 | curl_easy_setopt (c, CURLOPT_URL, url); | ||
113 | curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer); | 126 | curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer); |
114 | curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc); | 127 | curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc); |
115 | curl_easy_setopt (c, CURLOPT_POSTFIELDS, POST_DATA); | 128 | curl_easy_setopt (c, CURLOPT_POSTFIELDS, POST_DATA); |
@@ -143,6 +156,7 @@ testInternalPost () | |||
143 | } | 156 | } |
144 | } | 157 | } |
145 | MHD_stop_daemon (d); | 158 | MHD_stop_daemon (d); |
159 | fprintf(stderr, "\n"); | ||
146 | return 0; | 160 | return 0; |
147 | } | 161 | } |
148 | 162 | ||
@@ -155,18 +169,22 @@ testMultithreadedPost () | |||
155 | struct CBC cbc; | 169 | struct CBC cbc; |
156 | CURLcode errornum; | 170 | CURLcode errornum; |
157 | int i; | 171 | int i; |
172 | char url[1024]; | ||
158 | 173 | ||
159 | cbc.buf = buf; | 174 | cbc.buf = buf; |
160 | cbc.size = 2048; | 175 | cbc.size = 2048; |
161 | d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG, | 176 | d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG, |
162 | 8009, NULL, NULL, &ahc_echo, NULL, MHD_OPTION_END); | 177 | 1081, NULL, NULL, &ahc_echo, NULL, MHD_OPTION_END); |
163 | if (d == NULL) | 178 | if (d == NULL) |
164 | return 16; | 179 | return 16; |
165 | for (i=0;i<LOOPCOUNT;i++) { | 180 | for (i=0;i<LOOPCOUNT;i++) { |
181 | if (0 == i % 100) | ||
182 | fprintf(stderr, "."); | ||
166 | c = curl_easy_init (); | 183 | c = curl_easy_init (); |
167 | cbc.pos = 0; | 184 | cbc.pos = 0; |
168 | buf[0] = '\0'; | 185 | buf[0] = '\0'; |
169 | curl_easy_setopt (c, CURLOPT_URL, "http://localhost:1081/hello_world"); | 186 | sprintf(url, "http://localhost:1081/hw%d", i); |
187 | curl_easy_setopt (c, CURLOPT_URL, url); | ||
170 | curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer); | 188 | curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer); |
171 | curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc); | 189 | curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc); |
172 | curl_easy_setopt (c, CURLOPT_POSTFIELDS, POST_DATA); | 190 | curl_easy_setopt (c, CURLOPT_POSTFIELDS, POST_DATA); |
@@ -200,6 +218,7 @@ testMultithreadedPost () | |||
200 | } | 218 | } |
201 | } | 219 | } |
202 | MHD_stop_daemon (d); | 220 | MHD_stop_daemon (d); |
221 | fprintf(stderr, "\n"); | ||
203 | return 0; | 222 | return 0; |
204 | } | 223 | } |
205 | 224 | ||
@@ -222,6 +241,9 @@ testExternalPost () | |||
222 | time_t start; | 241 | time_t start; |
223 | struct timeval tv; | 242 | struct timeval tv; |
224 | int i; | 243 | int i; |
244 | unsigned long long timeout; | ||
245 | long ctimeout; | ||
246 | char url[1024]; | ||
225 | 247 | ||
226 | multi = NULL; | 248 | multi = NULL; |
227 | cbc.buf = buf; | 249 | cbc.buf = buf; |
@@ -238,10 +260,13 @@ testExternalPost () | |||
238 | return 512; | 260 | return 512; |
239 | } | 261 | } |
240 | for (i=0;i<LOOPCOUNT;i++) { | 262 | for (i=0;i<LOOPCOUNT;i++) { |
263 | if (0 == i % 100) | ||
264 | fprintf(stderr, "."); | ||
241 | c = curl_easy_init (); | 265 | c = curl_easy_init (); |
242 | cbc.pos = 0; | 266 | cbc.pos = 0; |
243 | buf[0] = '\0'; | 267 | buf[0] = '\0'; |
244 | curl_easy_setopt (c, CURLOPT_URL, "http://localhost:1082/hello_world"); | 268 | sprintf(url, "http://localhost:1082/hw%d", i); |
269 | curl_easy_setopt (c, CURLOPT_URL, url); | ||
245 | curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer); | 270 | curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer); |
246 | curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc); | 271 | curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc); |
247 | curl_easy_setopt (c, CURLOPT_POSTFIELDS, POST_DATA); | 272 | curl_easy_setopt (c, CURLOPT_POSTFIELDS, POST_DATA); |
@@ -291,8 +316,23 @@ testExternalPost () | |||
291 | MHD_stop_daemon (d); | 316 | MHD_stop_daemon (d); |
292 | return 4096; | 317 | return 4096; |
293 | } | 318 | } |
294 | tv.tv_sec = 0; | 319 | if (MHD_NO == MHD_get_timeout(d, &timeout)) |
295 | tv.tv_usec = 1000; | 320 | timeout = 1000000; /* 1000s == INFTY */ |
321 | if ( (CURLM_OK == curl_multi_timeout(multi, &ctimeout)) && | ||
322 | (ctimeout < timeout) && | ||
323 | (ctimeout >= 0) ) | ||
324 | timeout = ctimeout; | ||
325 | if (timeout > 0) | ||
326 | timeout = 0; /* this line is needed since CURL seems to have | ||
327 | a bug -- it returns a timeout of -1 even though | ||
328 | it should be attempting to connect -- and the | ||
329 | socket for doing the connection is not yet | ||
330 | in the write-set! If the timeout is too high, | ||
331 | no progress would happen! Even a timeout of | ||
332 | 1 would cause my system to be mostly idle instead | ||
333 | of processing at maximum speed... */ | ||
334 | tv.tv_sec = timeout / 1000; | ||
335 | tv.tv_usec = (timeout % 1000) * 1000; | ||
296 | select (max + 1, &rs, &ws, &es, &tv); | 336 | select (max + 1, &rs, &ws, &es, &tv); |
297 | curl_multi_perform (multi, &running); | 337 | curl_multi_perform (multi, &running); |
298 | if (running == 0) | 338 | if (running == 0) |
@@ -308,25 +348,26 @@ testExternalPost () | |||
308 | __FILE__, | 348 | __FILE__, |
309 | __LINE__, curl_easy_strerror (msg->data.result)); | 349 | __LINE__, curl_easy_strerror (msg->data.result)); |
310 | curl_multi_remove_handle (multi, c); | 350 | curl_multi_remove_handle (multi, c); |
311 | curl_multi_cleanup (multi); | ||
312 | curl_easy_cleanup (c); | 351 | curl_easy_cleanup (c); |
313 | c = NULL; | 352 | c = NULL; |
314 | multi = NULL; | ||
315 | } | 353 | } |
316 | } | 354 | } |
317 | MHD_run (d); | 355 | MHD_run (d); |
318 | } | 356 | } |
357 | if (c != NULL) { | ||
319 | curl_multi_remove_handle (multi, c); | 358 | curl_multi_remove_handle (multi, c); |
320 | curl_easy_cleanup (c); | 359 | curl_easy_cleanup (c); |
360 | } | ||
321 | if ( (buf[0] != 'O') || | 361 | if ( (buf[0] != 'O') || |
322 | (buf[1] != 'K') ) { | 362 | (buf[1] != 'K') ) { |
323 | curl_multi_cleanup (multi); | 363 | curl_multi_cleanup (multi); |
324 | MHD_stop_daemon (d); | 364 | MHD_stop_daemon (d); |
325 | return 8192; | 365 | return 8192; |
326 | } | 366 | } |
327 | } | 367 | } |
328 | curl_multi_cleanup (multi); | 368 | curl_multi_cleanup (multi); |
329 | MHD_stop_daemon (d); | 369 | MHD_stop_daemon (d); |
370 | fprintf(stderr, "\n"); | ||
330 | return 0; | 371 | return 0; |
331 | } | 372 | } |
332 | 373 | ||