Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 12 additions & 7 deletions githubapp/dispatcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,10 +134,7 @@ func (d *eventDispatcher) ServeHTTP(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()

// initialize context for SetResponder/GetResponder
// we store a pointer in the context so that functions deeper in the call
// tree can modify the value without creating a new context
var responder func(http.ResponseWriter, *http.Request)
ctx = context.WithValue(ctx, responderKey{}, &responder)
ctx = InitializeResponder(ctx)
r = r.WithContext(ctx)

eventType := r.Header.Get("X-GitHub-Event")
Expand Down Expand Up @@ -216,17 +213,25 @@ func DefaultResponseCallback(w http.ResponseWriter, r *http.Request, event strin

type responderKey struct{}

// InitializeResponder prepares the context to work with SetResponder and
// GetResponder. It is used to test handlers that call SetResponder or to
// implement custom event dispatchers that support responders.
func InitializeResponder(ctx context.Context) context.Context {
var responder func(http.ResponseWriter, *http.Request)
return context.WithValue(ctx, responderKey{}, &responder)
}

// SetResponder sets a function that sends a response to GitHub after event
// processing completes. This function may only be called from event handler
// functions invoked by the event dispatcher.
// processing completes. The context must be initialized by InitializeResponder.
// The event dispatcher does this automatically before calling a handler.
//
// Customizing individual handler responses should be rare. Applications that
// want to modify the standard responses should consider registering a response
// callback before using this function.
func SetResponder(ctx context.Context, responder func(http.ResponseWriter, *http.Request)) {
r, ok := ctx.Value(responderKey{}).(*func(http.ResponseWriter, *http.Request))
if !ok || r == nil {
panic("SetResponder() must be called from an event handler invoked by the go-githubapp event dispatcher")
panic("SetResponder() must be called with an initialized context, such as one from the event dispatcher")
}
*r = responder
}
Expand Down