Skip to content

Instantly share code, notes, and snippets.

@paulmach
Last active November 13, 2024 16:17
Show Gist options
  • Save paulmach/7271283 to your computer and use it in GitHub Desktop.
Save paulmach/7271283 to your computer and use it in GitHub Desktop.
Simple Static File Server in Go
/*
Serve is a very simple static file server in go
Usage:
-p="8100": port to serve on
-d=".": the directory of static files to host
Navigating to http://localhost:8100 will display the index.html or directory
listing file.
*/
package main
import (
"flag"
"log"
"net/http"
)
func main() {
port := flag.String("p", "8100", "port to serve on")
directory := flag.String("d", ".", "the directory of static file to host")
flag.Parse()
http.Handle("/", http.FileServer(http.Dir(*directory)))
log.Printf("Serving %s on HTTP port: %s\n", *directory, *port)
log.Fatal(http.ListenAndServe(":"+*port, nil))
}
Copy link

ghost commented Aug 16, 2016

thanks

@ctrekker
Copy link

Super helpful!

@gregogalante
Copy link

gregogalante commented Nov 2, 2017

My code is not working if i try to serve static files from a specific directory and a specific path.

The files structure is:

- serve.go
- images
- - example.jpg

The server handle is:

http.Handle("/images/", http.FileServer(http.Dir("./images")))

With this code the server return always a 404 error when i send a request to: http://localhost:8080/images/example.jpg

What's the problem?

Update

Solved with the usage of http.StripPrefix:

http.Handle("/images/", http.StripPrefix("/images/", http.FileServer(http.Dir("./images"))))

@philippgille
Copy link

Hi @paulmach,

I got inspired by this Gist, added printing a table of local network interfaces and a suggested URL for sharing, added flags, as well as created packages for Scoop (Windows package manager), Homebrew (macOS package manager) and Snap (Linux package manager).

See: https://github.com/philippgille/serve

I didn't add a license yet, because I wanted to ask you first about your consent regarding me creating that full-blown repository based on your Gist.

So: Is it okay for you if I add an Open Source license (haven't decided on one yet - eigher AGPL, MPL or Apache, see https://choosealicense.com/licenses/) to my project and continue working on it?

Kind regards,
Philipp

@paulmach
Copy link
Author

@philippgille Yes it is okay to use this GIST for whatever you want, Open Source or otherwise.

@philippgille
Copy link

@paulmach Thanks a lot!

@95rade
Copy link

95rade commented Oct 24, 2018

Awesome example of a simplest go web service. thanks for sharing

@bryaakov
Copy link

👍

@OnTitansShoulder
Copy link

Thanks for sharing, this is neat.

@immartian
Copy link

@abiiranathan
Copy link

It's weird that this exists. I was tired of using python3 -m http.server and decided to create my own. After, I googled to see what's out there, and alas!!

package main

import (
	"flag"
	"log"
	"net/http"
	"path/filepath"
)

var (
	path = flag.String("path", ".", "path to the folder to serve. Defaults to the current folder")
	port = flag.String("port", "8080", "port to serve on. Defaults to 8080")
)

func main() {
	flag.Parse()

	dirname, err := filepath.Abs(*path)
	if err != nil {
		log.Fatalf("Could not get absolute path to directory: %s: %s", dirname, err.Error())
	}

	log.Printf("Serving %s on port %s", dirname, *port)

	err = Serve(dirname, *port)
	if err != nil {
		log.Fatalf("Could not serve directory: %s: %s", dirname, err.Error())
	}

}

func Serve(dirname string, port string) error {
	fs := http.FileServer(http.Dir(dirname))
	http.Handle("/", fs)

	return http.ListenAndServe(":"+port, nil)
}

@kfelter
Copy link

kfelter commented May 10, 2022

Thanks!

@TheBrainDunne
Copy link

Thanks

@abiiranathan
Copy link

Am glad you found it useful

@hmmftg
Copy link

hmmftg commented Dec 11, 2023

Hi, I've added base URL as flag in this link

@ataha322
Copy link

ataha322 commented Jan 4, 2024

Thanks!

Does anybody happen to know why browsers try to display the old directory listing, even though the server is now launched from a different directory?

It's the same on my firefox on Linux machine and chrome on my android. If I reopen the page it'll show the old listing, even though it gets 404 if files are accessed. If I open in incognito or new browser, everything is fine and the new listing is loaded.

@azgar-taj
Copy link

Thanks a lot, This is great! @paulmach

@dawidmachon
Copy link

dawidmachon commented Oct 26, 2024

Thanks!

Does anybody happen to know why browsers try to display the old directory listing, even though the server is now launched from a different directory?

It's the same on my firefox on Linux machine and chrome on my android. If I reopen the page it'll show the old listing, even though it gets 404 if files are accessed. If I open in incognito or new browser, everything is fine and the new listing is loaded.

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control

example for cors, need to adjust for your need (cache, implementation)

package main

import "net/http"

func addCORS(next http.Handler) http.Handler {
  return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
    w.Header().Set("Cross-Origin-Embedder-Policy", "require-corp")
    w.Header().Set("Cross-Origin-Opener-Policy", "same-origin")
    next.ServeHTTP(w, req)
  })
}

func main() {
  port := ":9999"
  handler := addCORS(http.FileServer(http.Dir("files")))
  http.ListenAndServe(port, handler)
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment