From f122160a111500bce9e52c9337a9e208c049b7b0 Mon Sep 17 00:00:00 2001 From: Matthew Baird Date: Tue, 11 Aug 2015 14:45:02 -0700 Subject: [PATCH 1/2] fix issue where websockets don't work with SSL in dev mode. As the comment says, it's ok to skip the verify on the cert since this proxy is only used in dev mode. --- harness/harness.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/harness/harness.go b/harness/harness.go index df9f740..622c82d 100644 --- a/harness/harness.go +++ b/harness/harness.go @@ -204,7 +204,15 @@ func getFreePort() (port int) { // proxyWebsocket copies data between websocket client and server until one side // closes the connection. (ReverseProxy doesn't work with websocket requests.) func proxyWebsocket(w http.ResponseWriter, r *http.Request, host string) { - d, err := net.Dial("tcp", host) + var d net.Conn + var err error + if revel.HttpSsl { + // since this proxy isn't used in production, it's OK to set InsecureSkipVerify to true + // no need to add another configuration option. + d, err = tls.Dial("tcp", host, &tls.Config{InsecureSkipVerify: true}) + } else { + d, err = net.Dial("tcp", host) + } if err != nil { http.Error(w, "Error contacting backend server.", 500) revel.ERROR.Printf("Error dialing websocket backend %s: %v", host, err) From 6ebd22021e9edad5273436af0e2813631f7cf01b Mon Sep 17 00:00:00 2001 From: Jeevanandam M Date: Mon, 23 May 2016 22:54:44 -0700 Subject: [PATCH 2/2] #32 PR merge and code improvements --- harness/harness.go | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/harness/harness.go b/harness/harness.go index 622c82d..a6ae1cc 100644 --- a/harness/harness.go +++ b/harness/harness.go @@ -13,7 +13,6 @@ package harness import ( "crypto/tls" "fmt" - "github.com/revel/revel" "go/build" "io" "net" @@ -22,10 +21,11 @@ import ( "net/url" "os" "os/signal" - "path" "path/filepath" "strings" "sync/atomic" + + "github.com/revel/revel" ) var ( @@ -52,7 +52,7 @@ func renderError(w http.ResponseWriter, r *http.Request, err error) { // ServeHTTP handles all requests. // It checks for changes to app, rebuilds if necessary, and forwards the request. -func (hp *Harness) ServeHTTP(w http.ResponseWriter, r *http.Request) { +func (h *Harness) ServeHTTP(w http.ResponseWriter, r *http.Request) { // Don't rebuild the app for favicon requests. if lastRequestHadError > 0 && r.URL.Path == "/favicon.ico" { return @@ -71,18 +71,19 @@ func (hp *Harness) ServeHTTP(w http.ResponseWriter, r *http.Request) { // Reverse proxy the request. // (Need special code for websockets, courtesy of bradfitz) if strings.EqualFold(r.Header.Get("Upgrade"), "websocket") { - proxyWebsocket(w, r, hp.serverHost) + proxyWebsocket(w, r, h.serverHost) } else { - hp.proxy.ServeHTTP(w, r) + h.proxy.ServeHTTP(w, r) } } -// Return a reverse proxy that forwards requests to the given port. +// NewHarness method returns a reverse proxy that forwards requests +// to the given port. func NewHarness() *Harness { // Get a template loader to render errors. // Prefer the app's views/errors directory, and fall back to the stock error pages. revel.MainTemplateLoader = revel.NewTemplateLoader( - []string{path.Join(revel.RevelPath, "templates")}) + []string{filepath.Join(revel.RevelPath, "templates")}) revel.MainTemplateLoader.Refresh() addr := revel.HttpAddr @@ -101,12 +102,12 @@ func NewHarness() *Harness { port = getFreePort() } - serverUrl, _ := url.ParseRequestURI(fmt.Sprintf(scheme+"://%s:%d", addr, port)) + serverURL, _ := url.ParseRequestURI(fmt.Sprintf(scheme+"://%s:%d", addr, port)) harness := &Harness{ port: port, - serverHost: serverUrl.String()[len(scheme+"://"):], - proxy: httputil.NewSingleHostReverseProxy(serverUrl), + serverHost: serverURL.String()[len(scheme+"://"):], + proxy: httputil.NewSingleHostReverseProxy(serverURL), } if revel.HttpSsl { @@ -117,7 +118,7 @@ func NewHarness() *Harness { return harness } -// Rebuild the Revel application and run it on the given port. +// Refresh method rebuilds the Revel application and run it on the given port. func (h *Harness) Refresh() (err *revel.Error) { if h.app != nil { h.app.Kill() @@ -140,10 +141,14 @@ func (h *Harness) Refresh() (err *revel.Error) { return } +// WatchDir method returns false to file matches with doNotWatch +// otheriwse true func (h *Harness) WatchDir(info os.FileInfo) bool { return !revel.ContainsString(doNotWatch, info.Name()) } +// WatchFile method returns true given filename HasSuffix of ".go" +// otheriwse false func (h *Harness) WatchFile(filename string) bool { return strings.HasSuffix(filename, ".go") } @@ -204,10 +209,13 @@ func getFreePort() (port int) { // proxyWebsocket copies data between websocket client and server until one side // closes the connection. (ReverseProxy doesn't work with websocket requests.) func proxyWebsocket(w http.ResponseWriter, r *http.Request, host string) { - var d net.Conn - var err error + var ( + d net.Conn + err error + ) if revel.HttpSsl { - // since this proxy isn't used in production, it's OK to set InsecureSkipVerify to true + // since this proxy isn't used in production, + // it's OK to set InsecureSkipVerify to true // no need to add another configuration option. d, err = tls.Dial("tcp", host, &tls.Config{InsecureSkipVerify: true}) } else {