Skip to content

Commit

Permalink
Adding a redirector to https
Browse files Browse the repository at this point in the history
As a workaround for
istio/istio#1377
To be used in combo with ingress rules from
istio/fortio-deployment#32
  • Loading branch information
ldemailly committed Jan 12, 2018
1 parent 6adf860 commit 5df58cb
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 5 deletions.
3 changes: 2 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ COPY --from=build /go/src/istio.io/fortio/ui/templates /usr/local/lib/fortio/tem
COPY --from=build /go/src/istio.io/fortio.bin /usr/local/bin/fortio
EXPOSE 8079
EXPOSE 8080
EXPOSE 8081
VOLUME /var/lib/istio/fortio
ENTRYPOINT ["/usr/local/bin/fortio"]
# start the server mode (grpc ping on 8079, http echo and UI on 8080) by default
# start the server mode (grpc ping on 8079, http echo and UI on 8080, redirector on 8081) by default
CMD ["server"]
8 changes: 8 additions & 0 deletions fortio_main.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ var (

allowInitialErrorsFlag = flag.Bool("allow-initial-errors", false, "Allow and don't abort on initial warmup errors")
autoSaveFlag = flag.Bool("a", false, "Automatically save JSON result with filename based on labels and timestamp")
redirectFlag = flag.Int("redirect-port", 8081,
"Redirect all incoming traffic to https URL (need ingress to work properly). -1 means off.")
)

func main() {
Expand Down Expand Up @@ -133,8 +135,14 @@ func main() {
case "load":
fortioLoad()
case "report":
if *redirectFlag >= 0 {
go ui.RedirectToHTTPS(*redirectFlag)
}
ui.Report(*echoPortFlag, *staticDirFlag, *dataDirFlag)
case "server":
if *redirectFlag >= 0 {
go ui.RedirectToHTTPS(*redirectFlag)
}
go ui.Serve(*echoPortFlag, *echoDbgPathFlag, *uiPathFlag, *staticDirFlag, *dataDirFlag)
pingServer(*grpcPortFlag)
case "grpcping":
Expand Down
41 changes: 37 additions & 4 deletions ui/uihandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ import (
"istio.io/fortio/stats"
)

// TODO: move some of those in their own files/package (e.g data transfer TSV)
// and add unit tests.

var (
// UI and Debug prefix/paths (read in ui handler).
uiPath string // absolute (base)
Expand Down Expand Up @@ -386,7 +389,8 @@ func BrowseHandler(w http.ResponseWriter, r *http.Request) {

// LogRequest logs the incoming request, including headers when loglevel is verbose
func LogRequest(r *http.Request, msg string) {
log.Infof("%s: %v %v %v %v", msg, r.Method, r.URL, r.Proto, r.RemoteAddr)
log.Infof("%s: %v %v %v %v (%s)", msg, r.Method, r.URL, r.Proto, r.RemoteAddr,
r.Header.Get("X-Forwarded-Proto"))
if log.LogVerbose() {
for name, headers := range r.Header {
for _, h := range headers {
Expand Down Expand Up @@ -492,8 +496,13 @@ func LogAndFilterDataRequest(h http.Handler) http.Handler {
w.Header().Set("Access-Control-Allow-Origin", "*")
ext := "/index.tsv"
if strings.HasSuffix(path, ext) {
// TODO: what if we are reached through https ingress? or a different port
urlPrefix := "http://" + r.Host + path[:len(path)-len(ext)+1]
// Ingress effect:
// The Host header includes original host/port, only missing is the proto:
proto := r.Header.Get("X-Forwarded-Proto")
if len(proto) == 0 {
proto = "http"
}
urlPrefix := proto + "://" + r.Host + path[:len(path)-len(ext)+1]
log.LogVf("Prefix is '%s'", urlPrefix)
sendTSVDataIndex(urlPrefix, w)
return
Expand Down Expand Up @@ -616,6 +625,30 @@ func Report(port int, staticRsrcDir string, datadir string) {
fsd := http.FileServer(http.Dir(dataDir))
http.Handle(uiPath+"data/", LogAndFilterDataRequest(http.StripPrefix(uiPath+"data", fsd)))
if err := http.ListenAndServe(fmt.Sprintf(":%d", port), nil); err != nil {
log.Critf("Error starting server: %v", err)
log.Critf("Error starting report server: %v", err)
}
}

// -- Redirection to https feature --

// RedirectToHTTPSHandler handler sends a redirect to same URL with https.
func RedirectToHTTPSHandler(w http.ResponseWriter, r *http.Request) {
LogRequest(r, "Redirector to https")
http.Redirect(w, r, "https://"+r.Host+r.URL.String(), http.StatusSeeOther)
}

// RedirectToHTTPS Sets up a redirector to https on the given port.
// (Do not create a loop, make sure this is addressed from an ingress)
func RedirectToHTTPS(port int) {
m := http.NewServeMux()
m.HandleFunc("/", RedirectToHTTPSHandler)
s := &http.Server{
Addr: fmt.Sprintf(":%d", port),
Handler: m,
}
fmt.Printf("Https redirector running on %v\n", s.Addr)
if err := s.ListenAndServe(); err != nil {
log.Critf("Error starting report server: %v", err)
}
fmt.Printf("Not reached, https redirector exiting - was on %v\n", s.Addr)
}

0 comments on commit 5df58cb

Please sign in to comment.