0

Whenever I make a large download from my website using Go, it prevents me from navigating or doing anything else in my website in the same browser at the same time the download is happening. This happens with Firefox, chrome and Safari which makes me think it is a conf issue.

Go env

GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/root/.cache/go-build"
GOENV="/root/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build062753082=/tmp/go-build"

Using the default GO Web server net/http for this.

EDIT:

Sorry forgot about the code for the download

func FunctionName(res http.ResponseWriter, req *http.Request, p httprouter.Params) {
    defer req.Body.Close()
    setSecurityHeaders(res)
    req.ParseForm()
    id := p.ByName("id")

    incletter, err := GetIncLetterById(bson.ObjectIdHex(id))
    if err != nil {
        jsonResponse(res, map[string]string{"status": "error", "message": "."})
        return
    }

    bytes, filename := incletter.GetFileBytes()

    res.Header().Set("Content-Disposition", "attachment; filename=\""+filename+"\"")
    res.Header().Set("Content-type", "application/pdf")
    res.Header().Set("Content-Length", strconv.Itoa(len(bytes)))
    res.Write(bytes)
}
Alan Faz
  • 142
  • 14
  • GO VERSION: go version go1.14 linux/amd64 – Alan Faz Jun 01 '20 at 19:39
  • It would be interesting to see the code that handles the request (there's no way to know from the details that are there). Just a random guess, you might need to set a [`Content-Disposition` header](https://stackoverflow.com/a/9195376/5728357) on your response so the browser will directly start a download instead of trying to sniff the content – xarantolus Jun 01 '20 at 20:08
  • 2
    We cannot help with code we cannot see. Please create a [mre], and read [ask] – JimB Jun 01 '20 at 20:11
  • Added code that servers the file.. – Alan Faz Jun 01 '20 at 22:02

2 Answers2

0

Your headers look good (Though I think the proper content type notation is proper case ("Content-Type"). If this is only happening for large files, I suspect this means the entire file is being loaded into memory before being streamed to the client. To get around this, you can use the following:

byteSlice, filename := incletter.GetFileBytes()
byteStream := bytes.NewReader(byteSlice)

res.Header().Set("Content-Disposition", "attachment; filename=\""+filename+"\"")
res.Header().Set("Content-type", "application/pdf")
res.Header().Set("Content-Length", strconv.Itoa(len(bytes)))

io.Copy(res, byteStream)

This will essentially stream from a reader interface to a writer directly to the client.

Josh Ray
  • 291
  • 2
  • 7
0

After hours of beeing troubled I reached out to my server provider and it was their fault, they had some kind of limited bandwith... Thanks all

Alan Faz
  • 142
  • 14