Compare commits

...

45 Commits

Author SHA1 Message Date
Daniel Stenberg
61e2a8108b 7.6.1-pre3 2001-02-07 09:49:06 +00:00
Daniel Stenberg
abb14de7e0 GetLine() didn't properly act on -1 lengths returned from Curl_read() 2001-02-07 09:31:03 +00:00
Daniel Stenberg
ccd57e58f6 Added #define ssize_t int since ssize_t doesn't seem to exist in normal
win32 systems
2001-02-07 09:23:54 +00:00
Daniel Stenberg
58d70db92e no longer #includes "getenv.h" 2001-02-07 08:36:23 +00:00
Daniel Stenberg
09f6fc22ed silly me, corrected the strlcat() to compile 2001-02-06 09:12:39 +00:00
Daniel Stenberg
833ce37cb9 new openbsd inspired implementation of strlcat() 2001-02-06 09:08:24 +00:00
Daniel Stenberg
07e7018564 nntp@iname.com's suggested fix to set the libpath 2001-02-06 07:14:44 +00:00
Daniel Stenberg
db70cd28b3 adjusted the IPv6 stuff to compile and build on Linux as well 2001-02-05 23:35:44 +00:00
Daniel Stenberg
f6e2bfd464 Jun-ichiro itojun Hagino's IPv6 adjustments 2001-02-05 23:04:44 +00:00
Daniel Stenberg
1ae5dab8fb Robert Weaver's VC experiences 2001-02-05 22:35:55 +00:00
Daniel Stenberg
c6355e6a43 Added a telnet section 2001-02-05 22:35:21 +00:00
Daniel Stenberg
7d26eb61fe Added a few more configure option explanations 2001-02-05 10:24:12 +00:00
Daniel Stenberg
8613ce377f the new getinfo() stuff and the cygwin patch 2001-02-04 20:10:52 +00:00
Daniel Stenberg
d6b94488a1 Added blurb about the win32 thing that precents a DLL from using a pointer
passed to it from user-space!
2001-02-04 20:10:02 +00:00
Daniel Stenberg
5d7b32d09f extended 5.5 2001-02-04 20:08:42 +00:00
Daniel Stenberg
ed16d30ea8 CURLINFO_CONTENT_LENGTH_DOWNLOAD and CURLINFO_CONTENT_LENGTH_UPLOAD documented 2001-02-04 20:07:53 +00:00
Daniel Stenberg
6f7c70fbbc CURLINFO_CONTENT_LENGTH_DOWNLOAD and CURLINFO_CONTENT_LENGTH_UPLOAD were
added as suggested by Bob Schader
2001-02-04 20:03:30 +00:00
Daniel Stenberg
9ab5d30e3b Ingo Ralf Blum made it compile with the newest cygwin 2001-02-04 19:00:27 +00:00
Daniel Stenberg
3b44a3df76 7.6.1-pre2 2001-02-01 07:59:46 +00:00
Daniel Stenberg
572c29a4a3 Added support for --enable-debug 2001-02-01 07:58:49 +00:00
Daniel Stenberg
9464c5430d Curl_read() uses ssize_t now 2001-01-31 15:06:56 +00:00
Daniel Stenberg
a14aaaf23f fixed up the telnet to work (using support from Linus Nielsen) 2001-01-31 15:05:44 +00:00
Daniel Stenberg
c41c5a0ef2 curl_read() and Curl_read() now have ssize_t in the last argument 2001-01-31 13:54:12 +00:00
Daniel Stenberg
c0c0283356 Added a check for a working getaddrinfo() that is required for the IPv6
to be considered enabled
2001-01-31 13:53:31 +00:00
Daniel Stenberg
1bcd3e601a changed order of the range and follow-location checks so that a range-request
will work even when following a Location:
2001-01-30 11:52:59 +00:00
Daniel Stenberg
e721f85c83 new test case 2001-01-29 16:04:19 +00:00
Daniel Stenberg
7015c61b86 removed upload.NN files after each test 2001-01-29 15:07:28 +00:00
Daniel Stenberg
30ec0af109 test case 33, HTTP PUT resume 2001-01-29 14:36:49 +00:00
Daniel Stenberg
f585b66af7 7.6-pre1 2001-01-29 11:36:08 +00:00
Daniel Stenberg
1b77c18430 Added an extra text about % in POST data after comments from Daniel Marell 2001-01-29 10:24:51 +00:00
Daniel Stenberg
bd0bd35771 s/to I/do I/ 2001-01-29 10:16:47 +00:00
Daniel Stenberg
368e3526ea Added "3.9 How to I use curl in PHP?" 2001-01-29 10:16:21 +00:00
Daniel Stenberg
1bbe407a4d The PUT stuff is never set! It is set with the UPLOAD... 2001-01-29 07:26:50 +00:00
Daniel Stenberg
513bc44421 HTTP PUT resume now sends Content-Range: headers as I believe the RFC2616
describes, Bob Schader's research seems to agree.
2001-01-29 07:24:20 +00:00
Daniel Stenberg
4cc76d1576 upload sets HTTP request to PUT for "HTTP upload" 2001-01-29 07:23:11 +00:00
Daniel Stenberg
6dc5c6ffc7 the keep-alive issue 2001-01-27 20:51:31 +00:00
Daniel Stenberg
c69c79dd04 bettersupport for HTTP return codes 300-399 2001-01-27 20:31:51 +00:00
Daniel Stenberg
7fca24b14b PUT resume things
progress meter modified for resume
POST/GET/Location adjustments
2001-01-27 20:25:52 +00:00
Daniel Stenberg
2fa0d3dd5f test case 31 and 32 were added 2001-01-27 20:02:11 +00:00
Daniel Stenberg
3a8210c975 Resume is now done with a Content-Range header instead of a Range header if
the request isn't GET. Presumably, this is how it should be made.
2001-01-27 18:57:07 +00:00
Daniel Stenberg
d69302202d minor output fix 2001-01-27 18:51:10 +00:00
Daniel Stenberg
227662d2ed Added -d that enables easier protocol/server debug overview (it invokes
the servers with their -v options)
2001-01-27 18:50:54 +00:00
Daniel Stenberg
3cb3d43913 added test 29 and 30, HTTP resume and partial download tests 2001-01-27 18:49:48 +00:00
Daniel Stenberg
c8a546c941 The progess meter title get an extra output when a resumed transfer is
taking place
2001-01-27 18:23:59 +00:00
Daniel Stenberg
62fec1d28d data->httpreq was not set properly 2001-01-27 17:58:15 +00:00
58 changed files with 961 additions and 76 deletions

86
CHANGES
View File

