summaryrefslogtreecommitdiff
path: root/system/api/handlers.go
diff options
context:
space:
mode:
authorSteve <nilslice@gmail.com>2017-01-02 11:58:56 -0800
committerGitHub <noreply@github.com>2017-01-02 11:58:56 -0800
commit6f0d53777bcc792099113c7dbd1e5f0b012be562 (patch)
treec148636f245bb1efd4ce5b1f597519038da9816c /system/api/handlers.go
parent806fdbe1e8839feb1bcc4e5e07aa7c144a429901 (diff)
parentae7d01f3aae28797f3b9ebc67be843763a02da6d (diff)
Merge pull request #27 from ponzu-cms/ponzu-dev
[core] HTTP/2 Server Push for referenced items, Hideable interface
Diffstat (limited to 'system/api/handlers.go')
-rw-r--r--system/api/handlers.go88
1 files changed, 61 insertions, 27 deletions
diff --git a/system/api/handlers.go b/system/api/handlers.go
index 7b59dbd..8b4a387 100644
--- a/system/api/handlers.go
+++ b/system/api/handlers.go
@@ -15,8 +15,10 @@ import (
func typesHandler(res http.ResponseWriter, req *http.Request) {
var types = []string{}
- for t := range item.Types {
- types = append(types, string(t))
+ for t, fn := range item.Types {
+ if !hide(fn(), res, req) {
+ types = append(types, t)
+ }
}
j, err := toJSON(types)
@@ -36,11 +38,16 @@ func contentsHandler(res http.ResponseWriter, req *http.Request) {
return
}
- if _, ok := item.Types[t]; !ok {
+ it, ok := item.Types[t]
+ if !ok {
res.WriteHeader(http.StatusNotFound)
return
}
+ if hide(it(), res, req) {
+ return
+ }
+
count, err := strconv.Atoi(q.Get("count")) // int: determines number of posts to return (10 default, -1 is all)
if err != nil {
if q.Get("count") == "" {
@@ -98,13 +105,18 @@ func contentHandler(res http.ResponseWriter, req *http.Request) {
return
}
- if _, ok := item.Types[t]; !ok {
+ if t == "" || id == "" {
+ res.WriteHeader(http.StatusBadRequest)
+ return
+ }
+
+ pt, ok := item.Types[t]
+ if !ok {
res.WriteHeader(http.StatusNotFound)
return
}
- if t == "" || id == "" {
- res.WriteHeader(http.StatusBadRequest)
+ if hide(pt(), res, req) {
return
}
@@ -114,6 +126,8 @@ func contentHandler(res http.ResponseWriter, req *http.Request) {
return
}
+ defer push(res, req, pt, post)
+
j, err := fmtJSON(json.RawMessage(post))
if err != nil {
res.WriteHeader(http.StatusInternalServerError)
@@ -126,14 +140,31 @@ func contentHandler(res http.ResponseWriter, req *http.Request) {
func contentHandlerBySlug(res http.ResponseWriter, req *http.Request) {
slug := req.URL.Query().Get("slug")
+ if slug == "" {
+ res.WriteHeader(http.StatusBadRequest)
+ return
+ }
+
// lookup type:id by slug key in __contentIndex
- post, err := db.ContentBySlug(slug)
+ t, post, err := db.ContentBySlug(slug)
if err != nil {
log.Println("Error finding content by slug:", slug, err)
res.WriteHeader(http.StatusInternalServerError)
return
}
+ it, ok := item.Types[t]
+ if !ok {
+ res.WriteHeader(http.StatusBadRequest)
+ return
+ }
+
+ if hide(it(), res, req) {
+ return
+ }
+
+ defer push(res, req, it, post)
+
j, err := fmtJSON(json.RawMessage(post))
if err != nil {
res.WriteHeader(http.StatusInternalServerError)
@@ -143,6 +174,26 @@ func contentHandlerBySlug(res http.ResponseWriter, req *http.Request) {
sendData(res, j, http.StatusOK)
}
+func hide(it interface{}, res http.ResponseWriter, req *http.Request) bool {
+ // check if should be hidden
+ if h, ok := it.(item.Hideable); ok {
+ err := h.Hide(req)
+ if err != nil && err.Error() == item.AllowHiddenItem {
+ return false
+ }
+
+ if err != nil {
+ res.WriteHeader(http.StatusInternalServerError)
+ return true
+ }
+
+ res.WriteHeader(http.StatusNotFound)
+ return true
+ }
+
+ return false
+}
+
func fmtJSON(data ...json.RawMessage) ([]byte, error) {
var msg = []json.RawMessage{}
for _, d := range data {
@@ -193,36 +244,19 @@ func sendData(res http.ResponseWriter, data []byte, code int) {
}
}
-// SendPreflight is used to respond to a cross-origin "OPTIONS" request
-func SendPreflight(res http.ResponseWriter) {
+// sendPreflight is used to respond to a cross-origin "OPTIONS" request
+func sendPreflight(res http.ResponseWriter) {
res.Header().Set("Access-Control-Allow-Headers", "Accept, Authorization, Content-Type")
res.Header().Set("Access-Control-Allow-Origin", "*")
res.WriteHeader(200)
return
}
-// SendJSON returns a Response to a client as JSON
-func SendJSON(res http.ResponseWriter, j map[string]interface{}) {
- var data []byte
- var err error
-
- data, err = json.Marshal(j)
- if err != nil {
- log.Println(err)
- data, _ = json.Marshal(map[string]interface{}{
- "status": "fail",
- "message": err.Error(),
- })
- }
-
- sendData(res, data, 200)
-}
-
// CORS wraps a HandleFunc to respond to OPTIONS requests properly
func CORS(next http.HandlerFunc) http.HandlerFunc {
return db.CacheControl(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
if req.Method == http.MethodOptions {
- SendPreflight(res)
+ sendPreflight(res)
return
}