@@ -3,16 +3,26 @@ package main
33import (
44 "flag"
55 "fmt"
6- "io/ioutil "
6+ "github.com/gookit/color "
77 "log"
88 "net/http"
9+ "net/http/httptest"
10+ "net/http/httputil"
11+ "net/url"
12+ "time"
913)
1014
1115func main () {
1216 addr := flag .String ("addr" , ":19091" , "HTTP network address" )
17+ up := flag .String ("up" , "" , "upstream address for proxy address, if not set, there is no upstream and the sink returns always with 200" )
18+ sleep := flag .Duration ("sleep" , 0 , "sleeptime for non proxy function" )
1319 flag .Parse ()
1420
15- http .HandleFunc ("/" , rootHandler )
21+ if * up == "" {
22+ http .HandleFunc ("/" , rootHandler (* sleep ))
23+ } else {
24+ http .HandleFunc ("/" , proxyHandler (* up ))
25+ }
1626
1727 log .Printf ("Starting server on %s\n " , * addr )
1828
@@ -22,18 +32,59 @@ func main() {
2232 }
2333}
2434
25- func rootHandler (w http.ResponseWriter , _ * http.Request ) {
26- _ , _ = fmt .Fprintf (w , "<h1>Hello World</h1><div>Welcome to whereever you are</div>" )
35+ func rootHandler (sleep time.Duration ) http.HandlerFunc {
36+ return func (w http.ResponseWriter , req * http.Request ) {
37+ time .Sleep (sleep )
38+ _ , _ = fmt .Fprintf (w , "<h1>Hello World</h1><div>Welcome to whereever you are</div>" )
39+ }
40+ }
41+
42+ func proxyHandler (target string ) http.HandlerFunc {
43+ return func (w http.ResponseWriter , req * http.Request ) {
44+ // parse the url
45+ url , _ := url .Parse (target )
46+
47+ // create the reverse proxy
48+ proxy := httputil .NewSingleHostReverseProxy (url )
49+
50+ // Update the headers to allow for SSL redirection
51+ req .URL .Host = url .Host
52+ req .URL .Scheme = url .Scheme
53+ req .Header .Set ("X-Forwarded-Host" , req .Header .Get ("Host" ))
54+ req .Host = url .Host
55+
56+ // Note that ServeHttp is non blocking and uses a go routine under the hood
57+ proxy .ServeHTTP (w , req )
58+ }
2759}
2860
2961func logRequest (handler http.Handler ) http.Handler {
3062 return http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
31- log .Printf ("%s %s %s %v\n " , r .RemoteAddr , r .Method , r .URL , r .Header )
32- defer func () {
33- _ = r .Body .Close ()
34- }()
35- body , err := ioutil .ReadAll (r .Body )
36- log .Printf ("%s %s\n " , err , string (body ))
37- handler .ServeHTTP (w , r )
63+ x , err := httputil .DumpRequest (r , true )
64+ //defer func() {
65+ // _ = r.Body.Close()
66+ //}()
67+ //body, err := ioutil.ReadAll(r.Body)
68+ if err != nil {
69+ http .Error (w , fmt .Sprint (err ), http .StatusInternalServerError )
70+ return
71+ }
72+ //log.Printf("%s %s\n", err, string(body))
73+ rec := httptest .NewRecorder ()
74+ handler .ServeHTTP (rec , r )
75+ message := fmt .Sprintf ("Request:\n %s\n Response Code: %d\n Response:\n %s\n \n " , string (x ), rec .Code , rec .Body .String ())
76+ if rec .Code >= 500 {
77+ color .Error .Block (message )
78+ } else if rec .Code >= 404 {
79+ color .Warn .Block (message )
80+ } else if rec .Code >= 200 {
81+ color .Info .Block (message )
82+ }
83+ // this copies the recorded response to the response writer
84+ for k , v := range rec .Header () {
85+ w .Header ()[k ] = v
86+ }
87+ w .WriteHeader (rec .Code )
88+ rec .Body .WriteTo (w )
3889 })
3990}
0 commit comments