diff --git a/pkg/flags/urls.go b/pkg/flags/urls.go index 69f26d6dcad..2cbd26cdc5e 100644 --- a/pkg/flags/urls.go +++ b/pkg/flags/urls.go @@ -14,12 +14,9 @@ package flags import ( - "net" - "net/url" "strings" "github.com/pingcap/errors" - cerror "github.com/pingcap/ticdc/pkg/errors" "github.com/pingcap/ticdc/pkg/types" ) @@ -39,14 +36,6 @@ func (us *URLsValue) Set(s string) error { return nil } -func (us *URLsValue) String() string { - all := make([]string, len(*us)) - for i, u := range *us { - all[i] = u.String() - } - return strings.Join(all, ",") -} - // HostString return a string of host:port format list separated by comma func (us *URLsValue) HostString() string { all := make([]string, len(*us)) @@ -56,61 +45,9 @@ func (us *URLsValue) HostString() string { return strings.Join(all, ",") } -// StringSlice return a slice of string with formatted URL -func (us *URLsValue) StringSlice() []string { - all := make([]string, len(*us)) - for i, u := range *us { - all[i] = u.String() - } - return all -} - -// URLSlice return a slice of URLs -func (us *URLsValue) URLSlice() []url.URL { - urls := []url.URL(*us) - return urls -} - // NewURLsValue return a URLsValue from a string of URLs list func NewURLsValue(init string) (*URLsValue, error) { v := &URLsValue{} err := v.Set(init) return v, err } - -// ParseHostPortAddr returns a scheme://host:port or host:port list -func ParseHostPortAddr(s string) ([]string, error) { - strs := strings.Split(s, ",") - addrs := make([]string, 0, len(strs)) - - for _, str := range strs { - str = strings.TrimSpace(str) - - // str may looks like 127.0.0.1:8000 - if _, _, err := net.SplitHostPort(str); err == nil { - addrs = append(addrs, str) - continue - } - - u, err := url.Parse(str) - if err != nil { - return nil, cerror.WrapError(cerror.ErrURLFormatInvalid, - errors.Errorf("parse url %s failed %v", str, err)) - } - if u.Scheme != "http" && u.Scheme != "https" && u.Scheme != "unix" && u.Scheme != "unixs" { - return nil, cerror.WrapError(cerror.ErrURLFormatInvalid, - errors.Errorf("URL scheme must be http, https, unix, or unixs: %s", str)) - } - if _, _, err := net.SplitHostPort(u.Host); err != nil { - return nil, cerror.WrapError(cerror.ErrURLFormatInvalid, - errors.Errorf(`URL address does not have the form "host:port": %s`, str)) - } - if u.Path != "" { - return nil, cerror.WrapError(cerror.ErrURLFormatInvalid, - errors.Errorf("URL must not contain a path: %s", str)) - } - addrs = append(addrs, u.String()) - } - - return addrs, nil -} diff --git a/pkg/flags/urls_test.go b/pkg/flags/urls_test.go index 41c3e89913f..5fc16e91947 100644 --- a/pkg/flags/urls_test.go +++ b/pkg/flags/urls_test.go @@ -16,59 +16,47 @@ package flags import ( "testing" - . "github.com/pingcap/check" + "github.com/pingcap/check" ) func Test(t *testing.T) { - TestingT(t) + check.TestingT(t) } -var _ = Suite(&testUrlsSuite{}) +var _ = check.Suite(&testUrlsSuite{}) type testUrlsSuite struct{} -func (t *testUrlsSuite) TestParseHostPortAddr(c *C) { - urls := []string{ - "127.0.0.1:2379", - "127.0.0.1:2379,127.0.0.2:2379", - "localhost:2379", - "pump-1:8250,pump-2:8250", - "http://127.0.0.1:2379", - "https://127.0.0.1:2379", - "http://127.0.0.1:2379,http://127.0.0.2:2379", - "https://127.0.0.1:2379,https://127.0.0.2:2379", - "unix:///home/tidb/tidb.sock", - } - - expectUrls := [][]string{ - {"127.0.0.1:2379"}, - {"127.0.0.1:2379", "127.0.0.2:2379"}, - {"localhost:2379"}, - {"pump-1:8250", "pump-2:8250"}, - {"http://127.0.0.1:2379"}, - {"https://127.0.0.1:2379"}, - {"http://127.0.0.1:2379", "http://127.0.0.2:2379"}, - {"https://127.0.0.1:2379", "https://127.0.0.2:2379"}, - {"unix:///home/tidb/tidb.sock"}, +func (t *testUrlsSuite) TestNewURLsValue(c *check.C) { + cases := []struct { + url string + hostString string + }{ + {"http://127.0.0.1:2379", "127.0.0.1:2379"}, + {"http://127.0.0.1:2379,http://127.0.0.1:2380", "127.0.0.1:2379,127.0.0.1:2380"}, + {"http://pd-1:2379,http://pd-2:2380", "pd-1:2379,pd-2:2380"}, + {"https://127.0.0.1:2379,https://127.0.0.1:2380", "127.0.0.1:2379,127.0.0.1:2380"}, + // TODO: unix socket not supported now + // {"unix:///home/tidb/tidb.sock", "/home/tidb/tidb.sock"}, } - for i, url := range urls { - urlList, err := ParseHostPortAddr(url) - c.Assert(err, Equals, nil) - c.Assert(len(urlList), Equals, len(expectUrls[i])) - for j, u := range urlList { - c.Assert(u, Equals, expectUrls[i][j]) - } + for _, testCase := range cases { + urlsValue, err := NewURLsValue(testCase.url) + c.Assert(err, check.IsNil) + hs := urlsValue.HostString() + c.Assert(hs, check.Equals, testCase.hostString) } +} - inValidUrls := []string{ - "127.0.0.1", - "http:///127.0.0.1:2379", - "htt://127.0.0.1:2379", +func (t *testUrlsSuite) TestNewURLsValueError(c *check.C) { + urls := []string{ + "http:///192.168.199.111:2379", + "http://192.168.199.111", + "127.0.0.1:1080", + "http://192.168.199.112:8080/api/v1", } - - for _, url := range inValidUrls { - _, err := ParseHostPortAddr(url) - c.Assert(err, NotNil) + for _, url := range urls { + _, err := NewURLsValue(url) + c.Assert(err, check.NotNil) } } diff --git a/pkg/httputil/_certificates/ca.pem b/pkg/httputil/_certificates/ca.pem new file mode 100644 index 00000000000..49098d653c7 --- /dev/null +++ b/pkg/httputil/_certificates/ca.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDgDCCAmigAwIBAgIUHWvlRJydvYTR0ot3b8f6IlSHcGUwDQYJKoZIhvcNAQEL +BQAwVzELMAkGA1UEBhMCQ04xEDAOBgNVBAgTB0JlaWppbmcxEDAOBgNVBAcTB0Jl +aWppbmcxEDAOBgNVBAoTB1BpbmdDQVAxEjAQBgNVBAMTCU15IG93biBDQTAgFw0y +MDAyMTgwNzQxMDBaGA8yMTIwMDEyNTA3NDEwMFowVzELMAkGA1UEBhMCQ04xEDAO +BgNVBAgTB0JlaWppbmcxEDAOBgNVBAcTB0JlaWppbmcxEDAOBgNVBAoTB1BpbmdD +QVAxEjAQBgNVBAMTCU15IG93biBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBAOAdNtjanFhPaKJHQjr7+h/Cpps5bLc6S1vmgi/EIi9PKv3eyDgtlW1r +As2sjXRMHjcuZp2hHJ9r9FrMQD1rQQq5vJzQqM+eyWLc2tyZWXNWkZVvpjU4Hy5k +jZFLXoyHgAvps/LGu81F5Lk5CvLHswWTyGQUCFi1l/cYcQg6AExh2pO/WJu4hQhe +1mBBIKsJhZ5b5tWruLeI+YIjD1oo1ADMHYLK1BHON2fUmUHRGbrYKu4yCuyip3wn +rbVlpabn7l1JBMatCUJLHR6VWQ2MNjrOXAEUYm4xGEN+tUYyUOGl5mHFguLl3OIn +wj+1dT3WOr/NraPYlwVOnAd9GNbPJj0CAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEG +MA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJ0CEqxLwEpI6J2gYJRg15oWZrj/ +MA0GCSqGSIb3DQEBCwUAA4IBAQCf8xRf7q1xAaGrc9HCPvN4OFkxDwz1CifrvrLR +ZgIWGUdCHDW2D1IiWKZQWeJKC1otA5x0hrS5kEGfkLFhADEU4txwp70DQaBArPti +pSgheIEbaT0H3BUTYSgS3VL2HjxN5OVMN6jNG3rWyxnJpNOCsJhhJXPK50CRZ7fk +Dcodj6FfEM2bfp2bGkxyVtUch7eepfUVbslXa7jE7Y8M3cr9NoLUcSP6D1RJWkNd +dBQoUsb6Ckq27ozEKOgwuBVv4BrrbFN//+7WHP8Vy6sSMyd+dJLBi6wehJjQhIz6 +vqLWE81rSJuxZqjLpCkFdeEF+9SRjWegU0ZDM4V+YeX53BPC +-----END CERTIFICATE----- diff --git a/pkg/httputil/_certificates/client-key.pem b/pkg/httputil/_certificates/client-key.pem new file mode 100644 index 00000000000..43b021796ec --- /dev/null +++ b/pkg/httputil/_certificates/client-key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEA06qb7HABWHrU4CvBUO/2hXGgobi/UlTqTrYGZoJqSrvhKCP6 +HOivZjyWaSMDIfrguN+0C+bd80/5XGMmwjDt8PuZ+Ef3jcJLuB1e+Kms0s5tiTng +6Z028PkSpGvKXjPebWu7zoxVpDcTGM6MmlZQqpOuIgwi+7WX/bIgIu9wooCvJEGq +hScG2wpvK3txnpsVA4eXXdFoH0R5mtqbxVFfhwKMDqga4pRwJStLTDiMrtUz+OKc +rMIrkH4ndhvm2UYTVvhHlkZ3ooeDYsu40NnvedwaE+Ii7EnmcSDF9PaCVrXSK9F/ +KNRXX/x67PMWCVqcNyGtRsCuDe7FnDfGpudVXwIDAQABAoIBAHAzW/v1U4FHe1hp +WUxCJ3eNSAzyFdja0mlu6+2i7B05gpz4lTiFz5RuQXzx5lM43a6iRpqYgsbbed+T +X5RIw5iehnuqCnvGpsSuLQ27Q7VrX30ChUrQ37LVFSC7Usak0B9IoIFYun0WBLV9 +p+KYJqKFLiU2McUj+bGtnoNmUVqRzXQosoQue/pS9OknZ3NU7FxiyI3o4ME8rDvv +9x4vc1zcqbGXTQB224kOT0xoYt8RTmIbHvkR6/yszAtHDBcdzhINVuf38lv9FvaN +FxymwsY4IKPumQZlOEzHvSnpHTrwBMFdXjqpX1VxQb3yznEK+01MHf/tYsiU57IS +WVQMTeECgYEA7Fk0w66LGgdeeWrNTSTBCBPTofDVmR7Tro6k++5XTRt552ZoVz2l +8Lfi/Px5hIyve9gnM7slWrQ72JIQ5xVYZHtic3iwVFuRAD/QVfWU/SNsRsSB/93M +3BEumwJA6vN/qvkZueos3LOxN8kExk6GD0wIl6HjTeJPbbPHqmk6Pr0CgYEA5UQI +skaj8QGpjG8Hc10FeJpYsZiZA7gJaNu4RPqBj+1RHu/eYrL2mouooZdJfIJTmlTz +4NJcfb+Dl6qwbHUQ3mddhauFu1/YRwmaR5QKjwaBdeZbly9ljsRISFpjtosc7IBA +/Bl83xtbCboMdm7cH49X2CgRQ1uVFWraye0MBEsCgYEA43vtHFdYjaIAHa9dkV3J +6aNjtF/gxzNznXSwecfrAU1r5PydezLcEDh94vCDacAbe4EOIm2Dw6zsWUQlvrW9 +0WEs3mWQmnFTvECvnrz0PT2mDus/EO4EKuDi0dG2eC4MeJywVVB/A6J09XOnA9Q6 +lmihcIkiBinIN5etm2kS5aUCgYBCdcRnmZ6woKC7uvvX72FEosmPQgMpVtIzeW4j +YNLqHAtmAnbe+a4PAukxXp/I3ibKGFJSG+j/8uJ8tthJuG3ZavFrbFtqA9C4VwpI +MZwV9fbVbJ+kZfL0veWOQ9Wf9xe9Xzh3XBQcwNtVKH+wXVamN3FpkcPfWM8Q1Fb0 +LilLnQKBgQCq7+YlSnQX0rbmPTXVVb+B12rbqLDnqA0EuaVGrdu9zPPT04e5fpHU +SD33ibaEyeOF+zLg8T53whDbLJ0tURhUk+BlLTjdd99NXtyGMlfDnIsCnAeJhY8f +Iki6LYbbP2uWV4/5IDy9XW7J42Pfl9QyEVXq+PfTyPPjXC9/J4GOuw== +-----END RSA PRIVATE KEY----- diff --git a/pkg/httputil/_certificates/client.pem b/pkg/httputil/_certificates/client.pem new file mode 100644 index 00000000000..7dace2f9d60 --- /dev/null +++ b/pkg/httputil/_certificates/client.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDfDCCAmSgAwIBAgIUaupI14PPUSshx7FmD7lsVPFahwAwDQYJKoZIhvcNAQEL +BQAwVzELMAkGA1UEBhMCQ04xEDAOBgNVBAgTB0JlaWppbmcxEDAOBgNVBAcTB0Jl +aWppbmcxEDAOBgNVBAoTB1BpbmdDQVAxEjAQBgNVBAMTCU15IG93biBDQTAgFw0y +MDAyMTgwNzQ4MDBaGA8yMTIwMDEyNTA3NDgwMFowETEPMA0GA1UEAxMGY2xpZW50 +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA06qb7HABWHrU4CvBUO/2 +hXGgobi/UlTqTrYGZoJqSrvhKCP6HOivZjyWaSMDIfrguN+0C+bd80/5XGMmwjDt +8PuZ+Ef3jcJLuB1e+Kms0s5tiTng6Z028PkSpGvKXjPebWu7zoxVpDcTGM6MmlZQ +qpOuIgwi+7WX/bIgIu9wooCvJEGqhScG2wpvK3txnpsVA4eXXdFoH0R5mtqbxVFf +hwKMDqga4pRwJStLTDiMrtUz+OKcrMIrkH4ndhvm2UYTVvhHlkZ3ooeDYsu40Nnv +edwaE+Ii7EnmcSDF9PaCVrXSK9F/KNRXX/x67PMWCVqcNyGtRsCuDe7FnDfGpudV +XwIDAQABo4GDMIGAMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcD +AjAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBRqlq/slflqw/cdlE+xNcnmmxZwlTAf +BgNVHSMEGDAWgBSdAhKsS8BKSOidoGCUYNeaFma4/zALBgNVHREEBDACggAwDQYJ +KoZIhvcNAQELBQADggEBAMGC48O77wZHZRRxXIpTQDMUSpGTKks76l+s1N7sMLrG +DCQi/XFVfV8e/Z1qs224IyU1IGXXcdwK0Zfa9owUmVmiHE8lznv7m9m7j4BGOshc +pvnJaeuUluKR/QHzwpMsUKudoEyRjn09e0Jl0/IcsKh13rzgd458XR0ShCjxybo4 +nQ1aZb1wOPLG6tpUYsV+x2Coc6TgnJWJYlDbRfpIuj6y16T1kKuWzpm6VU3kbiJ9 +/nzDgauuJHIlXEWL9dBZcpzUibFswIQyGsK7c4AJrtY1OGx0/2nZIIjtGY3gtWyX +XGV9c4kM695gl5rJndB4IPl5GQeJBCNyIaVybh7Va70= +-----END CERTIFICATE----- diff --git a/pkg/httputil/_certificates/server-key.pem b/pkg/httputil/_certificates/server-key.pem new file mode 100644 index 00000000000..2779d6ec696 --- /dev/null +++ b/pkg/httputil/_certificates/server-key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEogIBAAKCAQEAq9mcQG/nSLREM2r7s2tCKCE/1KJQvV0xmkIglFD2VDDfYW+C +mBME5LNWbYR6L0yCVHU8B7aVnw1FsbiF4TpUY3w/r4mOGl7QbGivMYvRe6Nh2xUO +TvctwFyv2FvrtBX1rZ5/8QLbz1IFHOtTV7QUzLzWq3fSAiF1vhVsS3BUmh6QvWU8 +q9dylpmUQ22otSRXmirwEzFt9K+w3VK9Z6aac7e2XRurVPxbqgQUq2bblUhii8Fc +dCUA8NenlWp+H64mN2TzVaGb5Csr7SNS7AWDEPKfoo7W3H7bzKlmRVcPeRdftwti +SI1jfboxprya/nbTyBPE/yfLU/SYn/b89epziwIDAQABAoIBACPlI08OULgN90Tq +LsLuP3ZUY5nNgaHcKnU3JMj2FE3Hm5ElkpijOF1w3Dep+T+R8pMjnbNavuvnAMy7 +ZzOBVIknNcI7sDPv5AcQ4q8trkbt/I2fW0rBNIw+j/hYUuZdw+BNABpeZ31pe2nr ++Y+TLNkLBKfyMiqBxK88mE81mmZKblyvXCawW0A/iDDJ7fPNqoGF+y9ylTYaNRPk +aJGnaEZobJ4Lm5tSqW4gRX2ft6Hm67RkvVaopPFnlkvfusXUTFUqEVQCURRUqXbf +1ah2chUHxj22UdY9540H5yVNgEP3oR+uS/hbZqxKcJUTznUW5th3CyQPIKMlGlcB +p+zWlTECgYEAxlY4zGJw4QQwGYMKLyWCSHUgKYrKu2Ub2JKJFMTdsoj9H7DI+WHf +lQaO9NCOo2lt0ofYM1MzEpI5Cl/aMrPw+mwquBbxWdMHXK2eSsUQOVo9HtUjgK2t +J2AYFCfsYndo+hCj3ApMHgiY3sghTCXeycvT52bm11VeNVcs3pKxIYMCgYEA3dAJ +PwIfAB8t+6JCP2yYH4ExNjoMNYMdXqhz4vt3UGwgskRqTW6qdd9JvrRQ/JPvGpDy +T375h/+lLw0E4ljsnOPGSzbXNf4bYRHTwPOL+LqVM4Bg90hjclqphElHChxep1di +WcdArB0oae/l4M96z3GjfnXIUVOp8K6BUQCab1kCgYAFFAQUR5j4SfEpVg+WsXEq +hcUzCxixv5785pOX8opynctNWmtq5zSgTjCu2AAu8u4a69t/ROwT16aaO2YM0kqj +Ps3BNOUtFZgkqVVaOL13mnXiKjbkfo3majFzoqoMw13uuSpY4fKc+j9fxOQFXRrd +M9jTHfFfJhJpbzf44uyiHQKBgFIPwzvyVvG+l05/Ky83x9fv/frn4thxV45LmAQj +sHKqbjZFpWZcSOgu4aOSJlwrhsw3T84lVcAAzmXn1STAbVll01jEQz6QciSpacP6 +1pAAx240UqtptpD6BbkROxz8ffA/Hf3E/6Itb2QyAsP3PqI8kpYYkTG1WCvZA7Kq +HHiRAoGAXbUZ25LcrmyuxKWpbty8fck1tjKPvclQB35rOx6vgnfW6pcKMeebYvgq +nJka/QunEReOH/kGxAd/+ymvUBuFQCfFg3Aus+DtAuh9AkBr+cIyPjJqynnIT87J +MbkOw4uEhDJAtGUR9o1j83N1f05bnEwssXiXR0LZPylb9Qzc4tg= +-----END RSA PRIVATE KEY----- diff --git a/pkg/httputil/_certificates/server.pem b/pkg/httputil/_certificates/server.pem new file mode 100644 index 00000000000..ea5ef2d5f85 --- /dev/null +++ b/pkg/httputil/_certificates/server.pem @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDjzCCAnegAwIBAgIUWBTDQm4xOYDxZBTkpCQouREtT8QwDQYJKoZIhvcNAQEL +BQAwVzELMAkGA1UEBhMCQ04xEDAOBgNVBAgTB0JlaWppbmcxEDAOBgNVBAcTB0Jl +aWppbmcxEDAOBgNVBAoTB1BpbmdDQVAxEjAQBgNVBAMTCU15IG93biBDQTAgFw0y +MDAyMTgwOTExMDBaGA8yMTIwMDEyNTA5MTEwMFowFjEUMBIGA1UEAxMLdGlkYi1z +ZXJ2ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCr2ZxAb+dItEQz +avuza0IoIT/UolC9XTGaQiCUUPZUMN9hb4KYEwTks1ZthHovTIJUdTwHtpWfDUWx +uIXhOlRjfD+viY4aXtBsaK8xi9F7o2HbFQ5O9y3AXK/YW+u0FfWtnn/xAtvPUgUc +61NXtBTMvNard9ICIXW+FWxLcFSaHpC9ZTyr13KWmZRDbai1JFeaKvATMW30r7Dd +Ur1npppzt7ZdG6tU/FuqBBSrZtuVSGKLwVx0JQDw16eVan4friY3ZPNVoZvkKyvt +I1LsBYMQ8p+ijtbcftvMqWZFVw95F1+3C2JIjWN9ujGmvJr+dtPIE8T/J8tT9Jif +9vz16nOLAgMBAAGjgZEwgY4wDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsG +AQUFBwMBBggrBgEFBQcDAjAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBRVB/Bvdzvh +6WQRWpc9SzcbXLz77zAfBgNVHSMEGDAWgBSdAhKsS8BKSOidoGCUYNeaFma4/zAP +BgNVHREECDAGhwR/AAABMA0GCSqGSIb3DQEBCwUAA4IBAQAAqg5pgGQqORKRSdlY +wzVvzKaulpvjZfVMM6YiOUtmlU0CGWq7E3gLFzkvebpU0KsFlbyZ92h/2Fw5Ay2b +kxkCy18mJ4lGkvF0cU4UD3XheFMvD2QWWRX4WPpAhStofrWOXeyq3Div2+fQjMJd +kyeWUzPU7T467IWUHOWNsFAjfVHNsmG45qLGt+XQckHTvASX5IvN+5tkRUCW30vO +b3BdDQUFglGTUFU2epaZGTti0SYiRiY+9R3zFWX4uBcEBYhk9e/0BU8FqdWW5GjI +pFpH9t64CjKIdRQXpIn4cogK/GwyuRuDPV/RkMjrIqOi7pGejXwyDe9avHFVR6re +oowA +-----END CERTIFICATE----- diff --git a/pkg/httputil/httputil_test.go b/pkg/httputil/httputil_test.go new file mode 100644 index 00000000000..40d0373ec4c --- /dev/null +++ b/pkg/httputil/httputil_test.go @@ -0,0 +1,97 @@ +// Copyright 2020 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// See the License for the specific language governing permissions and +// limitations under the License. + +package httputil + +import ( + "context" + "crypto/tls" + "fmt" + "io/ioutil" + "net" + "net/http" + "os" + "path/filepath" + "testing" + + "github.com/pingcap/check" + "github.com/pingcap/ticdc/pkg/security" + "github.com/pingcap/tidb-tools/pkg/utils" +) + +func Test(t *testing.T) { check.TestingT(t) } + +type httputilSuite struct{} + +var _ = check.Suite(&httputilSuite{}) + +var httputilServerMsg = "this is httputil test server" + +func (s *httputilSuite) TestHttputilNewClient(c *check.C) { + port := 8303 + ctx, cancel := context.WithCancel(context.Background()) + + dir, err := os.Getwd() + c.Assert(err, check.IsNil) + certDir := "_certificates" + serverTLS, err := utils.ToTLSConfigWithVerify( + filepath.Join(dir, certDir, "ca.pem"), + filepath.Join(dir, certDir, "server.pem"), + filepath.Join(dir, certDir, "server-key.pem"), + []string{}, + ) + c.Assert(err, check.IsNil) + server := runServer(ctx, serverTLS, port, c) + defer func() { + cancel() + server.Close() + }() + credential := &security.Credential{ + CAPath: filepath.Join(dir, certDir, "ca.pem"), + CertPath: filepath.Join(dir, certDir, "client.pem"), + KeyPath: filepath.Join(dir, certDir, "client-key.pem"), + CertAllowedCN: []string{}, + } + cli, err := NewClient(credential) + c.Assert(err, check.IsNil) + url := fmt.Sprintf("https://127.0.0.1:%d/", port) + resp, err := cli.Get(url) + c.Assert(err, check.IsNil) + defer resp.Body.Close() + body, err := ioutil.ReadAll(resp.Body) + c.Assert(err, check.IsNil) + c.Assert(string(body), check.Equals, httputilServerMsg) +} + +func handler(w http.ResponseWriter, req *http.Request) { + w.Header().Set("Content-Type", "text/plain") + //nolint:errcheck + w.Write([]byte(httputilServerMsg)) +} + +func runServer(ctx context.Context, tlsCfg *tls.Config, port int, c *check.C) *http.Server { + http.HandleFunc("/", handler) + server := &http.Server{Addr: fmt.Sprintf(":%d", port), Handler: nil} + + conn, err := net.Listen("tcp", server.Addr) + if err != nil { + c.Assert(err, check.IsNil) + } + + tlsListener := tls.NewListener(conn, tlsCfg) + go func() { + //nolint:errcheck + server.Serve(tlsListener) + }() + return server +} diff --git a/pkg/quotes/quotes_test.go b/pkg/quotes/quotes_test.go new file mode 100644 index 00000000000..c645c8c8ffd --- /dev/null +++ b/pkg/quotes/quotes_test.go @@ -0,0 +1,74 @@ +// Copyright 2020 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// See the License for the specific language governing permissions and +// limitations under the License. + +package quotes + +import ( + "testing" + + "github.com/pingcap/check" +) + +func Test(t *testing.T) { check.TestingT(t) } + +type quotesSuite struct{} + +var _ = check.Suite("esSuite{}) + +func (s *quotesSuite) TestQuoteSchema(c *check.C) { + cases := []struct { + schema string + table string + expected string + }{ + {"testdb", "t1", "`testdb`.`t1`"}, + {"test-db-1`2", "t`1", "`test-db-1``2`.`t``1`"}, + } + for _, testCase := range cases { + name := QuoteSchema(testCase.schema, testCase.table) + c.Assert(name, check.Equals, testCase.expected) + } +} + +func (s *quotesSuite) TestQuoteName(c *check.C) { + cases := []struct { + name string + expected string + }{ + {"tbl", "`tbl`"}, + {"t`bl", "`t``bl`"}, + {"t``bl", "`t````bl`"}, + {"", "``"}, + } + for _, testCase := range cases { + escaped := QuoteName(testCase.name) + c.Assert(escaped, check.Equals, testCase.expected) + } +} + +func (s *quotesSuite) TestEscapeName(c *check.C) { + cases := []struct { + name string + expected string + }{ + {"tbl", "tbl"}, + {"t`bl", "t``bl"}, + {"t``bl", "t````bl"}, + {"`", "``"}, + {"", ""}, + } + for _, testCase := range cases { + escaped := EscapeName(testCase.name) + c.Assert(escaped, check.Equals, testCase.expected) + } +}