Documentation ¶
Overview ¶
easyhttpserver runs production-ready, Let's Encrypt-enabled HTTP server in a few lines of code.
Features HTTP, optional HTTPS with Let's Encrypt, graceful shutdown, Heroku-style 12-factor configuration, and development mode.
Example ¶
package main import ( "fmt" "net/http" "os" "strings" "time" "github.com/andreyvit/easyhttpserver" ) func main() { // normally you'd set up the environment externally, and create the dir manually os.Setenv("LETSENCRYPT_ENABLED", "1") os.Setenv("LETSENCRYPT_EMAIL", "you@example.com") // set your email here os.Setenv("LETSENCRYPT_CACHE_DIR", "~/.local/share/easyhttpserver_example/") // set your dir (mod 0700) here os.Setenv("HOST", "myhost.example.com") // set HTTPS hostname to respond to must(os.MkdirAll(os.Getenv("LETSENCRYPT_CACHE_DIR"), 0700)) serverOpt := easyhttpserver.Options{ DefaultDevPort: 3099, GracefulShutdownTimeout: 2 * time.Second, // no long-lived requests } must(serverOpt.LoadEnv()) // loads HOST, LETSENCRYPT_ENABLED, etc from environment srv, err := easyhttpserver.Start(http.HandlerFunc(helloWorld), serverOpt) must(err) easyhttpserver.InterceptShutdownSignals(srv.Shutdown) // shut down on Ctrl-C, SIGKILL, SIGHUP after500ms(srv.Shutdown) // end test after 500 ms, real servers don't do this fmt.Printf("HelloWorld server running at %s\n", strings.Join(srv.Endpoints(), ", ")) must(srv.Wait()) } func helloWorld(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello World!") } func after500ms(f func()) { go func() { time.Sleep(500 * time.Millisecond) f() }() } func must(err error) { if err != nil { panic(err) } }
Output: HelloWorld server running at https://myhost.example.com
Example (DefaultDevServer) ¶
package main import ( "fmt" "net/http" "strings" "time" "github.com/andreyvit/easyhttpserver" ) func main() { srv, err := easyhttpserver.Start(http.HandlerFunc(helloWorld), easyhttpserver.Options{ DefaultDevPort: 3099, GracefulShutdownTimeout: 2 * time.Second, // no long-lived requests }) must(err) easyhttpserver.InterceptShutdownSignals(srv.Shutdown) // shut down on Ctrl-C, SIGKILL, SIGHUP after500ms(srv.Shutdown) // end test after 500 ms, real servers don't do this fmt.Printf("HelloWorld server running at %s\n", strings.Join(srv.Endpoints(), ", ")) must(srv.Wait()) } func helloWorld(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello World!") } func after500ms(f func()) { go func() { time.Sleep(500 * time.Millisecond) f() }() } func must(err error) { if err != nil { panic(err) } }
Output: HelloWorld server running at http://localhost:3099
Example (ManualConfig) ¶
package main import ( "fmt" "net/http" "strings" "time" "github.com/andreyvit/easyhttpserver" ) func main() { srv, err := easyhttpserver.Start(http.HandlerFunc(helloWorld), easyhttpserver.Options{ DefaultDevPort: 3099, GracefulShutdownTimeout: 2 * time.Second, // no long-lived requests Host: "myhost.example.com", LetsEncrypt: true, LetsEncryptEmail: "you@example.com", LetsEncryptCacheDir: "~/.local/share/easyhttpserver_example/", }) must(err) easyhttpserver.InterceptShutdownSignals(srv.Shutdown) // shut down on Ctrl-C, SIGKILL, SIGHUP after500ms(srv.Shutdown) // end test after 500 ms, real servers don't do this fmt.Printf("HelloWorld server running at %s\n", strings.Join(srv.Endpoints(), ", ")) must(srv.Wait()) } func helloWorld(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello World!") } func after500ms(f func()) { go func() { time.Sleep(500 * time.Millisecond) f() }() } func must(err error) { if err != nil { panic(err) } }
Output: HelloWorld server running at https://myhost.example.com
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func InterceptShutdownSignals ¶
func InterceptShutdownSignals(shutdown func())
InterceptShutdownSignals invokes the given function the first time INT (Ctrl-C), KILL or HUP signal is received. This only happens once; the next signal received will kill the app.
Types ¶
type Options ¶
type Options struct { // Log is a log.Printf-style function to output logs Log func(format string, v ...interface{}) // DefaultDevPort is the HTTP port to use when running on localhost. DefaultDevPort int // GracefulShutdownTimeout is the time to allow existing requests to complete // when trying to shut down gracefully. After this delay, all existing // connections are killed. GracefulShutdownTimeout time.Duration // Port sets the HTTP port to use. Let's Encrypt mode requires port 80. Port int // Host sets the domain name to provide HTTPS certificates for. Host string // LetsEncrypt is the master toggle that enables Let's Encrypt. LetsEncrypt bool // LetsEncryptCacheDir is the directory to store Let's Encrypt certificates // and keys in. This directory should be secured as much as possible. LetsEncryptCacheDir string // LetsEncryptEmail is the email address to use for Let's Encrypt certificates. // Let's Encrypt might send important notifications to this email. LetsEncryptEmail string // IsLocalDevelopmentHost signals that Host is a localhost address. In this // mode, Port defaults to DefaultDevPort, and scheme is http. Incompatible // with LetsEncrypt mode. IsLocalDevelopmentHost bool // PrimaryScheme is either https or http, depending on whether Let's Encrypt // is enabled. PrimaryScheme string }
Options provide the necessary settings for starting a server and talking to Let's Encrypt.
func (Options) BaseURL ¶
Returns the preferred scheme and host to contact this server. This can be used for links in emails, etc.
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server represents both the HTTP and the HTTPS servers started via this package.
func Start ¶
Start creates a server and starts listening. It makes sure that everything is set up properly, and returns after both HTTP and HTTPS (if configured) servers start accepting connections.
After this call returns, you are supposed to log a message saying the server is running. Call Wait() to block until the server shuts down.
func (*Server) BaseURL ¶
BaseURL returns the preferred scheme and host of the server. Depending on the current settings, it might be something like https://your.externalhost.com/ or something more like http://localhost:3001/.
func (*Server) Endpoints ¶
Endpoints returns the list of URLs the server can be reached at, meant to be used for internal messaging and logging. The first item is BaseURL() and is the preferred endpoint; extra endpoints provide the alternatives.
Note that these values are for ease of debugging, and aren't necessarily valid URLs. E.g. some will lack a scheme.