diff --git a/_examples/shttp/proxy/main.go b/_examples/shttp/proxy/main.go
index 3de63adc8..6bbc68b5e 100644
--- a/_examples/shttp/proxy/main.go
+++ b/_examples/shttp/proxy/main.go
@@ -25,7 +25,7 @@ func main() {
// parseUDPAddr validates if the address is a SCION address
// which we can use to proxy to SCION
if _, err := snet.ParseUDPAddr(*remote); err == nil {
- proxyHandler, err := shttp.NewSingleSCIONHostReverseProxy(*remote, &tls.Config{InsecureSkipVerify: true})
+ proxyHandler, err := shttp.NewSingleSCIONHostReverseProxy(*remote, &tls.Config{InsecureSkipVerify: true, NextProtos: []string{"H3-22"}})
if err != nil {
log.Fatalf("Failed to create SCION reverse proxy %s", err)
}
@@ -50,5 +50,4 @@ func main() {
log.Printf("Listen on HTTP %s\n", *local)
log.Fatalf("%s", http.ListenAndServe(*local, mux))
}
-
}
diff --git a/go.sum b/go.sum
index 0844c4bf1..59e272952 100644
--- a/go.sum
+++ b/go.sum
@@ -384,4 +384,4 @@ rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck=
sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0=
zombiezen.com/go/capnproto2 v0.0.0-20190813022230-ddfb9bb855fa h1:oaUsHxHA/DGY+XtWA4i5FLMxwWheqW21Az6xSLS1OzY=
-zombiezen.com/go/capnproto2 v0.0.0-20190813022230-ddfb9bb855fa/go.mod h1:lwDtzVwsLXcHGddc2q1vAWPfocWiFh07Mmeqo/Oatko=
+zombiezen.com/go/capnproto2 v0.0.0-20190813022230-ddfb9bb855fa/go.mod h1:lwDtzVwsLXcHGddc2q1vAWPfocWiFh07Mmeqo/Oatko=
\ No newline at end of file
diff --git a/webapp/web/static/css/style.css b/webapp/web/static/css/style.css
index 972abee1e..d8f086727 100644
--- a/webapp/web/static/css/style.css
+++ b/webapp/web/static/css/style.css
@@ -220,3 +220,37 @@ img {
[tooltip]:hover:before, [tooltip]:hover:after {
display: block;
}
+
+.card {
+ /* Add shadows to create the "card" effect */
+ box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
+ transition: 0.3s;
+ max-width: 300px;
+ text-align: center;
+ }
+
+ /* On mouse-over, add a deeper shadow */
+ .card:hover {
+ box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2);
+ }
+
+ /* Add some padding inside the card container */
+ .text-container {
+ padding: 2px 16px;
+ }
+
+.cards {
+ display: flex;
+}
+
+.link {
+ cursor: pointer;
+}
+
+.link:hover {
+ transform: scale(1.1);
+}
+
+#tabs {
+ padding: 1em;
+}
\ No newline at end of file
diff --git a/webapp/web/template/header.html b/webapp/web/template/header.html
index c28c6f409..33ec9b541 100644
--- a/webapp/web/template/header.html
+++ b/webapp/web/template/header.html
@@ -53,6 +53,7 @@
Trust
Files
About
+ SCION HTTP
diff --git a/webapp/web/template/webview.html b/webapp/web/template/webview.html
new file mode 100644
index 000000000..6a2a9ca19
--- /dev/null
+++ b/webapp/web/template/webview.html
@@ -0,0 +1,105 @@
+{{define "webview"}} {{template "header" .}}
+
+
+
+
SCION HTTP
+This page provides some default SCION HTTP endpoints and a searchbar for SCION HTTP URLs, to provide easy access to those resources.
+
+
+
+
+
+
+
+
+
+
Trending:
+
+
+