@@ -7,6 +7,92 @@
History of Changes
Daniel (7 February 2001)
- SM found a flaw in the response reading function for FTP that could make
libcurl not get out of the loop properly when it should, if libcurl got -1
returned when reading the socket.
- I found a similar mistake in http.c when using a proxy and reading the
results from the proxy connection.
Daniel (6 February 2001)
- A friendly person named "SM" (nntp at iname.com) pointed out that the VC
makefile in src/ needed the libpath set for the debug build to work.
- Daniel Gehriger stepped in to assist with the VC++ stuff Robert Weaver
brought up yesterday.
Daniel (5 February 2001)
- Jun-ichiro itojun Hagino brought a big patch that brings IPv6-awareness to
a bunch of different areas within libcurl.
- Robert Weaver told me about the problems the MS VC++ 6.0 compiler has with
the 'static' keyword on a number of libcurl functions. I might need to add a
patch that redefines static when libcurl is compiled with that compiler.
How do I know when VC++ compiles, anyone?
Daniel (4 February 2001)
- curl_getinfo() was extended with two new options:
CURLINFO_CONTENT_LENGTH_DOWNLOAD and CURLINFO_CONTENT_LENGTH_UPLOAD. They
return the full assumed content length of the transfer in the given
direction. The CURLINFO_CONTENT_LENGTH_DOWNLOAD will be the Content-Length:
size of a HTTP download. Added descriptions to the man page as well. This
was done after discussions with Bob Schader.
Daniel (3 February 2001)
- Ingo Ralf Blum provided another fix that makes curl build under the more
recent cygwin installations. It seems they've changed the preset defines to
not include WIN32 anymore.
Version 7.6.1-pre2
Daniel (31 January 2001)
- Curl_read() and curl_read() now return a ssize_t for the size, as it had to
be able to return -1. The telnet support crashed due to this and there was a
possibility to weird behaviour all over. Linus Nielsen Feltzing helped me
find this.
- Added a configure.in check for a working getaddrinfo() if IPv6 is requested.
I also made the configure script feature --enable-debug which sets a couple
of compiler options when used. It assumes gcc.
Daniel (30 January 2001)
- I finally took a stab at the long-term FIXME item I've had on myself, and
now libcurl will properly work when doing a HTTP range-request that follows
a Location:. Previously that would make libcurl fail saying that the server
doesn't seem to support range requests.
Daniel (29 January 2001)
- I added a test case for the HTTP PUT resume thing (test case 33).
Version 7.6.1-pre1
Daniel (29 January 2001)
- Yet another Content-Range change. Ok now? Bob Schader checks from his end
and it works for him.
Daniel (27 January 2001)
- So the HTTP PUT resume fix wasn't good. There should appearantly be a
Content-Range header when resuming a PUT.
- I noticed I broke the download-check that verifies that a resumed HTTP
download is actually resumed. It got broke because my new 'httpreq' field
in the main curl struct. I should get slapped. I added a test case for
this now, so I won't be able to ruin this again without noticing.
- Added a test case for content-length verifying when downloading HTTP.
- Made the progress meter title say if the transfer is being transfered. It
makes the output slightly better for resumes.
- When dealing with Location: and HTTP return codes, libcurl will not attempt
to follow the spirit of RFC2616 better. It means that when POSTing to a
URL that is being following to a second place, the standard will judge on
what to do. All HTTP codes except 303 and 305 will cause curl to make a
second POST operation. 303 will make a GET and 305 is not yet supported.
I also wrote two test cases for this POST/GET/Location stuff.
Version 7.6
Daniel (26 January 2001)

View File

@@ -39,3 +39,7 @@
/* Define if you want to enable IPv6 support */
#undef ENABLE_IPV6
/* Define this to 'int' if ssize_t is not an available typedefed type */
#undef ssize_t

View File

@@ -23,6 +23,9 @@
/* Define to `unsigned' if <sys/types.h> doesn't define. */
/* #undef size_t */
/* Define this to 'int' if ssize_t is not an available typedefed type */
#define ssize_t int
/* Define if you have the ANSI C header files. */
#define STDC_HEADERS 1

View File

@@ -26,6 +26,66 @@ dnl The install stuff has already been taken care of by the automake stuff
dnl AC_PROG_INSTALL
AC_PROG_MAKE_SET
dnl ************************************************************
dnl lame option to switch on debug options
dnl
AC_MSG_CHECKING([whether to enable debug options])
AC_ARG_ENABLE(debug,
[ --enable-debug Enable pedantic debug options
--disable-debug Disable debug options],
[ case "$enableval" in
no)
AC_MSG_RESULT(no)
;;
*) AC_MSG_RESULT(yes)
CPPFLAGS="$CPPFLAGS -DMALLOCDEBUG"
CFLAGS="-Wall -pedantic -g"
;;
esac ],
AC_MSG_RESULT(no)
)
dnl
dnl check for working getaddrinfo()
dnl
AC_DEFUN(CURL_CHECK_WORKING_GETADDRINFO,[
AC_CACHE_CHECK(for working getaddrinfo, ac_cv_working_getaddrinfo,[
AC_TRY_RUN( [
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
void main(void) {
struct addrinfo hints, *ai;
int error;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
error = getaddrinfo("127.0.0.1", "8080", &hints, &ai);
if (error) {
exit(1);
}
else {
exit(0);
}
}
],[
ac_cv_working_getaddrinfo="yes"
],[
ac_cv_working_getaddrinfo="no"
],[
ac_cv_working_getaddrinfo="yes"
])])
if test "$ac_cv_working_getaddrinfo" = "yes"; then
AC_DEFINE(HAVE_GETADDRINFO, 1, [Define if getaddrinfo exists and works])
AC_DEFINE(ENABLE_IPV6, 1, [Define if you want to enable IPv6 support])
fi
])
AC_DEFUN(CURL_CHECK_LOCALTIME_R,
[
dnl check for a few thread-safe functions
@@ -251,7 +311,6 @@ AC_ARG_ENABLE(ipv6,
ipv6=no
;;
*) AC_MSG_RESULT(yes)
AC_DEFINE(ENABLE_IPV6)
ipv6=yes
;;
esac ],
@@ -268,7 +327,6 @@ main()
}
],
AC_MSG_RESULT(yes)
AC_DEFINE(ENABLE_IPV6)
ipv6=yes,
AC_MSG_RESULT(no)
ipv6=no,
@@ -276,6 +334,11 @@ main()
ipv6=no
))
if test "$ipv6" = "yes"; then
CURL_CHECK_WORKING_GETADDRINFO
fi
dnl **********************************************************************
dnl Checks for libraries.
dnl **********************************************************************
@@ -365,6 +428,10 @@ AC_MSG_CHECKING([if Kerberos4 support is requested])
if test "$want_krb4" = yes
then
if test "$ipv6" = "yes"; then
echo krb4 is not compatible with IPv6
exit 1
fi
AC_MSG_RESULT(yes)
dnl Check for & handle argument to --with-krb4
@@ -592,6 +659,9 @@ AC_CHECK_SIZEOF(long double, 8)
# check for 'long long'
AC_CHECK_SIZEOF(long long, 4)
# check for ssize_t
AC_CHECK_TYPE(ssize_t, int)
dnl Get system canonical name
AC_CANONICAL_HOST
AC_DEFINE_UNQUOTED(OS, "${host}")
@@ -622,7 +692,8 @@ AC_CHECK_FUNCS( socket \
setvbuf \
sigaction \
signal \
getpass_r
getpass_r \
strlcat
)
dnl removed 'getpass' check on October 26, 2000

View File

