Compare commits

..

32 Commits

Author SHA1 Message Date
Daniel Stenberg
d9c244278d 7.9.5-pre4 commit 2002-02-26 07:59:43 +00:00
Daniel Stenberg
b6c4185b27 more custom stuff, much about dealing with cookies 2002-02-25 15:25:34 +00:00
Daniel Stenberg
5896d35e72 a never ending stream of things to do... 2002-02-25 14:09:31 +00:00
Daniel Stenberg
b4dfdd8bbc use env to run perl 2002-02-25 14:08:51 +00:00
Daniel Stenberg
e6ed3478ea automake usage and options cleanup 2002-02-25 14:08:18 +00:00
Daniel Stenberg
db08d9c6b9 happy new year 2002-02-25 13:25:33 +00:00
Daniel Stenberg
9490278ece We got this web server's embryo from Georg Horn, muchos gracias. 2002-02-25 12:49:21 +00:00
Daniel Stenberg
fd8bf5f171 the test suite http server is now automake'd 2002-02-25 12:45:48 +00:00
Daniel Stenberg
c9bc14a222 use the pid file, use the automake subdir 2002-02-25 12:45:20 +00:00
Daniel Stenberg
63708cbfb0 automake this dir too 2002-02-25 12:44:58 +00:00
Daniel Stenberg
d9f307623c use the former logfile name again since the ftp server also uses that... 2002-02-25 12:14:24 +00:00
Daniel Stenberg
540f77a627 we actually ran all tests just now, feb 25th, 2002 12:11 MET. with the
new http server on Linux
2002-02-25 11:12:10 +00:00
Daniel Stenberg
71bb2d0b8b reply/postcmd support for "wait" 2002-02-25 11:11:03 +00:00
Daniel Stenberg
87dc44e434 portability, step one, use a config.h.in file 2002-02-25 11:00:16 +00:00
Daniel Stenberg
29e0fcd091 generate a config file for the test suite http server too 2002-02-25 10:56:37 +00:00
Daniel Stenberg
2e9a798f09 create the pidfile and store the pid on invoke 2002-02-25 10:27:29 +00:00
Daniel Stenberg
b32a39f44f oops, #if not #ifdef 2002-02-25 10:12:04 +00:00
Daniel Stenberg
d86f9611b3 support HUGE requests too 2002-02-25 09:42:58 +00:00
Daniel Stenberg
6a62fc4a40 make sure -d is treated as a POST request and thus should fail if mixed
with -I for example
2002-02-25 09:08:28 +00:00
Daniel Stenberg
7cdd6455d7 modified the command to fail properly! ;-) 2002-02-25 09:07:26 +00:00
Daniel Stenberg
e4fefd088d cygnus can't include winsock.h even though it has it, why we need to
make a different and more complicated check for when to include it
2002-02-25 08:20:29 +00:00
Daniel Stenberg
95e601e2b1 "Yet Another Geek" made %{content_type} work in the -w/--writeout option. 2002-02-25 07:40:49 +00:00
Daniel Stenberg
b1ffe7b74a better time selection for the connect timeout 2002-02-22 15:44:37 +00:00
Daniel Stenberg
417c8fb602 16 tests OK 2002-02-22 15:40:17 +00:00
Daniel Stenberg
85efa64c31 cut off big parts of the banner 2002-02-22 15:17:41 +00:00
Daniel Stenberg
d8cb026e80 make sure the custom config-*.h files are in the dist as well 2002-02-22 15:12:17 +00:00
Daniel Stenberg
41dd5121f0 adjusted to work on test case 11 better 2002-02-22 13:54:06 +00:00
Daniel Stenberg
94482d7ca5 use -W too 2002-02-22 13:53:41 +00:00
Daniel Stenberg
4d0e51aead fixed to work with 'nonewline' and thus this passes OK with the new http
server and things
2002-02-22 10:51:19 +00:00
Daniel Stenberg
ae8a8c8ba4 support for using protocol without a trailing newline 2002-02-22 10:50:36 +00:00
Daniel Stenberg
7d043f46d5 hide debug output from screen, use log/ for logfiles 2002-02-22 10:40:05 +00:00
Daniel Stenberg
cbca19d6c2 lib/config.h.in added to dist 2002-02-22 07:51:23 +00:00
24 changed files with 387 additions and 192 deletions

