From 625723d7564b9f85f62d8e50bd5d3792cab02407 Mon Sep 17 00:00:00 2001 From: gjahn <gregor.jahn@bht-berlin.de> Date: Wed, 20 Dec 2023 00:29:40 +0100 Subject: [PATCH] Add HEAD method to obtain MIME type & size w/o actually fetching the data --- README.md | 7 +++++++ routing/routes.go | 17 +++++++++++++++++ routing/routes_test.go | 12 +++++++++++- 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 74b1ca8..6195dd4 100644 --- a/README.md +++ b/README.md @@ -86,6 +86,13 @@ curl \ http://localhost:8080/state/bar ``` +Find out MIME type and size of an entry: +```bash +curl \ + -X HEAD \ + http://localhost:8080/state/bar +``` + Obtain an entry: ```bash curl \ diff --git a/routing/routes.go b/routing/routes.go index 183609f..e69f7d5 100644 --- a/routing/routes.go +++ b/routing/routes.go @@ -194,6 +194,23 @@ func SetRoutes( router *f.App, config *configuration.Config, store state.Store, }) + statePathGroup.Head( "/:name", func( c *f.Ctx ) error { + name := strings.Clone( c.Params( "name" ) ) + existingItem, err := store.Fetch( name ) + if err != nil { + return c.SendStatus( http.StatusInternalServerError ) + } + + if existingItem == nil { + return c.SendStatus( http.StatusNotFound ) + } + + c.Set( "Content-Type", existingItem.MimeType() ) + c.Set( "Content-Length", fmt.Sprintf( "%d", len( existingItem.Data() ) ) ) + return c.SendStatus( http.StatusOK ) + }) + + statePathGroup.Use( "*", func( c *f.Ctx ) error { if method := c.Method(); method == "OPTIONS" { c.Set( "Allow", "GET, PUT, DELETE, OPTIONS" ) diff --git a/routing/routes_test.go b/routing/routes_test.go index 53e7f6a..8e88301 100644 --- a/routing/routes_test.go +++ b/routing/routes_test.go @@ -5,6 +5,7 @@ import ( "fmt" "io" "os" + "strconv" "strings" "time" "math/rand" @@ -167,7 +168,7 @@ func TestState( t *testing.T ){ const statePath2 = "/state/another-test" const statePath2Mime = "application/octet-stream" - const statePath2BodySize = 64 + const statePath2BodySize = 128 statePath2Body := generateRandomBytes( statePath2BodySize ) req := ht.NewRequest( "GET", statePath1, nil ) @@ -211,6 +212,15 @@ func TestState( t *testing.T ){ res, _ = router.Test( req, -1 ) assert.Equal( t, http.StatusCreated, res.StatusCode ) + req = ht.NewRequest( "HEAD", statePath2, nil ) + res, _ = router.Test( req, -1 ) + contentLength, err := strconv.ParseInt( res.Header[ "Content-Length" ][0], 10, 64 ) + assert.Nil( t, err ) + assert.Equal( t, http.StatusOK, res.StatusCode ) + assert.Equal( t, statePath2Mime, res.Header[ "Content-Type" ][0] ) + assert.Equal( t, int64( statePath2BodySize ), contentLength ) + assert.IsType( t, res.Body, http.NoBody ) + req = ht.NewRequest( "GET", statePath2, nil ) res, _ = router.Test( req, -1 ) bodyBytes, err := io.ReadAll( res.Body ) -- GitLab