Hi,
Here's a patch for a couple of issues with ftp(1):
Servers that don't support content ranges
=========================================
Currently, performing "ftp -C" against a server that doesn't support
content ranges (which includes Apache 1.3), will redownload the
entire file, and append the entire contents onto the existing file.
So, if we have "myfile.txt" that is 200 bytes long (on the server), and
it already exists on the filesystem, but it is only 100 bytes long,
performing:
ftp -C http://localhost/myfile.txt
will result in a local file that is 300 bytes long.
HTTP 1.0 and the Host header
============================
The Host header didn't appear until the HTTP 1.1 spec, but we are using
it with HTTP 1.0 requests:
* I don't know if there are any httpds that actually care.
* Wget uses HTTP 1.0 with Host headers.
* Curl uses HTTP 1.1 with Host headers (gets it right?)
Connection: close
=================
According to:
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.10
"HTTP/1.1 applications that do not support persistent connections MUST
include the "close" connection option in every message."
Thoughts?
---
Matthew Mulrooney
Teamify - Team Management Simplified - http://www.teamify.com
---
Index: fetch.c
===================================================================
RCS file: /cvs/src/usr.bin/ftp/fetch.c,v
retrieving revision 1.97
diff -u fetch.c
--- fetch.c 16 Oct 2009 12:28:04 -0000 1.97
+++ fetch.c 12 Jan 2010 23:11:17 -0000
@@ -552,7 +552,7 @@
#endif /* !SMALL */
if (verbose)
- fprintf(ttyout, "Requesting %s", origline);
+ fprintf(ttyout, "Requesting %s%s", origline, debug ? "\n" : "");
/*
* Construct and send the request. Proxy requests don't want leading /.
@@ -590,11 +590,8 @@
restart_point = 0;
}
#endif /* !SMALL */
- ftp_printf(fin, ssl, "GET /%s %s\r\nHost: ", epath,
-#ifndef SMALL
- restart_point ? "HTTP/1.1" :
-#endif /* !SMALL */
- "HTTP/1.0");
+ /* The "Host" header is only valid for HTTP 1.1 */
+ ftp_printf(fin, ssl, "GET /%s %s\r\nHost: ", epath, "HTTP/1.1");
if (strchr(host, ':')) {
char *h, *p;
@@ -627,6 +624,11 @@
if (port && strcmp(port, "80") != 0)
ftp_printf(fin, ssl, ":%s", port);
#endif /* !SMALL */
+ /* "Connection: close" is required by RFC2616. It also
+ prevents a 15 second delay whilst the client and the server
+ both wait for the other to sever the connection (after the
+ data has finished streaming.) */
+ ftp_printf(fin, ssl, "\r\nConnection: close");
ftp_printf(fin, ssl, "\r\n%s%s\r\n\r\n",
buf ? buf : "", HTTP_USER_AGENT);
if (verbose)
@@ -670,6 +672,10 @@
switch (status) {
case 200: /* OK */
+ if (resume) {
+ warnx("Server lacks file transfer continuation
support.");
+ goto cleanup_url_get;
+ }
#ifndef SMALL
case 206: /* Partial Content */
#endif /* !SMALL */
@@ -1317,13 +1323,16 @@
va_start(ap, fmt);
- if (fp != NULL)
+ if (fp != NULL) {
+ /* Show the HTTP request when in debug mode. */
+ if (debug)
+ vprintf(fmt, ap);
ret = vfprintf(fp, fmt, ap);
#ifndef SMALL
- else if (ssl != NULL)
+ } else if (ssl != NULL) {
ret = SSL_vprintf((SSL*)ssl, fmt, ap);
#endif /* !SMALL */
- else
+ } else
ret = 0;
va_end(ap);