2

I want the home page to stop being available after a post request. Here is my code. Thanks in advance.

package main
import(
    "github.com/gin-contrib/static"
    "github.com/gin-gonic/gin"
)

func main() {
   r := gin.Default()
   r.Use(static.Serve("/", static.LocalFile("./pages/home", true)))
   r.POST("/example", func(c *gin.Context) {
      //here I would like to stop serving the static files on a POST request
   })
   r.Run(":8080")
}

My directory structure

-main.go
-pages
   -home
      -index.html
  • Do you know that your middleware (static file serve) causing infinite redirects? – Ozan Feb 01 '20 at 13:57
  • Could you be more specific about what you mean. –  Feb 01 '20 at 16:08
  • I run your code and browsers tell me ERR_TOO_MANY_REDIRECTS – Ozan Feb 01 '20 at 16:12
  • it works for me, have you made and placed a file a pages directory - I have added the directory structure to make it more clear –  Feb 01 '20 at 17:43
  • I already created the pages directory and `home` file under it as shown in your code. When I visit `http://localhost:8080` it redirects forever. I `go get` the latest versions of the libraries. In your directory structure it has index.html but not in your code. – Ozan Feb 01 '20 at 17:57
  • sorry i made a mistake in the directory tree. you have to make the folders and files as they are not made when adding libraries –  Feb 01 '20 at 18:13

1 Answers1

2

I am not an expert on gin but it is similar to echo so I created a snippet for you to check if it fits your needs.

It looks like it is not possible to detach middleware after attached as discussed here, so my way is to check a global variable for each request to see if the resource is available.

package main

import (
    "net/http"
    "sync/atomic"

    "github.com/gin-contrib/static"
    "github.com/gin-gonic/gin"
)

// using atomic package instead of using mutexes looks better in this scope
var noIndex int32

func indexMiddleware() gin.HandlerFunc {
    hdl := static.Serve("/", static.LocalFile("./pages/home", true))
    return func(c *gin.Context) {
        if atomic.LoadInt32(&noIndex) == 0 {
            hdl(c)
            // if you have additional middlewares, let them run
            c.Next()
            return
        }
        c.AbortWithStatus(http.StatusBadRequest)
    }
}

func main() {
    r := gin.Default()
    r.Use(indexMiddleware())
    r.POST("/example", func(c *gin.Context) {
        atomic.CompareAndSwapInt32(&noIndex, 0, 1)
        c.String(http.StatusOK, "OK")
    })
    r.Run(":8080")
}
Ozan
  • 1,044
  • 1
  • 9
  • 23
  • That works for all request so after that first post you cannot connect and receive the html file. –  Feb 01 '20 at 18:48
  • Yes, all requests are satisfied until a post request to /example end point. – Ozan Feb 01 '20 at 19:03
  • Is it possible only to stop requests to certain users –  Feb 01 '20 at 20:46
  • @JosephGlynn Yes it is possible of course if you have an authentication mechanism. You should know who made the request. HTTP protocol is stateless so, you should be able know clients somehow, e.g. headers, cookies, url parameters, etc. Please check basic http authentication and session management for gin. – Ozan Feb 01 '20 at 20:57