github.com/mysteriumnetwork/node@v0.0.0-20240516044423-365054f76801/tequilapi/middlewares/http_middlewares.go (about)

     1  /*
     2   * Copyright (C) 2017 The "MysteriumNetwork/node" Authors.
     3   *
     4   * This program is free software: you can redistribute it and/or modify
     5   * it under the terms of the GNU General Public License as published by
     6   * the Free Software Foundation, either version 3 of the License, or
     7   * (at your option) any later version.
     8   *
     9   * This program is distributed in the hope that it will be useful,
    10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12   * GNU General Public License for more details.
    13   *
    14   * You should have received a copy of the GNU General Public License
    15   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    16   */
    17  
    18  package middlewares
    19  
    20  import (
    21  	"net"
    22  	"net/http"
    23  	"strings"
    24  
    25  	"github.com/gin-gonic/gin"
    26  
    27  	"github.com/mysteriumnetwork/node/config"
    28  	"github.com/mysteriumnetwork/node/utils/domain"
    29  )
    30  
    31  // ApplyCacheConfigMiddleware forces no caching policy via "Cache-control" header
    32  func ApplyCacheConfigMiddleware(ctx *gin.Context) {
    33  	ctx.Writer.Header().Set("Cache-control", strings.Join([]string{"no-cache", "no-store", "must-revalidate"}, ", "))
    34  }
    35  
    36  // NewHostFilter returns instance of middleware allowing only requests
    37  // with allowed domains in Host header
    38  func NewHostFilter() func(*gin.Context) {
    39  	whitelist := domain.NewWhitelist(
    40  		strings.Split(config.GetString(config.FlagTequilapiAllowedHostnames), ","))
    41  	return func(c *gin.Context) {
    42  		host := c.Request.Host
    43  		if host == "" {
    44  			return
    45  		}
    46  
    47  		hostname, _, err := net.SplitHostPort(host)
    48  		if err != nil {
    49  			// There was no port, so we assume the address was just a hostname
    50  			hostname = host
    51  		}
    52  
    53  		if net.ParseIP(hostname) != nil {
    54  			return
    55  		}
    56  
    57  		if whitelist.Match(hostname) {
    58  			return
    59  		}
    60  
    61  		c.AbortWithStatus(http.StatusForbidden)
    62  	}
    63  }
    64  
    65  // NewLocalhostOnlyFilter returns instance of middleware allowing only requests
    66  // with local client IP.
    67  func NewLocalhostOnlyFilter() func(*gin.Context) {
    68  	return func(c *gin.Context) {
    69  
    70  		// ClientIP() parses the headers defined in Engine.RemoteIPHeaders if there is
    71  		// so it handles clients behind proxy
    72  		isLocal := net.ParseIP(c.ClientIP()).IsLoopback()
    73  		if isLocal {
    74  			return
    75  		}
    76  
    77  		c.AbortWithStatus(http.StatusForbidden)
    78  	}
    79  }