NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

bin/60346: ftp failure when handling redirect through HTTP proxy



>Number:         60346
>Category:       bin
>Synopsis:       ftp failure when handling redirect through HTTP proxy
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sun Jun 21 07:40:00 +0000 2026
>Originator:     Michael van Elst
>Release:        NetBSD 11.99.6
>Organization:
	
>Environment:
	
	
System: NetBSD arnold 11.99.6 NetBSD 11.99.6 (EGGHED64) #0: Sat Jun 6 12:50:49 UTC 2026 mlelstv@slowpoke:/home/netbsd-current/obj.evbarm64-el/scratch/netbsd-current/src/sys/arch/evbarm/compile/EGGHED64 evbarm
Architecture: aarch64
Machine: evbarm
>Description:

Using ftp(1) to fetch e.g.:

https://nycdn.netbsd.org/pub/NetBSD-daily/netbsd-11/latest/LAST_MINUTE

results in an error when the query is sent through a http proxy. E.g:

% ftp https://nycdn.netbsd.org/pub/NetBSD-daily/netbsd-11/latest/LAST_MINUTE
Trying [2a01:170:1141:404:9e5c:8eff:fe77:744e]:3128 ...
Requesting https://nycdn.netbsd.org/pub/NetBSD-daily/netbsd-11/latest/LAST_MINUTE
  (via proxy.local:3128)
Redirected to /pub/NetBSD-daily/netbsd-11/20260616154807Z/LAST_MINUTE
Trying [2a01:170:1141:404:9e5c:8eff:fe77:744e]:3128 ...
Requesting /pub/NetBSD-daily/netbsd-11/20260616154807Z/LAST_MINUTE
  (via proxy.local:3128)
ftp: Error retrieving file `400 Bad Request'

The reason ist that the 'latest' path is redirected to a relative
URL. This works without proxy as the web server understands the
relative URL. But a proxy must be queried with an absolute URL.

>How-To-Repeat:

Try to fetch from NetBSD-daily using the 'latest' path and using
a HTTP proxy.

>Fix:

Maybe this:

Index: usr.bin/ftp/fetch.c
===================================================================
RCS file: /cvsroot/src/usr.bin/ftp/fetch.c,v
retrieving revision 1.246
diff -p -u -r1.246 fetch.c
--- usr.bin/ftp/fetch.c	8 Feb 2026 09:00:54 -0000	1.246
+++ usr.bin/ftp/fetch.c	21 Jun 2026 07:32:25 -0000
@@ -115,6 +115,7 @@ static int	parse_url(const char *, const
 static void	url_decode(char *);
 static void	freeauthinfo(struct authinfo *);
 static void	freeurlinfo(struct urlinfo *);
+static char	*make_absurl(char *, const char *);
 
 static int	redirect_loop;
 
@@ -1115,6 +1116,41 @@ do_auth(int hcode, const char *url, cons
 }
 #endif
 
+static char *
+make_absurl(char *url, const char *prevurl)
+{
+	const char *proto, *hostport, *path;
+	char *buf;
+	size_t len;
+
+#ifdef WITH_SSL
+	if (STRNEQUAL(prevurl, HTTPS_URL))
+		proto = HTTPS_URL;
+	else
+#endif
+	if (STRNEQUAL(prevurl, HTTP_URL))
+		proto = HTTP_URL;
+	else
+		return url;
+
+	len = strlen(proto);
+	hostport = prevurl + len;
+	path = strchr(hostport, '/');
+	if (path != NULL)
+		len += path - hostport;
+	else
+		len += strlen(hostport);
+
+	buf = ftp_malloc(len + strlen(url) + 1);
+
+	strncpy(buf, prevurl, len);
+	strcat(buf, url);
+
+	FREEPTR(url);
+
+	return buf;
+}
+
 static int
 negotiate_connection(FETCH *fin, const char *url, const char *penv,
     struct posinfo *pi, time_t *mtime, struct authinfo *wauth,
@@ -1246,6 +1282,8 @@ negotiate_connection(FETCH *fin, const c
 			if (verbose)
 				fprintf(ttyout, "Redirected to %s\n",
 				    location);
+			if (location[0] == '/')
+				location = make_absurl(location, url);
 			*rval = go_fetch(location, ui);
 		}
 		goto cleanup_fetch_url;

>Unformatted:
 	
 	



Home | Main Index | Thread Index | Old Index