@@ -1,4 +1,4 @@
Updated: January 22, 2001 (http://curl.haxx.se/docs/faq.shtml)
Updated: February 2, 2001 (http://curl.haxx.se/docs/faq.shtml)
_ _ ____ _
___| | | | _ \| |
/ __| | | | |_) | |
@@ -30,6 +30,7 @@ FAQ
3.6 Does curl support javascript, ASP, XML, XHTML or HTML version Y?
3.7 Can I use curl to delete/rename a file through FTP?
3.8 How do I tell curl to follow HTTP redirects?
3.9 How do I use curl in PHP?
4. Running Problems
4.1 Problems connecting to SSL servers.
@@ -52,7 +53,8 @@ FAQ
5.2 How can I receive all data into a large memory chunk?
5.3 How do I fetch multiple files with libcurl?
5.4 Does libcurl do Winsock initing on win32 systems?
5.5 Does CURLOPT_FILE work on win32 ?
5.5 Does CURLOPT_FILE and CURLOPT_INFILE work on win32 ?
5.6 What about Keep-Alive or persistant connections?
6. License Issues
6.1 I have a GPL program, can I use the libcurl library?
@@ -279,6 +281,19 @@ FAQ
curl -L http://redirector.com
3.9 How do I use curl in PHP?
PHP4 has the ability to use libcurl as an internal module if built with that
option enabled. You then get a set of extra functions that can be used
within your PHP programs. You find all details about those functions in the
curl section in the PHP manual, see the online version at:
http://www.php.net/manual/ref.curl.php
PHP also offers the option to run a command line, and then you can of course
invoke the curl tool using a command line. This is the way to use curl if
you're using PHP3 or PHP4 built without curl module support.
4. Running Problems
4.1. Problems connecting to SSL servers.
@@ -310,6 +325,9 @@ FAQ
In win32, the standard DOS shell treats the %-letter specially and you may
need to quote the string properly when % is used in it.
Also note that if you want the literal %-letter to be part of the data you
pass in a POST using -d/--data you must encode it as '%25'.
4.3. How can I use {, }, [ or ] to specify multiple URLs?
Because those letters have a special meaning to the shell, and to be used in
@@ -473,14 +491,24 @@ FAQ
use several different libraries and parts, and there's no reason for every
single library to do this.
5.5 Does CURLOPT_FILE work on win32 ?
5.5 Does CURLOPT_FILE and CURLOPT_INFILE work on win32 ?
Yes, but you cannot open a FILE * and pass the pointer to a DLL and have
that DLL use the FILE *. You must use CURLOPT_WRITEFUNCTION as well to set a
function that writes the file, even if that simply writes the data to the
specified FILE*.
that DLL use the FILE *. If you set CURLOPT_FILE you must also use
CURLOPT_WRITEFUNCTION as well to set a function that writes the file, even
if that simply writes the data to the specified FILE*. Similarly, if you use
CURLOPT_INFILE you must also specify CURLOPT_READFUNCTION.
(provided by Joel DeYoung)
(Provided by Joel DeYoung and Bob Schader)
5.6 What about Keep-Alive or persistant connections?
This is closely related to issue 5.3. Since libcurl has no real support
for doing multiple file transfers, there's no support for Keep-Alive or
persistant connections either.
This is of course subject to change as soon as libcurl gets support for
multiple files. Feel free to join in and make this change happen sooner!
6. License Issues

View File

@@ -84,9 +84,10 @@ UNIX
KNOWN PROBLEMS
If you happen to have autoconf installed, but a version older than
2.12 you will get into trouble. Then you can still build curl by
issuing these commands: (from Ralph Beckmann)
If you happen to have autoconf installed, but a version older than 2.12
you will get into trouble. Then you can still build curl by issuing these
commands (note that this requires curl to be built staticly): (from Ralph
Beckmann)
./configure [...]
cd lib; make; cd ..
@@ -139,6 +140,14 @@ UNIX
./configure --with-krb4=/usr/athena
If your system support shared libraries, but you want to built a static
version only, you can disable building the shared version by using:
./configure --disable-shared
If you're a curl developer and use gcc, you might want to enable more
debug options with the --enable-debug option.
Win32
=====

View File

@@ -726,6 +726,25 @@ KERBEROS4 FTP TRANSFER
There's no use for a password on the -u switch, but a blank one will make
curl ask for one and you already entered the real password to kauth.
TELNET
The curl telnet support is basic and very easy to use. Curl passes all data
passed to it on stdin to the remote server. Connect to a remote telnet
server using a command line similar to:
curl telnet://remote.server.com
And enter the data to pass to the server on stdin. The result will be sent
to stdout or to the file you specify with -o.
You might want the -N/--no-buffer option to switch off the buffered output
for slow connections or similar.
NOTE: the telnet protocol does not specify any way to login with a specified
user and password so curl can't do that automatically. To do that, you need
to track when the login prompt is received and send the username and
password accordingly.
MAILING LIST
We have an open mailing list to discuss curl, its development and things

View File

@@ -788,6 +788,7 @@ If you do find bugs, mail them to curl-bug@haxx.se.
- Loic Dachary <loic@senga.org>
- Robert Weaver <robert.weaver@sabre.com>
- Ingo Ralf Blum <ingoralfblum@ingoralfblum.com>
- Jun-ichiro itojun Hagino <itojun@iijlab.net>
.SH WWW
http://curl.haxx.se

View File

@@ -2,7 +2,7 @@
.\" nroff -man [file]
.\" Written by daniel@haxx.se
.\"
.TH curl_easy_init 3 "22 November 2000" "Curl 7.5" "libcurl Manual"
.TH curl_easy_init 3 "4 February 2001" "Curl 7.6.1" "libcurl Manual"
.SH NAME
curl_easy_getinfo - Extract information from a curl session (added in 7.4)
.SH SYNOPSIS
@@ -81,6 +81,14 @@ than one request if FOLLOWLOCATION is true.
Pass a pointer to a long to receive the result of the certification
verification that was requested (using the CURLOPT_SSL_VERIFYPEER option to
curl_easy_setopt). (Added in 7.4.2)
.TP
.B CURLINFO_CONTENT_LENGTH_DOWNLOAD
Pass a pointer to a double to receive the content-length of the download.
(Added in 7.6.1)
.TP
.B CURLINFO_CONTENT_LENGTH_UPLOAD
Pass a pointer to a double to receive the specified size of the upload.
(Added in 7.6.1)
.PP
.SH RETURN VALUE

View File

@@ -2,7 +2,7 @@
.\" nroff -man [file]
.\" Written by daniel@haxx.se
.\"
.TH curl_easy_setopt 3 "28 November 2000" "Curl 7.5" "libcurl Manual"
.TH curl_easy_setopt 3 "2 February 2001" "Curl 7.5" "libcurl Manual"
.SH NAME
curl_easy_setopt - Set curl easy-session options
.SH SYNOPSIS
@@ -35,6 +35,12 @@ Data pointer to pass instead of FILE * to the file write function. Note that
if you specify the
.I CURLOPT_WRITEFUNCTION
, this is the pointer you'll get as input.
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.
.TP
.B CURLOPT_WRITEFUNCTION
Function pointer that should use match the following prototype:
@@ -53,6 +59,12 @@ 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.
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.
.TP
.B CURLOPT_READFUNCTION
Function pointer that should use match the following prototype:

View File

@@ -452,8 +452,8 @@ char *curl_getenv(char *variable);
char *curl_version(void);
/* This is the version number */
#define LIBCURL_VERSION "7.6"
#define LIBCURL_VERSION_NUM 0x070600
#define LIBCURL_VERSION "7.6.1-pre3"
#define LIBCURL_VERSION_NUM 0x070601
/* linked-list structure for the CURLOPT_QUOTE option (and other) */
struct curl_slist {
@@ -554,7 +554,7 @@ CURLcode curl_setopt(CURL *handle, CURLoption option, ...);
CURLcode curl_close(CURL *curl); /* the opposite of curl_open() */
CURLcode curl_read(CURLconnect *c_conn, char *buf, size_t buffersize,
size_t *n);
ssize_t *n);
CURLcode curl_write(CURLconnect *c_conn, char *buf, size_t amount,
size_t *n);
@@ -676,7 +676,10 @@ typedef enum {
CURLINFO_SSL_VERIFYRESULT = CURLINFO_LONG + 13,
CURLINFO_FILETIME = CURLINFO_LONG + 14,
CURLINFO_LASTONE = 15
CURLINFO_CONTENT_LENGTH_DOWNLOAD = CURLINFO_DOUBLE + 15,
CURLINFO_CONTENT_LENGTH_UPLOAD = CURLINFO_DOUBLE + 16,
CURLINFO_LASTONE = 17
} CURLINFO;
/*

271
lib/ftp.c
View File

@@ -221,7 +221,7 @@ int Curl_GetFTPResponse(int sockfd, char *buf,
int *ftpcode)
{
int nread;
size_t keepon=TRUE;
ssize_t keepon=TRUE;
char *ptr;
int timeout = 3600; /* in seconds */
struct timeval interval;
@@ -282,6 +282,8 @@ int Curl_GetFTPResponse(int sockfd, char *buf,
*/
if(CURLE_OK != Curl_read(conn, sockfd, ptr, 1, &keepon))
keepon = FALSE;
else if(keepon < 0)
error = SELECT_ERROR;
else if ((*ptr == '\n') || (*ptr == '\r'))
keepon = FALSE;
}
@@ -564,6 +566,9 @@ CURLcode _ftp(struct connectdata *conn)
#if defined (HAVE_INET_NTOA_R)
char ntoa_buf[64];
#endif
#ifdef ENABLE_IPV6
struct addrinfo *ai;
#endif
struct curl_slist *qitem; /* QUOTE item */
/* the ftp struct is already inited in ftp_connect() */
@@ -702,6 +707,178 @@ CURLcode _ftp(struct connectdata *conn)
/* We have chosen to use the PORT command */
if(data->bits.ftp_use_port) {
#ifdef ENABLE_IPV6
struct addrinfo hints, *res, *ai;
struct sockaddr_storage ss;
int sslen;
char hbuf[NI_MAXHOST];
char *localaddr;
struct sockaddr *sa=(struct sockaddr *)&ss;
#ifdef NI_WITHSCOPEID
const int niflags = NI_NUMERICHOST | NI_NUMERICSERV | NI_WITHSCOPEID;
#else
const int niflags = NI_NUMERICHOST | NI_NUMERICSERV;
#endif
unsigned char *ap;
unsigned char *pp;
int alen, plen;
char portmsgbuf[4096], tmp[4096];
char *p;
char *mode[] = { "EPRT", "LPRT", "PORT", NULL };
char **modep;
/*
* we should use Curl_if2ip? given pickiness of recent ftpd,
* I believe we should use the same address as the control connection.
*/
sslen = sizeof(ss);
if (getsockname(data->firstsocket, (struct sockaddr *)&ss, &sslen) < 0)
return CURLE_FTP_PORT_FAILED;
if (getnameinfo((struct sockaddr *)&ss, sslen, hbuf, sizeof(hbuf), NULL, 0,
niflags))
return CURLE_FTP_PORT_FAILED;
memset(&hints, 0, sizeof(hints));
hints.ai_family = sa->sa_family;
/*hints.ai_family = ss.ss_family;
this way can be used if sockaddr_storage is properly defined, as glibc
2.1.X doesn't do*/
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
if (getaddrinfo(hbuf, "0", &hints, &res))
return CURLE_FTP_PORT_FAILED;
portsock = -1;
for (ai = res; ai; ai = ai->ai_next) {
portsock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
if (portsock < 0)
continue;
if (bind(portsock, ai->ai_addr, ai->ai_addrlen) < 0) {
close(portsock);
portsock = -1;
continue;
}
if (listen(portsock, 1) < 0) {
close(portsock);
portsock = -1;
continue;
}
break;
}
if (portsock < 0) {
failf(data, strerror(errno));
freeaddrinfo(res);
return CURLE_FTP_PORT_FAILED;
}
sslen = sizeof(ss);
if (getsockname(portsock, sa, &sslen) < 0) {
failf(data, strerror(errno));
freeaddrinfo(res);
return CURLE_FTP_PORT_FAILED;
}
for (modep = mode; modep && *modep; modep++) {
int lprtaf, eprtaf;
switch (sa->sa_family) {
case AF_INET:
ap = (char *)&((struct sockaddr_in *)&ss)->sin_addr;
alen = sizeof(((struct sockaddr_in *)&ss)->sin_addr);
pp = (char *)&((struct sockaddr_in *)&ss)->sin_port;
plen = sizeof(((struct sockaddr_in *)&ss)->sin_port);
lprtaf = 4;
eprtaf = 1;
break;
case AF_INET6:
ap = (char *)&((struct sockaddr_in6 *)&ss)->sin6_addr;
alen = sizeof(((struct sockaddr_in6 *)&ss)->sin6_addr);
pp = (char *)&((struct sockaddr_in6 *)&ss)->sin6_port;
plen = sizeof(((struct sockaddr_in6 *)&ss)->sin6_port);
lprtaf = 6;
eprtaf = 2;
break;
default:
ap = pp = NULL;
lprtaf = eprtaf = -1;
break;
}
if (strcmp(*modep, "EPRT") == 0) {
if (eprtaf < 0)
continue;
if (getnameinfo((struct sockaddr *)&ss, sslen,
portmsgbuf, sizeof(portmsgbuf), tmp, sizeof(tmp), niflags))
continue;
/* do not transmit IPv6 scope identifier to the wire */
if (sa->sa_family == AF_INET6) {
char *q = strchr(portmsgbuf, '%');
if (q)
*q = '\0';
}
ftpsendf(data->firstsocket, conn, "%s |%d|%s|%s|", *modep, eprtaf,
portmsgbuf, tmp);
} else if (strcmp(*modep, "LPRT") == 0 || strcmp(*modep, "PORT") == 0) {
int i;
if (strcmp(*modep, "LPRT") == 0 && lprtaf < 0)
continue;
if (strcmp(*modep, "PORT") == 0 && sa->sa_family != AF_INET)
continue;
portmsgbuf[0] = '\0';
if (strcmp(*modep, "LPRT") == 0) {
snprintf(tmp, sizeof(tmp), "%d,%d", lprtaf, alen);
if (strlcat(portmsgbuf, tmp, sizeof(portmsgbuf)) >= sizeof(portmsgbuf)) {
goto again;
}
}
for (i = 0; i < alen; i++) {
if (portmsgbuf[0])
snprintf(tmp, sizeof(tmp), ",%u", ap[i]);
else
snprintf(tmp, sizeof(tmp), "%u", ap[i]);
if (strlcat(portmsgbuf, tmp, sizeof(portmsgbuf)) >= sizeof(portmsgbuf)) {
goto again;
}
}
if (strcmp(*modep, "LPRT") == 0) {
snprintf(tmp, sizeof(tmp), ",%d", plen);
if (strlcat(portmsgbuf, tmp, sizeof(portmsgbuf)) >= sizeof(portmsgbuf))
goto again;
}
for (i = 0; i < plen; i++) {
snprintf(tmp, sizeof(tmp), ",%u", pp[i]);
if (strlcat(portmsgbuf, tmp, sizeof(portmsgbuf)) >= sizeof(portmsgbuf)) {
goto again;
}
}
ftpsendf(data->firstsocket, conn, "%s %s", *modep, portmsgbuf);
}
nread = Curl_GetFTPResponse(data->firstsocket, buf, conn, &ftpcode);
if (nread < 0)
return CURLE_OPERATION_TIMEOUTED;
if (ftpcode != 200) {
failf(data, "Server does not grok %s", *modep);
continue;
} else
break;
again:;
}
if (!*modep) {
close(portsock);
freeaddrinfo(res);
return CURLE_FTP_PORT_FAILED;
}
#else
struct sockaddr_in sa;
struct hostent *h=NULL;
char *hostdataptr=NULL;
@@ -809,26 +986,43 @@ CURLcode _ftp(struct connectdata *conn)
failf(data, "Server does not grok PORT, try without it!");
return CURLE_FTP_PORT_FAILED;
}
#endif /* ENABLE_IPV6 */
}
else { /* we use the PASV command */
#if 0
char *mode[] = { "EPSV", "LPSV", "PASV", NULL };
int results[] = { 229, 228, 227, 0 };
#else
char *mode[] = { "PASV", NULL };
int results[] = { 227, 0 };
#endif
int modeoff;
ftpsendf(data->firstsocket, conn, "PASV");
for (modeoff = 0; mode[modeoff]; modeoff++) {
ftpsendf(data->firstsocket, conn, mode[modeoff]);
nread = Curl_GetFTPResponse(data->firstsocket, buf, conn, &ftpcode);
if(nread < 0)
return CURLE_OPERATION_TIMEOUTED;
nread = Curl_GetFTPResponse(data->firstsocket, buf, conn, &ftpcode);
if(nread < 0)
return CURLE_OPERATION_TIMEOUTED;
if (ftpcode == results[modeoff])
break;
}
if(ftpcode != 227) {
if (!mode[modeoff]) {
failf(data, "Odd return code after PASV");
return CURLE_FTP_WEIRD_PASV_REPLY;
}
else {
else if (strcmp(mode[modeoff], "PASV") == 0) {
int ip[4];
int port[2];
unsigned short newport; /* remote port, not necessary the local one */
unsigned short connectport; /* the local port connect() should use! */
char newhost[32];
#ifdef ENABLE_IPV6
struct addrinfo *res;
#else
struct hostent *he;
#endif
char *str=buf,*ip_addr;
char *hostdataptr=NULL;
@@ -863,20 +1057,78 @@ CURLcode _ftp(struct connectdata *conn)
* proxy again here. We already have the name info for it since the
* previous lookup.
*/
#ifdef ENABLE_IPV6
res = conn->res;
#else
he = conn->hp;
#endif
connectport =
(unsigned short)data->port; /* we connect to the proxy's port */
}
else {
/* normal, direct, ftp connection */
#ifdef ENABLE_IPV6
res = Curl_getaddrinfo(data, newhost, newport);
if(!res)
#else
he = Curl_gethost(data, newhost, &hostdataptr);
if(!he) {
if(!he)
#endif
{
failf(data, "Can't resolve new host %s", newhost);
return CURLE_FTP_CANT_GET_HOST;
}
connectport = newport; /* we connect to the remote port */
}
#ifdef ENABLE_IPV6
data->secondarysocket = -1;
for (ai = res; ai; ai = ai->ai_next) {
/* XXX for now, we can do IPv4 only */
if (ai->ai_family != AF_INET)
continue;
data->secondarysocket = socket(ai->ai_family, ai->ai_socktype,
ai->ai_protocol);
if (data->secondarysocket < 0)
continue;
if(data->bits.verbose) {
char hbuf[NI_MAXHOST];
char nbuf[NI_MAXHOST];
char sbuf[NI_MAXSERV];
#ifdef NI_WITHSCOPEID
const int niflags = NI_NUMERICHOST | NI_NUMERICSERV | NI_WITHSCOPEID;
#else
const int niflags = NI_NUMERICHOST | NI_NUMERICSERV;
#endif
if (getnameinfo(res->ai_addr, res->ai_addrlen, nbuf, sizeof(nbuf),
sbuf, sizeof(sbuf), niflags)) {
snprintf(nbuf, sizeof(nbuf), "?");
snprintf(sbuf, sizeof(sbuf), "?");
}
if (getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, sizeof(hbuf),
NULL, 0, 0)) {
infof(data, "Connecting to %s port %s\n", nbuf, sbuf);
} else {
infof(data, "Connecting to %s (%s) port %s\n", hbuf, nbuf, sbuf);
}
}
if (connect(data->secondarysocket, ai->ai_addr, ai->ai_addrlen) < 0) {
close(data->secondarysocket);
data->secondarysocket = -1;
continue;
}
break;
}
if (data->secondarysocket < 0) {
failf(data, strerror(errno));
return CURLE_FTP_CANT_RECONNECT;
}
#else
data->secondarysocket = socket(AF_INET, SOCK_STREAM, 0);
memset((char *) &serv_addr, '\0', sizeof(serv_addr));
@@ -971,6 +1223,7 @@ CURLcode _ftp(struct connectdata *conn)
}
return CURLE_FTP_CANT_RECONNECT;
}
#endif /*ENABLE_IPV6*/
if (data->bits.tunnel_thru_httpproxy) {
/* We want "seamless" FTP operations through HTTP proxy tunnel */
@@ -979,6 +1232,8 @@ CURLcode _ftp(struct connectdata *conn)
if(CURLE_OK != result)
return result;
}
} else {
return CURLE_FTP_CANT_RECONNECT;
}
}
/* we have the (new) data connection ready */

