fix endpoints

This commit is contained in:
2023-03-23 18:44:14 +01:00
parent 3fb66e075d
commit b6dfafd1c1
8 changed files with 59 additions and 51 deletions

View File

@@ -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

View File

@@ -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 {

View File

@@ -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,

View File

@@ -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)
})
}

View File

@@ -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")

View File

@@ -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)

View File

@@ -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))

View File

@@ -1,2 +1,2 @@
endpoint = "http://localhost:8080/api/v1"
endpoint = "http://localhost:8080/v1"
apikey = "970b391f22f515d96b3e9b86a2c62c627968828e47b356994d2e583188b4190a"