Commit ec9ab173 authored by Luke Champine's avatar Luke Champine Committed by GitHub

Merge pull request #2127 from NebulousLabs/api-close

add cleanCloseHandler: return from http handler immediately if remote hangs up
parents c537ed5f 74c47e9e
......@@ -4,6 +4,7 @@ import (
"encoding/json"
"net/http"
"strings"
"time"
"github.com/NebulousLabs/Sia/build"
"github.com/NebulousLabs/Sia/modules"
......@@ -118,6 +119,32 @@ func RequirePassword(h httprouter.Handle, password string) httprouter.Handle {
}
}
// cleanCloseHandler wraps the entire API, ensuring that underlying conns are
// not leaked if the rmeote end closes the connection before the underlying
// handler finishes.
func cleanCloseHandler(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Close this file handle either when the function completes or when the
// connection is done.
done := make(chan struct{})
go func(w http.ResponseWriter, r *http.Request) {
defer close(done)
next.ServeHTTP(w, r)
}(w, r)
select {
case <-done:
case <-r.Context().Done():
}
// Sanity check - thread should not take more than an hour to return.
select {
case <-done:
case <-time.After(time.Minute * 60):
build.Severe("api call is taking more than 20 minutes to return:", r.URL.Path)
}
})
}
// API encapsulates a collection of modules and implements a http.Handler
// to access their methods.
type API struct {
......@@ -266,7 +293,7 @@ func New(requiredUserAgent string, requiredPassword string, cs modules.Consensus
}
// Apply UserAgent middleware and return the API
api.router = RequireUserAgent(router, requiredUserAgent)
api.router = cleanCloseHandler(RequireUserAgent(router, requiredUserAgent))
return api
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment