Difference between revisions of "Echo http server"

From UVOO Tech Wiki
Jump to navigation Jump to search
(Created page with "``` package main import ( "net/http" "os" "log" ) // DefaultPort is the default port to use if once is not specified by the SERVER_PORT environment variable cons...")
 
 
Line 3: Line 3:
  
 
import (
 
import (
    "net/http"
+
        "crypto/tls"
    "os"
+
        "fmt"
    "log"
+
        "log"
 +
        "net/http"
 +
        "os"
 +
        "os/exec"
 +
        "strconv"
 +
        // "bytes"
 
)
 
)
  
// DefaultPort is the default port to use if once is not specified by the SERVER_PORT environment variable
+
var httpPort = 8080
const DefaultPort = "7893";
+
var httpsPort = 8443
 +
var tlsFqdn = "foo"
  
func getServerPort() (string) {
+
func logRequest(handler http.Handler) http.Handler {
    port := os.Getenv("SERVER_PORT");
+
        return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    if port != "" {
+
                log.Printf("%s %s %s\n", r.RemoteAddr, r.Method, r.URL)
         return port;
+
                handler.ServeHTTP(w, r)
    }
+
         })
 +
}
  
    return DefaultPort;
+
func genTls() {
 +
 
 +
        if _, err := os.Stat("tls.key"); err != nil {
 +
                err = nil
 +
                var cmd_txt = fmt.Sprintf("fqdn=%s; openssl req -x509 -nodes -days 3650 -newkey rsa:4096 -keyout tls.key -out tls.crt -subj \"/CN=$fqdn\" -addext \"subjectAltName = DNS:$fqdn\"", tlsFqdn)
 +
                fmt.Printf("Create fqdn %s tls.crt tls.key files.\n\n", tlsFqdn)
 +
                cmd := exec.Command("bash", "-c", cmd_txt)
 +
                out, _ := cmd.CombinedOutput()
 +
 
 +
                if err != nil {
 +
                        fmt.Println(err.Error())
 +
                        return
 +
                }
 +
                fmt.Printf("%s\n", out)
 +
        }
 
}
 
}
  
// EchoHandler echos back the request as a response
 
 
func EchoHandler(writer http.ResponseWriter, request *http.Request) {
 
func EchoHandler(writer http.ResponseWriter, request *http.Request) {
 +
        log.Println("Echoing back request made to " + request.URL.Path + " to client (" + request.RemoteAddr + ")")
 +
        writer.Header().Set("Access-Control-Allow-Origin", "*")
 +
        writer.Header().Set("Access-Control-Allow-Headers", "Content-Range, Content-Disposition, Content-Type, ETag")
 +
        request.Write(writer)
 +
}
  
    log.Println("Echoing back request made to " + request.URL.Path + " to client (" + request.RemoteAddr + ")")
+
func serveHTTP(mux *http.ServeMux, errs chan<- error) {
 +
        log.Printf("starting http server on port %v.", httpPort)
 +
        errs <- http.ListenAndServe(":"+strconv.Itoa(httpPort), mux)
 +
}
  
    writer.Header().Set("Access-Control-Allow-Origin", "*")
+
func serveHTTPS(mux *http.ServeMux, errs chan<- error) {
 
+
        cfg := &tls.Config{
    // allow pre-flight headers
+
                MinVersion:              tls.VersionTLS12,
    writer.Header().Set("Access-Control-Allow-Headers", "Content-Range, Content-Disposition, Content-Type, ETag")
+
                CurvePreferences:        []tls.CurveID{tls.CurveP521, tls.CurveP384, tls.CurveP256},
 
+
                PreferServerCipherSuites: true,
    request.Write(writer)
+
                CipherSuites: []uint16{
 +
                        tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
 +
                        tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
 +
                        tls.TLS_RSA_WITH_AES_256_GCM_SHA384,
 +
                        tls.TLS_RSA_WITH_AES_256_CBC_SHA,
 +
                },
 +
        }
 +
        https := &http.Server{
 +
                Addr:        fmt.Sprintf(":%d", httpsPort),
 +
                TLSConfig:    cfg,
 +
                Handler:      mux,
 +
                TLSNextProto: make(map[string]func(*http.Server, *tls.Conn, http.Handler), 0),
 +
        }
 +
        log.Printf("starting https server on port %v.", httpsPort)
 +
        errs <- https.ListenAndServeTLS("tls.crt", "tls.key")
 
}
 
}
  
 
func main() {
 
func main() {
 
+
        genTls()
    log.Println("starting server, listening on port " + getServerPort())
+
        mux := http.NewServeMux()
 
+
        mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
    http.HandleFunc("/", EchoHandler)
+
                w.Header().Set("Access-Control-Allow-Origin", "*")
    http.ListenAndServe(":" + getServerPort(), nil)
+
                w.Header().Set("Access-Control-Allow-Headers",
 +
                        "Content-Range,Content-Disposition, Content-Type, ETag")
 +
                r.Write(w)
 +
                // r.URL.Path
 +
                log.Printf("%s %s %s %s %s %s\n",
 +
                        r.RemoteAddr,
 +
                        r.Host,
 +
                        r.Proto,
 +
                        r.Method,
 +
                        r.URL,
 +
                        r.Header.Get("X-FORWARDED-FOR"))
 +
        })
 +
        errs := make(chan error, 1)
 +
        go serveHTTP(mux, errs)
 +
        go serveHTTPS(mux, errs)
 +
        log.Fatal(<-errs) // block until an error
 
}
 
}
 
