97 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Go
		
	
	
			
		
		
	
	
			97 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Go
		
	
	
package bugsnag
 | 
						|
 | 
						|
import (
 | 
						|
	"net/http"
 | 
						|
	"strings"
 | 
						|
)
 | 
						|
 | 
						|
type (
 | 
						|
	beforeFunc func(*Event, *Configuration) error
 | 
						|
 | 
						|
	// MiddlewareStacks keep middleware in the correct order. They are
 | 
						|
	// called in reverse order, so if you add a new middleware it will
 | 
						|
	// be called before all existing middleware.
 | 
						|
	middlewareStack struct {
 | 
						|
		before []beforeFunc
 | 
						|
	}
 | 
						|
)
 | 
						|
 | 
						|
// AddMiddleware adds a new middleware to the outside of the existing ones,
 | 
						|
// when the middlewareStack is Run it will be run before all middleware that
 | 
						|
// have been added before.
 | 
						|
func (stack *middlewareStack) OnBeforeNotify(middleware beforeFunc) {
 | 
						|
	stack.before = append(stack.before, middleware)
 | 
						|
}
 | 
						|
 | 
						|
// Run causes all the middleware to be run. If they all permit it the next callback
 | 
						|
// will be called with all the middleware on the stack.
 | 
						|
func (stack *middlewareStack) Run(event *Event, config *Configuration, next func() error) error {
 | 
						|
	// run all the before filters in reverse order
 | 
						|
	for i := range stack.before {
 | 
						|
		before := stack.before[len(stack.before)-i-1]
 | 
						|
 | 
						|
		err := stack.runBeforeFilter(before, event, config)
 | 
						|
		if err != nil {
 | 
						|
			return err
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	return next()
 | 
						|
}
 | 
						|
 | 
						|
func (stack *middlewareStack) runBeforeFilter(f beforeFunc, event *Event, config *Configuration) error {
 | 
						|
	defer func() {
 | 
						|
		if err := recover(); err != nil {
 | 
						|
			config.log("bugsnag/middleware: unexpected panic: %v", err)
 | 
						|
		}
 | 
						|
	}()
 | 
						|
 | 
						|
	return f(event, config)
 | 
						|
}
 | 
						|
 | 
						|
// catchMiddlewarePanic is used to log any panics that happen inside Middleware,
 | 
						|
// we wouldn't want to not notify Bugsnag in this case.
 | 
						|
func catchMiddlewarePanic(event *Event, config *Configuration, next func() error) {
 | 
						|
}
 | 
						|
 | 
						|
// httpRequestMiddleware is added OnBeforeNotify by default. It takes information
 | 
						|
// from an http.Request passed in as rawData, and adds it to the Event. You can
 | 
						|
// use this as a template for writing your own Middleware.
 | 
						|
func httpRequestMiddleware(event *Event, config *Configuration) error {
 | 
						|
	for _, datum := range event.RawData {
 | 
						|
		if request, ok := datum.(*http.Request); ok {
 | 
						|
			proto := "http://"
 | 
						|
			if request.TLS != nil {
 | 
						|
				proto = "https://"
 | 
						|
			}
 | 
						|
 | 
						|
			event.MetaData.Update(MetaData{
 | 
						|
				"Request": {
 | 
						|
					"RemoteAddr": request.RemoteAddr,
 | 
						|
					"Method":     request.Method,
 | 
						|
					"Url":        proto + request.Host + request.RequestURI,
 | 
						|
					"Params":     request.URL.Query(),
 | 
						|
				},
 | 
						|
			})
 | 
						|
 | 
						|
			// Add headers as a separate tab.
 | 
						|
			event.MetaData.AddStruct("Headers", request.Header)
 | 
						|
 | 
						|
			// Default context to Path
 | 
						|
			if event.Context == "" {
 | 
						|
				event.Context = request.URL.Path
 | 
						|
			}
 | 
						|
 | 
						|
			// Default user.id to IP so that users-affected works.
 | 
						|
			if event.User == nil {
 | 
						|
				ip := request.RemoteAddr
 | 
						|
				if idx := strings.LastIndex(ip, ":"); idx != -1 {
 | 
						|
					ip = ip[:idx]
 | 
						|
				}
 | 
						|
				event.User = &User{Id: ip}
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return nil
 | 
						|
}
 |