summaryrefslogtreecommitdiff
path: root/tests/server
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2020-04-16 17:52:24 +0200
committerDaniel Stenberg <daniel@haxx.se>2020-04-18 22:45:28 +0200
commit80d651541537433e1363f7b4ba7497b08d0fb53f (patch)
treed8cfbaeccb174df77ea16bd9020b79bd180268b1 /tests/server
parente917492048f4b85a0fd58a033d10072fc7666c3b (diff)
downloadgnurl-80d651541537433e1363f7b4ba7497b08d0fb53f.tar.gz
gnurl-80d651541537433e1363f7b4ba7497b08d0fb53f.tar.bz2
gnurl-80d651541537433e1363f7b4ba7497b08d0fb53f.zip
tests: run the sws server on "any port"
Makes the test servers for HTTP and Gopher pop up on a currently unused port and runtests adapts to that! Closes #5247
Diffstat (limited to 'tests/server')
-rw-r--r--tests/server/sws.c66
1 files changed, 61 insertions, 5 deletions
diff --git a/tests/server/sws.c b/tests/server/sws.c
index 427bd6e8d..faa1143d9 100644
--- a/tests/server/sws.c
+++ b/tests/server/sws.c
@@ -1849,6 +1849,7 @@ int main(int argc, char *argv[])
bool unlink_socket = false;
#endif
const char *pidname = ".http.pid";
+ const char *portname = ".http.port";
struct httprequest req;
int rc = 0;
int error;
@@ -1881,6 +1882,11 @@ int main(int argc, char *argv[])
if(argc>arg)
pidname = argv[arg++];
}
+ else if(!strcmp("--portfile", argv[arg])) {
+ arg++;
+ if(argc>arg)
+ portname = argv[arg++];
+ }
else if(!strcmp("--logfile", argv[arg])) {
arg++;
if(argc>arg)
@@ -1928,7 +1934,7 @@ int main(int argc, char *argv[])
char *endptr;
unsigned long ulnum = strtoul(argv[arg], &endptr, 10);
if((endptr != argv[arg] + strlen(argv[arg])) ||
- (ulnum < 1025UL) || (ulnum > 65535UL)) {
+ (ulnum && ((ulnum < 1025UL) || (ulnum > 65535UL)))) {
fprintf(stderr, "sws: invalid --port argument (%s)\n",
argv[arg]);
return 0;
@@ -1961,6 +1967,7 @@ int main(int argc, char *argv[])
" --version\n"
" --logfile [file]\n"
" --pidfile [file]\n"
+ " --portfile [file]\n"
" --ipv4\n"
" --ipv6\n"
" --unix-socket [file]\n"
@@ -1972,8 +1979,6 @@ int main(int argc, char *argv[])
}
}
- msnprintf(port_str, sizeof(port_str), "port %hu", port);
-
#ifdef WIN32
win32_init();
atexit(win32_cleanup);
@@ -2080,11 +2085,58 @@ int main(int argc, char *argv[])
}
if(0 != rc) {
error = SOCKERRNO;
- logmsg("Error binding socket on %s: (%d) %s",
- location_str, error, strerror(error));
+ logmsg("Error binding socket: (%d) %s", error, strerror(error));
goto sws_cleanup;
}
+ if(!port) {
+ /* The system was supposed to choose a port number, figure out which
+ port we actually got and update the listener port value with it. */
+ curl_socklen_t la_size;
+ srvr_sockaddr_union_t localaddr;
+#ifdef ENABLE_IPV6
+ if(socket_domain != AF_INET6)
+#endif
+ la_size = sizeof(localaddr.sa4);
+#ifdef ENABLE_IPV6
+ else
+ la_size = sizeof(localaddr.sa6);
+#endif
+ memset(&localaddr.sa, 0, (size_t)la_size);
+ if(getsockname(sock, &localaddr.sa, &la_size) < 0) {
+ error = SOCKERRNO;
+ logmsg("getsockname() failed with error: (%d) %s",
+ error, strerror(error));
+ sclose(sock);
+ goto sws_cleanup;
+ }
+ switch(localaddr.sa.sa_family) {
+ case AF_INET:
+ port = ntohs(localaddr.sa4.sin_port);
+ break;
+#ifdef ENABLE_IPV6
+ case AF_INET6:
+ port = ntohs(localaddr.sa6.sin6_port);
+ break;
+#endif
+ default:
+ break;
+ }
+ if(!port) {
+ /* Real failure, listener port shall not be zero beyond this point. */
+ logmsg("Apparently getsockname() succeeded, with listener port zero.");
+ logmsg("A valid reason for this failure is a binary built without");
+ logmsg("proper network library linkage. This might not be the only");
+ logmsg("reason, but double check it before anything else.");
+ sclose(sock);
+ goto sws_cleanup;
+ }
+ }
+#ifdef USE_UNIX_SOCKETS
+ if(socket_domain != AF_UNIX)
+#endif
+ msnprintf(port_str, sizeof(port_str), "port %hu", port);
+
logmsg("Running %s %s version on %s",
use_gopher?"GOPHER":"HTTP", socket_type, location_str);
@@ -2111,6 +2163,10 @@ int main(int argc, char *argv[])
if(!wrotepidfile)
goto sws_cleanup;
+ wrotepidfile = write_portfile(portname, port);
+ if(!wrotepidfile)
+ goto sws_cleanup;
+
/* initialization of httprequest struct is done before get_request(), but
the pipelining struct field must be initialized previously to FALSE
every time a new connection arrives. */