```
 
```

Latest revision as of 12:22, 16 February 2023

package main

import (
        "crypto/tls"
        "fmt"
        "log"
        "net/http"
        "os"
        "os/exec"
        "strconv"
        // "bytes"
)

var httpPort = 8080
var httpsPort = 8443
var tlsFqdn = "foo"

func logRequest(handler http.Handler) http.Handler {
        return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
                log.Printf("%s %s %s\n", r.RemoteAddr, r.Method, r.URL)
                handler.ServeHTTP(w, r)
        })
}

func genTls() {

        if _, err := os.Stat("tls.key"); err != nil {
                err = nil
                var cmd_txt = fmt.Sprintf("fqdn=%s; openssl req -x509 -nodes -days 3650 -newkey rsa:4096 -keyout tls.key -out tls.crt -subj \"/CN=$fqdn\" -addext \"subjectAltName = DNS:$fqdn\"", tlsFqdn)
                fmt.Printf("Create fqdn %s tls.crt tls.key files.\n\n", tlsFqdn)
                cmd := exec.Command("bash", "-c", cmd_txt)
                out, _ := cmd.CombinedOutput()

                if err != nil {
                        fmt.Println(err.Error())
                        return
                }
                fmt.Printf("%s\n", out)
        }
}

func EchoHandler(writer http.ResponseWriter, request *http.Request) {
        log.Println("Echoing back request made to " + request.URL.Path + " to client (" + request.RemoteAddr + ")")
        writer.Header().Set("Access-Control-Allow-Origin", "*")
        writer.Header().Set("Access-Control-Allow-Headers", "Content-Range, Content-Disposition, Content-Type, ETag")
        request.Write(writer)
}

func serveHTTP(mux *http.ServeMux, errs chan<- error) {
        log.Printf("starting http server on port %v.", httpPort)
        errs <- http.ListenAndServe(":"+strconv.Itoa(httpPort), mux)
}

func serveHTTPS(mux *http.ServeMux, errs chan<- error) {
        cfg := &tls.Config{
                MinVersion:               tls.VersionTLS12,
                CurvePreferences:         []tls.CurveID{tls.CurveP521, tls.CurveP384, tls.CurveP256},
                PreferServerCipherSuites: true,
                CipherSuites: []uint16{
                        tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
                        tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
                        tls.TLS_RSA_WITH_AES_256_GCM_SHA384,
                        tls.TLS_RSA_WITH_AES_256_CBC_SHA,
                },
        }
        https := &http.Server{
                Addr:         fmt.Sprintf(":%d", httpsPort),
                TLSConfig:    cfg,
                Handler:      mux,
                TLSNextProto: make(map[string]func(*http.Server, *tls.Conn, http.Handler), 0),
        }
        log.Printf("starting https server on port %v.", httpsPort)
        errs <- https.ListenAndServeTLS("tls.crt", "tls.key")
}

func main() {
        genTls()
        mux := http.NewServeMux()
        mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
                w.Header().Set("Access-Control-Allow-Origin", "*")
                w.Header().Set("Access-Control-Allow-Headers",
                        "Content-Range,Content-Disposition, Content-Type, ETag")
                r.Write(w)
                // r.URL.Path
                log.Printf("%s %s %s %s %s %s\n",
                        r.RemoteAddr,
                        r.Host,
                        r.Proto,
                        r.Method,
                        r.URL,
                        r.Header.Get("X-FORWARDED-FOR"))
        })
        errs := make(chan error, 1)
        go serveHTTP(mux, errs)
        go serveHTTPS(mux, errs)
        log.Fatal(<-errs) // block until an error
}