0

I am new to golang and i am trying to make a server which will fetch the list of files and create an html and write it to the response

i have created links of the file so that when it is clicked , then the file is downloaded

But this is not happening , instead the html is being downloaded instead of file

here is what i am doing

package main

import (
    "fmt"
    "io/ioutil"
    "net/http"
    "io"
)

func getFile(res http.ResponseWriter, req *http.Request) {

    files, _ := ioutil.ReadDir("./publicFolder/")
    res.Header().Set("Content-Type", "text/html; charset=utf-8")

    myHtml := `
           <!DOCTYPE html>
           <html>
           <head>
             <title>Home Network</title>
           </head>
           <body>
              <ul>`
    for _, f := range files {
    fmt.Println(f.Name())
    myHtml += (`
        <a href="./publicFolder/` + f.Name() + `" download="`+f.Name()+`" >` + f.Name() + `</a>`)

    }
    myHtml += (
    `
    </ul>
    </body>
    </html>
    `)  
    io.WriteString(res, myHtml)
}

func main() {
    http.HandleFunc("/getFile/", getFile)
    http.ListenAndServe(":8008", nil)
}

i have added download attribute to the html in tag But the html is being downloaded instead of file

i tried creating an html file and running it , in that case the file is being downloaded

here is the html which i created to test

<html>
    <head>
    </head>
    <body>
       <ul>
            <li><a href="./publicFolder/doc.txt" download="doc.txt">file1</a></li>
        </ul>
    </body>
</html>

EDIT

the content of doc.txt when downloading using the golang server

<html>
    <head>
    <title>
        Home Network
    </title>
    </head>
    <body>
        <ul>
        <li>
          <a href="./publicFolder/GAMES.cpp" download="GAMES.cpp">GAMES.cpp</a>
        </li>
        <li>
          <a href="./publicFolder/doc.txt" download="doc.txt">doc.txt</a>
        </li>
        <li>
          <a href="./publicFolder/erlang" download="erlang">erlang</a>
        </li>
    </ul>
    </body>
    </html>

Content of doc.txt when downloading from html file(and this is the actual content )

this is a test file doct.txt

EDIT i have added this FileServer

http.Handle("/getFile/publicFolder/", http.StripPrefix("/getFile/publicFolder/", http.FileServer(http.Dir("/publicFolder"))))
Ezio
  • 723
  • 6
  • 14
  • Please show what you mean by "html is being downloaded instead of file". What is the case that works? – JimB Jan 11 '17 at 14:02
  • There is nothing in your code that would send the file content, you only have a single handler which serves an HTML document. See this answer how to serve file content: [Include js file in Go template](http://stackoverflow.com/questions/28899675/include-js-file-in-go-template/28899786#28899786). – icza Jan 11 '17 at 14:03
  • when i am using html and clicking on the link then the file doc.txt is being dowloaded , but when i am serving html from the golang server the file is being downloaded but instead of having the content of the file , it is having the html code which was written to the response writer – Ezio Jan 11 '17 at 14:04
  • @icza when i am using the html file which i provided in the end of the post , in that case i am getting the file, if a particular html is able to send the file , then why not the same html being fed from response writer is doing so ? – Ezio Jan 11 '17 at 14:06
  • @Ezio Please read my previous comment carefully. You don't get file content because nothing in your posted code serves file content. I don't know the code where you claim you get some, but what you posted should never return any file content. – icza Jan 11 '17 at 14:07
  • @icza if i am doing file , from html file the file is being downloaded WITH ACTUAL CONTENT OF FILE, but the same html if i am writing to response writer , then the file is downloaded BUT IT DOESNOT CONTAINS THE CONTENT OF THE FILE but it contains the html code , my main Question is if an html file is doing something correctly , then how come same html written to response writer not doing the same thing – Ezio Jan 11 '17 at 14:12
  • 1
    @Ezio Please show me the part of your code which opens `doc.txt` and sends its content, because I only see a handler in your code which sends an html document. There isn't, that's why it never happens. – icza Jan 11 '17 at 14:15
  • @icza i have added the doc.txt content for both cases – Ezio Jan 11 '17 at 14:19
  • Programming languages do exactly what you tell them to do. If you want Go to send `doc.txt`, you *must* tell it to send `doc.txt`. – noisypixy Jan 11 '17 at 14:29
  • `http.Dir` is a path relative to the current working directory. To avoid problems, use an absolute path. – noisypixy Jan 11 '17 at 14:49
  • @noisypixy the folder publicFolder is inside the current directory only where the server program is stored – Ezio Jan 11 '17 at 14:51
  • @Ezio `http.Dir("./publicFolder")` – noisypixy Jan 11 '17 at 14:57
  • @noisypixy i forgot to add that , thank you its worked now :) – Ezio Jan 11 '17 at 14:59

2 Answers2

2

When you open a local HTML file in your browser, then the browser will read the HTML file locally, from your disk. You will see a URL and protocol something like file:///home/bob/test.html. In this case your Go web server is not called (it's excluded from the "loop"). Since you use relative paths in the href attributes of your <a> tags, they will also point to local files (file:/// protocol), so the browser will also read the linked files directly, "avoiding" your Go web server.

If you serve the HTML from Go (HTTP handler as in your example), and you access it from the browser, then the browser will not read the file, it will perform another HTTP GET as your link <a> dictates. Your Go server has to read it and send it.

Again, check out this answer how you can serve files from Go: Include js file in Go template

Community
  • 1
  • 1
icza
  • 389,944
  • 63
  • 907
  • 827
  • thank you for the answer, i understand what you are saying , so i have added the FileServer but still nothing is happening. i think i am missing something. It would real nice of you if you could please demonstrate what changes to do in my code in order to make the link in html to download the file from server – Ezio Jan 11 '17 at 14:32
  • please see the edit, it is having the file server that i have added – Ezio Jan 11 '17 at 14:43
1

While icza's answer is right, let me explain some things.

What is the difference between writing html through response writer and directly serving file in golang?

None. You'll be writing to an io.Writer either way.

i have created links of the file so that when it is clicked , then the file is downloaded

But this is not happening , instead the html is being downloaded instead of file

This is roughly what is happening under the hood:

  1. You open http://localhost:8008/getFile/ in your browser.
  2. Your browser makes an HTTP request to http://localhost:8008/getFile/.
  3. Your Go server receives the request. Since it begins with /getFile/, it runs the getFile handler.
  4. The getFile handler writes HTML back to the browser.
  5. The browser receives that HTML (the list of files).
  6. You click in the link for doc.txt.
  7. The browser makes an HTTP request to http://localhost:8008/getFile/publicFolder/doc.txt
  8. (Same as step 3)
  9. (Same as step 4)
  10. (Same as step 5)

You're never telling your Go server how to send those files. The only thing you're telling it to do is:

  • If you get a request, and its path starts with /getFile/, reply with this HTML.

That's the only thing it's doing, and it's doing it fine.

Community
  • 1
  • 1
noisypixy
  • 744
  • 4
  • 11