37
CHANGES
View File

@@ -7,6 +7,43 @@
History of Changes
Daniel (25 February 2002)
- Fiddled with the automake files to make all source files in the lib
directory not have ../src in the include path, and the src sources shouldn't
have ../lib!
- All 79 test cases ran OK under Linux and Solaris using the new HTTP server
in the test suite. The new HTTP server was first donated by Georg Horn and
subsequently modified to work with the test suite. It is currently still not
portable enough to run on "all over" but this is a start and I can run all
curl tests on my machines. This is an important requirement for the upcoming
public release.
- Using -d and -I on the same command line now reports an error, as it implies
two different HTTP requests that can't be mixed.
- Jeffrey Pohlmeyer provided a patch that made the -w/--write-out option
support %{content_type} to get the content type of the recent download.
- Kevin Roth reported that pre2 and pre3 didn't compile properly on cygwin,
and this was because I used #ifdef HAVE_WINSOCK_H in lib/multi.h to figure
out if we could include winsock.h which turns out not to be a wise choice to
do on cygwin since it has the file but can't include it!
Daniel (22 February 2002)
- Added src/config-vms.h to the release archive.
- Fixed the connection timeout value again, the change from February 18 wasn't
complete.
Version 7.9.5-pre3
Daniel (21 February 2002)
- Kevin Roth and Andr<64>s Garc<72>a both found out that lib/config.h.in was missing
in the pre-release archive and thus the configure script failed.
Version 7.9.5-pre2
Daniel (20 February 2002)
- Andr<64>s Garc<72>a provided a solution to bug report #515228. the total time
counter was not set correctly when -I was used during some conditions (all

View File

@@ -2,7 +2,7 @@
# $Id$
#
AUTOMAKE_OPTIONS = foreign no-dependencies
AUTOMAKE_OPTIONS = foreign
EXTRA_DIST = \
CHANGES LEGAL maketgz MITX.txt MPL-1.1.txt \

View File

@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al.
# Copyright (C) 2002, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# In order to be useful for every potential user, curl and libcurl are
# dual-licensed under the MPL and the MIT/X-derivate licenses.

View File

@@ -8,7 +8,7 @@ AC_PREREQ(2.50)
dnl First some basic init macros
AC_INIT
AC_CONFIG_SRCDIR([lib/urldata.h])
AM_CONFIG_HEADER(lib/config.h src/config.h)
AM_CONFIG_HEADER(lib/config.h src/config.h tests/server/config.h)
dnl figure out the libcurl version
VERSION=`sed -ne 's/^#define LIBCURL_VERSION "\(.*\)"/\1/p' ${srcdir}/include/curl/curl.h`
@@ -601,6 +601,7 @@ AC_CONFIG_FILES([Makefile \
lib/Makefile \
tests/Makefile \
tests/data/Makefile \
tests/server/Makefile \
packages/Makefile \
packages/Win32/Makefile \
packages/Win32/cygwin/Makefile \

View File

@@ -2,7 +2,7 @@
.\" nroff -man curl.1
.\" Written by Daniel Stenberg
.\"
.TH curl 1 "30 Nov 2001" "Curl 7.9.2" "Curl Manual"
.TH curl 1 "25 Feb 2002" "Curl 7.9.5" "Curl Manual"
.SH NAME
curl \- transfer a URL
.SH SYNOPSIS
@@ -594,6 +594,9 @@ The average download speed that curl measured for the complete download.
.TP
.B speed_upload
The average upload speed that curl measured for the complete upload.
.TP
.B content_type
The Content-Type of the requested document, if there was any. (Added in 7.9.5)
.RE
If this option is used several times, the last one will be used.

View File

@@ -114,7 +114,7 @@ Global Preparation
call initialized.
Repeated calls to curl_global_init() and curl_global_cleanup() should be
avoided. They should be called once each.
avoided. They should only be called once each.
Handle the Easy libcurl
@@ -741,6 +741,15 @@ Customizing Operations
consideration and you should be aware that you may violate the HTTP protocol
when doing so.
There's only one aspect left in the HTTP requests that we haven't yet
mentioned how to modify: the version field. All HTTP requests includes the
version number to tell the server which version we support. libcurl speak
HTTP 1.1 by default. Some very old servers don't like getting 1.1-requests
and when dealing with stubborn old things like that, you can tell libcurl to
use 1.0 instead by doing something like this:
curl_easy_setopt(easyhandle, CURLOPT_HTTP_VERSION, CURLHTTP_VERSION_1_0);
Not all protocols are HTTP-like, and thus the above may not help you when you
want to make for example your FTP transfers to behave differently.
@@ -770,16 +779,71 @@ Customizing Operations
instead be called CURLOPT_POSTQUOTE and used the exact same way.
The custom FTP command will be issued to the server in the same order they
are built in the list, and if a command gets an error code returned back from
the server no more commands will be issued and libcurl will bail out with an
error code. Note that if you use CURLOPT_QUOTE to send commands before a
transfer, no transfer will actually take place then.
are added to the list, and if a command gets an error code returned back from
the server, no more commands will be issued and libcurl will bail out with an
error code (CURLE_FTP_QUOTE_ERROR). Note that if you use CURLOPT_QUOTE to
send commands before a transfer, no transfer will actually take place when a
quote command has failed.
If you set the CURLOPT_HEADER to true, you will tell libcurl to get
information about the target file and output "headers" about it. The headers
will be in "HTTP-style", looking like they do in HTTP.
The option to enable headers or to run custom FTP commands may be useful to
combine with CURLOPT_NOBODY. If this option is set, no actual file content
transfer will be performed.
[ custom FTP commands without transfer, FTP "header-only", HTTP 1.0 ]
Cookies Without Chocolate Chips
[ set cookies, read cookies from file, cookie-jar ]
In the HTTP sense, a cookie is a name with an associated value. A server
sends the name and value to the client, and expects it to get sent back on
every subsequent request to the server that matches the particular conditions
set. The conditions include that the domain name and path match and that the
cookie hasn't become too old.
In real-world cases, servers send new cookies to replace existing one to
update them. Server use cookies to "track" users and to keep "sessions".
Cookies are sent from server to clients with the header Set-Cookie: and
they're sent from clients to servers with the Cookie: header.
To just send whatever cookie you want to a server, you can use CURLOPT_COOKIE
to set a cookie string like this:
curl_easy_setopt(easyhandle, CURLOPT_COOKIE, "name1=var1; name2=var2;");
In many cases, that is not enough. You might want to dynamicly save whatever
cookies the remote server passes to you, and make sure those cookies are then
use accordingly on later requests.
One way to do this, is to save all headers you receive in a plain file and
when you make a request, you tell libcurl to read the previous headers to
figure out which cookies to use. Set header file to read cookies from with
CURLOPT_COOKIEFILE.
The CURLOPT_COOKIEFILE option also automaticly enables the cookie parser in
libcurl. Until the cookie parser is enabled, libcurl will not parse or
understand incoming cookies and they will just be ignored. However, when the
parser is enabled the cookies will be understood and the cookies will be kept
in memory and used properly in subsequent requests when the same handle is
used. Many times this is enough, and you may not have to save the cookies to
disk at all. Note that the file you specify to CURLOPT_COOKIEFILE doesn't
have to exist to enable the parser, so a common way to just enable the parser
and not read able might be to use a file name you know doesn't exist.
If you rather use existing cookies that you've previously received with your
Netscape or Mozilla browsers, you can make libcurl use that cookie file as
input. The CURLOPT_COOKIEFILE is used for that too, as libcurl will
automaticly find out what kind of file it is and act accordingly.
The perhaps most advanced cookie operation libcurl offers, is saving the
entire internal cookie state back into a Netscape/Mozilla formatted cookie
file. We call that the cookie-jar. When you set a file name with
CURLOPT_COOKIEJAR, that file name will be created and all received cookies
will be stored in it when curl_easy_cleanup() is called. This enabled cookies
to get passed on properly between multiple handles without any information
getting lost.
Headers Equal Fun

View File

@@ -613,8 +613,8 @@ CURLcode curl_global_init(long flags);
void curl_global_cleanup(void);
/* This is the version number */
#define LIBCURL_VERSION "7.9.4"
#define LIBCURL_VERSION_NUM 0x070904
#define LIBCURL_VERSION "7.9.5-pre4"
#define LIBCURL_VERSION_NUM 0x070905
/* linked-list structure for the CURLOPT_QUOTE option (and other) */
struct curl_slist {

View File

@@ -2,18 +2,18 @@
# $Id$
#
AUTOMAKE_OPTIONS = foreign no-dependencies
AUTOMAKE_OPTIONS = foreign nostdinc
EXTRA_DIST = getdate.y \
Makefile.b32 Makefile.b32.resp Makefile.m32 Makefile.vc6 \
libcurl.def dllinit.c curllib.dsp curllib.dsw \
config-vms.h config-win32.h config-riscos.h config-mac.h
config-vms.h config-win32.h config-riscos.h config-mac.h \
config.h.in
lib_LTLIBRARIES = libcurl.la
INCLUDES = -I$(top_srcdir)/include
libcurl_la_LDFLAGS = -no-undefined -version-info 2:2:0
# This flag accepts an argument of the form current[:revision[:age]]. So,
# passing -version-info 3:12:1 sets current to 3, revision to 12, and age to

View File

@@ -364,8 +364,13 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
#endif
/* get the most strict timeout of the ones converted to milliseconds */
if(data->set.timeout &&
(data->set.timeout < data->set.connecttimeout))
if(data->set.timeout && data->set.connecttimeout) {
if (data->set.timeout < data->set.connecttimeout)
timeout_ms = data->set.timeout*1000;
else
timeout_ms = data->set.connecttimeout*1000;
}
else if(data->set.timeout)
timeout_ms = data->set.timeout*1000;
else
timeout_ms = data->set.connecttimeout*1000;

View File

@@ -50,7 +50,7 @@
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_WINSOCK_H
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
#include <winsock.h>
#endif

View File

@@ -2,26 +2,26 @@
# $Id$
#
# Some flags needed when trying to cause warnings ;-)
# CFLAGS = -g -DMALLOCDEBUG # -Wall -pedantic
#CPPFLAGS = -DGLOBURL -DCURL_SEPARATORS
AUTOMAKE_OPTIONS = foreign nostdinc
INCLUDES = -I$(top_srcdir)/include
bin_PROGRAMS = curl #memtest
noinst_HEADERS = setup.h \
#memtest_SOURCES = memtest.c
#memtest_LDADD = $(top_srcdir)/lib/libcurl.la
curl_SOURCES = main.c hugehelp.c urlglob.c writeout.c setup.h \
config-win32.h \
config-mac.h \
config-vms.h \
urlglob.h \
version.h \
writeout.h
writeout.h \
config-win32.h \
config-mac.h \
config-vms.h
#memtest_SOURCES = memtest.c
#memtest_LDADD = $(top_srcdir)/lib/libcurl.la
curl_SOURCES = main.c hugehelp.c urlglob.c writeout.c
curl_LDADD = ../lib/libcurl.la
curl_DEPENDENCIES = ../lib/libcurl.la
BUILT_SOURCES = hugehelp.c
@@ -35,8 +35,6 @@ EXTRA_DIST = mkhelp.pl curlmsg.msg \
macos/src/curl_GUSIConfig.cpp \
macos/src/macos_main.cpp
AUTOMAKE_OPTIONS = foreign no-dependencies
MANPAGE=$(top_srcdir)/docs/curl.1
README=$(top_srcdir)/docs/MANUAL
MKHELP=$(top_srcdir)/src/mkhelp.pl

View File

@@ -1176,8 +1176,8 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
config->postfields=postdata;
}
/* if(SetHTTPrequest(HTTPREQ_SIMPLEPOST, &config->httpreq))
return PARAM_BAD_USE;*/
if(SetHTTPrequest(HTTPREQ_SIMPLEPOST, &config->httpreq))
return PARAM_BAD_USE;
break;
case 'D':
/* dump-header to given file name */

View File

@@ -1,3 +1,3 @@
#define CURL_NAME "curl"
#define CURL_VERSION "7.9.5-pre1"
#define CURL_VERSION "7.9.5-pre4"
#define CURL_ID CURL_NAME " " CURL_VERSION " (" OS ") "

View File

@@ -46,6 +46,7 @@ typedef enum {
VAR_HEADER_SIZE,
VAR_REQUEST_SIZE,
VAR_EFFECTIVE_URL,
VAR_CONTENT_TYPE,
VAR_NUM_OF_VARS /* must be the last */
} replaceid;
@@ -69,6 +70,7 @@ static struct variable replacements[]={
{"size_upload", VAR_SIZE_UPLOAD},
{"speed_download", VAR_SPEED_DOWNLOAD},
{"speed_upload", VAR_SPEED_UPLOAD},
{"content_type", VAR_CONTENT_TYPE},
{NULL, 0}
};
@@ -165,6 +167,11 @@ void ourWriteOut(CURL *curl, char *writeinfo)
curl_easy_getinfo(curl, CURLINFO_SPEED_UPLOAD, &doubleinfo))
fprintf(stream, "%.3f", doubleinfo);
break;
case VAR_CONTENT_TYPE:
if(CURLE_OK ==
curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &stringp))
fputs(stringp, stream);
break;
default:
break;
}

