package micropub
import (
"encoding/json"
"log"
"net/http"
"strings"
"hawx.me/code/mux"
)
func postHandler(publisher Publisher) http.Handler {
h := micropubPostHandler{publisher: publisher}
return mux.ContentType{
"application/json": http.HandlerFunc(h.handleJSON),
"application/x-www-form-urlencoded": http.HandlerFunc(h.handleForm),
"multipart/form-data": http.HandlerFunc(h.handleMultiPart),
}
}
type micropubPostHandler struct {
publisher Publisher
}
func (h *micropubPostHandler) handleJSON(w http.ResponseWriter, r *http.Request) {
v := jsonMicroformat{Properties: map[string][]interface{}{}}
if err := json.NewDecoder(r.Body).Decode(&v); err != nil {
http.Error(w, "could not decode json request: "+err.Error(), http.StatusBadRequest)
return
}
data := jsonToForm(v)
if v.Action == "update" {
http.Error(w, "'update' not supported", http.StatusBadRequest)
return
}
h.publish(w, data)
}
func (h *micropubPostHandler) handleForm(w http.ResponseWriter, r *http.Request) {
data := map[string][]interface{}{}
if err := r.ParseForm(); err != nil {
http.Error(w, "could not parse form: "+err.Error(), http.StatusBadRequest)
return
}
for key, values := range r.Form {
if reservedKey(key) {
continue
}
if strings.HasSuffix(key, "[]") {
key := key[:len(key)-2]
for _, value := range values {
data[key] = append(data[key], value)
}
} else {
data[key] = []interface{}{values[0]}
}
}
h.publish(w, data)
}
func (h *micropubPostHandler) handleMultiPart(w http.ResponseWriter, r *http.Request) {
// todo
log.Println("received multi-part request")
}
func (h *micropubPostHandler) publish(w http.ResponseWriter, data map[string][]interface{}) {
location, err := h.publisher(data)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Add("Location", location)
w.WriteHeader(http.StatusCreated)
}
func reservedKey(key string) bool {
return key == "access_token" || key == "action" || key == "url" || strings.HasPrefix(key, "mp-")
}