mirror of
https://codeberg.org/scip/ephemerup.git
synced 2025-12-16 20:20:58 +01:00
fix endpoints
This commit is contained in:
26
README.md
26
README.md
@@ -151,19 +151,19 @@ Every endpoint returns a JSON object. Each returned object contains the data req
|
||||
|
||||
#### Endpoints
|
||||
|
||||
| HTTP Method | Endpoint | Parameters | Input | Returns | Description |
|
||||
|-------------|-------------------|---------------------|----------------------------|---------------------------------------|-----------------------------------------------|
|
||||
| GET | /v1/uploads | apicontext,q,expire | | List of upload objects | list upload objects |
|
||||
| POST | /v1/uploads | | multipart-formdata file[s] | List of 1 upload object if successful | upload a file and create a new upload object |
|
||||
| GET | /v1/uploads/{id} | | | List of 1 upload object if successful | list one specific upload object matching {id} |
|
||||
| DELETE | /v1/uploads/{id} | | | Noting | delete an upload object identified by {id} |
|
||||
| PUT | /v1/uploads/{id} | | JSON upload object | List of 1 upload object if successful | modify an upload object identified by {id} |
|
||||
| GET | /v1/download/{id} | | | File download | Download the file associated with the object |
|
||||
| GET | /v1/forms | apicontext,q,expire | | List of form objects | list form objects |
|
||||
| POST | /v1/forms | | JSON form object | List of 1 form object if successful | create a new form object |
|
||||
| GET | /v1/forms/{id} | | | List of 1 form object if successful | list one specific form object matching {id} |
|
||||
| DELETE | /v1/forms/{id} | | | Noting | delete an form object identified by {id} |
|
||||
| PUT | /v1/forms/{id} | | JSON form object | List of 1 form object if successful | modify an form object identified by {id} |
|
||||
| HTTP Method | Endpoint | Parameters | Input | Returns | Description |
|
||||
|-------------|-----------------------|---------------------|----------------------------|---------------------------------------|-----------------------------------------------|
|
||||
| GET | /v1/uploads | apicontext,q,expire | | List of upload objects | list upload objects |
|
||||
| POST | /v1/uploads | | multipart-formdata file[s] | List of 1 upload object if successful | upload a file and create a new upload object |
|
||||
| GET | /v1/uploads/{id} | | | List of 1 upload object if successful | list one specific upload object matching {id} |
|
||||
| DELETE | /v1/uploads/{id} | | | Noting | delete an upload object identified by {id} |
|
||||
| PUT | /v1/uploads/{id} | | JSON upload object | List of 1 upload object if successful | modify an upload object identified by {id} |
|
||||
| GET | /v1/uploads/{id}/file | | | File download | Download the file associated with the object |
|
||||
| GET | /v1/forms | apicontext,q,expire | | List of form objects | list form objects |
|
||||
| POST | /v1/forms | | JSON form object | List of 1 form object if successful | create a new form object |
|
||||
| GET | /v1/forms/{id} | | | List of 1 form object if successful | list one specific form object matching {id} |
|
||||
| DELETE | /v1/forms/{id} | | | Noting | delete an form object identified by {id} |
|
||||
| PUT | /v1/forms/{id} | | JSON form object | List of 1 form object if successful | modify an form object identified by {id} |
|
||||
|
||||
#### Consumer URLs
|
||||
|
||||
|
||||
@@ -106,7 +106,7 @@ func (db *Db) Delete(apicontext string, id string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func (db *Db) List(apicontext string, filter string) (*common.Uploads, error) {
|
||||
func (db *Db) UploadsList(apicontext string, filter string) (*common.Uploads, error) {
|
||||
uploads := &common.Uploads{}
|
||||
|
||||
err := db.bolt.View(func(tx *bolt.Tx) error {
|
||||
|
||||
@@ -34,7 +34,7 @@ type SetContext struct {
|
||||
Apicontext string `json:"apicontext" form:"apicontext"`
|
||||
}
|
||||
|
||||
func FilePut(c *fiber.Ctx, cfg *cfg.Config, db *Db) error {
|
||||
func UploadPost(c *fiber.Ctx, cfg *cfg.Config, db *Db) error {
|
||||
// supports upload of multiple files with:
|
||||
//
|
||||
// curl -X POST localhost:8080/putfile \
|
||||
@@ -106,6 +106,7 @@ func FilePut(c *fiber.Ctx, cfg *cfg.Config, db *Db) error {
|
||||
"Could not process uploaded file[s]: "+err.Error())
|
||||
}
|
||||
entry.File = Newfilename
|
||||
entry.Url = returnUrl
|
||||
|
||||
Log("Now serving %s from %s/%s", returnUrl, cfg.StorageDir, id)
|
||||
Log("Expire set to: %s", entry.Expire)
|
||||
@@ -117,12 +118,11 @@ func FilePut(c *fiber.Ctx, cfg *cfg.Config, db *Db) error {
|
||||
// everything went well so far
|
||||
res := &common.Uploads{Entries: []*common.Upload{entry}}
|
||||
res.Success = true
|
||||
res.Message = "Download url: " + returnUrl
|
||||
res.Code = fiber.StatusOK
|
||||
return c.Status(fiber.StatusOK).JSON(res)
|
||||
}
|
||||
|
||||
func FileGet(c *fiber.Ctx, cfg *cfg.Config, db *Db, shallExpire ...bool) error {
|
||||
func UploadFetch(c *fiber.Ctx, cfg *cfg.Config, db *Db, shallExpire ...bool) error {
|
||||
// deliver a file and delete it if expire is set to asap
|
||||
|
||||
// we ignore c.Params("file"), cause it may be malign. Also we've
|
||||
@@ -173,7 +173,7 @@ func FileGet(c *fiber.Ctx, cfg *cfg.Config, db *Db, shallExpire ...bool) error {
|
||||
}
|
||||
|
||||
// delete file, id dir and db entry
|
||||
func DeleteUpload(c *fiber.Ctx, cfg *cfg.Config, db *Db) error {
|
||||
func UploadDelete(c *fiber.Ctx, cfg *cfg.Config, db *Db) error {
|
||||
|
||||
id, err := common.Untaint(c.Params("id"), cfg.RegKey)
|
||||
if err != nil {
|
||||
@@ -206,7 +206,7 @@ func DeleteUpload(c *fiber.Ctx, cfg *cfg.Config, db *Db) error {
|
||||
}
|
||||
|
||||
// returns the whole list + error code, no post processing by server
|
||||
func List(c *fiber.Ctx, cfg *cfg.Config, db *Db) error {
|
||||
func UploadsList(c *fiber.Ctx, cfg *cfg.Config, db *Db) error {
|
||||
// fetch filter from body(json expected)
|
||||
setcontext := new(SetContext)
|
||||
if err := c.BodyParser(setcontext); err != nil {
|
||||
@@ -228,7 +228,7 @@ func List(c *fiber.Ctx, cfg *cfg.Config, db *Db) error {
|
||||
}
|
||||
|
||||
// get list
|
||||
uploads, err := db.List(apicontext, filter)
|
||||
uploads, err := db.UploadsList(apicontext, filter)
|
||||
if err != nil {
|
||||
return JsonStatus(c, fiber.StatusForbidden,
|
||||
"Unable to list uploads: "+err.Error())
|
||||
@@ -242,7 +242,7 @@ func List(c *fiber.Ctx, cfg *cfg.Config, db *Db) error {
|
||||
}
|
||||
|
||||
// returns just one upload obj + error code, no post processing by server
|
||||
func Describe(c *fiber.Ctx, cfg *cfg.Config, db *Db) error {
|
||||
func UploadDescribe(c *fiber.Ctx, cfg *cfg.Config, db *Db) error {
|
||||
id, err := common.Untaint(c.Params("id"), cfg.RegKey)
|
||||
if err != nil {
|
||||
return JsonStatus(c, fiber.StatusForbidden,
|
||||
|
||||
@@ -56,29 +56,29 @@ func Runserver(conf *cfg.Config, args []string) error {
|
||||
api := router.Group(conf.ApiPrefix + ApiVersion)
|
||||
{
|
||||
// upload
|
||||
api.Post("/uploads/", auth, func(c *fiber.Ctx) error {
|
||||
return FilePut(c, conf, db)
|
||||
api.Post("/uploads", auth, func(c *fiber.Ctx) error {
|
||||
return UploadPost(c, conf, db)
|
||||
})
|
||||
|
||||
// remove
|
||||
api.Delete("/uploads/:id/", auth, func(c *fiber.Ctx) error {
|
||||
err := DeleteUpload(c, conf, db)
|
||||
api.Delete("/uploads/:id", auth, func(c *fiber.Ctx) error {
|
||||
err := UploadDelete(c, conf, db)
|
||||
return SendResponse(c, "", err)
|
||||
})
|
||||
|
||||
// listing
|
||||
api.Get("/uploads", auth, func(c *fiber.Ctx) error {
|
||||
return List(c, conf, db)
|
||||
return UploadsList(c, conf, db)
|
||||
})
|
||||
|
||||
// info/describe
|
||||
api.Get("/upload/:id/", auth, func(c *fiber.Ctx) error {
|
||||
return Describe(c, conf, db)
|
||||
api.Get("/uploads/:id", auth, func(c *fiber.Ctx) error {
|
||||
return UploadDescribe(c, conf, db)
|
||||
})
|
||||
|
||||
// download w/o expire
|
||||
api.Get("/download/:id/", auth, func(c *fiber.Ctx) error {
|
||||
return FileGet(c, conf, db)
|
||||
api.Get("/uploads/:id/file", auth, func(c *fiber.Ctx) error {
|
||||
return UploadFetch(c, conf, db)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -89,11 +89,11 @@ func Runserver(conf *cfg.Config, args []string) error {
|
||||
})
|
||||
|
||||
router.Get("/download/:id/:file", func(c *fiber.Ctx) error {
|
||||
return FileGet(c, conf, db, shallExpire)
|
||||
return UploadFetch(c, conf, db, shallExpire)
|
||||
})
|
||||
|
||||
router.Get("/download/:id/", func(c *fiber.Ctx) error {
|
||||
return FileGet(c, conf, db, shallExpire)
|
||||
router.Get("/download/:id", func(c *fiber.Ctx) error {
|
||||
return UploadFetch(c, conf, db, shallExpire)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ func Execute() error {
|
||||
f.BoolVarP(&conf.Debug, "debug", "d", false, "Enable debugging")
|
||||
f.StringVarP(&conf.Listen, "listen", "l", ":8080", "listen to custom ip:port (use [ip]:port for ipv6)")
|
||||
f.StringVarP(&conf.StorageDir, "storagedir", "s", "/tmp", "storage directory for uploaded files")
|
||||
f.StringVarP(&conf.ApiPrefix, "apiprefix", "a", "/api", "API endpoint path")
|
||||
f.StringVarP(&conf.ApiPrefix, "apiprefix", "a", "", "API endpoint path")
|
||||
f.StringVarP(&conf.Url, "url", "u", "", "HTTP endpoint w/o path")
|
||||
f.StringVarP(&conf.DbFile, "dbfile", "D", "/tmp/uploads.db", "Bold database file to use")
|
||||
f.StringVarP(&conf.Super, "super", "", "", "The API Context which has permissions on all contexts")
|
||||
|
||||
@@ -135,11 +135,6 @@ func HandleResponse(c *cfg.Config, resp *req.Response) error {
|
||||
// we expect a json response, extract the error, if any
|
||||
r := Response{}
|
||||
|
||||
if err := json.Unmarshal([]byte(resp.String()), &r); err != nil {
|
||||
// text output!
|
||||
r.Message = resp.String()
|
||||
}
|
||||
|
||||
if c.Debug {
|
||||
trace := resp.Request.TraceInfo()
|
||||
fmt.Println(trace.Blame())
|
||||
@@ -147,6 +142,15 @@ func HandleResponse(c *cfg.Config, resp *req.Response) error {
|
||||
fmt.Println(trace)
|
||||
}
|
||||
|
||||
if !resp.IsSuccessState() {
|
||||
return fmt.Errorf("bad response: %s", resp.Status)
|
||||
}
|
||||
|
||||
if err := json.Unmarshal([]byte(resp.String()), &r); err != nil {
|
||||
// text output!
|
||||
r.Message = resp.String()
|
||||
}
|
||||
|
||||
if !r.Success {
|
||||
if len(r.Message) == 0 {
|
||||
if resp.Err != nil {
|
||||
@@ -200,7 +204,7 @@ func UploadFiles(w io.Writer, c *cfg.Config, args []string) error {
|
||||
}
|
||||
|
||||
func List(w io.Writer, c *cfg.Config, args []string) error {
|
||||
rq := Setup(c, "/list/")
|
||||
rq := Setup(c, "/uploads")
|
||||
|
||||
params := &ListParams{Apicontext: c.Apicontext}
|
||||
resp, err := rq.R.
|
||||
@@ -245,7 +249,7 @@ func Describe(w io.Writer, c *cfg.Config, args []string) error {
|
||||
|
||||
id := args[0] // we describe only 1 object
|
||||
|
||||
rq := Setup(c, "/upload/"+id+"/")
|
||||
rq := Setup(c, "/uploads/"+id+"/")
|
||||
resp, err := rq.R.Get(rq.Url)
|
||||
|
||||
if err != nil {
|
||||
@@ -266,7 +270,7 @@ func Download(w io.Writer, c *cfg.Config, args []string) error {
|
||||
|
||||
id := args[0]
|
||||
|
||||
rq := Setup(c, "/uploads/"+id+"/")
|
||||
rq := Setup(c, "/uploads/"+id+"/file")
|
||||
|
||||
if !c.Silent {
|
||||
// progres bar
|
||||
@@ -289,6 +293,10 @@ func Download(w io.Writer, c *cfg.Config, args []string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if !resp.IsSuccessState() {
|
||||
return fmt.Errorf("bad response: %s", resp.Status)
|
||||
}
|
||||
|
||||
_, params, err := mime.ParseMediaType(resp.Header.Get("Content-Disposition"))
|
||||
if err != nil {
|
||||
os.Remove(id)
|
||||
|
||||
@@ -33,7 +33,7 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
const endpoint string = "http://localhost:8080/api/v1"
|
||||
const endpoint string = "http://localhost:8080/v1"
|
||||
|
||||
type Unit struct {
|
||||
name string
|
||||
@@ -200,7 +200,7 @@ func TestList(t *testing.T) {
|
||||
name: "list",
|
||||
apikey: "token",
|
||||
wantfail: false,
|
||||
route: "/list/",
|
||||
route: "/uploads",
|
||||
sendcode: 200,
|
||||
sendjson: listing,
|
||||
files: []string{},
|
||||
@@ -211,7 +211,7 @@ func TestList(t *testing.T) {
|
||||
name: "list-catch-empty-json",
|
||||
apikey: "token",
|
||||
wantfail: true,
|
||||
route: "/list/",
|
||||
route: "/uploads",
|
||||
sendcode: 404,
|
||||
sendjson: "",
|
||||
files: []string{},
|
||||
@@ -221,7 +221,7 @@ func TestList(t *testing.T) {
|
||||
name: "list-catch-no-access",
|
||||
apikey: "token",
|
||||
wantfail: true,
|
||||
route: "/list/",
|
||||
route: "/uploads",
|
||||
sendcode: 503,
|
||||
sendjson: listingnoaccess,
|
||||
files: []string{},
|
||||
@@ -261,7 +261,7 @@ func TestDescribe(t *testing.T) {
|
||||
name: "describe",
|
||||
apikey: "token",
|
||||
wantfail: false,
|
||||
route: "/upload/",
|
||||
route: "/uploads/",
|
||||
sendcode: 200,
|
||||
sendjson: listing,
|
||||
files: []string{"cc2c965a"},
|
||||
@@ -272,7 +272,7 @@ func TestDescribe(t *testing.T) {
|
||||
name: "describe-catch-empty-json",
|
||||
apikey: "token",
|
||||
wantfail: true,
|
||||
route: "/upload/",
|
||||
route: "/uploads/",
|
||||
sendcode: 200,
|
||||
sendjson: "",
|
||||
files: []string{"cc2c965a"},
|
||||
@@ -282,7 +282,7 @@ func TestDescribe(t *testing.T) {
|
||||
name: "describe-catch-no-access",
|
||||
apikey: "token",
|
||||
wantfail: true,
|
||||
route: "/upload/",
|
||||
route: "/uploads/",
|
||||
sendcode: 503,
|
||||
sendjson: listingnoaccess,
|
||||
files: []string{"cc2c965a"},
|
||||
@@ -395,7 +395,7 @@ func TestDownload(t *testing.T) {
|
||||
|
||||
for _, unit := range tests {
|
||||
var w bytes.Buffer
|
||||
unit.route += unit.files[0] + "/"
|
||||
unit.route += unit.files[0] + "/file"
|
||||
Intercept(unit)
|
||||
Check(t, unit, &w, Download(&w, conf, unit.files))
|
||||
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
endpoint = "http://localhost:8080/api/v1"
|
||||
endpoint = "http://localhost:8080/v1"
|
||||
apikey = "970b391f22f515d96b3e9b86a2c62c627968828e47b356994d2e583188b4190a"
|
||||
|
||||
Reference in New Issue
Block a user