go: net/http: Transport does not handle 302 redirects with link-local server address correctly

Please answer these questions before submitting your issue. Thanks!

What version of Go are you using (go version)?

go version go1.8.3 linux/amd64

What operating system and processor architecture are you using (go env)?

GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/usr/local/go"
GORACE=""
GOROOT="/opt/go"
GOTOOLDIR="/opt/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0"
CXX="g++"
CGO_ENABLED="1"
PKG_CONFIG="pkg-config"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"

What did you do?

I need to get some data from link-local neighbor:

package main

import (
	"fmt"
	"net/http"
)

func main() {
	if resp, err := http.Get("http://[fe80::1%25eth0]:8002/info.json"); err == nil {
		defer resp.Body.Close()
		fmt.Println(resp)
	} else {
		fmt.Println(err)
	}
}

What did you expect to see?

Something like this:

&{200 OK 200 HTTP/1.1 1 1 map[Connection:[keep-alive] Set-Cookie:[uid=AAAAAVlBPd2KJ2cFAwMUAg==; path=/] Server:[nginx] Date:[Wed, 14 Jun 2017 13:45:01 GMT] Content-Type:[application/json]] 0xc42007a600 -1 [chunked] false false map[] 0xc4200e8300 <nil>}

What did you see instead?

Get http://[fe80::1]:8002/info.sh: dial tcp [fe80::1]:8002: connect: invalid argument

It happened, because http://[fe80::1%eth0]:8002/info.json returned 302-redirect to /info.sh and http-library lost zone-prefix somewhere while following redirect. Proof:

curl -v "http://\[fe80::1%25eth0\]:8002/info.json"
*   Trying fe80::1...
* Connected to fe80::1 (fe80::1) port 8002 (#0)
> GET /info.json HTTP/1.1
> Host: [fe80::1]:8002
> User-Agent: curl/7.47.0
> Accept: */*
>
< HTTP/1.1 302 Moved Temporarily
< Server: nginx
< Date: Wed, 14 Jun 2017 13:49:17 GMT
< Content-Type: text/html
< Content-Length: 154
< Location: http://[fe80::1]:8002/info.sh
< Connection: keep-alive
< Set-Cookie: uid=AAAAAVlBPt2KJ2cFAwMVAg==; path=/
<
<html>
<head><title>302 Found</title></head>
<body bgcolor="white">
<center><h1>302 Found</h1></center>
<hr><center>nginx</center>
</body>
</html>
* Connection #0 to host fe80::1 left intact

About this issue

  • Original URL
  • State: open
  • Created 7 years ago
  • Comments: 20 (13 by maintainers)

Most upvoted comments

I have no strong opinion on this feature because I have no measurement for IPv6 addressing/routing scope boundary handling in transport- and/or session-layer protocols, such as HTTP.

FWIW, the net/http package provides the CheckRedirect field of http.Client for such use cases.