View File

@@ -62,8 +62,10 @@ One regex per line that is removed from the protocol dumps before the
comparison is made. This is very useful to remove dependencies on dynamicly
changing protocol data such as port numbers or user-agent strings.
</strip>
<protocol>
the protocol dump curl should transmit
<protocol [nonewline=yes]>
the protocol dump curl should transmit, if 'nonewline' is set, we will cut
off the trailing newline of this given data before comparing with the one
actually sent by the client
</protocol>
<stdout>
This verfies that this data was passed to stdout.

View File

@@ -2,7 +2,7 @@ EXTRA_DIST = ftpserver.pl httpserver.pl httpsserver.pl runtests.pl \
ftpsserver.pl stunnel.pm getpart.pm FILEFORMAT README \
stunnel.pem
SUBDIRS = data
SUBDIRS = data server
PERLFLAGS = -I$(srcdir)
@@ -12,11 +12,11 @@ install:
curl:
@(cd ..; make)
test:
test: server/sws
@cd data && exec $(MAKE) test
srcdir=$(srcdir) $(PERL) $(PERLFLAGS) $(srcdir)/runtests.pl
quiet-test:
quiet-test: server/sws
@cd data && exec $(MAKE) test
srcdir=$(srcdir) $(PERL) $(PERLFLAGS) $(srcdir)/runtests.pl -s -a
@@ -24,3 +24,5 @@ clean:
rm -rf log
find . -name "*~" | xargs rm -f
server/sws:
cd server; make sws

