A Simple Web Server In Go

How do you build a really simple web server in Go? With all hard coded values:

// Simple HTTP server

package main

import (
	"log"
	"net/http"
)

func main() {
	port := "8765"
	dir := "./www"
	log.Fatal(http.ListenAndServe(":"+port, http.FileServer(http.Dir(dir))))
}



You have to change the source code and recompile to change the server. As it is coded it will serve content on port 8765. The files are in the ./www directory.

To Run it

    $ go run server.go

Or to compile a binary of it

    $ go build server.go

Now let's take the simple server and add a little bit to it. First the processing of some command line arguments. This will allow us to run it with a different port and a different directory for the files. -p or –port for the port. -d or –dir for the directory.

Go provides access to the command line arguments. However it is just a set of strings. Let's use a parser for the arguments. The one that I like is called "flags". We will need to fetch it so that Go can link it into our executable.

    $ go get github.com/jessevdk/go-flags

Now we need to tell our program that we are using a few more libraries. Change the "import" to

import (
    "github.com/jessevdk/go-flags"
    "log"
    "os"
    "net/http"
)

The first line tells it about the flags library that we are going to use.

The entire program is:

// Simple HTTP server with ability to set PORT and the directory files are served from

package main

//
// Commaind Line Params
//
//	--port=8765
//	--dir=.
//
// go get github.com/jessevdk/go-flags
//

import (
	"log"
	"net/http"
	"os"

	"github.com/jessevdk/go-flags"
)

func main() {

	var opts struct {
		Port string `short:"p" long:"port" description:"A port number to listen on" default:"8765"`
		Dir  string `short:"d" long:"dir" description:"Directory to serve over HTTP" default:"."`
	}

	_, err := flags.ParseArgs(&opts, os.Args)

	if err != nil {
		panic(err)
		os.Exit(1)
	}

	port := opts.Port
	dir := opts.Dir

	log.Fatal(http.ListenAndServe(":"+port, http.FileServer(http.Dir(dir))))
}


We need to tell the parser what the arguments are

    var opts struct {
        Port string `short:"p" long:"port" description:"A port number to listen on" default:"8765"`
        Dir  string `short:"d" long:"dir" description:"Directory to serve over HTTP" default:"."`
    }

Then to tell it to actually parse the arguments. The "_" is important. It tells the language that we are not using the first return value from flags.ParseArgs(). The first argument is all the command line arguments that were left after parsing the '-' arguments.

    _, err := flags.ParseArgs(&opts, os.Args)

Then a little bit of error checking. Note the "os.Exit(1)" if an error occurs.

    if err != nil {
            panic(err)
            os.Exit(1)
    }

And finally we will actually use the arguments. The := declares the variables "port" and "dir" for us.

    port := opts.Port
    dir  := opts.Dir

Simple enough.

    $ go build server2.go
    $ ./server2 --dir=./myFiles --port:8080 &

Go Have Fun!

Code tested on: Ubuntu 12.04, Mac 10.8, Windows 7 in go 1.1.2


•       •       •       •       •       •

Summary: # of Words: 439
Author: Philip J. Schlump
Published On: 2013-10-19

Download code from this articles in .tar.gz for Mac/Linux/Unix or .zip with CR/LF for Windows format.

 

Before You Go....

Have you read "Unintend Consinsequences"?

"I laughed so hard it hurt..."
    Rod Brown

"Incredibly funny! Incredibly true!"
    Tad Stevens