files impl
parent
c9156f397c
commit
1655a9b83a
|
|
@ -0,0 +1,42 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func (rest *REST) entities(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.Method {
|
||||
case http.MethodPut:
|
||||
rest.entitiesReplace(w, r)
|
||||
case http.MethodPatch:
|
||||
rest.entitiesUpdate(w, r)
|
||||
case http.MethodPost:
|
||||
rest.entitiesCreate(w, r)
|
||||
case http.MethodGet:
|
||||
rest.entitiesGet(w, r)
|
||||
case http.MethodDelete:
|
||||
rest.entitiesDelete(w, r)
|
||||
default:
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
}
|
||||
|
||||
func (rest *REST) entitiesCreate(w http.ResponseWriter, r *http.Request) {
|
||||
http.Error(w, "not impl", http.StatusNotImplemented)
|
||||
}
|
||||
|
||||
func (rest *REST) entitiesDelete(w http.ResponseWriter, r *http.Request) {
|
||||
http.Error(w, "not impl", http.StatusNotImplemented)
|
||||
}
|
||||
|
||||
func (rest *REST) entitiesGet(w http.ResponseWriter, r *http.Request) {
|
||||
http.Error(w, "not impl", http.StatusNotImplemented)
|
||||
}
|
||||
|
||||
func (rest *REST) entitiesReplace(w http.ResponseWriter, r *http.Request) {
|
||||
http.Error(w, "not impl", http.StatusNotImplemented)
|
||||
}
|
||||
|
||||
func (rest *REST) entitiesUpdate(w http.ResponseWriter, r *http.Request) {
|
||||
http.Error(w, "not impl", http.StatusNotImplemented)
|
||||
}
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"io"
|
||||
"local/dndex/config"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
)
|
||||
|
||||
func (rest *REST) files(w http.ResponseWriter, r *http.Request) {
|
||||
if len(r.URL.Path) < 2 {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
switch r.Method {
|
||||
case http.MethodPut:
|
||||
rest.filesUpdate(w, r)
|
||||
case http.MethodPost:
|
||||
rest.filesCreate(w, r)
|
||||
case http.MethodGet:
|
||||
rest.filesGet(w, r)
|
||||
case http.MethodDelete:
|
||||
rest.filesDelete(w, r)
|
||||
default:
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
}
|
||||
|
||||
func (rest *REST) filesCreate(w http.ResponseWriter, r *http.Request) {
|
||||
localPath := rest.filesPath(r)
|
||||
if stat, err := os.Stat(localPath); !os.IsNotExist(err) || (stat != nil && stat.IsDir()) {
|
||||
rest.respConflict(w)
|
||||
return
|
||||
}
|
||||
f, err := os.Open(localPath)
|
||||
if err != nil {
|
||||
rest.respError(w, err)
|
||||
return
|
||||
}
|
||||
defer f.Close()
|
||||
if _, err := io.Copy(f, r.Body); err != nil {
|
||||
rest.respError(w, err)
|
||||
}
|
||||
rest.respOK(w)
|
||||
}
|
||||
|
||||
func (rest *REST) filesDelete(w http.ResponseWriter, r *http.Request) {
|
||||
localPath := rest.filesPath(r)
|
||||
if stat, err := os.Stat(localPath); os.IsNotExist(err) {
|
||||
rest.respOK(w)
|
||||
return
|
||||
} else if err != nil || stat.IsDir() {
|
||||
rest.respConflict(w)
|
||||
return
|
||||
}
|
||||
if err := os.Remove(localPath); err != nil {
|
||||
rest.respError(w, err)
|
||||
}
|
||||
rest.respOK(w)
|
||||
}
|
||||
|
||||
func (rest *REST) filesGet(w http.ResponseWriter, r *http.Request) {
|
||||
localPath := rest.filesPath(r)
|
||||
if stat, err := os.Stat(localPath); os.IsNotExist(err) {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
} else if err != nil || stat.IsDir() {
|
||||
rest.respConflict(w)
|
||||
return
|
||||
}
|
||||
f, err := os.Open(localPath)
|
||||
if err != nil {
|
||||
rest.respError(w, err)
|
||||
return
|
||||
}
|
||||
defer f.Close()
|
||||
if _, err := io.Copy(w, f); err != nil {
|
||||
rest.respError(w, err)
|
||||
}
|
||||
}
|
||||
|
||||
func (rest *REST) filesUpdate(w http.ResponseWriter, r *http.Request) {
|
||||
localPath := rest.filesPath(r)
|
||||
if stat, err := os.Stat(localPath); os.IsNotExist(err) {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
} else if err != nil || stat.IsDir() {
|
||||
rest.respConflict(w)
|
||||
return
|
||||
}
|
||||
f, err := os.Open(localPath)
|
||||
if err != nil {
|
||||
rest.respError(w, err)
|
||||
return
|
||||
}
|
||||
defer f.Close()
|
||||
if _, err := io.Copy(f, r.Body); err != nil {
|
||||
rest.respError(w, err)
|
||||
}
|
||||
rest.respOK(w)
|
||||
}
|
||||
|
||||
func (rest *REST) filesPath(r *http.Request) string {
|
||||
scope := rest.scope(r)
|
||||
localPath := path.Join(config.New().FileRoot, scope.Namespace, r.URL.Path)
|
||||
return localPath
|
||||
}
|
||||
|
|
@ -2,9 +2,31 @@ package server
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func (rest *REST) respOK(w http.ResponseWriter) {
|
||||
rest.respMap(w, "ok", true)
|
||||
}
|
||||
|
||||
func (rest *REST) respConflict(w http.ResponseWriter) {
|
||||
rest.respMapStatus(w, "error", "collision found", http.StatusConflict)
|
||||
}
|
||||
|
||||
func (rest *REST) respError(w http.ResponseWriter, err error) {
|
||||
rest.respMapStatus(w, "error", fmt.Sprint(err), http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
func (rest *REST) respBadRequest(w http.ResponseWriter, msg string) {
|
||||
rest.respMapStatus(w, "error", msg, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
func (rest *REST) respMapStatus(w http.ResponseWriter, key string, value interface{}, status int) {
|
||||
w.WriteHeader(status)
|
||||
rest.resp(w, map[string]interface{}{key: value})
|
||||
}
|
||||
|
||||
func (rest *REST) respMap(w http.ResponseWriter, key string, value interface{}) {
|
||||
rest.resp(w, map[string]interface{}{key: value})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import (
|
|||
"local/dndex/server/auth"
|
||||
"local/dndex/storage"
|
||||
"local/router"
|
||||
"log"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
|
|
@ -33,12 +32,11 @@ func NewREST(g storage.RateLimitedGraph) (*REST, error) {
|
|||
|
||||
param := router.Wildcard
|
||||
params := router.Wildcard + router.Wildcard
|
||||
_, _ = param, params
|
||||
|
||||
paths := map[string]http.HandlerFunc{
|
||||
fmt.Sprintf("version"): rest.version,
|
||||
fmt.Sprintf("%s/%s", config.New().FilePrefix, params): rest.files,
|
||||
fmt.Sprintf("users"): rest.users,
|
||||
fmt.Sprintf("users/%s", param): rest.users,
|
||||
fmt.Sprintf("entities/%s", params): rest.entities,
|
||||
}
|
||||
|
||||
|
|
@ -59,18 +57,3 @@ func NewREST(g storage.RateLimitedGraph) (*REST, error) {
|
|||
func (rest *REST) scope(r *http.Request) auth.Scope {
|
||||
return auth.GetScope(r)
|
||||
}
|
||||
|
||||
func (rest *REST) files(w http.ResponseWriter, r *http.Request) {
|
||||
log.Println("files: SCOPE:", rest.scope(r), r.URL.Path)
|
||||
http.Error(w, "not impl", http.StatusNotImplemented)
|
||||
}
|
||||
|
||||
func (rest *REST) users(w http.ResponseWriter, r *http.Request) {
|
||||
log.Println("users: SCOPE:", rest.scope(r), r.URL.Path)
|
||||
http.Error(w, "not impl", http.StatusNotImplemented)
|
||||
}
|
||||
|
||||
func (rest *REST) entities(w http.ResponseWriter, r *http.Request) {
|
||||
log.Println("entities: SCOPE:", rest.scope(r), r.URL.Path)
|
||||
http.Error(w, "not impl", http.StatusNotImplemented)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,15 +28,12 @@ var (
|
|||
)
|
||||
|
||||
func TestRESTRouter(t *testing.T) {
|
||||
rest, setAuth, clean := testREST(t)
|
||||
defer clean()
|
||||
_, _, clean := testREST(t)
|
||||
clean()
|
||||
cases := map[string]struct {
|
||||
method string
|
||||
is404 bool
|
||||
}{
|
||||
"/version": {
|
||||
method: http.MethodGet,
|
||||
},
|
||||
fmt.Sprintf(`%s`, config.New().FilePrefix): {
|
||||
method: http.MethodGet,
|
||||
is404: true,
|
||||
|
|
@ -45,9 +42,18 @@ func TestRESTRouter(t *testing.T) {
|
|||
method: http.MethodGet,
|
||||
is404: true,
|
||||
},
|
||||
fmt.Sprintf(`%s/%s`, config.New().FilePrefix, testFilename): {
|
||||
fmt.Sprintf(`%s/%s?g`, config.New().FilePrefix, testFilename): {
|
||||
method: http.MethodGet,
|
||||
},
|
||||
fmt.Sprintf(`%s/%s?pu`, config.New().FilePrefix, testFilename): {
|
||||
method: http.MethodPut,
|
||||
},
|
||||
fmt.Sprintf(`%s/%s?po`, config.New().FilePrefix, testFilename): {
|
||||
method: http.MethodPost,
|
||||
},
|
||||
fmt.Sprintf(`%s/%s?d`, config.New().FilePrefix, testFilename): {
|
||||
method: http.MethodDelete,
|
||||
},
|
||||
fmt.Sprintf(`%s/fake.fake`, config.New().FilePrefix): {
|
||||
method: http.MethodGet,
|
||||
is404: true,
|
||||
|
|
@ -56,19 +62,23 @@ func TestRESTRouter(t *testing.T) {
|
|||
method: http.MethodGet,
|
||||
is404: true,
|
||||
},
|
||||
fmt.Sprintf("/users/%s", testNamespace): {
|
||||
"/users/register": {
|
||||
method: http.MethodPost,
|
||||
},
|
||||
"/users/login": {
|
||||
method: http.MethodPost,
|
||||
is404: true,
|
||||
},
|
||||
"/users/": {
|
||||
method: http.MethodGet,
|
||||
method: http.MethodPost,
|
||||
is404: true,
|
||||
},
|
||||
"/users": {
|
||||
method: http.MethodPost,
|
||||
is404: true,
|
||||
},
|
||||
"/users?": {
|
||||
method: http.MethodGet,
|
||||
method: http.MethodPost,
|
||||
is404: true,
|
||||
},
|
||||
"/entities": {
|
||||
method: http.MethodGet,
|
||||
|
|
@ -124,37 +134,49 @@ func TestRESTRouter(t *testing.T) {
|
|||
fmt.Sprintf("/entities/%s/connections", testEntityID): {
|
||||
method: http.MethodPatch,
|
||||
},
|
||||
"/version": {
|
||||
method: http.MethodGet,
|
||||
},
|
||||
fmt.Sprintf("/entities/%s/connections/uuid/", testEntityID): {
|
||||
method: http.MethodDelete,
|
||||
},
|
||||
fmt.Sprintf("/entities/%s/connections/uuid", testEntityID): {
|
||||
method: http.MethodDelete,
|
||||
},
|
||||
fmt.Sprintf("/entities/%s/connections/", testEntityID): {
|
||||
fmt.Sprintf("/entities/%s/connections/?d", testEntityID): {
|
||||
method: http.MethodDelete,
|
||||
},
|
||||
fmt.Sprintf("/entities/%s/connections?d", testEntityID): {
|
||||
method: http.MethodDelete,
|
||||
},
|
||||
fmt.Sprintf("/entities/%s/?d", testEntityID): {
|
||||
method: http.MethodDelete,
|
||||
},
|
||||
fmt.Sprintf("/entities/%s?d", testEntityID): {
|
||||
method: http.MethodDelete,
|
||||
},
|
||||
"/entities/?d": {
|
||||
method: http.MethodDelete,
|
||||
is404: true,
|
||||
},
|
||||
fmt.Sprintf("/entities/%s/connections", testEntityID): {
|
||||
method: http.MethodDelete,
|
||||
},
|
||||
fmt.Sprintf("/entities/%s/", testEntityID): {
|
||||
"/entities?d": {
|
||||
method: http.MethodDelete,
|
||||
is404: true,
|
||||
},
|
||||
fmt.Sprintf("/entities/%s", testEntityID): {
|
||||
method: http.MethodDelete,
|
||||
},
|
||||
}
|
||||
|
||||
for name, d := range cases {
|
||||
c := d
|
||||
path := name
|
||||
t.Run(name, func(t *testing.T) {
|
||||
rest, setAuth, clean := testREST(t)
|
||||
defer clean()
|
||||
r := httptest.NewRequest(c.method, path, strings.NewReader(``))
|
||||
setAuth(r)
|
||||
w := httptest.NewRecorder()
|
||||
rest.router.ServeHTTP(w, r)
|
||||
if (w.Code == http.StatusNotFound) != c.is404 {
|
||||
t.Fatalf("want 404==%v, got %d: %+v: %s", c.is404, w.Code, c, w.Body.Bytes())
|
||||
t.Errorf("%s: want 404==%v, got %d: %+v: %s", name, c.is404, w.Code, c, w.Body.Bytes())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -163,14 +185,14 @@ func testREST(t *testing.T) (*REST, func(r *http.Request), func()) {
|
|||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := ioutil.WriteFile(path.Join(d, testFilename), []byte(testContent), os.ModePerm); err != nil {
|
||||
os.MkdirAll(path.Join(d, testNamespace), os.ModePerm)
|
||||
if err := ioutil.WriteFile(path.Join(d, testNamespace, testFilename), []byte(testContent), os.ModePerm); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
os.Setenv("FILEROOT", d)
|
||||
os.Setenv("DRIVER_TYPE", "map")
|
||||
os.Setenv("AUTH", "true")
|
||||
os.Args = os.Args[:1]
|
||||
os.Args = os.Args[:1]
|
||||
config.New()
|
||||
rest, err := NewREST(storage.NewRateLimitedGraph(""))
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func (rest *REST) users(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.Method {
|
||||
case http.MethodPost:
|
||||
default:
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
switch r.URL.Path {
|
||||
case "/register":
|
||||
rest.usersRegister(w, r)
|
||||
case "/login":
|
||||
rest.usersLogin(w, r)
|
||||
default:
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
}
|
||||
|
||||
func (rest *REST) usersRegister(w http.ResponseWriter, r *http.Request) {
|
||||
log.Println(r.URL.Path, rest.scope(r))
|
||||
http.Error(w, "not impl", http.StatusNotImplemented)
|
||||
}
|
||||
|
||||
func (rest *REST) usersLogin(w http.ResponseWriter, r *http.Request) {
|
||||
log.Println(r.URL.Path, rest.scope(r))
|
||||
http.Error(w, "not impl", http.StatusNotImplemented)
|
||||
}
|
||||
Loading…
Reference in New Issue