package routes import ( "net/http" "sour.is/x/httpsrv" "sour.is/x/ident" "encoding/json" "github.com/gorilla/mux" "io/ioutil" "io" "sour.is/x/log" "os" "golang.org/x/sys/unix" "crypto/rand" "strconv" "sour.is/x/paste/model" ) var store string var randBytes int func init() { httpsrv.HttpRegister("paste", httpsrv.HttpRoutes{ { "Paste", "GET", "/paste/rng", GetRandom, }, { "Paste", "GET", "/paste/{id}", GetPaste, }, { "Paste", "GET", "/paste/get/{id}", GetPaste, }, { "Paste", "POST", "/paste", PostPaste, }, // { "Paste", "DELETE", "/paste/{id}", DeletePaste, }, { "Paste", "GET", "/api/rng", GetRandom, }, { "Paste", "GET", "/api/{id}", GetPaste, }, { "Paste", "GET", "/api/get/{id}", GetPaste, }, { "Paste", "POST", "/api", PostPaste, }, // { "Paste", "DELETE", "/api/{id}", DeletePaste, }, }) } func SetConfig (config map[string]string) { store = "data/" if config["store"] != "" { store = config["store"] } if !chkStore(store) { log.Fatalf("[routes::Paste] Store location [%s] does not exist or is not writable.", store) } randBytes = 1024 if config["random"] != "" { randBytes, _ = strconv.Atoi(config["random"]) } } func chkStore(path string) bool { file, err := os.Stat(path) if err == nil { return true } if os.IsNotExist(err) { return false } if !file.IsDir() { return false } if unix.Access(path, unix.W_OK & unix.R_OK) != nil { return false } return true } func chkFile(path string) bool { file, err := os.Stat(path) if err == nil { return true } if os.IsNotExist(err) { return false } if file.IsDir() { return false } if unix.Access(path, unix.W_OK & unix.R_OK) != nil { return false } return true } func chkGone(path string) bool { file, err := os.Stat(path) if err != nil { return true } if file.Size() == 0 { return true } return false } func GetRandom(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) w.Header().Set("content-type","application/octet-stream") s := make([]byte, randBytes) rand.Read(s) w.Write(s) } // swagger:route GET /paste pasteIndex // // Welcomes user. // // This welcome user based on identity used. // // Consumes: // - application/json // // Produces: // - application/json // // Schemes: http // // Security: // user_token: // // Responses: // default: genericError // 200: someResponse // 422: validationError func GetPaste(w http.ResponseWriter, r *http.Request, i ident.Ident) { vars := mux.Vars(r) id := vars["id"] p, err := model.GetPaste(id) log.Printf("%#v",p) if err != nil { w.WriteHeader(http.StatusBadRequest) w.Write([]byte("Bad Request")) return } if p.Id == "" { w.WriteHeader(http.StatusNotFound) w.Write([]byte("Not Found")) return } //switch accept { //case "text/plain": w.WriteHeader(http.StatusOK) if _, err := w.Write([]byte(p.String())); err != nil { panic(err) } /* case "application/json": w.WriteHeader(http.StatusOK) if err := json.NewEncoder(w).Encode(p); err != nil { panic(err) } default: w.WriteHeader(http.StatusNotAcceptable) w.Write([]byte("")) } */ } func PostPaste(w http.ResponseWriter, r *http.Request, i ident.Ident) { var p model.Paste body, err := ioutil.ReadAll(io.LimitReader(r.Body, 1048576)) checkErr(err, w) err = r.Body.Close() checkErr(err, w) if err := json.Unmarshal(body, &p); err != nil { w.WriteHeader(422) // unprocessable entity err = json.NewEncoder(w).Encode(err) checkErr(err, w) } p.CreatedBy = i.Identity() np, err := model.CreatePaste(p) checkErr(err, w) // accept := negotiate.Negotiate("text/plain,application/json;q=0.7", r) //switch accept { //case "text/plain": w.WriteHeader(http.StatusCreated) if _, err := w.Write([]byte(np.String())); err != nil { panic(err) } /* case "application/json": w.WriteHeader(http.StatusCreated) if err := json.NewEncoder(w).Encode(np); err != nil { panic(err) } default: w.WriteHeader(http.StatusNotAcceptable) w.Write([]byte("")) } */ } func checkErr(err error, w http.ResponseWriter) { if err != nil { w.WriteHeader(http.StatusBadRequest) json.NewEncoder(w).Encode(err); panic(err) } }