Compare commits

..

77 Commits

Author SHA1 Message Date
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
Daniel Stenberg
ac98c73b04 7.6 2001-01-27 16:16:54 +00:00
Daniel Stenberg
a145654394 http upload resume 2001-01-26 15:53:33 +00:00
Daniel Stenberg
e8382ba290 moved the symbols talk to the library part, updated slightly to match 2001-01-26 15:52:51 +00:00
Daniel Stenberg
fcb347d124 Added a httpreq field in the main struct so that there's one field to check
for what HTTP request that is being used. The old bit-style fields are still
in there as well.
2001-01-26 15:52:01 +00:00
Daniel Stenberg
c331ef02f9 The check for that content-range is received must only be made if we requested
GET resume. Other resumes are upload-wise and don't care about this header
in the download stream
2001-01-26 15:50:56 +00:00
Daniel Stenberg
3a3f632bf0 Made it possible to do "upload resume" over HTTP 2001-01-26 15:49:39 +00:00
Daniel Stenberg
68d7b6f871 7.6-pre4 2001-01-25 13:48:28 +00:00
Daniel Stenberg
c43a9d9068 timespent is now updated in every call to the progress meter update function 2001-01-25 12:32:40 +00:00
Daniel Stenberg
64e80091db Rick's and Jeff's stuff 2001-01-25 12:31:44 +00:00
Daniel Stenberg
4f255ffbeb make the configure script die if select() or socket() is missing 2001-01-25 12:28:46 +00:00
Daniel Stenberg
80d75b0eaf Added Ingo Ralf Blum 2001-01-25 12:28:10 +00:00
Daniel Stenberg
808c4020e6 use this function only once note added 2001-01-25 12:27:44 +00:00
Daniel Stenberg
149d6363b3 modified the Curl_ConnectHTTPProxyTunnel proto 2001-01-25 12:24:34 +00:00
Daniel Stenberg
30eab8ca51 moved curl_read() and curl_write() to sendf.c 2001-01-25 12:23:57 +00:00
Daniel Stenberg
e49a82b06c converted to use Curl_read() and Curl_write() 2001-01-25 12:23:12 +00:00
Daniel Stenberg
45fdb48189 uses Curl_read() and Curl_write()
unfolded telwrite() instead of being a separate single function
2001-01-25 12:22:17 +00:00
Daniel Stenberg
3fcc9677c4 use recv()/send() instead of read()/write() with sockets 2001-01-25 12:21:10 +00:00
Daniel Stenberg
1552bd9c8c sendf is now only Curl_sendf
Curl_write() and Curl_read() are here
2001-01-25 12:20:30 +00:00
Daniel Stenberg
939c0c5521 removed two compiler warnings 2001-01-25 12:19:36 +00:00
Daniel Stenberg
f0b9aefd2e Curl_read() and Curl_write() are now used for reading/writing sockets.
Some functions changed prototype due to this change as well.
2001-01-25 12:19:02 +00:00
Daniel Stenberg
11f3c51e8f Get get-ftp-response function is now using Curl_read() for reading from a
socket. Curl_ConnectHTTPProxyTunnel changed prototype.
2001-01-25 12:17:07 +00:00
Daniel Stenberg
1a329b98a3 replaced sendf() calls with Curl_sendf() 2001-01-25 12:13:35 +00:00
Daniel Stenberg
29bcba9a90 Ingo Ralf Blum's cygwin fixes 2001-01-24 14:44:05 +00:00
Daniel Stenberg
1716dbb68a Robert Weaver's win32 getenv fix, my added comments in some files 2001-01-24 14:04:47 +00:00
Daniel Stenberg
16ecfcf62c Added Robert Weaver as contributor 2001-01-24 14:04:14 +00:00
Daniel Stenberg
8bafc3692d fixed the comment for 'path' 2001-01-24 14:03:48 +00:00
Daniel Stenberg
8a75120568 added comments all over 2001-01-24 12:32:34 +00:00
Daniel Stenberg
3d96ee7423 extended the gname field one byte to avoid a possible overflow
added lots of explaining comments
2001-01-24 12:10:10 +00:00
Daniel Stenberg
b3dbdfa306 Robert Weaver's fix 2001-01-24 09:01:32 +00:00
Daniel Stenberg
25bad589ba generated by autoheader 2001-01-23 13:00:43 +00:00
Daniel Stenberg
0b6cd75004 ipv6 adjustments 2001-01-23 10:29:16 +00:00
Daniel Stenberg
7872cc131a Enabled support for IPv6-style IP-addresses if ENABLE_IPV6 is set. If it isn't,
curl will return an error when such an address is used.
2001-01-23 10:21:30 +00:00
Daniel Stenberg
210aa4371c big reorg to make it not exit when it fails, but instead just not do any
globbing, it makes IPv6 support easier and smoother to add.
2001-01-23 10:14:43 +00:00
Daniel Stenberg
6f438bc8fb Added 'ipv6 enabled' for ipv6 compiled versions 2001-01-23 08:16:59 +00:00
Daniel Stenberg
65840f1fd1 Added simple IPv6 recognition support 2001-01-22 23:54:54 +00:00
Daniel Stenberg
5fc492e5c6 Bjrn's progress meter fix, new test cases and ftpserver.pl patch 2001-01-22 16:25:55 +00:00
Daniel Stenberg
abcd1e7d5a Bjrn Stenberg's patch for making the progress meter betterlooking 2001-01-22 16:21:05 +00:00
Daniel Stenberg
6429c378a2 the custom reply engine was not inited properly 2001-01-22 16:16:18 +00:00
Daniel Stenberg
d830f10417 test case 121 2001-01-22 16:05:12 +00:00
Daniel Stenberg
3d6fcbf97b Added test case 120, ftp with '-Q -' 2001-01-22 16:00:28 +00:00
Daniel Stenberg
609be218c2 Removed the deprecated -c and -t from the --help output. 2001-01-22 10:09:04 +00:00
Daniel Stenberg
41084e57ca Added 5.5 the CURLOPT_FILE problem on win32, DeYoung provided it! 2001-01-22 08:42:00 +00:00
Daniel Stenberg
9afab85105 Added -g/--globoff description 2001-01-19 12:24:46 +00:00
Daniel Stenberg
7822233964 Made the complaint on free-twice errors a lot better 2001-01-19 12:20:30 +00:00
Daniel Stenberg
022315089b removed URL length restrictions, added a test case 2001-01-19 12:20:02 +00:00
Daniel Stenberg
faa5c14aee No more URL length restrictions 2001-01-19 12:15:23 +00:00
Daniel Stenberg
3dd886955b removed MAX_URL_LENGTH, there is no longer any length restrictions on URLs
anywhere within libcurl
2001-01-19 12:14:55 +00:00
Daniel Stenberg
c2dbf21459 corrected url memory handling with --globoff 2001-01-19 12:14:09 +00:00
Daniel Stenberg
133eb220b9 Added files for test case 28 2001-01-19 12:13:37 +00:00
Daniel Stenberg
c5796d9e39 --globoff test case 2001-01-19 12:12:54 +00:00
71 changed files with 1280 additions and 779 deletions

121
CHANGES
View File

