TL;DR
You are only serving the root HTML page, you need to respond to requests to other resources too (you can see what resource is being requested with the URL variable of the *http.Request variable)
When serving the resources, you need to write the Header's Content-Type
to let the browser know what's the type of the resource (like image/png
)
Full Answer
What you are doing in your request handler is getting http://www.meaningfultype.com/
, the HTML page, then the browser finds an image like /images/header-logo.png
and makes the request to get it but your server in localhost doesn't know how to respond to http://localhost/images/header-logo.png
.
Assuming your handler function is handling requests at the root of the server ("/"
), you could get the requested URL r.URL
and use it to get the required resource:
url := "http://www.meaningfultype.com/"
if r.URL.Host == "" {
url += r.URL.String()
} else {
url = r.URL.String()
}
res, err := http.Get(url)
The problem is that, even after doing this, all the resources are sent as plain/text
because you are not setting the Header's Content-Type
. That's why you need to specify the type of the resource before writing. In order to know what the type of the resource is, just get it from the Content-Type
you just received in the Header of the response of http.Get
:
contentType := res.Header.Get("Content-Type")
w.Header().Set("Content-Type", contentType)
w.Write(robots)
The final result:
package main
import (
"io/ioutil"
"log"
"net/http"
)
func main() {
http.HandleFunc("/", factHandler)
http.ListenAndServe(":8080", nil)
}
func factHandler(w http.ResponseWriter, r *http.Request) {
url := "http://www.meaningfultype.com/"
if r.URL.Host == "" {
url += r.URL.String()
} else {
url = r.URL.String()
}
res, err := http.Get(url)
if err != nil {
log.Fatal(err)
}
robots, err := ioutil.ReadAll(res.Body)
res.Body.Close()
if err != nil {
log.Fatal(err)
}
contentType := res.Header.Get("Content-Type")
w.Header().Set("Content-Type", contentType)
w.Write(robots)
}