From 24f381761ef06081553b1be8c87241688cdca845 Mon Sep 17 00:00:00 2001
From: saurabh hirani <saurabh.hirani@gmail.com>
Date: Thu, 21 Mar 2019 23:30:40 +0800
Subject: [PATCH] adding support for -host, -https-cert-file, -https-key-file
 (#14)

---
 README.md              | 27 ++++++++++++++++++++++--
 cmd/go-httpbin/main.go | 48 ++++++++++++++++++++++++++++++++++++------
 2 files changed, 67 insertions(+), 8 deletions(-)

diff --git a/README.md b/README.md
index 8fcf1a3..a3a3aa2 100644
--- a/README.md
+++ b/README.md
@@ -16,18 +16,41 @@ variables:
 ```
 $ go-httpbin -help
 Usage of go-httpbin:
+  -host string
+      Host to listen on (default "0.0.0.0")
+  -port int
+        Port to listen on (default 8080)
+  -https-cert-file string
+         HTTPS certificate file
+  -https-key-file string
+         HTTPS private key file
   -max-body-size int
         Maximum size of request or response, in bytes (default 1048576)
   -max-duration duration
         Maximum duration a response may take (default 10s)
-  -port int
-        Port to listen on (default 8080)
+
+Examples:
+  # Run http server
+  $ go-httpbin -host 127.0.0.1 -port 8081
+
+  # Run https server
+
+  # Generate .crt and .key files
+  $ openssl genrsa -out server.key 2048
+  $ openssl ecparam -genkey -name secp384r1 -out server.key
+  $ openssl req -new -x509 -sha256 -key server.key -out server.crt -days 3650
+
+  $ go-httpbin -host 127.0.0.1 -port 8081 -https-cert-file ./server.crt -https-key-file ./server.key
 ```
 
 Docker images are published to [Docker Hub][docker-hub]:
 
 ```
+# Run http server
 $ docker run -P mccutchen/go-httpbin
+
+# Run https server
+$ docker run -e HTTPS_CERT_FILE='/tmp/server.crt' -e HTTPS_KEY_FILE='/tmp/server.key' -p 8080:8080 -v /tmp:/tmp mccutchen/go-httpbin
 ```
 
 The `github.com/mccutchen/go-httpbin/httpbin` package can also be used as a
diff --git a/cmd/go-httpbin/main.go b/cmd/go-httpbin/main.go
index fecdcaf..2b32654 100644
--- a/cmd/go-httpbin/main.go
+++ b/cmd/go-httpbin/main.go
@@ -1,6 +1,7 @@
 package main
 
 import (
+	"crypto/tls"
 	"flag"
 	"fmt"
 	"log"
@@ -13,16 +14,23 @@ import (
 	"github.com/mccutchen/go-httpbin/httpbin"
 )
 
+const defaultHost = "0.0.0.0"
 const defaultPort = 8080
 
 var (
-	port        int
-	maxBodySize int64
-	maxDuration time.Duration
+	host          string
+	port          int
+	maxBodySize   int64
+	maxDuration   time.Duration
+	httpsCertFile string
+	httpsKeyFile  string
 )
 
 func main() {
+	flag.StringVar(&host, "host", defaultHost, "Host to listen on")
 	flag.IntVar(&port, "port", defaultPort, "Port to listen on")
+	flag.StringVar(&httpsCertFile, "https-cert-file", "", "HTTPS Server certificate file")
+	flag.StringVar(&httpsKeyFile, "https-key-file", "", "HTTPS Server private key file")
 	flag.Int64Var(&maxBodySize, "max-body-size", httpbin.DefaultMaxBodySize, "Maximum size of request or response, in bytes")
 	flag.DurationVar(&maxDuration, "max-duration", httpbin.DefaultMaxDuration, "Maximum duration a response may take")
 	flag.Parse()
@@ -47,6 +55,9 @@ func main() {
 			os.Exit(1)
 		}
 	}
+	if host == defaultHost && os.Getenv("HOST") != "" {
+		host = os.Getenv("HOST")
+	}
 	if port == defaultPort && os.Getenv("PORT") != "" {
 		port, err = strconv.Atoi(os.Getenv("PORT"))
 		if err != nil {
@@ -56,6 +67,13 @@ func main() {
 		}
 	}
 
+	if httpsCertFile == "" && os.Getenv("HTTPS_CERT_FILE") != "" {
+		httpsCertFile = os.Getenv("HTTPS_CERT_FILE")
+	}
+	if httpsKeyFile == "" && os.Getenv("HTTPS_KEY_FILE") != "" {
+		httpsKeyFile = os.Getenv("HTTPS_KEY_FILE")
+	}
+
 	logger := log.New(os.Stderr, "", 0)
 
 	h := httpbin.New(
@@ -64,7 +82,25 @@ func main() {
 		httpbin.WithObserver(httpbin.StdLogObserver(logger)),
 	)
 
-	listenAddr := net.JoinHostPort("0.0.0.0", strconv.Itoa(port))
-	logger.Printf("go-httpbin listening on %s", listenAddr)
-	http.ListenAndServe(listenAddr, h.Handler())
+	listenAddr := net.JoinHostPort(host, strconv.Itoa(port))
+
+	server := &http.Server{
+		Addr:    listenAddr,
+		Handler: h.Handler(),
+	}
+
+	if httpsCertFile != "" && httpsKeyFile != "" {
+		cert, err := tls.LoadX509KeyPair(httpsCertFile, httpsKeyFile)
+		if err != nil {
+			log.Fatal("Failed to generate https key pair: ", err)
+		}
+		server.TLSConfig = &tls.Config{
+			Certificates: []tls.Certificate{cert},
+		}
+		logger.Printf("go-httpbin listening on https://%s", listenAddr)
+		server.ListenAndServeTLS("", "")
+	} else {
+		logger.Printf("go-httpbin listening on http://%s", listenAddr)
+		server.ListenAndServe()
+	}
 }
-- 
GitLab