Changes
4 changed files (+136/-106)
-
-
@@ -4,4 +4,5 @@ require (github.com/buger/jsonparser v0.0.0-20181023193515-52c6e1462ebd github.com/go-ap/activitystreams v0.0.0-20190530184402-5829d059925a github.com/go-ap/jsonld v0.0.0-20190306111347-fbb94302fe92 github.com/go-ap/storage v0.0.0-20190531125723-e0cad53055b4 )
-
-
-
@@ -1,7 +1,9 @@package handler import ( "errors" "fmt" "github.com/go-ap/storage" as "github.com/go-ap/activitystreams" j "github.com/go-ap/jsonld" "net/http"
-
@@ -14,7 +16,16 @@ import (// an IRI representing a new Object - in the case of transitive activities that had a side effect, or // an error. // In the case of intransitive activities the iri will always be empty. type ActivityHandlerFn func(http.ResponseWriter, *http.Request) (as.IRI, int, error) type ActivityHandlerFn func(CollectionType, *http.Request, storage.ActivitySaver) (as.IRI, int, error) func (a ActivityHandlerFn) Storage(r *http.Request) (storage.ActivitySaver, error) { ctxVal := r.Context().Value(RepositoryKey) st, ok := ctxVal.(storage.ActivitySaver) if !ok { return nil, errors.New("unable to load storage from context") } return st, nil } // ValidMethod validates if the current handler can process the current request func (a ActivityHandlerFn) ValidMethod(r *http.Request) bool {
-
@@ -34,33 +45,62 @@ func (a ActivityHandlerFn) ServeHTTP(w http.ResponseWriter, r *http.Request) {var dat []byte var iri as.IRI var err error var status = http.StatusOK var status = http.StatusInternalServerError writeResponse := func(status int, dat []byte) { w.WriteHeader(status) if r.Method == http.MethodGet { w.Write(dat) } } if status, err = a.ValidateRequest(r); err != nil { dat = []byte(err.Error()) writeResponse(status, dat) return } if iri, status, err = a(w, r); err != nil { status = http.StatusInternalServerError st, err := a.Storage(r) if err != nil { dat = []byte(err.Error()) } else { dat = []byte("OK") writeResponse(status, dat) return } if iri, status, err = a(Typer.Type(r), r, st); err != nil { dat = []byte(err.Error()) writeResponse(status, dat) return } w.WriteHeader(status) if len(iri) > 0 { switch status { case http.StatusCreated: dat = []byte("CREATED") w.Header().Set("Location", iri.String()) case http.StatusGone: dat = []byte("DELETED") default: dat = []byte("OK") } w.Write(dat) } type ClientHandler interface { // MethodValidator is the interface need to be implemented to specify if an HTTP request's method // is supported by the implementor object type MethodValidator interface { ValidMethod(r *http.Request) bool } // RequestValidator is the interface need to be implemented to specify if the whole HTTP request // is valid in the context of the implementor object type RequestValidator interface { ValidateRequest(r *http.Request) (int, error) } // CollectionHandlerFn is the type that we're using to represent handlers that will return ActivityStreams // Collection or OrderedCollection objects. It needs to implement the http.Handler interface. type CollectionHandlerFn func(http.ResponseWriter, *http.Request) (as.CollectionInterface, error) type CollectionHandlerFn func(CollectionType, *http.Request, storage.CollectionLoader) (as.CollectionInterface, error) // ValidMethod validates if the current handler can process the current request func (c CollectionHandlerFn) ValidMethod(r *http.Request) bool {
-
@@ -75,35 +115,74 @@ func (c CollectionHandlerFn) ValidateRequest(r *http.Request) (int, error) {return http.StatusOK, nil } // CtxtKey type alias for the key under which we're storing the Collection Storage in the Request's context type CtxtKey string var RepositoryKey = CtxtKey("__repo") func (c CollectionHandlerFn) Storage(r *http.Request) (storage.CollectionLoader, error) { ctxVal := r.Context().Value(RepositoryKey) repo, ok := ctxVal.(storage.CollectionLoader) if !ok { return nil, errors.New("unable to load storage from context") } return repo, nil } // ServeHTTP implements the http.Handler interface for the CollectionHandlerFn type func (c CollectionHandlerFn) ServeHTTP(w http.ResponseWriter, r *http.Request) { var dat []byte var status = http.StatusOK var status = http.StatusInternalServerError var err error if status, err = c.ValidateRequest(r); err != nil { dat = []byte(err.Error()) } else { if col, err := c(w, r); err != nil { dat = []byte(err.Error()) } else { if dat, err = j.WithContext(j.IRI(as.ActivityBaseURI)).Marshal(col); err != nil { status = http.StatusInternalServerError dat = []byte(err.Error()) } writeResponse := func(status int, dat []byte) { w.WriteHeader(status) if r.Method == http.MethodGet { w.Write(dat) } } w.WriteHeader(status) if r.Method == http.MethodGet { w.Write(dat) status, err = c.ValidateRequest(r) if err != nil { dat = []byte(err.Error()) writeResponse(status, dat) return } st, err := c.Storage(r) if err != nil { dat = []byte(err.Error()) writeResponse(status, dat) return } col, err := c(Typer.Type(r), r, st) if err != nil { dat = []byte(err.Error()) writeResponse(status, dat) return } if dat, err = j.WithContext(j.IRI(as.ActivityBaseURI)).Marshal(col); err != nil { dat = []byte(err.Error()) } status = http.StatusOK writeResponse(status, dat) } // ItemHandlerFn is the type that we're using to represent handlers that return ActivityStreams // objects. It needs to implement the http.Handler interface type ItemHandlerFn func(http.ResponseWriter, *http.Request) (as.Item, error) type ItemHandlerFn func(*http.Request, storage.ObjectSaver) (as.Item, error) func (i ItemHandlerFn) Storage(r *http.Request) (storage.ObjectSaver, error) { ctxVal := r.Context().Value(RepositoryKey) st, ok := ctxVal.(storage.ObjectSaver) if !ok { return nil, errors.New("unable to load storage from context") } return st, nil } // ValidMethod validates if the current handler can process the current request func (i ItemHandlerFn) ValidMethod(r *http.Request) bool {
-
@@ -121,25 +200,42 @@ func (i ItemHandlerFn) ValidateRequest(r *http.Request) (int, error) {// ServeHTTP implements the http.Handler interface for the ItemHandlerFn type func (i ItemHandlerFn) ServeHTTP(w http.ResponseWriter, r *http.Request) { var dat []byte var status = http.StatusOK var err error status := http.StatusInternalServerError if status, err = i.ValidateRequest(r); err != nil { dat = []byte(err.Error()) } else { if it, err := i(w, r); err != nil { status = http.StatusInternalServerError dat = []byte(err.Error()) } else { if dat, err = j.WithContext(j.IRI(as.ActivityBaseURI)).Marshal(it); err != nil { status = http.StatusInternalServerError dat = []byte(err.Error()) } writeResponse := func(status int, dat []byte) { w.WriteHeader(status) if r.Method == http.MethodGet { w.Write(dat) } } w.WriteHeader(status) if r.Method == http.MethodGet { w.Write(dat) status, err = i.ValidateRequest(r) if err != nil { dat = []byte(err.Error()) writeResponse(status, dat) return } st, err := i.Storage(r) if err != nil { dat = []byte(err.Error()) writeResponse(status, dat) return } it, err := i(r, st) if err != nil { dat = []byte(err.Error()) writeResponse(status, dat) return } if dat, err = j.WithContext(j.IRI(as.ActivityBaseURI)).Marshal(it); err != nil { dat = []byte(err.Error()) writeResponse(status, dat) return } status = http.StatusOK writeResponse(status, dat) }
-
-
storage/filters.go (deleted)
-
@@ -1,22 +0,0 @@package storage import ( as "github.com/go-ap/activitystreams" ) // Filterable type Filterable interface { Types() []as.ActivityVocabularyType IRIs() []as.IRI } // Paginator type Paginator interface { QueryString() string BasePage() Paginator CurrentPage() Paginator NextPage() Paginator PrevPage() Paginator FirstPage() Paginator CurrentIndex() int }
-
-
storage/repository.go (deleted)
-
@@ -1,45 +0,0 @@package storage import ( as "github.com/go-ap/activitystreams" ) // Loader type Loader interface { Load(f Filterable) (as.ItemCollection, int, error) } // ActivityLoader type ActivityLoader interface { LoadActivities(f Filterable) (as.ItemCollection, int, error) } // ActorLoader type ActorLoader interface { LoadActors(f Filterable) (as.ItemCollection, int, error) } // ObjectLoader type ObjectLoader interface { LoadObjects(f Filterable) (as.ItemCollection, int, error) } // CollectionLoader type CollectionLoader interface { LoadCollection(f Filterable) (as.CollectionInterface, int, error) } // ActivitySaver type ActivitySaver interface { SaveActivity(as.Item) (as.Item, error) } // ActorSaver type ActorSaver interface { SaveActor(as.Item) (as.Item, error) } // ObjectSaver type ObjectSaver interface { SaveObject(as.Item) (as.Item, error) }
-