Compare commits
39 Commits
curl-7_7_2
...
curl-7_7_3
Author | SHA1 | Date | |
---|---|---|---|
![]() |
3654bd1b56 | ||
![]() |
237edbc9d8 | ||
![]() |
4127903183 | ||
![]() |
2ffc20dc7c | ||
![]() |
a2a446cb2f | ||
![]() |
9304055df5 | ||
![]() |
53e0c1b1a6 | ||
![]() |
4efa1e8e4c | ||
![]() |
ecba113125 | ||
![]() |
350c536f6c | ||
![]() |
a33eb9881c | ||
![]() |
bbe8aa073e | ||
![]() |
14521b418e | ||
![]() |
73982c65d2 | ||
![]() |
2eb94acb95 | ||
![]() |
6a80fb3482 | ||
![]() |
26d4c80049 | ||
![]() |
3974f30ed4 | ||
![]() |
44c246dbf2 | ||
![]() |
ef07903a51 | ||
![]() |
a7dc45997f | ||
![]() |
583c2e2f09 | ||
![]() |
90cce2ae3a | ||
![]() |
775dc07eb5 | ||
![]() |
a652db18bd | ||
![]() |
48f3feed59 | ||
![]() |
4ddb3fbbf4 | ||
![]() |
cc872ebc19 | ||
![]() |
ba46006896 | ||
![]() |
0b7e0638a9 | ||
![]() |
be49b01952 | ||
![]() |
8d0c1d5495 | ||
![]() |
2769a9ab0b | ||
![]() |
8ea5b5bbd0 | ||
![]() |
0ce49cb7ed | ||
![]() |
d802dfe86a | ||
![]() |
aabc0c08a1 | ||
![]() |
476addb9c1 | ||
![]() |
37d7a198d5 |
55
CHANGES
55
CHANGES
@@ -6,6 +6,61 @@
|
||||
|
||||
History of Changes
|
||||
|
||||
Version 7.7.3-pre1
|
||||
|
||||
Daniel (4 May 2001)
|
||||
- All callback functions now take 'void *' instead of 'FILE *'. This is made
|
||||
this way to make it more obvious to people that anything can be passed to
|
||||
them (by using the apropriate option). After discussions with Sterling
|
||||
Hughes.
|
||||
|
||||
Daniel (3 May 2001)
|
||||
- Cris Bailiff fixed a chunked transfer encoding problem with persistent
|
||||
connection that made libcurl fail if the persistent connection used mixed
|
||||
chunked and non-chunked transfers.
|
||||
|
||||
- Cris Bailiff fixed a bad treatment of 304-replies, as they would not be
|
||||
treated as content-length 0 replies but would cause a "hang" until the
|
||||
server timed-out and closed the connection.
|
||||
|
||||
- Brad Burdick found a minor problem in the docs/examples/Makefile.am
|
||||
|
||||
Daniel (27 April 2001)
|
||||
- Updated the INTERALS document again. It was lagging a bit. I think I made it
|
||||
more easy to follow now as well.
|
||||
|
||||
- Brad Burdick found a problem with persistent connections when curl received
|
||||
a "Content-Length: 0" header.
|
||||
|
||||
- Giuseppe D'Ambrosio was first out to report that TELNET doesn't work in curl
|
||||
compiled/built on win32. It seems to work for unixes though!
|
||||
|
||||
- Dave Hamilton reported weird problems with CURL/PHP that I really can't
|
||||
explain at the moment. I'm hoping on some help from the PHP crew.
|
||||
|
||||
Daniel (26 April 2001)
|
||||
- I rewrote the FTP command response function. I had to do it to make ftps
|
||||
work, as the OpenSSL read()-function didn't work the same way the normal
|
||||
unix read() does, but it was also a huge performance boost. Previously the
|
||||
function read one byte at a time, now it reads very large chunks, and it
|
||||
makes a notable speed difference.
|
||||
|
||||
Daniel (25 April 2001)
|
||||
- Connection re-use when not using a proxy didn't work properly for
|
||||
non-default port numbers.
|
||||
|
||||
Daniel (24 April 2001)
|
||||
- I've noticed that FTPS doesn't work. We attempt to use ssl even for the
|
||||
data transfer, which causes the transfer to 'hang'... We need to fix this.
|
||||
|
||||
- Improved the test suite to use 'stunnel' to do HTTPS and FTPS testing on
|
||||
the alredy written perl servers easily.
|
||||
|
||||
Daniel (23 April 2001)
|
||||
- The OpenSSL version string recently modified didn't zero terminate one
|
||||
of the generated strings properly, which could lead to a crash or simply
|
||||
weird version string output!
|
||||
|
||||
Version 7.7.2
|
||||
|
||||
Daniel (22 April 2001)
|
||||
|
7
CVS-INFO
7
CVS-INFO
@@ -17,6 +17,8 @@ inner sanctum.
|
||||
memanalyze.pl is for analyzing the output generated by curl if -DMALLOCDEBUG
|
||||
is used when compiling
|
||||
|
||||
buildconf builds the makefiles and configure stuff
|
||||
|
||||
Makefile.dist is included as the root Makefile in distribution archives
|
||||
|
||||
perl/contrib/ is a subdirectory with various perl scripts
|
||||
@@ -25,9 +27,6 @@ inner sanctum.
|
||||
|
||||
To build after having extracted everything from CVS, do this:
|
||||
|
||||
automake
|
||||
aclocal
|
||||
autoheader
|
||||
autoconf
|
||||
./buildconf
|
||||
./configure
|
||||
make
|
||||
|
2
README
2
README
@@ -12,7 +12,7 @@ README
|
||||
document.
|
||||
|
||||
libcurl is a library that Curl is using to do its job. It is readily
|
||||
available to be used by your software. Read the LIBCURL document to
|
||||
available to be used by your software. Read the libcurl.5 man page to
|
||||
find out how!
|
||||
|
||||
You find answers to the most frequent questions we get in the FAQ document.
|
||||
|
6
buildconf
Executable file
6
buildconf
Executable file
@@ -0,0 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
automake
|
||||
aclocal
|
||||
autoheader
|
||||
autoconf
|
@@ -237,7 +237,7 @@ IBM OS/2
|
||||
If you want to build with OpenSSL or OpenLDAP support, you'll need to
|
||||
download those libraries, too. Dirk Ohme has done some work to port SSL
|
||||
libraries under OS/2, but it looks like he doesn't care about emx. You'll
|
||||
find his patches on: http://come.to/Dirk.Ohme
|
||||
find his patches on: http://come.to/Dirk_Ohme
|
||||
|
||||
If during the linking you get an error about _errno being an undefined
|
||||
symbol referenced from the text segment, you need to add -D__ST_MT_ERRNO__
|
||||
|
@@ -1,4 +1,4 @@
|
||||
Updated for curl 7.7 on March 13, 2001
|
||||
Updated for curl 7.7.2 on April 26, 2001
|
||||
_ _ ____ _
|
||||
___| | | | _ \| |
|
||||
/ __| | | | |_) | |
|
||||
@@ -73,7 +73,7 @@ Library
|
||||
makes sure we stay absolutely platform independent.
|
||||
|
||||
curl_easy_init() allocates an internal struct and makes some initializations.
|
||||
The returned handle does not revail internals.
|
||||
The returned handle does not reveal internals.
|
||||
|
||||
curl_easy_setopt() takes a three arguments, where the option stuff must be
|
||||
passed in pairs, the parameter-ID and the parameter-value. The list of
|
||||
@@ -81,33 +81,68 @@ Library
|
||||
|
||||
curl_easy_perform() does a whole lot of things:
|
||||
|
||||
It starts off in the lib/easy.c file by calling curl_transfer(), but the main
|
||||
work is lib/url.c. The function first analyzes the URL, it separates the
|
||||
different components and connects to the remote host. This may involve using
|
||||
a proxy and/or using SSL. The Curl_gethost() function in lib/hostip.c is used
|
||||
for looking up host names.
|
||||
It starts off in the lib/easy.c file by calling Curl_perform() and the main
|
||||
work then continues lib/url.c. The flow continues with a call to
|
||||
Curl_connect() to connect to the remote site.
|
||||
|
||||
When connected, the proper protocol-specific function is called. The
|
||||
functions are named after the protocols they handle. Curl_ftp(), Curl_http(),
|
||||
Curl_dict(), etc. They all reside in their respective files (ftp.c, http.c
|
||||
and dict.c).
|
||||
o Curl_connect()
|
||||
|
||||
... analyzes the URL, it separates the different components and connects to
|
||||
the remote host. This may involve using a proxy and/or using SSL. The
|
||||
Curl_gethost() function in lib/hostip.c is used for looking up host names.
|
||||
|
||||
When Curl_connect is done, we are connected to the remote site. Then it is
|
||||
time to tell the server to get a document/file. Curl_do() arranges this.
|
||||
|
||||
o Curl_do()
|
||||
|
||||
Curl_do() makes sure the proper protocol-specific function is called. The
|
||||
functions are named after the protocols they handle. Curl_ftp(),
|
||||
Curl_http(), Curl_dict(), etc. They all reside in their respective files
|
||||
(ftp.c, http.c and dict.c).
|
||||
|
||||
The protocol-specific functions of course deal with protocol-specific
|
||||
negotiations and setup. They have access to the Curl_sendf() (from
|
||||
lib/sendf.c) function to send printf-style formatted data to the remote host
|
||||
and when they're ready to make the actual file transfer they call the
|
||||
lib/sendf.c) function to send printf-style formatted data to the remote
|
||||
host and when they're ready to make the actual file transfer they call the
|
||||
Curl_Transfer() function (in lib/transfer.c) to setup the transfer and
|
||||
returns. Curl_perform() then calls Transfer() in lib/transfer.c that performs
|
||||
the entire file transfer. Curl_perform() is what does the main "connect - do
|
||||
- transfer - done" loop. It loops if there's a Location: to follow.
|
||||
returns.
|
||||
|
||||
o Transfer()
|
||||
|
||||
Curl_perform() then calls Transfer() in lib/transfer.c that performs
|
||||
the entire file transfer.
|
||||
|
||||
During transfer, the progress functions in lib/progress.c are called at a
|
||||
frequent interval (or at the user's choice, a specified callback might get
|
||||
called). The speedcheck functions in lib/speedcheck.c are also used to verify
|
||||
that the transfer is as fast as required.
|
||||
called). The speedcheck functions in lib/speedcheck.c are also used to
|
||||
verify that the transfer is as fast as required.
|
||||
|
||||
o Curl_done()
|
||||
|
||||
Called after a transfer is done. This function takes care of everything
|
||||
that has to be done after a transfer. This function attempts to leave
|
||||
matters in a state so that Curl_do() should be possible to call again on
|
||||
the same connection (in a persistent connection case). It may also soon be
|
||||
closed with Curl_disconnect().
|
||||
|
||||
o Curl_disconnect()
|
||||
|
||||
During normal connection and transfers, no one ever tries to close any
|
||||
connection so this is not normally called when curl_easy_perform() is
|
||||
used. This function is only used when we are certain that no more transfers
|
||||
is going to be made on the connection (it can be also closed by
|
||||
force). This function can also be called at times to make sure that libcurl
|
||||
doesn't keep too many connections alive at the same time.
|
||||
|
||||
This function cleans up all resources that are associated with a single
|
||||
connection.
|
||||
|
||||
Curl_perform() is the function that does the main "connect - do - transfer -
|
||||
done" loop. It loops if there's a Location: to follow.
|
||||
|
||||
When completed, the curl_easy_cleanup() should be called to free up used
|
||||
resources.
|
||||
resources. It runs Curl_disconnect() on all open connectons.
|
||||
|
||||
A quick roundup on internal function sequences (many of these call
|
||||
protocol-specific function-pointers):
|
||||
@@ -257,6 +292,7 @@ Client
|
||||
======
|
||||
|
||||
main() resides in src/main.c together with most of the client code.
|
||||
|
||||
src/hugehelp.c is automatically generated by the mkhelp.pl perl script to
|
||||
display the complete "manual" and the src/urlglob.c file holds the functions
|
||||
used for the URL-"globbing" support. Globbing in the sense that the {} and []
|
||||
@@ -272,25 +308,26 @@ Client
|
||||
curl_easy_getinfo() function to extract useful information from the curl
|
||||
session.
|
||||
|
||||
Recent versions may loop and do all that several times if many URLs were
|
||||
Recent versions may loop and do all this several times if many URLs were
|
||||
specified on the command line or config file.
|
||||
|
||||
Memory Debugging
|
||||
================
|
||||
|
||||
The file named lib/memdebug.c contains debug-versions of a few
|
||||
functions. Functions such as malloc, free, fopen, fclose, etc that somehow
|
||||
deal with resources that might give us problems if we "leak" them. The
|
||||
functions in the memdebug system do nothing fancy, they do their normal
|
||||
function and then log information about what they just did. The logged data
|
||||
can then be analyzed after a complete session,
|
||||
The file lib/memdebug.c contains debug-versions of a few functions. Functions
|
||||
such as malloc, free, fopen, fclose, etc that somehow deal with resources
|
||||
that might give us problems if we "leak" them. The functions in the memdebug
|
||||
system do nothing fancy, they do their normal function and then log
|
||||
information about what they just did. The logged data can then be analyzed
|
||||
after a complete session,
|
||||
|
||||
memanalyze.pl is a perl script present only present in CVS (not part of the
|
||||
memanalyze.pl is the perl script present only present in CVS (not part of the
|
||||
release archives) that analyzes a log file generated by the memdebug
|
||||
system. It detects if resources are allocated but never freed and other kinds
|
||||
of errors related to resource management.
|
||||
|
||||
Use -DMALLOCDEBUG when compiling to enable memory debugging.
|
||||
Use -DMALLOCDEBUG when compiling to enable memory debugging, this is also
|
||||
switched on by running configure with --enable-debug.
|
||||
|
||||
Test Suite
|
||||
==========
|
||||
|
@@ -23,7 +23,7 @@ man_MANS = \
|
||||
curl_unescape.3 \
|
||||
curl_strequal.3 \
|
||||
curl_strnequal.3 \
|
||||
curl_printf.3 \
|
||||
curl_mprintf.3 \
|
||||
libcurl.5
|
||||
|
||||
EXTRA_DIST = $(man_MANS) \
|
||||
|
@@ -22,3 +22,8 @@ README.win32
|
||||
in order to extract a separate text file:
|
||||
|
||||
curl -M >manual.txt
|
||||
|
||||
Download all the libcurl man pages in HTML format using the link on the
|
||||
bottom of this page:
|
||||
|
||||
http://curl.haxx.se/libcurl/c/
|
||||
|
@@ -825,6 +825,8 @@ If you do find bugs, mail them to curl-bug@haxx.se.
|
||||
- Frederic Lepied <flepied@mandrakesoft.com>
|
||||
- Georg Horn <horn@koblenz-net.de>
|
||||
- Cris Bailiff <c.bailiff@awayweb.com>
|
||||
- Sterling Hughes <sterling@designmultimedia.com>
|
||||
- S. Moonesamy
|
||||
|
||||
.SH WWW
|
||||
http://curl.haxx.se
|
||||
|
@@ -42,54 +42,43 @@ call.
|
||||
These options are in a bit of random order, but you'll figure it out!
|
||||
.TP 0.8i
|
||||
.B CURLOPT_FILE
|
||||
Data pointer to pass instead of FILE * to the file write function. Note that
|
||||
if you specify the
|
||||
Data pointer to pass to file write function. Note that if you specify the
|
||||
.I CURLOPT_WRITEFUNCTION
|
||||
, this is the pointer you'll get as input.
|
||||
, this is the pointer you'll get as input. If you don't use a callback, you
|
||||
must pass a 'FILE *' as libcurl passes it to fwrite() when writing data.
|
||||
|
||||
NOTE: If you're using libcurl as a win32 .DLL, you MUST use a
|
||||
.I CURLOPT_WRITEFUNCTION
|
||||
if you set the
|
||||
.I CURLOPT_FILE
|
||||
option.
|
||||
NOTE: If you're using libcurl as a win32 DLL, you MUST use the
|
||||
\fICURLOPT_WRITEFUNCTION\fP if you set this option.
|
||||
.TP
|
||||
.B CURLOPT_WRITEFUNCTION
|
||||
Function pointer that should match the following prototype:
|
||||
.BI "size_t function( void *ptr, size_t size, size_t nmemb, FILE *stream);"
|
||||
.BI "size_t function( void *ptr, size_t size, size_t nmemb, void *stream);"
|
||||
This function gets called by libcurl as soon as there is received data that
|
||||
needs to be written down. The size of the data pointed to by
|
||||
.I ptr
|
||||
is
|
||||
.I size
|
||||
multiplied with
|
||||
.I nmemb.
|
||||
Return the number of bytes actually written or return -1 to signal error to the library (it will cause it to abort the transfer).
|
||||
needs to be written down. The size of the data pointed to by \fIptr\fP is
|
||||
\fIsize\fP multiplied with \fInmemb\fP. Return the number of bytes actually
|
||||
written or return -1 to signal error to the library (it will cause it to abort
|
||||
the transfer with CURLE_WRITE_ERROR).
|
||||
|
||||
Set the \fIstream\fP argument with the \fBCURLOPT_FILE\fP option.
|
||||
.TP
|
||||
.B CURLOPT_INFILE
|
||||
Data pointer to pass instead of FILE * to the file read function. Note that if
|
||||
you specify the
|
||||
.I CURLOPT_READFUNCTION
|
||||
, this is the pointer you'll get as input.
|
||||
Data pointer to pass to the file read function. Note that if you specify the
|
||||
\fICURLOPT_READFUNCTION\fP, this is the pointer you'll get as input. If you
|
||||
don't specify a read callback, this must be a valid FILE *.
|
||||
|
||||
NOTE: If you're using libcurl as a win32 .DLL, you MUST use a
|
||||
.I CURLOPT_READFUNCTION
|
||||
if you set the
|
||||
.I CURLOPT_INFILE
|
||||
option.
|
||||
NOTE: If you're using libcurl as a win32 DLL, you MUST use a
|
||||
\fICURLOPT_READFUNCTION\fP if you set this option.
|
||||
.TP
|
||||
.B CURLOPT_READFUNCTION
|
||||
Function pointer that should match the following prototype:
|
||||
.BI "size_t function( void *ptr, size_t size, size_t nmemb, FILE *stream);"
|
||||
.BI "size_t function( void *ptr, size_t size, size_t nmemb, void *stream);"
|
||||
This function gets called by libcurl as soon as it needs to read data in order
|
||||
to send it to the peer. The data area pointed at by the pointer
|
||||
.I ptr
|
||||
may be filled with at most
|
||||
.I size
|
||||
multiplied with
|
||||
.I nmemb
|
||||
number of bytes. Your function must return the actual number of bytes that you
|
||||
stored in that memory area. Returning -1 will signal an error to the library
|
||||
and cause it to abort the current transfer immediately.
|
||||
to send it to the peer. The data area pointed at by the pointer \fIptr\fP may
|
||||
be filled with at most \fIsize\fP multiplied with \fInmemb\fP number of
|
||||
bytes. Your function must return the actual number of bytes that you stored in
|
||||
that memory area. Returning -1 will signal an error to the library and cause
|
||||
it to abort the current transfer immediately (with a CURLE_READ_ERROR return
|
||||
code).
|
||||
.TP
|
||||
.B CURLOPT_INFILESIZE
|
||||
When uploading a file to a remote site, this option should be used to tell
|
||||
@@ -317,16 +306,15 @@ struct curl_slist structs properly filled in as described for
|
||||
.I "CURLOPT_QUOTE"
|
||||
.TP
|
||||
.B CURLOPT_WRITEHEADER
|
||||
Pass a FILE * to be used to write the header part of the received data to. The
|
||||
headers are guaranteed to be written one-by-one to this file handle and only
|
||||
complete lines are written. Parsing headers should be easy enough using
|
||||
this. See also the
|
||||
.I CURLOPT_HEADERFUNCTION
|
||||
option.
|
||||
Pass a pointer to be used to write the header part of the received data to. If
|
||||
you don't use a callback to take care of the writing, this must be a FILE
|
||||
*. The headers are guaranteed to be written one-by-one and only complete lines
|
||||
are written. Parsing headers should be easy enough using this. See also the
|
||||
\fICURLOPT_HEADERFUNCTION\fP option.
|
||||
.TP
|
||||
.B CURLOPT_HEADERFUNCTION
|
||||
Function pointer that should match the following prototype:
|
||||
.BI "size_t function( void *ptr, size_t size, size_t nmemb, FILE *stream);"
|
||||
.BI "size_t function( void *ptr, size_t size, size_t nmemb, void *stream);"
|
||||
This function gets called by libcurl as soon as there is received header data
|
||||
that needs to be written down. The function will be called once for each
|
||||
header with a complete header line in each invoke. The size of the data
|
||||
|
@@ -2,7 +2,7 @@
|
||||
.\" nroff -man [file]
|
||||
.\" Written by daniel@haxx.se
|
||||
.\"
|
||||
.TH curl_formparse 3 "5 March 2001" "libcurl 7.0" "libcurl Manual"
|
||||
.TH curl_formparse 3 "3 May 2001" "libcurl 7.7.2" "libcurl Manual"
|
||||
.SH NAME
|
||||
curl_formparse - add a section to a multipart/formdata HTTP POST
|
||||
.SH SYNOPSIS
|
||||
@@ -13,15 +13,20 @@ curl_formparse - add a section to a multipart/formdata HTTP POST
|
||||
.ad
|
||||
.SH DESCRIPTION
|
||||
curl_formparse() is used to append sections when building a multipart/formdata
|
||||
HTTP POST. Append one section at a time until you've added all the sections
|
||||
you want included and then you pass the
|
||||
.I firstitem
|
||||
pointer as parameter to CURLOPT_HTTPPOST.
|
||||
.I lastitem
|
||||
is set after each call and on repeated invokes it should be left as set to
|
||||
allow repeated invokes to find the end of the list in a faster way.
|
||||
.I string
|
||||
must be a zero terminated string following the following syntax.
|
||||
HTTP POST (sometimes refered to as rfc1867-style posts). Append one section at
|
||||
a time until you've added all the sections you want included and then you pass
|
||||
the \fI firstitem\fP pointer as parameter to \fBCURLOPT_HTTPPOST\fP.
|
||||
\fIlastitem\fP is set after each call and on repeated invokes it should be
|
||||
left as set to allow repeated invokes to find the end of the list in a faster
|
||||
way. \fIstring\fP must be a zero terminated string abiding to the syntax
|
||||
described in a section below
|
||||
|
||||
The pointers \fIfirstitem\fP and \fIlastitem\fP point to, should both be
|
||||
pointers to NULL in the first call to this function. All list-data will be
|
||||
allocated by the function itself. You must call \fIcurl_formfree\fP after the
|
||||
form post has been done to free the resources again.
|
||||
|
||||
See example below.
|
||||
.SH "FORM PARSE STRINGS"
|
||||
The
|
||||
.I string
|
||||
@@ -55,6 +60,18 @@ content-type for all of them in the same way as with a single file.
|
||||
.PP
|
||||
.SH RETURN VALUE
|
||||
Returns non-zero if an error occurs.
|
||||
.SH EXAMPLE
|
||||
|
||||
HttpPost* post = NULL;
|
||||
HttpPost* last = NULL;
|
||||
|
||||
/* Add an image section */
|
||||
curl_formparse("picture=@my-face.jpg", &post, &last);
|
||||
/* Add a normal text section */
|
||||
curl_formparse("name=FooBar", &post, &last);
|
||||
/* Set the form info */
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPPOST, post);
|
||||
|
||||
.SH "SEE ALSO"
|
||||
.BR curl_easy_setopt "(3) "
|
||||
.SH BUGS
|
||||
|
@@ -4,9 +4,9 @@
|
||||
|
||||
AUTOMAKE_OPTIONS = foreign no-dependencies
|
||||
|
||||
EXTRA_DIST =
|
||||
README curlgtk.c sepheaders.c simple.c postit.c \
|
||||
win32sockets.c persistant.c ftpget.c Makefile.example
|
||||
EXTRA_DIST = README curlgtk.c sepheaders.c simple.c postit.c \
|
||||
win32sockets.c persistant.c ftpget.c Makefile.example \
|
||||
multithread.c
|
||||
|
||||
all:
|
||||
@echo "done"
|
||||
|
70
docs/examples/multithread.c
Normal file
70
docs/examples/multithread.c
Normal file
@@ -0,0 +1,70 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/* A multi-threaded example that uses pthreads extensively to fetch
|
||||
* X remote files at once */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <pthread.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
/* silly list of test-URLs */
|
||||
char *urls[]= {
|
||||
"http://curl.haxx.se/",
|
||||
"ftp://cool.haxx.se/",
|
||||
"http://www.contactor.se/",
|
||||
"www.haxx.se"
|
||||
};
|
||||
|
||||
void *pull_one_url(void *url)
|
||||
{
|
||||
CURL *curl;
|
||||
|
||||
curl = curl_easy_init();
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, url);
|
||||
curl_easy_perform(curl);
|
||||
|
||||
curl_easy_cleanup(curl);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
int pthread_create(pthread_t *new_thread_ID,
|
||||
const pthread_attr_t *attr,
|
||||
void * (*start_func)(void *), void *arg);
|
||||
*/
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
pthread_t tid[4];
|
||||
int i;
|
||||
int error;
|
||||
for(i=0; i< 4; i++) {
|
||||
error = pthread_create(&tid[i],
|
||||
NULL, /* default attributes please */
|
||||
pull_one_url,
|
||||
urls[i]);
|
||||
if(0 != error)
|
||||
fprintf(stderr, "Couldn't run thread number %d, errno %d\n", i, error);
|
||||
else
|
||||
fprintf(stderr, "Thread %d, gets %s\n", i, urls[i]);
|
||||
}
|
||||
|
||||
/* now wait for all threads to terminate */
|
||||
for(i=0; i< 4; i++) {
|
||||
error = pthread_join(tid[i], NULL);
|
||||
fprintf(stderr, "Thread %d terminated\n", i);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@@ -1,8 +1,8 @@
|
||||
.\" You can view this file with:
|
||||
.\" nroff -man libcurl.5
|
||||
.\" nroff -man [file]
|
||||
.\" Written by Daniel Stenberg
|
||||
.\"
|
||||
.TH libcurl 5 "20 April 2001" "libcurl 7.7.2" "libcurl overview"
|
||||
.TH libcurl 5 "23 April 2001" "libcurl 7.7.2" "libcurl overview"
|
||||
.SH NAME
|
||||
libcurl \- client-side URL transfers
|
||||
.SH DESCRIPTION
|
||||
@@ -64,6 +64,12 @@ builds a linked list
|
||||
.TP
|
||||
.B curl_slist_free_all()
|
||||
frees a whole curl_slist
|
||||
.TP
|
||||
.B curl_mprintf()
|
||||
portable printf() functions
|
||||
.TP
|
||||
.B curl_streual()
|
||||
portable case insensitive string comparisons
|
||||
.RE
|
||||
|
||||
.SH "LINKING WITH LIBCURL"
|
||||
@@ -120,5 +126,5 @@ Note that the options set with curl_easy_setopt() will be used in on every
|
||||
repeat curl_easy_perform() call
|
||||
.SH "COMPATIBILITY WITH OLDER LIBCURLS"
|
||||
Repeated curl_easy_perform() calls on the same handle were not supported in
|
||||
pre-7.7 versions, and caused confusion and defined behaviour.
|
||||
pre-7.7 versions, and caused confusion and undefined behaviour.
|
||||
|
||||
|
@@ -76,12 +76,12 @@ typedef int (*curl_progress_callback)(void *clientp,
|
||||
typedef size_t (*curl_write_callback)(char *buffer,
|
||||
size_t size,
|
||||
size_t nitems,
|
||||
FILE *outstream);
|
||||
void *outstream);
|
||||
|
||||
typedef size_t (*curl_read_callback)(char *buffer,
|
||||
size_t size,
|
||||
size_t nitems,
|
||||
FILE *instream);
|
||||
void *instream);
|
||||
|
||||
typedef int (*curl_passwd_callback)(void *clientp,
|
||||
char *prompt,
|
||||
@@ -173,7 +173,7 @@ typedef enum {
|
||||
typedef enum {
|
||||
CINIT(NOTHING, LONG, 0), /********* the first one is unused ************/
|
||||
|
||||
/* This is the FILE * the regular output should be written to. */
|
||||
/* This is the FILE * or void * the regular output should be written to. */
|
||||
CINIT(FILE, OBJECTPOINT, 1),
|
||||
|
||||
/* The full URL to get/put */
|
||||
@@ -276,7 +276,8 @@ typedef enum {
|
||||
/* send linked-list of QUOTE commands */
|
||||
CINIT(QUOTE, OBJECTPOINT, 28),
|
||||
|
||||
/* send FILE * to store headers to */
|
||||
/* send FILE * or void * to store headers to, if you use a callback it
|
||||
is simply passed to the callback unmodified */
|
||||
CINIT(WRITEHEADER, OBJECTPOINT, 29),
|
||||
|
||||
#ifdef MULTIDOC
|
||||
@@ -486,8 +487,8 @@ char *curl_escape(char *string, int length);
|
||||
char *curl_unescape(char *string, int length);
|
||||
|
||||
/* This is the version number */
|
||||
#define LIBCURL_VERSION "7.7.2"
|
||||
#define LIBCURL_VERSION_NUM 0x070702
|
||||
#define LIBCURL_VERSION "7.7.3"
|
||||
#define LIBCURL_VERSION_NUM 0x070703
|
||||
|
||||
/* linked-list structure for the CURLOPT_QUOTE option (and other) */
|
||||
struct curl_slist {
|
||||
|
172
lib/ftp.c
172
lib/ftp.c
@@ -147,6 +147,165 @@ static CURLcode AllowServerConnect(struct UrlData *data,
|
||||
#define lastline(line) (isdigit((int)line[0]) && isdigit((int)line[1]) && \
|
||||
isdigit((int)line[2]) && (' ' == line[3]))
|
||||
|
||||
|
||||
int Curl_GetFTPResponse(int sockfd,
|
||||
char *buf,
|
||||
struct connectdata *conn,
|
||||
int *ftpcode)
|
||||
{
|
||||
/* Brand new implementation.
|
||||
* We cannot read just one byte per read() and then go back to select()
|
||||
* as it seems that the OpenSSL read() stuff doesn't grok that properly.
|
||||
*
|
||||
* Alas, read as much as possible, split up into lines, use the ending
|
||||
* line in a response or continue reading.
|
||||
*/
|
||||
|
||||
int nread; /* total size read */
|
||||
int perline; /* count bytes per line */
|
||||
bool keepon=TRUE;
|
||||
ssize_t gotbytes;
|
||||
char *ptr;
|
||||
int timeout = 3600; /* default timeout in seconds */
|
||||
struct timeval interval;
|
||||
fd_set rkeepfd;
|
||||
fd_set readfd;
|
||||
struct UrlData *data = conn->data;
|
||||
char *line_start;
|
||||
int code;
|
||||
|
||||
#define SELECT_OK 0
|
||||
#define SELECT_ERROR 1
|
||||
#define SELECT_TIMEOUT 2
|
||||
int error = SELECT_OK;
|
||||
|
||||
if(ftpcode)
|
||||
*ftpcode=0; /* 0 for errors */
|
||||
|
||||
if(data->timeout) {
|
||||
/* if timeout is requested, find out how much remaining time we have */
|
||||
timeout = data->timeout - /* timeout time */
|
||||
(Curl_tvlong(Curl_tvnow()) - Curl_tvlong(conn->now)); /* spent time */
|
||||
if(timeout <=0 ) {
|
||||
failf(data, "Transfer aborted due to timeout");
|
||||
return -SELECT_TIMEOUT; /* already too little time */
|
||||
}
|
||||
}
|
||||
|
||||
FD_ZERO (&readfd); /* clear it */
|
||||
FD_SET (sockfd, &readfd); /* read socket */
|
||||
|
||||
/* get this in a backup variable to be able to restore it on each lap in the
|
||||
select() loop */
|
||||
rkeepfd = readfd;
|
||||
|
||||
ptr=buf;
|
||||
line_start = buf;
|
||||
|
||||
nread=0;
|
||||
perline=0;
|
||||
keepon=TRUE;
|
||||
|
||||
while((nread<BUFSIZE) && (keepon && !error)) {
|
||||
readfd = rkeepfd; /* set every lap */
|
||||
interval.tv_sec = timeout;
|
||||
interval.tv_usec = 0;
|
||||
|
||||
switch (select (sockfd+1, &readfd, NULL, NULL, &interval)) {
|
||||
case -1: /* select() error, stop reading */
|
||||
error = SELECT_ERROR;
|
||||
failf(data, "Transfer aborted due to select() error");
|
||||
break;
|
||||
case 0: /* timeout */
|
||||
error = SELECT_TIMEOUT;
|
||||
failf(data, "Transfer aborted due to timeout");
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
* This code previously didn't use the kerberos sec_read() code
|
||||
* to read, but when we use Curl_read() it may do so. Do confirm
|
||||
* that this is still ok and then remove this comment!
|
||||
*/
|
||||
if(CURLE_OK != Curl_read(conn, sockfd, ptr, BUFSIZE-nread, &gotbytes))
|
||||
keepon = FALSE;
|
||||
else if(gotbytes <= 0) {
|
||||
keepon = FALSE;
|
||||
error = SELECT_ERROR;
|
||||
failf(data, "Connection aborted");
|
||||
}
|
||||
else {
|
||||
/* we got a whole chunk of data, which can be anything from one
|
||||
* byte to a set of lines and possible just a piece of the last
|
||||
* line */
|
||||
int i;
|
||||
|
||||
nread += gotbytes;
|
||||
for(i=0; i< gotbytes; ptr++, i++) {
|
||||
perline++;
|
||||
if(*ptr=='\n') {
|
||||
/* a newline is CRLF in ftp-talk, so the CR is ignored as
|
||||
the line isn't really terminated until the LF comes */
|
||||
|
||||
/* output debug output if that is requested */
|
||||
if(data->bits.verbose) {
|
||||
fputs("< ", data->err);
|
||||
fwrite(line_start, 1, perline, data->err);
|
||||
/* no need to output LF here, it is part of the data */
|
||||
}
|
||||
|
||||
if(perline>3 && lastline(line_start)) {
|
||||
/* This is the end of the last line, copy the last
|
||||
* line to the start of the buffer and zero terminate,
|
||||
* for old times sake (and krb4)! */
|
||||
char *moo;
|
||||
int i;
|
||||
for(moo=line_start, i=0; moo<ptr; moo++, i++)
|
||||
buf[i] = *moo;
|
||||
moo[i]=0; /* zero terminate */
|
||||
keepon=FALSE;
|
||||
break;
|
||||
}
|
||||
perline=0; /* line starts over here */
|
||||
line_start = ptr+1;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
} /* switch */
|
||||
} /* while there's buffer left and loop is requested */
|
||||
|
||||
if(!error)
|
||||
code = atoi(buf);
|
||||
|
||||
#if KRB4
|
||||
/* handle the security-oriented responses 6xx ***/
|
||||
/* FIXME: some errorchecking perhaps... ***/
|
||||
switch(code) {
|
||||
case 631:
|
||||
sec_read_msg(conn, buf, prot_safe);
|
||||
break;
|
||||
case 632:
|
||||
sec_read_msg(conn, buf, prot_private);
|
||||
break;
|
||||
case 633:
|
||||
sec_read_msg(conn, buf, prot_confidential);
|
||||
break;
|
||||
default:
|
||||
/* normal ftp stuff we pass through! */
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(error)
|
||||
return -error;
|
||||
|
||||
if(ftpcode)
|
||||
*ftpcode=code; /* return the initial number like this */
|
||||
|
||||
return nread; /* total amount of bytes read */
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* We allow the ftpcode pointer to be NULL if no reply integer is wanted
|
||||
*/
|
||||
@@ -157,6 +316,7 @@ int Curl_GetFTPResponse(int sockfd, char *buf,
|
||||
{
|
||||
int nread;
|
||||
ssize_t keepon=TRUE;
|
||||
size_t got;
|
||||
char *ptr;
|
||||
int timeout = 3600; /* in seconds */
|
||||
struct timeval interval;
|
||||
@@ -260,6 +420,7 @@ int Curl_GetFTPResponse(int sockfd, char *buf,
|
||||
|
||||
return nread;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* -- who are we? -- */
|
||||
char *Curl_getmyhost(char *buf, int buf_size)
|
||||
@@ -837,7 +998,8 @@ CURLcode _ftp(struct connectdata *conn)
|
||||
}
|
||||
ftpsendf(conn->firstsocket, conn, "%s |%d|%s|%s|", *modep, eprtaf,
|
||||
portmsgbuf, tmp);
|
||||
} else if (strcmp(*modep, "LPRT") == 0 || strcmp(*modep, "PORT") == 0) {
|
||||
} else if (strcmp(*modep, "LPRT") == 0 ||
|
||||
strcmp(*modep, "PORT") == 0) {
|
||||
int i;
|
||||
|
||||
if (strcmp(*modep, "LPRT") == 0 && lprtaf < 0)
|
||||
@@ -849,7 +1011,7 @@ CURLcode _ftp(struct connectdata *conn)
|
||||
if (strcmp(*modep, "LPRT") == 0) {
|
||||
snprintf(tmp, sizeof(tmp), "%d,%d", lprtaf, alen);
|
||||
if (strlcat(portmsgbuf, tmp, sizeof(portmsgbuf)) >= sizeof(portmsgbuf)) {
|
||||
goto again;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < alen; i++) {
|
||||
@@ -858,18 +1020,18 @@ CURLcode _ftp(struct connectdata *conn)
|
||||
else
|
||||
snprintf(tmp, sizeof(tmp), "%u", ap[i]);
|
||||
if (strlcat(portmsgbuf, tmp, sizeof(portmsgbuf)) >= sizeof(portmsgbuf)) {
|
||||
goto again;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (strcmp(*modep, "LPRT") == 0) {
|
||||
snprintf(tmp, sizeof(tmp), ",%d", plen);
|
||||
if (strlcat(portmsgbuf, tmp, sizeof(portmsgbuf)) >= sizeof(portmsgbuf))
|
||||
goto again;
|
||||
continue;
|
||||
}
|
||||
for (i = 0; i < plen; i++) {
|
||||
snprintf(tmp, sizeof(tmp), ",%u", pp[i]);
|
||||
if (strlcat(portmsgbuf, tmp, sizeof(portmsgbuf)) >= sizeof(portmsgbuf)) {
|
||||
goto again;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
ftpsendf(conn->firstsocket, conn, "%s %s", *modep, portmsgbuf);
|
||||
|
@@ -37,6 +37,11 @@
|
||||
#ifdef USE_SSLEAY
|
||||
#include <openssl/rand.h>
|
||||
|
||||
/* The last #include file should be: */
|
||||
#ifdef MALLOCDEBUG
|
||||
#include "memdebug.h"
|
||||
#endif
|
||||
|
||||
static char global_passwd[64];
|
||||
|
||||
static int passwd_callback(char *buf, int num, int verify
|
||||
|
@@ -361,6 +361,22 @@ Transfer(struct connectdata *c_conn)
|
||||
*/
|
||||
if(data->bits.no_body)
|
||||
return CURLE_OK;
|
||||
|
||||
if(!conn->bits.close) {
|
||||
/* If this is not the last request before a close, we must
|
||||
set the maximum download size to the size of the
|
||||
expected document or else, we won't know when to stop
|
||||
reading! */
|
||||
if(-1 != conn->size)
|
||||
conn->maxdownload = conn->size;
|
||||
|
||||
/* If max download size is *zero* (nothing) we already
|
||||
have nothing and can safely return ok now! */
|
||||
if(0 == conn->maxdownload)
|
||||
return CURLE_OK;
|
||||
|
||||
/* What to do if the size is *not* known? */
|
||||
}
|
||||
break; /* exit header line loop */
|
||||
}
|
||||
|
||||
@@ -392,11 +408,21 @@ Transfer(struct connectdata *c_conn)
|
||||
}
|
||||
data->progress.httpcode = httpcode;
|
||||
data->progress.httpversion = httpversion;
|
||||
|
||||
if(httpversion == 0)
|
||||
/* Default action for HTTP/1.0 must be to close, unless
|
||||
we get one of those fancy headers that tell us the
|
||||
server keeps it open for us! */
|
||||
conn->bits.close = TRUE;
|
||||
|
||||
if (httpcode == 304)
|
||||
/* (quote from RFC2616, section 10.3.5):
|
||||
* The 304 response MUST NOT contain a
|
||||
* message-body, and thus is always
|
||||
* terminated by the first empty line
|
||||
* after the header fields.
|
||||
*/
|
||||
conn->size=0;
|
||||
}
|
||||
else {
|
||||
header = FALSE; /* this is not a header line */
|
||||
@@ -583,16 +609,6 @@ Transfer(struct connectdata *c_conn)
|
||||
} /* two valid time strings */
|
||||
} /* we have a time condition */
|
||||
|
||||
if(!conn->bits.close) {
|
||||
/* If this is not the last request before a close, we must
|
||||
set the maximum download size to the size of the expected
|
||||
document or else, we won't know when to stop reading! */
|
||||
if(-1 != conn->size)
|
||||
conn->maxdownload = conn->size;
|
||||
|
||||
/* What to do if the size is *not* known? */
|
||||
}
|
||||
|
||||
} /* this is HTTP */
|
||||
} /* this is the first time we write a body part */
|
||||
bodywrites++;
|
||||
@@ -622,7 +638,7 @@ Transfer(struct connectdata *c_conn)
|
||||
/* If it returned OK, we just keep going */
|
||||
}
|
||||
|
||||
if(conn->maxdownload &&
|
||||
if((-1 != conn->maxdownload) &&
|
||||
(bytecount + nread >= conn->maxdownload)) {
|
||||
nread = conn->maxdownload - bytecount;
|
||||
if((signed int)nread < 0 ) /* this should be unusual */
|
||||
@@ -634,7 +650,7 @@ Transfer(struct connectdata *c_conn)
|
||||
|
||||
Curl_pgrsSetDownloadCounter(data, (double)bytecount);
|
||||
|
||||
if(! conn->bits.chunk) {
|
||||
if(!conn->bits.chunk && nread) {
|
||||
/* If this is chunky transfer, it was already written */
|
||||
urg = Curl_client_write(data, CLIENTWRITE_BODY, str, nread);
|
||||
if(urg)
|
||||
|
12
lib/url.c
12
lib/url.c
@@ -216,10 +216,10 @@ CURLcode Curl_open(CURL **curl, char *url)
|
||||
data->err = stderr; /* default stderr to stderr */
|
||||
|
||||
/* use fwrite as default function to store output */
|
||||
data->fwrite = (size_t (*)(char *, size_t, size_t, FILE *))fwrite;
|
||||
data->fwrite = (curl_write_callback)fwrite;
|
||||
|
||||
/* use fread as default function to read input */
|
||||
data->fread = (size_t (*)(char *, size_t, size_t, FILE *))fread;
|
||||
data->fread = (curl_read_callback)fread;
|
||||
|
||||
/* set the default passwd function */
|
||||
data->fpasswd = my_getpass;
|
||||
@@ -930,7 +930,7 @@ ConnectionExists(struct UrlData *data,
|
||||
|
||||
if(strequal(needle->protostr, check->protostr) &&
|
||||
strequal(needle->name, check->name) &&
|
||||
(needle->port == check->port) ) {
|
||||
(needle->remote_port == check->remote_port) ) {
|
||||
bool dead;
|
||||
if(strequal(needle->protostr, "FTP")) {
|
||||
/* This is FTP, verify that we're using the same name and
|
||||
@@ -1364,6 +1364,9 @@ static CURLcode Connect(struct UrlData *data,
|
||||
conn->bits.user_passwd = data->userpwd?1:0;
|
||||
conn->bits.proxy_user_passwd = data->proxyuserpwd?1:0;
|
||||
|
||||
/* maxdownload must be -1 on init, as 0 is a valid value! */
|
||||
conn->maxdownload = -1; /* might have been used previously! */
|
||||
|
||||
/* Store creation time to help future close decision making */
|
||||
conn->created = Curl_tvnow();
|
||||
|
||||
@@ -2029,8 +2032,9 @@ static CURLcode Connect(struct UrlData *data,
|
||||
conn->ppath = path; /* set this too */
|
||||
|
||||
/* re-use init */
|
||||
conn->maxdownload = 0; /* might have been used previously! */
|
||||
conn->bits.reuse = TRUE; /* yes, we're re-using here */
|
||||
conn->bits.chunk = FALSE; /* always assume not chunked unless told otherwise */
|
||||
conn->maxdownload = -1; /* might have been used previously! */
|
||||
|
||||
free(old_conn); /* we don't need this anymore */
|
||||
|
||||
|
@@ -456,9 +456,10 @@ struct UrlData {
|
||||
long header_size; /* size of read header(s) in bytes */
|
||||
long request_size; /* the amount of bytes sent in the request(s) */
|
||||
|
||||
FILE *out; /* the fetched file goes here */
|
||||
FILE *in; /* the uploaded file is read from here */
|
||||
FILE *writeheader; /* write the header to this is non-NULL */
|
||||
void *out; /* the fetched file goes here */
|
||||
void *in; /* the uploaded file is read from here */
|
||||
void *writeheader; /* write the header to this is non-NULL */
|
||||
|
||||
char *url; /* what to get */
|
||||
char *freethis; /* if non-NULL, an allocated string for the URL */
|
||||
long use_port; /* which port to use (when not using default) */
|
||||
|
@@ -41,11 +41,12 @@ char *curl_version(void)
|
||||
#if (SSLEAY_VERSION_NUMBER >= 0x906000)
|
||||
{
|
||||
char sub[2];
|
||||
sub[1]='\0';
|
||||
if(SSLEAY_VERSION_NUMBER&0xff0) {
|
||||
sub[0]=((SSLEAY_VERSION_NUMBER>>4)&0xff) + 'a' -1;
|
||||
}
|
||||
else
|
||||
sub[0]=0;
|
||||
sub[0]='\0';
|
||||
|
||||
sprintf(ptr, " (OpenSSL %lx.%lx.%lx%s)",
|
||||
(SSLEAY_VERSION_NUMBER>>28)&0xf,
|
||||
@@ -63,11 +64,12 @@ char *curl_version(void)
|
||||
#else
|
||||
{
|
||||
char sub[2];
|
||||
sub[1]='\0';
|
||||
if(SSLEAY_VERSION_NUMBER&0x0f) {
|
||||
sub[0]=(SSLEAY_VERSION_NUMBER&0x0f) + 'a' -1;
|
||||
}
|
||||
else
|
||||
sub[0]=0;
|
||||
sub[0]='\0';
|
||||
|
||||
sprintf(ptr, " (SSL %x.%x.%x%s)",
|
||||
(SSLEAY_VERSION_NUMBER>>12)&0xff,
|
||||
|
@@ -12,12 +12,21 @@ do {
|
||||
}
|
||||
} while (shift @ARGV);
|
||||
|
||||
my $maxmem;
|
||||
|
||||
sub newtotal {
|
||||
my ($newtot)=@_;
|
||||
# count a max here
|
||||
|
||||
if($newtot > $maxmem) {
|
||||
$maxmem= $newtot;
|
||||
}
|
||||
}
|
||||
|
||||
while(<STDIN>) {
|
||||
chomp $_;
|
||||
$line = $_;
|
||||
if($verbose) {
|
||||
print "IN: $line\n";
|
||||
}
|
||||
|
||||
if($line =~ /^MEM ([^:]*):(\d*) (.*)/) {
|
||||
# generic match for the filename+linenumber
|
||||
$source = $1;
|
||||
@@ -34,17 +43,39 @@ while(<STDIN>) {
|
||||
print "FREE ERROR: Previously freed at: ".$getmem{$addr}."\n";
|
||||
}
|
||||
else {
|
||||
if(0 && $verbose) {
|
||||
print "malloc at ".$getmem{$addr}." is freed again at $source:$linenum\n";
|
||||
}
|
||||
|
||||
$totalmem -= $sizeataddr{$addr};
|
||||
|
||||
newtotal($totalmem);
|
||||
$frees++;
|
||||
|
||||
$sizeataddr{$addr}=-1; # set -1 to mark as freed
|
||||
$getmem{$addr}="$source:$linenum";
|
||||
|
||||
}
|
||||
}
|
||||
elsif($function =~ /malloc\((\d*)\) = 0x([0-9a-f]*)/) {
|
||||
$size = $1;
|
||||
$addr = $2;
|
||||
|
||||
if($sizeataddr{$addr}>0) {
|
||||
# this means weeeeeirdo
|
||||
print "Fucked up debug compile, rebuild curl now\n";
|
||||
}
|
||||
|
||||
$sizeataddr{$addr}=$size;
|
||||
$totalmem += $size;
|
||||
|
||||
if(0 && $verbose) {
|
||||
print "malloc($size) at $source:$linenum\n";
|
||||
}
|
||||
|
||||
newtotal($totalmem);
|
||||
$mallocs++;
|
||||
|
||||
$getmem{$addr}="$source:$linenum";
|
||||
}
|
||||
elsif($function =~ /realloc\(0x([0-9a-f]*), (\d*)\) = 0x([0-9a-f]*)/) {
|
||||
@@ -58,6 +89,9 @@ while(<STDIN>) {
|
||||
$totalmem += $newsize;
|
||||
$sizeataddr{$newaddr}=$newsize;
|
||||
|
||||
newtotal($totalmem);
|
||||
$reallocs++;
|
||||
|
||||
$getmem{$oldaddr}="";
|
||||
$getmem{$newaddr}="$source:$linenum";
|
||||
}
|
||||
@@ -71,6 +105,9 @@ while(<STDIN>) {
|
||||
$sizeataddr{$addr}=$size;
|
||||
|
||||
$totalmem += $size;
|
||||
|
||||
newtotal($totalmem);
|
||||
$strdups++;
|
||||
}
|
||||
else {
|
||||
print "Not recognized input line: $function\n";
|
||||
@@ -134,9 +171,6 @@ while(<STDIN>) {
|
||||
else {
|
||||
print "Not recognized prefix line: $line\n";
|
||||
}
|
||||
if($verbose) {
|
||||
print "TOTAL: $totalmem\n";
|
||||
}
|
||||
}
|
||||
|
||||
if($totalmem) {
|
||||
@@ -168,3 +202,12 @@ if($fopens) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($verbose) {
|
||||
print "Mallocs: $mallocs\n",
|
||||
"Reallocs: $reallocs\n",
|
||||
"Strdups: $strdups\n",
|
||||
"Frees: $frees\n";
|
||||
|
||||
print "Maximum allocated: $maxmem\n";
|
||||
}
|
||||
|
@@ -1268,7 +1268,7 @@ struct OutStruct {
|
||||
struct Configurable *config;
|
||||
};
|
||||
|
||||
int my_fwrite(void *buffer, size_t size, size_t nmemb, FILE *stream)
|
||||
int my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream)
|
||||
{
|
||||
struct OutStruct *out=(struct OutStruct *)stream;
|
||||
if(out && !out->stream) {
|
||||
|
@@ -1,3 +1,3 @@
|
||||
#define CURL_NAME "curl"
|
||||
#define CURL_VERSION "7.7.2"
|
||||
#define CURL_VERSION "7.7.3"
|
||||
#define CURL_ID CURL_NAME " " CURL_VERSION " (" OS ") "
|
||||
|
@@ -8,6 +8,8 @@ The cURL Test Suite
|
||||
|
||||
Requires:
|
||||
perl (and a unix-style shell)
|
||||
diff (when a test fail, a diff is shown)
|
||||
stunnel (for HTTPS and FTPS tests)
|
||||
|
||||
Run:
|
||||
'make test'. This invokes the 'runtests.pl' perl script. Edit the top
|
||||
|
1
tests/data/command300.txt
Normal file
1
tests/data/command300.txt
Normal file
@@ -0,0 +1 @@
|
||||
https://%HOSTIP:%HTTPSPORT/300
|
3
tests/data/command40.txt
Normal file
3
tests/data/command40.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
http://%HOSTIP:%HOSTPORT/want/40
|
||||
|
||||
|
1
tests/data/command400.txt
Normal file
1
tests/data/command400.txt
Normal file
@@ -0,0 +1 @@
|
||||
ftps://%HOSTIP:%FTPSPORT/
|
2
tests/data/command41.txt
Normal file
2
tests/data/command41.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
-U proxy:pppp -u site:moooo -x %HOSTIP:%HOSTPORT http://weeird.site.com/YES/boo/2
|
||||
|
1
tests/data/name300.txt
Normal file
1
tests/data/name300.txt
Normal file
@@ -0,0 +1 @@
|
||||
simple HTTPS GET
|
1
tests/data/name40.txt
Normal file
1
tests/data/name40.txt
Normal file
@@ -0,0 +1 @@
|
||||
HTTP GET returns content-length 0 on persitent connection
|
1
tests/data/name400.txt
Normal file
1
tests/data/name400.txt
Normal file
@@ -0,0 +1 @@
|
||||
FTP dir list PASV
|
1
tests/data/name41.txt
Normal file
1
tests/data/name41.txt
Normal file
@@ -0,0 +1 @@
|
||||
HTTP with proxy AND web page athorization
|
6
tests/data/prot300.txt
Normal file
6
tests/data/prot300.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
GET /300 HTTP/1.1
|
||||
User-Agent: curl/7.7 (i686-pc-linux-gnu) libcurl 7.7.1 (SSL 0.9.5) (ipv6 enabled)
|
||||
Host: 127.0.0.1:8433
|
||||
Pragma: no-cache
|
||||
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*
|
||||
|
6
tests/data/prot40.txt
Normal file
6
tests/data/prot40.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
GET /want/40 HTTP/1.1
|
||||
User-Agent: curl/7.7.2 (sparc-sun-solaris2.7) libcurl 7.7.2 (OpenSSL 0.9.6a) (krb4 enabled)
|
||||
Host: 127.0.0.1:8999
|
||||
Pragma: no-cache
|
||||
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*
|
||||
|
8
tests/data/prot41.txt
Normal file
8
tests/data/prot41.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
GET http://weeird.site.com/YES/boo/2 HTTP/1.1
|
||||
Proxy-authorization: Basic cHJveHk6cHBwcA==
|
||||
Authorization: Basic c2l0ZTptb29vbw==
|
||||
User-Agent: curl/7.7.2 (sparc-sun-solaris2.7) libcurl 7.7.2 (OpenSSL 0.9.6a) (krb4 enabled)
|
||||
Host: weeird.site.com
|
||||
Pragma: no-cache
|
||||
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*
|
||||
|
8
tests/data/reply40.txt
Normal file
8
tests/data/reply40.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
HTTP/1.1 100 Continue weirdo message
|
||||
Server: heeee heeee
|
||||
|
||||
HTTP/1.1 200 This is a weirdo text message
|
||||
Date: Thu, 09 Nov 2010 14:49:00 GMT
|
||||
Content-Length: 0
|
||||
|
||||
*** This should not be received ***
|
7
tests/data/reply41.txt
Normal file
7
tests/data/reply41.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
HTTP/1.1 200 OK
|
||||
Date: Thu, 09 Nov 2010 14:49:00 GMT
|
||||
Server: test-server/fake
|
||||
Content-Type: text/html
|
||||
Funny-head: yesyes
|
||||
|
||||
|
@@ -4,4 +4,4 @@ Fake: yes
|
||||
Fake: yes
|
||||
|
||||
Repeated nonsense-headers
|
||||
http://127.0.0.1:8999/want/15 200 26.000
|
||||
http://127.0.0.1:8999/want/15 200 26
|
||||
|
31
tests/data/stunnel.pem
Normal file
31
tests/data/stunnel.pem
Normal file
@@ -0,0 +1,31 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIICXQIBAAKBgQDQPvaAU+Pdd5B0XlR71lDw0LyMridewzGaN6H3T+vRKYkvxyZw
|
||||
nrxhYSLWn4g9wcu/EWcTN23A07Oa4HSZ/wHQ/yO+Yv01OmfGHylWZNN0eb/qemv8
|
||||
wp/bFRaubeuIGz9hl4r1HM5Mn3cNjhDjIjDqzGorObUItigCHY4ZDNHOOQIDAQAB
|
||||
AoGAfK4V3ANeHEznuiR4JKTOVUBEg14JyFzJp/HDEVVSdSqPLoHn6+m+E/eaajGd
|
||||
2ovbNwxuUD0Rgy+9Cu90IHdjV+8i7xo/ttnzg8UDUUhT0BMuOsbEPGGABqPxXEoM
|
||||
+c58smG9r30K+5ToctRlsYuH4xQvHL3fc2DHRDEwPDD+KdkCQQD3kO9D6sV9/So3
|
||||
wWLamW0AFK/spK0i1MqSdPi/gnor37WNqOxBz2MVYDmTWeDWtq9HuG2QRKCNiqGB
|
||||
tAUyKSVjAkEA11ccOxGleOM+scugobGkktnCniyMJSxQijMpIDmO/S0DBH5SiTee
|
||||
BywwtcadjUWn4uQGJ0CQCJo2mjsmY13OswJBAKJgPJ7WWKyXJV6mh9kLMrQP3Yeg
|
||||
RzMGUMuYzyKFSO6H74O3nSZZCQsXLwxXsiICdpra+3nZmVjc6aux0Iqi9DMCQQCh
|
||||
DXaAux7t/c9q/CeEJy814YWL9TdPqggGhGLyxfmqYprKJowmMiGPrb40hXpaKUl6
|
||||
CR6NBt1ygZvq1+hLEuK/AkBYJ0ikl3YHkWqSFgiw/yDsVa3CDpChLGxjlheX5gop
|
||||
LKrKE8RO3rtT3CdWyI/IBWPyc0h+qCTEqUdqKW1vRYeS
|
||||
-----END RSA PRIVATE KEY-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICcTCCAdqgAwIBAgIBADANBgkqhkiG9w0BAQQFADBzMQswCQYDVQQGEwJTRTEO
|
||||
MAwGA1UECBMFU29sbmExDTALBgNVBAcTBE1vb28xDTALBgNVBAoTBEhheHgxDjAM
|
||||
BgNVBAsTBUNvb2x4MRIwEAYDVQQDEwlzdG9yZWJyb3IxEjAQBgNVBAMTCWxvY2Fs
|
||||
aG9zdDAeFw0wMTA0MjAxODI2MjhaFw0wMjA0MjAxODI2MjhaMHMxCzAJBgNVBAYT
|
||||
AlNFMQ4wDAYDVQQIEwVTb2xuYTENMAsGA1UEBxMETW9vbzENMAsGA1UEChMESGF4
|
||||
eDEOMAwGA1UECxMFQ29vbHgxEjAQBgNVBAMTCXN0b3JlYnJvcjESMBAGA1UEAxMJ
|
||||
bG9jYWxob3N0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDQPvaAU+Pdd5B0
|
||||
XlR71lDw0LyMridewzGaN6H3T+vRKYkvxyZwnrxhYSLWn4g9wcu/EWcTN23A07Oa
|
||||
4HSZ/wHQ/yO+Yv01OmfGHylWZNN0eb/qemv8wp/bFRaubeuIGz9hl4r1HM5Mn3cN
|
||||
jhDjIjDqzGorObUItigCHY4ZDNHOOQIDAQABoxUwEzARBglghkgBhvhCAQEEBAMC
|
||||
BkAwDQYJKoZIhvcNAQEEBQADgYEASTzH6Af6xmkpPGAdL/lecdkeuChfgb7tVkOE
|
||||
rTzgxE5fVcW9NK79HXZ3OND2uHyu9WMieIr7QKyzfK1uskxQcY6mPApn/Z+yD1vn
|
||||
TYBuyP8I+khaLKA69QzVv+5yVBR0xlAaXGwTKxNzBTXznSmshgvYt5nsmcMw2Xfg
|
||||
CMkSsOU=
|
||||
-----END CERTIFICATE-----
|
@@ -289,7 +289,15 @@ sub PORT_command {
|
||||
return 0;
|
||||
}
|
||||
my $iaddr = inet_aton("$1.$2.$3.$4");
|
||||
my $paddr = sockaddr_in(($5<<8)+$6, $iaddr);
|
||||
|
||||
my $port = ($5<<8)+$6;
|
||||
|
||||
if(!$port || $port > 65535) {
|
||||
print STDERR "very illegal PORT number: $port\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
my $paddr = sockaddr_in($port, $iaddr);
|
||||
my $proto = getprotobyname('tcp') || 6;
|
||||
|
||||
socket(SOCK, PF_INET, SOCK_STREAM, $proto) || die "major failure";
|
||||
|
48
tests/ftpsserver.pl
Normal file
48
tests/ftpsserver.pl
Normal file
@@ -0,0 +1,48 @@
|
||||
#!/usr/bin/perl
|
||||
#
|
||||
# $Id$
|
||||
# This is the HTTPS server designed for the curl test suite.
|
||||
#
|
||||
# It is actually just a layer that runs stunnel properly.
|
||||
|
||||
use strict;
|
||||
|
||||
use stunnel;
|
||||
|
||||
my $stunnel = &checkstunnel;
|
||||
|
||||
if(!$stunnel) {
|
||||
exit;
|
||||
}
|
||||
|
||||
#
|
||||
# -p pemfile
|
||||
# -P pid dir
|
||||
# -d listen port
|
||||
# -r target port
|
||||
|
||||
my $verbose=0; # set to 1 for debugging
|
||||
|
||||
my $port = 8821; # just our default, weird enough
|
||||
my $ftp = 8921; # test ftp-server port
|
||||
do {
|
||||
if($ARGV[0] eq "-v") {
|
||||
$verbose=1;
|
||||
}
|
||||
elsif($ARGV[0] eq "-r") {
|
||||
$ftp=$ARGV[1];
|
||||
shift @ARGV;
|
||||
}
|
||||
elsif($ARGV[0] =~ /^(\d+)$/) {
|
||||
$port = $1;
|
||||
}
|
||||
} while(shift @ARGV);
|
||||
|
||||
my $path = `pwd`;
|
||||
chomp $path;
|
||||
my $cmd = "$stunnel -p $path/data/stunnel.pem -P $path/.ftps.pid -d $port -r $ftp";
|
||||
|
||||
if($verbose) {
|
||||
print "FTPS server: $cmd\n";
|
||||
}
|
||||
system($cmd);
|
51
tests/httpsserver.pl
Normal file
51
tests/httpsserver.pl
Normal file
@@ -0,0 +1,51 @@
|
||||
#!/usr/bin/perl
|
||||
#
|
||||
# $Id$
|
||||
# This is the HTTPS server designed for the curl test suite.
|
||||
#
|
||||
# It is actually just a layer that runs stunnel properly.
|
||||
|
||||
use strict;
|
||||
|
||||
use stunnel;
|
||||
|
||||
my $stunnel = &checkstunnel;
|
||||
|
||||
if(!$stunnel) {
|
||||
exit;
|
||||
}
|
||||
|
||||
#
|
||||
# -p pemfile
|
||||
# -P pid dir
|
||||
# -d listen port
|
||||
# -r target port
|
||||
|
||||
my $verbose=0; # set to 1 for debugging
|
||||
|
||||
my $port = 8433; # just a default
|
||||
my $http = 8999; # http-port
|
||||
do {
|
||||
if($ARGV[0] eq "-v") {
|
||||
$verbose=1;
|
||||
}
|
||||
if($ARGV[0] eq "-w") {
|
||||
return 0; # return success, means we have stunnel working!
|
||||
}
|
||||
elsif($ARGV[0] eq "-r") {
|
||||
$http=$ARGV[1];
|
||||
shift @ARGV;
|
||||
}
|
||||
elsif($ARGV[0] =~ /^(\d+)$/) {
|
||||
$port = $1;
|
||||
}
|
||||
} while(shift @ARGV);
|
||||
|
||||
my $path = `pwd`;
|
||||
chomp $path;
|
||||
my $cmd = "$stunnel -p $path/data/stunnel.pem -P $path/.https.pid -d $port -r $http";
|
||||
|
||||
if($verbose) {
|
||||
print "$cmd\n";
|
||||
}
|
||||
system($cmd);
|
@@ -8,15 +8,18 @@
|
||||
|
||||
use strict;
|
||||
|
||||
use stunnel;
|
||||
|
||||
my $srcdir = $ENV{'srcdir'} || '.';
|
||||
my $HOSTIP="127.0.0.1";
|
||||
my $HOSTPORT=8999; # bad name, but this is the HTTP server port
|
||||
my $HTTPSPORT=8433; # this is the HTTPS server port
|
||||
my $FTPPORT=8921; # this is the FTP server port
|
||||
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/server.input"; # what curl sent the server
|
||||
my $CURLOUT="$LOGDIR/curl.out"; # curl output if not stdout
|
||||
my $CURLLOG="$LOGDIR/curl.log"; # all command lines run
|
||||
my $FTPDCMD="$LOGDIR/ftpserver.cmd"; # copy ftp server instructions here
|
||||
|
||||
@@ -31,8 +34,10 @@ my $TESTCASES="all";
|
||||
# No variables below this point should need to be modified
|
||||
#
|
||||
|
||||
my $PIDFILE=".server.pid";
|
||||
my $FTPPIDFILE=".ftpserver.pid";
|
||||
my $HTTPPIDFILE=".server.pid";
|
||||
my $HTTPSPIDFILE=".https.pid";
|
||||
my $FTPPIDFILE=".ftps.pid";
|
||||
my $FTPSPIDFILE=".ftpsserver.pid";
|
||||
|
||||
# this gets set if curl is compiled with memory debugging:
|
||||
my $memory_debug=0;
|
||||
@@ -43,6 +48,8 @@ my $memdump="memdump";
|
||||
# the path to the script that analyzes the memory debug output file:
|
||||
my $memanalyze="../memanalyze.pl";
|
||||
|
||||
my $checkstunnel = &checkstunnel;
|
||||
|
||||
#######################################################################
|
||||
# variables the command line options may set
|
||||
#
|
||||
@@ -52,6 +59,7 @@ my $verbose;
|
||||
my $debugprotocol;
|
||||
my $anyway;
|
||||
my $gdbthis; # run test case with gdb debugger
|
||||
my $keepoutfiles; # keep stdout and stderr files after tests
|
||||
|
||||
#######################################################################
|
||||
# Return the pid of the server as found in the given pid file
|
||||
@@ -85,38 +93,52 @@ sub stopserver {
|
||||
}
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
# check the given test server if it is still alive
|
||||
#
|
||||
sub checkserver {
|
||||
my ($pidfile)=@_;
|
||||
my $RUNNING=0;
|
||||
my $PID=0;
|
||||
|
||||
# check for pidfile
|
||||
if ( -f $pidfile ) {
|
||||
my $PID=serverpid($pidfile);
|
||||
if ($PID ne "" && kill(0, $PID)) {
|
||||
$RUNNING=1;
|
||||
}
|
||||
else {
|
||||
$RUNNING=0;
|
||||
$PID = -$PID; # negative means dead process
|
||||
}
|
||||
}
|
||||
else {
|
||||
$RUNNING=0;
|
||||
}
|
||||
return $PID
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
# start the http server, or if it already runs, verify that it is our
|
||||
# test server on the test-port!
|
||||
#
|
||||
sub runhttpserver {
|
||||
my $verbose = $_[0];
|
||||
my $STATUS;
|
||||
my $RUNNING;
|
||||
# check for pidfile
|
||||
if ( -f $PIDFILE ) {
|
||||
my $PID=serverpid($PIDFILE);
|
||||
if ($PID ne "" && kill(0, $PID)) {
|
||||
$STATUS="httpd (pid $PID) running";
|
||||
$RUNNING=1;
|
||||
}
|
||||
else {
|
||||
$STATUS="httpd (pid $PID?) not running";
|
||||
$RUNNING=0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
$STATUS="httpd (no pid file) not running";
|
||||
$RUNNING=0;
|
||||
}
|
||||
|
||||
if ($RUNNING != 1) {
|
||||
my $pid = checkserver($HTTPPIDFILE );
|
||||
|
||||
if ($pid <= 0) {
|
||||
my $flag=$debugprotocol?"-v ":"";
|
||||
system("perl $srcdir/httpserver.pl $flag $HOSTPORT &");
|
||||
sleep 1; # give it a little time to start
|
||||
if($verbose) {
|
||||
print "httpd started\n";
|
||||
}
|
||||
}
|
||||
else {
|
||||
print "$STATUS\n";
|
||||
if($pid > 0) {
|
||||
print "httpd ($pid) runs\n";
|
||||
}
|
||||
|
||||
# verify that our server is one one running on this port:
|
||||
my $data=`$CURL --silent -i $HOSTIP:$HOSTPORT/verifiedserver`;
|
||||
@@ -127,42 +149,61 @@ sub runhttpserver {
|
||||
exit;
|
||||
}
|
||||
|
||||
if($verbose) {
|
||||
print "The running HTTP server has been verified to be our server\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
# start the https server (or rather, tunnel) if needed
|
||||
#
|
||||
sub runhttpsserver {
|
||||
my $verbose = $_[0];
|
||||
my $STATUS;
|
||||
my $RUNNING;
|
||||
my $PID=checkserver($HTTPSPIDFILE );
|
||||
|
||||
if($PID > 0) {
|
||||
# kill previous stunnel!
|
||||
if($verbose) {
|
||||
print "kills off running stunnel at $PID\n";
|
||||
}
|
||||
stopserver($HTTPSPIDFILE);
|
||||
}
|
||||
|
||||
my $flag=$debugprotocol?"-v ":"";
|
||||
system("perl $srcdir/httpsserver.pl $flag -r $HOSTPORT $HTTPSPORT &");
|
||||
if($verbose) {
|
||||
print "httpd stunnel started\n";
|
||||
}
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
# start the ftp server if needed
|
||||
#
|
||||
sub runftpserver {
|
||||
my $verbose = $_[0];
|
||||
my $STATUS;
|
||||
my $RUNNING;
|
||||
# check for pidfile
|
||||
if ( -f $FTPPIDFILE ) {
|
||||
my $PID=serverpid($FTPPIDFILE);
|
||||
if ($PID ne "" && kill(0, $PID)) {
|
||||
$STATUS="ftpd (pid $PID) running";
|
||||
$RUNNING=1;
|
||||
}
|
||||
else {
|
||||
$STATUS="ftpd (pid $PID?) not running";
|
||||
$RUNNING=0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
$STATUS="ftpd (no pid file) not running";
|
||||
$RUNNING=0;
|
||||
}
|
||||
my $pid = checkserver ($FTPPIDFILE );
|
||||
|
||||
if ($RUNNING != 1) {
|
||||
if ($pid <= 0) {
|
||||
my $flag=$debugprotocol?"-v ":"";
|
||||
if($debugprotocol) {
|
||||
print "* Starts ftp server verbose:\n";
|
||||
print "perl $srcdir/ftpserver.pl $flag $FTPPORT &\n";
|
||||
}
|
||||
system("perl $srcdir/ftpserver.pl $flag $FTPPORT &");
|
||||
sleep 1; # give it a little time to start
|
||||
if($verbose) {
|
||||
print "ftpd started\n";
|
||||
}
|
||||
}
|
||||
else {
|
||||
print "$STATUS\n";
|
||||
if($verbose) {
|
||||
print "ftpd ($pid) is already running\n";
|
||||
}
|
||||
|
||||
# verify that our server is one one running on this port:
|
||||
my $data=`$CURL --silent -i ftp://$HOSTIP:$FTPPORT/verifiedserver`;
|
||||
@@ -174,9 +215,37 @@ sub runftpserver {
|
||||
exit;
|
||||
}
|
||||
|
||||
if($verbose) {
|
||||
print "The running FTP server has been verified to be our server\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
# start the ftps server (or rather, tunnel) if needed
|
||||
#
|
||||
sub runftpsserver {
|
||||
my $verbose = $_[0];
|
||||
my $STATUS;
|
||||
my $RUNNING;
|
||||
my $PID=checkserver($FTPSPIDFILE );
|
||||
|
||||
if($PID > 0) {
|
||||
# kill previous stunnel!
|
||||
if($verbose) {
|
||||
print "kills off running stunnel at $PID\n";
|
||||
}
|
||||
stopserver($FTPSPIDFILE);
|
||||
}
|
||||
|
||||
my $flag=$debugprotocol?"-v ":"";
|
||||
my $cmd="perl $srcdir/ftpsserver.pl $flag -r $FTPPORT $FTPSPORT &";
|
||||
print "CMD: $cmd\n";
|
||||
system($cmd);
|
||||
if($verbose) {
|
||||
print "ftpd stunnel started\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#######################################################################
|
||||
@@ -204,9 +273,7 @@ sub comparefiles {
|
||||
$dnum = read(D, $d, $m);
|
||||
if(($snum != $dnum) ||
|
||||
($s ne $d)) {
|
||||
print "$source and $dest differ\n";
|
||||
$res=1;
|
||||
$snum=0;
|
||||
return 1;
|
||||
}
|
||||
} while($snum);
|
||||
close(S);
|
||||
@@ -285,7 +352,9 @@ sub compare {
|
||||
|
||||
$res = comparefiles($first, $sec);
|
||||
if ($res != 0) {
|
||||
print " $text FAILED";
|
||||
print " $text FAILED\n";
|
||||
print "=> diff $first $sec' looks like (\">\" added by runtime):\n";
|
||||
print `diff $sec $first`;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -303,11 +372,19 @@ sub displaydata {
|
||||
unlink($memdump); # remove this if there was one left
|
||||
|
||||
my $version=`$CURL -V`;
|
||||
chomp $version;
|
||||
|
||||
my $curl = $version;
|
||||
|
||||
$curl =~ s/^(.*)(libcurl.*)/$1/g;
|
||||
my $libcurl = $2;
|
||||
|
||||
my $hostname=`hostname`;
|
||||
my $hosttype=`uname -a`;
|
||||
|
||||
print "Running tests on:\n",
|
||||
"* $version",
|
||||
print "********* System characteristics ******** \n",
|
||||
"* $curl\n",
|
||||
"* $libcurl\n",
|
||||
"* Host: $hostname",
|
||||
"* System: $hosttype";
|
||||
|
||||
@@ -318,7 +395,9 @@ sub displaydata {
|
||||
$memory_debug=1;
|
||||
}
|
||||
printf("* Memory debugging: %s\n", $memory_debug?"ON":"OFF");
|
||||
|
||||
printf("* HTTPS server: %s\n", $checkstunnel?"ON":"OFF");
|
||||
printf("* FTPS server: %s\n", $checkstunnel?"ON":"OFF");
|
||||
print "***************************************** \n";
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
@@ -353,11 +432,15 @@ sub singletest {
|
||||
# if this file exists, it is FTP server instructions:
|
||||
my $ftpservercmd="$TESTDIR/ftpd$NUMBER.txt";
|
||||
|
||||
my $CURLOUT="$LOGDIR/curl$NUMBER.out"; # curl output if not stdout
|
||||
|
||||
if(! -r $CURLCMD) {
|
||||
if($verbose) {
|
||||
# this is not a test
|
||||
print "$NUMBER doesn't look like a test case!\n";
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
# remove previous server output logfile
|
||||
unlink($SERVERIN);
|
||||
@@ -369,7 +452,7 @@ sub singletest {
|
||||
|
||||
# name of the test
|
||||
open(N, "<$TESTDIR/name$NUMBER.txt") ||
|
||||
print "** Couldn't read name on test $NUMBER\n";
|
||||
return -1; # not a test
|
||||
my $DESC=<N>;
|
||||
close(N);
|
||||
$DESC =~ s/[\r\n]//g;
|
||||
@@ -389,7 +472,9 @@ sub singletest {
|
||||
# make some nice replace operations
|
||||
$cmd =~ s/%HOSTIP/$HOSTIP/g;
|
||||
$cmd =~ s/%HOSTPORT/$HOSTPORT/g;
|
||||
$cmd =~ s/%HTTPSPORT/$HTTPSPORT/g;
|
||||
$cmd =~ s/%FTPPORT/$FTPPORT/g;
|
||||
$cmd =~ s/%FTPSPORT/$FTPSPORT/g;
|
||||
#$cmd =~ s/%HOSTNAME/$HOSTNAME/g;
|
||||
|
||||
if($memory_debug) {
|
||||
@@ -520,12 +605,15 @@ sub singletest {
|
||||
|
||||
}
|
||||
|
||||
if(!$keepoutfiles) {
|
||||
# remove the stdout and stderr files
|
||||
unlink($STDOUT);
|
||||
unlink($STDERR);
|
||||
unlink($CURLOUT); # remove the downloaded results
|
||||
|
||||
unlink("$LOGDIR/upload.$NUMBER"); # remove upload leftovers
|
||||
unlink($CURLOUT); # remove the downloaded results
|
||||
}
|
||||
|
||||
unlink($FTPDCMD); # remove the instructions for this test
|
||||
|
||||
if($memory_debug) {
|
||||
@@ -562,6 +650,69 @@ sub singletest {
|
||||
return 0;
|
||||
}
|
||||
|
||||
my %run;
|
||||
|
||||
sub serverfortest {
|
||||
my ($testnum)=@_;
|
||||
|
||||
if($testnum< 100) {
|
||||
# 0 - 99 is for HTTP
|
||||
if(!$run{'http'}) {
|
||||
runhttpserver($verbose);
|
||||
$run{'http'}=$HTTPPIDFILE;
|
||||
}
|
||||
}
|
||||
elsif($testnum< 200) {
|
||||
# 100 - 199 is for FTP
|
||||
if(!$run{'ftp'}) {
|
||||
runftpserver($verbose);
|
||||
$run{'ftp'}=$FTPPIDFILE;
|
||||
}
|
||||
}
|
||||
elsif($testnum< 300) {
|
||||
# 200 - 299 is for FILE, no server!
|
||||
$run{'file'}="moo";
|
||||
}
|
||||
elsif($testnum< 400) {
|
||||
# 300 - 399 is for HTTPS, two servers!
|
||||
|
||||
if(!$checkstunnel) {
|
||||
# we can't run https tests without stunnel
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(!$run{'http'}) {
|
||||
runhttpserver($verbose);
|
||||
$run{'http'}=$HTTPPIDFILE;
|
||||
}
|
||||
if(!$run{'https'}) {
|
||||
runhttpsserver($verbose);
|
||||
$run{'https'}=$HTTPSPIDFILE;
|
||||
}
|
||||
}
|
||||
elsif($testnum< 500) {
|
||||
# 400 - 499 is for FTPS, also two servers
|
||||
|
||||
if(!$checkstunnel) {
|
||||
# we can't run https tests without stunnel
|
||||
return 1;
|
||||
}
|
||||
if(!$run{'ftp'}) {
|
||||
runftpserver($verbose);
|
||||
$run{'ftp'}=$FTPPIDFILE;
|
||||
}
|
||||
if(!$run{'ftps'}) {
|
||||
runftpsserver($verbose);
|
||||
$run{'ftps'}=$FTPSPIDFILE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
print "Bad test number, no server available\n";
|
||||
return 100;
|
||||
}
|
||||
sleep 1; # give a second for the server(s) to startup
|
||||
return 0; # ok
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
# Check options to this test program
|
||||
@@ -591,17 +742,22 @@ do {
|
||||
# continue anyway, even if a test fail
|
||||
$anyway=1;
|
||||
}
|
||||
elsif($ARGV[0] eq "-k") {
|
||||
# keep stdout and stderr files after tests
|
||||
$keepoutfiles=1;
|
||||
}
|
||||
elsif($ARGV[0] eq "-h") {
|
||||
# show help text
|
||||
print <<EOHELP
|
||||
Usage: runtests.pl [-h][-s][-v][numbers]
|
||||
Usage: runtests.pl [options]
|
||||
-a continue even if a test fails
|
||||
-d display server debug info
|
||||
-g run the test case with gdb
|
||||
-h this help text
|
||||
-k keep stdout and stderr files present after tests
|
||||
-s short output
|
||||
-v verbose output
|
||||
[num] as string like "5 6 9" to run those tests only
|
||||
[num] like "5 6 9" or " 5 to 22 " to run those tests only
|
||||
EOHELP
|
||||
;
|
||||
exit;
|
||||
@@ -644,8 +800,11 @@ mkdir($LOGDIR, 0777);
|
||||
# First, start our test servers
|
||||
#
|
||||
|
||||
runhttpserver($verbose);
|
||||
runftpserver($verbose);
|
||||
#runhttpserver($verbose);
|
||||
#runftpserver($verbose);
|
||||
#runhttpsserver($verbose);
|
||||
|
||||
#sleep 1; # start-up time
|
||||
|
||||
#######################################################################
|
||||
# If 'all' tests are requested, find out all test numbers
|
||||
@@ -683,8 +842,19 @@ my $failed;
|
||||
my $testnum;
|
||||
my $ok=0;
|
||||
my $total=0;
|
||||
my $skipped=0;
|
||||
|
||||
foreach $testnum (split(" ", $TESTCASES)) {
|
||||
|
||||
my $serverproblem = serverfortest($testnum);
|
||||
|
||||
if($serverproblem) {
|
||||
# there's a problem with the server, don't run
|
||||
# this particular server, but count it as "skipped"
|
||||
$skipped++;
|
||||
next;
|
||||
}
|
||||
|
||||
my $error = singletest($testnum);
|
||||
if(-1 != $error) {
|
||||
# valid test case number
|
||||
@@ -714,8 +884,12 @@ close(CMDLOG);
|
||||
# Tests done, stop the servers
|
||||
#
|
||||
|
||||
stopserver($FTPPIDFILE);
|
||||
stopserver($PIDFILE);
|
||||
for(keys %run) {
|
||||
stopserver($run{$_}); # the pid file is in the hash table
|
||||
}
|
||||
#stopserver($FTPPIDFILE);
|
||||
#stopserver($PIDFILE);
|
||||
#stopserver($HTTPSPIDFILE);
|
||||
|
||||
if($total) {
|
||||
print "$ok tests out of $total reported OK\n";
|
||||
@@ -727,3 +901,6 @@ if($total) {
|
||||
else {
|
||||
print "No tests were performed!\n";
|
||||
}
|
||||
if($skipped) {
|
||||
print "$skipped tests were skipped due to server problems\n";
|
||||
}
|
||||
|
11
tests/stunnel.pm
Normal file
11
tests/stunnel.pm
Normal file
@@ -0,0 +1,11 @@
|
||||
sub checkstunnel {
|
||||
my @paths=("/usr/sbin", "/usr/local/sbin", "/sbin", "/usr/bin",
|
||||
"/usr/local/bin");
|
||||
for(@paths) {
|
||||
if( -x "$_/stunnel") {
|
||||
return "$_/stunnel";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
Reference in New Issue
Block a user