View File

@@ -103,6 +103,12 @@ CURLcode curl_getinfo(CURL *curl, CURLINFO info, ...)
case CURLINFO_SSL_VERIFYRESULT:
*param_longp = data->ssl.certverifyresult;
break;
case CURLINFO_CONTENT_LENGTH_DOWNLOAD:
*param_doublep = data->progress.size_dl;
break;
case CURLINFO_CONTENT_LENGTH_UPLOAD:
*param_doublep = data->progress.size_ul;
break;
default:
return CURLE_BAD_FUNCTION_ARGUMENT;
}

View File

@@ -83,6 +83,29 @@ static char *MakeIP(unsigned long num,char *addr, int addr_len)
return (addr);
}
#ifdef ENABLE_IPV6
struct addrinfo *Curl_getaddrinfo(struct UrlData *data,
char *hostname,
int port)
{
struct addrinfo hints, *res;
int error;
char sbuf[NI_MAXSERV];
memset(&hints, 0, sizeof(hints));
hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_CANONNAME;
snprintf(sbuf, sizeof(sbuf), "%d", port);
error = getaddrinfo(hostname, sbuf, &hints, &res);
if (error) {
infof(data, "getaddrinfo(3) failed for %s\n", hostname);
return NULL;
}
return res;
}
#endif
/* The original code to this function was once stolen from the Dancer source
code, written by Bjorn Reese, it has since been patched and modified
considerably. */

