#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
+#ifdef HAVE_NETINET_IN6_H
+#include <netinet/in6.h>
+#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#define REQBUFSIZ 150000
#define REQBUFSIZ_TXT "149999"
-static long prevtestno=-1; /* previous test number we served */
-static long prevpartno=-1; /* previous part number we served */
-static bool prevbounce=FALSE; /* instructs the server to increase the part
- number for a test in case the identical
- testno+partno request shows up again */
+static long prevtestno = -1; /* previous test number we served */
+static long prevpartno = -1; /* previous part number we served */
+static bool prevbounce = FALSE; /* instructs the server to increase the part
+ number for a test in case the identical
+ testno+partno request shows up again */
#define RCMD_NORMALREQ 0 /* default request, use the tests file normally */
#define RCMD_IDLE 1 /* told to sit idle */
static size_t num_sockets = 0;
static int ProcessRequest(struct httprequest *req);
-static void storerequest(char *reqbuf, size_t totalsize);
+static void storerequest(const char *reqbuf, size_t totalsize);
#define DEFAULT_PORT 8999
filename = test2file(req->testno);
- stream=fopen(filename, "rb");
+ stream = fopen(filename, "rb");
if(!stream) {
error = errno;
logmsg("fopen() failed with error: %d %s", error, strerror(error));
char *orgcmd = NULL;
char *cmd = NULL;
size_t cmdsize = 0;
- int num=0;
+ int num = 0;
/* get the custom server control "commands" */
error = getpart(&orgcmd, &cmdsize, "reply", "servercmd", stream);
static int ProcessRequest(struct httprequest *req)
{
- char *line=&req->reqbuf[req->checkindex];
+ char *line = &req->reqbuf[req->checkindex];
bool chunked = FALSE;
static char request[REQUEST_KEYWORD_SIZE];
static char doc[MAXDOCNAMELEN];
if(sscanf(req->reqbuf, "CONNECT %" MAXDOCNAMELEN_TXT "s HTTP/%d.%d",
doc, &prot_major, &prot_minor) == 3) {
char *portp = NULL;
- unsigned long part=0;
+ unsigned long part = 0;
snprintf(logbuf, sizeof(logbuf),
"Received a CONNECT %s HTTP/%d.%d request",
}
if(*p != ']')
logmsg("Invalid CONNECT IPv6 address format");
- else if(*(p+1) != ':')
+ else if(*(p + 1) != ':')
logmsg("Invalid CONNECT IPv6 port format");
else
- portp = p+1;
+ portp = p + 1;
req->testno = part;
}
else
portp = strchr(doc, ':');
- if(portp && (*(portp+1) != '\0') && ISDIGIT(*(portp+1))) {
- unsigned long ulnum = strtoul(portp+1, NULL, 10);
+ if(portp && (*(portp + 1) != '\0') && ISDIGIT(*(portp + 1))) {
+ unsigned long ulnum = strtoul(portp + 1, NULL, 10);
if(!ulnum || (ulnum > 65535UL))
logmsg("Invalid CONNECT port received");
else
}
if(req->testno == DOCNUMBER_NOTHING) {
+ /* check for a Testno: header with the test case number */
+ char *testno = strstr(line, "\nTestno: ");
+ if(testno) {
+ req->testno = strtol(&testno[9], NULL, 10);
+ logmsg("Found test number %d in Testno: header!", req->testno);
+ }
+ }
+ if(req->testno == DOCNUMBER_NOTHING) {
/* Still no test case number. Try to get the the number off the last dot
instead, IE we consider the TLD to be the test number. Test 123 can
then be written as "example.com.123". */
if(got_exit_signal)
return 1; /* done */
- if((req->cl==0) && strncasecompare("Content-Length:", line, 15)) {
+ if((req->cl == 0) && strncasecompare("Content-Length:", line, 15)) {
/* If we don't ignore content-length, we read it and we read the whole
request including the body before we return. If we've been told to
ignore the content-length, we will return as soon as all headers
logmsg("Authorization header found, as required");
}
- if(!req->digest && strstr(req->reqbuf, "Authorization: Digest")) {
+ if(strstr(req->reqbuf, "Authorization: Negotiate")) {
+ /* Negotiate iterations */
+ static long prev_testno = -1;
+ static long prev_partno = -1;
+ logmsg("Negotiate: prev_testno: %d, prev_partno: %d",
+ prev_testno, prev_partno);
+ if(req->testno != prev_testno) {
+ prev_testno = req->testno;
+ prev_partno = req->partno;
+ }
+ prev_partno += 1;
+ req->partno = prev_partno;
+ }
+ else if(!req->digest && strstr(req->reqbuf, "Authorization: Digest")) {
/* If the client is passing this Digest-header, we set the part number
to 1000. Not only to spice up the complexity of this, but to make
Digest stuff to work in the test suite. */
}
/* store the entire request in a file */
-static void storerequest(char *reqbuf, size_t totalsize)
+static void storerequest(const char *reqbuf, size_t totalsize)
{
int res;
int error = 0;
size_t written;
size_t writeleft;
FILE *dump;
- const char *dumpfile=is_proxy?REQUEST_PROXY_DUMP:REQUEST_DUMP;
+ const char *dumpfile = is_proxy?REQUEST_PROXY_DUMP:REQUEST_DUMP;
if(reqbuf == NULL)
return;
ssize_t written;
size_t count;
const char *buffer;
- char *ptr=NULL;
+ char *ptr = NULL;
FILE *stream;
- char *cmd=NULL;
- size_t cmdsize=0;
+ char *cmd = NULL;
+ size_t cmdsize = 0;
FILE *dump;
bool persistant = TRUE;
bool sendfailure = FALSE;
/* select the <data> tag for "normal" requests and the <connect> one
for CONNECT requests (within the <reply> section) */
- const char *section= req->connect_request?"connect":"data";
+ const char *section = req->connect_request?"connect":"data";
if(req->partno)
snprintf(partbuf, sizeof(partbuf), "%s%ld", section, req->partno);
logmsg("Send response test%ld section <%s>", req->testno, partbuf);
- stream=fopen(filename, "rb");
+ stream = fopen(filename, "rb");
if(!stream) {
error = errno;
logmsg("fopen() failed with error: %d %s", error, strerror(error));
}
/* re-open the same file again */
- stream=fopen(filename, "rb");
+ stream = fopen(filename, "rb");
if(!stream) {
error = errno;
logmsg("fopen() failed with error: %d %s", error, strerror(error));
responsesize = count;
do {
- /* Ok, we send no more than 200 bytes at a time, just to make sure that
+ /* Ok, we send no more than N bytes at a time, just to make sure that
larger chunks are split up so that the client will need to do multiple
recv() calls to get it and thus we exercise that code better */
size_t num = count;
- if(num > 200)
- num = 200;
+ if(num > 20)
+ num = 20;
retry:
written = swrite(sock, buffer, num);
sendfailure = TRUE;
break;
}
- else {
- logmsg("Sent off %zd bytes", written);
- }
/* write to file as well */
fwrite(buffer, 1, (size_t)written, dump);
char command[32];
int quarters;
int num;
- ptr=cmd;
+ ptr = cmd;
do {
if(2 == sscanf(ptr, "%31s %d", command, &num)) {
if(!strcmp("wait", command)) {
serverfd = socket(socket_domain, SOCK_STREAM, 0);
if(CURL_SOCKET_BAD == serverfd) {
error = SOCKERRNO;
- logmsg("Error creating socket for server conection: (%d) %s",
+ logmsg("Error creating socket for server connection: (%d) %s",
error, strerror(error));
return CURL_SOCKET_BAD;
}
curl_socklen_t flag = 1;
if(0 != setsockopt(serverfd, IPPROTO_TCP, TCP_NODELAY,
(void *)&flag, sizeof(flag)))
- logmsg("====> TCP_NODELAY for server conection failed");
+ logmsg("====> TCP_NODELAY for server connection failed");
}
#endif
* either end.
*
* When doing FTP through a CONNECT proxy, we expect that the data connection
- * will be setup while the first connect is still being kept up. Therefor we
+ * will be setup while the first connect is still being kept up. Therefore we
* must accept a new connection and deal with it appropriately.
*/
int max_tunnel_idx; /* CTRL or DATA */
int loop;
int i;
- int timeout_count=0;
+ int timeout_count = 0;
/* primary tunnel client endpoint already connected */
clientfd[CTRL] = *infdp;
maxfd = clientfd[i];
}
if(poll_client_wr[i] && toc[i]) {
- /* unless told not to do so, monitor writeability
+ /* unless told not to do so, monitor writability
if there is data ready to be sent to client */
FD_SET(clientfd[i], &output);
if(clientfd[i] > maxfd)
maxfd = serverfd[i];
}
if(poll_server_wr[i] && tos[i]) {
- /* unless told not to do so, monitor writeability
+ /* unless told not to do so, monitor writability
if there is data ready to be sent to server */
FD_SET(serverfd[i], &output);
if(serverfd[i] > maxfd)
if(rc > 0) {
/* socket action */
bool tcp_fin_wr;
- timeout_count=0;
+ timeout_count = 0;
if(got_exit_signal)
break;
curl_socklen_t flag = 1;
if(0 != setsockopt(datafd, IPPROTO_TCP, TCP_NODELAY,
(void *)&flag, sizeof(flag)))
- logmsg("====> TCP_NODELAY for client DATA conection failed");
+ logmsg("====> TCP_NODELAY for client DATA connection failed");
}
#endif
req2.pipelining = FALSE;
/* ---------------------------------------------------------- */
- /* react to tunnel endpoint readable/writeable notifications */
+ /* react to tunnel endpoint readable/writable notifications */
for(i = 0; i <= max_tunnel_idx; i++) {
size_t len;
if(clientfd[i] != CURL_SOCKET_BAD) {
while(!req->done_processing) {
int rc = get_request(msgsock, req);
if(rc <= 0) {
- /* Nothing further to read now (possibly because the socket was closed */
+ /* Nothing further to read now, possibly because the socket was closed */
return rc;
}
}
const char *unix_socket = NULL;
bool unlink_socket = false;
#endif
- char *pidname= (char *)".http.pid";
+ const char *pidname = ".http.pid";
struct httprequest req;
int rc = 0;
int error;
- int arg=1;
+ int arg = 1;
long pid;
const char *connecthost = "127.0.0.1";
const char *socket_type = "IPv4";
if(got_exit_signal)
goto sws_cleanup;
- /* Set up for select*/
+ /* Set up for select */
FD_ZERO(&input);
FD_ZERO(&output);
goto sws_cleanup;
if(rc == 0) {
- /* Timed out - try again*/
+ /* Timed out - try again */
continue;
}
logmsg("====> Client disconnect %d", req.connmon);
if(req.connmon) {
- const char *keepopen="[DISCONNECT]\n";
- storerequest((char *)keepopen, strlen(keepopen));
+ const char *keepopen = "[DISCONNECT]\n";
+ storerequest(keepopen, strlen(keepopen));
}
if(!req.open)