View File

@@ -10,7 +10,7 @@
use curl with multiple request methods
</name>
<command>
-I -X FOOO localhost
-I -d FOOO localhost
</command>
</test>

View File

@@ -28,7 +28,7 @@ HTTP POST with user and password
<strip>
^User-Agent:.*
</strip>
<protocol>
<protocol nonewline=yes>
POST /3 HTTP/1.1
Authorization: Basic ZmFrZTotdXNlcg==
Host: 127.0.0.1:8999

View File

@@ -1,4 +1,4 @@
#!/usr/bin/perl
#!/usr/bin/env perl
# $Id$
#
# Main curl test script, in perl to run on more platforms
@@ -22,7 +22,7 @@ my $FTPSPORT=8821; # this is the FTPS server port
my $CURL="../src/curl"; # what curl executable to run on the tests
my $LOGDIR="log";
my $TESTDIR="data";
my $SERVERIN="$LOGDIR/http-request.dump"; # what curl sent the server
my $SERVERIN="$LOGDIR/server.input"; # what curl sent the server
my $CURLLOG="$LOGDIR/curl.log"; # all command lines run
my $FTPDCMD="$LOGDIR/ftpserver.cmd"; # copy ftp server instructions here
@@ -140,16 +140,27 @@ sub runhttpserver {
my $RUNNING;
my $pid;
$pid = checkserver ($HTTPPIDFILE);
# verify if our/any server is running on this port
my $data=`$CURL --silent -i $HOSTIP:$HOSTPORT/verifiedserver`;
if ( $data =~ /WE ROOLZ(: |)(\d*)/ ) {
if($2) {
$pid = 0+$2;
}
if(!$pid) {
print "Test server already running with unknown pid! Use it...\n";
return;
}
if($verbose) {
print "Test server already running with pid $pid, killing it...\n";
}
}
elsif($data ne "") {
print "GOT: $data\n";
print "An alien HTTP server is running on port $HOSTPORT\n",
"Edit runtests.pl to use another port and rerun the test script\n";
exit;
@@ -602,6 +613,15 @@ sub singletest {
my @protstrip=@protocol;
# check if there's any attributes on the verify/protocol section
my %hash = getpartattr("verify", "protocol");
if($hash{'nonewline'}) {
# Yes, we must cut off the final newline from the final line
# of the protocol data
chomp($protstrip[$#protstrip]);
}
for(@strip) {
# strip all patterns from both arrays
@out = striparray( $_, \@out);
@@ -835,36 +855,6 @@ if($testthis[0] ne "") {
$TESTCASES=join(" ", @testthis);
}
############################################################################
#
# don't let anyone think this works right now
print <<EOM
***************************************************************************
THIS DOES NOT WORK
***************************************************************************
Things in curl-land have changed, but the test suite has not been fixed
accordingly and thus, the test suite is currently more or less useless.
*PLEASE* help us fixing this. We have to make our new test server written
in C work and get used instead of the perl version previously used.
The working version of the test server is found in the tests/server
directory in the CVS tree.
If you run this in the tests/ directory and run the server in there, you
can actually get test-responses if you do like this:
\$ ./server/sws 8080 &
\$ curl localhost:8080/3
EOM
;
#######################################################################
# Output curl version and host info being tested
#

View File

@@ -1,16 +0,0 @@
CC = gcc
CFLAGS = -g -Wall
.PHONY: all clean
TARGET = sws
OBJS= sws.o getpart.o
all: $(TARGET)
$(TARGET): $(OBJS)
$(CC) $(LDFLAGS) -o $@ $^
clean:
-rm -f $(OBJS) *~ $(TARGET) core logfile

12
tests/server/Makefile.am Normal file
View File

@@ -0,0 +1,12 @@
# sws is the Silly Web Server
#
# Original http server code contributed by Georg Horn. Heavily modified since.
#
AUTOMAKE_OPTIONS = foreign
noinst_PROGRAMS = sws
sws_SOURCES= sws.c getpart.c
extra_DIST = config.h.in

2
tests/server/config.h.in Normal file
View File

@@ -0,0 +1,2 @@
#undef HAVE_SIGNAL

View File

@@ -7,6 +7,13 @@
#define EAT_SPACE(ptr) while( ptr && *ptr && isspace(*ptr) ) ptr++
#define EAT_WORD(ptr) while( ptr && *ptr && !isspace(*ptr) && ('>' != *ptr)) ptr++
#ifdef DEBUG
#define show(x) printf x
#else
#define show(x)
#endif
static
char *appendstring(char *string, /* original string */
char *buffer, /* to append */
int *stringlen, int *stralloc)
@@ -40,7 +47,6 @@ char *spitout(FILE *stream, char *main, char *sub, int *size)
char *string;
int stringlen=0;
int stralloc=256;
int len;
enum {
STATE_OUTSIDE,
@@ -60,9 +66,9 @@ char *spitout(FILE *stream, char *main, char *sub, int *size)
if('<' != *ptr) {
if(display) {
printf("=> %s", buffer);
show(("=> %s", buffer));
string = appendstring(string, buffer, &stringlen, &stralloc);
printf("* %s\n", buffer);
show(("* %s\n", buffer));
}
continue;
}
@@ -113,17 +119,17 @@ char *spitout(FILE *stream, char *main, char *sub, int *size)
}
if(display) {
string = appendstring(string, buffer, &stringlen, &stralloc);
printf("* %s\n", buffer);
show(("* %s\n", buffer));
}
if((STATE_INSUB == state) &&
!strcmp(cmain, main) &&
!strcmp(csub, sub)) {
printf("* (%d bytes) %s\n", stringlen, buffer);
show(("* (%d bytes) %s\n", stringlen, buffer));
display = 1; /* start displaying */
}
else {
printf("%d (%s/%s): %s\n", state, cmain, csub, buffer);
show(("%d (%s/%s): %s\n", state, cmain, csub, buffer));
display = 0; /* no display */
}
}

View File

@@ -5,19 +5,19 @@
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <getopt.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <assert.h>
char *spitout(FILE *stream, char *main, char *sub, int *size);
#define DEFAULT_PORT 8999
#ifndef DEFAULT_LOGFILE
#define DEFAULT_LOGFILE "/dev/null"
#define DEFAULT_LOGFILE "log/sws.log"
#endif
#define DOCBUFSIZE 4
@@ -25,11 +25,11 @@
#define VERSION "cURL test suite HTTP server/0.1"
#define REQUEST_DUMP "http-request.dump"
#define REQUEST_DUMP "log/server.input"
#define TEST_DATA_PATH "data/test%d"
static char *docfriends = "WE ROOLZ\r\n";
static char *docfriends = "HTTP/1.1 200 Mighty fine indeed\r\n\r\nWE ROOLZ\r\n";
static char *doc404 = "HTTP/1.1 404 Not Found\n"
"Server: " VERSION "\n"
"Connection: close\n"
@@ -56,7 +56,9 @@ static void logmsg(const char *msg)
strcpy(loctime, asctime(curr_time));
loctime[strlen(loctime) - 1] = '\0';
fprintf(logfp, "%s: pid %d: %s\n", loctime, getpid(), msg);
#ifdef DEBUG
fprintf(stderr, "%s: pid %d: %s\n", loctime, getpid(), msg);
#endif
fflush(logfp);
}
@@ -78,7 +80,7 @@ static void sigterm_handler(int sig)
int ProcessRequest(char *request)
{
char *line=request;
long contentlength=-1;
unsigned long contentlength=0;
#define END_OF_HEADERS "\r\n\r\n"
@@ -109,7 +111,7 @@ int ProcessRequest(char *request)
line++;
} while(line);
if(contentlength > -1 ) {
if(contentlength > 0 ) {
if(contentlength <= strlen(end+strlen(END_OF_HEADERS)))
return 1; /* done */
else
@@ -123,7 +125,7 @@ void storerequest(char *reqbuf)
{
FILE *dump;
dump = fopen(REQUEST_DUMP, "wb"); /* b is for windows-preparing */
dump = fopen(REQUEST_DUMP, "ab"); /* b is for windows-preparing */
if(dump) {
fwrite(reqbuf, 1, strlen(reqbuf), dump);
@@ -133,15 +135,23 @@ void storerequest(char *reqbuf)
}
#define REQBUFSIZ 4096
#define MAXDOCNAMELEN 1024
#define REQBUFSIZ 50000
#define REQBUFSIZ_TXT "49999"
/* very-big-path support */
#define MAXDOCNAMELEN 40000
#define MAXDOCNAMELEN_TXT "39999"
#define REQUEST_KEYWORD_SIZE 256
static int get_request(int sock)
static int get_request(int sock, int *part)
{
char reqbuf[REQBUFSIZ], doc[MAXDOCNAMELEN];
char request[REQUEST_KEYWORD_SIZE];
static char reqbuf[REQBUFSIZ], doc[MAXDOCNAMELEN];
static char request[REQUEST_KEYWORD_SIZE];
unsigned int offset = 0;
int prot_major, prot_minor;
char logbuf[256];
*part = 0; /* part zero equals none */
while (offset < REQBUFSIZ) {
int got = recv(sock, reqbuf + offset, REQBUFSIZ - offset, 0);
@@ -172,7 +182,7 @@ static int get_request(int sock)
/* dump the request to an external file */
storerequest(reqbuf);
if (sscanf(reqbuf, "%s %s HTTP/%d.%d",
if (sscanf(reqbuf, "%" REQBUFSIZ_TXT"s %" MAXDOCNAMELEN_TXT "s HTTP/%d.%d",
request,
doc,
&prot_major,
@@ -185,13 +195,31 @@ static int get_request(int sock)
/* get the number after it */
if(ptr) {
if(!strcmp("/verifiedserver", ptr)) {
if((strlen(doc) + strlen(request)) < 200)
sprintf(logbuf, "Got request: %s %s HTTP/%d.%d",
request, doc, prot_major, prot_minor);
else
sprintf(logbuf, "Got a *HUGE* request HTTP/%d.%d",
prot_major, prot_minor);
logmsg(logbuf);
if(!strncmp("/verifiedserver", ptr, 15)) {
logmsg("Are-we-friendly question received");
return -2;
}
test_no = strtol(ptr+1, &ptr, 10);
logmsg("Found test number in PATH");
ptr++; /* skip the slash */
test_no = strtol(ptr, &ptr, 10);
if(test_no > 10000) {
*part = test_no % 10000;
test_no /= 10000;
}
sprintf(logbuf, "Found test number %d in path", test_no);
logmsg(logbuf);
}
else {
@@ -207,15 +235,18 @@ static int get_request(int sock)
}
static int send_doc(int sock, int doc)
static int send_doc(int sock, int doc, int part_no)
{
int written;
int count;
char *buffer;
char *ptr;
FILE *stream;
char *cmd=NULL;
int cmdsize;
char filename[256];
char partbuf[80]="data";
if(doc < 0) {
if(-2 == doc)
@@ -225,8 +256,15 @@ static int send_doc(int sock, int doc)
buffer = doc404;
ptr = NULL;
stream=NULL;
count = strlen(buffer);
}
else {
if(0 != part_no) {
sprintf(partbuf, "data%d", part_no);
}
sprintf(filename, TEST_DATA_PATH, doc);
stream=fopen(filename, "rb");
@@ -234,14 +272,27 @@ static int send_doc(int sock, int doc)
logmsg("Couldn't open test file");
return 0;
}
else {
ptr = buffer = spitout(stream, "reply", partbuf, &count);
fclose(stream);
}
ptr = buffer = spitout(stream, "reply", "data", &count);
/* re-open the same file again */
stream=fopen(filename, "rb");
if(!stream) {
logmsg("Couldn't open test file");
return 0;
}
else {
/* get the custom server control "commands" */
cmd = spitout(stream, "reply", "postcmd", &cmdsize);
fclose(stream);
}
}
do {
written = send(sock, buffer, count, 0);
if (written < 0) {
fclose(stream);
return -1;
}
count -= written;
@@ -250,8 +301,28 @@ static int send_doc(int sock, int doc)
if(ptr)
free(ptr);
if(stream)
fclose(stream);
if(cmdsize > 0 ) {
char command[32];
int num;
char *ptr=cmd;
do {
if(2 == sscanf(ptr, "%31s %d", command, &num)) {
if(!strcmp("wait", command))
sleep(num); /* wait this many seconds */
else {
logmsg("Unknown command in reply command section");
}
}
ptr = strchr(ptr, '\n');
if(ptr)
ptr++;
else
ptr = NULL;
} while(ptr && *ptr);
}
if(cmd)
free(cmd);
return 0;
}
@@ -262,12 +333,12 @@ int main(int argc, char *argv[])
int sock, msgsock, flag;
unsigned short port = DEFAULT_PORT;
char *logfile = DEFAULT_LOGFILE;
int part_no;
FILE *pidfile;
if(argc>1)
port = atoi(argv[1]);
logfile = "logfile";
/* FIX: write our pid to a file name */
logfp = fopen(logfile, "a");
@@ -276,6 +347,8 @@ int main(int argc, char *argv[])
exit(1);
}
#ifdef HAVE_SIGNAL
/* FIX: make a more portable signal handler */
signal(SIGPIPE, sigpipe_handler);
signal(SIGINT, sigterm_handler);
signal(SIGTERM, sigterm_handler);
@@ -283,6 +356,7 @@ int main(int argc, char *argv[])
siginterrupt(SIGPIPE, 1);
siginterrupt(SIGINT, 1);
siginterrupt(SIGTERM, 1);
#endif
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
@@ -309,10 +383,18 @@ int main(int argc, char *argv[])
exit(1);
}
pidfile = fopen(".http.pid", "w");
if(pidfile) {
fprintf(pidfile, "%d\n", (int)getpid());
fclose(pidfile);
}
else
fprintf(stderr, "Couldn't write pid file\n");
/* start accepting connections */
listen(sock, 5);
printf("*** %s listening on port %u ***\n", VERSION, port);
fprintf(stderr, "*** %s listening on port %u ***\n", VERSION, port);
while (!sigterm) {
int doc;
@@ -329,8 +411,8 @@ int main(int argc, char *argv[])
logmsg("New client connected");
doc = get_request(msgsock);
send_doc(msgsock, doc);
doc = get_request(msgsock, &part_no);
send_doc(msgsock, doc, part_no);
close(msgsock);
}