Compare commits

..

39 Commits

Author SHA1 Message Date
Daniel Stenberg
3654bd1b56 7.7.3 2001-05-07 11:12:03 +00:00
Daniel Stenberg
237edbc9d8 changed FILE * to void * in all callbacks 2001-05-07 10:51:23 +00:00
Daniel Stenberg
4127903183 Added multithread.c 2001-05-04 09:35:55 +00:00
Daniel Stenberg
2ffc20dc7c example using multiple threads to get URLs 2001-05-04 09:35:43 +00:00
Daniel Stenberg
a2a446cb2f updated contributors list 2001-05-04 08:46:11 +00:00
Daniel Stenberg
9304055df5 'FILE *' changed to 'void *' in all callback functions 2001-05-04 07:47:11 +00:00
Daniel Stenberg
53e0c1b1a6 fixed the link to the OS/2 Patch for OpenSSL 2001-05-04 06:17:01 +00:00
Daniel Stenberg
4efa1e8e4c corrected bad use of the CURLOPT_HTTPPOST header 2001-05-03 14:24:37 +00:00
Daniel Stenberg
ecba113125 Cris changes 2001-05-03 11:09:00 +00:00
Daniel Stenberg
350c536f6c Cris Bailiff's fix to disable chunked transfers on re-used persistent
connections.
2001-05-03 10:53:01 +00:00
Daniel Stenberg
a33eb9881c Cris Bailiff's fix to never attempt to get the body of a 304-reply! 2001-05-03 10:45:39 +00:00
Daniel Stenberg
bbe8aa073e buildconf added, Sterling Hughes added that file 2001-05-03 09:13:53 +00:00
Daniel Stenberg
14521b418e useful script to run after updating from CVS 2001-05-03 09:12:53 +00:00
Daniel Stenberg
73982c65d2 fixed the EXTRA_DIST line 2001-05-03 09:10:07 +00:00
Daniel Stenberg
2eb94acb95 When Content-Length:0 is received, we now bail now and return success
directly after all the headers are received!
2001-04-27 18:03:44 +00:00
Daniel Stenberg
6a80fb3482 bugs, fixes and updates 2001-04-27 14:48:04 +00:00
Daniel Stenberg
26d4c80049 clarified and updated 2001-04-27 14:46:17 +00:00
Daniel Stenberg
3974f30ed4 improved treatment of "Content-Length: 0", which is done by having
maxdownload set to -1 when not used
2001-04-27 08:02:10 +00:00
Daniel Stenberg
44c246dbf2 new 2001-04-27 07:58:26 +00:00
Daniel Stenberg
ef07903a51 Curl_GetFTPResponse() is rewritten to read all incoming data in large
chunks, which makes it a lot faster and will make ftps work better...
2001-04-26 10:29:24 +00:00
Daniel Stenberg
a7dc45997f split curl and libcurl into two strings in the initial display 2001-04-26 08:32:12 +00:00
Daniel Stenberg
583c2e2f09 connection re-using didn't work on non-default ports when not using proxy
until now
2001-04-25 21:24:27 +00:00
Daniel Stenberg
90cce2ae3a added some verbose summary output stuff 2001-04-24 21:47:01 +00:00
Daniel Stenberg
775dc07eb5 no name no test 2001-04-24 21:46:37 +00:00
Daniel Stenberg
a652db18bd include debugmem for memory leak detection 2001-04-24 21:41:29 +00:00
Daniel Stenberg
48f3feed59 SSL based tests 2001-04-24 21:11:34 +00:00
Daniel Stenberg
4ddb3fbbf4 new tests, new server invoke system 2001-04-24 21:09:53 +00:00
Daniel Stenberg
cc872ebc19 fixed 2001-04-24 21:09:27 +00:00
Daniel Stenberg
ba46006896 stunnel and diff are added requirements 2001-04-24 21:09:12 +00:00
Daniel Stenberg
0b7e0638a9 on albert chin's comment I remade the fix to set '\0' instead of 0 since
they're chars
2001-04-24 06:12:07 +00:00
Daniel Stenberg
be49b01952 libcurl.5 replaces LIBCURL as main libcurl overview document 2001-04-23 12:37:27 +00:00
Daniel Stenberg
8d0c1d5495 minor rephrasing 2001-04-23 12:36:02 +00:00
Daniel Stenberg
2769a9ab0b form post, not just form 2001-04-23 11:57:50 +00:00
Daniel Stenberg
8ea5b5bbd0 clarified and extended with an example 2001-04-23 11:55:25 +00:00
Daniel Stenberg
0ce49cb7ed Added comment about where to find the HTML versions of the man pages 2001-04-23 11:42:24 +00:00
Daniel Stenberg
d802dfe86a Added curl_mprintf and curl_strequal in the list of "useful functions" 2001-04-23 11:40:53 +00:00
Daniel Stenberg
aabc0c08a1 curl_printf became curl_mprintf 2001-04-23 08:30:22 +00:00
Daniel Stenberg
476addb9c1 curl_printf is curl_mprintf now 2001-04-23 08:29:56 +00:00
Daniel Stenberg
37d7a198d5 Added zero termination, as the OpenSSL version string was written without
it!
2001-04-23 07:54:12 +00:00
46 changed files with 1001 additions and 208 deletions

55
CHANGES
View File

@@ -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)

View File

@@ -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
View File

@@ -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
View File

@@ -0,0 +1,6 @@
#!/bin/sh
automake
aclocal
autoheader
autoconf

View File

@@ -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__

View File

@@ -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
==========

View File

@@ -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) \

View File

@@ -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/

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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"

View 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;
}

View File

@@ -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.

View File

@@ -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
View File

@@ -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);

View File

@@ -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

View File

@@ -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)

View File

@@ -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 */

View File

@@ -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) */

View File

@@ -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,

View File

@@ -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";
}

View File

@@ -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) {

View File

@@ -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 ") "

View File

@@ -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

View File

@@ -0,0 +1 @@
https://%HOSTIP:%HTTPSPORT/300

3
tests/data/command40.txt Normal file
View File

@@ -0,0 +1,3 @@
http://%HOSTIP:%HOSTPORT/want/40

View File

@@ -0,0 +1 @@
ftps://%HOSTIP:%FTPSPORT/

2
tests/data/command41.txt Normal file
View 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
View File

@@ -0,0 +1 @@
simple HTTPS GET

1
tests/data/name40.txt Normal file
View File

@@ -0,0 +1 @@
HTTP GET returns content-length 0 on persitent connection

1
tests/data/name400.txt Normal file
View File

@@ -0,0 +1 @@
FTP dir list PASV

1
tests/data/name41.txt Normal file
View File

@@ -0,0 +1 @@
HTTP with proxy AND web page athorization

6
tests/data/prot300.txt Normal file
View 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
View 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
View 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
View 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
View 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

View File

@@ -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
View 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-----

View File

@@ -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
View 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
View 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);

View File

@@ -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
View 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;