summaryrefslogtreecommitdiff
path: root/service/http
diff options
context:
space:
mode:
authorWolfy-J <[email protected]>2019-12-23 14:43:47 +0300
committerWolfy-J <[email protected]>2019-12-23 14:43:47 +0300
commitc7b0a4a81827284f7565c56aa476eea34fb6382f (patch)
treeee30e93169c37fb058fbe55af6b3f954eabd9646 /service/http
parent7f694966730f6dac09d0d0ea3bf51276b8e4dfe4 (diff)
- test fixes
Diffstat (limited to 'service/http')
-rw-r--r--service/http/attributes/attributes_test.go20
-rw-r--r--service/http/config.go15
-rw-r--r--service/http/h2c_test.go7
-rw-r--r--service/http/handler.go16
-rw-r--r--service/http/handler_test.go744
-rw-r--r--service/http/request.go9
-rw-r--r--service/http/response.go10
-rw-r--r--service/http/rpc_test.go21
-rw-r--r--service/http/service.go52
-rw-r--r--service/http/service_test.go77
-rw-r--r--service/http/ssl_test.go56
-rw-r--r--service/http/uploads.go43
-rw-r--r--service/http/uploads_test.go196
13 files changed, 1053 insertions, 213 deletions
diff --git a/service/http/attributes/attributes_test.go b/service/http/attributes/attributes_test.go
index a71d6542..2360fd12 100644
--- a/service/http/attributes/attributes_test.go
+++ b/service/http/attributes/attributes_test.go
@@ -10,7 +10,10 @@ func TestAllAttributes(t *testing.T) {
r := &http.Request{}
r = Init(r)
- Set(r, "key", "value")
+ err := Set(r, "key", "value")
+ if err != nil {
+ t.Errorf("error during the Set: error %v", err)
+ }
assert.Equal(t, All(r), map[string]interface{}{
"key": "value",
@@ -34,7 +37,10 @@ func TestGetAttribute(t *testing.T) {
r := &http.Request{}
r = Init(r)
- Set(r, "key", "value")
+ err := Set(r, "key", "value")
+ if err != nil {
+ t.Errorf("error during the Set: error %v", err)
+ }
assert.Equal(t, Get(r, "key"), "value")
}
@@ -55,13 +61,19 @@ func TestSetAttribute(t *testing.T) {
r := &http.Request{}
r = Init(r)
- Set(r, "key", "value")
+ err := Set(r, "key", "value")
+ if err != nil {
+ t.Errorf("error during the Set: error %v", err)
+ }
assert.Equal(t, Get(r, "key"), "value")
}
func TestSetAttributeNone(t *testing.T) {
r := &http.Request{}
- Set(r, "key", "value")
+ err := Set(r, "key", "value")
+ if err != nil {
+ t.Errorf("error during the Set: error %v", err)
+ }
assert.Equal(t, Get(r, "key"), nil)
}
diff --git a/service/http/config.go b/service/http/config.go
index ba3e6300..13a2cfc9 100644
--- a/service/http/config.go
+++ b/service/http/config.go
@@ -126,9 +126,18 @@ func (c *Config) Hydrate(cfg service.Config) error {
c.SSL.Port = 443
}
- c.HTTP2.InitDefaults()
- c.Uploads.InitDefaults()
- c.Workers.InitDefaults()
+ err := c.HTTP2.InitDefaults()
+ if err != nil {
+ return err
+ }
+ err = c.Uploads.InitDefaults()
+ if err != nil {
+ return err
+ }
+ err = c.Workers.InitDefaults()
+ if err != nil {
+ return err
+ }
if err := cfg.Unmarshal(c); err != nil {
return err
diff --git a/service/http/h2c_test.go b/service/http/h2c_test.go
index d806e5ff..e2669845 100644
--- a/service/http/h2c_test.go
+++ b/service/http/h2c_test.go
@@ -49,7 +49,12 @@ func Test_Service_H2C(t *testing.T) {
r, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
- defer r.Body.Close()
+ defer func() {
+ err := r.Body.Close()
+ if err != nil {
+ t.Errorf("fail to close the Body: error %v", err)
+ }
+ }()
assert.Equal(t, "101 Switching Protocols", r.Status)
diff --git a/service/http/handler.go b/service/http/handler.go
index a4da224d..3c667035 100644
--- a/service/http/handler.go
+++ b/service/http/handler.go
@@ -2,6 +2,7 @@ package http
import (
"github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
"github.com/spiral/roadrunner"
"net"
"net/http"
@@ -59,6 +60,7 @@ func (e *ResponseEvent) Elapsed() time.Duration {
// parsed files and query, payload will include parsed form dataTree (if any).
type Handler struct {
cfg *Config
+ log *logrus.Logger
rr *roadrunner.Server
mul sync.Mutex
lsn func(event int, ctx interface{})
@@ -98,8 +100,8 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// proxy IP resolution
h.resolveIP(req)
- req.Open()
- defer req.Close()
+ req.Open(h.log)
+ defer req.Close(h.log)
p, err := req.Payload()
if err != nil {
@@ -120,7 +122,10 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
}
h.handleResponse(req, resp, start)
- resp.Write(w)
+ err = resp.Write(w)
+ if err != nil {
+ h.handleError(w, r, err, start)
+ }
}
// handleError sends error.
@@ -128,7 +133,10 @@ func (h *Handler) handleError(w http.ResponseWriter, r *http.Request, err error,
h.throw(EventError, &ErrorEvent{Request: r, Error: err, start: start, elapsed: time.Since(start)})
w.WriteHeader(500)
- w.Write([]byte(err.Error()))
+ _, err = w.Write([]byte(err.Error()))
+ if err != nil {
+ h.throw(EventError, &ErrorEvent{Request: r, Error: err, start: start, elapsed: time.Since(start)})
+ }
}
// handleResponse triggers response event.
diff --git a/service/http/handler_test.go b/service/http/handler_test.go
index e29b76ac..4efcdd00 100644
--- a/service/http/handler_test.go
+++ b/service/http/handler_test.go
@@ -23,9 +23,15 @@ func get(url string) (string, *http.Response, error) {
if err != nil {
return "", nil, err
}
- defer r.Body.Close()
-
b, err := ioutil.ReadAll(r.Body)
+ if err != nil {
+ return "", nil, err
+ }
+
+ err = r.Body.Close()
+ if err != nil {
+ return "", nil, err
+ }
return string(b), r, err
}
@@ -44,9 +50,16 @@ func getHeader(url string, h map[string]string) (string, *http.Response, error)
if err != nil {
return "", nil, err
}
- defer r.Body.Close()
b, err := ioutil.ReadAll(r.Body)
+ if err != nil {
+ return "", nil, err
+ }
+
+ err = r.Body.Close()
+ if err != nil {
+ return "", nil, err
+ }
return string(b), r, err
}
@@ -74,9 +87,19 @@ func TestHandler_Echo(t *testing.T) {
defer h.rr.Stop()
hs := &http.Server{Addr: ":8177", Handler: h}
- defer hs.Shutdown(context.Background())
+ defer func() {
+ err := hs.Shutdown(context.Background())
+ if err != nil {
+ t.Errorf("error during the shutdown: error %v", err)
+ }
+ }()
- go func() { hs.ListenAndServe() }()
+ go func() {
+ err := hs.ListenAndServe()
+ if err != nil && err != http.ErrServerClosed {
+ t.Errorf("error listening the interface: error %v", err)
+ }
+ }()
time.Sleep(time.Millisecond * 10)
body, r, err := get("http://localhost:8177/?hello=world")
@@ -165,10 +188,20 @@ func TestHandler_Headers(t *testing.T) {
defer h.rr.Stop()
hs := &http.Server{Addr: ":8078", Handler: h}
- defer hs.Shutdown(context.Background())
+ defer func() {
+ err := hs.Shutdown(context.Background())
+ if err != nil {
+ t.Errorf("error during the shutdown: error %v", err)
+ }
+ }()
- go func() { hs.ListenAndServe() }()
- time.Sleep(time.Millisecond * 10)
+ go func() {
+ err := hs.ListenAndServe()
+ if err != nil && err != http.ErrServerClosed {
+ t.Errorf("error listening the interface: error %v", err)
+ }
+ }()
+ time.Sleep(time.Millisecond * 100)
req, err := http.NewRequest("GET", "http://localhost:8078?hello=world", nil)
assert.NoError(t, err)
@@ -177,7 +210,13 @@ func TestHandler_Headers(t *testing.T) {
r, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
- defer r.Body.Close()
+ defer func() {
+ err := r.Body.Close()
+ if err != nil {
+ t.Errorf("error during the closing Body: error %v", err)
+
+ }
+ }()
b, err := ioutil.ReadAll(r.Body)
assert.NoError(t, err)
@@ -212,9 +251,19 @@ func TestHandler_Empty_User_Agent(t *testing.T) {
defer h.rr.Stop()
hs := &http.Server{Addr: ":8088", Handler: h}
- defer hs.Shutdown(context.Background())
+ defer func() {
+ err := hs.Shutdown(context.Background())
+ if err != nil {
+ t.Errorf("error during the shutdown: error %v", err)
+ }
+ }()
- go func() { hs.ListenAndServe() }()
+ go func() {
+ err := hs.ListenAndServe()
+ if err != nil && err != http.ErrServerClosed {
+ t.Errorf("error listening the interface: error %v", err)
+ }
+ }()
time.Sleep(time.Millisecond * 10)
req, err := http.NewRequest("GET", "http://localhost:8088?hello=world", nil)
@@ -224,7 +273,13 @@ func TestHandler_Empty_User_Agent(t *testing.T) {
r, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
- defer r.Body.Close()
+ defer func() {
+ err := r.Body.Close()
+ if err != nil {
+ t.Errorf("error during the closing Body: error %v", err)
+
+ }
+ }()
b, err := ioutil.ReadAll(r.Body)
assert.NoError(t, err)
@@ -258,9 +313,19 @@ func TestHandler_User_Agent(t *testing.T) {
defer h.rr.Stop()
hs := &http.Server{Addr: ":8088", Handler: h}
- defer hs.Shutdown(context.Background())
+ defer func() {
+ err := hs.Shutdown(context.Background())
+ if err != nil {
+ t.Errorf("error during the shutdown: error %v", err)
+ }
+ }()
- go func() { hs.ListenAndServe() }()
+ go func() {
+ err := hs.ListenAndServe()
+ if err != nil && err != http.ErrServerClosed {
+ t.Errorf("error listening the interface: error %v", err)
+ }
+ }()
time.Sleep(time.Millisecond * 10)
req, err := http.NewRequest("GET", "http://localhost:8088?hello=world", nil)
@@ -270,7 +335,13 @@ func TestHandler_User_Agent(t *testing.T) {
r, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
- defer r.Body.Close()
+ defer func() {
+ err := r.Body.Close()
+ if err != nil {
+ t.Errorf("error during the closing Body: error %v", err)
+
+ }
+ }()
b, err := ioutil.ReadAll(r.Body)
assert.NoError(t, err)
@@ -304,9 +375,19 @@ func TestHandler_Cookies(t *testing.T) {
defer h.rr.Stop()
hs := &http.Server{Addr: ":8079", Handler: h}
- defer hs.Shutdown(context.Background())
+ defer func() {
+ err := hs.Shutdown(context.Background())
+ if err != nil {
+ t.Errorf("error during the shutdown: error %v", err)
+ }
+ }()
- go func() { hs.ListenAndServe() }()
+ go func() {
+ err := hs.ListenAndServe()
+ if err != nil && err != http.ErrServerClosed {
+ t.Errorf("error listening the interface: error %v", err)
+ }
+ }()
time.Sleep(time.Millisecond * 10)
req, err := http.NewRequest("GET", "http://localhost:8079", nil)
@@ -316,7 +397,13 @@ func TestHandler_Cookies(t *testing.T) {
r, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
- defer r.Body.Close()
+ defer func() {
+ err := r.Body.Close()
+ if err != nil {
+ t.Errorf("error during the closing Body: error %v", err)
+
+ }
+ }()
b, err := ioutil.ReadAll(r.Body)
assert.NoError(t, err)
@@ -355,9 +442,19 @@ func TestHandler_JsonPayload_POST(t *testing.T) {
defer h.rr.Stop()
hs := &http.Server{Addr: ":8090", Handler: h}
- defer hs.Shutdown(context.Background())
+ defer func() {
+ err := hs.Shutdown(context.Background())
+ if err != nil {
+ t.Errorf("error during the shutdown: error %v", err)
+ }
+ }()
- go func() { hs.ListenAndServe() }()
+ go func() {
+ err := hs.ListenAndServe()
+ if err != nil && err != http.ErrServerClosed {
+ t.Errorf("error listening the interface: error %v", err)
+ }
+ }()
time.Sleep(time.Millisecond * 10)
req, err := http.NewRequest(
@@ -371,7 +468,13 @@ func TestHandler_JsonPayload_POST(t *testing.T) {
r, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
- defer r.Body.Close()
+ defer func() {
+ err := r.Body.Close()
+ if err != nil {
+ t.Errorf("error during the closing Body: error %v", err)
+
+ }
+ }()
b, err := ioutil.ReadAll(r.Body)
assert.NoError(t, err)
@@ -405,9 +508,19 @@ func TestHandler_JsonPayload_PUT(t *testing.T) {
defer h.rr.Stop()
hs := &http.Server{Addr: ":8081", Handler: h}
- defer hs.Shutdown(context.Background())
+ defer func() {
+ err := hs.Shutdown(context.Background())
+ if err != nil {
+ t.Errorf("error during the shutdown: error %v", err)
+ }
+ }()
- go func() { hs.ListenAndServe() }()
+ go func() {
+ err := hs.ListenAndServe()
+ if err != nil && err != http.ErrServerClosed {
+ t.Errorf("error listening the interface: error %v", err)
+ }
+ }()
time.Sleep(time.Millisecond * 10)
req, err := http.NewRequest("PUT", "http://localhost"+hs.Addr, bytes.NewBufferString(`{"key":"value"}`))
@@ -417,7 +530,12 @@ func TestHandler_JsonPayload_PUT(t *testing.T) {
r, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
- defer r.Body.Close()
+ defer func() {
+ err := r.Body.Close()
+ if err != nil {
+ t.Errorf("error during the closing Body: error %v", err)
+ }
+ }()
b, err := ioutil.ReadAll(r.Body)
assert.NoError(t, err)
@@ -451,9 +569,19 @@ func TestHandler_JsonPayload_PATCH(t *testing.T) {
defer h.rr.Stop()
hs := &http.Server{Addr: ":8082", Handler: h}
- defer hs.Shutdown(context.Background())
+ defer func() {
+ err := hs.Shutdown(context.Background())
+ if err != nil {
+ t.Errorf("error during the shutdown: error %v", err)
+ }
+ }()
- go func() { hs.ListenAndServe() }()
+ go func() {
+ err := hs.ListenAndServe()
+ if err != nil && err != http.ErrServerClosed {
+ t.Errorf("error listening the interface: error %v", err)
+ }
+ }()
time.Sleep(time.Millisecond * 10)
req, err := http.NewRequest("PATCH", "http://localhost"+hs.Addr, bytes.NewBufferString(`{"key":"value"}`))
@@ -463,7 +591,13 @@ func TestHandler_JsonPayload_PATCH(t *testing.T) {
r, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
- defer r.Body.Close()
+ defer func() {
+ err := r.Body.Close()
+ if err != nil {
+ t.Errorf("error during the closing Body: error %v", err)
+
+ }
+ }()
b, err := ioutil.ReadAll(r.Body)
assert.NoError(t, err)
@@ -497,9 +631,19 @@ func TestHandler_FormData_POST(t *testing.T) {
defer h.rr.Stop()
hs := &http.Server{Addr: ":8083", Handler: h}
- defer hs.Shutdown(context.Background())
+ defer func() {
+ err := hs.Shutdown(context.Background())
+ if err != nil {
+ t.Errorf("error during the shutdown: error %v", err)
+ }
+ }()
- go func() { hs.ListenAndServe() }()
+ go func() {
+ err := hs.ListenAndServe()
+ if err != nil && err != http.ErrServerClosed {
+ t.Errorf("error listening the interface: error %v", err)
+ }
+ }()
time.Sleep(time.Millisecond * 10)
form := url.Values{}
@@ -520,7 +664,13 @@ func TestHandler_FormData_POST(t *testing.T) {
r, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
- defer r.Body.Close()
+ defer func() {
+ err := r.Body.Close()
+ if err != nil {
+ t.Errorf("error during the closing Body: error %v", err)
+
+ }
+ }()
b, err := ioutil.ReadAll(r.Body)
assert.NoError(t, err)
@@ -555,9 +705,19 @@ func TestHandler_FormData_POST_Overwrite(t *testing.T) {
defer h.rr.Stop()
hs := &http.Server{Addr: ":8083", Handler: h}
- defer hs.Shutdown(context.Background())
+ defer func() {
+ err := hs.Shutdown(context.Background())
+ if err != nil {
+ t.Errorf("error during the shutdown: error %v", err)
+ }
+ }()
- go func() { hs.ListenAndServe() }()
+ go func() {
+ err := hs.ListenAndServe()
+ if err != nil && err != http.ErrServerClosed {
+ t.Errorf("error listening the interface: error %v", err)
+ }
+ }()
time.Sleep(time.Millisecond * 10)
form := url.Values{}
@@ -572,7 +732,13 @@ func TestHandler_FormData_POST_Overwrite(t *testing.T) {
r, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
- defer r.Body.Close()
+ defer func() {
+ err := r.Body.Close()
+ if err != nil {
+ t.Errorf("error during the closing Body: error %v", err)
+
+ }
+ }()
b, err := ioutil.ReadAll(r.Body)
assert.NoError(t, err)
@@ -607,9 +773,19 @@ func TestHandler_FormData_POST_Form_UrlEncoded_Charset(t *testing.T) {
defer h.rr.Stop()
hs := &http.Server{Addr: ":8083", Handler: h}
- defer hs.Shutdown(context.Background())
+ defer func() {
+ err := hs.Shutdown(context.Background())
+ if err != nil {
+ t.Errorf("error during the shutdown: error %v", err)
+ }
+ }()
- go func() { hs.ListenAndServe() }()
+ go func() {
+ err := hs.ListenAndServe()
+ if err != nil && err != http.ErrServerClosed {
+ t.Errorf("error listening the interface: error %v", err)
+ }
+ }()
time.Sleep(time.Millisecond * 10)
form := url.Values{}
@@ -630,7 +806,13 @@ func TestHandler_FormData_POST_Form_UrlEncoded_Charset(t *testing.T) {
r, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
- defer r.Body.Close()
+ defer func() {
+ err := r.Body.Close()
+ if err != nil {
+ t.Errorf("error during the closing Body: error %v", err)
+
+ }
+ }()
b, err := ioutil.ReadAll(r.Body)
assert.NoError(t, err)
@@ -665,9 +847,19 @@ func TestHandler_FormData_PUT(t *testing.T) {
defer h.rr.Stop()
hs := &http.Server{Addr: ":8084", Handler: h}
- defer hs.Shutdown(context.Background())
+ defer func() {
+ err := hs.Shutdown(context.Background())
+ if err != nil {
+ t.Errorf("error during the shutdown: error %v", err)
+ }
+ }()
- go func() { hs.ListenAndServe() }()
+ go func() {
+ err := hs.ListenAndServe()
+ if err != nil && err != http.ErrServerClosed {
+ t.Errorf("error listening the interface: error %v", err)
+ }
+ }()
time.Sleep(time.Millisecond * 10)
form := url.Values{}
@@ -688,7 +880,13 @@ func TestHandler_FormData_PUT(t *testing.T) {
r, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
- defer r.Body.Close()
+ defer func() {
+ err := r.Body.Close()
+ if err != nil {
+ t.Errorf("error during the closing Body: error %v", err)
+
+ }
+ }()
b, err := ioutil.ReadAll(r.Body)
assert.NoError(t, err)
@@ -723,9 +921,19 @@ func TestHandler_FormData_PATCH(t *testing.T) {
defer h.rr.Stop()
hs := &http.Server{Addr: ":8085", Handler: h}
- defer hs.Shutdown(context.Background())
+ defer func() {
+ err := hs.Shutdown(context.Background())
+ if err != nil {
+ t.Errorf("error during the shutdown: error %v", err)
+ }
+ }()
- go func() { hs.ListenAndServe() }()
+ go func() {
+ err := hs.ListenAndServe()
+ if err != nil && err != http.ErrServerClosed {
+ t.Errorf("error listening the interface: error %v", err)
+ }
+ }()
time.Sleep(time.Millisecond * 10)
form := url.Values{}
@@ -746,7 +954,13 @@ func TestHandler_FormData_PATCH(t *testing.T) {
r, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
- defer r.Body.Close()
+ defer func() {
+ err := r.Body.Close()
+ if err != nil {
+ t.Errorf("error during the closing Body: error %v", err)
+
+ }
+ }()
b, err := ioutil.ReadAll(r.Body)
assert.NoError(t, err)
@@ -781,25 +995,72 @@ func TestHandler_Multipart_POST(t *testing.T) {
defer h.rr.Stop()
hs := &http.Server{Addr: ":8019", Handler: h}
- defer hs.Shutdown(context.Background())
+ defer func() {
+ err := hs.Shutdown(context.Background())
+ if err != nil {
+ t.Errorf("error during the shutdown: error %v", err)
+ }
+ }()
- go func() { hs.ListenAndServe() }()
+ go func() {
+ err := hs.ListenAndServe()
+ if err != nil && err != http.ErrServerClosed {
+ t.Errorf("error listening the interface: error %v", err)
+ }
+ }()
time.Sleep(time.Millisecond * 10)
var mb bytes.Buffer
w := multipart.NewWriter(&mb)
- w.WriteField("key", "value")
+ err := w.WriteField("key", "value")
+ if err != nil {
+ t.Errorf("error writing the field: error %v", err)
+ }
+
+ err = w.WriteField("key", "value")
+ if err != nil {
+ t.Errorf("error writing the field: error %v", err)
+ }
+
+ err = w.WriteField("name[]", "name1")
+ if err != nil {
+ t.Errorf("error writing the field: error %v", err)
+ }
+
+ err = w.WriteField("name[]", "name2")
+ if err != nil {
+ t.Errorf("error writing the field: error %v", err)
+ }
+
+ err = w.WriteField("name[]", "name3")
+ if err != nil {
+ t.Errorf("error writing the field: error %v", err)
+ }
+
+ err = w.WriteField("arr[x][y][z]", "y")
+ if err != nil {
+ t.Errorf("error writing the field: error %v", err)
+ }
- w.WriteField("key", "value")
- w.WriteField("name[]", "name1")
- w.WriteField("name[]", "name2")
- w.WriteField("name[]", "name3")
- w.WriteField("arr[x][y][z]", "y")
- w.WriteField("arr[x][y][e]", "f")
- w.WriteField("arr[c]p", "l")
- w.WriteField("arr[c]z", "")
+ err = w.WriteField("arr[x][y][e]", "f")
+ if err != nil {
+ t.Errorf("error writing the field: error %v", err)
+ }
- w.Close()
+ err = w.WriteField("arr[c]p", "l")
+ if err != nil {
+ t.Errorf("error writing the field: error %v", err)
+ }
+
+ err = w.WriteField("arr[c]z", "")
+ if err != nil {
+ t.Errorf("error writing the field: error %v", err)
+ }
+
+ err = w.Close()
+ if err != nil {
+ t.Errorf("error closing the writer: error %v", err)
+ }
req, err := http.NewRequest("POST", "http://localhost"+hs.Addr, &mb)
assert.NoError(t, err)
@@ -808,7 +1069,13 @@ func TestHandler_Multipart_POST(t *testing.T) {
r, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
- defer r.Body.Close()
+ defer func() {
+ err := r.Body.Close()
+ if err != nil {
+ t.Errorf("error during the closing Body: error %v", err)
+
+ }
+ }()
b, err := ioutil.ReadAll(r.Body)
assert.NoError(t, err)
@@ -843,25 +1110,72 @@ func TestHandler_Multipart_PUT(t *testing.T) {
defer h.rr.Stop()
hs := &http.Server{Addr: ":8020", Handler: h}
- defer hs.Shutdown(context.Background())
+ defer func() {
+ err := hs.Shutdown(context.Background())
+ if err != nil {
+ t.Errorf("error during the shutdown: error %v", err)
+ }
+ }()
- go func() { hs.ListenAndServe() }()
+ go func() {
+ err := hs.ListenAndServe()
+ if err != nil && err != http.ErrServerClosed {
+ t.Errorf("error listening the interface: error %v", err)
+ }
+ }()
time.Sleep(time.Millisecond * 10)
var mb bytes.Buffer
w := multipart.NewWriter(&mb)
- w.WriteField("key", "value")
+ err := w.WriteField("key", "value")
+ if err != nil {
+ t.Errorf("error writing the field: error %v", err)
+ }
+
+ err = w.WriteField("key", "value")
+ if err != nil {
+ t.Errorf("error writing the field: error %v", err)
+ }
- w.WriteField("key", "value")
- w.WriteField("name[]", "name1")
- w.WriteField("name[]", "name2")
- w.WriteField("name[]", "name3")
- w.WriteField("arr[x][y][z]", "y")
- w.WriteField("arr[x][y][e]", "f")
- w.WriteField("arr[c]p", "l")
- w.WriteField("arr[c]z", "")
+ err = w.WriteField("name[]", "name1")
+ if err != nil {
+ t.Errorf("error writing the field: error %v", err)
+ }
- w.Close()
+ err = w.WriteField("name[]", "name2")
+ if err != nil {
+ t.Errorf("error writing the field: error %v", err)
+ }
+
+ err = w.WriteField("name[]", "name3")
+ if err != nil {
+ t.Errorf("error writing the field: error %v", err)
+ }
+
+ err = w.WriteField("arr[x][y][z]", "y")
+ if err != nil {
+ t.Errorf("error writing the field: error %v", err)
+ }
+
+ err = w.WriteField("arr[x][y][e]", "f")
+ if err != nil {
+ t.Errorf("error writing the field: error %v", err)
+ }
+
+ err = w.WriteField("arr[c]p", "l")
+ if err != nil {
+ t.Errorf("error writing the field: error %v", err)
+ }
+
+ err = w.WriteField("arr[c]z", "")
+ if err != nil {
+ t.Errorf("error writing the field: error %v", err)
+ }
+
+ err = w.Close()
+ if err != nil {
+ t.Errorf("error closing the writer: error %v", err)
+ }
req, err := http.NewRequest("PUT", "http://localhost"+hs.Addr, &mb)
assert.NoError(t, err)
@@ -870,7 +1184,13 @@ func TestHandler_Multipart_PUT(t *testing.T) {
r, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
- defer r.Body.Close()
+ defer func() {
+ err := r.Body.Close()
+ if err != nil {
+ t.Errorf("error during the closing Body: error %v", err)
+
+ }
+ }()
b, err := ioutil.ReadAll(r.Body)
assert.NoError(t, err)
@@ -905,25 +1225,72 @@ func TestHandler_Multipart_PATCH(t *testing.T) {
defer h.rr.Stop()
hs := &http.Server{Addr: ":8021", Handler: h}
- defer hs.Shutdown(context.Background())
+ defer func() {
+ err := hs.Shutdown(context.Background())
+ if err != nil {
+ t.Errorf("error during the shutdown: error %v", err)
+ }
+ }()
- go func() { hs.ListenAndServe() }()
+ go func() {
+ err := hs.ListenAndServe()
+ if err != nil && err != http.ErrServerClosed {
+ t.Errorf("error listening the interface: error %v", err)
+ }
+ }()
time.Sleep(time.Millisecond * 10)
var mb bytes.Buffer
w := multipart.NewWriter(&mb)
- w.WriteField("key", "value")
+ err := w.WriteField("key", "value")
+ if err != nil {
+ t.Errorf("error writing the field: error %v", err)
+ }
+
+ err = w.WriteField("key", "value")
+ if err != nil {
+ t.Errorf("error writing the field: error %v", err)
+ }
+
+ err = w.WriteField("name[]", "name1")
+ if err != nil {
+ t.Errorf("error writing the field: error %v", err)
+ }
- w.WriteField("key", "value")
- w.WriteField("name[]", "name1")
- w.WriteField("name[]", "name2")
- w.WriteField("name[]", "name3")
- w.WriteField("arr[x][y][z]", "y")
- w.WriteField("arr[x][y][e]", "f")
- w.WriteField("arr[c]p", "l")
- w.WriteField("arr[c]z", "")
+ err = w.WriteField("name[]", "name2")
+ if err != nil {
+ t.Errorf("error writing the field: error %v", err)
+ }
+
+ err = w.WriteField("name[]", "name3")
+ if err != nil {
+ t.Errorf("error writing the field: error %v", err)
+ }
- w.Close()
+ err = w.WriteField("arr[x][y][z]", "y")
+ if err != nil {
+ t.Errorf("error writing the field: error %v", err)
+ }
+
+ err = w.WriteField("arr[x][y][e]", "f")
+ if err != nil {
+ t.Errorf("error writing the field: error %v", err)
+ }
+
+ err = w.WriteField("arr[c]p", "l")
+ if err != nil {
+ t.Errorf("error writing the field: error %v", err)
+ }
+
+ err = w.WriteField("arr[c]z", "")
+ if err != nil {
+ t.Errorf("error writing the field: error %v", err)
+ }
+
+ err = w.Close()
+ if err != nil {
+ t.Errorf("error closing the writer: error %v", err)
+ }
req, err := http.NewRequest("PATCH", "http://localhost"+hs.Addr, &mb)
assert.NoError(t, err)
@@ -932,7 +1299,13 @@ func TestHandler_Multipart_PATCH(t *testing.T) {
r, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
- defer r.Body.Close()
+ defer func() {
+ err := r.Body.Close()
+ if err != nil {
+ t.Errorf("error during the closing Body: error %v", err)
+
+ }
+ }()
b, err := ioutil.ReadAll(r.Body)
assert.NoError(t, err)
@@ -967,9 +1340,19 @@ func TestHandler_Error(t *testing.T) {
defer h.rr.Stop()
hs := &http.Server{Addr: ":8177", Handler: h}
- defer hs.Shutdown(context.Background())
+ defer func() {
+ err := hs.Shutdown(context.Background())
+ if err != nil {
+ t.Errorf("error during the shutdown: error %v", err)
+ }
+ }()
- go func() { hs.ListenAndServe() }()
+ go func() {
+ err := hs.ListenAndServe()
+ if err != nil && err != http.ErrServerClosed {
+ t.Errorf("error listening the interface: error %v", err)
+ }
+ }()
time.Sleep(time.Millisecond * 10)
_, r, err := get("http://localhost:8177/?hello=world")
@@ -1001,9 +1384,19 @@ func TestHandler_Error2(t *testing.T) {
defer h.rr.Stop()
hs := &http.Server{Addr: ":8177", Handler: h}
- defer hs.Shutdown(context.Background())
+ defer func() {
+ err := hs.Shutdown(context.Background())
+ if err != nil {
+ t.Errorf("error during the shutdown: error %v", err)
+ }
+ }()
- go func() { hs.ListenAndServe() }()
+ go func() {
+ err := hs.ListenAndServe()
+ if err != nil && err != http.ErrServerClosed {
+ t.Errorf("error listening the interface: error %v", err)
+ }
+ }()
time.Sleep(time.Millisecond * 10)
_, r, err := get("http://localhost:8177/?hello=world")
@@ -1035,9 +1428,19 @@ func TestHandler_Error3(t *testing.T) {
defer h.rr.Stop()
hs := &http.Server{Addr: ":8177", Handler: h}
- defer hs.Shutdown(context.Background())
+ defer func() {
+ err := hs.Shutdown(context.Background())
+ if err != nil {
+ t.Errorf("error during the shutdown: error %v", err)
+ }
+ }()
- go func() { hs.ListenAndServe() }()
+ go func() {
+ err := hs.ListenAndServe()
+ if err != nil && err != http.ErrServerClosed {
+ t.Errorf("error listening the interface: error %v", err)
+ }
+ }()
time.Sleep(time.Millisecond * 10)
b2 := &bytes.Buffer{}
@@ -1050,7 +1453,13 @@ func TestHandler_Error3(t *testing.T) {
r, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
- defer r.Body.Close()
+ defer func() {
+ err := r.Body.Close()
+ if err != nil {
+ t.Errorf("error during the closing Body: error %v", err)
+
+ }
+ }()
assert.NoError(t, err)
assert.Equal(t, 500, r.StatusCode)
@@ -1080,9 +1489,19 @@ func TestHandler_ResponseDuration(t *testing.T) {
defer h.rr.Stop()
hs := &http.Server{Addr: ":8177", Handler: h}
- defer hs.Shutdown(context.Background())
+ defer func() {
+ err := hs.Shutdown(context.Background())
+ if err != nil {
+ t.Errorf("error during the shutdown: error %v", err)
+ }
+ }()
- go func() { hs.ListenAndServe() }()
+ go func() {
+ err := hs.ListenAndServe()
+ if err != nil && err != http.ErrServerClosed {
+ t.Errorf("error listening the interface: error %v", err)
+ }
+ }()
time.Sleep(time.Millisecond * 10)
gotresp := make(chan interface{})
@@ -1129,9 +1548,19 @@ func TestHandler_ResponseDurationDelayed(t *testing.T) {
defer h.rr.Stop()
hs := &http.Server{Addr: ":8177", Handler: h}
- defer hs.Shutdown(context.Background())
+ defer func() {
+ err := hs.Shutdown(context.Background())
+ if err != nil {
+ t.Errorf("error during the shutdown: error %v", err)
+ }
+ }()
- go func() { hs.ListenAndServe() }()
+ go func() {
+ err := hs.ListenAndServe()
+ if err != nil && err != http.ErrServerClosed {
+ t.Errorf("error listening the interface: error %v", err)
+ }
+ }()
time.Sleep(time.Millisecond * 10)
gotresp := make(chan interface{})
@@ -1178,9 +1607,19 @@ func TestHandler_ErrorDuration(t *testing.T) {
defer h.rr.Stop()
hs := &http.Server{Addr: ":8177", Handler: h}
- defer hs.Shutdown(context.Background())
+ defer func() {
+ err := hs.Shutdown(context.Background())
+ if err != nil {
+ t.Errorf("error during the shutdown: error %v", err)
+ }
+ }()
- go func() { hs.ListenAndServe() }()
+ go func() {
+ err := hs.ListenAndServe()
+ if err != nil && err != http.ErrServerClosed {
+ t.Errorf("error listening the interface: error %v", err)
+ }
+ }()
time.Sleep(time.Millisecond * 10)
goterr := make(chan interface{})
@@ -1231,15 +1670,28 @@ func TestHandler_IP(t *testing.T) {
}),
}
- h.cfg.parseCIDRs()
+ err := h.cfg.parseCIDRs()
+ if err != nil {
+ t.Errorf("error parsing CIDRs: error %v", err)
+ }
assert.NoError(t, h.rr.Start())
defer h.rr.Stop()
hs := &http.Server{Addr: "127.0.0.1:8177", Handler: h}
- defer hs.Shutdown(context.Background())
+ defer func() {
+ err := hs.Shutdown(context.Background())
+ if err != nil {
+ t.Errorf("error during the shutdown: error %v", err)
+ }
+ }()
- go func() { hs.ListenAndServe() }()
+ go func() {
+ err := hs.ListenAndServe()
+ if err != nil && err != http.ErrServerClosed {
+ t.Errorf("error listening the interface: error %v", err)
+ }
+ }()
time.Sleep(time.Millisecond * 10)
body, r, err := get("http://127.0.0.1:8177/")
@@ -1277,15 +1729,28 @@ func TestHandler_XRealIP(t *testing.T) {
}),
}
- h.cfg.parseCIDRs()
+ err := h.cfg.parseCIDRs()
+ if err != nil {
+ t.Errorf("error parsing CIDRs: error %v", err)
+ }
assert.NoError(t, h.rr.Start())
defer h.rr.Stop()
hs := &http.Server{Addr: "127.0.0.1:8177", Handler: h}
- defer hs.Shutdown(context.Background())
+ defer func() {
+ err := hs.Shutdown(context.Background())
+ if err != nil {
+ t.Errorf("error during the shutdown: error %v", err)
+ }
+ }()
- go func() { hs.ListenAndServe() }()
+ go func() {
+ err := hs.ListenAndServe()
+ if err != nil && err != http.ErrServerClosed {
+ t.Errorf("error listening the interface: error %v", err)
+ }
+ }()
time.Sleep(time.Millisecond * 10)
body, r, err := getHeader("http://127.0.0.1:8177/", map[string]string{
@@ -1328,15 +1793,27 @@ func TestHandler_XForwardedFor(t *testing.T) {
}),
}
- h.cfg.parseCIDRs()
-
+ err := h.cfg.parseCIDRs()
+ if err != nil {
+ t.Errorf("error parsing CIDRs: error %v", err)
+ }
assert.NoError(t, h.rr.Start())
defer h.rr.Stop()
hs := &http.Server{Addr: "127.0.0.1:8177", Handler: h}
- defer hs.Shutdown(context.Background())
+ defer func() {
+ err := hs.Shutdown(context.Background())
+ if err != nil {
+ t.Errorf("error during the shutdown: error %v", err)
+ }
+ }()
- go func() { hs.ListenAndServe() }()
+ go func() {
+ err := hs.ListenAndServe()
+ if err != nil && err != http.ErrServerClosed {
+ t.Errorf("error listening the interface: error %v", err)
+ }
+ }()
time.Sleep(time.Millisecond * 10)
body, r, err := getHeader("http://127.0.0.1:8177/", map[string]string{
@@ -1379,15 +1856,27 @@ func TestHandler_XForwardedFor_NotTrustedRemoteIp(t *testing.T) {
}),
}
- h.cfg.parseCIDRs()
-
+ err := h.cfg.parseCIDRs()
+ if err != nil {
+ t.Errorf("error parsing CIDRs: error %v", err)
+ }
assert.NoError(t, h.rr.Start())
defer h.rr.Stop()
hs := &http.Server{Addr: "127.0.0.1:8177", Handler: h}
- defer hs.Shutdown(context.Background())
+ defer func() {
+ err := hs.Shutdown(context.Background())
+ if err != nil {
+ t.Errorf("error during the shutdown: error %v", err)
+ }
+ }()
- go func() { hs.ListenAndServe() }()
+ go func() {
+ err := hs.ListenAndServe()
+ if err != nil && err != http.ErrServerClosed {
+ t.Errorf("error listening the interface: error %v", err)
+ }
+ }()
time.Sleep(time.Millisecond * 10)
body, r, err := getHeader("http://127.0.0.1:8177/", map[string]string{
@@ -1419,13 +1908,26 @@ func BenchmarkHandler_Listen_Echo(b *testing.B) {
}),
}
- h.rr.Start()
+ err := h.rr.Start()
+ if err != nil {
+ b.Errorf("error starting the worker pool: error %v", err)
+ }
defer h.rr.Stop()
hs := &http.Server{Addr: ":8177", Handler: h}
- defer hs.Shutdown(context.Background())
+ defer func() {
+ err := hs.Shutdown(context.Background())
+ if err != nil {
+ b.Errorf("error during the shutdown: error %v", err)
+ }
+ }()
- go func() { hs.ListenAndServe() }()
+ go func() {
+ err := hs.ListenAndServe()
+ if err != nil && err != http.ErrServerClosed {
+ b.Errorf("error listening the interface: error %v", err)
+ }
+ }()
time.Sleep(time.Millisecond * 10)
bb := "WORLD"
@@ -1434,11 +1936,21 @@ func BenchmarkHandler_Listen_Echo(b *testing.B) {
if err != nil {
b.Fail()
}
- defer r.Body.Close()
-
- br, _ := ioutil.ReadAll(r.Body)
- if string(br) != bb {
- b.Fail()
+ // Response might be nil here
+ if r != nil {
+ br, err := ioutil.ReadAll(r.Body)
+ if err != nil {
+ b.Errorf("error reading Body: error %v", err)
+ }
+ if string(br) != bb {
+ b.Fail()
+ }
+ err = r.Body.Close()
+ if err != nil {
+ b.Errorf("error closing the Body: error %v", err)
+ }
+ } else {
+ b.Errorf("got nil response")
}
}
}
diff --git a/service/http/request.go b/service/http/request.go
index 98508342..5d91bfb6 100644
--- a/service/http/request.go
+++ b/service/http/request.go
@@ -3,6 +3,7 @@ package http
import (
"encoding/json"
"fmt"
+ "github.com/sirupsen/logrus"
"github.com/spiral/roadrunner"
"github.com/spiral/roadrunner/service/http/attributes"
"io/ioutil"
@@ -112,21 +113,21 @@ func NewRequest(r *http.Request, cfg *UploadsConfig) (req *Request, err error) {
}
// Open moves all uploaded files to temporary directory so it can be given to php later.
-func (r *Request) Open() {
+func (r *Request) Open(log *logrus.Logger) {
if r.Uploads == nil {
return
}
- r.Uploads.Open()
+ r.Uploads.Open(log)
}
// Close clears all temp file uploads
-func (r *Request) Close() {
+func (r *Request) Close(log *logrus.Logger) {
if r.Uploads == nil {
return
}
- r.Uploads.Clear()
+ r.Uploads.Clear(log)
}
// Payload request marshaled RoadRunner payload based on PSR7 data. values encode method is JSON. Make sure to open
diff --git a/service/http/response.go b/service/http/response.go
index 166ced82..aafaed13 100644
--- a/service/http/response.go
+++ b/service/http/response.go
@@ -36,7 +36,10 @@ func (r *Response) Write(w http.ResponseWriter) error {
p, h := handlePushHeaders(r.Headers)
if pusher, ok := w.(http.Pusher); ok {
for _, v := range p {
- pusher.Push(v, nil)
+ err := pusher.Push(v, nil)
+ if err != nil {
+ return err
+ }
}
}
@@ -50,7 +53,10 @@ func (r *Response) Write(w http.ResponseWriter) error {
w.WriteHeader(r.Status)
if data, ok := r.body.([]byte); ok {
- w.Write(data)
+ _, err := w.Write(data)
+ if err != nil {
+ return err
+ }
}
if rc, ok := r.body.(io.Reader); ok {
diff --git a/service/http/rpc_test.go b/service/http/rpc_test.go
index 669b201c..0e4b2c0a 100644
--- a/service/http/rpc_test.go
+++ b/service/http/rpc_test.go
@@ -49,7 +49,12 @@ func Test_RPC(t *testing.T) {
s2, _ := c.Get(rpc.ID)
rs := s2.(*rpc.Service)
- go func() { c.Serve() }()
+ go func() {
+ err := c.Serve()
+ if err != nil {
+ t.Errorf("error during the Serve: error %v", err)
+ }
+ }()
time.Sleep(time.Millisecond * 100)
defer c.Stop()
@@ -110,7 +115,12 @@ func Test_RPC_Unix(t *testing.T) {
s2, _ := c.Get(rpc.ID)
rs := s2.(*rpc.Service)
- go func() { c.Serve() }()
+ go func() {
+ err := c.Serve()
+ if err != nil {
+ t.Errorf("error during the Serve: error %v", err)
+ }
+ }()
time.Sleep(time.Millisecond * 100)
defer c.Stop()
@@ -164,7 +174,12 @@ func Test_Workers(t *testing.T) {
s2, _ := c.Get(rpc.ID)
rs := s2.(*rpc.Service)
- go func() { c.Serve() }()
+ go func() {
+ err := c.Serve()
+ if err != nil {
+ t.Errorf("error during the Serve: error %v", err)
+ }
+ }()
time.Sleep(time.Millisecond * 100)
defer c.Stop()
diff --git a/service/http/service.go b/service/http/service.go
index 945a12c4..abe7b3a7 100644
--- a/service/http/service.go
+++ b/service/http/service.go
@@ -3,6 +3,7 @@ package http
import (
"context"
"fmt"
+ "github.com/sirupsen/logrus"
"github.com/spiral/roadrunner"
"github.com/spiral/roadrunner/service/env"
"github.com/spiral/roadrunner/service/http/attributes"
@@ -31,6 +32,7 @@ type middleware func(f http.HandlerFunc) http.HandlerFunc
// Service manages rr, http servers.
type Service struct {
cfg *Config
+ log *logrus.Logger
cprod roadrunner.CommandProducer
env env.Environment
lsns []func(event int, ctx interface{})
@@ -66,8 +68,9 @@ func (s *Service) AddListener(l func(event int, ctx interface{})) {
// Init must return configure svc and return true if svc hasStatus enabled. Must return error in case of
// misconfiguration. Services must not be used without proper configuration pushed first.
-func (s *Service) Init(cfg *Config, r *rpc.Service, e env.Environment) (bool, error) {
+func (s *Service) Init(cfg *Config, r *rpc.Service, e env.Environment, log *logrus.Logger) (bool, error) {
s.cfg = cfg
+ s.log = log
s.env = e
if r != nil {
@@ -139,19 +142,34 @@ func (s *Service) Serve() error {
if s.http != nil {
go func() {
- err <- s.http.ListenAndServe()
+ httpErr := s.http.ListenAndServe()
+ if httpErr != nil && httpErr != http.ErrServerClosed {
+ err <- httpErr
+ } else {
+ err <- nil
+ }
}()
}
if s.https != nil {
go func() {
- err <- s.https.ListenAndServeTLS(s.cfg.SSL.Cert, s.cfg.SSL.Key)
+ httpErr := s.https.ListenAndServeTLS(s.cfg.SSL.Cert, s.cfg.SSL.Key)
+ if httpErr != nil && httpErr != http.ErrServerClosed {
+ err <- httpErr
+ } else {
+ err <- nil
+ }
}()
}
if s.fcgi != nil {
go func() {
- err <- s.serveFCGI()
+ httpErr := s.serveFCGI()
+ if httpErr != nil && httpErr != http.ErrServerClosed {
+ err <- httpErr
+ } else {
+ err <- nil
+ }
}()
}
@@ -164,15 +182,35 @@ func (s *Service) Stop() {
defer s.mu.Unlock()
if s.fcgi != nil {
- go s.fcgi.Shutdown(context.Background())
+ go func() {
+ err := s.fcgi.Shutdown(context.Background())
+ if err != nil && err != http.ErrServerClosed {
+ // Stop() error
+ // push error from goroutines to the channel and block unil error or success shutdown or timeout
+ s.log.Error(fmt.Errorf("error shutting down the fcgi server, error: %v", err))
+ return
+ }
+ }()
}
if s.https != nil {
- go s.https.Shutdown(context.Background())
+ go func() {
+ err := s.https.Shutdown(context.Background())
+ if err != nil && err != http.ErrServerClosed {
+ s.log.Error(fmt.Errorf("error shutting down the https server, error: %v", err))
+ return
+ }
+ }()
}
if s.http != nil {
- go s.http.Shutdown(context.Background())
+ go func() {
+ err := s.http.Shutdown(context.Background())
+ if err != nil && err != http.ErrServerClosed {
+ s.log.Error(fmt.Errorf("error shutting down the http server, error: %v", err))
+ return
+ }
+ }()
}
}
diff --git a/service/http/service_test.go b/service/http/service_test.go
index 69cb7003..c4b2c2c4 100644
--- a/service/http/service_test.go
+++ b/service/http/service_test.go
@@ -53,7 +53,8 @@ func Test_Service_NoConfig(t *testing.T) {
c := service.NewContainer(logger)
c.Register(ID, &Service{})
- c.Init(&testCfg{httpCfg: `{"Enable":true}`})
+ err := c.Init(&testCfg{httpCfg: `{"Enable":true}`})
+ assert.Error(t, err)
s, st := c.Get(ID)
assert.NotNil(t, s)
@@ -138,7 +139,12 @@ func Test_Service_Echo(t *testing.T) {
// should do nothing
s.(*Service).Stop()
- go func() { c.Serve() }()
+ go func() {
+ err := c.Serve()
+ if err != nil {
+ t.Errorf("serve error: %v", err)
+ }
+ }()
time.Sleep(time.Millisecond * 100)
defer c.Stop()
@@ -147,7 +153,12 @@ func Test_Service_Echo(t *testing.T) {
r, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
- defer r.Body.Close()
+ defer func() {
+ err := r.Body.Close()
+ if err != nil {
+ t.Errorf("error closing the Body: error %v", err)
+ }
+ }()
b, err := ioutil.ReadAll(r.Body)
assert.NoError(t, err)
@@ -191,7 +202,12 @@ func Test_Service_Env(t *testing.T) {
// should do nothing
s.(*Service).Stop()
- go func() { c.Serve() }()
+ go func() {
+ err := c.Serve()
+ if err != nil {
+ t.Errorf("serve error: %v", err)
+ }
+ }()
time.Sleep(time.Millisecond * 100)
defer c.Stop()
@@ -200,7 +216,12 @@ func Test_Service_Env(t *testing.T) {
r, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
- defer r.Body.Close()
+ defer func() {
+ err := r.Body.Close()
+ if err != nil {
+ t.Errorf("error closing the Body: error %v", err)
+ }
+ }()
b, err := ioutil.ReadAll(r.Body)
assert.NoError(t, err)
@@ -249,7 +270,12 @@ func Test_Service_ErrorEcho(t *testing.T) {
}
})
- go func() { c.Serve() }()
+ go func() {
+ err := c.Serve()
+ if err != nil {
+ t.Errorf("serve error: %v", err)
+ }
+ }()
time.Sleep(time.Millisecond * 100)
defer c.Stop()
@@ -258,7 +284,12 @@ func Test_Service_ErrorEcho(t *testing.T) {
r, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
- defer r.Body.Close()
+ defer func() {
+ err := r.Body.Close()
+ if err != nil {
+ t.Errorf("error closing the Body: error %v", err)
+ }
+ }()
b, err := ioutil.ReadAll(r.Body)
assert.NoError(t, err)
@@ -304,14 +335,22 @@ func Test_Service_Middleware(t *testing.T) {
return func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path == "/halt" {
w.WriteHeader(500)
- w.Write([]byte("halted"))
+ _, err := w.Write([]byte("halted"))
+ if err != nil {
+ t.Errorf("error writing the data to the http reply: error %v", err)
+ }
} else {
f(w, r)
}
}
})
- go func() { c.Serve() }()
+ go func() {
+ err := c.Serve()
+ if err != nil {
+ t.Errorf("serve error: %v", err)
+ }
+ }()
time.Sleep(time.Millisecond * 100)
defer c.Stop()
@@ -320,7 +359,6 @@ func Test_Service_Middleware(t *testing.T) {
r, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
- defer r.Body.Close()
b, err := ioutil.ReadAll(r.Body)
assert.NoError(t, err)
@@ -329,19 +367,27 @@ func Test_Service_Middleware(t *testing.T) {
assert.Equal(t, 201, r.StatusCode)
assert.Equal(t, "WORLD", string(b))
+ err = r.Body.Close()
+ if err != nil {
+ t.Errorf("error closing the Body: error %v", err)
+ }
+
req, err = http.NewRequest("GET", "http://localhost:6029/halt", nil)
assert.NoError(t, err)
r, err = http.DefaultClient.Do(req)
assert.NoError(t, err)
- defer r.Body.Close()
-
b, err = ioutil.ReadAll(r.Body)
assert.NoError(t, err)
assert.NoError(t, err)
assert.Equal(t, 500, r.StatusCode)
assert.Equal(t, "halted", string(b))
+
+ err = r.Body.Close()
+ if err != nil {
+ t.Errorf("error closing the Body: error %v", err)
+ }
}
func Test_Service_Listener(t *testing.T) {
@@ -381,7 +427,12 @@ func Test_Service_Listener(t *testing.T) {
}
})
- go func() { c.Serve() }()
+ go func() {
+ err := c.Serve()
+ if err != nil {
+ t.Errorf("serve error: %v", err)
+ }
+ }()
time.Sleep(time.Millisecond * 100)
c.Stop()
diff --git a/service/http/ssl_test.go b/service/http/ssl_test.go
index 63eb90b1..c9b4d090 100644
--- a/service/http/ssl_test.go
+++ b/service/http/ssl_test.go
@@ -47,7 +47,12 @@ func Test_SSL_Service_Echo(t *testing.T) {
// should do nothing
s.(*Service).Stop()
- go func() { c.Serve() }()
+ go func() {
+ err := c.Serve()
+ if err != nil {
+ t.Errorf("error during the Serve: error %v", err)
+ }
+ }()
time.Sleep(time.Millisecond * 100)
defer c.Stop()
@@ -56,7 +61,12 @@ func Test_SSL_Service_Echo(t *testing.T) {
r, err := sslClient.Do(req)
assert.NoError(t, err)
- defer r.Body.Close()
+ defer func() {
+ err := r.Body.Close()
+ if err != nil {
+ t.Errorf("fail to close the Body: error %v", err)
+ }
+ }()
b, err := ioutil.ReadAll(r.Body)
assert.NoError(t, err)
@@ -93,7 +103,12 @@ func Test_SSL_Service_NoRedirect(t *testing.T) {
// should do nothing
s.(*Service).Stop()
- go func() { c.Serve() }()
+ go func() {
+ err := c.Serve()
+ if err != nil {
+ t.Errorf("error during the Serve: error %v", err)
+ }
+ }()
time.Sleep(time.Millisecond * 100)
defer c.Stop()
@@ -102,7 +117,12 @@ func Test_SSL_Service_NoRedirect(t *testing.T) {
r, err := sslClient.Do(req)
assert.NoError(t, err)
- defer r.Body.Close()
+ defer func() {
+ err := r.Body.Close()
+ if err != nil {
+ t.Errorf("fail to close the Body: error %v", err)
+ }
+ }()
assert.Nil(t, r.TLS)
@@ -142,7 +162,12 @@ func Test_SSL_Service_Redirect(t *testing.T) {
// should do nothing
s.(*Service).Stop()
- go func() { c.Serve() }()
+ go func() {
+ err := c.Serve()
+ if err != nil {
+ t.Errorf("error during the Serve: error %v", err)
+ }
+ }()
time.Sleep(time.Millisecond * 100)
defer c.Stop()
@@ -151,7 +176,12 @@ func Test_SSL_Service_Redirect(t *testing.T) {
r, err := sslClient.Do(req)
assert.NoError(t, err)
- defer r.Body.Close()
+ defer func() {
+ err := r.Body.Close()
+ if err != nil {
+ t.Errorf("fail to close the Body: error %v", err)
+ }
+ }()
assert.NotNil(t, r.TLS)
@@ -191,7 +221,12 @@ func Test_SSL_Service_Push(t *testing.T) {
// should do nothing
s.(*Service).Stop()
- go func() { c.Serve() }()
+ go func() {
+ err := c.Serve()
+ if err != nil {
+ t.Errorf("error during the Serve: error %v", err)
+ }
+ }()
time.Sleep(time.Millisecond * 100)
defer c.Stop()
@@ -200,7 +235,12 @@ func Test_SSL_Service_Push(t *testing.T) {
r, err := sslClient.Do(req)
assert.NoError(t, err)
- defer r.Body.Close()
+ defer func() {
+ err := r.Body.Close()
+ if err != nil {
+ t.Errorf("fail to close the Body: error %v", err)
+ }
+ }()
assert.NotNil(t, r.TLS)
diff --git a/service/http/uploads.go b/service/http/uploads.go
index 7610ab28..8a46f230 100644
--- a/service/http/uploads.go
+++ b/service/http/uploads.go
@@ -2,6 +2,8 @@ package http
import (
"encoding/json"
+ "fmt"
+ "github.com/sirupsen/logrus"
"io"
"io/ioutil"
"mime/multipart"
@@ -45,13 +47,16 @@ func (u *Uploads) MarshalJSON() ([]byte, error) {
// Open moves all uploaded files to temp directory, return error in case of issue with temp directory. File errors
// will be handled individually.
-func (u *Uploads) Open() {
+func (u *Uploads) Open(log *logrus.Logger) {
var wg sync.WaitGroup
for _, f := range u.list {
wg.Add(1)
go func(f *FileUpload) {
defer wg.Done()
- f.Open(u.cfg)
+ err := f.Open(u.cfg)
+ if err != nil && log != nil {
+ log.Error(fmt.Errorf("error opening the file: error %v", err))
+ }
}(f)
}
@@ -59,10 +64,13 @@ func (u *Uploads) Open() {
}
// Clear deletes all temporary files.
-func (u *Uploads) Clear() {
+func (u *Uploads) Clear(log *logrus.Logger) {
for _, f := range u.list {
if f.TempFilename != "" && exists(f.TempFilename) {
- os.Remove(f.TempFilename)
+ err := os.Remove(f.TempFilename)
+ if err != nil && log != nil {
+ log.Error(fmt.Errorf("error removing the file: error %v", err))
+ }
}
}
}
@@ -99,7 +107,13 @@ func NewUpload(f *multipart.FileHeader) *FileUpload {
}
// Open moves file content into temporary file available for PHP.
-func (f *FileUpload) Open(cfg *UploadsConfig) error {
+// NOTE:
+// There is 2 deferred functions, and in case of getting 2 errors from both functions
+// error from close of temp file would be overwritten by error from the main file
+// STACK
+// DEFER FILE CLOSE (2)
+// DEFER TMP CLOSE (1)
+func (f *FileUpload) Open(cfg *UploadsConfig) (err error) {
if cfg.Forbids(f.Name) {
f.Error = UploadErrorExtension
return nil
@@ -110,7 +124,11 @@ func (f *FileUpload) Open(cfg *UploadsConfig) error {
f.Error = UploadErrorNoFile
return err
}
- defer file.Close()
+
+ defer func() {
+ // close the main file
+ err = file.Close()
+ }()
tmp, err := ioutil.TempFile(cfg.TmpDir(), "upload")
if err != nil {
@@ -120,7 +138,10 @@ func (f *FileUpload) Open(cfg *UploadsConfig) error {
}
f.TempFilename = tmp.Name()
- defer tmp.Close()
+ defer func() {
+ // close the temp file
+ err = tmp.Close()
+ }()
if f.Size, err = io.Copy(tmp, file); err != nil {
f.Error = UploadErrorCantWrite
@@ -131,10 +152,8 @@ func (f *FileUpload) Open(cfg *UploadsConfig) error {
// exists if file exists.
func exists(path string) bool {
- _, err := os.Stat(path)
- if err == nil {
- return true
+ if _, err := os.Stat(path); os.IsNotExist(err) {
+ return false
}
-
- return false
+ return true
}
diff --git a/service/http/uploads_test.go b/service/http/uploads_test.go
index 0fbf0e14..1890c02b 100644
--- a/service/http/uploads_test.go
+++ b/service/http/uploads_test.go
@@ -6,6 +6,7 @@ import (
"crypto/md5"
"encoding/hex"
"encoding/json"
+ "fmt"
"github.com/spiral/roadrunner"
"github.com/stretchr/testify/assert"
"io"
@@ -41,22 +42,43 @@ func TestHandler_Upload_File(t *testing.T) {
defer h.rr.Stop()
hs := &http.Server{Addr: ":8021", Handler: h}
- defer hs.Shutdown(context.Background())
-
- go func() { hs.ListenAndServe() }()
+ defer func() {
+ err := hs.Shutdown(context.Background())
+ if err != nil {
+ t.Errorf("error during the shutdown: error %v", err)
+ }
+ }()
+
+ go func() {
+ err := hs.ListenAndServe()
+ if err != nil && err != http.ErrServerClosed {
+ t.Errorf("error listening the interface: error %v", err)
+ }
+ }()
time.Sleep(time.Millisecond * 10)
var mb bytes.Buffer
w := multipart.NewWriter(&mb)
f := mustOpen("uploads_test.go")
- defer f.Close()
+ defer func() {
+ err := f.Close()
+ if err != nil {
+ t.Errorf("failed to close a file: error %v", err)
+ }
+ }()
fw, err := w.CreateFormFile("upload", f.Name())
assert.NotNil(t, fw)
assert.NoError(t, err)
- io.Copy(fw, f)
+ _, err = io.Copy(fw, f)
+ if err != nil {
+ t.Errorf("error copying the file: error %v", err)
+ }
- w.Close()
+ err = w.Close()
+ if err != nil {
+ t.Errorf("error closing the file: error %v", err)
+ }
req, err := http.NewRequest("POST", "http://localhost"+hs.Addr, &mb)
assert.NoError(t, err)
@@ -65,7 +87,12 @@ func TestHandler_Upload_File(t *testing.T) {
r, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
- defer r.Body.Close()
+ defer func() {
+ err := r.Body.Close()
+ if err != nil {
+ t.Errorf("error closing the Body: error %v", err)
+ }
+ }()
b, err := ioutil.ReadAll(r.Body)
assert.NoError(t, err)
@@ -102,22 +129,43 @@ func TestHandler_Upload_NestedFile(t *testing.T) {
defer h.rr.Stop()
hs := &http.Server{Addr: ":8021", Handler: h}
- defer hs.Shutdown(context.Background())
-
- go func() { hs.ListenAndServe() }()
+ defer func() {
+ err := hs.Shutdown(context.Background())
+ if err != nil {
+ t.Errorf("error during the shutdown: error %v", err)
+ }
+ }()
+
+ go func() {
+ err := hs.ListenAndServe()
+ if err != nil && err != http.ErrServerClosed {
+ t.Errorf("error listening the interface: error %v", err)
+ }
+ }()
time.Sleep(time.Millisecond * 10)
var mb bytes.Buffer
w := multipart.NewWriter(&mb)
f := mustOpen("uploads_test.go")
- defer f.Close()
+ defer func() {
+ err := f.Close()
+ if err != nil {
+ t.Errorf("failed to close a file: error %v", err)
+ }
+ }()
fw, err := w.CreateFormFile("upload[x][y][z][]", f.Name())
assert.NotNil(t, fw)
assert.NoError(t, err)
- io.Copy(fw, f)
+ _, err = io.Copy(fw, f)
+ if err != nil {
+ t.Errorf("error copying the file: error %v", err)
+ }
- w.Close()
+ err = w.Close()
+ if err != nil {
+ t.Errorf("error closing the file: error %v", err)
+ }
req, err := http.NewRequest("POST", "http://localhost"+hs.Addr, &mb)
assert.NoError(t, err)
@@ -126,7 +174,12 @@ func TestHandler_Upload_NestedFile(t *testing.T) {
r, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
- defer r.Body.Close()
+ defer func() {
+ err := r.Body.Close()
+ if err != nil {
+ t.Errorf("error closing the Body: error %v", err)
+ }
+ }()
b, err := ioutil.ReadAll(r.Body)
assert.NoError(t, err)
@@ -163,22 +216,43 @@ func TestHandler_Upload_File_NoTmpDir(t *testing.T) {
defer h.rr.Stop()
hs := &http.Server{Addr: ":8021", Handler: h}
- defer hs.Shutdown(context.Background())
-
- go func() { hs.ListenAndServe() }()
+ defer func() {
+ err := hs.Shutdown(context.Background())
+ if err != nil {
+ t.Errorf("error during the shutdown: error %v", err)
+ }
+ }()
+
+ go func() {
+ err := hs.ListenAndServe()
+ if err != nil && err != http.ErrServerClosed {
+ t.Errorf("error listening the interface: error %v", err)
+ }
+ }()
time.Sleep(time.Millisecond * 10)
var mb bytes.Buffer
w := multipart.NewWriter(&mb)
f := mustOpen("uploads_test.go")
- defer f.Close()
+ defer func() {
+ err := f.Close()
+ if err != nil {
+ t.Errorf("failed to close a file: error %v", err)
+ }
+ }()
fw, err := w.CreateFormFile("upload", f.Name())
assert.NotNil(t, fw)
assert.NoError(t, err)
- io.Copy(fw, f)
+ _, err = io.Copy(fw, f)
+ if err != nil {
+ t.Errorf("error copying the file: error %v", err)
+ }
- w.Close()
+ err = w.Close()
+ if err != nil {
+ t.Errorf("error closing the file: error %v", err)
+ }
req, err := http.NewRequest("POST", "http://localhost"+hs.Addr, &mb)
assert.NoError(t, err)
@@ -187,7 +261,12 @@ func TestHandler_Upload_File_NoTmpDir(t *testing.T) {
r, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
- defer r.Body.Close()
+ defer func() {
+ err := r.Body.Close()
+ if err != nil {
+ t.Errorf("error closing the Body: error %v", err)
+ }
+ }()
b, err := ioutil.ReadAll(r.Body)
assert.NoError(t, err)
@@ -224,22 +303,43 @@ func TestHandler_Upload_File_Forbids(t *testing.T) {
defer h.rr.Stop()
hs := &http.Server{Addr: ":8021", Handler: h}
- defer hs.Shutdown(context.Background())
-
- go func() { hs.ListenAndServe() }()
+ defer func() {
+ err := hs.Shutdown(context.Background())
+ if err != nil {
+ t.Errorf("error during the shutdown: error %v", err)
+ }
+ }()
+
+ go func() {
+ err := hs.ListenAndServe()
+ if err != nil && err != http.ErrServerClosed {
+ t.Errorf("error listening the interface: error %v", err)
+ }
+ }()
time.Sleep(time.Millisecond * 10)
var mb bytes.Buffer
w := multipart.NewWriter(&mb)
f := mustOpen("uploads_test.go")
- defer f.Close()
+ defer func() {
+ err := f.Close()
+ if err != nil {
+ t.Errorf("failed to close a file: error %v", err)
+ }
+ }()
fw, err := w.CreateFormFile("upload", f.Name())
assert.NotNil(t, fw)
assert.NoError(t, err)
- io.Copy(fw, f)
+ _, err = io.Copy(fw, f)
+ if err != nil {
+ t.Errorf("error copying the file: error %v", err)
+ }
- w.Close()
+ err = w.Close()
+ if err != nil {
+ t.Errorf("error closing the file: error %v", err)
+ }
req, err := http.NewRequest("POST", "http://localhost"+hs.Addr, &mb)
assert.NoError(t, err)
@@ -248,7 +348,12 @@ func TestHandler_Upload_File_Forbids(t *testing.T) {
r, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
- defer r.Body.Close()
+ defer func() {
+ err := r.Body.Close()
+ if err != nil {
+ t.Errorf("error closing the Body: error %v", err)
+ }
+ }()
b, err := ioutil.ReadAll(r.Body)
assert.NoError(t, err)
@@ -282,28 +387,47 @@ type fInfo struct {
MD5 string `json:"md5,omitempty"`
}
-func fileString(f string, err int, mime string) string {
- s, _ := os.Stat(f)
+func fileString(f string, errNo int, mime string) string {
+ s, err := os.Stat(f)
+ if err != nil {
+ fmt.Println(fmt.Errorf("error stat the file, error: %v", err))
+ }
+
+ ff, err := os.Open(f)
+ if err != nil {
+ fmt.Println(fmt.Errorf("error opening the file, error: %v", err))
+ }
+
+ defer func() {
+ er := ff.Close()
+ if er != nil {
+ fmt.Println(fmt.Errorf("error closing the file, error: %v", er))
+ }
+ }()
- ff, _ := os.Open(f)
- defer ff.Close()
h := md5.New()
- io.Copy(h, ff)
+ _, err = io.Copy(h, ff)
+ if err != nil {
+ fmt.Println(fmt.Errorf("error copying the file, error: %v", err))
+ }
v := &fInfo{
Name: s.Name(),
Size: s.Size(),
- Error: err,
+ Error: errNo,
Mime: mime,
MD5: hex.EncodeToString(h.Sum(nil)),
}
- if err != 0 {
+ if errNo != 0 {
v.MD5 = ""
v.Size = 0
}
- r, _ := json.Marshal(v)
+ r, err := json.Marshal(v)
+ if err != nil {
+ fmt.Println(fmt.Errorf("error marshalling fInfo, error: %v", err))
+ }
return string(r)
}