Go to build a static page server note

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

Go is a simple and powerful language, and after a brief experience it feels great to support the network and the command line, this article describes the general process of go implementing a static server.

Basic implementation

Recently took over the translation work of Gobyexample, which requires a local test environment after the project is reconstructed.
Because you want the URL of the page to appear as " https://gobyexample.xgwang.me/hello-world " this end without the "/" form, the child page does not have HTML, and a picture resource therefore requires a static server.

According to the Golang Wiki, implementing this simple server requires only ... One line of code:

package mainimport "net/http"func main() {    panic(http.ListenAndServe(":8080", http.FileServer(http.Dir("/usr/share/doc"))))}

After adding the log, rewrite it and put it in the tools directory of our project:

package mainimport (    "log"    "net/http")func main() {    // Simple static webserver:    port := ":8080"    log.Printf("Serving at: http://localhost%s\n", port)    err := http.ListenAndServe(port, http.FileServer(http.Dir("public")))    if err != nil {        log.Fatal("ListenAndServe fail:", err)    }}

One more executable file. tools/serve

#!/bin/bashexec go run tools/serve.go

OK now you just need to tools/serve start this server.

404

Everything looks normal, but if we visit a page that does not exist, 404.html will not be serve, because go provides FileServer 404 pages that we do not know we have customized.
So we need to http.FileServer change to a custom one Handler .

The best thing to do when writing go is that the Go official team offers very opinionated convention, such as GO-GET,GO-FMT.
In our input http.FileServer will automatically add the imports corresponding library, jump to the source code to see the implementation of this function:

type fileHandler struct {    root FileSystem}// FileServer returns a handler that serves HTTP requests// with the contents of the file system rooted at root.//// To use the operating system's file system implementation,// use http.Dir:////     http.Handle("/", http.FileServer(http.Dir("/tmp")))//// As a special case, the returned file server redirects any request// ending in "/index.html" to the same path, without the final// "index.html".func FileServer(root FileSystem) Handler {    return &fileHandler{root}}func (f *fileHandler) ServeHTTP(w ResponseWriter, r *Request) {    upath := r.URL.Path    if !strings.HasPrefix(upath, "/") {        upath = "/" + upath        r.URL.Path = upath    }    serveFile(w, r, f.root, path.Clean(upath), true)}

So we know that the function here needs to return the handler there is a ServeHTTP method. But here's serveFile not a direct http.serveFile call: go specifies that a package starts with a lowercase letter that is private and cannot be accessed by an external package.

But it doesn't matter, we can fileHandler wrap a layer of agent on it, execute all the original contents after we have executed the logic that we judge the existence of the file fileHandler.ServeHTTP , the modified code is as follows:

type fileHandler struct {    root http.FileSystem    h    http.Handler}func fileServer(root http.FileSystem, h http.Handler) http.Handler {    return &fileHandler{root, h}}func (f *fileHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {    path := r.URL.Path    if _, err := os.Stat("public/" + path); os.IsNotExist(err) {        http.ServeFile(w, r, "public/404.html")        return    }    f.h.ServeHTTP(w, r)}func main() {    // Simple static webserver:    port := ":8080"    log.Printf("Serving at: http://localhost%s\n", port)    fs := http.Dir("public")    http.Handle("/", fileServer(&fs, http.FileServer(&fs)))    err := http.ListenAndServe(port, nil)    if err != nil {        log.Fatal("ListenAndServe fail:", err)    }}

FileSystemincoming pointers are also avoided when they are passed in, and have a sense of c.

Small details

Basic functionality has been implemented, but as a command-line tool, I hope to make some improvements.

First we need to support the parameter, go to command line parameters support is very good, as long as the introduction of BUILTIN flag packet, we join

port := flag.String("port", ":8080", "localhost port to serve")path := flag.String("path", "public", "public files path")flag.Parse()

You can get *string the command line arguments of the type, and naturally support the default values and descriptions, and test it to go run tools/serve.go -h get:

Usage of /var/folders/sd/cwk5fwtd4ms5vflhq5_0_5rr0000gn/T/go-build178666598/command-line-arguments/_obj/exe/serve:  -path string        public files path (default "public")  -port string        localhost port to serve (default ":8080")

Before you prepare the serve file, output the formatted information with a bold look at the parameters we passed in:

log.Printf("Serving \x1b[1m%s\x1b[0m at: http://localhost\x1b[1m%s\x1b[0m\n", *path, *port)

This \x1b[0m represents "all attributes off", which stands for " \x1b[1m Bold on (enable foreground intensity)".

Summarize

As a static language, go has the flexibility to rival dynamic languages, has a complete and easy-to-use toolchain and a rich standard library, and is the fastest growing language in the 2017, simple and powerful.
Hope that more people can learn go together, I am perfecting go by example translation, welcome to read and contribute pr!

Read the original

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.