View File

@@ -23,6 +23,11 @@
* $Id$
*****************************************************************************/
struct addrinfo;
struct addrinfo *Curl_getaddrinfo(struct UrlData *data,
char *hostname,
int port);
struct hostent *Curl_gethost(struct UrlData *data,
char *hostname,
char **bufp);

View File

@@ -214,7 +214,7 @@ CURLcode add_buffer(send_buffer *in, void *inptr, size_t size)
static
int GetLine(int sockfd, char *buf, struct connectdata *conn)
{
size_t nread;
ssize_t nread;
int read_rc=1;
char *ptr;
struct UrlData *data=conn->data;
@@ -226,17 +226,18 @@ int GetLine(int sockfd, char *buf, struct connectdata *conn)
(nread<BUFSIZE) && read_rc;
nread++, ptr++) {
if((CURLE_OK != Curl_read(conn, sockfd, ptr, 1, &nread)) ||
(nread <= 0) ||
(*ptr == '\n'))
break;
}
*ptr=0; /* zero terminate */
if(data->bits.verbose) {
fputs("< ", data->err);
fwrite(buf, 1, nread, data->err);
fputs("\n", data->err);
}
return nread;
return nread>0?nread:0;
}
@@ -429,9 +430,6 @@ CURLcode Curl_http(struct connectdata *conn)
}
}
}
if((data->bits.set_range) && !checkheaders(data, "Range:")) {
data->ptr_rangeline = aprintf("Range: bytes=%s\015\012", data->range);
}
if((data->bits.http_set_referer) && !checkheaders(data, "Referer:")) {
data->ptr_ref = aprintf("Referer: %s\015\012", data->referer);
}
@@ -528,6 +526,34 @@ CURLcode Curl_http(struct connectdata *conn)
/* we've passed, proceed as normal */
}
}
if(data->bits.set_range) {
/*
* A range is selected. We use different headers whether we're downloading
* or uploading and we always let customized headers override our internal
* ones if any such are specified.
*/
if((data->httpreq == HTTPREQ_GET) &&
!checkheaders(data, "Range:")) {
data->ptr_rangeline = aprintf("Range: bytes=%s\r\n", data->range);
}
else if((data->httpreq != HTTPREQ_GET) &&
!checkheaders(data, "Content-Range:")) {
if(data->resume_from) {
/* This is because "resume" was selected */
long total_expected_size= data->resume_from + data->infilesize;
data->ptr_rangeline = aprintf("Content-Range: bytes %s%ld/%ld\r\n",
data->range, total_expected_size-1,
total_expected_size);
}
else {
/* Range was selected and then we just pass the incoming range and
append total size */
data->ptr_rangeline = aprintf("Content-Range: bytes %s/%d\r\n",
data->range, data->infilesize);
}
}
}
do {
send_buffer *req_buffer;

View File

@@ -24,7 +24,7 @@
*****************************************************************************/
#include "setup.h"
#if ! defined(WIN32) && ! defined(__BEOS__)
#if ! defined(WIN32) && ! defined(__BEOS__) && !defined(__CYGWIN32__)
extern char *Curl_if2ip(char *interface, char *buf, int buf_size);
#else
#define Curl_if2ip(a,b,c) NULL

View File

@@ -27,7 +27,8 @@
#include <stdlib.h>
#include <string.h>
#include "getenv.h"
#include <curl/curl.h>
#include "strequal.h"
/* Debug this single source file with:

View File

@@ -203,6 +203,9 @@ int Curl_pgrsUpdate(struct UrlData *data)
even when not displayed! */
else if(!(data->progress.flags & PGRS_HEADERS_OUT)) {
if (!data->progress.callback) {
if(data->resume_from)
fprintf(data->err, "** Resuming transfer from byte position %d\n",
data->resume_from);
fprintf(data->err,
" %% Total %% Received %% Xferd Average Speed Time Curr.\n"
" Dload Upload Total Current Left Speed\n");

View File

@@ -198,10 +198,10 @@ CURLcode Curl_client_write(struct UrlData *data,
*/
CURLcode Curl_read(struct connectdata *conn, int sockfd,
char *buf, size_t buffersize,
size_t *n)
ssize_t *n)
{
struct UrlData *data = conn->data;
size_t nread;
ssize_t nread;
#ifdef USE_SSLEAY
if (data->ssl.use) {
@@ -234,7 +234,7 @@ CURLcode Curl_read(struct connectdata *conn, int sockfd,
*/
CURLcode curl_read(CURLconnect *c_conn, char *buf, size_t buffersize,
size_t *n)
ssize_t *n)
{
struct connectdata *conn = (struct connectdata *)c_conn;

View File

@@ -47,7 +47,7 @@ CURLcode Curl_client_write(struct UrlData *data, int type, char *ptr,
/* internal read-function, does plain socket, SSL and krb4 */
CURLcode Curl_read(struct connectdata *conn, int sockfd,
char *buf, size_t buffersize,
size_t *n);
ssize_t *n);
/* internal write-function, does plain socket, SSL and krb4 */
CURLcode Curl_write(struct connectdata *conn, int sockfd,
void *mem, size_t len,

View File

@@ -66,3 +66,44 @@ int Curl_strnequal(const char *first, const char *second, size_t max)
#endif
}
#ifndef HAVE_STRLCAT
/*
* The strlcat() function appends the NUL-terminated string src to the end
* of dst. It will append at most size - strlen(dst) - 1 bytes, NUL-termi-
* nating the result.
*
* The strlcpy() and strlcat() functions return the total length of the
* string they tried to create. For strlcpy() that means the length of src.
* For strlcat() that means the initial length of dst plus the length of
* src. While this may seem somewhat confusing it was done to make trunca-
* tion detection simple.
*
*
*/
size_t strlcat(char *dst, const char *src, size_t siz)
{
char *d = dst;
const char *s = src;
size_t n = siz;
size_t dlen;
/* Find the end of dst and adjust bytes left but don't go past end */
while (n-- != 0 && *d != '\0')
d++;
dlen = d - dst;
n = siz - dlen;
if (n == 0)
return(dlen + strlen(s));
while (*s != '\0') {
if (n != 1) {
*d++ = *s;
n--;
}
s++;
}
*d = '\0';
return(dlen + (s - src)); /* count does not include NUL */
}
#endif

View File

@@ -833,7 +833,7 @@ CURLcode Curl_telnet(struct connectdata *conn)
bool keepon = TRUE;
char *buf = data->buffer;
size_t nread;
ssize_t nread;
init_telnet(data);
@@ -872,20 +872,22 @@ CURLcode Curl_telnet(struct connectdata *conn)
}
}
if(FD_ISSET(sockfd, &readfd))
if(FD_ISSET(sockfd, &readfd)) {
Curl_read(conn, sockfd, buf, BUFSIZE - 1, &nread);
/* if we receive 0 or less here, the server closed the connection and
we bail out from this! */
if (nread <= 0) {
keepon = FALSE;
break;
}
/* if we receive 0 or less here, the server closed the connection and
we bail out from this! */
if (nread <= 0) {
keepon = FALSE;
break;
}
telrcv(data, (unsigned char *)buf, nread);
telrcv(data, (unsigned char *)buf, nread);
}
}
}
return CURLE_OK;
/* mark this as "no further transfer wanted" */
return Curl_Transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
}

View File

@@ -82,7 +82,6 @@
#include <curl/types.h>
#include "netrc.h"
#include "getenv.h"
#include "hostip.h"
#include "transfer.h"
#include "sendf.h"
@@ -109,7 +108,7 @@
CURLcode static
_Transfer(struct connectdata *c_conn)
{
size_t nread; /* number of bytes read */
ssize_t nread; /* number of bytes read */
int bytecount = 0; /* total number of bytes read */
int writebytecount = 0; /* number of bytes written */
long contentlength=0; /* size of incoming data */
@@ -161,6 +160,12 @@ _Transfer(struct connectdata *c_conn)
Curl_pgrsTime(data, TIMER_PRETRANSFER);
Curl_speedinit(data);
if((conn->sockfd == -1) &&
(conn->writesockfd == -1)) {
/* nothing to read, nothing to write, we're already OK! */
return CURLE_OK;
}
if (!conn->getheader) {
header = FALSE;
if(conn->size > 0)
@@ -444,9 +449,14 @@ _Transfer(struct connectdata *c_conn)
write a chunk of the body */
if(conn->protocol&PROT_HTTP) {
/* HTTP-only checks */
if (data->resume_from &&
!content_range &&
(data->httpreq==HTTPREQ_GET)) {
if (data->newurl) {
/* abort after the headers if "follow Location" is set */
infof (data, "Follow to new URL: %s\n", data->newurl);
return CURLE_OK;
}
else if (data->resume_from &&
!content_range &&
(data->httpreq==HTTPREQ_GET)) {
/* we wanted to resume a download, although the server
doesn't seem to support this and we did this with a GET
(if it wasn't a GET we did a POST or PUT resume) */
@@ -454,11 +464,6 @@ _Transfer(struct connectdata *c_conn)
"byte ranges. Cannot resume.");
return CURLE_HTTP_RANGE_ERROR;
}
else if (data->newurl) {
/* abort after the headers if "follow Location" is set */
infof (data, "Follow to new URL: %s\n", data->newurl);
return CURLE_OK;
}
else if(data->timecondition && !data->range) {
/* A time condition has been set AND no ranges have been
requested. This seems to be what chapter 13.3.4 of
@@ -725,13 +730,48 @@ CURLcode curl_transfer(CURL *curl)
data->newurl = NULL; /* don't show! */
data->bits.urlstringalloc = TRUE; /* the URL is allocated */
/* Disable both types of POSTs, since doing a second POST when
following isn't what anyone would want! */
data->bits.http_post = FALSE;
data->bits.http_formpost = FALSE;
infof(data, "Follows Location: to new URL: '%s'\n", data->url);
/*
* We get here when the HTTP code is 300-399. We need to perform
* differently based on exactly what return code there was.
* Discussed on the curl mailing list and posted about on the 26th
* of January 2001.
*/
switch(data->progress.httpcode) {
case 300: /* Multiple Choices */
case 301: /* Moved Permanently */
case 302: /* Found */
case 306: /* Not used */
case 307: /* Temporary Redirect */
default: /* for all unknown ones */
/* These are explicitly mention since I've checked RFC2616 and they
* seem to be OK to POST to.
*/
break;
case 303: /* See Other */
/* Disable both types of POSTs, since doing a second POST when
* following isn't what anyone would want! */
data->bits.http_post = FALSE;
data->bits.http_formpost = FALSE;
data->httpreq = HTTPREQ_GET; /* enfore GET request */
infof(data, "Disables POST\n");
break;
case 304: /* Not Modified */
/* 304 means we did a conditional request and it was "Not modified".
* We shouldn't get any Location: header in this response!
*/
break;
case 305: /* Use Proxy */
/* (quote from RFC2616, section 10.3.6):
* "The requested resource MUST be accessed through the proxy given
* by the Location field. The Location field gives the URI of the
* proxy. The recipient is expected to repeat this single request
* via the proxy. 305 responses MUST only be generated by origin
* servers."
*/
break;
}
curl_disconnect(c_connect);
continue;
}

View File

@@ -80,7 +80,6 @@
#include "netrc.h"
#include "formdata.h"
#include "getenv.h"
#include "base64.h"
#include "ssluse.h"
#include "hostip.h"
@@ -339,10 +338,14 @@ CURLcode curl_setopt(CURL *curl, CURLoption option, ...)
break;
case CURLOPT_UPLOAD:
data->bits.upload = va_arg(param, long)?TRUE:FALSE;
if(data->bits.upload)
/* If this is HTTP, PUT is what's needed to "upload" */
data->httpreq = HTTPREQ_PUT;
break;
case CURLOPT_POST:
data->bits.http_post = va_arg(param, long)?TRUE:FALSE;
data->httpreq = HTTPREQ_POST;
if(data->bits.http_post)
data->httpreq = HTTPREQ_POST;
break;
case CURLOPT_FILETIME:
data->bits.get_filetime = va_arg(param, long)?TRUE:FALSE;
@@ -364,7 +367,8 @@ CURLcode curl_setopt(CURL *curl, CURLoption option, ...)
break;
case CURLOPT_PUT:
data->bits.http_put = va_arg(param, long)?TRUE:FALSE;
data->httpreq = HTTPREQ_PUT;
if(data->bits.http_put)
data->httpreq = HTTPREQ_PUT;
break;
case CURLOPT_MUTE:
data->bits.mute = va_arg(param, long)?TRUE:FALSE;
@@ -406,12 +410,14 @@ CURLcode curl_setopt(CURL *curl, CURLoption option, ...)
break;
case CURLOPT_CUSTOMREQUEST:
data->customrequest = va_arg(param, char *);
data->httpreq = HTTPREQ_CUSTOM;
if(data->customrequest)
data->httpreq = HTTPREQ_CUSTOM;
break;
case CURLOPT_HTTPPOST:
data->httppost = va_arg(param, struct HttpPost *);
data->bits.http_formpost = data->httppost?1:0;
data->httpreq = HTTPREQ_POST_FORM;
if(data->bits.http_formpost)
data->httpreq = HTTPREQ_POST_FORM;
break;
case CURLOPT_INFILE:
data->in = va_arg(param, FILE *);
@@ -555,8 +561,13 @@ CURLcode curl_disconnect(CURLconnect *c_connect)
struct UrlData *data = conn->data;
#ifdef ENABLE_IPV6
if(conn->res) /* host name info */
freeaddrinfo(conn->res);
#else
if(conn->hostent_buf) /* host name info */
free(conn->hostent_buf);
#endif
if(conn->path) /* the URL path part */
free(conn->path);
@@ -582,6 +593,9 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
struct sigaction sigact;
#endif
int urllen;
#ifdef ENABLE_IPV6
struct addrinfo *ai;
#endif
/*************************************************************
* Check input data
@@ -1182,13 +1196,23 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
data->port = data->remote_port; /* it is the same port */
/* Connect to target host right on */
#ifdef ENABLE_IPV6
conn->res = Curl_getaddrinfo(data, conn->name, data->port);
if(!conn->res)
#else
conn->hp = Curl_gethost(data, conn->name, &conn->hostent_buf);
if(!conn->hp) {
if(!conn->hp)
#endif
{
failf(data, "Couldn't resolve host '%s'", conn->name);
return CURLE_COULDNT_RESOLVE_HOST;
}
}
else {
#ifdef ENABLE_IPV6
failf(data, "proxy yet to be supported");
return CURLE_OUT_OF_MEMORY;
#else
char *prox_portno;
char *endofprot;
@@ -1237,9 +1261,11 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
}
free(proxydup); /* free the duplicate pointer and not the modified */
#endif
}
Curl_pgrsTime(data, TIMER_NAMELOOKUP);
#ifndef ENABLE_IPV6
data->firstsocket = socket(AF_INET, SOCK_STREAM, 0);
memset((char *) &conn->serv_addr, '\0', sizeof(conn->serv_addr));
@@ -1247,6 +1273,7 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
conn->hp->h_addr, conn->hp->h_length);
conn->serv_addr.sin_family = conn->hp->h_addrtype;
conn->serv_addr.sin_port = htons(data->port);
#endif
#if !defined(WIN32)||defined(__CYGWIN32__)
/* We don't generally like checking for OS-versions, we should make this
@@ -1259,6 +1286,7 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
#define INADDR_NONE (unsigned long) ~0
#endif
#ifndef ENABLE_IPV6
/*************************************************************
* Select device to bind socket to
*************************************************************/
@@ -1367,10 +1395,31 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
} /* end of device selection support */
#endif /* end of HAVE_INET_NTOA */
#endif /* end of not WIN32 */
#endif /*ENABLE_IPV6*/
/*************************************************************
* Connect to server/proxy
*************************************************************/
#ifdef ENABLE_IPV6
data->firstsocket = -1;
for (ai = conn->res; ai; ai = ai->ai_next) {
data->firstsocket = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
if (data->firstsocket < 0)
continue;
if (connect(data->firstsocket, ai->ai_addr, ai->ai_addrlen) < 0) {
close(data->firstsocket);
data->firstsocket = -1;
continue;
}
break;
}
if (data->firstsocket < 0) {
failf(data, strerror(errno));
return CURLE_COULDNT_CONNECT;
}
#else
if (connect(data->firstsocket,
(struct sockaddr *) &(conn->serv_addr),
sizeof(conn->serv_addr)
@@ -1419,6 +1468,7 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
}
return CURLE_COULDNT_CONNECT;
}
#endif
/*************************************************************
* Proxy authentication
@@ -1466,11 +1516,31 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
conn->bytecount = 0;
/* Figure out the ip-number and display the first host name it shows: */
#ifdef ENABLE_IPV6
{
char hbuf[NI_MAXHOST];
#ifdef NI_WITHSCOPEID
const int niflags = NI_NUMERICHOST | NI_WITHSCOPEID;
#else
const int niflags = NI_NUMERICHOST;
#endif
if (getnameinfo(ai->ai_addr, ai->ai_addrlen, hbuf, sizeof(hbuf), NULL, 0,
niflags)) {
snprintf(hbuf, sizeof(hbuf), "?");
}
if (ai->ai_canonname) {
infof(data, "Connected to %s (%s)\n", ai->ai_canonname, hbuf);
} else {
infof(data, "Connected to %s\n", hbuf);
}
}
#else
{
struct in_addr in;
(void) memcpy(&in.s_addr, *conn->hp->h_addr_list, sizeof (in.s_addr));
infof(data, "Connected to %s (%s)\n", conn->hp->h_name, inet_ntoa(in));
}
#endif
#ifdef __EMX__
/* 20000330 mgs
@@ -1502,8 +1572,13 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect)
if(conn) {
if(conn->path)
free(conn->path);
#ifdef ENABLE_IPV6
if(conn->res)
freeaddrinfo(conn->res);
#else
if(conn->hostent_buf)
free(conn->hostent_buf);
#endif
free(conn);
*in_connect=NULL;
}

View File

@@ -159,9 +159,13 @@ struct connectdata {
#define PROT_LDAP (1<<7)
#define PROT_FILE (1<<8)
#ifdef ENABLE_IPV6
struct addrinfo *res;
#else
char *hostent_buf; /* pointer to allocated memory for name info */
struct hostent *hp;
struct sockaddr_in serv_addr;
#endif
char proto[64]; /* store the protocol string in this buffer */
char gname[257]; /* store the hostname in this buffer */
char *name; /* host name pointer to fool around with */

View File

@@ -17,7 +17,7 @@ LINKR = link.exe /incremental:no /libpath:"../lib"
## Debug
CCD = cl.exe /MDd /Gm /ZI /Od /D "_DEBUG" /GZ
LINKD = link.exe /incremental:yes /debug
LINKD = link.exe /incremental:yes /debug /libpath:"../lib"
CFLAGS = /I "../include" /nologo /W3 /GX /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
LFLAGS = /nologo /out:$(PROGRAM_NAME) /subsystem:console /machine:I386

View File

@@ -109,7 +109,9 @@ typedef enum {
#define CONF_FOLLOWLOCATION (1<<23) /* use Location: Luke! */
#define CONF_GETTEXT (1<<24) /* use ASCII/text for transfer */
#define CONF_HTTPPOST (1<<25) /* multipart/form-data HTTP POST */
#if 0
#define CONF_PUT (1<<27) /* PUT the input file */
#endif
#define CONF_MUTE (1<<28) /* force NOPROGRESS */
#ifndef HAVE_STRDUP
@@ -1749,7 +1751,9 @@ operate(struct Configurable *config, int argc, char *argv[])
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION,
config->conf&CONF_FOLLOWLOCATION);
curl_easy_setopt(curl, CURLOPT_TRANSFERTEXT, config->conf&CONF_GETTEXT);
#if 0
curl_easy_setopt(curl, CURLOPT_PUT, config->conf&CONF_PUT);
#endif
curl_easy_setopt(curl, CURLOPT_MUTE, config->conf&CONF_MUTE);
curl_easy_setopt(curl, CURLOPT_USERPWD, config->userpwd);
curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, config->proxyuserpwd);

