()
| 93 | c.Next() |
| 94 | } |
| 95 | } |
| 96 | |
| 97 | func NewRouter() *gin.Engine { |
| 98 | gin.EnableJsonDecoderDisallowUnknownFields() |
| 99 | gin.SetMode(gin.ReleaseMode) |
| 100 | gin.DefaultWriter = nil |
| 101 | router := gin.New() |
| 102 | pprof.Register(router) |
| 103 | router.Use(gin.Recovery()) |
| 104 | corsConf := cors.Config{ |
| 105 | AllowAllOrigins: true, |
| 106 | AllowMethods: []string{"GET", "HEAD"}, |
| 107 | AllowHeaders: []string{`Origin`, `Content-Length`, `Content-Type`, `Authorization`}, |
| 108 | } |
| 109 | router.Use(cors.New(corsConf)) |
| 110 | router.Use(gzip.Gzip(gzip.DefaultCompression)) |
| 111 | router.Use(NewRateLimiter(func(c *gin.Context) { |
| 112 | c.AbortWithStatus(http.StatusTooManyRequests) |
| 113 | })) |
| 114 | |
| 115 | // Crawlable HTML landing page describing the service. |
| 116 | router.GET(`/`, ServeIndex) |
| 117 | |
| 118 | // Machine-readable catalog of every servable token/chain asset URL, plus a robots.txt |
| 119 | // that advertises it. |
| 120 | router.GET(`/sitemap.xml`, ServeSitemap) |
| 121 | router.GET(`/robots.txt`, ServeRobots) |
| 122 | |
| 123 | // Starting with API for node conf copy |
| 124 | router.GET(`api/token/:chainID/:tokenAddress/:filename`, ServeToken) |
| 125 | router.GET(`api/tokens/:chainID/:tokenAddress/:filename`, ServeToken) |
| 126 | router.GET(`api/chain/:chainID/:filename`, ServeChain) |
| 127 | router.GET(`api/chains/:chainID/:filename`, ServeChain) |
| 128 | |
| 129 | // Omitting the /api/ prefix |
| 130 | router.GET(`token/:chainID/:tokenAddress/:filename`, ServeToken) |
| 131 | router.GET(`tokens/:chainID/:tokenAddress/:filename`, ServeToken) |
| 132 | router.GET(`chain/:chainID/:filename`, ServeChain) |
| 133 | router.GET(`chains/:chainID/:filename`, ServeChain) |
| 134 |
no test coverage detected