Repository: go
Issue: net/http: NewFileTransport does not populate Response.Request on redirect
Labels: NeedsInvestigation

<!--
Please answer these questions before submitting your issue. Thanks!
-->

### What version of Go are you using (`go version`)?

<pre>
$ go version
go version go1.17.8 darwin/amd64
</pre>

### Does this issue reproduce with the latest release?



### What operating system and processor architecture are you using (`go env`)?

<details><summary><code>go env</code> Output</summary><br><pre>
$ go env

GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/aron/Library/Caches/go-build"
GOENV="/Users/aron/Library/Application Support/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="/Users/aron/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/aron/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
GOVCS=""
GOVERSION="go1.17.8"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/dev/null"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -arch x86_64 -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/8j/pt4fjhkj11d3xd9344pdspmh0000gn/T/go-build2963024848=/tmp/go-build -gno-record-gcc-switches -fno-common"
</pre></details>

### What did you do?

The `http.NewFileTransport` creates a transport where `RoundTrip` does not populate the `Request` field of its `http.Response` on redirects.

Given the following Go program:

```go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)
func main() {
	transport := &http.Transport{}
	transport.RegisterProtocol("file", http.NewFileTransport(http.Dir("./www")))
	client := &http.Client{
		Transport: transport,
		CheckRedirect: func(req *http.Request, via []*http.Request) error {
			fmt.Printf("redirect-check: %s\n", req.URL)
			// we do our own redirect processing.
			return nil
		},
	}
	targetURL := "file:///sub"
	fmt.Printf("target url: %s\n", targetURL)
	resp, err := client.Get(targetURL)
	if err != nil {
		fmt.Printf("client error: %s\n")
		os.Exit(1)
	}

	if resp.Request != nil {
		fmt.Printf("request url: %s\n", resp.Request.URL)
	} else {
		fmt.Printf("no response request\n")
	}

	fmt.Printf("body-start\n")
	io.Copy(os.Stdout, resp.Body)
	fmt.Printf("body-end\n")
	
}
```

Using a local directory structure:

```
www/
    sub/
        index.html
```

### What did you expect to see?

I expected the program to print:

```
target url: file:///sub
redirect-check: file:///sub/
request url: file:///sub/
body-start
<html><body>sub</body></html>
body-end
```

The `request url` print line indicates that the `http.Response` returned by the client has its `Request` field populated, which allows the caller to understand the final URL requested along the (local) redirect chain.

### What did you see instead?

Using Go 1.17.8, the program prints:

```
$ go run main.go
target url: file:///sub
redirect-check: file:///sub/
no response request
body-start
<html><body>sub</body></html>
body-end
```

The `no response redirect` indicates that the `http.Response` returned by the client has an empty `Request` field, which is different than the behavior seen when using non-file transports.