View File

@@ -1,3 +1,3 @@
#define CURL_NAME "curl"
#define CURL_VERSION "7.6"
#define CURL_VERSION "7.6.1-pre3"
#define CURL_ID CURL_NAME " " CURL_VERSION " (" OS ") "

View File

@@ -56,4 +56,10 @@ command26.txt prot26.txt command27.txt prot27.txt \
name26.txt reply26.txt name27.txt stdout27.txt \
command28.txt name28.txt prot28.txt reply28.txt \
command120.txt name120.txt prot120.txt reply120.txt \
command121.txt name121.txt prot121.txt reply121.txt
command121.txt name121.txt prot121.txt reply121.txt \
command29.txt error30.txt name30.txt prot30.txt reply30.txt \
command30.txt name29.txt prot29.txt reply29.txt \
command31.txt name32.txt reply31.txt reply32.txt \
command32.txt prot31.txt reply310001.txt reply320001.txt \
name31.txt prot32.txt reply310002.txt reply320002.txt \
command33.txt extra33.txt name33.txt prot33.txt reply33.txt

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

@@ -0,0 +1 @@
-C 200 http://%HOSTIP:%HOSTPORT/29

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

@@ -0,0 +1 @@
http://%HOSTIP:%HOSTPORT/30

2
tests/data/command31.txt Normal file
View File

