I am trying to serve some fonts, but when i visit localhost:4000/fonts, it gives me 404 not found. my code:
fs := http.FileServer(http.Dir("./fonts"))
http.Handle("/fonts", http.StripPrefix("/fonts/", fs))
http.Handle("/", app.routes())
log.Println("Serving at localhost:4000...")
log.Fatal(http.ListenAndServe(fmt.Sprintf("localhost:%d", cfg.Port), nil))
UPDATE
if im serving from "/" and not "/fonts", it works. but i want it to work from "/fonts".
You should not strip the trailing slash after fonts since you want the result to be /file and not file.
You should also add the trailing slash to the handler path, for the same reason.
http.Handle("/fonts/", http.StripPrefix("/fonts", fs))
Both changes, as mentioned, have the purpose to leave you with a path like /somefile that is looked up against the filesevers file system.
Related
main.go
package main
import (
"net/http"
)
func main() {
http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))
http.ListenAndServe(":8080", nil)
}
Directory structure:
%GOPATH%/src/project_name/main.go
%GOPATH%/src/project_name/static/..files and folders ..
Even after reading the documentation I have trouble understanding what exactly http.StripPrefix does here.
1) Why can't I access localhost:8080/static if I remove http.StripPrefix?
2) What URL maps to /static folder if I remove that function?
http.StripPrefix() forwards the handling of the request to one you specify as its parameter, but before that it modifies the request URL by stripping off the specified prefix.
So for example in your case if the browser (or an HTTP client) requests the resource:
/static/example.txt
StripPrefix will cut the /static/ and forward the modified request to the handler returned by http.FileServer() so it will see that the requested resource is
/example.txt
The Handler returned by http.FileServer() will look for and serve the content of a file relative to the folder (or rather FileSystem) specified as its parameter (you specified "static" to be the root of static files).
Now since "example.txt" is in the static folder, you have to specify a relative path to that to get the corrent file path.
Another Example
This example can be found on the http package documentation page (here):
// To serve a directory on disk (/tmp) under an alternate URL
// path (/tmpfiles/), use StripPrefix to modify the request
// URL's path before the FileServer sees it:
http.Handle("/tmpfiles/",
http.StripPrefix("/tmpfiles/", http.FileServer(http.Dir("/tmp"))))
Explanation:
FileServer() is told the root of static files is "/tmp". We want the URL to start with "/tmpfiles/". So if someone requests "/tempfiles/example.txt", we want the server to send the file "/tmp/example.txt".
In order to achieve this, we have to strip "/tmpfiles" from the URL, and the remaining will be the relative path compared to the root folder "/tmp" which if we join gives:
/tmp/example.txt
Assume that
I have a file
/home/go/src/js/kor.js
Then, tell fileserve serves local directory
fs := http.FileServer(http.Dir("/home/go/src/js"))
Example 1 - root url to Filerserver root
Now file server takes "/" request as "/home/go/src/js"+"/"
http.Handle("/", fs)
Yes, http://localhost/kor.js request tells Fileserver, find kor.js in
"/home/go/src/js" + "/" + "kor.js".
we got kor.js file.
Example2 - custom url to Fileserver root
But, if we add additional resquest name.
http.Handle("/static/", fs)
Now file server takes "/static/" request as "/home/go/src/js"+"/static/"
Yes, http://localhost/static/kor.js request tells Fileserver, find kor.js in
"/home/go/src/js" + "/static/" + "kor.js".
We got 404 error.
Example 3 - custom url to Fileserver root with
so, we modify request url before Fileserver takes it with http.StripPrefix("/tmpfiles/", ...
after stripPrefix Fileserver take / instead /static/
"/home/go/src/js" + "/" + "kor.js".
got kor.js
I'll answer the two questions one by one.
Answer 1 to Question 1:
If your code is written like below:
http.Handle("/static/", http.FileServer(http.Dir("static"))
your root folder is %GOPATH%/src/project_name/static/. When you access localhost:8080/static, the URL /static will be forwarded to the handler returned by http.FileServer(). However, you have no directory or file named static in the root folder.
Answer 2 to Question 2: In general, you cannot access /static folder if you remove the http.StripPrefix(). However, if you have a directory or file named static, you can access it (exactly not the root directory you want) with the URL localhost:8080:/static.
By the way, you cannot access anything if your URL does not begin with /static, because the http.ServeMux will not redirect your request.
For anyone having issues with subdirectories, you need to add a "." because it seems it treats the path as relative only if it's a folder in the root directory of the binary.
For example
s.router.PathPrefix("/logos/").Handler(
http.StripPrefix("/logos/", http.FileServer(http.Dir("./uploads/logos/"))))
Note the "." before "/uploads"
I created a static folder that contains index.html file, and in my go file, I wrote:
package main
import (
"net/http"
)
func main() {
http.Handle("/", http.FileServer(http.Dir("./static")))
http.ListenAndServe(":8482", nil)
}
And it works fine upon exploring http://localhost:8482/
I tried to write the code as:
http.Handle("/static", http.FileServer(http.Dir("./static")))
But it fails upon exploring http://localhost:8482/static with 404 error
http.Handle("/static", http.FileServer(http.Dir("./static"))) simply means, "whenever someone connects to .../static, reroute the entire request to a file server rooted at directory ./static".
However, the url is passed along to the file server as-is. In other words, the file server receives the request from the user, and believes that the user is looking for a file called "static" within the root ("./static") directory.
In fact, if you simply placed a file called "static" in your "./static" directory, going to .../static would serve that file.
So the fix requires two things:
Change the path prefix to "/static/" rather than "/static", so that all files within the static directory can be rerouted to the file server (rather than only the "/static" request)
Strip the "/static/" path prefix from the request before passing it to the file server.
Like so:
http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("./static"))))
I need to serve an html file to localhost:8080/lvlione but the FileServer function in golang doesn't seem to work.
Here is main.go:
package main
import (
"log" //logging that the server is running and other stuff
"net/http" //serving files and stuff
)
func main() {
//servemux
server := http.NewServeMux()
//handlers that serve the home html file when called
fs := http.FileServer(http.Dir("./home"))
os := http.FileServer(http.Dir("./lvlone")) //!!this is what is broken!!
//handles paths by serving correct files
//there will be if statements down here that check if someone has won or not soon
server.Handle("/", fs)
server.Handle("/lvlione", os)
//logs that server is Listening
log.Println("Listening...")
//starts server
http.ListenAndServe(":8080", server)
}
There is a folder in this directory called lvlone with one file in it (index.html). When I point my browser to localhost:8080/lvlione it returns 404, but when it is pointed to localhost:8080 it returns the correct file.
You need to call http.StripPrefix to remove the extra lvlone from the directory path.
server.Handle("/lvlone/", http.StripPrefix("/lvlone/", os))
By default the http.FileServer assumes the path given to it is the root path, and appends the URL to it. If it is to serve a subdirectory of the virtual path, then that needs to be stripped from the path.
And note that you need to have the trailing slashes in both places.
I'm trying to serve static files via http.FileServer, however it never sends back the directory I'm asking for. The code is snipped below:
func main() {
fmt.Println("Serving Files")
http.HandleFunc("/", homeFunc)
http.HandleFunc("/search", searchFunc)
http.Handle("/tmp/",
http.StripPrefix("/tmp/", http.FileServer(http.Dir("/assets"))))
http.ListenAndServe(":8080", nil)
}
When visiting mywebsite.com/tmp/, text appears saying "404 page not found." A little help in case I'm missing something would be greatly appreciated!
Edit: Here's the file architecture:
main folder
|
|-/Assets
|--(assets)
|
|-main.go
Does the directory /assets exist? Note that /assets is an absolute path, so it must be at the root of your filesystem. If you want something in the working directory where you're executing your program, you should use ./assets.
If you use relative path, you can check what your path is.
import (
"fmt"
"os"
)
dir, _ := os.Getwd()
fmt.Println("current path :" + dir)
What's wrong with http.Handle("/static/", http.FileServer(http.Dir("")))?
The shortest example I can find looks like this:
fs := http.FileServer(http.Dir("static"))
http.Handle("/static/", http.StripPrefix("/static/", fs))
Is http.StripPrefix necessary?
No it is not required, but if you DO NOT use it the path used to find the file will include the prefix. This is clearer with an example, so imagine your folder structure was:
main.go
static/
styles.css
And you serve the files with:
http.Handle("/static/", http.FileServer(http.Dir("")))
Then a user requesting the file at yoursite.com/static/styles.css would get the styles.css file in the static dir. But for this to work your paths must line up perfectly.
Most people prefer to do the following instead:
fs := http.FileServer(http.Dir("static"))
http.Handle("/static/", http.StripPrefix("/static/", fs))
Because they could change their URL path to be something like /assets/ without needing to rename the static dir (or vise versa - change the local dir structure w/out updating the URL path).
TL;DR - Path prefix isn't required but is useful to break any requirements of URL paths and local directory structure matching perfectly.