package main import ( "encoding/json" "net/http" "strconv" "time" ) type MicropubConfig struct { SyndicateTo []SyndicationTarget `json:"syndicate-to,omitempty"` MediaEndpoint string `json:"media-endpoint,omitempty"` } func getMediaEndpoint() string { if SelectedMediaStorage != nil { return MediaEndpointUrl } else { return "" } } func HandleMicroPub(w http.ResponseWriter, r *http.Request) { // a handler for GET requests, used for troubleshooting if r.Method == "GET" { if q := r.URL.Query().Get("q"); q == "config" || q == "syndicate-to" { w.Header().Add("Content-type", "application/json") w.WriteHeader(http.StatusOK) jsonBytes, err := json.Marshal(&MicropubConfig{ SyndicateTo: SyndicationTargets, MediaEndpoint: getMediaEndpoint(), }) if err != nil { w.WriteHeader(http.StatusBadRequest) _, _ = w.Write([]byte(err.Error())) return } _, _ = w.Write(jsonBytes) return } else if url := r.URL.Query().Get("url"); q == "source" { limit := r.URL.Query().Get("limit") limitInt, err := strconv.Atoi(limit) jsonBytes, err := QueryURL(url, limitInt) if err != nil { w.WriteHeader(http.StatusBadRequest) _, _ = w.Write([]byte(err.Error())) return } w.Header().Add("Content-type", "application/json") w.WriteHeader(http.StatusOK) _, _ = w.Write(jsonBytes) return } else { w.Header().Add("Content-type", "application/json") w.WriteHeader(http.StatusOK) _, _ = w.Write([]byte("{}")) return } } // check if the request is a POST if r.Method != "POST" { w.WriteHeader(http.StatusMethodNotAllowed) _, _ = w.Write([]byte("The HTTP method is not allowed, make a POST request")) return } // check content type contentType, err := GetContentType(r.Header.Get("content-type")) if err != nil { w.WriteHeader(http.StatusBadRequest) _, _ = w.Write([]byte(err.Error())) return } // Create entry entry, err := CreateEntry(contentType, r) if err != nil || entry == nil { w.WriteHeader(http.StatusBadRequest) if err != nil { _, _ = w.Write([]byte(err.Error())) } else { _, _ = w.Write([]byte("There was an error creating the entry")) } return } if authHeader := r.Header.Get("authorization"); len(entry.token) == 0 && len(authHeader) > 0 { entry.token = authHeader } if CheckAuthorization(entry.token) { location, err := WriteEntry(entry) if err != nil { w.WriteHeader(http.StatusBadRequest) _, _ = w.Write([]byte("There was an error committing the entry to the repository")) return } else { w.Header().Add("Location", location) w.WriteHeader(http.StatusAccepted) // Purge CDN in 10 seconds, send webmentions, post to social media go func() { if SelectedCdn != nil { time.Sleep(10 * time.Second) SelectedCdn.Purge(location) } time.Sleep(10 * time.Second) // Send webmentions go SendWebmentions(location) go func() { if SelectedSocials != nil { SelectedSocials.Post(location, entry.title) } }() }() return } } else { w.WriteHeader(http.StatusForbidden) _, _ = w.Write([]byte("Forbidden, there was a problem with the provided access token")) return } }