@@ -0,0 +1,2 @@
http://%HOSTIP:%HOSTPORT/31 -d mooo=fooo -L

2
tests/data/command32.txt Normal file
View File

@@ -0,0 +1,2 @@
http://%HOSTIP:%HOSTPORT/32 -d mooo=fooo -L

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

@@ -0,0 +1,3 @@
http://%HOSTIP:%HOSTPORT/33 -Tdata/extra33.txt -C 50

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

@@ -0,0 +1 @@
18

15
tests/data/extra33.txt Normal file
View File

@@ -0,0 +1,15 @@
012345678
012345678
012345678
012345678
012345678
012345678
012345678
012345678
012345678
012345678
012345678
012345678
012345678
012345678
012345678

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

@@ -0,0 +1 @@
HTTP download resume with Content-Length validity

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

@@ -0,0 +1 @@
HTTP GET uncomplete document

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

@@ -0,0 +1 @@
HTTP POST and follow Location: (error 301)

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

@@ -0,0 +1 @@
HTTP POST and follow Location: (error 303)

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

@@ -0,0 +1 @@
HTTP PUT resume

7
tests/data/prot29.txt Normal file
View File

@@ -0,0 +1,7 @@
GET /29 HTTP/1.0
Range: bytes=200-
User-Agent: curl/7.6 (i686-pc-linux-gnu) libcurl 7.6 (SSL 0.9.5) (ipv6 enabled)
Host: 127.0.0.1:8999
Pragma: no-cache
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*

