Beispiel #1
0
func main() {
	// Log
	core.Use(func(c *core.Context) {
		start := time.Now()
		c.Next()
		log.Printf(" %s  %s  %s", c.Request.Method, c.Request.URL, time.Since(start))
	})

	// Response
	core.Use(func(c *core.Context) {
		fmt.Fprint(c.ResponseWriter, "Hello, World!")
	})

	core.Run()
}
Beispiel #2
0
// Use tells the core to use this handler with the provided options.
func Use(options *Options) {
	fmtOpt := formatCORS(options)
	core.Use(func(c *core.Context) {
		setCORS(c, fmtOpt, func() {
			c.Next()
		})
	})
}
Beispiel #3
0
func use(methods []string, p *pat, handler func(*core.Context, map[string]string)) {
	core.Use(func(c *core.Context) {
		if methodMatch(methods, c) && p.match(c) {
			handler(c, p.parseParams(c))
		} else {
			c.Next()
		}
	})
}
Beispiel #4
0
// Use adds a handler that compress all the compressible responses.
func Use() {
	core.Use(func(c *core.Context) {
		if strings.Contains(c.Request.Header.Get("Accept-Encoding"), "gzip") && len(c.Request.Header.Get("Sec-WebSocket-Key")) == 0 {
			gzw := gzip.NewWriter(c.ResponseWriter)
			defer gzw.Close()
			c.ResponseWriter = compressWriter{gzw, c.ResponseWriter} // Set the new ResponseWriter.
		}
		c.Next()
	})
}
Beispiel #5
0
// Use adds the handler to the default handlers stack.
// It matches locale for client, thanks to matchers.
// Multiple matchers can be used.
// The client locale is set as soon as a matcher is confident.
func Use(matchers ...Matcher) {
	core.Use(func(c *core.Context) {
		for _, m := range matchers {
			if t, conf := m(c); conf != language.No {
				if err := SetClientLocale(c, t); err == nil {
					break
				}
			}
		}
		c.Next()
	})
}
Beispiel #6
0
// Use adds the handler to the default handlers stack.
// Argument maxAge is expressed in seconds and applies to all content (in a production environment only).
func Use(maxAge time.Duration) {
	maxAgeString := fmt.Sprintf("%.f", maxAge.Seconds())
	core.Use(func(c *core.Context) {
		if strings.HasPrefix(c.Request.URL.Path, "/"+assetsDir) {
			if core.Production {
				c.ResponseWriter.Header().Set("Cache-Control", "public, max-age="+maxAgeString)
			}
			http.StripPrefix("/"+assetsDir, fs).ServeHTTP(c.ResponseWriter, c.Request)
		} else {
			c.Next()
		}
	})
}
Beispiel #7
0
// Use adds the handler to the default handlers stack.
// It prints each request/response information (time, duration, status, method, path).
func Use() {
	core.BeforeRun(func() {
		fmt.Printf("%s%s Server running on %s%s%s %s %s\n\n", colors.ResetAll, colors.Reverse, colors.ResetAll, colors.BackgroundMagenta, colors.White, core.Address, colors.ResetAll)
	})

	core.Use(func(c *core.Context) {
		start := time.Now()
		path := c.Request.URL.Path // Keep original request path in case of http.StripPrefix.

		defer func() {
			log.Printf("  %s   %s   %s  %s", fmtDuration(start), fmtStatus(c), fmtMethod(c), fmtPath(path))
		}()
		defer c.Recover()
		c.Next()
	})
}
Beispiel #8
0
// Use adds the handler to the default handlers stack.
// It compress all the compressible responses.
func Use() {
	core.Use(func(c *core.Context) {
		if !strings.Contains(c.Request.Header.Get("Accept-Encoding"), "gzip") || c.Request.Header.Get("Sec-WebSocket-Key") != "" {
			c.Next()
			return
		}

		cw := &compressWriter{
			ResponseWriter: c.ResponseWriter,
			gzipWriter:     gzipPool.Get().(*gzip.Writer),
		}
		c.ResponseWriter = cw
		defer gzipPool.Put(cw.gzipWriter)
		defer cw.close()
		defer c.Recover()

		c.Next()
	})
}
Beispiel #9
0
// Use adds this handler to the stack.
func Use(options *Options) {
	// Panic when options are invalid.
	if options != nil {
		if options.HPKP != nil {
			if _, err := hpkpHeader(options.HPKP); err != nil {
				panic(err)
			}
		}
		if options.HSTS != nil {
			if _, err := hstsHeader(options); err != nil {
				panic(err)
			}
		}
	}

	core.Use(func(c *core.Context) {
		if options != nil {
			if core.Production {
				// Check if host is allowed.
				if len(options.AllowedHosts) > 0 {
					for _, host := range options.AllowedHosts {
						if host == c.Request.URL.Host {
							goto SSLOptions
						}
					}
					http.NotFound(c.ResponseWriter, c.Request)
					return
				}

			SSLOptions:
				isSSL := (c.Request.URL.Scheme == "https" || c.Request.TLS != nil || c.Request.Header.Get("X-Forwarded-Proto") == "https")

				// If wanted, redirect permanently to the secure protocol.
				if !isSSL && options.SSLForced {
					url := c.Request.URL
					url.Scheme = "https"
					http.Redirect(c.ResponseWriter, c.Request, url.String(), http.StatusMovedPermanently)
					return
				}

				// Set HPKP header, but only if connected by SSL and the HPKP options are valid.
				if isSSL && options.HPKP != nil {
					if v, err := hpkpHeader(options.HPKP); err != nil {
						log.Stack(err)
					} else {
						c.ResponseWriter.Header().Set("Public-Key-Pins", v)
					}
				}

				// HSTS header, but only if HSTS options are valid.
				if options.HSTS != nil {
					if v, err := hstsHeader(options); err != nil {
						log.Stack(err)
					} else {
						c.ResponseWriter.Header().Set("Strict-Transport-Security", v)
					}
				}
			}

			// Set Content Security Policy headers.
			if options.CSP != "" {
				c.ResponseWriter.Header().Set("Content-Security-Policy", options.CSP)
				c.ResponseWriter.Header().Set("X-Content-Security-Policy", options.CSP)
				c.ResponseWriter.Header().Set("X-WebKit-CSP", options.CSP)
			}
		}

		// If not explicitly allowed, displaying content inside a frame of a different origin is forbidden.
		if options == nil || !options.FrameAllowed {
			c.ResponseWriter.Header().Set("X-Frame-Options", "SAMEORIGIN")
		}

		// Set some "good practice" default headers.
		c.ResponseWriter.Header().Set("X-Content-Type-Options", "nosniff")
		c.ResponseWriter.Header().Set("X-XSS-Protection", "1; mode=block")

		c.Next()
	})
}