diff --git a/cmd/config.go b/cmd/config.go index 03ee9a1..84cd6f9 100644 --- a/cmd/config.go +++ b/cmd/config.go @@ -26,6 +26,12 @@ type Server struct { // PortHTTP is port where the HTTPS server must listen. // If 0, HTTPS is disabled. PortHTTPS int + + // TLSCertFile contains path to cert file for TLS Server. + TLSCertFile string + + // TLSCertFile contains path to key file for TLS Server. + TLSKeyFile string } // Conf contains the current configuration. @@ -35,7 +41,9 @@ var Conf = Config{ Interval: 300, }, Server{ - PortHTTP: 8083, - PortHTTPS: 0, + PortHTTP: 8083, + PortHTTPS: 8084, + TLSCertFile: "/wttr.in/etc/fullchain.pem", + TLSKeyFile: "/wttr.in/etc/privkey.pem", }, } diff --git a/cmd/log.go b/cmd/log.go index 7385206..3de1b1c 100644 --- a/cmd/log.go +++ b/cmd/log.go @@ -47,6 +47,9 @@ func (rl *RequestLogger) Log(r *http.Request) error { URI: r.RequestURI, UserAgent: r.Header.Get("User-Agent"), } + if r.TLS != nil { + le.Proto = "https" + } rl.m.Lock() rl.buf[le]++ diff --git a/cmd/processRequest.go b/cmd/processRequest.go index 84011c3..4b9aede 100644 --- a/cmd/processRequest.go +++ b/cmd/processRequest.go @@ -84,6 +84,10 @@ func get(req *http.Request) responseWithHeader { } } + if proxyReq.Header.Get("X-Forwarded-For") == "" { + proxyReq.Header.Set("X-Forwarded-For", ipFromAddr(req.RemoteAddr)) + } + res, err := client.Do(proxyReq) if err != nil { @@ -197,3 +201,12 @@ func readUserIP(r *http.Request) string { func randInt(min int, max int) int { return min + rand.Intn(max-min) } + +// ipFromAddr returns IP address from a ADDR:PORT pair. +func ipFromAddr(s string) string { + pos := strings.LastIndex(s, ":") + if pos == -1 { + return s + } + return s[:pos] +} diff --git a/cmd/srv.go b/cmd/srv.go index d0b2eed..f85d3f2 100644 --- a/cmd/srv.go +++ b/cmd/srv.go @@ -71,12 +71,33 @@ func copyHeader(dst, src http.Header) { } } -func main() { - logger := NewRequestLogger( - Conf.Logging.AccessLog, - time.Duration(Conf.Logging.Interval)*time.Second) +func serveHTTP(mux *http.ServeMux, port int, errs chan<- error) { + errs <- http.ListenAndServe(fmt.Sprintf(":%d", port), mux) +} - http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { +func serveHTTPS(mux *http.ServeMux, port int, errs chan<- error) { + errs <- http.ListenAndServeTLS(fmt.Sprintf(":%d", port), + Conf.Server.TLSCertFile, Conf.Server.TLSKeyFile, mux) +} + +func main() { + var ( + // mux is main HTTP/HTTP requests multiplexer. + mux *http.ServeMux = http.NewServeMux() + + // logger is optimized requests logger. + logger *RequestLogger = NewRequestLogger( + Conf.Logging.AccessLog, + time.Duration(Conf.Logging.Interval)*time.Second) + + // errs is the servers errors channel. + errs chan error = make(chan error, 1) + + // numberOfServers started. If 0, exit. + numberOfServers int + ) + + mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { if err := logger.Log(r); err != nil { log.Println(err) } @@ -89,5 +110,17 @@ func main() { w.Write(response.Body) }) - log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", Conf.Server.PortHTTP), nil)) + if Conf.Server.PortHTTP != 0 { + go serveHTTP(mux, Conf.Server.PortHTTP, errs) + numberOfServers++ + } + if Conf.Server.PortHTTPS != 0 { + go serveHTTPS(mux, Conf.Server.PortHTTPS, errs) + numberOfServers++ + } + if numberOfServers == 0 { + log.Println("no servers configured; exiting") + return + } + log.Fatal(<-errs) // block until one of the servers writes an error }