5
5
* | (__| |_| | _ <| |___
6
6
* \___|\___/|_| \_\_____|
8
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
8
* Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
10
10
* This software is licensed as described in the file COPYING, which
11
11
* you should have received as part of this distribution. The terms
18
18
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19
19
* KIND, either express or implied.
21
* $Id: sws.c,v 1.110 2008-01-25 05:08:53 yangtse Exp $
21
* $Id: sws.c,v 1.120 2008-04-23 23:55:34 yangtse Exp $
22
22
***************************************************************************/
24
24
/* sws.c: simple (silly?) web server
84
77
long prevtestno=-1; /* previous test number we served */
85
78
long prevpartno=-1; /* previous part number we served */
86
bool prevbounce; /* instructs the server to increase the part number for
87
a test in case the identical testno+partno request
79
bool prevbounce=FALSE; /* instructs the server to increase the part number for
80
a test in case the identical testno+partno request
90
83
#define RCMD_NORMALREQ 0 /* default request, use the tests file normally */
91
84
#define RCMD_IDLE 1 /* told to sit idle */
97
90
int offset; /* size of the incoming request */
98
91
long testno; /* test number found in the request */
99
92
long partno; /* part number found in the request */
100
int open; /* keep connection open info, as found in the request */
93
bool open; /* keep connection open info, as found in the request */
101
94
bool auth_req; /* authentication required, don't wait for body unless
102
95
there's an Authorization header */
103
96
bool auth; /* Authorization header present in the incoming request */
509
505
writeleft -= written;
510
506
} while ((writeleft > 0) && ((error = ERRNO) == EINTR));
512
fclose(dump); /* close it ASAP */
514
508
if (writeleft > 0) {
515
509
logmsg("Error writing file %s error: %d %s",
516
510
REQUEST_DUMP, error, strerror(error));
517
511
logmsg("Wrote only (%d bytes) of (%d bytes) request input to %s",
518
512
totalsize-writeleft, totalsize, REQUEST_DUMP);
517
} while(res && ((error = ERRNO) == EINTR));
519
logmsg("Error closing file %s error: %d %s",
520
REQUEST_DUMP, error, strerror(error));
521
523
logmsg("Wrote request (%d bytes) input to " REQUEST_DUMP,
526
527
/* return 0 on success, non-zero on failure */
527
528
static int get_request(curl_socket_t sock, struct httprequest *req)
530
531
char *reqbuf = req->reqbuf;
532
char pipereq[REQBUFSIZ];
535
int pipereq_length = 0;
534
537
if(req->pipelining) {
538
pipereq = reqbuf + req->checkindex;
535
539
pipereq_length = req->offset - req->checkindex;
536
memcpy(pipereq, reqbuf + req->checkindex, pipereq_length);
541
542
/*** Init the httpreqest structure properly for the upcoming request ***/
542
memset(req, 0, sizeof(struct httprequest));
544
/* here's what should not be 0 from the start */
545
req->testno = DOCNUMBER_NOTHING; /* safe default */
546
req->open = TRUE; /* connection should remain open and wait for more
546
req->testno = DOCNUMBER_NOTHING;
549
req->auth_req = FALSE;
555
req->rcmd = RCMD_NORMALREQ;
556
req->prot_version = 0;
557
req->pipelining = FALSE;
550
559
/*** end of httprequest init ***/
552
while (req->offset < REQBUFSIZ) {
561
while (req->offset < REQBUFSIZ-1) {
554
562
if(pipereq_length) {
555
memcpy(reqbuf, pipereq, pipereq_length);
563
memmove(reqbuf, pipereq, pipereq_length);
556
564
got = pipereq_length;
557
565
pipereq_length = 0;
560
got = sread(sock, reqbuf + req->offset, REQBUFSIZ - req->offset);
568
got = sread(sock, reqbuf + req->offset, REQBUFSIZ-1 - req->offset);
563
571
logmsg("recv() returned error: %d", SOCKERRNO);
564
572
return DOCNUMBER_INTERNAL;
566
574
logmsg("Connection closed by client");
567
reqbuf[req->offset]=0;
575
reqbuf[req->offset] = '\0';
569
577
/* dump the request receivied so far to the external file */
570
578
storerequest(reqbuf, req->offset);
589
if (req->offset >= REQBUFSIZ) {
596
if((req->offset == REQBUFSIZ-1) && (got > 0)) {
597
logmsg("Request would overflow buffer, closing connection");
598
/* dump request received so far to external file anyway */
599
reqbuf[REQBUFSIZ-1] = '\0';
602
else if(req->offset > REQBUFSIZ-1) {
590
603
logmsg("Request buffer overflow, closing connection");
591
reqbuf[REQBUFSIZ-1]=0;
593
/* dump the request to an external file anyway */
604
/* dump request received so far to external file anyway */
605
reqbuf[REQBUFSIZ-1] = '\0';
596
reqbuf[req->offset]=0;
609
reqbuf[req->offset] = '\0';
598
611
/* dump the request to an external file */
599
612
storerequest(reqbuf, req->pipelining ? req->checkindex : req->offset);
601
return fail; /* success */
614
return fail; /* return 0 on success */
604
617
/* returns -1 on failure */
656
671
case DOCNUMBER_WERULEZ:
657
672
/* we got a "friends?" question, reply back that we sure are */
658
673
logmsg("Identifying ourselves as friends");
659
sprintf(msgbuf, "WE ROOLZ: %d\r\n", (int)getpid());
674
sprintf(msgbuf, "WE ROOLZ: %ld\r\n", (long)getpid());
660
675
msglen = strlen(msgbuf);
661
676
sprintf(weare, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\n\r\n%s",
768
782
buffer += written;
769
783
} while(count>0);
787
} while(res && ((error = ERRNO) == EINTR));
789
logmsg("Error closing file %s error: %d %s",
790
RESPONSE_DUMP, error, strerror(error));
793
logmsg("Sending response failed. Only (%d bytes) of (%d bytes) were sent",
794
responsesize-count, responsesize);
773
802
logmsg("Response sent (%d bytes) and written to " RESPONSE_DUMP,
935
pidfile = fopen(pidname, "w");
937
fprintf(pidfile, "%d\n", (int)getpid());
942
logmsg("fopen() failed with error: %d %s", error, strerror(error));
943
logmsg("Error opening file: %s", pidname);
944
logmsg("Couldn't write pid file");
962
if(!write_pidfile(pidname)) {
1004
/* full initialization for new request after connection */
1005
memset(&req, 0, sizeof(req));
1006
req.testno = DOCNUMBER_NOTHING;
1008
req.auth_req = FALSE;
1012
req.pipelining = FALSE;
1024
/* initialization of httprequest struct is done in get_request(), but due
1025
to pipelining treatment the pipelining struct field must be initialized
1026
previously to FALSE every time a new connection arrives. */
1028
req.pipelining = FALSE;
1015
1031
if(get_request(msgsock, &req))
1016
1032
/* non-zero means error, break out of loop */