6
tests/data/prot30.txt Normal file
View File

@@ -0,0 +1,6 @@
GET /30 HTTP/1.0
User-Agent: curl/7.6 (i686-pc-linux-gnu) libcurl 7.6 (SSL 0.9.5) (ipv6 enabled)
Host: 127.0.0.1:8999
Pragma: no-cache
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*

9
tests/data/prot31.txt Normal file
View File

@@ -0,0 +1,9 @@
POST /moo/moo/moo/310002 HTTP/1.0
User-Agent: curl/7.6 (i686-pc-linux-gnu) libcurl 7.6 (SSL 0.9.5) (ipv6 enabled)
Host: 127.0.0.1:8999
Pragma: no-cache
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*
Content-Length: 9
Content-Type: application/x-www-form-urlencoded
mooo=fooo

6
tests/data/prot32.txt Normal file
View File

@@ -0,0 +1,6 @@
GET /moo/moo/moo/320002 HTTP/1.0
User-Agent: curl/7.6 (i686-pc-linux-gnu) libcurl 7.6 (SSL 0.9.5) (ipv6 enabled)
Host: 127.0.0.1:8999
Pragma: no-cache
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*

18
tests/data/prot33.txt Normal file
View File

@@ -0,0 +1,18 @@
PUT /33 HTTP/1.0
Content-Range: bytes 50-149/150
User-Agent: curl/7.6 (sparc-sun-solaris2.7) libcurl 7.6-pre4 (SSL 0.9.6) (krb4 enabled)
Host: 127.0.0.1:8999
Pragma: no-cache
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*
Content-Length: 100
012345678
012345678
012345678
012345678
012345678
012345678
012345678
012345678
012345678
012345678

9
tests/data/reply29.txt Normal file
View File

@@ -0,0 +1,9 @@
HTTP/1.1 200 OK
Server: fake
Content-Range: bytes 200-3526/3527
Content-Length: 84
The Content-Range header's contents above aren't really genuine for this
content.

7
tests/data/reply30.txt Normal file
View File

@@ -0,0 +1,7 @@
HTTP/1.1 200 OK
Server: fake
Content-Length: 8400
This file is a lot smaller than 8400 and thus curl should return an error
for this.

6
tests/data/reply31.txt Normal file
View File

@@ -0,0 +1,6 @@
HTTP/1.1 301 Moved Permanently
Server: fake
Location: /moo/moo/moo/310002
No contents

View File

@@ -0,0 +1,9 @@
HTTP/1.1 301 Moved Permanently
Server: fake
Location: /moo/moo/moo/310002
HTTP/1.1 200 Followed here fine
Date: Thu, 09 Nov 2010 14:49:00 GMT
Server: test-server/fake
If this is received, the location following worked

View File

@@ -0,0 +1,5 @@
HTTP/1.1 200 Followed here fine
Date: Thu, 09 Nov 2010 14:49:00 GMT
Server: test-server/fake
If this is received, the location following worked

7
tests/data/reply32.txt Normal file
View File

@@ -0,0 +1,7 @@
HTTP/1.1 303 See Other
Server: fake
Location: /moo/moo/moo/320002
This Location should be fetched with a GET!

View File

@@ -0,0 +1,9 @@
HTTP/1.1 303 See Other
Server: fake
Location: /moo/moo/moo/320002
HTTP/1.1 200 Followed here fine
Date: Thu, 09 Nov 2010 14:49:00 GMT
Server: test-server/fake
If this is received, the location following worked

View File

@@ -0,0 +1,5 @@
HTTP/1.1 200 Followed here fine
Date: Thu, 09 Nov 2010 14:49:00 GMT
Server: test-server/fake
If this is received, the location following worked

7
tests/data/reply33.txt Normal file
View File

@@ -0,0 +1,7 @@
HTTP/1.1 303 See Other
Server: fake
Location: /moo/moo/moo/320002
This Location should be fetched with a GET!

View File

@@ -119,7 +119,7 @@ for ( $waitedpid = 0;
$testnum=$1;
if($verbose) {
print STDERR "sending reply $testnum\n";
print STDERR "OUT: sending reply $testnum\n";
}
}
else {

View File

@@ -49,6 +49,7 @@ my $memanalyze="../memanalyze.pl";
my $short;
my $verbose;
my $debugprotocol;
my $anyway;
#######################################################################
@@ -109,7 +110,8 @@ sub runhttpserver {
}
if ($RUNNING != 1) {
system("perl $srcdir/httpserver.pl $HOSTPORT &");
my $flag=$debugprotocol?"-v ":"";
system("perl $srcdir/httpserver.pl $flag $HOSTPORT &");
sleep 1; # give it a little time to start
}
else {
@@ -150,7 +152,8 @@ sub runftpserver {
}
if ($RUNNING != 1) {
system("perl $srcdir/ftpserver.pl $FTPPORT &");
my $flag=$debugprotocol?"-v ":"";
system("perl $srcdir/ftpserver.pl $flag $FTPPORT &");
sleep 1; # give it a little time to start
}
else {
@@ -504,6 +507,8 @@ sub singletest {
unlink($STDOUT);
unlink($STDERR);
unlink("$LOGDIR/upload.$NUMBER"); # remove upload leftovers
unlink($CURLOUT); # remove the downloaded results
unlink($FTPDCMD); # remove the instructions for this test
if($memory_debug) {
@@ -551,6 +556,10 @@ do {
# verbose output
$verbose=1;
}
elsif ($ARGV[0] eq "-d") {
# have the servers display protocol output
$debugprotocol=1;
}
elsif($ARGV[0] eq "-s") {
# short output
$short=1;
@@ -564,6 +573,7 @@ do {
print <<EOHELP
Usage: runtests.pl [-h][-s][-v][numbers]
-a continue even if a test fails
-d display server debug info
-h this help text
-s short output
-v verbose output