|
@@ -1,114 +0,0 @@
|
|
|
-/**
|
|
|
- * This file provided by Facebook is for non-commercial testing and evaluation
|
|
|
- * purposes only. Facebook reserves all rights not expressly granted.
|
|
|
- *
|
|
|
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
|
- * FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
|
|
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
|
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
- */
|
|
|
-
|
|
|
-package main
|
|
|
-
|
|
|
-import (
|
|
|
- "bytes"
|
|
|
- "encoding/json"
|
|
|
- "fmt"
|
|
|
- "io"
|
|
|
- "io/ioutil"
|
|
|
- "log"
|
|
|
- "net/http"
|
|
|
- "os"
|
|
|
- "sync"
|
|
|
- "time"
|
|
|
-)
|
|
|
-
|
|
|
-type comment struct {
|
|
|
- ID int64 `json:"id"`
|
|
|
- Author string `json:"author"`
|
|
|
- Text string `json:"text"`
|
|
|
-}
|
|
|
-
|
|
|
-const dataFile = "./comments.json"
|
|
|
-
|
|
|
-var commentMutex = new(sync.Mutex)
|
|
|
-
|
|
|
-func updateComments(w http.ResponseWriter, r *http.Request, commentData []byte, fi os.FileInfo) {
|
|
|
- // Decode the JSON data
|
|
|
- var comments []comment
|
|
|
- if err := json.Unmarshal(commentData, &comments); err != nil {
|
|
|
- http.Error(w, fmt.Sprintf("Unable to Unmarshal comments from data file (%s): %s", dataFile, err), http.StatusInternalServerError)
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- // Add a new comment to the in memory slice of comments
|
|
|
- comments = append(comments, comment{ID: time.Now().UnixNano() / 1000000, Author: r.FormValue("author"), Text: r.FormValue("text")})
|
|
|
-
|
|
|
- // Marshal the comments to indented json.
|
|
|
- commentData, err := json.MarshalIndent(comments, "", " ")
|
|
|
- if err != nil {
|
|
|
- http.Error(w, fmt.Sprintf("Unable to marshal comments to json: %s", err), http.StatusInternalServerError)
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- // Write out the comments to the file, preserving permissions.
|
|
|
- err = ioutil.WriteFile(dataFile, commentData, fi.Mode())
|
|
|
- if err != nil {
|
|
|
- http.Error(w, fmt.Sprintf("Unable to write comments to data file (%s): %s", dataFile, err), http.StatusInternalServerError)
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- w.Header().Set("Content-Type", "application/json")
|
|
|
- w.Header().Set("Cache-Control", "no-cache")
|
|
|
- io.Copy(w, bytes.NewReader(commentData))
|
|
|
-}
|
|
|
-
|
|
|
-// Handle comments
|
|
|
-func handleComments(w http.ResponseWriter, r *http.Request) {
|
|
|
- // Since multiple requests could come in at once, ensure we have a lock
|
|
|
- // around all file operations
|
|
|
- commentMutex.Lock()
|
|
|
- defer commentMutex.Unlock()
|
|
|
-
|
|
|
- // Stat the file, so we can find its current permissions
|
|
|
- fi, err := os.Stat(dataFile)
|
|
|
- if err != nil {
|
|
|
- http.Error(w, fmt.Sprintf("Unable to stat the data file (%s): %s", dataFile, err), http.StatusInternalServerError)
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- // Read the comments from the file.
|
|
|
- commentData, err := ioutil.ReadFile(dataFile)
|
|
|
- if err != nil {
|
|
|
- http.Error(w, fmt.Sprintf("Unable to read the data file (%s): %s", dataFile, err), http.StatusInternalServerError)
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- switch r.Method {
|
|
|
- case "POST":
|
|
|
- updateComments(w, r, commentData, fi);
|
|
|
-
|
|
|
- case "GET":
|
|
|
- w.Header().Set("Content-Type", "application/json")
|
|
|
- w.Header().Set("Cache-Control", "no-cache")
|
|
|
- // stream the contents of the file to the response
|
|
|
- io.Copy(w, bytes.NewReader(commentData))
|
|
|
-
|
|
|
- default:
|
|
|
- // Don't know the method, so error.
|
|
|
- http.Error(w, fmt.Sprintf("Unsupported method: %s", r.Method), http.StatusMethodNotAllowed)
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-func main() {
|
|
|
- port := os.Getenv("PORT")
|
|
|
- if port == "" {
|
|
|
- port = "3000"
|
|
|
- }
|
|
|
- http.HandleFunc("/api/comments", handleComments)
|
|
|
- http.Handle("/", http.FileServer(http.Dir("./public")))
|
|
|
- log.Println("Server started: http://localhost:" + port)
|
|
|
- log.Fatal(http.ListenAndServe(":" + port, nil))
|
|
|
-}
|