summaryrefslogtreecommitdiff
path: root/service
diff options
context:
space:
mode:
authorValery Piashchynski <[email protected]>2020-08-27 17:24:52 +0300
committerValery Piashchynski <[email protected]>2020-08-27 17:24:52 +0300
commita7f8371096fce063d64d0ea3e780685a366c537b (patch)
treec7c04e87d0f1b8e655eb652804cb05a2e3873d1a /service
parent9103939fa98de53170d2bf0e8cd74529786d7ab2 (diff)
Issue with broken pipe properly handled
Diffstat (limited to 'service')
-rw-r--r--service/http/handler.go27
-rw-r--r--service/http/response.go16
2 files changed, 34 insertions, 9 deletions
diff --git a/service/http/handler.go b/service/http/handler.go
index ab7c382b..eca05483 100644
--- a/service/http/handler.go
+++ b/service/http/handler.go
@@ -1,15 +1,17 @@
package http
import (
- "github.com/pkg/errors"
- "github.com/sirupsen/logrus"
- "github.com/spiral/roadrunner"
+ "fmt"
"net"
"net/http"
"strconv"
"strings"
"sync"
"time"
+
+ "github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
+ "github.com/spiral/roadrunner"
)
const (
@@ -130,13 +132,22 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// handleError sends error.
func (h *Handler) handleError(w http.ResponseWriter, r *http.Request, err error, start time.Time) {
- h.throw(EventError, &ErrorEvent{Request: r, Error: err, start: start, elapsed: time.Since(start)})
-
- w.WriteHeader(500)
- _, err = w.Write([]byte(err.Error()))
- if err != nil {
+ // if pipe is broken, there is no sense to write the header
+ // in this case we just report about error
+ if err == errEPIPE {
h.throw(EventError, &ErrorEvent{Request: r, Error: err, start: start, elapsed: time.Since(start)})
+ return
}
+ // ResponseWriter is ok, write the error code
+ w.WriteHeader(500)
+ _, err2 := w.Write([]byte(err.Error()))
+ // error during the writing to the ResponseWriter
+ if err2 != nil {
+ // concat original error with ResponseWriter error
+ h.throw(EventError, &ErrorEvent{Request: r, Error: errors.New(fmt.Sprintf("error: %v, during handle this error, ResponseWriter error occurred: %v", err, err2)), start: start, elapsed: time.Since(start)})
+ return
+ }
+ h.throw(EventError, &ErrorEvent{Request: r, Error: err, start: start, elapsed: time.Since(start)})
}
// handleResponse triggers response event.
diff --git a/service/http/response.go b/service/http/response.go
index 0942b3d2..045f56da 100644
--- a/service/http/response.go
+++ b/service/http/response.go
@@ -1,14 +1,21 @@
package http
import (
- json "github.com/json-iterator/go"
+ "errors"
"io"
+ "net"
"net/http"
+ "os"
"strings"
+ "syscall"
+
+ json "github.com/json-iterator/go"
"github.com/spiral/roadrunner"
)
+var errEPIPE = errors.New("EPIPE(32) -> possibly connection reset by peer")
+
// Response handles PSR7 response logic.
type Response struct {
// Status contains response status.
@@ -57,6 +64,13 @@ func (r *Response) Write(w http.ResponseWriter) error {
if data, ok := r.body.([]byte); ok {
_, err := w.Write(data)
if err != nil {
+ if netErr, ok2 := err.(*net.OpError); ok2 {
+ if syscallErr, ok3 := netErr.Err.(*os.SyscallError); ok3 {
+ if syscallErr.Err == syscall.EPIPE {
+ return errEPIPE
+ }
+ }
+ }
return err
}
}