package view import ( "encoding/json" "errors" "fmt" "local/dndex/config" "local/dndex/storage" "local/gziphttp" "log" "net/http" "strings" ) func JSON(g storage.Graph) error { port := config.New().Port log.Println("listening on", port) err := http.ListenAndServe(fmt.Sprintf(":%d", port), jsonHandler(g)) return err } func jsonHandler(g storage.Graph) http.Handler { mux := http.NewServeMux() routes := []struct { path string foo func(g storage.Graph, w http.ResponseWriter, r *http.Request) error noauth bool }{ { path: "/who", foo: who, }, { path: config.New().FilePrefix + "/", foo: files, noauth: true, }, } for _, route := range routes { foo := route.foo auth := !route.noauth mux.HandleFunc(route.path, func(w http.ResponseWriter, r *http.Request) { if auth { if err := Auth(g, w, r); err != nil { log.Println(err) return } } if err := foo(g, w, r); err != nil { status := http.StatusInternalServerError if strings.Contains(err.Error(), "collision") { status = http.StatusConflict } b, _ := json.Marshal(map[string]string{"error": err.Error()}) http.Error(w, string(b), status) } }) } return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if gziphttp.Can(r) { gz := gziphttp.New(w) defer gz.Close() w = gz } mux.ServeHTTP(w, r) }) } func getAuthNamespace(r *http.Request) (string, error) { namespace := r.URL.Query().Get("namespace") if len(namespace) == 0 { return "", errors.New("no namespace found") } return strings.Join([]string{namespace, AuthKey}, "."), nil } func getNamespace(r *http.Request) (string, error) { namespace := r.URL.Query().Get("namespace") if len(namespace) == 0 { return "", errors.New("no namespace found") } return namespace, nil }