+
+
DVB-T2 Live Stream
+
Open Stream
+
+
+
+
+
+
+{{template "footer" .}} {{end}}
\ No newline at end of file
diff --git a/webapp/webapp.go b/webapp/webapp.go
index 58c54ffbd..91d43be05 100644
--- a/webapp/webapp.go
+++ b/webapp/webapp.go
@@ -18,12 +18,15 @@ package main
import (
"bufio"
+ "crypto/tls"
"encoding/json"
"errors"
"fmt"
"html/template"
"io"
"net/http"
+ "net/http/httputil"
+ "net/url"
"os"
"os/exec"
"path"
@@ -38,6 +41,9 @@ import (
lib "github.com/netsec-ethz/scion-apps/webapp/lib"
model "github.com/netsec-ethz/scion-apps/webapp/models"
. "github.com/netsec-ethz/scion-apps/webapp/util"
+
+ "github.com/netsec-ethz/scion-apps/pkg/shttp"
+ "github.com/scionproto/scion/go/lib/snet"
)
var settings lib.UserSetting
@@ -82,6 +88,53 @@ type Page struct {
var options lib.CmdOptions
+var proxy *httputil.ReverseProxy
+
+// Can be overwritte by api calls
+type ProxyConfig struct {
+ Remote string `json:"remote"`
+}
+
+//TODO: Thread safe/Routine safe
+func setProxyConfig(wr http.ResponseWriter, r *http.Request) {
+ var newConfig ProxyConfig
+
+ // Try to decode the request body into the struct. If there is an error,
+ // respond to the client with the error message and a 400 status code.
+ err := json.NewDecoder(r.Body).Decode(&newConfig)
+ if err != nil {
+ http.Error(wr, err.Error(), http.StatusBadRequest)
+ return
+ }
+
+ setRemote(&newConfig.Remote)
+}
+
+func proxyWrapper(rw http.ResponseWriter, req *http.Request) {
+ req.URL.Path = strings.Replace(req.URL.Path, "__proxy/", "", 1)
+ proxy.ServeHTTP(rw, req)
+}
+
+func setRemote(remote *string) {
+ // parseUDPAddr validates if the address is a SCION address
+ // which we can use to proxy to SCION
+ if _, err := snet.ParseUDPAddr(*remote); err == nil {
+ proxy, err = shttp.NewSingleSCIONHostReverseProxy(*remote, &tls.Config{InsecureSkipVerify: true, NextProtos: []string{"H3-22"}})
+ if err != nil {
+ log.Crit("Failed to create SCION reverse proxy %s", err)
+ }
+
+ fmt.Printf("Proxy to SCION remote %s\n", *remote)
+ } else {
+ u, err := url.Parse(*remote)
+ if err != nil {
+ log.Crit(fmt.Sprintf("Failed parse remote %s, %s", *remote, err))
+ }
+ fmt.Printf("Proxy to HTTP remote %s\n", *remote)
+ proxy = httputil.NewSingleHostReverseProxy(u)
+ }
+}
+
func ensurePath(srcpath, staticDir string) string {
dir := path.Join(srcpath, staticDir)
if _, err := os.Stat(dir); os.IsNotExist(err) {
@@ -188,6 +241,7 @@ func initServeHandlers() {
http.HandleFunc("/", mainHandler)
http.HandleFunc("/about", aboutHandler)
http.HandleFunc("/apps", appsHandler)
+ http.HandleFunc("/webview", webviewHandler)
http.HandleFunc("/astopo", astopoHandler)
http.HandleFunc("/trc", trcHandler)
fsStatic := http.FileServer(http.Dir(path.Join(options.StaticRoot, "static")))
@@ -217,6 +271,9 @@ func initServeHandlers() {
http.HandleFunc("/getpathtopo", getPathInfoHandler)
http.HandleFunc("/getastopo", getAsTopoHandler)
http.HandleFunc("/gettrc", getTrcInfoHandler)
+
+ http.HandleFunc("/__proxy/setconfig", setProxyConfig)
+ http.HandleFunc("/__proxy/", proxyWrapper)
}
func logRequestHandler(handler http.Handler) http.Handler {
@@ -237,6 +294,7 @@ func prepareTemplates(srcpath string) *template.Template {
path.Join(srcpath, "template/about.html"),
path.Join(srcpath, "template/astopo.html"),
path.Join(srcpath, "template/trc.html"),
+ path.Join(srcpath, "template/webview.html"),
))
}
@@ -275,6 +333,10 @@ func appsHandler(w http.ResponseWriter, r *http.Request) {
display(w, "apps", &Page{Title: "SCIONLab Apps", MyIA: settings.MyIA})
}
+func webviewHandler(w http.ResponseWriter, r *http.Request) {
+ display(w, "webview", &Page{Title: "SCION HTTP", MyIA: settings.MyIA})
+}
+
func astopoHandler(w http.ResponseWriter, r *http.Request) {
display(w, "astopo", &Page{Title: "SCIONLab AS Topology", MyIA: settings.MyIA})
}