diff options
author | Valery Piashchynski <[email protected]> | 2020-12-21 19:42:23 +0300 |
---|---|---|
committer | Valery Piashchynski <[email protected]> | 2020-12-21 19:42:23 +0300 |
commit | ee8b4075c0f836d698d1ae505c87c17147de447a (patch) | |
tree | 531d980e5bfb94ee39b03952a97e0445f7955409 /plugins/http/tests | |
parent | 0ad45031047bb479e06ce0a0f496c6db9b2641c9 (diff) |
Move plugins to the roadrunner-plugins repository
Diffstat (limited to 'plugins/http/tests')
23 files changed, 0 insertions, 4511 deletions
diff --git a/plugins/http/tests/config_test.go b/plugins/http/tests/config_test.go deleted file mode 100644 index 068bd66e..00000000 --- a/plugins/http/tests/config_test.go +++ /dev/null @@ -1,330 +0,0 @@ -package tests - -//import ( -// "os" -// "testing" -// "time" -// -// json "github.com/json-iterator/go" -// "github.com/stretchr/testify/assert" -//) -// -//type mockCfg struct{ cfg string } -// -//func (cfg *mockCfg) Get(name string) service.Config { return nil } -//func (cfg *mockCfg) Unmarshal(out interface{}) error { -// j := json.ConfigCompatibleWithStandardLibrary -// return j.Unmarshal([]byte(cfg.cfg), out) -//} -// -//func Test_Config_Hydrate_Error1(t *testing.T) { -// cfg := &mockCfg{`{"address": "localhost:8080"}`} -// c := &Config{} -// -// assert.NoError(t, c.Hydrate(cfg)) -//} -// -//func Test_Config_Hydrate_Error2(t *testing.T) { -// cfg := &mockCfg{`{"dir": "/dir/"`} -// c := &Config{} -// -// assert.Error(t, c.Hydrate(cfg)) -//} -// -//func Test_Config_Valid(t *testing.T) { -// cfg := &Config{ -// Address: ":8080", -// MaxRequestSize: 1024, -// HTTP2: &HTTP2Config{ -// Enabled: true, -// }, -// Uploads: &UploadsConfig{ -// Dir: os.TempDir(), -// Forbid: []string{".go"}, -// }, -// Workers: &roadrunner.ServerConfig{ -// Command: "php tests/client.php echo pipes", -// Relay: "pipes", -// Pool: &roadrunner.Config{ -// NumWorkers: 1, -// AllocateTimeout: time.Second, -// DestroyTimeout: time.Second, -// }, -// }, -// } -// -// assert.NoError(t, cfg.Valid()) -//} -// -//func Test_Trusted_Subnets(t *testing.T) { -// cfg := &Config{ -// Address: ":8080", -// MaxRequestSize: 1024, -// Uploads: &UploadsConfig{ -// Dir: os.TempDir(), -// Forbid: []string{".go"}, -// }, -// HTTP2: &HTTP2Config{ -// Enabled: true, -// }, -// TrustedSubnets: []string{"200.1.0.0/16"}, -// Workers: &roadrunner.ServerConfig{ -// Command: "php tests/client.php echo pipes", -// Relay: "pipes", -// Pool: &roadrunner.Config{ -// NumWorkers: 1, -// AllocateTimeout: time.Second, -// DestroyTimeout: time.Second, -// }, -// }, -// } -// -// assert.NoError(t, cfg.parseCIDRs()) -// -// assert.True(t, cfg.IsTrusted("200.1.0.10")) -// assert.False(t, cfg.IsTrusted("127.0.0.0.1")) -//} -// -//func Test_Trusted_Subnets_Err(t *testing.T) { -// cfg := &Config{ -// Address: ":8080", -// MaxRequestSize: 1024, -// Uploads: &UploadsConfig{ -// Dir: os.TempDir(), -// Forbid: []string{".go"}, -// }, -// HTTP2: &HTTP2Config{ -// Enabled: true, -// }, -// TrustedSubnets: []string{"200.1.0.0"}, -// Workers: &roadrunner.ServerConfig{ -// Command: "php tests/client.php echo pipes", -// Relay: "pipes", -// Pool: &roadrunner.Config{ -// NumWorkers: 1, -// AllocateTimeout: time.Second, -// DestroyTimeout: time.Second, -// }, -// }, -// } -// -// assert.Error(t, cfg.parseCIDRs()) -//} -// -//func Test_Config_Valid_SSL(t *testing.T) { -// cfg := &Config{ -// Address: ":8080", -// SSL: SSLConfig{ -// Cert: "fixtures/server.crt", -// Key: "fixtures/server.key", -// }, -// MaxRequestSize: 1024, -// Uploads: &UploadsConfig{ -// Dir: os.TempDir(), -// Forbid: []string{".go"}, -// }, -// HTTP2: &HTTP2Config{ -// Enabled: true, -// }, -// Workers: &roadrunner.ServerConfig{ -// Command: "php tests/client.php echo pipes", -// Relay: "pipes", -// Pool: &roadrunner.Config{ -// NumWorkers: 1, -// AllocateTimeout: time.Second, -// DestroyTimeout: time.Second, -// }, -// }, -// } -// -// assert.Error(t, cfg.Hydrate(&testCfg{httpCfg: "{}"})) -// -// assert.NoError(t, cfg.Valid()) -// assert.True(t, cfg.EnableTLS()) -// assert.Equal(t, 443, cfg.SSL.Port) -//} -// -//func Test_Config_SSL_No_key(t *testing.T) { -// cfg := &Config{ -// Address: ":8080", -// SSL: SSLConfig{ -// Cert: "fixtures/server.crt", -// }, -// MaxRequestSize: 1024, -// Uploads: &UploadsConfig{ -// Dir: os.TempDir(), -// Forbid: []string{".go"}, -// }, -// HTTP2: &HTTP2Config{ -// Enabled: true, -// }, -// Workers: &roadrunner.ServerConfig{ -// Command: "php tests/client.php echo pipes", -// Relay: "pipes", -// Pool: &roadrunner.Config{ -// NumWorkers: 1, -// AllocateTimeout: time.Second, -// DestroyTimeout: time.Second, -// }, -// }, -// } -// -// assert.Error(t, cfg.Valid()) -//} -// -//func Test_Config_SSL_No_Cert(t *testing.T) { -// cfg := &Config{ -// Address: ":8080", -// SSL: SSLConfig{ -// Key: "fixtures/server.key", -// }, -// MaxRequestSize: 1024, -// Uploads: &UploadsConfig{ -// Dir: os.TempDir(), -// Forbid: []string{".go"}, -// }, -// HTTP2: &HTTP2Config{ -// Enabled: true, -// }, -// Workers: &roadrunner.ServerConfig{ -// Command: "php tests/client.php echo pipes", -// Relay: "pipes", -// Pool: &roadrunner.Config{ -// NumWorkers: 1, -// AllocateTimeout: time.Second, -// DestroyTimeout: time.Second, -// }, -// }, -// } -// -// assert.Error(t, cfg.Valid()) -//} -// -//func Test_Config_NoUploads(t *testing.T) { -// cfg := &Config{ -// Address: ":8080", -// MaxRequestSize: 1024, -// HTTP2: &HTTP2Config{ -// Enabled: true, -// }, -// Workers: &roadrunner.ServerConfig{ -// Command: "php tests/client.php echo pipes", -// Relay: "pipes", -// Pool: &roadrunner.Config{ -// NumWorkers: 1, -// AllocateTimeout: time.Second, -// DestroyTimeout: time.Second, -// }, -// }, -// } -// -// assert.Error(t, cfg.Valid()) -//} -// -//func Test_Config_NoHTTP2(t *testing.T) { -// cfg := &Config{ -// Address: ":8080", -// MaxRequestSize: 1024, -// Uploads: &UploadsConfig{ -// Dir: os.TempDir(), -// Forbid: []string{".go"}, -// }, -// Workers: &roadrunner.ServerConfig{ -// Command: "php tests/client.php echo pipes", -// Relay: "pipes", -// Pool: &roadrunner.Config{ -// NumWorkers: 0, -// AllocateTimeout: time.Second, -// DestroyTimeout: time.Second, -// }, -// }, -// } -// -// assert.Error(t, cfg.Valid()) -//} -// -//func Test_Config_NoWorkers(t *testing.T) { -// cfg := &Config{ -// Address: ":8080", -// MaxRequestSize: 1024, -// HTTP2: &HTTP2Config{ -// Enabled: true, -// }, -// Uploads: &UploadsConfig{ -// Dir: os.TempDir(), -// Forbid: []string{".go"}, -// }, -// } -// -// assert.Error(t, cfg.Valid()) -//} -// -//func Test_Config_NoPool(t *testing.T) { -// cfg := &Config{ -// Address: ":8080", -// MaxRequestSize: 1024, -// Uploads: &UploadsConfig{ -// Dir: os.TempDir(), -// Forbid: []string{".go"}, -// }, -// HTTP2: &HTTP2Config{ -// Enabled: true, -// }, -// Workers: &roadrunner.ServerConfig{ -// Command: "php tests/client.php echo pipes", -// Relay: "pipes", -// Pool: &roadrunner.Config{ -// NumWorkers: 0, -// AllocateTimeout: time.Second, -// DestroyTimeout: time.Second, -// }, -// }, -// } -// -// assert.Error(t, cfg.Valid()) -//} -// -//func Test_Config_DeadPool(t *testing.T) { -// cfg := &Config{ -// Address: ":8080", -// MaxRequestSize: 1024, -// Uploads: &UploadsConfig{ -// Dir: os.TempDir(), -// Forbid: []string{".go"}, -// }, -// HTTP2: &HTTP2Config{ -// Enabled: true, -// }, -// Workers: &roadrunner.ServerConfig{ -// Command: "php tests/client.php echo pipes", -// Relay: "pipes", -// }, -// } -// -// assert.Error(t, cfg.Valid()) -//} -// -//func Test_Config_InvalidAddress(t *testing.T) { -// cfg := &Config{ -// Address: "unexpected_address", -// MaxRequestSize: 1024, -// Uploads: &UploadsConfig{ -// Dir: os.TempDir(), -// Forbid: []string{".go"}, -// }, -// HTTP2: &HTTP2Config{ -// Enabled: true, -// }, -// Workers: &roadrunner.ServerConfig{ -// Command: "php tests/client.php echo pipes", -// Relay: "pipes", -// Pool: &roadrunner.Config{ -// NumWorkers: 1, -// AllocateTimeout: time.Second, -// DestroyTimeout: time.Second, -// }, -// }, -// } -// -// assert.Error(t, cfg.Valid()) -//} diff --git a/plugins/http/tests/configs/.rr-broken-pipes.yaml b/plugins/http/tests/configs/.rr-broken-pipes.yaml deleted file mode 100644 index e57d0b86..00000000 --- a/plugins/http/tests/configs/.rr-broken-pipes.yaml +++ /dev/null @@ -1,31 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - disabled: false - -server: - command: "php ../../../tests/http/client.php broken pipes" - user: "" - group: "" - env: - "RR_HTTP": "true" - relay: "pipes" - relayTimeout: "20s" - -http: - debug: true - address: 127.0.0.1:12384 - maxRequestSize: 1024 - middleware: [ "" ] - uploads: - forbid: [ ".php", ".exe", ".bat" ] - trustedSubnets: [ "10.0.0.0/8", "127.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "::1/128", "fc00::/7", "fe80::/10" ] - pool: - numWorkers: 2 - maxJobs: 0 - allocateTimeout: 60s - destroyTimeout: 60s -logs: - mode: development - level: error - - diff --git a/plugins/http/tests/configs/.rr-echoErr.yaml b/plugins/http/tests/configs/.rr-echoErr.yaml deleted file mode 100644 index 24946c88..00000000 --- a/plugins/http/tests/configs/.rr-echoErr.yaml +++ /dev/null @@ -1,30 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - disabled: false - -server: - command: "php ../../../tests/http/client.php echoerr pipes" - user: "" - group: "" - env: - "RR_HTTP": "true" - relay: "pipes" - relayTimeout: "20s" - -http: - debug: true - address: 127.0.0.1:8080 - maxRequestSize: 1024 - middleware: [ "pluginMiddleware", "pluginMiddleware2" ] - uploads: - forbid: [ "" ] - trustedSubnets: [ "10.0.0.0/8", "127.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "::1/128", "fc00::/7", "fe80::/10" ] - pool: - numWorkers: 2 - maxJobs: 0 - allocateTimeout: 60s - destroyTimeout: 60s -logs: - mode: development - level: error - diff --git a/plugins/http/tests/configs/.rr-env.yaml b/plugins/http/tests/configs/.rr-env.yaml deleted file mode 100644 index e29f66cc..00000000 --- a/plugins/http/tests/configs/.rr-env.yaml +++ /dev/null @@ -1,33 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - disabled: false - -server: - command: "php ../../../tests/http/client.php env pipes" - user: "" - group: "" - env: - "env_key": "ENV_VALUE" - relay: "pipes" - relayTimeout: "20s" - -http: - debug: true - address: 127.0.0.1:12084 - maxRequestSize: 1024 - middleware: [ "" ] - env: - "RR_HTTP": "true" - "env_key": "ENV_VALUE" - uploads: - forbid: [ ".php", ".exe", ".bat" ] - trustedSubnets: [ "10.0.0.0/8", "127.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "::1/128", "fc00::/7", "fe80::/10" ] - pool: - numWorkers: 2 - maxJobs: 0 - allocateTimeout: 60s - destroyTimeout: 60s -logs: - mode: development - level: error - diff --git a/plugins/http/tests/configs/.rr-fcgi-reqUri.yaml b/plugins/http/tests/configs/.rr-fcgi-reqUri.yaml deleted file mode 100644 index 3009c30e..00000000 --- a/plugins/http/tests/configs/.rr-fcgi-reqUri.yaml +++ /dev/null @@ -1,38 +0,0 @@ -server: - command: "php ../../../tests/http/client.php request-uri pipes" - user: "" - group: "" - env: - "RR_HTTP": "true" - relay: "pipes" - relayTimeout: "20s" - -http: - debug: true - address: :8082 - maxRequestSize: 1024 - middleware: [ "" ] - uploads: - forbid: [ ".php", ".exe", ".bat" ] - trustedSubnets: [ "10.0.0.0/8", "127.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "::1/128", "fc00::/7", "fe80::/10" ] - pool: - numWorkers: 1 - maxJobs: 0 - allocateTimeout: 60s - destroyTimeout: 60s - - ssl: - port: 8890 - redirect: false - cert: fixtures/server.crt - key: fixtures/server.key - # rootCa: root.crt - fcgi: - address: tcp://127.0.0.1:6921 - http2: - enabled: false - h2c: false - maxConcurrentStreams: 128 -logs: - mode: development - level: error
\ No newline at end of file diff --git a/plugins/http/tests/configs/.rr-fcgi.yaml b/plugins/http/tests/configs/.rr-fcgi.yaml deleted file mode 100644 index 45b6dbd0..00000000 --- a/plugins/http/tests/configs/.rr-fcgi.yaml +++ /dev/null @@ -1,38 +0,0 @@ -server: - command: "php ../../../tests/http/client.php echo pipes" - user: "" - group: "" - env: - "RR_HTTP": "true" - relay: "pipes" - relayTimeout: "20s" - -http: - debug: true - address: :8081 - maxRequestSize: 1024 - middleware: [ "" ] - uploads: - forbid: [ ".php", ".exe", ".bat" ] - trustedSubnets: [ "10.0.0.0/8", "127.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "::1/128", "fc00::/7", "fe80::/10" ] - pool: - numWorkers: 1 - maxJobs: 0 - allocateTimeout: 60s - destroyTimeout: 60s - - ssl: - port: 8889 - redirect: false - cert: fixtures/server.crt - key: fixtures/server.key - # rootCa: root.crt - fcgi: - address: tcp://0.0.0.0:6920 - http2: - enabled: false - h2c: false - maxConcurrentStreams: 128 -logs: - mode: development - level: error
\ No newline at end of file diff --git a/plugins/http/tests/configs/.rr-h2c.yaml b/plugins/http/tests/configs/.rr-h2c.yaml deleted file mode 100644 index cc42e3bf..00000000 --- a/plugins/http/tests/configs/.rr-h2c.yaml +++ /dev/null @@ -1,29 +0,0 @@ -server: - command: "php ../../../tests/http/client.php echo pipes" - user: "" - group: "" - env: - "RR_HTTP": "true" - relay: "pipes" - relayTimeout: "20s" - -http: - debug: true - address: :8083 - maxRequestSize: 1024 - middleware: [ "" ] - uploads: - forbid: [ ".php", ".exe", ".bat" ] - trustedSubnets: [ "10.0.0.0/8", "127.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "::1/128", "fc00::/7", "fe80::/10" ] - pool: - numWorkers: 1 - maxJobs: 0 - allocateTimeout: 60s - destroyTimeout: 60s - http2: - enabled: true - h2c: true - maxConcurrentStreams: 128 -logs: - mode: development - level: error
\ No newline at end of file diff --git a/plugins/http/tests/configs/.rr-http.yaml b/plugins/http/tests/configs/.rr-http.yaml deleted file mode 100644 index e2e361cf..00000000 --- a/plugins/http/tests/configs/.rr-http.yaml +++ /dev/null @@ -1,31 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - disabled: false - -server: - command: "php ../../../tests/http/client.php echo pipes" - user: "" - group: "" - env: - "RR_HTTP": "true" - relay: "pipes" - relayTimeout: "20s" - -http: - debug: true - address: 127.0.0.1:18903 - maxRequestSize: 1024 - middleware: [ "pluginMiddleware", "pluginMiddleware2" ] - uploads: - forbid: [ ".php", ".exe", ".bat" ] - trustedSubnets: [ "10.0.0.0/8", "127.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "::1/128", "fc00::/7", "fe80::/10" ] - pool: - numWorkers: 2 - maxJobs: 0 - allocateTimeout: 60s - destroyTimeout: 60s -logs: - mode: development - level: error - - diff --git a/plugins/http/tests/configs/.rr-init.yaml b/plugins/http/tests/configs/.rr-init.yaml deleted file mode 100644 index 70b9642b..00000000 --- a/plugins/http/tests/configs/.rr-init.yaml +++ /dev/null @@ -1,43 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - disabled: false - -server: - command: "php ../../../tests/http/client.php echo pipes" - user: "" - group: "" - env: - "RR_HTTP": "true" - relay: "pipes" - relayTimeout: "20s" - -http: - debug: true - address: 127.0.0.1:15395 - maxRequestSize: 1024 - middleware: [ "" ] - uploads: - forbid: [ ".php", ".exe", ".bat" ] - trustedSubnets: [ "10.0.0.0/8", "127.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "::1/128", "fc00::/7", "fe80::/10" ] - pool: - numWorkers: 2 - maxJobs: 0 - allocateTimeout: 60s - destroyTimeout: 60s - - ssl: - port: 8892 - redirect: false - cert: fixtures/server.crt - key: fixtures/server.key - # rootCa: root.crt - fcgi: - address: tcp://0.0.0.0:7921 - http2: - enabled: false - h2c: false - maxConcurrentStreams: 128 -logs: - mode: development - level: error - diff --git a/plugins/http/tests/configs/.rr-resetter.yaml b/plugins/http/tests/configs/.rr-resetter.yaml deleted file mode 100644 index f2134812..00000000 --- a/plugins/http/tests/configs/.rr-resetter.yaml +++ /dev/null @@ -1,30 +0,0 @@ -rpc: - listen: tcp://127.0.0.1:6001 - disabled: false - -server: - command: "php ../../../tests/http/client.php echo pipes" - user: "" - group: "" - env: - "RR_HTTP": "true" - relay: "pipes" - relayTimeout: "20s" - -http: - debug: true - address: 127.0.0.1:10084 - maxRequestSize: 1024 - middleware: [ "" ] - uploads: - forbid: [ ".php", ".exe", ".bat" ] - trustedSubnets: [ "10.0.0.0/8", "127.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "::1/128", "fc00::/7", "fe80::/10" ] - pool: - numWorkers: 2 - maxJobs: 0 - allocateTimeout: 60s - destroyTimeout: 60s -logs: - mode: development - level: error - diff --git a/plugins/http/tests/configs/.rr-ssl-push.yaml b/plugins/http/tests/configs/.rr-ssl-push.yaml deleted file mode 100644 index 3aea683c..00000000 --- a/plugins/http/tests/configs/.rr-ssl-push.yaml +++ /dev/null @@ -1,31 +0,0 @@ -server: - command: "php ../../../tests/http/client.php push pipes" - user: "" - group: "" - env: - "RR_HTTP": "true" - relay: "pipes" - relayTimeout: "20s" - -http: - debug: true - address: :8086 - maxRequestSize: 1024 - middleware: [ "" ] - uploads: - forbid: [ ".php", ".exe", ".bat" ] - trustedSubnets: [ "10.0.0.0/8", "127.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "::1/128", "fc00::/7", "fe80::/10" ] - pool: - numWorkers: 1 - maxJobs: 0 - allocateTimeout: 60s - destroyTimeout: 60s - - ssl: - port: 8894 - redirect: true - cert: fixtures/server.crt - key: fixtures/server.key -logs: - mode: development - level: error
\ No newline at end of file diff --git a/plugins/http/tests/configs/.rr-ssl-redirect.yaml b/plugins/http/tests/configs/.rr-ssl-redirect.yaml deleted file mode 100644 index 4d889734..00000000 --- a/plugins/http/tests/configs/.rr-ssl-redirect.yaml +++ /dev/null @@ -1,31 +0,0 @@ -server: - command: "php ../../../tests/http/client.php echo pipes" - user: "" - group: "" - env: - "RR_HTTP": "true" - relay: "pipes" - relayTimeout: "20s" - -http: - debug: true - address: :8087 - maxRequestSize: 1024 - middleware: [ "" ] - uploads: - forbid: [ ".php", ".exe", ".bat" ] - trustedSubnets: [ "10.0.0.0/8", "127.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "::1/128", "fc00::/7", "fe80::/10" ] - pool: - numWorkers: 1 - maxJobs: 0 - allocateTimeout: 60s - destroyTimeout: 60s - - ssl: - port: 8895 - redirect: true - cert: fixtures/server.crt - key: fixtures/server.key -logs: - mode: development - level: error
\ No newline at end of file diff --git a/plugins/http/tests/configs/.rr-ssl.yaml b/plugins/http/tests/configs/.rr-ssl.yaml deleted file mode 100644 index 83b5a2dc..00000000 --- a/plugins/http/tests/configs/.rr-ssl.yaml +++ /dev/null @@ -1,38 +0,0 @@ -server: - command: "php ../../../tests/http/client.php echo pipes" - user: "" - group: "" - env: - "RR_HTTP": "true" - relay: "pipes" - relayTimeout: "20s" - -http: - debug: true - address: :8085 - maxRequestSize: 1024 - middleware: [ "" ] - uploads: - forbid: [ ".php", ".exe", ".bat" ] - trustedSubnets: [ "10.0.0.0/8", "127.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "::1/128", "fc00::/7", "fe80::/10" ] - pool: - numWorkers: 1 - maxJobs: 0 - allocateTimeout: 60s - destroyTimeout: 60s - - ssl: - port: 8893 - redirect: false - cert: fixtures/server.crt - key: fixtures/server.key - # rootCa: root.crt - fcgi: - address: tcp://0.0.0.0:16920 - http2: - enabled: false - h2c: false - maxConcurrentStreams: 128 -logs: - mode: development - level: error
\ No newline at end of file diff --git a/plugins/http/tests/fixtures/server.crt b/plugins/http/tests/fixtures/server.crt deleted file mode 100644 index 24d67fd7..00000000 --- a/plugins/http/tests/fixtures/server.crt +++ /dev/null @@ -1,15 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICTTCCAdOgAwIBAgIJAOKyUd+llTRKMAoGCCqGSM49BAMCMGMxCzAJBgNVBAYT -AlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4gRnJhbmNpc2Nv -MRMwEQYDVQQKDApSb2FkUnVubmVyMRIwEAYDVQQDDAlsb2NhbGhvc3QwHhcNMTgw -OTMwMTMzNDUzWhcNMjgwOTI3MTMzNDUzWjBjMQswCQYDVQQGEwJVUzETMBEGA1UE -CAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzETMBEGA1UECgwK -Um9hZFJ1bm5lcjESMBAGA1UEAwwJbG9jYWxob3N0MHYwEAYHKoZIzj0CAQYFK4EE -ACIDYgAEVnbShsM+l5RR3wfWWmGhzuFGwNzKCk7i9xyobDIyBUxG/UUSfj7KKlUX -puDnDEtF5xXcepl744CyIAYFLOXHb5WqI4jCOzG0o9f/00QQ4bQudJOdbqV910QF -C2vb7Fxro1MwUTAdBgNVHQ4EFgQU9xUexnbB6ORKayA7Pfjzs33otsAwHwYDVR0j -BBgwFoAU9xUexnbB6ORKayA7Pfjzs33otsAwDwYDVR0TAQH/BAUwAwEB/zAKBggq -hkjOPQQDAgNoADBlAjEAue3HhR/MUhxoa9tSDBtOJT3FYbDQswrsdqBTz97CGKst -e7XeZ3HMEvEXy0hGGEMhAjAqcD/4k9vViVppgWFtkk6+NFbm+Kw/QeeAiH5FgFSj -8xQcb+b7nPwNLp3JOkXkVd4= ------END CERTIFICATE----- diff --git a/plugins/http/tests/fixtures/server.key b/plugins/http/tests/fixtures/server.key deleted file mode 100644 index 7501dd46..00000000 --- a/plugins/http/tests/fixtures/server.key +++ /dev/null @@ -1,9 +0,0 @@ ------BEGIN EC PARAMETERS----- -BgUrgQQAIg== ------END EC PARAMETERS----- ------BEGIN EC PRIVATE KEY----- -MIGkAgEBBDCQP8utxNbHR6xZOLAJgUhn88r6IrPqmN0MsgGJM/jePB+T9UhkmIU8 -PMm2HeScbcugBwYFK4EEACKhZANiAARWdtKGwz6XlFHfB9ZaYaHO4UbA3MoKTuL3 -HKhsMjIFTEb9RRJ+PsoqVRem4OcMS0XnFdx6mXvjgLIgBgUs5cdvlaojiMI7MbSj -1//TRBDhtC50k51upX3XRAULa9vsXGs= ------END EC PRIVATE KEY----- diff --git a/plugins/http/tests/handler_test.go b/plugins/http/tests/handler_test.go deleted file mode 100644 index 54a4ae80..00000000 --- a/plugins/http/tests/handler_test.go +++ /dev/null @@ -1,1860 +0,0 @@ -package tests - -import ( - "bytes" - "context" - "io/ioutil" - "mime/multipart" - "net/url" - "os/exec" - "runtime" - "strings" - - "github.com/spiral/roadrunner/v2/pkg/pipe" - poolImpl "github.com/spiral/roadrunner/v2/pkg/pool" - httpPlugin "github.com/spiral/roadrunner/v2/plugins/http" - "github.com/stretchr/testify/assert" - - "net/http" - "os" - "testing" - "time" -) - -func TestHandler_Echo(t *testing.T) { - pool, err := poolImpl.NewPool(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../../tests/http/client.php", "echo", "pipes") }, - pipe.NewPipeFactory(), - poolImpl.Config{ - NumWorkers: 1, - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - t.Fatal(err) - } - - h, err := httpPlugin.NewHandler(1024, httpPlugin.UploadsConfig{ - Dir: os.TempDir(), - Forbid: []string{}, - }, nil, pool) - assert.NoError(t, err) - - hs := &http.Server{Addr: ":8177", Handler: h} - defer func() { - err := hs.Shutdown(context.Background()) - if err != nil { - t.Errorf("error during the shutdown: error %v", err) - } - }() - go func(server *http.Server) { - err := server.ListenAndServe() - if err != nil && err != http.ErrServerClosed { - t.Errorf("error listening the interface: error %v", err) - } - }(hs) - time.Sleep(time.Millisecond * 10) - - body, r, err := get("http://localhost:8177/?hello=world") - assert.NoError(t, err) - defer func() { - _ = r.Body.Close() - }() - assert.Equal(t, 201, r.StatusCode) - assert.Equal(t, "WORLD", body) -} - -func Test_HandlerErrors(t *testing.T) { - _, err := httpPlugin.NewHandler(1024, httpPlugin.UploadsConfig{ - Dir: os.TempDir(), - Forbid: []string{}, - }, nil, nil) - assert.Error(t, err) -} - -func TestHandler_Headers(t *testing.T) { - pool, err := poolImpl.NewPool(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../../tests/http/client.php", "header", "pipes") }, - pipe.NewPipeFactory(), - poolImpl.Config{ - NumWorkers: 1, - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - t.Fatal(err) - } - defer func() { - pool.Destroy(context.Background()) - }() - - h, err := httpPlugin.NewHandler(1024, httpPlugin.UploadsConfig{ - Dir: os.TempDir(), - Forbid: []string{}, - }, nil, pool) - assert.NoError(t, err) - - hs := &http.Server{Addr: ":8078", Handler: h} - 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 * 100) - - req, err := http.NewRequest("GET", "http://localhost:8078?hello=world", nil) - assert.NoError(t, err) - - req.Header.Add("input", "sample") - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - 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) - - assert.NoError(t, err) - assert.Equal(t, 200, r.StatusCode) - assert.Equal(t, "world", r.Header.Get("Header")) - assert.Equal(t, "SAMPLE", string(b)) -} - -func TestHandler_Empty_User_Agent(t *testing.T) { - pool, err := poolImpl.NewPool(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../../tests/http/client.php", "user-agent", "pipes") }, - pipe.NewPipeFactory(), - poolImpl.Config{ - NumWorkers: 1, - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - t.Fatal(err) - } - defer func() { - pool.Destroy(context.Background()) - }() - - h, err := httpPlugin.NewHandler(1024, httpPlugin.UploadsConfig{ - Dir: os.TempDir(), - Forbid: []string{}, - }, nil, pool) - assert.NoError(t, err) - - hs := &http.Server{Addr: ":8088", Handler: h} - 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) - - req, err := http.NewRequest("GET", "http://localhost:8088?hello=world", nil) - assert.NoError(t, err) - - req.Header.Add("user-agent", "") - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - 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) - - assert.NoError(t, err) - assert.Equal(t, 200, r.StatusCode) - assert.Equal(t, "", string(b)) -} - -func TestHandler_User_Agent(t *testing.T) { - pool, err := poolImpl.NewPool(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../../tests/http/client.php", "user-agent", "pipes") }, - pipe.NewPipeFactory(), - poolImpl.Config{ - NumWorkers: 1, - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - t.Fatal(err) - } - defer func() { - pool.Destroy(context.Background()) - }() - - h, err := httpPlugin.NewHandler(1024, httpPlugin.UploadsConfig{ - Dir: os.TempDir(), - Forbid: []string{}, - }, nil, pool) - assert.NoError(t, err) - - hs := &http.Server{Addr: ":8088", Handler: h} - 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) - - req, err := http.NewRequest("GET", "http://localhost:8088?hello=world", nil) - assert.NoError(t, err) - - req.Header.Add("User-Agent", "go-agent") - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - 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) - - assert.NoError(t, err) - assert.Equal(t, 200, r.StatusCode) - assert.Equal(t, "go-agent", string(b)) -} - -func TestHandler_Cookies(t *testing.T) { - pool, err := poolImpl.NewPool(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../../tests/http/client.php", "cookie", "pipes") }, - pipe.NewPipeFactory(), - poolImpl.Config{ - NumWorkers: 1, - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - t.Fatal(err) - } - defer func() { - pool.Destroy(context.Background()) - }() - - h, err := httpPlugin.NewHandler(1024, httpPlugin.UploadsConfig{ - Dir: os.TempDir(), - Forbid: []string{}, - }, nil, pool) - assert.NoError(t, err) - - hs := &http.Server{Addr: ":8079", Handler: h} - 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) - - req, err := http.NewRequest("GET", "http://localhost:8079", nil) - assert.NoError(t, err) - - req.AddCookie(&http.Cookie{Name: "input", Value: "input-value"}) - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - 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) - - assert.NoError(t, err) - assert.Equal(t, 200, r.StatusCode) - assert.Equal(t, "INPUT-VALUE", string(b)) - - for _, c := range r.Cookies() { - assert.Equal(t, "output", c.Name) - assert.Equal(t, "cookie-output", c.Value) - } -} - -func TestHandler_JsonPayload_POST(t *testing.T) { - pool, err := poolImpl.NewPool(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../../tests/http/client.php", "payload", "pipes") }, - pipe.NewPipeFactory(), - poolImpl.Config{ - NumWorkers: 1, - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - t.Fatal(err) - } - defer func() { - pool.Destroy(context.Background()) - }() - - h, err := httpPlugin.NewHandler(1024, httpPlugin.UploadsConfig{ - Dir: os.TempDir(), - Forbid: []string{}, - }, nil, pool) - assert.NoError(t, err) - - hs := &http.Server{Addr: ":8090", Handler: h} - 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) - - req, err := http.NewRequest( - "POST", - "http://localhost"+hs.Addr, - bytes.NewBufferString(`{"key":"value"}`), - ) - assert.NoError(t, err) - - req.Header.Add("Content-Type", "application/json") - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - 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) - - assert.NoError(t, err) - assert.Equal(t, 200, r.StatusCode) - assert.Equal(t, `{"value":"key"}`, string(b)) -} - -func TestHandler_JsonPayload_PUT(t *testing.T) { - pool, err := poolImpl.NewPool(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../../tests/http/client.php", "payload", "pipes") }, - pipe.NewPipeFactory(), - poolImpl.Config{ - NumWorkers: 1, - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - t.Fatal(err) - } - defer func() { - pool.Destroy(context.Background()) - }() - - h, err := httpPlugin.NewHandler(1024, httpPlugin.UploadsConfig{ - Dir: os.TempDir(), - Forbid: []string{}, - }, nil, pool) - assert.NoError(t, err) - - hs := &http.Server{Addr: ":8081", Handler: h} - 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) - - req, err := http.NewRequest("PUT", "http://localhost"+hs.Addr, bytes.NewBufferString(`{"key":"value"}`)) - assert.NoError(t, err) - - req.Header.Add("Content-Type", "application/json") - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - 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) - - assert.NoError(t, err) - assert.Equal(t, 200, r.StatusCode) - assert.Equal(t, `{"value":"key"}`, string(b)) -} - -func TestHandler_JsonPayload_PATCH(t *testing.T) { - pool, err := poolImpl.NewPool(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../../tests/http/client.php", "payload", "pipes") }, - pipe.NewPipeFactory(), - poolImpl.Config{ - NumWorkers: 1, - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - t.Fatal(err) - } - defer func() { - pool.Destroy(context.Background()) - }() - - h, err := httpPlugin.NewHandler(1024, httpPlugin.UploadsConfig{ - Dir: os.TempDir(), - Forbid: []string{}, - }, nil, pool) - assert.NoError(t, err) - - hs := &http.Server{Addr: ":8082", Handler: h} - 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) - - req, err := http.NewRequest("PATCH", "http://localhost"+hs.Addr, bytes.NewBufferString(`{"key":"value"}`)) - assert.NoError(t, err) - - req.Header.Add("Content-Type", "application/json") - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - 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) - - assert.NoError(t, err) - assert.Equal(t, 200, r.StatusCode) - assert.Equal(t, `{"value":"key"}`, string(b)) -} - -func TestHandler_FormData_POST(t *testing.T) { - pool, err := poolImpl.NewPool(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../../tests/http/client.php", "data", "pipes") }, - pipe.NewPipeFactory(), - poolImpl.Config{ - NumWorkers: 1, - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - t.Fatal(err) - } - defer func() { - pool.Destroy(context.Background()) - }() - - h, err := httpPlugin.NewHandler(1024, httpPlugin.UploadsConfig{ - Dir: os.TempDir(), - Forbid: []string{}, - }, nil, pool) - assert.NoError(t, err) - - hs := &http.Server{Addr: ":8083", Handler: h} - 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 * 500) - - form := url.Values{} - - form.Add("key", "value") - form.Add("name[]", "name1") - form.Add("name[]", "name2") - form.Add("name[]", "name3") - form.Add("arr[x][y][z]", "y") - form.Add("arr[x][y][e]", "f") - form.Add("arr[c]p", "l") - form.Add("arr[c]z", "") - - req, err := http.NewRequest("POST", "http://localhost"+hs.Addr, strings.NewReader(form.Encode())) - assert.NoError(t, err) - - req.Header.Add("Content-Type", "application/x-www-form-urlencoded") - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - 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) - - assert.NoError(t, err) - assert.Equal(t, 200, r.StatusCode) - - // Sorted - assert.Equal(t, "{\"arr\":{\"c\":{\"p\":\"l\",\"z\":\"\"},\"x\":{\"y\":{\"e\":\"f\",\"z\":\"y\"}}},\"key\":\"value\",\"name\":[\"name1\",\"name2\",\"name3\"]}", string(b)) -} - -func TestHandler_FormData_POST_Overwrite(t *testing.T) { - pool, err := poolImpl.NewPool(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../../tests/http/client.php", "data", "pipes") }, - pipe.NewPipeFactory(), - poolImpl.Config{ - NumWorkers: 1, - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - t.Fatal(err) - } - defer func() { - pool.Destroy(context.Background()) - }() - - h, err := httpPlugin.NewHandler(1024, httpPlugin.UploadsConfig{ - Dir: os.TempDir(), - Forbid: []string{}, - }, nil, pool) - assert.NoError(t, err) - - hs := &http.Server{Addr: ":8083", Handler: h} - 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) - - form := url.Values{} - - form.Add("key", "value") - form.Add("key", "value2") - form.Add("name[]", "name1") - form.Add("name[]", "name2") - form.Add("name[]", "name3") - form.Add("arr[x][y][z]", "y") - form.Add("arr[x][y][e]", "f") - form.Add("arr[c]p", "l") - form.Add("arr[c]z", "") - - req, err := http.NewRequest("POST", "http://localhost"+hs.Addr, strings.NewReader(form.Encode())) - assert.NoError(t, err) - - req.Header.Add("Content-Type", "application/x-www-form-urlencoded") - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - 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) - - assert.NoError(t, err) - assert.Equal(t, 200, r.StatusCode) - - assert.Equal(t, `{"arr":{"c":{"p":"l","z":""},"x":{"y":{"e":"f","z":"y"}}},"key":"value2","name":["name1","name2","name3"]}`, string(b)) -} - -func TestHandler_FormData_POST_Form_UrlEncoded_Charset(t *testing.T) { - pool, err := poolImpl.NewPool(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../../tests/http/client.php", "data", "pipes") }, - pipe.NewPipeFactory(), - poolImpl.Config{ - NumWorkers: 1, - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - t.Fatal(err) - } - defer func() { - pool.Destroy(context.Background()) - }() - - h, err := httpPlugin.NewHandler(1024, httpPlugin.UploadsConfig{ - Dir: os.TempDir(), - Forbid: []string{}, - }, nil, pool) - assert.NoError(t, err) - - hs := &http.Server{Addr: ":8083", Handler: h} - 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) - - form := url.Values{} - - form.Add("key", "value") - form.Add("name[]", "name1") - form.Add("name[]", "name2") - form.Add("name[]", "name3") - form.Add("arr[x][y][z]", "y") - form.Add("arr[x][y][e]", "f") - form.Add("arr[c]p", "l") - form.Add("arr[c]z", "") - - req, err := http.NewRequest("POST", "http://localhost"+hs.Addr, strings.NewReader(form.Encode())) - assert.NoError(t, err) - - req.Header.Add("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8") - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - 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) - - assert.NoError(t, err) - assert.Equal(t, 200, r.StatusCode) - - assert.Equal(t, `{"arr":{"c":{"p":"l","z":""},"x":{"y":{"e":"f","z":"y"}}},"key":"value","name":["name1","name2","name3"]}`, string(b)) -} - -func TestHandler_FormData_PUT(t *testing.T) { - pool, err := poolImpl.NewPool(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../../tests/http/client.php", "data", "pipes") }, - pipe.NewPipeFactory(), - poolImpl.Config{ - NumWorkers: 1, - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - t.Fatal(err) - } - defer func() { - pool.Destroy(context.Background()) - }() - - h, err := httpPlugin.NewHandler(1024, httpPlugin.UploadsConfig{ - Dir: os.TempDir(), - Forbid: []string{}, - }, nil, pool) - assert.NoError(t, err) - - hs := &http.Server{Addr: ":17834", Handler: h} - 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 * 500) - - form := url.Values{} - - form.Add("key", "value") - form.Add("name[]", "name1") - form.Add("name[]", "name2") - form.Add("name[]", "name3") - form.Add("arr[x][y][z]", "y") - form.Add("arr[x][y][e]", "f") - form.Add("arr[c]p", "l") - form.Add("arr[c]z", "") - - req, err := http.NewRequest("PUT", "http://localhost"+hs.Addr, strings.NewReader(form.Encode())) - assert.NoError(t, err) - - req.Header.Add("Content-Type", "application/x-www-form-urlencoded") - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - 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) - - assert.NoError(t, err) - assert.Equal(t, 200, r.StatusCode) - - assert.Equal(t, `{"arr":{"c":{"p":"l","z":""},"x":{"y":{"e":"f","z":"y"}}},"key":"value","name":["name1","name2","name3"]}`, string(b)) -} - -func TestHandler_FormData_PATCH(t *testing.T) { - pool, err := poolImpl.NewPool(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../../tests/http/client.php", "data", "pipes") }, - pipe.NewPipeFactory(), - poolImpl.Config{ - NumWorkers: 1, - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - t.Fatal(err) - } - defer func() { - pool.Destroy(context.Background()) - }() - - h, err := httpPlugin.NewHandler(1024, httpPlugin.UploadsConfig{ - Dir: os.TempDir(), - Forbid: []string{}, - }, nil, pool) - assert.NoError(t, err) - - hs := &http.Server{Addr: ":8085", Handler: h} - 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) - - form := url.Values{} - - form.Add("key", "value") - form.Add("name[]", "name1") - form.Add("name[]", "name2") - form.Add("name[]", "name3") - form.Add("arr[x][y][z]", "y") - form.Add("arr[x][y][e]", "f") - form.Add("arr[c]p", "l") - form.Add("arr[c]z", "") - - req, err := http.NewRequest("PATCH", "http://localhost"+hs.Addr, strings.NewReader(form.Encode())) - assert.NoError(t, err) - - req.Header.Add("Content-Type", "application/x-www-form-urlencoded") - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - 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) - - assert.NoError(t, err) - assert.Equal(t, 200, r.StatusCode) - - assert.Equal(t, "{\"arr\":{\"c\":{\"p\":\"l\",\"z\":\"\"},\"x\":{\"y\":{\"e\":\"f\",\"z\":\"y\"}}},\"key\":\"value\",\"name\":[\"name1\",\"name2\",\"name3\"]}", string(b)) -} - -func TestHandler_Multipart_POST(t *testing.T) { - pool, err := poolImpl.NewPool(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../../tests/http/client.php", "data", "pipes") }, - pipe.NewPipeFactory(), - poolImpl.Config{ - NumWorkers: 1, - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - t.Fatal(err) - } - defer func() { - pool.Destroy(context.Background()) - }() - - h, err := httpPlugin.NewHandler(1024, httpPlugin.UploadsConfig{ - Dir: os.TempDir(), - Forbid: []string{}, - }, nil, pool) - assert.NoError(t, err) - - hs := &http.Server{Addr: ":8019", Handler: h} - 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) - 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) - } - - 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("POST", "http://localhost"+hs.Addr, &mb) - assert.NoError(t, err) - - req.Header.Set("Content-Type", w.FormDataContentType()) - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - 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) - - assert.NoError(t, err) - assert.Equal(t, 200, r.StatusCode) - - assert.Equal(t, "{\"arr\":{\"c\":{\"p\":\"l\",\"z\":\"\"},\"x\":{\"y\":{\"e\":\"f\",\"z\":\"y\"}}},\"key\":\"value\",\"name\":[\"name1\",\"name2\",\"name3\"]}", string(b)) -} - -func TestHandler_Multipart_PUT(t *testing.T) { - pool, err := poolImpl.NewPool(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../../tests/http/client.php", "data", "pipes") }, - pipe.NewPipeFactory(), - poolImpl.Config{ - NumWorkers: 1, - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - t.Fatal(err) - } - defer func() { - pool.Destroy(context.Background()) - }() - - h, err := httpPlugin.NewHandler(1024, httpPlugin.UploadsConfig{ - Dir: os.TempDir(), - Forbid: []string{}, - }, nil, pool) - assert.NoError(t, err) - - hs := &http.Server{Addr: ":8020", Handler: h} - 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 * 500) - - var mb bytes.Buffer - w := multipart.NewWriter(&mb) - 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) - } - - 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) - - req.Header.Set("Content-Type", w.FormDataContentType()) - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - 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) - - assert.NoError(t, err) - assert.Equal(t, 200, r.StatusCode) - - assert.Equal(t, `{"arr":{"c":{"p":"l","z":""},"x":{"y":{"e":"f","z":"y"}}},"key":"value","name":["name1","name2","name3"]}`, string(b)) -} - -func TestHandler_Multipart_PATCH(t *testing.T) { - pool, err := poolImpl.NewPool(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../../tests/http/client.php", "data", "pipes") }, - pipe.NewPipeFactory(), - poolImpl.Config{ - NumWorkers: 1, - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - t.Fatal(err) - } - defer func() { - pool.Destroy(context.Background()) - }() - - h, err := httpPlugin.NewHandler(1024, httpPlugin.UploadsConfig{ - Dir: os.TempDir(), - Forbid: []string{}, - }, nil, pool) - assert.NoError(t, err) - - hs := &http.Server{Addr: ":8021", Handler: h} - 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 * 500) - - var mb bytes.Buffer - w := multipart.NewWriter(&mb) - 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) - } - - 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) - - req.Header.Set("Content-Type", w.FormDataContentType()) - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - 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) - - assert.NoError(t, err) - assert.Equal(t, 200, r.StatusCode) - - assert.Equal(t, `{"arr":{"c":{"p":"l","z":""},"x":{"y":{"e":"f","z":"y"}}},"key":"value","name":["name1","name2","name3"]}`, string(b)) -} - -func TestHandler_Error(t *testing.T) { - pool, err := poolImpl.NewPool(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../../tests/http/client.php", "error", "pipes") }, - pipe.NewPipeFactory(), - poolImpl.Config{ - NumWorkers: 1, - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - t.Fatal(err) - } - defer func() { - pool.Destroy(context.Background()) - }() - - h, err := httpPlugin.NewHandler(1024, httpPlugin.UploadsConfig{ - Dir: os.TempDir(), - Forbid: []string{}, - }, nil, pool) - assert.NoError(t, err) - - hs := &http.Server{Addr: ":8177", Handler: h} - 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) - - _, r, err := get("http://localhost:8177/?hello=world") - assert.NoError(t, err) - defer func() { - _ = r.Body.Close() - }() - assert.Equal(t, 500, r.StatusCode) -} - -func TestHandler_Error2(t *testing.T) { - pool, err := poolImpl.NewPool(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../../tests/http/client.php", "error2", "pipes") }, - pipe.NewPipeFactory(), - poolImpl.Config{ - NumWorkers: 1, - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - t.Fatal(err) - } - defer func() { - pool.Destroy(context.Background()) - }() - - h, err := httpPlugin.NewHandler(1024, httpPlugin.UploadsConfig{ - Dir: os.TempDir(), - Forbid: []string{}, - }, nil, pool) - assert.NoError(t, err) - - hs := &http.Server{Addr: ":8177", Handler: h} - 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) - - _, r, err := get("http://localhost:8177/?hello=world") - assert.NoError(t, err) - defer func() { - _ = r.Body.Close() - }() - assert.Equal(t, 500, r.StatusCode) -} - -func TestHandler_Error3(t *testing.T) { - pool, err := poolImpl.NewPool(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../../tests/http/client.php", "pid", "pipes") }, - pipe.NewPipeFactory(), - poolImpl.Config{ - NumWorkers: 1, - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - t.Fatal(err) - } - defer func() { - pool.Destroy(context.Background()) - }() - - h, err := httpPlugin.NewHandler(1, httpPlugin.UploadsConfig{ - Dir: os.TempDir(), - Forbid: []string{}, - }, nil, pool) - assert.NoError(t, err) - - hs := &http.Server{Addr: ":8177", Handler: h} - 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) - - b2 := &bytes.Buffer{} - for i := 0; i < 1024*1024; i++ { - b2.Write([]byte(" ")) - } - - req, err := http.NewRequest("POST", "http://localhost"+hs.Addr, b2) - assert.NoError(t, err) - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - 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) -} - -func TestHandler_ResponseDuration(t *testing.T) { - pool, err := poolImpl.NewPool(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../../tests/http/client.php", "echo", "pipes") }, - pipe.NewPipeFactory(), - poolImpl.Config{ - NumWorkers: 1, - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - t.Fatal(err) - } - defer func() { - pool.Destroy(context.Background()) - }() - - h, err := httpPlugin.NewHandler(1024, httpPlugin.UploadsConfig{ - Dir: os.TempDir(), - Forbid: []string{}, - }, nil, pool) - assert.NoError(t, err) - - hs := &http.Server{Addr: ":8177", Handler: h} - 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) - - gotresp := make(chan interface{}) - h.AddListener(func(event interface{}) { - switch t := event.(type) { - case httpPlugin.ResponseEvent: - if t.Elapsed() > 0 { - close(gotresp) - } - default: - } - }) - - body, r, err := get("http://localhost:8177/?hello=world") - assert.NoError(t, err) - defer func() { - _ = r.Body.Close() - }() - - <-gotresp - - assert.Equal(t, 201, r.StatusCode) - assert.Equal(t, "WORLD", body) -} - -func TestHandler_ResponseDurationDelayed(t *testing.T) { - pool, err := poolImpl.NewPool(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../../tests/http/client.php", "echoDelay", "pipes") }, - pipe.NewPipeFactory(), - poolImpl.Config{ - NumWorkers: 1, - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - t.Fatal(err) - } - defer func() { - pool.Destroy(context.Background()) - }() - - h, err := httpPlugin.NewHandler(1024, httpPlugin.UploadsConfig{ - Dir: os.TempDir(), - Forbid: []string{}, - }, nil, pool) - assert.NoError(t, err) - - hs := &http.Server{Addr: ":8177", Handler: h} - 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) - - gotresp := make(chan interface{}) - h.AddListener(func(event interface{}) { - switch tp := event.(type) { - case httpPlugin.ResponseEvent: - if tp.Elapsed() > time.Second { - close(gotresp) - } - default: - } - }) - - body, r, err := get("http://localhost:8177/?hello=world") - assert.NoError(t, err) - defer func() { - _ = r.Body.Close() - }() - <-gotresp - - assert.Equal(t, 201, r.StatusCode) - assert.Equal(t, "WORLD", body) -} - -func TestHandler_ErrorDuration(t *testing.T) { - pool, err := poolImpl.NewPool(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../../tests/http/client.php", "error", "pipes") }, - pipe.NewPipeFactory(), - poolImpl.Config{ - NumWorkers: 1, - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - t.Fatal(err) - } - defer func() { - pool.Destroy(context.Background()) - }() - - h, err := httpPlugin.NewHandler(1024, httpPlugin.UploadsConfig{ - Dir: os.TempDir(), - Forbid: []string{}, - }, nil, pool) - assert.NoError(t, err) - - hs := &http.Server{Addr: ":8177", Handler: h} - 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) - - goterr := make(chan interface{}) - h.AddListener(func(event interface{}) { - switch tp := event.(type) { - case httpPlugin.ErrorEvent: - if tp.Elapsed() > 0 { - close(goterr) - } - default: - } - }) - - _, r, err := get("http://localhost:8177/?hello=world") - assert.NoError(t, err) - defer func() { - _ = r.Body.Close() - }() - - <-goterr - - assert.Equal(t, 500, r.StatusCode) -} - -func TestHandler_IP(t *testing.T) { - trusted := []string{ - "10.0.0.0/8", - "127.0.0.0/8", - "172.16.0.0/12", - "192.168.0.0/16", - "::1/128", - "fc00::/7", - "fe80::/10", - } - - cidrs, err := httpPlugin.ParseCIDRs(trusted) - assert.NoError(t, err) - assert.NotNil(t, cidrs) - - pool, err := poolImpl.NewPool(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../../tests/http/client.php", "ip", "pipes") }, - pipe.NewPipeFactory(), - poolImpl.Config{ - NumWorkers: 1, - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - t.Fatal(err) - } - defer func() { - pool.Destroy(context.Background()) - }() - - h, err := httpPlugin.NewHandler(1024, httpPlugin.UploadsConfig{ - Dir: os.TempDir(), - Forbid: []string{}, - }, cidrs, pool) - assert.NoError(t, err) - - hs := &http.Server{Addr: "127.0.0.1:8177", Handler: h} - 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) - - body, r, err := get("http://127.0.0.1:8177/") - assert.NoError(t, err) - defer func() { - _ = r.Body.Close() - }() - assert.Equal(t, 200, r.StatusCode) - assert.Equal(t, "127.0.0.1", body) -} - -func TestHandler_XRealIP(t *testing.T) { - trusted := []string{ - "10.0.0.0/8", - "127.0.0.0/8", - "172.16.0.0/12", - "192.168.0.0/16", - "::1/128", - "fc00::/7", - "fe80::/10", - } - - cidrs, err := httpPlugin.ParseCIDRs(trusted) - assert.NoError(t, err) - assert.NotNil(t, cidrs) - - pool, err := poolImpl.NewPool(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../../tests/http/client.php", "ip", "pipes") }, - pipe.NewPipeFactory(), - poolImpl.Config{ - NumWorkers: 1, - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - t.Fatal(err) - } - defer func() { - pool.Destroy(context.Background()) - }() - - h, err := httpPlugin.NewHandler(1024, httpPlugin.UploadsConfig{ - Dir: os.TempDir(), - Forbid: []string{}, - }, cidrs, pool) - assert.NoError(t, err) - - hs := &http.Server{Addr: "127.0.0.1:8179", Handler: h} - 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) - - body, r, err := getHeader("http://127.0.0.1:8179/", map[string]string{ - "X-Real-Ip": "200.0.0.1", - }) - - assert.NoError(t, err) - defer func() { - _ = r.Body.Close() - }() - assert.Equal(t, 200, r.StatusCode) - assert.Equal(t, "200.0.0.1", body) -} - -func TestHandler_XForwardedFor(t *testing.T) { - trusted := []string{ - "10.0.0.0/8", - "127.0.0.0/8", - "172.16.0.0/12", - "192.168.0.0/16", - "100.0.0.0/16", - "200.0.0.0/16", - "::1/128", - "fc00::/7", - "fe80::/10", - } - - cidrs, err := httpPlugin.ParseCIDRs(trusted) - assert.NoError(t, err) - assert.NotNil(t, cidrs) - - pool, err := poolImpl.NewPool(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../../tests/http/client.php", "ip", "pipes") }, - pipe.NewPipeFactory(), - poolImpl.Config{ - NumWorkers: 1, - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - t.Fatal(err) - } - defer func() { - pool.Destroy(context.Background()) - }() - - h, err := httpPlugin.NewHandler(1024, httpPlugin.UploadsConfig{ - Dir: os.TempDir(), - Forbid: []string{}, - }, cidrs, pool) - assert.NoError(t, err) - - hs := &http.Server{Addr: "127.0.0.1:8177", Handler: h} - 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) - - body, r, err := getHeader("http://127.0.0.1:8177/", map[string]string{ - "X-Forwarded-For": "100.0.0.1, 200.0.0.1, invalid, 101.0.0.1", - }) - - assert.NoError(t, err) - assert.Equal(t, 200, r.StatusCode) - assert.Equal(t, "101.0.0.1", body) - _ = r.Body.Close() - - body, r, err = getHeader("http://127.0.0.1:8177/", map[string]string{ - "X-Forwarded-For": "100.0.0.1, 200.0.0.1, 101.0.0.1, invalid", - }) - - assert.NoError(t, err) - _ = r.Body.Close() - assert.Equal(t, 200, r.StatusCode) - assert.Equal(t, "101.0.0.1", body) -} - -func TestHandler_XForwardedFor_NotTrustedRemoteIp(t *testing.T) { - trusted := []string{ - "10.0.0.0/8", - } - - cidrs, err := httpPlugin.ParseCIDRs(trusted) - assert.NoError(t, err) - assert.NotNil(t, cidrs) - - pool, err := poolImpl.NewPool(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../../tests/http/client.php", "ip", "pipes") }, - pipe.NewPipeFactory(), - poolImpl.Config{ - NumWorkers: 1, - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - t.Fatal(err) - } - defer func() { - pool.Destroy(context.Background()) - }() - - h, err := httpPlugin.NewHandler(1024, httpPlugin.UploadsConfig{ - Dir: os.TempDir(), - Forbid: []string{}, - }, cidrs, pool) - assert.NoError(t, err) - - hs := &http.Server{Addr: "127.0.0.1:8177", Handler: h} - 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) - - body, r, err := getHeader("http://127.0.0.1:8177/", map[string]string{ - "X-Forwarded-For": "100.0.0.1, 200.0.0.1, invalid, 101.0.0.1", - }) - - assert.NoError(t, err) - _ = r.Body.Close() - assert.Equal(t, 200, r.StatusCode) - assert.Equal(t, "127.0.0.1", body) -} - -func BenchmarkHandler_Listen_Echo(b *testing.B) { - pool, err := poolImpl.NewPool(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../../tests/http/client.php", "echo", "pipes") }, - pipe.NewPipeFactory(), - poolImpl.Config{ - NumWorkers: int64(runtime.NumCPU()), - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - b.Fatal(err) - } - defer func() { - pool.Destroy(context.Background()) - }() - - h, err := httpPlugin.NewHandler(1024, httpPlugin.UploadsConfig{ - Dir: os.TempDir(), - Forbid: []string{}, - }, nil, pool) - assert.NoError(b, err) - - hs := &http.Server{Addr: ":8177", Handler: h} - defer func() { - err := hs.Shutdown(context.Background()) - if err != nil { - b.Errorf("error during the shutdown: error %v", err) - } - }() - - 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) - - b.ResetTimer() - b.ReportAllocs() - bb := "WORLD" - for n := 0; n < b.N; n++ { - r, err := http.Get("http://localhost:8177/?hello=world") - if err != nil { - 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/plugins/http/tests/http_test.go b/plugins/http/tests/http_test.go deleted file mode 100644 index d7818981..00000000 --- a/plugins/http/tests/http_test.go +++ /dev/null @@ -1,1131 +0,0 @@ -package tests - -import ( - "bytes" - "crypto/tls" - "io/ioutil" - "net" - "net/http" - "net/http/httptest" - "net/rpc" - "os" - "os/signal" - "sync" - "syscall" - "testing" - "time" - - "github.com/golang/mock/gomock" - "github.com/spiral/endure" - goridgeRpc "github.com/spiral/goridge/v3/pkg/rpc" - "github.com/spiral/roadrunner/v2" - "github.com/spiral/roadrunner/v2/interfaces/events" - "github.com/spiral/roadrunner/v2/mocks" - "github.com/spiral/roadrunner/v2/plugins/config" - httpPlugin "github.com/spiral/roadrunner/v2/plugins/http" - "github.com/spiral/roadrunner/v2/plugins/informer" - "github.com/spiral/roadrunner/v2/plugins/logger" - "github.com/spiral/roadrunner/v2/plugins/resetter" - "github.com/yookoala/gofast" - - rpcPlugin "github.com/spiral/roadrunner/v2/plugins/rpc" - "github.com/spiral/roadrunner/v2/plugins/server" - "github.com/stretchr/testify/assert" -) - -var sslClient = &http.Client{ - Transport: &http.Transport{ - TLSClientConfig: &tls.Config{ - InsecureSkipVerify: true, - }, - }, -} - -func TestHTTPInit(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-init.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &logger.ZapLogger{}, - &server.Plugin{}, - &httpPlugin.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - tt := time.NewTimer(time.Second * 5) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-tt.C: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - wg.Wait() -} - -func TestHTTPInformerReset(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-resetter.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &rpcPlugin.Plugin{}, - &logger.ZapLogger{}, - &server.Plugin{}, - &httpPlugin.Plugin{}, - &informer.Plugin{}, - &resetter.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - go func() { - tt := time.NewTimer(time.Second * 10) - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-tt.C: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 1) - t.Run("HTTPInformerTest", informerTest) - t.Run("HTTPEchoTestBefore", echoHTTP) - t.Run("HTTPResetTest", resetTest) - t.Run("HTTPEchoTestAfter", echoHTTP) - - wg.Wait() -} - -func echoHTTP(t *testing.T) { - req, err := http.NewRequest("GET", "http://localhost:10084?hello=world", nil) - assert.NoError(t, err) - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - b, err := ioutil.ReadAll(r.Body) - assert.NoError(t, err) - assert.Equal(t, 201, r.StatusCode) - assert.Equal(t, "WORLD", string(b)) - - err = r.Body.Close() - assert.NoError(t, err) -} - -func resetTest(t *testing.T) { - conn, err := net.Dial("tcp", "127.0.0.1:6001") - assert.NoError(t, err) - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - // WorkerList contains list of workers. - - var ret bool - err = client.Call("resetter.Reset", "http", &ret) - assert.NoError(t, err) - assert.True(t, ret) - ret = false - - var services []string - err = client.Call("resetter.List", nil, &services) - assert.NoError(t, err) - if services[0] != "http" { - t.Fatal("no enough services") - } -} - -func informerTest(t *testing.T) { - conn, err := net.Dial("tcp", "127.0.0.1:6001") - assert.NoError(t, err) - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - // WorkerList contains list of workers. - list := struct { - // Workers is list of workers. - Workers []roadrunner.ProcessState `json:"workers"` - }{} - - err = client.Call("informer.Workers", "http", &list) - assert.NoError(t, err) - assert.Len(t, list.Workers, 2) -} - -func TestSSL(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-ssl.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &rpcPlugin.Plugin{}, - &logger.ZapLogger{}, - &server.Plugin{}, - &httpPlugin.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - tt := time.NewTimer(time.Second * 10) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-tt.C: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 1) - t.Run("SSLEcho", sslEcho) - t.Run("SSLNoRedirect", sslNoRedirect) - t.Run("fCGIecho", fcgiEcho) - wg.Wait() -} - -func sslNoRedirect(t *testing.T) { - req, err := http.NewRequest("GET", "http://localhost:8085?hello=world", nil) - assert.NoError(t, err) - - r, err := sslClient.Do(req) - assert.NoError(t, err) - - assert.Nil(t, r.TLS) - - b, err := ioutil.ReadAll(r.Body) - assert.NoError(t, err) - - assert.NoError(t, err) - assert.Equal(t, 201, r.StatusCode) - assert.Equal(t, "WORLD", string(b)) - - err2 := r.Body.Close() - if err2 != nil { - t.Errorf("fail to close the Body: error %v", err2) - } -} - -func sslEcho(t *testing.T) { - req, err := http.NewRequest("GET", "https://localhost:8893?hello=world", nil) - assert.NoError(t, err) - - r, err := sslClient.Do(req) - assert.NoError(t, err) - - b, err := ioutil.ReadAll(r.Body) - assert.NoError(t, err) - - assert.NoError(t, err) - assert.Equal(t, 201, r.StatusCode) - assert.Equal(t, "WORLD", string(b)) - - err2 := r.Body.Close() - if err2 != nil { - t.Errorf("fail to close the Body: error %v", err2) - } -} - -func fcgiEcho(t *testing.T) { - fcgiConnFactory := gofast.SimpleConnFactory("tcp", "0.0.0.0:16920") - - fcgiHandler := gofast.NewHandler( - gofast.BasicParamsMap(gofast.BasicSession), - gofast.SimpleClientFactory(fcgiConnFactory, 0), - ) - - w := httptest.NewRecorder() - req := httptest.NewRequest("GET", "http://site.local/?hello=world", nil) - fcgiHandler.ServeHTTP(w, req) - - body, err := ioutil.ReadAll(w.Result().Body) - - assert.NoError(t, err) - assert.Equal(t, 201, w.Result().StatusCode) - assert.Equal(t, "WORLD", string(body)) -} - -func TestSSLRedirect(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-ssl-redirect.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &rpcPlugin.Plugin{}, - &logger.ZapLogger{}, - &server.Plugin{}, - &httpPlugin.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - tt := time.NewTimer(time.Second * 10) - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-tt.C: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 1) - t.Run("SSLRedirect", sslRedirect) - wg.Wait() -} - -func sslRedirect(t *testing.T) { - req, err := http.NewRequest("GET", "http://localhost:8087?hello=world", nil) - assert.NoError(t, err) - - r, err := sslClient.Do(req) - assert.NoError(t, err) - assert.NotNil(t, r.TLS) - - b, err := ioutil.ReadAll(r.Body) - assert.NoError(t, err) - - assert.NoError(t, err) - assert.Equal(t, 201, r.StatusCode) - assert.Equal(t, "WORLD", string(b)) - - err2 := r.Body.Close() - if err2 != nil { - t.Errorf("fail to close the Body: error %v", err2) - } -} - -func TestSSLPushPipes(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-ssl-push.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &rpcPlugin.Plugin{}, - &logger.ZapLogger{}, - &server.Plugin{}, - &httpPlugin.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - tt := time.NewTimer(time.Second * 10) - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-tt.C: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 1) - t.Run("SSLPush", sslPush) - wg.Wait() -} - -func sslPush(t *testing.T) { - req, err := http.NewRequest("GET", "https://localhost:8894?hello=world", nil) - assert.NoError(t, err) - - r, err := sslClient.Do(req) - assert.NoError(t, err) - - assert.NotNil(t, r.TLS) - - b, err := ioutil.ReadAll(r.Body) - assert.NoError(t, err) - - assert.Equal(t, "", r.Header.Get("Http2-Push")) - - assert.NoError(t, err) - assert.Equal(t, 201, r.StatusCode) - assert.Equal(t, "WORLD", string(b)) - - err2 := r.Body.Close() - if err2 != nil { - t.Errorf("fail to close the Body: error %v", err2) - } -} - -func TestFastCGI_RequestUri(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-fcgi-reqUri.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &logger.ZapLogger{}, - &server.Plugin{}, - &httpPlugin.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - tt := time.NewTimer(time.Second * 10) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-tt.C: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 1) - t.Run("FastCGIServiceRequestUri", fcgiReqURI) - wg.Wait() -} - -func fcgiReqURI(t *testing.T) { - time.Sleep(time.Second * 2) - fcgiConnFactory := gofast.SimpleConnFactory("tcp", "127.0.0.1:6921") - - fcgiHandler := gofast.NewHandler( - gofast.BasicParamsMap(gofast.BasicSession), - gofast.SimpleClientFactory(fcgiConnFactory, 0), - ) - - w := httptest.NewRecorder() - req := httptest.NewRequest("GET", "http://site.local/hello-world", nil) - fcgiHandler.ServeHTTP(w, req) - - body, err := ioutil.ReadAll(w.Result().Body) - assert.NoError(t, err) - assert.Equal(t, 200, w.Result().StatusCode) - assert.Equal(t, "http://site.local/hello-world", string(body)) -} - -func TestH2CUpgrade(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-h2c.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &rpcPlugin.Plugin{}, - &logger.ZapLogger{}, - &server.Plugin{}, - &httpPlugin.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - tt := time.NewTimer(time.Second * 10) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-tt.C: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 1) - t.Run("H2cUpgrade", h2cUpgrade) - wg.Wait() -} - -func h2cUpgrade(t *testing.T) { - req, err := http.NewRequest("PRI", "http://localhost:8083?hello=world", nil) - if err != nil { - t.Fatal(err) - } - - req.Header.Add("Upgrade", "h2c") - req.Header.Add("Connection", "HTTP2-Settings") - req.Header.Add("HTTP2-Settings", "") - - r, err2 := http.DefaultClient.Do(req) - if err2 != nil { - t.Fatal(err) - } - - assert.Equal(t, "101 Switching Protocols", r.Status) - - err3 := r.Body.Close() - if err3 != nil { - t.Fatal(err) - } -} - -func TestH2C(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-h2c.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &rpcPlugin.Plugin{}, - &logger.ZapLogger{}, - &server.Plugin{}, - &httpPlugin.Plugin{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - tt := time.NewTimer(time.Second * 10) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-tt.C: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 1) - t.Run("H2c", h2c) - wg.Wait() -} - -func h2c(t *testing.T) { - req, err := http.NewRequest("PRI", "http://localhost:8083?hello=world", nil) - if err != nil { - t.Fatal(err) - } - - req.Header.Add("Connection", "HTTP2-Settings") - req.Header.Add("HTTP2-Settings", "") - - r, err2 := http.DefaultClient.Do(req) - if err2 != nil { - t.Fatal(err) - } - - assert.Equal(t, "201 Created", r.Status) - - err3 := r.Body.Close() - if err3 != nil { - t.Fatal(err) - } -} - -func TestHttpMiddleware(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-http.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &rpcPlugin.Plugin{}, - &logger.ZapLogger{}, - &server.Plugin{}, - &httpPlugin.Plugin{}, - &PluginMiddleware{}, - &PluginMiddleware2{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - tt := time.NewTimer(time.Second * 20) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-tt.C: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 1) - t.Run("MiddlewareTest", middleware) - wg.Wait() -} - -func middleware(t *testing.T) { - req, err := http.NewRequest("GET", "http://localhost:18903?hello=world", nil) - assert.NoError(t, err) - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - - b, err := ioutil.ReadAll(r.Body) - assert.NoError(t, err) - - assert.Equal(t, 201, r.StatusCode) - assert.Equal(t, "WORLD", string(b)) - - err = r.Body.Close() - assert.NoError(t, err) - - req, err = http.NewRequest("GET", "http://localhost:18903/halt", nil) - assert.NoError(t, err) - - r, err = http.DefaultClient.Do(req) - assert.NoError(t, err) - b, err = ioutil.ReadAll(r.Body) - assert.NoError(t, err) - - assert.Equal(t, 500, r.StatusCode) - assert.Equal(t, "halted", string(b)) - - err = r.Body.Close() - assert.NoError(t, err) -} - -func TestHttpEchoErr(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-echoErr.yaml", - Prefix: "rr", - } - - controller := gomock.NewController(t) - mockLogger := mocks.NewMockLogger(controller) - - mockLogger.EXPECT().Debug("http handler response received", "elapsed", gomock.Any(), "remote address", "127.0.0.1") - mockLogger.EXPECT().Debug("WORLD", "pid", gomock.Any()) - mockLogger.EXPECT().Debug("worker event received", "event", events.EventWorkerLog, "worker state", gomock.Any()) - - err = cont.RegisterAll( - cfg, - mockLogger, - &server.Plugin{}, - &httpPlugin.Plugin{}, - &PluginMiddleware{}, - &PluginMiddleware2{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - tt := time.NewTimer(time.Second * 10) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-tt.C: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 1) - t.Run("HttpEchoError", echoError) - wg.Wait() -} - -func echoError(t *testing.T) { - req, err := http.NewRequest("GET", "http://localhost:8080?hello=world", nil) - assert.NoError(t, err) - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - - b, err := ioutil.ReadAll(r.Body) - assert.NoError(t, err) - - assert.Equal(t, 201, r.StatusCode) - assert.Equal(t, "WORLD", string(b)) - err = r.Body.Close() - assert.NoError(t, err) -} - -func TestHttpEnvVariables(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-env.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &logger.ZapLogger{}, - &server.Plugin{}, - &httpPlugin.Plugin{}, - &PluginMiddleware{}, - &PluginMiddleware2{}, - ) - assert.NoError(t, err) - - err = cont.Init() - if err != nil { - t.Fatal(err) - } - - ch, err := cont.Serve() - assert.NoError(t, err) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - wg := &sync.WaitGroup{} - wg.Add(1) - - tt := time.NewTimer(time.Second * 10) - - go func() { - defer wg.Done() - for { - select { - case e := <-ch: - assert.Fail(t, "error", e.Error.Error()) - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - case <-sig: - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - case <-tt.C: - // timeout - err = cont.Stop() - if err != nil { - assert.FailNow(t, "error", err.Error()) - } - return - } - } - }() - - time.Sleep(time.Second * 1) - t.Run("EnvVariablesTest", envVarsTest) - wg.Wait() -} - -func envVarsTest(t *testing.T) { - req, err := http.NewRequest("GET", "http://localhost:12084", nil) - assert.NoError(t, err) - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - - b, err := ioutil.ReadAll(r.Body) - assert.NoError(t, err) - - assert.Equal(t, 200, r.StatusCode) - assert.Equal(t, "ENV_VALUE", string(b)) - - err = r.Body.Close() - assert.NoError(t, err) -} - -func TestHttpBrokenPipes(t *testing.T) { - cont, err := endure.NewContainer(nil, endure.SetLogLevel(endure.ErrorLevel)) - assert.NoError(t, err) - - cfg := &config.Viper{ - Path: "configs/.rr-broken-pipes.yaml", - Prefix: "rr", - } - - err = cont.RegisterAll( - cfg, - &logger.ZapLogger{}, - &server.Plugin{}, - &httpPlugin.Plugin{}, - &PluginMiddleware{}, - &PluginMiddleware2{}, - ) - assert.NoError(t, err) - - err = cont.Init() - assert.Error(t, err) - - _, err = cont.Serve() - assert.Error(t, err) -} - -func get(url string) (string, *http.Response, error) { - r, err := http.Get(url) - if err != nil { - return "", nil, err - } - b, err := ioutil.ReadAll(r.Body) - if err != nil { - return "", nil, err - } - defer func() { - _ = r.Body.Close() - }() - return string(b), r, err -} - -// get request and return body -func getHeader(url string, h map[string]string) (string, *http.Response, error) { - req, err := http.NewRequest("GET", url, bytes.NewBuffer(nil)) - if err != nil { - return "", nil, err - } - - for k, v := range h { - req.Header.Set(k, v) - } - - r, err := http.DefaultClient.Do(req) - if err != nil { - return "", nil, err - } - - 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 -} diff --git a/plugins/http/tests/parse_test.go b/plugins/http/tests/parse_test.go deleted file mode 100644 index a93bc059..00000000 --- a/plugins/http/tests/parse_test.go +++ /dev/null @@ -1,54 +0,0 @@ -package tests - -import ( - "testing" - - "github.com/spiral/roadrunner/v2/plugins/http" -) - -var samples = []struct { - in string - out []string -}{ - {"key", []string{"key"}}, - {"key[subkey]", []string{"key", "subkey"}}, - {"key[subkey]value", []string{"key", "subkey", "value"}}, - {"key[subkey][value]", []string{"key", "subkey", "value"}}, - {"key[subkey][value][]", []string{"key", "subkey", "value", ""}}, - {"key[subkey] [value][]", []string{"key", "subkey", "value", ""}}, - {"key [ subkey ] [ value ] [ ]", []string{"key", "subkey", "value", ""}}, -} - -func Test_FetchIndexes(t *testing.T) { - for i := 0; i < len(samples); i++ { - r := http.FetchIndexes(samples[i].in) - if !same(r, samples[i].out) { - t.Errorf("got %q, want %q", r, samples[i].out) - } - } -} - -func BenchmarkConfig_FetchIndexes(b *testing.B) { - for _, tt := range samples { - for n := 0; n < b.N; n++ { - r := http.FetchIndexes(tt.in) - if !same(r, tt.out) { - b.Fail() - } - } - } -} - -func same(in, out []string) bool { - if len(in) != len(out) { - return false - } - - for i, v := range in { - if v != out[i] { - return false - } - } - - return true -} diff --git a/plugins/http/tests/plugin1.go b/plugins/http/tests/plugin1.go deleted file mode 100644 index 7e5c03da..00000000 --- a/plugins/http/tests/plugin1.go +++ /dev/null @@ -1,27 +0,0 @@ -package tests - -import ( - "github.com/spiral/roadrunner/v2/interfaces/config" -) - -type Plugin1 struct { - config config.Configurer -} - -func (p1 *Plugin1) Init(cfg config.Configurer) error { - p1.config = cfg - return nil -} - -func (p1 *Plugin1) Serve() chan error { - errCh := make(chan error, 1) - return errCh -} - -func (p1 *Plugin1) Stop() error { - return nil -} - -func (p1 *Plugin1) Name() string { - return "http_test.plugin1" -} diff --git a/plugins/http/tests/plugin_middleware.go b/plugins/http/tests/plugin_middleware.go deleted file mode 100644 index 9003c0ad..00000000 --- a/plugins/http/tests/plugin_middleware.go +++ /dev/null @@ -1,61 +0,0 @@ -package tests - -import ( - "net/http" - - "github.com/spiral/roadrunner/v2/interfaces/config" -) - -type PluginMiddleware struct { - config config.Configurer -} - -func (p *PluginMiddleware) Init(cfg config.Configurer) error { - p.config = cfg - return nil -} - -func (p *PluginMiddleware) Middleware(next http.Handler) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - if r.URL.Path == "/halt" { - w.WriteHeader(500) - _, err := w.Write([]byte("halted")) - if err != nil { - panic("error writing the data to the http reply") - } - } else { - next.ServeHTTP(w, r) - } - } -} - -func (p *PluginMiddleware) Name() string { - return "pluginMiddleware" -} - -type PluginMiddleware2 struct { - config config.Configurer -} - -func (p *PluginMiddleware2) Init(cfg config.Configurer) error { - p.config = cfg - return nil -} - -func (p *PluginMiddleware2) Middleware(next http.Handler) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - if r.URL.Path == "/boom" { - w.WriteHeader(555) - _, err := w.Write([]byte("boom")) - if err != nil { - panic("error writing the data to the http reply") - } - } else { - next.ServeHTTP(w, r) - } - } -} - -func (p *PluginMiddleware2) Name() string { - return "pluginMiddleware2" -} diff --git a/plugins/http/tests/response_test.go b/plugins/http/tests/response_test.go deleted file mode 100644 index 7901a0d1..00000000 --- a/plugins/http/tests/response_test.go +++ /dev/null @@ -1,163 +0,0 @@ -package tests - -import ( - "bytes" - "errors" - "net/http" - "testing" - - "github.com/spiral/roadrunner/v2/pkg/payload" - http2 "github.com/spiral/roadrunner/v2/plugins/http" - "github.com/stretchr/testify/assert" -) - -type testWriter struct { - h http.Header - buf bytes.Buffer - wroteHeader bool - code int - err error - pushErr error - pushes []string -} - -func (tw *testWriter) Header() http.Header { return tw.h } - -func (tw *testWriter) Write(p []byte) (int, error) { - if !tw.wroteHeader { - tw.WriteHeader(http.StatusOK) - } - - n, e := tw.buf.Write(p) - if e == nil { - e = tw.err - } - - return n, e -} - -func (tw *testWriter) WriteHeader(code int) { tw.wroteHeader = true; tw.code = code } - -func (tw *testWriter) Push(target string, opts *http.PushOptions) error { - tw.pushes = append(tw.pushes, target) - - return tw.pushErr -} - -func TestNewResponse_Error(t *testing.T) { - r, err := http2.NewResponse(payload.Payload{Context: []byte(`invalid payload`)}) - assert.Error(t, err) - assert.Nil(t, r) -} - -func TestNewResponse_Write(t *testing.T) { - r, err := http2.NewResponse(payload.Payload{ - Context: []byte(`{"headers":{"key":["value"]},"status": 301}`), - Body: []byte(`sample body`), - }) - - assert.NoError(t, err) - assert.NotNil(t, r) - - w := &testWriter{h: http.Header(make(map[string][]string))} - assert.NoError(t, r.Write(w)) - - assert.Equal(t, 301, w.code) - assert.Equal(t, "value", w.h.Get("key")) - assert.Equal(t, "sample body", w.buf.String()) -} - -func TestNewResponse_Stream(t *testing.T) { - r, err := http2.NewResponse(payload.Payload{ - Context: []byte(`{"headers":{"key":["value"]},"status": 301}`), - }) - - // r is pointer, so, it might be nil - if r == nil { - t.Fatal("response is nil") - } - - r.Body = &bytes.Buffer{} - r.Body.(*bytes.Buffer).WriteString("hello world") - - assert.NoError(t, err) - assert.NotNil(t, r) - - w := &testWriter{h: http.Header(make(map[string][]string))} - assert.NoError(t, r.Write(w)) - - assert.Equal(t, 301, w.code) - assert.Equal(t, "value", w.h.Get("key")) - assert.Equal(t, "hello world", w.buf.String()) -} - -func TestNewResponse_StreamError(t *testing.T) { - r, err := http2.NewResponse(payload.Payload{ - Context: []byte(`{"headers":{"key":["value"]},"status": 301}`), - }) - - // r is pointer, so, it might be nil - if r == nil { - t.Fatal("response is nil") - } - - r.Body = &bytes.Buffer{} - r.Body.(*bytes.Buffer).WriteString("hello world") - - assert.NoError(t, err) - assert.NotNil(t, r) - - w := &testWriter{h: http.Header(make(map[string][]string)), err: errors.New("error")} - assert.Error(t, r.Write(w)) -} - -func TestWrite_HandlesPush(t *testing.T) { - r, err := http2.NewResponse(payload.Payload{ - Context: []byte(`{"headers":{"Http2-Push":["/test.js"],"content-type":["text/html"]},"status": 200}`), - }) - - assert.NoError(t, err) - assert.NotNil(t, r) - - w := &testWriter{h: http.Header(make(map[string][]string))} - assert.NoError(t, r.Write(w)) - - assert.Nil(t, w.h["Http2-Push"]) - assert.Equal(t, []string{"/test.js"}, w.pushes) -} - -func TestWrite_HandlesTrailers(t *testing.T) { - r, err := http2.NewResponse(payload.Payload{ - Context: []byte(`{"headers":{"Trailer":["foo, bar", "baz"],"foo":["test"],"bar":["demo"]},"status": 200}`), - }) - - assert.NoError(t, err) - assert.NotNil(t, r) - - w := &testWriter{h: http.Header(make(map[string][]string))} - assert.NoError(t, r.Write(w)) - - assert.Nil(t, w.h[http2.TrailerHeaderKey]) - assert.Nil(t, w.h["foo"]) //nolint:golint,staticcheck - assert.Nil(t, w.h["baz"]) //nolint:golint,staticcheck - - assert.Equal(t, "test", w.h.Get("Trailer:foo")) - assert.Equal(t, "demo", w.h.Get("Trailer:bar")) -} - -func TestWrite_HandlesHandlesWhitespacesInTrailer(t *testing.T) { - r, err := http2.NewResponse(payload.Payload{ - Context: []byte( - `{"headers":{"Trailer":["foo\t,bar , baz"],"foo":["a"],"bar":["b"],"baz":["c"]},"status": 200}`), - }) - - assert.NoError(t, err) - assert.NotNil(t, r) - - w := &testWriter{h: http.Header(make(map[string][]string))} - assert.NoError(t, r.Write(w)) - - assert.Equal(t, "a", w.h.Get("Trailer:foo")) - assert.Equal(t, "b", w.h.Get("Trailer:bar")) - assert.Equal(t, "c", w.h.Get("Trailer:baz")) -} diff --git a/plugins/http/tests/uploads_config_test.go b/plugins/http/tests/uploads_config_test.go deleted file mode 100644 index 497cd54f..00000000 --- a/plugins/http/tests/uploads_config_test.go +++ /dev/null @@ -1,26 +0,0 @@ -package tests - -import ( - "os" - "testing" - - "github.com/spiral/roadrunner/v2/plugins/http" - "github.com/stretchr/testify/assert" -) - -func TestFsConfig_Forbids(t *testing.T) { - cfg := http.UploadsConfig{Forbid: []string{".php"}} - - assert.True(t, cfg.Forbids("index.php")) - assert.True(t, cfg.Forbids("index.PHP")) - assert.True(t, cfg.Forbids("phpadmin/index.bak.php")) - assert.False(t, cfg.Forbids("index.html")) -} - -func TestFsConfig_TmpFallback(t *testing.T) { - cfg := http.UploadsConfig{Dir: "test"} - assert.Equal(t, "test", cfg.TmpDir()) - - cfg = http.UploadsConfig{Dir: ""} - assert.Equal(t, os.TempDir(), cfg.TmpDir()) -} diff --git a/plugins/http/tests/uploads_test.go b/plugins/http/tests/uploads_test.go deleted file mode 100644 index f255ec91..00000000 --- a/plugins/http/tests/uploads_test.go +++ /dev/null @@ -1,432 +0,0 @@ -package tests - -import ( - "bytes" - "context" - "crypto/sha512" - "encoding/hex" - "fmt" - "io" - "io/ioutil" - "mime/multipart" - "net/http" - "os" - "os/exec" - "testing" - "time" - - j "github.com/json-iterator/go" - "github.com/spiral/roadrunner/v2/pkg/pipe" - poolImpl "github.com/spiral/roadrunner/v2/pkg/pool" - httpPlugin "github.com/spiral/roadrunner/v2/plugins/http" - "github.com/stretchr/testify/assert" -) - -var json = j.ConfigCompatibleWithStandardLibrary - -const testFile = "uploads_test.go" - -func TestHandler_Upload_File(t *testing.T) { - pool, err := poolImpl.NewPool(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../../tests/http/client.php", "upload", "pipes") }, - pipe.NewPipeFactory(), - poolImpl.Config{ - NumWorkers: 1, - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - t.Fatal(err) - } - - h, err := httpPlugin.NewHandler(1024, httpPlugin.UploadsConfig{ - Dir: os.TempDir(), - Forbid: []string{}, - }, nil, pool) - assert.NoError(t, err) - - hs := &http.Server{Addr: ":8021", Handler: h} - 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(testFile) - 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) - _, err = io.Copy(fw, f) - if err != nil { - t.Errorf("error copying the file: error %v", err) - } - - 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) - - req.Header.Set("Content-Type", w.FormDataContentType()) - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - 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) - - assert.NoError(t, err) - assert.Equal(t, 200, r.StatusCode) - - fs := fileString(testFile, 0, "application/octet-stream") - - assert.Equal(t, `{"upload":`+fs+`}`, string(b)) -} - -func TestHandler_Upload_NestedFile(t *testing.T) { - pool, err := poolImpl.NewPool(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../../tests/http/client.php", "upload", "pipes") }, - pipe.NewPipeFactory(), - poolImpl.Config{ - NumWorkers: 1, - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - t.Fatal(err) - } - - h, err := httpPlugin.NewHandler(1024, httpPlugin.UploadsConfig{ - Dir: os.TempDir(), - Forbid: []string{}, - }, nil, pool) - assert.NoError(t, err) - - hs := &http.Server{Addr: ":8021", Handler: h} - 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(testFile) - 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) - _, err = io.Copy(fw, f) - if err != nil { - t.Errorf("error copying the file: error %v", err) - } - - 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) - - req.Header.Set("Content-Type", w.FormDataContentType()) - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - 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) - - assert.NoError(t, err) - assert.Equal(t, 200, r.StatusCode) - - fs := fileString(testFile, 0, "application/octet-stream") - - assert.Equal(t, `{"upload":{"x":{"y":{"z":[`+fs+`]}}}}`, string(b)) -} - -func TestHandler_Upload_File_NoTmpDir(t *testing.T) { - pool, err := poolImpl.NewPool(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../../tests/http/client.php", "upload", "pipes") }, - pipe.NewPipeFactory(), - poolImpl.Config{ - NumWorkers: 1, - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - t.Fatal(err) - } - - h, err := httpPlugin.NewHandler(1024, httpPlugin.UploadsConfig{ - Dir: "-------", - Forbid: []string{}, - }, nil, pool) - assert.NoError(t, err) - - hs := &http.Server{Addr: ":8021", Handler: h} - 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(testFile) - 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) - _, err = io.Copy(fw, f) - if err != nil { - t.Errorf("error copying the file: error %v", err) - } - - 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) - - req.Header.Set("Content-Type", w.FormDataContentType()) - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - 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) - - assert.NoError(t, err) - assert.Equal(t, 200, r.StatusCode) - - fs := fileString(testFile, 6, "application/octet-stream") - - assert.Equal(t, `{"upload":`+fs+`}`, string(b)) -} - -func TestHandler_Upload_File_Forbids(t *testing.T) { - pool, err := poolImpl.NewPool(context.Background(), - func() *exec.Cmd { return exec.Command("php", "../../../tests/http/client.php", "upload", "pipes") }, - pipe.NewPipeFactory(), - poolImpl.Config{ - NumWorkers: 1, - AllocateTimeout: time.Second * 1000, - DestroyTimeout: time.Second * 1000, - }) - if err != nil { - t.Fatal(err) - } - - h, err := httpPlugin.NewHandler(1024, httpPlugin.UploadsConfig{ - Dir: os.TempDir(), - Forbid: []string{".go"}, - }, nil, pool) - assert.NoError(t, err) - - hs := &http.Server{Addr: ":8021", Handler: h} - 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(testFile) - 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) - _, err = io.Copy(fw, f) - if err != nil { - t.Errorf("error copying the file: error %v", err) - } - - 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) - - req.Header.Set("Content-Type", w.FormDataContentType()) - - r, err := http.DefaultClient.Do(req) - assert.NoError(t, err) - 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) - - assert.NoError(t, err) - assert.Equal(t, 200, r.StatusCode) - - fs := fileString(testFile, 8, "application/octet-stream") - - assert.Equal(t, `{"upload":`+fs+`}`, string(b)) -} - -func Test_FileExists(t *testing.T) { - assert.True(t, exists(testFile)) - assert.False(t, exists("uploads_test.")) -} - -func mustOpen(f string) *os.File { - r, err := os.Open(f) - if err != nil { - panic(err) - } - return r -} - -type fInfo struct { - Name string `json:"name"` - Size int64 `json:"size"` - Mime string `json:"mime"` - Error int `json:"error"` - Sha512 string `json:"sha512,omitempty"` -} - -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)) - } - }() - - h := sha512.New() - _, 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: errNo, - Mime: mime, - Sha512: hex.EncodeToString(h.Sum(nil)), - } - - if errNo != 0 { - v.Sha512 = "" - v.Size = 0 - } - - r, err := json.Marshal(v) - if err != nil { - fmt.Println(fmt.Errorf("error marshalling fInfo, error: %v", err)) - } - return string(r) -} - -// exists if file exists. -func exists(path string) bool { - if _, err := os.Stat(path); os.IsNotExist(err) { - return false - } - return true -} |