@@ -6,6 +6,127 @@
History of Changes
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.
- 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)
- Lots of mails back and forth with Bob Schader finally made me add a small
piece of code in the HTTP engine so that HTTP upload resume works. You can
now do an operation like 'curl -T file -C <offset> <URL>' and curl will PUT
the ending part of the file starting at given offet to the specified URL.
Version 7.6-pre4
Daniel (25 January 2001)
- I took hold of Rick Jones' question why we don't use recv() and send() for
reading/writing to the sockets and I've now modified the sread() and
swrite() macros to use them instead. If nothing else, they could be tested
in the next beta-round coming right up.
- Jeff Morrow found a problem with libcurl's usage of SSL_read() and supplied
his research results in how to fix this. It turns out we have to invoke the
function several times in some cases. The same goes for the SSL_write().
I made some rather drastic changes all over libcurl to make all writes and
reads get done on one single place so that this repeated-attempts thing
would only have to be implemented at one point.
- Rick Jones spotted that the 'total time' counter really didn't measure the
total time very accurate on subsecond levels.
- Johan Nilsson pointed out the need to more clearly specify that the timeout
value you set for a download is for the *entire* download. There's currently
no option available that sets a timeout for the connection phase only.
Daniel (24 January 2001)
- Ingo Ralf Blum submitted a series of patches required to get curl to compile
properly with cygwin.
- Robert Weaver posted a fix for the win32 section of the curl_getenv() code
that corrected a potential memory leak.
- Added comments in a few files in a sudden attempt to make the sources more
easy to read and understand!
Daniel (23 January 2001)
- Added simple IPv6 detection in the configure script and made the version
string add 'ipv6' to the enable section in that case. ENABLE_IPV6 will be
set if curl is compiled with IPv6 support enabled.
- Added a parser for IPv6-style specified IP-addresses in a URL. Thus, when
IPv6 gets enabled soon, we can use URLs like '[0::1]:80'...
- Made the URL globbing in the client possible to fail silently if there's an
error in the globbing. It makes it almost intuitive, so when you don't
follow the syntax rules, globbing is simply switched off and the raw string
is used instead.
I still think we'll get problems with IPv6-style IP-addresses when we *want*
globbing on parts of the URL as the initial part of the URL will for sure
seriously confuse the globber.
Daniel (22 January 2001)
- Bj<42>rn Stenberg supplied a progress meter patch that makes it look better even
during slow starts. Previously it made some silly assumptions...
- Added two FTP tests for -Q and -Q - stuff since it was being discussed on
the mailing list. Had to correct the ftpserver.pl too as it bugged slightly.
Daniel (19 January 2001)
- Made the Location: parsers deal with any-length URLs. Thus I removed the last
code that restricts the length of URLs that curl supports.
- Added a --globoff test case (#28) and it quickly identified a memory problem
in src/main.c that I took care of.
Version 7.6-pre3
Daniel (17 January 2001)
- Made the two former files lib/download.c and lib/highlevel.c become the new
lib/transfer.c which makes more sense. I also did the rename from Transfer()

View File

@@ -36,3 +36,6 @@
/* Define if you have the Kerberos4 libraries (including -ldes) */
#undef KRB4
/* Define if you want to enable IPv6 support */
#undef ENABLE_IPV6

View File

@@ -1,312 +0,0 @@
/* config.h.in. Generated automatically from configure.in by autoheader. */
/* Define if on AIX 3.
System headers sometimes define this.
We just want to avoid a redefinition error message. */
#ifndef _ALL_SOURCE
#undef _ALL_SOURCE
#endif
/* Define to empty if the keyword does not work. */
#undef const
/* Define as the return type of signal handlers (int or void). */
#undef RETSIGTYPE
/* Define to `unsigned' if <sys/types.h> doesn't define. */
#undef size_t
/* Define if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Define if you can safely include both <sys/time.h> and <time.h>. */
#undef TIME_WITH_SYS_TIME
/* Define cpu-machine-OS */
#undef OS
/* Define if you have the gethostbyaddr_r() function with 5 arguments */
#undef HAVE_GETHOSTBYADDR_R_5
/* Define if you have the gethostbyaddr_r() function with 7 arguments */
#undef HAVE_GETHOSTBYADDR_R_7
/* Define if you have the gethostbyaddr_r() function with 8 arguments */
#undef HAVE_GETHOSTBYADDR_R_8
/* Define if you have the gethostbyname_r() function with 3 arguments */
#undef HAVE_GETHOSTBYNAME_R_3
/* Define if you have the gethostbyname_r() function with 5 arguments */
#undef HAVE_GETHOSTBYNAME_R_5
/* Define if you have the gethostbyname_r() function with 6 arguments */
#undef HAVE_GETHOSTBYNAME_R_6
/* Define if you have the inet_ntoa_r function declared. */
#undef HAVE_INET_NTOA_R_DECL
/* Define if you need the _REENTRANT define for some functions */
#undef NEED_REENTRANT
/* Define if you have the Kerberos4 libraries (including -ldes) */
#undef KRB4
/* The number of bytes in a long double. */
#undef SIZEOF_LONG_DOUBLE
/* The number of bytes in a long long. */
#undef SIZEOF_LONG_LONG
/* Define if you have the RAND_screen function. */
#undef HAVE_RAND_SCREEN
/* Define if you have the RAND_status function. */
#undef HAVE_RAND_STATUS
/* Define if you have the closesocket function. */
#undef HAVE_CLOSESOCKET
/* Define if you have the gethostbyaddr function. */
#undef HAVE_GETHOSTBYADDR
/* Define if you have the gethostbyaddr_r function. */
#undef HAVE_GETHOSTBYADDR_R
/* Define if you have the gethostbyname_r function. */
#undef HAVE_GETHOSTBYNAME_R
/* Define if you have the gethostname function. */
#undef HAVE_GETHOSTNAME
/* Define if you have the getpass_r function. */
#undef HAVE_GETPASS_R
/* Define if you have the getservbyname function. */
#undef HAVE_GETSERVBYNAME
/* Define if you have the gettimeofday function. */
#undef HAVE_GETTIMEOFDAY
/* Define if you have the inet_addr function. */
#undef HAVE_INET_ADDR
/* Define if you have the inet_ntoa function. */
#undef HAVE_INET_NTOA
/* Define if you have the inet_ntoa_r function. */
#undef HAVE_INET_NTOA_R
/* Define if you have the krb_get_our_ip_for_realm function. */
#undef HAVE_KRB_GET_OUR_IP_FOR_REALM
/* Define if you have the localtime_r function. */
#undef HAVE_LOCALTIME_R
/* Define if you have the perror function. */
#undef HAVE_PERROR
/* Define if you have the select function. */
#undef HAVE_SELECT
/* Define if you have the setvbuf function. */
#undef HAVE_SETVBUF
/* Define if you have the sigaction function. */
#undef HAVE_SIGACTION
/* Define if you have the signal function. */
#undef HAVE_SIGNAL
/* Define if you have the socket function. */
#undef HAVE_SOCKET
/* Define if you have the strcasecmp function. */
#undef HAVE_STRCASECMP
/* Define if you have the strcmpi function. */
#undef HAVE_STRCMPI
/* Define if you have the strdup function. */
#undef HAVE_STRDUP
/* Define if you have the strftime function. */
#undef HAVE_STRFTIME
/* Define if you have the stricmp function. */
#undef HAVE_STRICMP
/* Define if you have the strlcpy function. */
#undef HAVE_STRLCPY
/* Define if you have the strstr function. */
#undef HAVE_STRSTR
/* Define if you have the tcgetattr function. */
#undef HAVE_TCGETATTR
/* Define if you have the tcsetattr function. */
#undef HAVE_TCSETATTR
/* Define if you have the uname function. */
#undef HAVE_UNAME
/* Define if you have the <alloca.h> header file. */
#undef HAVE_ALLOCA_H
/* Define if you have the <arpa/inet.h> header file. */
#undef HAVE_ARPA_INET_H
/* Define if you have the <crypto.h> header file. */
#undef HAVE_CRYPTO_H
/* Define if you have the <des.h> header file. */
#undef HAVE_DES_H
/* Define if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
/* Define if you have the <err.h> header file. */
#undef HAVE_ERR_H
/* Define if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H
/* Define if you have the <getopt.h> header file. */
#undef HAVE_GETOPT_H
/* Define if you have the <io.h> header file. */
#undef HAVE_IO_H
/* Define if you have the <krb.h> header file. */
#undef HAVE_KRB_H
/* Define if you have the <malloc.h> header file. */
#undef HAVE_MALLOC_H
/* Define if you have the <net/if.h> header file. */
#undef HAVE_NET_IF_H
/* Define if you have the <netdb.h> header file. */
#undef HAVE_NETDB_H
/* Define if you have the <netinet/if_ether.h> header file. */
#undef HAVE_NETINET_IF_ETHER_H
/* Define if you have the <netinet/in.h> header file. */
#undef HAVE_NETINET_IN_H
/* Define if you have the <openssl/crypto.h> header file. */
#undef HAVE_OPENSSL_CRYPTO_H
/* Define if you have the <openssl/err.h> header file. */
#undef HAVE_OPENSSL_ERR_H
/* Define if you have the <openssl/pem.h> header file. */
#undef HAVE_OPENSSL_PEM_H
/* Define if you have the <openssl/rsa.h> header file. */
#undef HAVE_OPENSSL_RSA_H
/* Define if you have the <openssl/ssl.h> header file. */
#undef HAVE_OPENSSL_SSL_H
/* Define if you have the <openssl/x509.h> header file. */
#undef HAVE_OPENSSL_X509_H
/* Define if you have the <pem.h> header file. */
#undef HAVE_PEM_H
/* Define if you have the <rsa.h> header file. */
#undef HAVE_RSA_H
/* Define if you have the <sgtty.h> header file. */
#undef HAVE_SGTTY_H
/* Define if you have the <ssl.h> header file. */
#undef HAVE_SSL_H
/* Define if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define if you have the <sys/param.h> header file. */
#undef HAVE_SYS_PARAM_H
/* Define if you have the <sys/select.h> header file. */
#undef HAVE_SYS_SELECT_H
/* Define if you have the <sys/socket.h> header file. */
#undef HAVE_SYS_SOCKET_H
/* Define if you have the <sys/sockio.h> header file. */
#undef HAVE_SYS_SOCKIO_H
/* Define if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define if you have the <sys/time.h> header file. */
#undef HAVE_SYS_TIME_H
/* Define if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define if you have the <termio.h> header file. */
#undef HAVE_TERMIO_H
/* Define if you have the <termios.h> header file. */
#undef HAVE_TERMIOS_H
/* Define if you have the <time.h> header file. */
#undef HAVE_TIME_H
/* Define if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define if you have the <winsock.h> header file. */
#undef HAVE_WINSOCK_H
/* Define if you have the <x509.h> header file. */
#undef HAVE_X509_H
/* Define if you have the crypto library (-lcrypto). */
#undef HAVE_LIBCRYPTO
/* Define if you have the dl library (-ldl). */
#undef HAVE_LIBDL
/* Define if you have the nsl library (-lnsl). */
#undef HAVE_LIBNSL
/* Define if you have the resolv library (-lresolv). */
#undef HAVE_LIBRESOLV
/* Define if you have the resolve library (-lresolve). */
#undef HAVE_LIBRESOLVE
/* Define if you have the socket library (-lsocket). */
#undef HAVE_LIBSOCKET
/* Define if you have the ssl library (-lssl). */
#undef HAVE_LIBSSL
/* Define if you have the ucb library (-lucb). */
#undef HAVE_LIBUCB
/* Name of package */
#undef PACKAGE
/* Version number of package */
#undef VERSION
/* Number of bits in a file offset, on hosts where this is settable. */
#undef _FILE_OFFSET_BITS
/* Define to make ftello visible on some hosts (e.g. HP-UX 10.20). */
#undef _LARGEFILE_SOURCE
/* Define for large files, on AIX-style hosts. */
#undef _LARGE_FILES
/* Set to explicitly specify we don't want to use thread-safe functions */
#undef DISABLED_THREADSAFE

View File

@@ -26,6 +26,72 @@ 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( [
#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
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
@@ -237,6 +303,47 @@ exit (rc != 0 ? 1 : 0); }],[
])
dnl **********************************************************************
dnl Checks for IPv6
dnl **********************************************************************
AC_MSG_CHECKING([whether to enable ipv6])
AC_ARG_ENABLE(ipv6,
[ --enable-ipv6 Enable ipv6 (with ipv4) support
--disable-ipv6 Disable ipv6 support],
[ case "$enableval" in
no)
AC_MSG_RESULT(no)
ipv6=no
;;
*) AC_MSG_RESULT(yes)
ipv6=yes
;;
esac ],
AC_TRY_RUN([ /* is AF_INET6 available? */
#include <sys/types.h>
#include <sys/socket.h>
main()
{
if (socket(AF_INET6, SOCK_STREAM, 0) < 0)
exit(1);
else
exit(0);
}
],
AC_MSG_RESULT(yes)
ipv6=yes,
AC_MSG_RESULT(no)
ipv6=no,
AC_MSG_RESULT(no)
ipv6=no
))
if test "$ipv6" = "yes"; then
CURL_CHECK_WORKING_GETADDRINFO
fi
dnl **********************************************************************
dnl Checks for libraries.
@@ -590,6 +697,9 @@ AC_CHECK_FUNCS( socket \
dnl removed 'getpass' check on October 26, 2000
if test "$ac_cv_func_select" != "yes"; then
AC_MSG_ERROR(Can't work without an existing select() function)
fi
if test "$ac_cv_func_socket" != "yes"; then
AC_MSG_ERROR(Can't work without an existing socket() function)
fi

View File

@@ -1,4 +1,4 @@
Updated: January 15, 2001 (http://curl.haxx.se/docs/faq.shtml)
Updated: January 29, 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,6 +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.6 What about Keep-Alive or persistant connections?
6. License Issues
6.1 I have a GPL program, can I use the libcurl library?
@@ -278,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.
@@ -309,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
@@ -472,6 +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 ?
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*.
(provided by Joel DeYoung)
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
NOTE: This section is now updated to concern curl 7.5.2 or later!

View File

@@ -1,3 +1,4 @@
Updated for curl 7.6 on January 26, 2001
_ _ ____ _
___| | | | _ \| |
/ __| | | | |_) | |
@@ -12,13 +13,6 @@ INTERNALS
Thus, the largest amount of code and complexity is in the library part.
SYMBOLS
=======
All symbols used internally must use a 'Curl_' prefix if they're used in more
than a single file. Single-file symbols must be made static. Public
(exported) symbols must use a 'curl_' prefix. (There are exceptions, but they
are destined to be changed to follow this pattern in the future.)
CVS
===
All changes to the sources are committed to the CVS repository as soon as
@@ -35,10 +29,11 @@ Windows vs Unix
There are a few differences in how to program curl the unix way compared to
the Windows way. The four perhaps most notable details are:
1. Different function names for close(), read(), write()
1. Different function names for socket operations.
In curl, this is solved with defines and macros, so that the source looks
the same at all places except for the header file that defines them.
the same at all places except for the header file that defines them. The
macros in use are sclose(), sread() and swrite().
2. Windows requires a couple of init calls for the socket stuff
@@ -187,6 +182,15 @@ Library
exists in lib/getpass.c. libcurl offers a custom callback that can be used
instead of this, but it doesn't change much to us.
Library Symbols
===============
All symbols used internally in libcurl must use a 'Curl_' prefix if they're
used in more than a single file. Single-file symbols must be made
static. Public (exported) symbols must use a 'curl_' prefix. (There are
exceptions, but they are destined to be changed to follow this pattern in the
future.)
Return Codes and Informationals
===============================

View File

@@ -2,7 +2,7 @@
.\" nroff -man curl.1
.\" Written by Daniel Stenberg
.\"
.TH curl 1 "9 January 2001" "Curl 7.6" "Curl Manual"
.TH curl 1 "19 January 2001" "Curl 7.6" "Curl Manual"
.SH NAME
curl \- get a URL with FTP, TELNET, LDAP, GOPHER, DICT, FILE, HTTP or
HTTPS syntax.
@@ -205,6 +205,12 @@ To read the file's content from stdin insted of a file, use - where the file
name should've been. This goes for both @ and < constructs.
This option can be used multiple times.
.IP "-g/--globoff"
This option switches off the "URL globbing parser". When you set this option,
you can specify URLs that contain the letters {}[] without having them being
interpreted by curl itself. Note that these letters are not normal legal URL
contents but they should be encoded according to the URI standard. (Option
added in curl 7.6)
.IP "-h/--help"
Usage help.
.IP "-H/--header <header>"
@@ -780,6 +786,8 @@ If you do find bugs, mail them to curl-bug@haxx.se.
- Alexander Kourakos <awk@users.sourceforge.net>
- James Griffiths <griffiths_james@yahoo.com>
- Loic Dachary <loic@senga.org>
- Robert Weaver <robert.weaver@sabre.com>
- Ingo Ralf Blum <ingoralfblum@ingoralfblum.com>
.SH WWW
http://curl.haxx.se

View File

@@ -2,7 +2,7 @@
.\" nroff -man [file]
.\" Written by daniel@haxx.se
.\"
.TH curl_easy_perform 3 "26 May 2000" "Curl 7.0" "libcurl Manual"
.TH curl_easy_perform 3 "25 Jan 2001" "Curl 7.0" "libcurl Manual"
.SH NAME
curl_easy_perform - Do the actual transfer in a "easy" session
.SH SYNOPSIS
@@ -16,6 +16,10 @@ are made, and will perform the transfer as described in the options.
It must be called with the same
.I handle
as input as the curl_easy_init call returned.
You are only allowed to call this function once using the same handle. If you
want to do repeated calls, you must call curl_easy_cleanup and curl_easy_init
again first.
.SH RETURN VALUE
0 means everything was ok, non-zero means an error occurred as
.I <curl/curl.h>

View File

@@ -166,10 +166,6 @@ typedef enum {
#define CURL_ERROR_SIZE 256
/* maximum URL length we deal with in headers */
#define URL_MAX_LENGTH 4096
#define URL_MAX_LENGTH_TXT "4095"
/* name is uppercase CURLOPT_<name>,
type is one of the defined CURLOPTTYPE_<type>
number is unique identifier */
@@ -456,8 +452,8 @@ char *curl_getenv(char *variable);
char *curl_version(void);
/* This is the version number */
#define LIBCURL_VERSION "7.6-pre3"
#define LIBCURL_VERSION_NUM 0x070600
#define LIBCURL_VERSION "7.6.1-pre2"
#define LIBCURL_VERSION_NUM 0x070601
/* linked-list structure for the CURLOPT_QUOTE option (and other) */
struct curl_slist {
@@ -558,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);

View File

@@ -141,7 +141,7 @@ CURLcode Curl_dict(struct connectdata *conn)
nth = atoi(nthdef);
}
sendf(data->firstsocket, data,
Curl_sendf(data->firstsocket, conn,
"CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\n"
"MATCH "
"%s " /* database */
@@ -191,7 +191,7 @@ CURLcode Curl_dict(struct connectdata *conn)
nth = atoi(nthdef);
}
sendf(data->firstsocket, data,
Curl_sendf(data->firstsocket, conn,
"CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\n"
"DEFINE "
"%s " /* database */
@@ -220,7 +220,7 @@ CURLcode Curl_dict(struct connectdata *conn)
if (ppath[i] == ':')
ppath[i] = ' ';
}
sendf(data->firstsocket, data,
Curl_sendf(data->firstsocket, conn,
"CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\n"
"%s\n"
"QUIT\n",

View File

@@ -221,7 +221,7 @@ int Curl_GetFTPResponse(int sockfd, char *buf,
int *ftpcode)
{
int nread;
int keepon=TRUE;
ssize_t keepon=TRUE;
char *ptr;
int timeout = 3600; /* in seconds */
struct timeval interval;
@@ -272,22 +272,17 @@ int Curl_GetFTPResponse(int sockfd, char *buf,
break;
case 0: /* timeout */
error = SELECT_TIMEOUT;
infof(data, "Transfer aborted due to timeout\n");
failf(data, "Transfer aborted due to timeout");
break;
default:
#ifdef USE_SSLEAY
if (data->ssl.use) {
keepon = SSL_read(data->ssl.handle, ptr, 1);
}
else {
#endif
keepon = sread(sockfd, ptr, 1);
#ifdef USE_SSLEAY
}
#endif /* USE_SSLEAY */
if ((*ptr == '\n') || (*ptr == '\r'))
/*
* 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, 1, &keepon))
keepon = FALSE;
else if ((*ptr == '\n') || (*ptr == '\r'))
keepon = FALSE;
}
if(keepon) {
@@ -372,7 +367,7 @@ CURLcode Curl_ftp_connect(struct connectdata *conn)
if (data->bits.tunnel_thru_httpproxy) {
/* We want "seamless" FTP operations through HTTP proxy tunnel */
result = Curl_ConnectHTTPProxyTunnel(data, data->firstsocket,
result = Curl_ConnectHTTPProxyTunnel(conn, data->firstsocket,
data->hostname, data->remote_port);
if(CURLE_OK != result)
return result;
@@ -979,7 +974,7 @@ CURLcode _ftp(struct connectdata *conn)
if (data->bits.tunnel_thru_httpproxy) {
/* We want "seamless" FTP operations through HTTP proxy tunnel */
result = Curl_ConnectHTTPProxyTunnel(data, data->secondarysocket,
result = Curl_ConnectHTTPProxyTunnel(conn, data->secondarysocket,
newhost, newport);
if(CURLE_OK != result)
return result;

View File

@@ -41,12 +41,13 @@ char *GetEnv(char *variable)
char env[MAX_PATH]; /* MAX_PATH is from windef.h */
char *temp = getenv(variable);
env[0] = '\0';
if (temp != NULL)
ExpandEnvironmentStrings(temp, env, sizeof(env));
#else
/* no length control */
char *env = getenv(variable);
#endif
return env?strdup(env):NULL;
return (env && env[0])?strdup(env):NULL;
}
char *curl_getenv(char *v)

View File

@@ -94,7 +94,6 @@
#include "base64.h"
#include "cookie.h"
#include "strequal.h"
#include "url.h"
#include "ssluse.h"
#define _MPRINTF_REPLACE /* use our functions only */
@@ -141,7 +140,7 @@ size_t add_buffer_send(int sockfd, struct connectdata *conn, send_buffer *in)
fwrite(in->buffer, in->size_used, 1, conn->data->err);
}
amount = ssend(sockfd, conn, in->buffer, in->size_used);
Curl_write(conn, sockfd, in->buffer, in->size_used, &amount);
if(in->buffer)
free(in->buffer);
@@ -213,28 +212,21 @@ CURLcode add_buffer(send_buffer *in, void *inptr, size_t size)
*/
static
int GetLine(int sockfd, char *buf, struct UrlData *data)
int GetLine(int sockfd, char *buf, struct connectdata *conn)
{
int nread;
ssize_t nread;
int read_rc=1;
char *ptr;
struct UrlData *data=conn->data;
ptr=buf;
/* get us a full line, terminated with a newline */
for(nread=0;
(nread<BUFSIZE) && read_rc;
nread++, ptr++) {
#ifdef USE_SSLEAY
if (data->ssl.use) {
read_rc = SSL_read(data->ssl.handle, ptr, 1);
}
else {
#endif
read_rc = sread(sockfd, ptr, 1);
#ifdef USE_SSLEAY
}
#endif /* USE_SSLEAY */
if (*ptr == '\n')
if((CURLE_OK != Curl_read(conn, sockfd, ptr, 1, &nread)) ||
(*ptr == '\n'))
break;
}
*ptr=0; /* zero terminate */
@@ -272,16 +264,18 @@ bool static checkheaders(struct UrlData *data, char *thisheader)
* this proxy. After that, the socket can be used just as a normal socket.
*/
CURLcode Curl_ConnectHTTPProxyTunnel(struct UrlData *data, int tunnelsocket,
CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
int tunnelsocket,
char *hostname, int remote_port)
{
int httperror=0;
int subversion=0;
struct UrlData *data=conn->data;
infof(data, "Establish HTTP proxy tunnel to %s:%d\n", hostname, remote_port);
/* OK, now send the connect statment */
sendf(tunnelsocket, data,
/* OK, now send the connect request to the proxy */
Curl_sendf(tunnelsocket, conn,
"CONNECT %s:%d HTTP/1.0\015\012"
"%s"
"%s"
@@ -292,7 +286,7 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct UrlData *data, int tunnelsocket,
);
/* wait for the proxy to send us a HTTP/1.0 200 OK header */
while(GetLine(tunnelsocket, data->buffer, data)) {
while(GetLine(tunnelsocket, data->buffer, conn)) {
if('\r' == data->buffer[0])
break; /* end of headers */
if(2 == sscanf(data->buffer, "HTTP/1.%d %d",
@@ -330,7 +324,7 @@ CURLcode Curl_http_connect(struct connectdata *conn)
if (conn->protocol & PROT_HTTPS) {
if (data->bits.httpproxy) {
/* HTTPS through a proxy can only be done with a tunnel */
result = Curl_ConnectHTTPProxyTunnel(data, data->firstsocket,
result = Curl_ConnectHTTPProxyTunnel(conn, data->firstsocket,
data->hostname, data->remote_port);
if(CURLE_OK != result)
return result;
@@ -435,9 +429,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);
}
@@ -477,6 +468,92 @@ CURLcode Curl_http(struct connectdata *conn)
if(!checkheaders(data, "Accept:"))
http->p_accept = "Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*\r\n";
if((data->bits.http_post ||
data->bits.http_formpost ||
data->bits.http_put) &&
data->resume_from) {
/**********************************************************************
* Resuming upload in HTTP means that we PUT or POST and that we have
* got a resume_from value set. The resume value has already created
* a Range: header that will be passed along. We need to "fast forward"
* the file the given number of bytes and decrease the assume upload
* file size before we continue this venture in the dark lands of HTTP.
*********************************************************************/
if(data->resume_from < 0 ) {
/*
* This is meant to get the size of the present remote-file by itself.
* We don't support this now. Bail out!
*/
data->resume_from = 0;
}
if(data->resume_from) {
/* do we still game? */
int passed=0;
/* Now, let's read off the proper amount of bytes from the
input. If we knew it was a proper file we could've just
fseek()ed but we only have a stream here */
do {
int readthisamountnow = (data->resume_from - passed);
int actuallyread;
if(readthisamountnow > BUFSIZE)
readthisamountnow = BUFSIZE;
actuallyread =
data->fread(data->buffer, 1, readthisamountnow, data->in);
passed += actuallyread;
if(actuallyread != readthisamountnow) {
failf(data, "Could only read %d bytes from the input\n",
passed);
return CURLE_READ_ERROR;
}
} while(passed != data->resume_from); /* loop until done */
/* now, decrease the size of the read */
if(data->infilesize>0) {
data->infilesize -= data->resume_from;
if(data->infilesize <= 0) {
failf(data, "File already completely uploaded\n");
return CURLE_PARTIAL_FILE;
}
}
/* 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;
struct curl_slist *headers=data->headers;

View File

@@ -25,7 +25,8 @@
*****************************************************************************/
/* ftp can use this as well */
CURLcode Curl_ConnectHTTPProxyTunnel(struct UrlData *data, int tunnelsocket,
CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
int tunnelsocket,
char *hostname, int remote_port);
/* protocol-specific functions set up to be called by the main engine */

View File

@@ -32,7 +32,7 @@
#include <unistd.h>
#endif
#if ! defined(WIN32) && ! defined(__BEOS__)
#if ! defined(WIN32) && ! defined(__BEOS__) && !defined(__CYGWIN32__)
#ifdef NEED_REENTRANT
#define _REENTRANT

View File

@@ -283,7 +283,9 @@ krb4_auth(void *app_data, struct connectdata *conn)
u_int32_t cs;
struct krb4_data *d = app_data;
struct sockaddr_in *localaddr = (struct sockaddr_in *)LOCAL_ADDR;
#if 0
struct sockaddr_in *remoteaddr = (struct sockaddr_in *)REMOTE_ADDR;
#endif
char *host = conn->hp->h_name;
size_t nread;
int l = sizeof(local_addr);
@@ -313,7 +315,7 @@ krb4_auth(void *app_data, struct connectdata *conn)
else {
if (natAddr.s_addr != localaddr->sin_addr.s_addr) {
printf("Using NAT IP address (%s) for kerberos 4\n",
inet_ntoa(natAddr));
(char *)inet_ntoa(natAddr));
localaddr->sin_addr = natAddr;
/*
@@ -399,7 +401,6 @@ void krb_kauth(struct connectdata *conn)
KTEXT_ST tkt, tktcopy;
char *name;
char *p;
int overbose;
char passwd[100];
int tmp;
size_t nread;
@@ -417,12 +418,10 @@ void krb_kauth(struct connectdata *conn)
return /*CURLE_OPERATION_TIMEOUTED*/;
if(/*ret != CONTINUE*/conn->data->buffer[0] != '3'){
/*verbose = overbose;***/
set_command_prot(conn, save);
/*code = -1;***/
return;
}
/*verbose = overbose;***/
p = strstr(/*reply_string***/conn->data->buffer, "T=");
if(!p){
printf("Bad reply from server.\n");
@@ -444,7 +443,6 @@ void krb_kauth(struct connectdata *conn)
p = strstr(/*reply_string***/conn->data->buffer, "P=");
if(!p){
printf("Bad reply from server.\n");
/*verbose = overbose;***/
set_command_prot(conn, save);
/*code = -1;***/
return;

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");
@@ -212,14 +215,14 @@ int Curl_pgrsUpdate(struct UrlData *data)
now = Curl_tvnow(); /* what time is it */
/* The exact time spent so far */
data->progress.timespent = Curl_tvdiff (now, data->progress.start);
if(data->progress.lastshow == Curl_tvlong(now))
return 0; /* never update this more than once a second if the end isn't
reached */
data->progress.lastshow = now.tv_sec;
/* The exact time spent so far */
data->progress.timespent = Curl_tvdiff (now, data->progress.start);
/* The average download speed this far */
data->progress.dlspeed = data->progress.downloaded/(data->progress.timespent!=0.0?data->progress.timespent:1.0);
@@ -257,17 +260,13 @@ int Curl_pgrsUpdate(struct UrlData *data)
}
/* Figure out the estimated time of arrival for the upload */
if(data->progress.flags & PGRS_UL_SIZE_KNOWN) {
if(!data->progress.ulspeed)
data->progress.ulspeed=1;
if((data->progress.flags & PGRS_UL_SIZE_KNOWN) && data->progress.ulspeed){
ulestimate = data->progress.size_ul / data->progress.ulspeed;
ulpercen = (data->progress.uploaded / data->progress.size_ul)*100;
}
/* ... and the download */
if(data->progress.flags & PGRS_DL_SIZE_KNOWN) {
if(!data->progress.dlspeed)
data->progress.dlspeed=1;
if((data->progress.flags & PGRS_DL_SIZE_KNOWN) && data->progress.dlspeed) {
dlestimate = data->progress.size_dl / data->progress.dlspeed;
dlpercen = (data->progress.downloaded / data->progress.size_dl)*100;
}

View File

@@ -77,59 +77,87 @@ void Curl_failf(struct UrlData *data, char *fmt, ...)
va_end(ap);
}
/* sendf() sends the formated data to the server */
size_t Curl_sendf(int fd, struct UrlData *data, char *fmt, ...)
/* Curl_sendf() sends formated data to the server */
size_t Curl_sendf(int sockfd, struct connectdata *conn,
char *fmt, ...)
{
struct UrlData *data = conn->data;
size_t bytes_written;
char *s;
va_list ap;
va_start(ap, fmt);
s = vaprintf(fmt, ap);
s = vaprintf(fmt, ap); /* returns an allocated string */
va_end(ap);
if(!s)
return 0; /* failure */
if(data->bits.verbose)
fprintf(data->err, "> %s", s);
#ifndef USE_SSLEAY
bytes_written = swrite(fd, s, strlen(s));
#else /* USE_SSLEAY */
if (data->ssl.use) {
bytes_written = SSL_write(data->ssl.handle, s, strlen(s));
} else {
bytes_written = swrite(fd, s, strlen(s));
}
#endif /* USE_SSLEAY */
/* Write the buffer to the socket */
Curl_write(conn, sockfd, s, strlen(s), &bytes_written);
free(s); /* free the output string */
return(bytes_written);
return bytes_written;
}
/* ssend() sends plain (binary) data to the server */
size_t Curl_ssend(int fd, struct connectdata *conn, void *mem, size_t len)
/*
* Curl_write() is an internal write function that sends plain (binary) data
* to the server. Works with plain sockets, SSL or kerberos.
*
*/
CURLcode Curl_write(struct connectdata *conn, int sockfd,
void *mem, size_t len,
size_t *written)
{
size_t bytes_written;
struct UrlData *data=conn->data; /* conn knows data, not vice versa */
#ifdef USE_SSLEAY
if (data->ssl.use) {
int loop=100; /* just a precaution to never loop endlessly */
while(loop--) {
bytes_written = SSL_write(data->ssl.handle, mem, len);
if((-1 != bytes_written) ||
(SSL_ERROR_WANT_WRITE != SSL_get_error(data->ssl.handle,
bytes_written) ))
break;
}
}
else {
#endif
#ifdef KRB4
if(conn->sec_complete) {
bytes_written = sec_write(conn, fd, mem, len);
bytes_written = sec_write(conn, sockfd, mem, len);
}
else
#endif /* KRB4 */
bytes_written = swrite(fd, mem, len);
bytes_written = swrite(sockfd, mem, len);
#ifdef USE_SSLEAY
}
#endif
return bytes_written;
*written = bytes_written;
return CURLE_OK;
}
/*
* External write-function, writes to the data-socket.
* Takes care of plain sockets, SSL or kerberos transparently.
*/
CURLcode curl_write(CURLconnect *c_conn, char *buf, size_t amount,
size_t *n)
{
struct connectdata *conn = (struct connectdata *)c_conn;
if(!n || !conn || (conn->handle != STRUCT_CONNECT))
return CURLE_FAILED_INIT;
return Curl_write(conn, conn->sockfd, buf, amount, n);
}
/* client_write() sends data to the write callback(s)
The bit pattern defines to what "streams" to write to. Body and/or header.
@@ -163,3 +191,56 @@ CURLcode Curl_client_write(struct UrlData *data,
return CURLE_OK;
}
/*
* Internal read-from-socket function. This is meant to deal with plain
* sockets, SSL sockets and kerberos sockets.
*/
CURLcode Curl_read(struct connectdata *conn, int sockfd,
char *buf, size_t buffersize,
ssize_t *n)
{
struct UrlData *data = conn->data;
ssize_t nread;
#ifdef USE_SSLEAY
if (data->ssl.use) {
int loop=100; /* just a precaution to never loop endlessly */
while(loop--) {
nread = SSL_read(data->ssl.handle, buf, buffersize);
if((-1 != nread) ||
(SSL_ERROR_WANT_READ != SSL_get_error(data->ssl.handle, nread) ))
break;
}
}
else {
#endif
#ifdef KRB4
if(conn->sec_complete)
nread = sec_read(conn, sockfd, buf, buffersize);
else
#endif
nread = sread (sockfd, buf, buffersize);
#ifdef USE_SSLEAY
}
#endif /* USE_SSLEAY */
*n = nread;
return CURLE_OK;
}
/*
* The public read function reads from the 'sockfd' file descriptor only.
* Use the Curl_read() internally when you want to specify fd.
*/
CURLcode curl_read(CURLconnect *c_conn, char *buf, size_t buffersize,
ssize_t *n)
{
struct connectdata *conn = (struct connectdata *)c_conn;
if(!n || !conn || (conn->handle != STRUCT_CONNECT))
return CURLE_FAILED_INIT;
return Curl_read(conn, conn->sockfd, buf, buffersize, n);
}

View File

@@ -23,13 +23,10 @@
* $Id$
*****************************************************************************/
size_t Curl_sendf(int fd, struct UrlData *, char *fmt, ...);
size_t Curl_ssend(int fd, struct connectdata *, void *fmt, size_t len);
size_t Curl_sendf(int fd, struct connectdata *, char *fmt, ...);
void Curl_infof(struct UrlData *, char *fmt, ...);
void Curl_failf(struct UrlData *, char *fmt, ...);
#define sendf Curl_sendf
#define ssend Curl_ssend
#define infof Curl_infof
#define failf Curl_failf
@@ -47,4 +44,13 @@ typedef struct send_buffer send_buffer;
CURLcode Curl_client_write(struct UrlData *data, int type, char *ptr,
size_t len);
/* internal read-function, does plain socket, SSL and krb4 */
CURLcode Curl_read(struct connectdata *conn, int sockfd,
char *buf, size_t buffersize,
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,
size_t *written);
#endif

View File

@@ -100,7 +100,6 @@ defined(HAVE_LIBSSL) && defined(HAVE_LIBCRYPTO)
1. close a socket
2. read from a socket
3. write to a socket
(Hopefully, only win32-crap do this weird name changing)
4. set the SIGALRM signal timeout
5. set dir/file naming defines
@@ -115,8 +114,8 @@ defined(HAVE_LIBSSL) && defined(HAVE_LIBCRYPTO)
#else
/* gcc-for-win is still good :) */
#define sclose(x) close(x)
#define sread(x,y,z) read(x,y,z)
#define swrite(x,y,z) write(x,y,z)
#define sread(x,y,z) recv(x,y,z,0)
#define swrite(x,y,z) send(x,y,z,0)
#define myalarm(x) alarm(x)
#endif

View File

@@ -73,8 +73,6 @@
#include <curl/curl.h>
#include "transfer.h"
#include "sendf.h"
#include "formdata.h"
#include "progress.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
@@ -97,11 +95,6 @@
#define SB_EOF() (subpointer >= subend)
#define SB_LEN() (subend - subpointer)
static
void telwrite(struct UrlData *data,
unsigned char *buffer, /* Data to write */
int count); /* Number of bytes to write */
static
void telrcv(struct UrlData *data,
unsigned char *inbuf, /* Data received from socket */
@@ -826,36 +819,6 @@ void telrcv(struct UrlData *data,
}
}
static
void telwrite(struct UrlData *data,
unsigned char *buffer, /* Data to write */
int count) /* Number of bytes to write */
{
unsigned char outbuf[2];
int out_count = 0;
int bytes_written;
while(count--)
{
outbuf[0] = *buffer++;
out_count = 1;
if(outbuf[0] == IAC)
outbuf[out_count++] = IAC;
#ifndef USE_SSLEAY
bytes_written = swrite(data->firstsocket, outbuf, out_count);
#else
if (data->ssl.use) {
bytes_written = SSL_write(data->ssl.handle, (char *)outbuf,
out_count);
}
else {
bytes_written = swrite(data->firstsocket, outbuf, out_count);
}
#endif /* USE_SSLEAY */
}
}
CURLcode Curl_telnet_done(struct connectdata *conn)
{
return CURLE_OK;
@@ -870,7 +833,7 @@ CURLcode Curl_telnet(struct connectdata *conn)
bool keepon = TRUE;
char *buf = data->buffer;
int nread;
ssize_t nread;
init_telnet(data);
@@ -880,37 +843,37 @@ CURLcode Curl_telnet(struct connectdata *conn)
keepfd = readfd;
while (keepon)
{
while (keepon) {
readfd = keepfd; /* set this every lap in the loop */
switch (select (sockfd + 1, &readfd, NULL, NULL, NULL))
{
switch (select (sockfd + 1, &readfd, NULL, NULL, NULL)) {
case -1: /* error, stop reading */
keepon = FALSE;
continue;
case 0: /* timeout */
break;
default: /* read! */
if(FD_ISSET(1, &readfd))
{
if(FD_ISSET(1, &readfd)) { /* read from stdin */
unsigned char outbuf[2];
int out_count = 0;
size_t bytes_written;
char *buffer = buf;
nread = read(1, buf, 255);
telwrite(data, (unsigned char *)buf, nread);
while(nread--) {
outbuf[0] = *buffer++;
out_count = 1;
if(outbuf[0] == IAC)
outbuf[out_count++] = IAC;
Curl_write(conn, data->firstsocket, outbuf,
out_count, &bytes_written);
}
}
if(FD_ISSET(sockfd, &readfd))
{
#ifndef USE_SSLEAY
nread = sread (sockfd, buf, BUFSIZE - 1);
#else
if (data->ssl.use) {
nread = SSL_read (data->ssl.handle, buf, BUFSIZE - 1);
}
else {
nread = sread (sockfd, buf, BUFSIZE - 1);
}
#endif /* USE_SSLEAY */
}
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! */
@@ -922,7 +885,9 @@ CURLcode Curl_telnet(struct connectdata *conn)
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

@@ -109,7 +109,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 */
@@ -133,8 +133,6 @@ _Transfer(struct connectdata *c_conn)
CURLcode urg;
time_t timeofdoc=0;
long bodywrites=0;
char newurl[URL_MAX_LENGTH]; /* buffer for Location: URL */
int writetype;
/* the highest fd we use + 1 */
@@ -163,6 +161,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)
@@ -224,7 +228,7 @@ _Transfer(struct connectdata *c_conn)
default:
if((keepon & KEEP_READ) && FD_ISSET(conn->sockfd, &readfd)) {
/* read! */
urg = curl_read(conn, buf, BUFSIZE -1, &nread);
urg = Curl_read(conn, conn->sockfd, buf, BUFSIZE -1, &nread);
/* NULL terminate, allowing string ops to be used */
if (0 < (signed int) nread)
@@ -389,12 +393,21 @@ _Transfer(struct connectdata *c_conn)
}
else if ((code >= 300 && code < 400) &&
(data->bits.http_follow_location) &&
strnequal("Location", p, 8) &&
sscanf (p+8, ": %" URL_MAX_LENGTH_TXT "s",
newurl)) {
/* this is the URL that the server advices us to get
instead */
data->newurl = strdup (newurl);
strnequal("Location: ", p, 10)) {
/* this is the URL that the server advices us to get instead */
char *ptr;
char *start=p;
char backup;
start += 10; /* pass "Location: " */
ptr = start; /* start scanning here */
/* scan through the string to find the end */
while(*ptr && !isspace((int)*ptr))
ptr++;
backup = *ptr; /* store the ending letter */
*ptr = '\0'; /* zero terminate */
data->newurl = strdup(start); /* clone string */
*ptr = backup; /* restore ending letter */
}
writetype = CLIENTWRITE_HEADER;
@@ -437,17 +450,21 @@ _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 ) {
/* we wanted to resume a download, although the server
doesn't seem to support this */
failf (data, "HTTP server doesn't seem to support byte ranges. Cannot resume.");
return CURLE_HTTP_RANGE_ERROR;
}
else if (data->newurl) {
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) */
failf (data, "HTTP server doesn't seem to support "
"byte ranges. Cannot resume.");
return CURLE_HTTP_RANGE_ERROR;
}
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
@@ -534,7 +551,8 @@ _Transfer(struct connectdata *c_conn)
}
/* write to socket */
urg = curl_write(conn, buf, nread, &bytes_written);
urg = Curl_write(conn, conn->writesockfd, buf, nread,
&bytes_written);
if(nread != bytes_written) {
failf(data, "Failed uploading data");
@@ -613,8 +631,9 @@ CURLcode curl_transfer(CURL *curl)
This is assumed to happen for HTTP(S) only!
*/
char prot[16];
char path[URL_MAX_LENGTH];
char prot[16]; /* URL protocol string storage */
char letter; /* used for a silly sscanf */
if (data->maxredirs && (data->followlocation >= data->maxredirs)) {
failf(data,"Maximum (%d) redirects followed", data->maxredirs);
curl_disconnect(c_connect);
@@ -642,8 +661,7 @@ CURLcode curl_transfer(CURL *curl)
data->bits.http_set_referer = TRUE; /* might have been false */
}
if(2 != sscanf(data->newurl, "%15[^:]://%" URL_MAX_LENGTH_TXT
"s", prot, path)) {
if(2 != sscanf(data->newurl, "%15[^:]://%c", prot, &letter)) {
/***
*DANG* this is an RFC 2068 violation. The URL is supposed
to be absolute and this doesn't seem to be that!
@@ -713,13 +731,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;
}

311
lib/url.c
View File

@@ -301,6 +301,8 @@ CURLcode curl_open(CURL **curl, char *url)
data->current_speed = -1; /* init to negative == impossible */
data->httpreq = HTTPREQ_GET; /* Default HTTP request */
*curl = data;
return CURLE_OK;
}
@@ -337,9 +339,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;
if(data->bits.http_post)
data->httpreq = HTTPREQ_POST;
break;
case CURLOPT_FILETIME:
data->bits.get_filetime = va_arg(param, long)?TRUE:FALSE;
@@ -361,19 +368,18 @@ CURLcode curl_setopt(CURL *curl, CURLoption option, ...)
break;
case CURLOPT_PUT:
data->bits.http_put = va_arg(param, long)?TRUE:FALSE;
if(data->bits.http_put)
data->httpreq = HTTPREQ_PUT;
break;
case CURLOPT_MUTE:
data->bits.mute = va_arg(param, long)?TRUE:FALSE;
break;
case CURLOPT_TIMECONDITION:
data->timecondition = va_arg(param, long);
break;
case CURLOPT_TIMEVALUE:
data->timevalue = va_arg(param, long);
break;
case CURLOPT_SSLVERSION:
data->ssl.version = va_arg(param, long);
break;
@@ -405,10 +411,14 @@ CURLcode curl_setopt(CURL *curl, CURLoption option, ...)
break;
case CURLOPT_CUSTOMREQUEST:
data->customrequest = va_arg(param, char *);
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;
if(data->bits.http_formpost)
data->httpreq = HTTPREQ_POST_FORM;
break;
case CURLOPT_INFILE:
data->in = va_arg(param, FILE *);
@@ -533,7 +543,7 @@ CURLcode curl_setopt(CURL *curl, CURLoption option, ...)
return CURLE_OK;
}
#ifndef WIN32
#if !defined(WIN32)||defined(__CYGWIN32__)
#ifndef RETSIGTYPE
#define RETSIGTYPE void
#endif
@@ -546,67 +556,6 @@ RETSIGTYPE alarmfunc(int signal)
}
#endif
CURLcode curl_write(CURLconnect *c_conn, char *buf, size_t amount,
size_t *n)
{
struct connectdata *conn = (struct connectdata *)c_conn;
struct UrlData *data;
size_t bytes_written;
if(!n || !conn || (conn->handle != STRUCT_CONNECT))
return CURLE_FAILED_INIT;
data = conn->data;
#ifdef USE_SSLEAY
if (data->ssl.use) {
bytes_written = SSL_write(data->ssl.handle, buf, amount);
}
else {
#endif
#ifdef KRB4
if(conn->sec_complete)
bytes_written = sec_write(conn, conn->writesockfd, buf, amount);
else
#endif
bytes_written = swrite(conn->writesockfd, buf, amount);
#ifdef USE_SSLEAY
}
#endif /* USE_SSLEAY */
*n = bytes_written;
return CURLE_OK;
}
CURLcode curl_read(CURLconnect *c_conn, char *buf, size_t buffersize,
size_t *n)
{
struct connectdata *conn = (struct connectdata *)c_conn;
struct UrlData *data;
size_t nread;
if(!n || !conn || (conn->handle != STRUCT_CONNECT))
return CURLE_FAILED_INIT;
data = conn->data;
#ifdef USE_SSLEAY
if (data->ssl.use) {
nread = SSL_read (data->ssl.handle, buf, buffersize);
}
else {
#endif
#ifdef KRB4
if(conn->sec_complete)
nread = sec_read(conn, conn->sockfd, buf, buffersize);
else
#endif
nread = sread (conn->sockfd, buf, buffersize);
#ifdef USE_SSLEAY
}
#endif /* USE_SSLEAY */
*n = nread;
return CURLE_OK;
}
CURLcode curl_disconnect(CURLconnect *c_connect)
{
struct connectdata *conn = c_connect;
@@ -635,17 +584,25 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
char resumerange[40]="";
struct UrlData *data = curl;
struct connectdata *conn;
char endbracket;
#ifdef HAVE_SIGACTION
struct sigaction sigact;
#endif
int urllen;
/*************************************************************
* Check input data
*************************************************************/
if(!data || (data->handle != STRUCT_OPEN))
return CURLE_BAD_FUNCTION_ARGUMENT; /* TBD: make error codes */
if(!data->url)
return CURLE_URL_MALFORMAT;
/*************************************************************
* Allocate and initiate a connection struct
*************************************************************/
conn = (struct connectdata *)malloc(sizeof(struct connectdata));
if(!conn) {
*in_connect = NULL; /* clear the pointer */
@@ -664,6 +621,9 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
buf = data->buffer; /* this is our buffer */
/*************************************************************
* Set signal handler
*************************************************************/
#ifdef HAVE_SIGACTION
sigaction(SIGALRM, NULL, &sigact);
sigact.sa_handler = alarmfunc;
@@ -680,9 +640,11 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
#endif
/* We need to allocate memory to store the path in. We get the size of the
full URL to be sure, and we need to make it at least 256 bytes since
other parts of the code will rely on this fact */
/***********************************************************
* We need to allocate memory to store the path in. We get the size of the
* full URL to be sure, and we need to make it at least 256 bytes since
* other parts of the code will rely on this fact
***********************************************************/
#define LEAST_PATH_ALLOC 256
urllen=strlen(data->url);
if(urllen < LEAST_PATH_ALLOC)
@@ -692,25 +654,30 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
if(NULL == conn->path)
return CURLE_OUT_OF_MEMORY; /* really bad error */
/* Parse <url> */
/* We need to parse the url, even when using the proxy, because
* we will need the hostname and port in case we are trying
* to SSL connect through the proxy -- and we don't know if we
* will need to use SSL until we parse the url ...
*/
/*************************************************************
* Parse the URL.
*
* We need to parse the url even when using the proxy, because we will need
* the hostname and port in case we are trying to SSL connect through the
* proxy -- and we don't know if we will need to use SSL until we parse the
* url ...
************************************************************/
if((2 == sscanf(data->url, "%64[^:]://%[^\n]",
conn->proto,
conn->path)) && strequal(conn->proto, "file")) {
/* we deal with file://<host>/<path> differently since it
supports no hostname other than "localhost" and "127.0.0.1",
which is unique among the protocols specified in RFC 1738 */
/*
* we deal with file://<host>/<path> differently since it supports no
* hostname other than "localhost" and "127.0.0.1", which is unique among
* the URL protocols specified in RFC 1738
*/
if (strnequal(conn->path, "localhost/", 10) ||
strnequal(conn->path, "127.0.0.1/", 10))
/* ... since coincidentally both host strings are of equal length
otherwise, <host>/ is quietly ommitted */
/* If there's another host name than the one we support, <host>/ is
* quietly ommitted */
strcpy(conn->path, &conn->path[10]);
strcpy(conn->proto, "file");
strcpy(conn->proto, "file"); /* store protocol string lowercase */
}
else {
/* Set default host and default path */
@@ -721,12 +688,24 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
"%64[^\n:]://%256[^\n/]%[^\n]",
conn->proto, conn->gname, conn->path)) {
/* badly formatted, let's try the browser-style _without_ 'http://' */
/*
* The URL was badly formatted, let's try the browser-style _without_
* protocol specified like 'http://'.
*/
if((1 > sscanf(data->url, "%256[^\n/]%[^\n]",
conn->gname, conn->path)) ) {
/*
* We couldn't even get this format.
*/
failf(data, "<url> malformed");
return CURLE_URL_MALFORMAT;
}
/*
* Since there was no protocol part specified, we guess what protocol it
* is based on the first letters of the server name.
*/
if(strnequal(conn->gname, "FTP", 3)) {
strcpy(conn->proto, "ftp");
}
@@ -750,6 +729,9 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
}
}
/*************************************************************
* Take care of user and password authentication stuff
*************************************************************/
if(data->bits.user_passwd && !data->bits.use_netrc) {
data->user[0] =0;
@@ -773,6 +755,9 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
}
}
/*************************************************************
* Take care of proxy authentication stuff
*************************************************************/
if(data->bits.proxy_user_passwd) {
data->proxyuser[0] =0;
data->proxypasswd[0]=0;
@@ -798,29 +783,35 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
}
/*************************************************************
* Set a few convenience pointers
*************************************************************/
conn->name = conn->gname;
conn->ppath = conn->path;
data->hostname = conn->name;
/*************************************************************
* Detect what (if any) proxy to use
*************************************************************/
if(!data->bits.httpproxy) {
/* If proxy was not specified, we check for default proxy environment
variables, to enable i.e Lynx compliance:
http_proxy=http://some.server.dom:port/
https_proxy=http://some.server.dom:port/
ftp_proxy=http://some.server.dom:port/
gopher_proxy=http://some.server.dom:port/
no_proxy=domain1.dom,host.domain2.dom
(a comma-separated list of hosts which should
not be proxied, or an asterisk to override
all proxy variables)
all_proxy=http://some.server.dom:port/
(seems to exist for the CERN www lib. Probably
the first to check for.)
For compatibility, the all-uppercase versions of these variables are
checked if the lowercase versions don't exist.
* variables, to enable i.e Lynx compliance:
*
* http_proxy=http://some.server.dom:port/
* https_proxy=http://some.server.dom:port/
* ftp_proxy=http://some.server.dom:port/
* gopher_proxy=http://some.server.dom:port/
* no_proxy=domain1.dom,host.domain2.dom
* (a comma-separated list of hosts which should
* not be proxied, or an asterisk to override
* all proxy variables)
* all_proxy=http://some.server.dom:port/
* (seems to exist for the CERN www lib. Probably
* the first to check for.)
*
* For compatibility, the all-uppercase versions of these variables are
* checked if the lowercase versions don't exist.
*/
char *no_proxy=NULL;
char *proxy=NULL;
@@ -890,6 +881,9 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
free(no_proxy);
} /* if not using proxy */
/*************************************************************
* No protocol but proxy usage needs attention
*************************************************************/
if((conn->protocol&PROT_MISSING) && data->bits.httpproxy ) {
/* We're guessing prefixes here and since we're told to use a proxy, we
need to add the protocol prefix to the URL string before we continue!
@@ -909,13 +903,15 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
conn->protocol &= ~PROT_MISSING; /* switch that one off again */
}
/* RESUME on a HTTP page is a tricky business. First, let's just check that
'range' isn't used, then set the range parameter and leave the resume as
it is to inform about this situation for later use. We will then
"attempt" to resume, and if we're talking to a HTTP/1.1 (or later)
server, we will get the document resumed. If we talk to a HTTP/1.0
server, we just fail since we can't rewind the file writing from within
this function. */
/************************************************************
* RESUME on a HTTP page is a tricky business. First, let's just check that
* 'range' isn't used, then set the range parameter and leave the resume as
* it is to inform about this situation for later use. We will then
* "attempt" to resume, and if we're talking to a HTTP/1.1 (or later)
* server, we will get the document resumed. If we talk to a HTTP/1.0
* server, we just fail since we can't rewind the file writing from within
* this function.
***********************************************************/
if(data->resume_from) {
if(!data->bits.set_range) {
/* if it already was in use, we just skip this */
@@ -926,19 +922,19 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
}
}
/*************************************************************
* Set timeout if that is being used
*************************************************************/
if(data->timeout) {
/* We set the timeout on the connection/resolving phase first, separately
from the download/upload part to allow a maximum time on everything */
* from the download/upload part to allow a maximum time on everything */
myalarm(data->timeout); /* this sends a signal when the timeout fires
off, and that will abort system calls */
}
/*
* Hmm, if we are using a proxy, then we can skip the GOPHER and the
* FTP steps, although we cannot skip the HTTPS step (since the proxy
* works differently, depending on whether its SSL or not).
*/
/*************************************************************
* Setup internals depending on protocol
*************************************************************/
if (strequal(conn->proto, "HTTP")) {
if(!data->port)
@@ -1006,7 +1002,7 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
conn->ppath++; /* don't include the initial slash */
/* FTP URLs support an extension like ";type=<typecode>" that
we'll try to get now! */
* we'll try to get now! */
type=strstr(conn->ppath, ";type=");
if(!type) {
type=strstr(conn->gname, ";type=");
@@ -1068,12 +1064,16 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
return CURLE_OK;
}
else {
/* We fell through all checks and thus we don't support the specified
protocol */
failf(data, "Unsupported protocol: %s", conn->proto);
return CURLE_UNSUPPORTED_PROTOCOL;
}
/*************************************************************
* .netrc scanning coming up
*************************************************************/
if(data->bits.use_netrc) {
if(Curl_parsenetrc(data->hostname, data->user, data->passwd)) {
infof(data, "Couldn't find host %s in the .netrc file, using defaults",
@@ -1092,9 +1092,9 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
else if(!(data->bits.user_passwd) &&
(conn->protocol & (PROT_FTP|PROT_HTTP)) ) {
/* This is a FTP or HTTP URL, and we haven't got the user+password in
the extra parameter, we will now try to extract the possible
user+password pair in a string like:
ftp://user:password@ftp.my.site:8021/README */
* the extra parameter, we will now try to extract the possible
* user+password pair in a string like:
* ftp://user:password@ftp.my.site:8021/README */
char *ptr=NULL; /* assign to remove possible warnings */
if((ptr=strchr(conn->name, '@'))) {
/* there's a user+password given here, to the left of the @ */
@@ -1146,15 +1146,47 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
}
}
/*************************************************************
* Figure out the remote port number
*
* No matter if we use a proxy or not, we have to figure out the remote
* port number of various reasons.
*
* To be able to detect port number flawlessly, we must not confuse them
* IPv6-specified addresses in the [0::1] style.
*************************************************************/
if((1 == sscanf(conn->name, "[%*39[0-9a-fA-F:]%c", &endbracket)) &&
(']' == endbracket)) {
/* this is a IPv6-style specified IP-address */
#ifndef ENABLE_IPV6
failf(data, "You haven't enabled IPv6 support");
return CURLE_URL_MALFORMAT;
#else
tmp = strchr(conn->name, ']');
tmp++; /* pass the ending bracket */
if(':' != *tmp)
tmp = NULL; /* no port number available */
#endif
}
else {
/* traditional IPv4-style port-extracting */
tmp = strchr(conn->name, ':');
}
if (tmp) {
*tmp++ = '\0'; /* cut off the name there */
data->remote_port = atoi(tmp);
}
/*************************************************************
* Resolve the name of the server or proxy
*************************************************************/
if(!data->bits.httpproxy) {
/* If not connecting via a proxy, extract the port from the URL, if it is
* there, thus overriding any defaults that might have been set above. */
tmp = strchr(conn->name, ':');
if (tmp) {
*tmp++ = '\0';
data->port = atoi(tmp);
}
data->remote_port = data->port; /* it is the same port */
data->port = data->remote_port; /* it is the same port */
/* Connect to target host right on */
conn->hp = Curl_gethost(data, conn->name, &conn->hostent_buf);
@@ -1179,14 +1211,6 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
return CURLE_OUT_OF_MEMORY;
}
/* we use proxy all right, but we wanna know the remote port for SSL
reasons */
tmp = strchr(conn->name, ':');
if (tmp) {
*tmp++ = '\0'; /* cut off the name there */
data->remote_port = atoi(tmp);
}
/* Daniel Dec 10, 1998:
We do the proxy host string parsing here. We want the host name and the
port name. Accept a protocol:// prefix, even though it should just be
@@ -1231,20 +1255,20 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
conn->serv_addr.sin_family = conn->hp->h_addrtype;
conn->serv_addr.sin_port = htons(data->port);
#ifndef WIN32
#if !defined(WIN32)||defined(__CYGWIN32__)
/* We don't generally like checking for OS-versions, we should make this
HAVE_XXXX based, although at the moment I don't have a decent test for
this! */
/* sck 8/31/2000 add support for specifing device to bind socket to */
/* I am using this, but it may not work everywhere, only tested on
RedHat 6.2 */
#ifdef HAVE_INET_NTOA
#ifndef INADDR_NONE
#define INADDR_NONE (unsigned long) ~0
#endif
/*************************************************************
* Select device to bind socket to
*************************************************************/
if (data->device && (strlen(data->device)<255)) {
struct sockaddr_in sa;
struct hostent *h=NULL;
@@ -1351,6 +1375,9 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
#endif /* end of HAVE_INET_NTOA */
#endif /* end of not WIN32 */
/*************************************************************
* Connect to server/proxy
*************************************************************/
if (connect(data->firstsocket,
(struct sockaddr *) &(conn->serv_addr),
sizeof(conn->serv_addr)
@@ -1400,6 +1427,9 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
return CURLE_COULDNT_CONNECT;
}
/*************************************************************
* Proxy authentication
*************************************************************/
if(data->bits.proxy_user_passwd) {
char *authorization;
snprintf(data->buffer, BUFSIZE, "%s:%s",
@@ -1411,6 +1441,11 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
free(authorization);
}
}
/*************************************************************
* Send user-agent to HTTP proxies even if the target protocol
* isn't HTTP.
*************************************************************/
if((conn->protocol&PROT_HTTP) || data->bits.httpproxy) {
if(data->useragent) {
data->ptr_uagent =
@@ -1422,9 +1457,11 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
/* is there a connect() procedure? */
/* set start time here for timeout purposes in the
connect procedure, it is later set again for the
progress meter purpose */
* connect procedure, it is later set again for the
* progress meter purpose */
conn->now = Curl_tvnow();
/* Call the protocol-specific connect function */
result = conn->curl_connect(conn);
if(result != CURLE_OK)
return result; /* pass back errors */
@@ -1435,7 +1472,7 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
conn->now = Curl_tvnow(); /* time this *after* the connect is done */
conn->bytecount = 0;
/* Figure out the ip-number and the first host name it shows: */
/* Figure out the ip-number and display the first host name it shows: */
{
struct in_addr in;
(void) memcpy(&in.s_addr, *conn->hp->h_addr_list, sizeof (in.s_addr));

View File

@@ -82,8 +82,8 @@
/* Download buffer size, keep it fairly big for speed reasons */
#define BUFSIZE (1024*50)
/* Upload buffer size, keep it smallish to get faster progress meter
updates. This should probably become dynamic and adjust to the upload
/* Defaul upload buffer size, keep it smallish to get faster progress meter
updates. This is just default, it is dynamic and adjusts to the upload
speed. */
#define UPLOAD_BUFSIZE (1024*2)
@@ -91,10 +91,14 @@
of need. */
#define HEADERSIZE 256
/* Just a convenience macro to get the larger value out of two given */
#ifndef MAX
#define MAX(x,y) ((x)>(y)?(x):(y))
#endif
/* Type of handle. All publicly returned 'handles' in the curl interface
have a handle first in the struct that describes what kind of handle it
is. Used to detect bad handle usage. */
typedef enum {
STRUCT_NONE,
STRUCT_OPEN,
@@ -102,6 +106,8 @@ typedef enum {
STRUCT_LAST
} Handle;
/* Connecting to a remote server using the curl interface is moving through
a state machine, this type is used to store the current state */
typedef enum {
CONN_NONE, /* illegal state */
CONN_INIT, /* curl_connect() has been called */
@@ -112,6 +118,7 @@ typedef enum {
} ConnState;
#ifdef KRB4
/* Types needed for krb4-ftp connections */
struct krb4buffer {
void *data;
size_t size;
@@ -155,13 +162,13 @@ struct connectdata {
char *hostent_buf; /* pointer to allocated memory for name info */
struct hostent *hp;
struct sockaddr_in serv_addr;
char proto[64];
char gname[256];
char *name;
char *path; /* formerly staticly this size: URL_MAX_LENGTH */
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 */
char *path; /* allocated buffer to store the URL's path part in */
char *ppath;
long bytecount;
struct timeval now;
struct timeval now; /* current time */
long upload_bufsize; /* adjust as you see fit, never bigger than BUFSIZE
never smaller than UPLOAD_BUFSIZE */
@@ -248,8 +255,8 @@ struct Progress {
struct HTTP {
struct FormData *sendit;
int postsize;
char *p_pragma;
char *p_accept;
char *p_pragma; /* Pragma: string */
char *p_accept; /* Accept: string */
long readbytecount;
long writebytecount;
@@ -264,14 +271,32 @@ struct HTTP {
***************************************************************************/
struct FTP {
long *bytecountp;
char *user;
char *passwd;
char *user; /* user name string */
char *passwd; /* password string */
char *urlpath; /* the originally given path part of the URL */
char *dir; /* decoded directory */
char *file; /* decoded file */
};
typedef enum {
HTTPREQ_NONE, /* first in list */
HTTPREQ_GET,
HTTPREQ_POST,
HTTPREQ_POST_FORM, /* we make a difference internally */
HTTPREQ_PUT,
HTTPREQ_CUSTOM,
HTTPREQ_LAST /* last in list */
} Curl_HttpReq;
/* This struct is for boolean settings that define how to behave during
this session. */
struct Configbits {
/* these four request types mirror the httpreq field */
bool http_formpost;
bool http_post;
bool http_put;
bool http_get;
bool get_filetime;
bool tunnel_thru_httpproxy;
bool ftp_append;
@@ -281,10 +306,7 @@ struct Configbits {
bool hide_progress;
bool http_fail_on_error;
bool http_follow_location;
bool http_formpost;
bool http_include_header;
bool http_post;
bool http_put;
bool http_set_referer;
bool http_auto_referer; /* set "correct" referer when following location: */
bool httpproxy;
@@ -299,7 +321,6 @@ struct Configbits {
bool verbose;
bool this_is_a_follow; /* this is a followed Location: request */
bool krb4; /* kerberos4 connection requested */
bool proxystringalloc; /* the http proxy string is malloc()'ed */
bool rangestringalloc; /* the range string is malloc()'ed */
bool urlstringalloc; /* the URL string is malloc()'ed */
@@ -313,6 +334,7 @@ typedef enum {
CURLI_LAST
} CurlInterface;
/* struct for data related to SSL and SSL connections */
struct ssldata {
bool use; /* use ssl encrypted communications TRUE/FALSE */
long version; /* what version the client wants to use */
@@ -468,8 +490,10 @@ struct UrlData {
struct curl_slist *quote; /* before the transfer */
struct curl_slist *postquote; /* after the transfer */
TimeCond timecondition;
time_t timevalue;
TimeCond timecondition; /* kind of comparison */
time_t timevalue; /* what time to compare with */
Curl_HttpReq httpreq; /* what kind of HTTP request (if any) is this */
char *customrequest; /* http/ftp request to use */
@@ -482,7 +506,7 @@ struct UrlData {
completion */
#endif
struct Progress progress;
struct Progress progress; /* for all the progress meter data */
#define MAX_CURL_USER_LENGTH 128
#define MAX_CURL_PASSWORD_LENGTH 128
@@ -492,6 +516,7 @@ struct UrlData {
* host (which location-following otherwise could lead to)
*/
/* buffers to store authentication data in */
char user[MAX_CURL_USER_LENGTH];
char passwd[MAX_CURL_PASSWORD_LENGTH];
char proxyuser[MAX_CURL_USER_LENGTH];
@@ -506,7 +531,7 @@ struct UrlData {
char *ptr_cookie; /* free later if not NULL! */
char *ptr_host; /* free later if not NULL */
char *krb4_level;
char *krb4_level; /* what security level */
#ifdef KRB4
FILE *cmdchannel;
#endif

View File

@@ -61,8 +61,18 @@ char *curl_version(void)
ptr=strchr(ptr, '\0');
#endif
#if defined(KRB4) || defined(ENABLE_IPV6)
strcat(ptr, " (");
ptr+=2;
#ifdef KRB4
sprintf(ptr, " (krb4 enabled)");
sprintf(ptr, "krb4 ");
ptr += strlen(ptr);
#endif
#ifdef ENABLE_IPV6
sprintf(ptr, "ipv6 ");
ptr += strlen(ptr);
#endif
sprintf(ptr, "enabled)");
ptr += strlen(ptr);
#endif

View File

@@ -26,13 +26,17 @@ while(<STDIN>) {
if($function =~ /free\(0x([0-9a-f]*)/) {
$addr = $1;
if($sizeataddr{$addr} <= 0) {
if($sizeataddr{$addr} == 0) {
print "FREE ERROR: No memory allocated: $line\n";
}
elsif(-1 == $sizeataddr{$addr}) {
print "FREE ERROR: Memory freed twice: $line\n";
print "FREE ERROR: Previously freed at: ".$getmem{$addr}."\n";
}
else {
$totalmem -= $sizeataddr{$addr};
$sizeataddr{$addr}=0;
$getmem{$addr}=""; # forget after a good free()
$sizeataddr{$addr}=-1; # set -1 to mark as freed
$getmem{$addr}="$source:$linenum";
}
}
elsif($function =~ /malloc\((\d*)\) = 0x([0-9a-f]*)/) {

View File

@@ -48,7 +48,7 @@
/* This is now designed to have its own local setup.h */
#include "setup.h"
#ifdef WIN32
#if defined(WIN32)&&!defined(__CYGWIN32__)
#include <winsock.h>
#endif
@@ -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
@@ -244,7 +246,6 @@ static void help(void)
" -A/--user-agent <string> User-Agent to send to server (H)\n"
" -b/--cookie <name=string/file> Cookie string or file to read cookies from (H)\n"
" -B/--use-ascii Use ASCII/text transfer\n"
" -c/--continue Resume a previous transfer where we left it\n"
" -C/--continue-at <offset> Specify absolute resume offset\n"
" -d/--data <data> HTTP POST data (H)\n"
" --data-ascii <data> HTTP POST ASCII data (H)\n"
@@ -278,7 +279,6 @@ static void help(void)
" -r/--range <range> Retrieve a byte range from a HTTP/1.1 or FTP server\n"
" -s/--silent Silent mode. Don't output anything\n"
" -S/--show-error Show error. With -s, make curl show errors when they occur\n"
" -t/--upload Transfer/upload stdin to remote site\n"
" -T/--upload-file <file> Transfer/upload <file> to remote site\n"
" --url <URL> Another way to specify URL to work with\n"
" -u/--user <user[:password]> Specify user and password to use\n"
@@ -1579,7 +1579,9 @@ operate(struct Configurable *config, int argc, char *argv[])
/* multiple files extracted to stdout, insert separators! */
separator = 1;
}
for (i = 0; (url = urls?next_url(urls):(i?NULL:url)); ++i) {
for(i = 0;
(url = urls?next_url(urls):(i?NULL:strdup(url)));
i++) {
char *outfile;
outfile = outfiles?strdup(outfiles):NULL;
@@ -1713,7 +1715,7 @@ operate(struct Configurable *config, int argc, char *argv[])
if(!config->errors)
config->errors = stderr;
#ifdef WIN32
#if defined(WIN32) && !defined(__CYGWIN32__)
if(!outfile && !(config->conf & CONF_GETTEXT)) {
/* We get the output to stdout and we have not got the ASCII/text flag,
then set stdout to be binary */
@@ -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

@@ -32,9 +32,23 @@
#include "../lib/memdebug.h"
#endif
int glob_word(URLGlob *, char*, int);
typedef enum {
GLOB_OK,
GLOB_ERROR
} GlobCode;
int glob_set(URLGlob *glob, char *pattern, int pos)
/*
* glob_word()
*
* Input a full globbed string, set the forth argument to the amount of
* strings we get out of this. Return GlobCode.
*/
GlobCode glob_word(URLGlob *, /* object anchor */
char *, /* globbed string */
int, /* position */
int *); /* returned number of strings */
GlobCode glob_set(URLGlob *glob, char *pattern, int pos, int *amount)
{
/* processes a set expression with the point behind the opening '{'
','-separated elements are collected until the next closing '}'
@@ -53,12 +67,14 @@ int glob_set(URLGlob *glob, char *pattern, int pos)
while (1) {
switch (*pattern) {
case '\0': /* URL ended while set was still open */
printf("error: unmatched brace at pos %d\n", pos);
exit (CURLE_URL_MALFORMAT);
/*printf("error: unmatched brace at pos %d\n", pos);*/
return GLOB_ERROR;
case '{':
case '[': /* no nested expressions at this time */
printf("error: nested braces not supported %d\n", pos);
exit (CURLE_URL_MALFORMAT);
/*printf("error: nested braces not supported %d\n", pos);*/
return GLOB_ERROR;
case ',':
case '}': /* set element completed */
*buf = '\0';
@@ -66,40 +82,51 @@ int glob_set(URLGlob *glob, char *pattern, int pos)
realloc(pat->content.Set.elements,
(pat->content.Set.size + 1) * sizeof(char*));
if (!pat->content.Set.elements) {
printf("out of memory in set pattern\n");
exit(CURLE_OUT_OF_MEMORY);
/*printf("out of memory in set pattern\n");*/
return GLOB_ERROR;
}
pat->content.Set.elements[pat->content.Set.size] =
strdup(glob->glob_buffer);
++pat->content.Set.size;
if (*pattern == '}') /* entire set pattern completed */
if (*pattern == '}') {
/* entire set pattern completed */
int wordamount;
/* always check for a literal (may be "") between patterns */
return pat->content.Set.size * glob_word(glob, ++pattern, ++pos);
if(GLOB_ERROR == glob_word(glob, ++pattern, ++pos, &wordamount))
wordamount=1;
*amount = pat->content.Set.size * wordamount;
return GLOB_OK;
}
buf = glob->glob_buffer;
++pattern;
++pos;
break;
case ']': /* illegal closing bracket */
printf("error: illegal pattern at pos %d\n", pos);
exit (CURLE_URL_MALFORMAT);
/*printf("error: illegal pattern at pos %d\n", pos);*/
return GLOB_ERROR;
case '\\': /* escaped character, skip '\' */
if (*(buf+1) == '\0') { /* but no escaping of '\0'! */
printf("error: illegal pattern at pos %d\n", pos);
exit (CURLE_URL_MALFORMAT);
/*printf("error: illegal pattern at pos %d\n", pos); */
return GLOB_ERROR;
}
++pattern;
++pos; /* intentional fallthrough */
default:
*buf++ = *pattern++; /* copy character to set element */
++pos;
}
}
exit (CURLE_FAILED_INIT);
return GLOB_ERROR;
}
int glob_range(URLGlob *glob, char *pattern, int pos)
GlobCode glob_range(URLGlob *glob, char *pattern, int pos, int *amount)
{
/* processes a range expression with the point behind the opening '['
- char range: e.g. "a-z]", "B-Q]"
@@ -109,6 +136,7 @@ int glob_range(URLGlob *glob, char *pattern, int pos)
*/
URLPattern *pat;
char *c;
int wordamount=1;
pat = (URLPattern*)&glob->pattern[glob->size / 2];
/* patterns 0,1,2,... correspond to size=1,3,5,... */
@@ -116,44 +144,71 @@ int glob_range(URLGlob *glob, char *pattern, int pos)
if (isalpha((int)*pattern)) { /* character range detected */
pat->type = UPTCharRange;
if (sscanf(pattern, "%c-%c]", &pat->content.CharRange.min_c, &pat->content.CharRange.max_c) != 2 ||
if (sscanf(pattern, "%c-%c]", &pat->content.CharRange.min_c,
&pat->content.CharRange.max_c) != 2 ||
pat->content.CharRange.min_c >= pat->content.CharRange.max_c ||
pat->content.CharRange.max_c - pat->content.CharRange.min_c > 'z' - 'a') {
/* the pattern is not well-formed */
printf("error: illegal pattern or range specification after pos %d\n", pos);
exit (CURLE_URL_MALFORMAT);
#if 0
printf("error: illegal pattern or range specification after pos %d\n",
pos);
#endif
return GLOB_ERROR;
}
pat->content.CharRange.ptr_c = pat->content.CharRange.min_c;
/* always check for a literal (may be "") between patterns */
return (pat->content.CharRange.max_c - pat->content.CharRange.min_c + 1) *
glob_word(glob, pattern + 4, pos + 4);
if(GLOB_ERROR == glob_word(glob, pattern + 4, pos + 4, &wordamount))
wordamount=1;
*amount = (pat->content.CharRange.max_c -
pat->content.CharRange.min_c + 1) *
wordamount;
return GLOB_OK;
}
if (isdigit((int)*pattern)) { /* numeric range detected */
pat->type = UPTNumRange;
pat->content.NumRange.padlength = 0;
if (sscanf(pattern, "%d-%d]", &pat->content.NumRange.min_n, &pat->content.NumRange.max_n) != 2 ||
if (sscanf(pattern, "%d-%d]",
&pat->content.NumRange.min_n,
&pat->content.NumRange.max_n) != 2 ||
pat->content.NumRange.min_n >= pat->content.NumRange.max_n) {
/* the pattern is not well-formed */
printf("error: illegal pattern or range specification after pos %d\n", pos);
exit (CURLE_URL_MALFORMAT);
#if 0
printf("error: illegal pattern or range specification after pos %d\n",
pos);
#endif
return GLOB_ERROR;
}
if (*pattern == '0') { /* leading zero specified */
c = pattern;
while (isdigit((int)*c++))
++pat->content.NumRange.padlength; /* padding length is set for all instances
of this pattern */
++pat->content.NumRange.padlength; /* padding length is set for all
instances of this pattern */
}
pat->content.NumRange.ptr_n = pat->content.NumRange.min_n;
c = (char*)(strchr(pattern, ']') + 1); /* continue after next ']' */
/* always check for a literal (may be "") between patterns */
return (pat->content.NumRange.max_n - pat->content.NumRange.min_n + 1) *
glob_word(glob, c, pos + (c - pattern));
if(GLOB_ERROR == glob_word(glob, c, pos + (c - pattern), &wordamount))
wordamount = 1;
*amount = (pat->content.NumRange.max_n -
pat->content.NumRange.min_n + 1) *
wordamount;
return GLOB_OK;
}
printf("error: illegal character in range specification at pos %d\n", pos);
exit (CURLE_URL_MALFORMAT);
/*printf("error: illegal character in range specification at pos %d\n",
pos);*/
return GLOB_ERROR;
}
int glob_word(URLGlob *glob, char *pattern, int pos)
GlobCode glob_word(URLGlob *glob, char *pattern, int pos, int *amount)
{
/* processes a literal string component of a URL
special characters '{' and '[' branch to set/range processing functions
@@ -161,17 +216,17 @@ int glob_word(URLGlob *glob, char *pattern, int pos)
char* buf = glob->glob_buffer;
int litindex;
*amount = 1; /* default is one single string */
while (*pattern != '\0' && *pattern != '{' && *pattern != '[') {
if (*pattern == '}' || *pattern == ']') {
printf("illegal character at position %d\n", pos);
exit (CURLE_URL_MALFORMAT);
return GLOB_ERROR;
}
if (*pattern == '\\') { /* escape character, skip '\' */
++pattern;
++pos;
if (*pattern == '\0') { /* but no escaping of '\0'! */
printf("illegal character at position %d\n", pos);
exit (CURLE_URL_MALFORMAT);
return GLOB_ERROR;
}
}
*buf++ = *pattern++; /* copy character to literal */
@@ -182,16 +237,21 @@ int glob_word(URLGlob *glob, char *pattern, int pos)
/* literals 0,1,2,... correspond to size=0,2,4,... */
glob->literal[litindex] = strdup(glob->glob_buffer);
++glob->size;
if (*pattern == '\0')
return 1; /* singular URL processed */
if (*pattern == '{') {
return glob_set(glob, ++pattern, ++pos); /* process set pattern */
switch (*pattern) {
case '\0':
return GLOB_OK; /* singular URL processed */
case '{':
/* process set pattern */
return glob_set(glob, ++pattern, ++pos, amount);
case '[':
/* process range pattern */
return glob_range(glob, ++pattern, ++pos, amount);
}
if (*pattern == '[') {
return glob_range(glob, ++pattern, ++pos);/* process range pattern */
}
printf("internal error\n");
exit (CURLE_FAILED_INIT);
return GLOB_ERROR; /* something got wrong */
}
int glob_url(URLGlob** glob, char* url, int *urlnum)
@@ -201,7 +261,9 @@ int glob_url(URLGlob** glob, char* url, int *urlnum)
* as the specified URL!
*/
URLGlob *glob_expand;
int amount;
char *glob_buffer=(char *)malloc(strlen(url)+1);
if(NULL == glob_buffer)
return CURLE_OUT_OF_MEMORY;
@@ -214,7 +276,16 @@ int glob_url(URLGlob** glob, char* url, int *urlnum)
glob_expand->urllen = strlen(url);
glob_expand->glob_buffer = glob_buffer;
glob_expand->beenhere=0;
*urlnum = glob_word(glob_expand, url, 1);
if(GLOB_OK == glob_word(glob_expand, url, 1, &amount))
*urlnum = amount;
else {
/* it failed, we cleanup */
free(glob_buffer);
free(glob_expand);
glob_expand = NULL;
*urlnum = 1;
}
*glob = glob_expand;
return CURLE_OK;
}

View File

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

View File

@@ -53,4 +53,13 @@ command8.txt name14.txt prot5.txt \
command9.txt name15.txt prot6.txt \
error111.txt name16.txt prot7.txt \
command26.txt prot26.txt command27.txt prot27.txt \
name26.txt reply26.txt name27.txt stdout27.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 \
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

View File

@@ -0,0 +1,3 @@
ftp://%HOSTIP:%FTPPORT/106 -Q "-DELE file"

View File

@@ -0,0 +1 @@
ftp://%HOSTIP:%FTPPORT/106 -Q "-DELE after_transfer" -Q "DELE before_transfer"

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

@@ -0,0 +1 @@
--globoff http://%HOSTIP:%HOSTPORT/wantit/{}[]/28

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/name120.txt Normal file
View File

@@ -0,0 +1 @@
ftp download with post-quote delete operation

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

@@ -0,0 +1 @@
ftp download with post- and pre-transfer delete operations

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

@@ -0,0 +1 @@
--globoff with {][} in URL

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

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

@@ -0,0 +1,6 @@
USER anonymous
PASS curl_by_daniel@haxx.se
PASV
TYPE I
RETR 106
DELE file

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

@@ -0,0 +1,7 @@
USER anonymous
PASS curl_by_daniel@haxx.se
DELE before_transfer
PASV
TYPE I
RETR 106
DELE after_transfer

5
tests/data/prot28.txt Normal file
View File

@@ -0,0 +1,5 @@
GET /wantit/{}[]/28 HTTP/1.0
Host: 127.0.0.1:8999
Pragma: no-cache
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*

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

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

@@ -0,0 +1,6 @@
data
to
see
that FTP
works
so does it?

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

@@ -0,0 +1,6 @@
data
to
see
that FTP
works
so does it?

5
tests/data/reply28.txt Normal file
View File

@@ -0,0 +1,5 @@
HTTP/1.1 200 OK
Server: fake
{}[] in the URL is not legal

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

@@ -76,6 +76,7 @@ my %commandok = (
'SIZE' => 'loggedin|twosock',
'PWD' => 'loggedin|twosock',
'QUIT' => 'loggedin|twosock',
'DELE' => 'loggedin|twosock'
);
# initially, we're in 'fresh' state
@@ -97,6 +98,7 @@ my %displaytext = ('USER' => '331 We are happy you popped in!',
'QUIT' => '221 bye bye baby', # just reply something
'PWD' => '257 "/nowhere/anywhere" is current directory',
'REST' => '350 Yeah yeah we set it there for you',
'DELE' => '200 OK OK OK whatever you say'
);
# callback functions for certain commands
@@ -300,6 +302,7 @@ $SIG{CHLD} = \&REAPER;
my %customreply;
sub customize {
undef %customreply;
open(CUSTOM, "<log/ftpserver.cmd") ||
return 1;
@@ -307,7 +310,6 @@ sub customize {
print STDERR "FTPD: Getting commands from log/ftpserver.cmd\n";
}
undef %customreply;
while(<CUSTOM>) {
if($_ =~ /REPLY ([A-Z]+) (.*)/) {
$customreply{$1}=$2;

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