Skip to content

Commit

Permalink
Add 'host' flag for URL display (#26)
Browse files Browse the repository at this point in the history
* add host flag, which allows one to specify the host that provided as the source in API output, and use this for UI rendering

* move to forked go-bindata

Co-authored-by: Adam Allred <[email protected]>
  • Loading branch information
adamallred and Adam Allred authored May 1, 2020
1 parent 2fc3359 commit 043936a
Show file tree
Hide file tree
Showing 10 changed files with 133 additions and 62 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ DST = $(patsubst %.scss,%.css,$(patsubst %.ts,%.js,$(subst web/assets,.build/ass
ALL: web/bindata.go

.build/bin/go-bindata:
GOPATH=$(shell pwd)/.build go get github.com/jteeuwen/go-bindata/...
GOPATH=$(shell pwd)/.build go get github.com/a-urth/go-bindata/...

.build/assets:
mkdir -p $@

.build/assets/%.css: web/assets/%.scss
sass --no-cache --sourcemap=none --style=compressed $< $@
sass --no-source-map --style=compressed $< $@

.build/assets/%.js: web/assets/%.ts
$(eval TMP := $(shell mktemp))
Expand Down
2 changes: 1 addition & 1 deletion cmd/go/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ func main() {
pflag.String("backend", "leveldb", "backing store to use. 'leveldb' and 'firestore' currently supported.")
pflag.String("data", "data", "The location of the leveldb data directory")
pflag.String("project", "", "The GCP project to use for the firestore backend. Will attempt to use application default creds if not defined.")

pflag.String("host", "", "The host field to use when gnerating the source URL of a link. Defaults to the Host header of the generate request")
pflag.Parse()

if err := viper.BindPFlags(pflag.CommandLine); err != nil {
Expand Down
36 changes: 21 additions & 15 deletions web/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ func validateURL(r *http.Request, s string) error {
return nil
}

func apiURLPost(backend backend.Backend, w http.ResponseWriter, r *http.Request) {
func apiURLPost(backend backend.Backend, host string, w http.ResponseWriter, r *http.Request) {
p := parseName("/api/url/", r.URL.Path)

var req struct {
Expand Down Expand Up @@ -125,10 +125,10 @@ func apiURLPost(backend backend.Backend, w http.ResponseWriter, r *http.Request)
return
}

writeJSONRoute(w, p, &rt)
writeJSONRoute(w, p, &rt, host)
}

func apiURLGet(backend backend.Backend, w http.ResponseWriter, r *http.Request) {
func apiURLGet(backend backend.Backend, host string, w http.ResponseWriter, r *http.Request) {
p := parseName("/api/url/", r.URL.Path)

if p == "" {
Expand All @@ -148,7 +148,7 @@ func apiURLGet(backend backend.Backend, w http.ResponseWriter, r *http.Request)
return
}

writeJSONRoute(w, p, rt)
writeJSONRoute(w, p, rt, host)
}

func apiURLDelete(backend backend.Backend, w http.ResponseWriter, r *http.Request) {
Expand Down Expand Up @@ -208,7 +208,7 @@ func parseBool(v string, def bool) (bool, error) {
return false, errors.New("invalid boolean value")
}

func apiURLsGet(backend backend.Backend, w http.ResponseWriter, r *http.Request) {
func apiURLsGet(backend backend.Backend, host string, w http.ResponseWriter, r *http.Request) {
c, err := parseCursor(r.FormValue("cursor"))
if err != nil {
writeJSONError(w, "invalid cursor value", http.StatusBadRequest)
Expand Down Expand Up @@ -250,10 +250,16 @@ func apiURLsGet(backend backend.Backend, w http.ResponseWriter, r *http.Request)
}
}

res.Routes = append(res.Routes, &routeWithName{
r := routeWithName{
Name: iter.Name(),
Route: iter.Route(),
})
}

if host != "" {
r.SourceHost = host
}

res.Routes = append(res.Routes, &r)

if len(res.Routes) == lim {
break
Expand All @@ -272,35 +278,35 @@ func apiURLsGet(backend backend.Backend, w http.ResponseWriter, r *http.Request)
writeJSON(w, &res, http.StatusOK)
}

func apiURL(backend backend.Backend, w http.ResponseWriter, r *http.Request) {
func apiURL(backend backend.Backend, host string, w http.ResponseWriter, r *http.Request) {
switch r.Method {
case "POST":
apiURLPost(backend, w, r)
apiURLPost(backend, host, w, r)
case "GET":
apiURLGet(backend, w, r)
apiURLGet(backend, host, w, r)
case "DELETE":
apiURLDelete(backend, w, r)
default:
writeJSONError(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusOK) // fix
}
}

func apiURLs(backend backend.Backend, w http.ResponseWriter, r *http.Request) {
func apiURLs(backend backend.Backend, host string, w http.ResponseWriter, r *http.Request) {
switch r.Method {
case "GET":
apiURLsGet(backend, w, r)
apiURLsGet(backend, host, w, r)
default:
writeJSONError(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusOK) // fix
}
}

// Setup ...
func Setup(m *http.ServeMux, backend backend.Backend) {
func Setup(m *http.ServeMux, backend backend.Backend, host string) {
m.HandleFunc("/api/url/", func(w http.ResponseWriter, r *http.Request) {
apiURL(backend, w, r)
apiURL(backend, host, w, r)
})

m.HandleFunc("/api/urls/", func(w http.ResponseWriter, r *http.Request) {
apiURLs(backend, w, r)
apiURLs(backend, host, w, r)
})
}
72 changes: 57 additions & 15 deletions web/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ func (e *env) call(method, path string, body io.Reader) (*mockResponse, error) {
return res, nil
}

func newEnv() (*env, error) {
func newEnv(host string) (*env, error) {
dir, err := ioutil.TempDir("", "")
if err != nil {
return nil, err
Expand All @@ -86,7 +86,7 @@ func newEnv() (*env, error) {

mux := http.NewServeMux()

Setup(mux, backend)
Setup(mux, backend, host)

return &env{
mux: mux,
Expand All @@ -95,8 +95,8 @@ func newEnv() (*env, error) {
}, nil
}

func needEnv(t *testing.T) *env {
e, err := newEnv()
func needEnv(t *testing.T, host string) *env {
e, err := newEnv(host)
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -137,11 +137,15 @@ func mustBeRouteOf(t *testing.T, rt *internal.Route, url string) {
}
}

func mustBeNamedRouteOf(t *testing.T, rt *routeWithName, name, url string) {
func mustBeNamedRouteOf(t *testing.T, rt *routeWithName, name, url string, host string) {
mustBeRouteOf(t, rt.Route, url)
if rt.Name != name {
t.Fatalf("expected name of %s, got %s", name, rt.Name)
}

if host != "" && rt.SourceHost != host {
t.Fatalf("expected source of %s, got %s", host, rt.SourceHost)
}
}

func mustBeOk(t *testing.T, ok bool) {
Expand All @@ -167,7 +171,7 @@ func mustHaveStatus(t *testing.T, res *mockResponse, status int) {
}

func TestAPIGetNotFound(t *testing.T) {
e := needEnv(t)
e := needEnv(t, "")
defer e.destroy()

names := map[string]int{
Expand All @@ -194,7 +198,45 @@ func TestAPIGetNotFound(t *testing.T) {
}

func TestAPIPutThenGet(t *testing.T) {
e := needEnv(t)
e := needEnv(t, "")
defer e.destroy()

res, err := e.post("/api/url/xxx", &urlReq{
URL: "http://ex.com/",
})
if err != nil {
t.Fatal(err)
}

mustHaveStatus(t, res, http.StatusOK)

var pm msgRoute
if err := json.NewDecoder(res).Decode(&pm); err != nil {
t.Fatal(err)
}

mustBeOk(t, pm.Ok)
mustBeNamedRouteOf(t, pm.Route, "xxx", "http://ex.com/", "")

res, err = e.get("/api/url/xxx")
if err != nil {
t.Fatal(err)
}

mustHaveStatus(t, res, http.StatusOK)

var gm msgRoute
if err := json.NewDecoder(res).Decode(&gm); err != nil {
t.Fatal(err)
}

mustBeOk(t, gm.Ok)
mustBeNamedRouteOf(t, pm.Route, "xxx", "http://ex.com/", "")
}

func TestAPIPutThenGetWithHost(t *testing.T) {
host := "http://test.com"
e := needEnv(t, host)
defer e.destroy()

res, err := e.post("/api/url/xxx", &urlReq{
Expand All @@ -212,7 +254,7 @@ func TestAPIPutThenGet(t *testing.T) {
}

mustBeOk(t, pm.Ok)
mustBeNamedRouteOf(t, pm.Route, "xxx", "http://ex.com/")
mustBeNamedRouteOf(t, pm.Route, "xxx", "http://ex.com/", host)

res, err = e.get("/api/url/xxx")
if err != nil {
Expand All @@ -227,11 +269,11 @@ func TestAPIPutThenGet(t *testing.T) {
}

mustBeOk(t, gm.Ok)
mustBeNamedRouteOf(t, pm.Route, "xxx", "http://ex.com/")
mustBeNamedRouteOf(t, pm.Route, "xxx", "http://ex.com/", host)
}

func TestBadPuts(t *testing.T) {
e := needEnv(t)
e := needEnv(t, "")
defer e.destroy()

var m msgErr
Expand Down Expand Up @@ -271,7 +313,7 @@ func TestBadPuts(t *testing.T) {
}

func TestAPIDel(t *testing.T) {
e := needEnv(t)
e := needEnv(t, "")
defer e.destroy()

ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
Expand Down Expand Up @@ -306,7 +348,7 @@ func TestAPIDel(t *testing.T) {
}

func TestAPIPutThenGetAuto(t *testing.T) {
e := needEnv(t)
e := needEnv(t, "")
defer e.destroy()

res, err := e.post("/api/url/", &urlReq{URL: "http://b.com/"})
Expand Down Expand Up @@ -335,7 +377,7 @@ func TestAPIPutThenGetAuto(t *testing.T) {
t.Fatal(err)
}
mustBeOk(t, bm.Ok)
mustBeNamedRouteOf(t, bm.Route, am.Route.Name, "http://b.com/")
mustBeNamedRouteOf(t, bm.Route, am.Route.Name, "http://b.com/", "")
}

func getInPages(e *env, params url.Values) ([][]*routeWithName, error) {
Expand Down Expand Up @@ -376,7 +418,7 @@ type listTest struct {
}

func TestAPIList(t *testing.T) {
e := needEnv(t)
e := needEnv(t, "")
defer e.destroy()

rts := []*routeWithName{
Expand Down Expand Up @@ -545,7 +587,7 @@ func TestAPIList(t *testing.T) {
}

func TestBadList(t *testing.T) {
e := needEnv(t)
e := needEnv(t, "")
defer e.destroy()

tests := map[string]int{
Expand Down
19 changes: 13 additions & 6 deletions web/assets/edit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ namespace go {
// Called with the window resizes.
var windowDidResize = () => {
var rect = $frm.getBoundingClientRect();
dom.css($frm, 'margin-top', (window.innerHeight/3 - rect.height/2) + 'px');
dom.css($frm, 'margin-top', (window.innerHeight / 3 - rect.height / 2) + 'px');
};

// Called when the URL changes.
Expand All @@ -44,7 +44,7 @@ namespace go {
url = ($url.value || '').trim();

xhr.post('/api/url/' + name)
.sendJSON({url: url})
.sendJSON({ url: url })
.onDone((data: string, status: number) => {
var msg = <MsgRoute>JSON.parse(data);
if (!msg.ok) {
Expand All @@ -59,10 +59,11 @@ namespace go {
}

var url = route.url || '',
name = route.name || '';
name = route.name || '',
host = route.source_host || '';
if (url) {
history.replaceState({}, null, '/edit/' + name);
showLink(name);
showLink(name, host);
}
});
};
Expand Down Expand Up @@ -104,8 +105,14 @@ namespace go {
dom.css($cmp, 'transform', 'scaleY(1)');
};

var showLink = (name: string) => {
var lnk = location.origin + '/' + name;
var showLink = (name: string, src: string) => {
var lnk = '/' + name;

if (src != '') {
lnk = src + lnk;
} else {
lnk = location.origin + lnk;
}

$cmp.textContent = '';
$cmp.classList.remove('fuck');
Expand Down
13 changes: 10 additions & 3 deletions web/assets/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,14 @@ var load = function() {
});
}

var showLink = function(name) {
var lnk = location.origin + '/' + name;
var showLink = function(name, src) {
var lnk = '/' + name;

if (src != '') {
lnk = src + lnk;
} else {
lnk = location.origin + lnk;
}

$cmp.text('')
.removeClass('fuck')
Expand Down Expand Up @@ -116,9 +122,10 @@ $frm.on('submit', function(e) {

var url = route.url || '',
name = route.name || '';
src = route.source_host || '';
if (url) {
history.replaceState({}, null, '/edit/' + name);
showLink(name);
showLink(name, src);
}
});
});
Expand Down
1 change: 1 addition & 0 deletions web/assets/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ interface Route {
name: string;
url: string;
time: string;
source_host: string;
}

interface Msg {
Expand Down
Loading

0 comments on commit 043936a

Please sign in to comment.