mirror of
https://github.com/kevin-DL/revel-cmd.git
synced 2026-01-17 13:04:51 +00:00
Merge branch 'mattbaird-feature/ssl-support-for-websockets' into develop
This commit is contained in:
@@ -13,7 +13,6 @@ package harness
|
|||||||
import (
|
import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/revel/revel"
|
|
||||||
"go/build"
|
"go/build"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
@@ -22,10 +21,11 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"path"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
|
||||||
|
"github.com/revel/revel"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -52,7 +52,7 @@ func renderError(w http.ResponseWriter, r *http.Request, err error) {
|
|||||||
|
|
||||||
// ServeHTTP handles all requests.
|
// ServeHTTP handles all requests.
|
||||||
// It checks for changes to app, rebuilds if necessary, and forwards the request.
|
// 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.
|
// Don't rebuild the app for favicon requests.
|
||||||
if lastRequestHadError > 0 && r.URL.Path == "/favicon.ico" {
|
if lastRequestHadError > 0 && r.URL.Path == "/favicon.ico" {
|
||||||
return
|
return
|
||||||
@@ -71,18 +71,19 @@ func (hp *Harness) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
// Reverse proxy the request.
|
// Reverse proxy the request.
|
||||||
// (Need special code for websockets, courtesy of bradfitz)
|
// (Need special code for websockets, courtesy of bradfitz)
|
||||||
if strings.EqualFold(r.Header.Get("Upgrade"), "websocket") {
|
if strings.EqualFold(r.Header.Get("Upgrade"), "websocket") {
|
||||||
proxyWebsocket(w, r, hp.serverHost)
|
proxyWebsocket(w, r, h.serverHost)
|
||||||
} else {
|
} 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 {
|
func NewHarness() *Harness {
|
||||||
// Get a template loader to render errors.
|
// Get a template loader to render errors.
|
||||||
// Prefer the app's views/errors directory, and fall back to the stock error pages.
|
// Prefer the app's views/errors directory, and fall back to the stock error pages.
|
||||||
revel.MainTemplateLoader = revel.NewTemplateLoader(
|
revel.MainTemplateLoader = revel.NewTemplateLoader(
|
||||||
[]string{path.Join(revel.RevelPath, "templates")})
|
[]string{filepath.Join(revel.RevelPath, "templates")})
|
||||||
revel.MainTemplateLoader.Refresh()
|
revel.MainTemplateLoader.Refresh()
|
||||||
|
|
||||||
addr := revel.HttpAddr
|
addr := revel.HttpAddr
|
||||||
@@ -101,12 +102,12 @@ func NewHarness() *Harness {
|
|||||||
port = getFreePort()
|
port = getFreePort()
|
||||||
}
|
}
|
||||||
|
|
||||||
serverUrl, _ := url.ParseRequestURI(fmt.Sprintf(scheme+"://%s:%d", addr, port))
|
serverURL, _ := url.ParseRequestURI(fmt.Sprintf(scheme+"://%s:%d", addr, port))
|
||||||
|
|
||||||
harness := &Harness{
|
harness := &Harness{
|
||||||
port: port,
|
port: port,
|
||||||
serverHost: serverUrl.String()[len(scheme+"://"):],
|
serverHost: serverURL.String()[len(scheme+"://"):],
|
||||||
proxy: httputil.NewSingleHostReverseProxy(serverUrl),
|
proxy: httputil.NewSingleHostReverseProxy(serverURL),
|
||||||
}
|
}
|
||||||
|
|
||||||
if revel.HttpSsl {
|
if revel.HttpSsl {
|
||||||
@@ -117,7 +118,7 @@ func NewHarness() *Harness {
|
|||||||
return 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) {
|
func (h *Harness) Refresh() (err *revel.Error) {
|
||||||
if h.app != nil {
|
if h.app != nil {
|
||||||
h.app.Kill()
|
h.app.Kill()
|
||||||
@@ -140,10 +141,14 @@ func (h *Harness) Refresh() (err *revel.Error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WatchDir method returns false to file matches with doNotWatch
|
||||||
|
// otheriwse true
|
||||||
func (h *Harness) WatchDir(info os.FileInfo) bool {
|
func (h *Harness) WatchDir(info os.FileInfo) bool {
|
||||||
return !revel.ContainsString(doNotWatch, info.Name())
|
return !revel.ContainsString(doNotWatch, info.Name())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WatchFile method returns true given filename HasSuffix of ".go"
|
||||||
|
// otheriwse false
|
||||||
func (h *Harness) WatchFile(filename string) bool {
|
func (h *Harness) WatchFile(filename string) bool {
|
||||||
return strings.HasSuffix(filename, ".go")
|
return strings.HasSuffix(filename, ".go")
|
||||||
}
|
}
|
||||||
@@ -204,7 +209,18 @@ func getFreePort() (port int) {
|
|||||||
// proxyWebsocket copies data between websocket client and server until one side
|
// proxyWebsocket copies data between websocket client and server until one side
|
||||||
// closes the connection. (ReverseProxy doesn't work with websocket requests.)
|
// closes the connection. (ReverseProxy doesn't work with websocket requests.)
|
||||||
func proxyWebsocket(w http.ResponseWriter, r *http.Request, host string) {
|
func proxyWebsocket(w http.ResponseWriter, r *http.Request, host string) {
|
||||||
d, err := net.Dial("tcp", host)
|
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
|
||||||
|
// 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 {
|
if err != nil {
|
||||||
http.Error(w, "Error contacting backend server.", 500)
|
http.Error(w, "Error contacting backend server.", 500)
|
||||||
revel.ERROR.Printf("Error dialing websocket backend %s: %v", host, err)
|
revel.ERROR.Printf("Error dialing websocket backend %s: %v", host, err)
|
||||||
|
|||||||
Reference in New Issue
Block a user