go – Golang mux http.FileServer not returning image-ThrowExceptions

Exception or error:

I am new to go and am trying to setup a go server. My intention is to return an image when the url is hit.

this is what i have done

myRouter := mux.NewRouter()
myRouter.HandleFunc("/poster_path/{id}",posterfunc)

This is my posterfunc

func posterfunc(w http.ResponseWriter, r *http.Request){
    w.Header().Set("Content-Type", "image/jpeg")
    vars := mux.Vars(r)
    key := vars["id"]
    var url = "/home/rakshithjk/Desktop/poster/"+key+".jpg"
    http.FileServer(http.Dir(url))
}

This is the output in Postman –
enter image description here

Any help would be appreciated.

UPDATE –
tried changing http.FileServer to http.ServeFile, but the output remains the same
Modified handler function

func posterfunc(w http.ResponseWriter, r *http.Request){
    w.Header().Set("Content-Type", "image/jpeg")
    vars := mux.Vars(r)
    key := vars["id"]
    var url = "/home/rakshithjk/Desktop/poster/"+key+".jpg"
    http.ServeFile(w, r,url)

This is my entire file contents(for reference)

package main

import (
    "fmt"
    "log"
    "net/http"
    "encoding/json"
    "database/sql"
    _ "github.com/go-sql-driver/mysql"
    "github.com/gorilla/mux"
    //"github.com/davecgh/go-spew/spew"
)


func handleRequests() {
    myRouter := mux.NewRouter()
    myRouter.HandleFunc("/", homePage)
    myRouter.HandleFunc("/movie/top_rated", returnSingleArticle)
    myRouter.HandleFunc("/poster_path",posterfunc)

    log.Fatal(http.ListenAndServe(":10000", myRouter))
}

func enableCors(w *http.ResponseWriter) {
    (*w).Header().Set("Access-Control-Allow-Origin", "*")

}
type movie_list struct {
    Page int `json:"page"`
    Results []movie `json:"results"`
}
type movie struct {
    Id      int `json:"id"`
    Title   string `json:"title"`
    Language    string `json:"language"`
    Release_date string `json:"release_date"`
    Poster_path string `json:"poster_path"`
    Background_path string `json:"background_path"`
    Overview string `json:"overview"`
    Genre_ids string `json:"genre_ids"`
}

func posterfunc(w http.ResponseWriter, r *http.Request){
     w.Header().Set("Content-Type", "image/jpeg")
    //vars := mux.Vars(r)
    //key := vars["id"]
    enableCors(&w)

    var url = "/home/rakshithjk/go/src/clumio/112.png"
    fmt.Fprintf(w, "Hello, %q\n", url)
    http.ServeFile(w, r,url)
}

func homePage(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Welcome to the HomePage!")
    fmt.Println("Endpoint Hit: homePage")
}

func returnSingleArticle(w http.ResponseWriter, r *http.Request) {
    //vars := mux.Vars(r)
    //key := vars["id"]
    enableCors(&w)
    db, err := sql.Open("mysql", "root:72574484@tcp(127.0.0.1:3306)/PicturePerfect")
             if err != nil {
                 fmt.Println(err)
                 }else{
                 fmt.Println("Connection Established")
             }
    rows,err:=db.Query("select * from movies limit 10")

         if err!=nil{
            fmt.Println(err)
         }

         var list movie_list
         var tag movie

         for rows.Next(){

             err:=rows.Scan(&tag.Id,&tag.Title,&tag.Language,&tag.Release_date,&tag.Poster_path,&tag.Background_path,&tag.Overview,&tag.Genre_ids)
             if err != nil {
             fmt.Println(err)
            }
            fmt.Println(tag.Id)
            list.Results = append(list.Results,tag)
         }

        err = rows.Err()
        if err != nil {
            fmt.Println(err)
        }

        defer db.Close()


            //fmt.Fprintf(w, "Hello, %q\n", list.Results[3])
            w.Header().Set("Content-Type", "application/json")
            json.NewEncoder(w).Encode(list) 
            //spew.Dump(list)
            //fmt.Fprintf(w, "given lamguage, %q\n", tag.Poster_path)



}

func main() {
    handleRequests()

}
How to solve:

http.FileServer() should not be called in a function like that. It returns a Handler function (a function similar to the posterfunc you created).

It should be used as the handler function in the route configuration like this:

myRouter.HandleFunc("/poster_path/",http.FileServer(http.Dir("./your_dir")))

Here you can find the documentation for http.FileServer, with some more detailed examples.

This blog post does a fine step-by-step explanation on how to set it up.

UPDATE:

If you want to use it inside your handler, you should use http.ServeFile. It will respond to the request with the contents of the named file or directory.

Docs here

func posterfunc(w http.ResponseWriter, r *http.Request){
    w.Header().Set("Content-Type", "image/jpeg")
    vars := mux.Vars(r)
    key := vars["id"]
    var url = "/home/rakshithjk/Desktop/poster/"+key+".jpg"
    http.ServeFile(w, r, url)
}

UPDATE 2:

The issue in the new snippet is that you are printing to the interface just before serving the file.
Remove this line:

fmt.Fprintf(w, "Hello, %q\n", url)

Leave a Reply

Your email address will not be published. Required fields are marked *