Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package fortio for openSUSE:Factory checked in at 2022-03-25 21:54:44 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/fortio (Old) and /work/SRC/openSUSE:Factory/.fortio.new.1900 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "fortio" Fri Mar 25 21:54:44 2022 rev:4 rq:964802 version:1.23.0 Changes: -------- --- /work/SRC/openSUSE:Factory/fortio/fortio.changes 2022-03-20 20:55:54.390557360 +0100 +++ /work/SRC/openSUSE:Factory/.fortio.new.1900/fortio.changes 2022-03-25 21:54:58.318295255 +0100 @@ -1,0 +2,7 @@ +Fri Mar 25 09:05:18 UTC 2022 - ka...@b1-systems.de + +- Update to version 1.23.0: + * Fast client support for https/TLS (#529) + * Be consistent with precedence, query args H= will overwrite a json + +------------------------------------------------------------------- Old: ---- fortio-1.22.0.tar.gz New: ---- fortio-1.23.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ fortio.spec ++++++ --- /var/tmp/diff_new_pack.Bma3nX/_old 2022-03-25 21:54:58.922295830 +0100 +++ /var/tmp/diff_new_pack.Bma3nX/_new 2022-03-25 21:54:58.930295838 +0100 @@ -19,7 +19,7 @@ %define __arch_install_post export NO_BRP_STRIP_DEBUG=true Name: fortio -Version: 1.22.0 +Version: 1.23.0 Release: 0 Summary: Load testing library, command line tool, advanced echo server and web UI License: Apache-2.0 ++++++ _service ++++++ --- /var/tmp/diff_new_pack.Bma3nX/_old 2022-03-25 21:54:58.962295868 +0100 +++ /var/tmp/diff_new_pack.Bma3nX/_new 2022-03-25 21:54:58.966295872 +0100 @@ -3,7 +3,7 @@ <param name="url">https://github.com/fortio/fortio</param> <param name="scm">git</param> <param name="exclude">.git</param> - <param name="revision">v1.22.0</param> + <param name="revision">v1.23.0</param> <param name="versionformat">@PARENT_TAG@</param> <param name="changesgenerate">enable</param> <param name="versionrewrite-pattern">v(.*)</param> @@ -16,7 +16,7 @@ <param name="compression">gz</param> </service> <service name="go_modules" mode="disabled"> - <param name="archive">fortio-1.22.0.tar.gz</param> + <param name="archive">fortio-1.23.0.tar.gz</param> </service> </services> ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.Bma3nX/_old 2022-03-25 21:54:58.998295903 +0100 +++ /var/tmp/diff_new_pack.Bma3nX/_new 2022-03-25 21:54:59.002295907 +0100 @@ -1,6 +1,6 @@ <servicedata> <service name="tar_scm"> <param name="url">https://github.com/fortio/fortio</param> - <param name="changesrevision">b0adf910295107f689dcca6afb9fe2b397cbb977</param></service></servicedata> + <param name="changesrevision">8c28aec56c639807472392db3b0ebb3fd5d448ed</param></service></servicedata> (No newline at EOF) ++++++ fortio-1.22.0.tar.gz -> fortio-1.23.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fortio-1.22.0/README.md new/fortio-1.23.0/README.md --- old/fortio-1.22.0/README.md 2022-03-20 02:19:30.000000000 +0100 +++ new/fortio-1.23.0/README.md 2022-03-25 02:46:50.000000000 +0100 @@ -46,13 +46,13 @@ Or download one of the binary distributions, from the [releases](https://github.com/fortio/fortio/releases) assets page or for instance: ```shell -curl -L https://github.com/fortio/fortio/releases/download/v1.22.0/fortio-linux_x64-1.22.0.tgz \ +curl -L https://github.com/fortio/fortio/releases/download/v1.23.0/fortio-linux_x64-1.23.0.tgz \ | sudo tar -C / -xvzpf - # or the debian package -wget https://github.com/fortio/fortio/releases/download/v1.22.0/fortio_1.22.0_amd64.deb -dpkg -i fortio_1.22.0_amd64.deb +wget https://github.com/fortio/fortio/releases/download/v1.23.0/fortio_1.23.0_amd64.deb +dpkg -i fortio_1.23.0_amd64.deb # or the rpm -rpm -i https://github.com/fortio/fortio/releases/download/v1.22.0/fortio-1.22.0-1.x86_64.rpm +rpm -i https://github.com/fortio/fortio/releases/download/v1.23.0/fortio-1.23.0-1.x86_64.rpm ``` On a MacOS you can also install Fortio using [Homebrew](https://brew.sh/): @@ -61,7 +61,7 @@ brew install fortio ``` -On Windows, download https://github.com/fortio/fortio/releases/download/v1.22.0/fortio_win_1.22.0.zip and extract `fortio.exe` to any location, then using the Windows Command Prompt: +On Windows, download https://github.com/fortio/fortio/releases/download/v1.23.0/fortio_win_1.23.0.zip and extract `fortio.exe` to any location, then using the Windows Command Prompt: ``` fortio.exe server ``` @@ -106,7 +106,7 @@ <details> <!-- use release/updateFlags.sh to update this section --> <pre> -???????????? 1.22.0 usage: +???????????? 1.23.0 usage: where command is one of: load (load testing), server (starts ui, http-echo, redirect, proxies, tcp-echo and grpc ping servers), tcp-echo (only the tcp-echo server), report (report only UI server), redirect (only the redirect server), @@ -281,7 +281,7 @@ -static-dir path Deprecated/unused path. -stdclient - Use the slower net/http standard client (works for TLS) + Use the slower net/http standard client (slower but supports h2) -sync URL index.tsv or s3/gcs bucket xml URL to fetch at startup for server modes. -sync-interval duration @@ -675,7 +675,7 @@ "ActualQPS": 38.44836361217263, "ActualDuration": 104035637, "NumThreads": 2, - "Version": "v1.22.0", + "Version": "X.Y.Z", "DurationHistogram": { "Count": 4, "Min": 0.00027292, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fortio-1.22.0/bincommon/commonflags.go new/fortio-1.23.0/bincommon/commonflags.go --- old/fortio-1.22.0/bincommon/commonflags.go 2022-03-20 02:19:30.000000000 +0100 +++ new/fortio-1.23.0/bincommon/commonflags.go 2022-03-25 02:46:50.000000000 +0100 @@ -62,7 +62,7 @@ halfCloseFlag = flag.Bool("halfclose", false, "When not keepalive, whether to half close the connection (only for fast http)") httpReqTimeoutFlag = flag.Duration("timeout", fhttp.HTTPReqTimeOutDefaultValue, "Connection and read timeout value (for http)") - stdClientFlag = flag.Bool("stdclient", false, "Use the slower net/http standard client (works for TLS)") + stdClientFlag = flag.Bool("stdclient", false, "Use the slower net/http standard client (slower but supports h2)") http10Flag = flag.Bool("http1.0", false, "Use http1.0 (instead of http 1.1)") httpsInsecureFlag = flag.Bool("k", false, "Do not verify certs in https connections") httpsInsecureFlagL = flag.Bool("https-insecure", false, "Long form of the -k flag") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fortio-1.22.0/fhttp/http_client.go new/fortio-1.23.0/fhttp/http_client.go --- old/fortio-1.22.0/fhttp/http_client.go 2022-03-20 02:19:30.000000000 +0100 +++ new/fortio-1.23.0/fhttp/http_client.go 2022-03-25 02:46:50.000000000 +0100 @@ -142,10 +142,6 @@ } if strings.HasPrefix(lcURL, hs) { h.https = true - if !h.DisableFastClient { - log.Warnf("https requested, switching to standard go client") - h.DisableFastClient = true - } return // url is good } if !strings.HasPrefix(lcURL, "http://") { @@ -443,32 +439,9 @@ }, TLSHandshakeTimeout: o.HTTPReqTimeOut, } - if o.https { // nolint: nestif // fine for now - tr.TLSClientConfig = &tls.Config{MinVersion: tls.VersionTLS12} - if o.Insecure { - log.LogVf("Using insecure https") - tr.TLSClientConfig.InsecureSkipVerify = true - } - if len(o.Cert) > 0 && len(o.Key) > 0 { - cert, err := tls.LoadX509KeyPair(o.Cert, o.Key) - if err != nil { - log.Errf("LoadX509KeyPair error for cert %v / key %v: %v", o.Cert, o.Key, err) - return nil, err - } - tr.TLSClientConfig.Certificates = []tls.Certificate{cert} - } - if len(o.CACert) > 0 { - // Load CA cert - caCert, err := ioutil.ReadFile(o.CACert) - if err != nil { - log.Errf("Unable to read CA from %v: %v", o.CACert, err) - return nil, err - } - log.LogVf("Using custom CA from %v", o.CACert) - caCertPool := x509.NewCertPool() - caCertPool.AppendCertsFromPEM(caCert) - tr.TLSClientConfig.RootCAs = caCertPool - } + tr.TLSClientConfig, err = o.TLSClientConfig() + if err != nil { + return nil, err } client := Client{ @@ -497,6 +470,43 @@ return &client, nil } +// TLSClientConfig creates a tls.Config based on input HTTPOptions. +// ServerName is set later (once host is determined after URL parsing +// and depending on hostOverride). +func (h *HTTPOptions) TLSClientConfig() (*tls.Config, error) { + if !h.https { + return nil, nil + } + var res *tls.Config + + res = &tls.Config{MinVersion: tls.VersionTLS12} + if h.Insecure { + log.LogVf("Using insecure https") + res.InsecureSkipVerify = true + } + if len(h.Cert) > 0 && len(h.Key) > 0 { + cert, err := tls.LoadX509KeyPair(h.Cert, h.Key) + if err != nil { + log.Errf("LoadX509KeyPair error for cert %v / key %v: %v", h.Cert, h.Key, err) + return nil, err + } + res.Certificates = []tls.Certificate{cert} + } + if len(h.CACert) > 0 { + // Load CA cert + caCert, err := ioutil.ReadFile(h.CACert) + if err != nil { + log.Errf("Unable to read CA from %v: %v", h.CACert, err) + return nil, err + } + log.LogVf("Using custom CA from %v", h.CACert) + caCertPool := x509.NewCertPool() + caCertPool.AppendCertsFromPEM(caCert) + res.RootCAs = caCertPool + } + return res, nil +} + // FetchURL fetches the data at the given url using the standard client and default options. // Returns the http status code (http.StatusOK == 200 for success) and the data. // To be used only for single fetches or when performance doesn't matter as the client is closed at the end. @@ -540,6 +550,8 @@ uuidMarkers [][]byte logErrors bool id int + https bool + tlsConfig *tls.Config } // Close cleans up any resources used by FastClient. @@ -587,14 +599,15 @@ log.Errf("Bad url '%s' : %v", urlString, err) return nil, err } - if url.Scheme != "http" { - log.Errf("Only http is supported with the optimized client, use -stdclient for url %s", o.URL) - return nil, fmt.Errorf("only http for fast client") + tlsConfig, err := o.TLSClientConfig() + if err != nil { + return nil, err } // note: Host includes the port bc := FastClient{ url: o.URL, host: url.Host, hostname: url.Hostname(), port: url.Port(), http10: o.HTTP10, halfClose: o.AllowHalfClose, logErrors: o.LogErrors, id: o.ID, + https: o.https, tlsConfig: tlsConfig, } bc.buffer = make([]byte, BufferSizeKb*1024) if bc.port == "" { @@ -627,6 +640,9 @@ if customHostHeader { host = o.hostOverride } + if tlsConfig != nil { + tlsConfig.ServerName = host + } var buf bytes.Buffer buf.WriteString(method + " " + url.RequestURI() + " HTTP/" + proto + "\r\n") if !bc.http10 || customHostHeader { @@ -670,10 +686,20 @@ // connect to destination. func (c *FastClient) connect() net.Conn { c.socketCount++ - socket, err := net.Dial(c.dest.Network(), c.dest.String()) - if err != nil { - log.Errf("Unable to connect to %v : %v", c.dest, err) - return nil + var socket net.Conn + var err error + if c.https { + socket, err = tls.Dial(c.dest.Network(), c.dest.String(), c.tlsConfig) + if err != nil { + log.Errf("Unable to TLS connect to %v : %v", c.dest, err) + return nil + } + } else { + socket, err = net.Dial(c.dest.Network(), c.dest.String()) + if err != nil { + log.Errf("Unable to connect to %v : %v", c.dest, err) + return nil + } } fnet.SetSocketBuffers(socket, len(c.buffer), len(c.req)) return socket diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fortio-1.22.0/fhttp/http_test.go new/fortio-1.23.0/fhttp/http_test.go --- old/fortio-1.22.0/fhttp/http_test.go 2022-03-20 02:19:30.000000000 +0100 +++ new/fortio-1.23.0/fhttp/http_test.go 2022-03-25 02:46:50.000000000 +0100 @@ -114,27 +114,23 @@ tests := []struct { input string output string - stdcli bool }{ - {"https://www.google.com/", "https://www.google.com/", true}, - {"www.google.com", "http://www.google.com", false}, - {"hTTps://foo.bar:123/ab/cd", "hTTps://foo.bar:123/ab/cd", true}, // not double http: - {"HTTP://foo.bar:124/ab/cd", "HTTP://foo.bar:124/ab/cd", false}, // not double http: - {"", "", false}, // and error in the logs - {"x", "http://x", false}, // should not crash because url is shorter than prefix - {"http:/", "http://http:/", false}, // boundary - {"http://", "http://", false}, // boundary - {"https://", "https://", true}, // boundary - {"https:/", "http://https:/", false}, // boundary + {"https://www.google.com/", "https://www.google.com/"}, + {"www.google.com", "http://www.google.com"}, + {"hTTps://foo.bar:123/ab/cd", "hTTps://foo.bar:123/ab/cd"}, // not double http: + {"HTTP://foo.bar:124/ab/cd", "HTTP://foo.bar:124/ab/cd"}, // not double http: + {"", ""}, // and error in the logs + {"x", "http://x"}, // should not crash because url is shorter than prefix + {"http:/", "http://http:/"}, // boundary + {"http://", "http://"}, // boundary + {"https://", "https://"}, // boundary + {"https:/", "http://https:/"}, // boundary } for _, tst := range tests { o := NewHTTPOptions(tst.input) if o.URL != tst.output { t.Errorf("Got %v, expecting %v for url '%s'", o.URL, tst.output, tst.input) } - if o.DisableFastClient != tst.stdcli { - t.Errorf("Got %v, expecting %v for stdclient for url '%s'", o.DisableFastClient, tst.stdcli, tst.input) - } } } @@ -696,12 +692,7 @@ cli.Close() opts.URL = "https://fortio.org" // will be https port 443 opts.Insecure = true // not needed as we have valid certs but to exercise that code - cli, err := NewFastClient(opts) - if cli != nil || err == nil { - // If https support was added, remove this whitebox/for coverage purpose assertion - t.Errorf("fast client isn't supposed to support https (yet), got %v", cli) - } - cli, err = NewClient(opts) + cli, err := NewClient(opts) if cli == nil { t.Fatalf("Couldn't get a client using NewClient on modified opts: %v", err) } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fortio-1.22.0/ui/restHandler.go new/fortio-1.23.0/ui/restHandler.go --- old/fortio-1.22.0/ui/restHandler.go 2022-03-20 02:19:30.000000000 +0100 +++ new/fortio-1.23.0/ui/restHandler.go 2022-03-25 02:46:50.000000000 +0100 @@ -193,16 +193,6 @@ if len(payload) > 0 { httpopts.Payload = []byte(payload) } - for _, header := range r.Form["H"] { - if len(header) == 0 { - continue - } - log.LogVf("adding header %v", header) - err := httpopts.AddAndValidateExtraHeader(header) - if err != nil { - log.Errf("Error adding custom headers: %v", err) - } - } jsonHeaders, found := jd["headers"] for found { // really an if, but using while to break out without else below res, ok := jsonHeaders.([]interface{}) @@ -223,6 +213,16 @@ } break } + for _, header := range r.Form["H"] { + if len(header) == 0 { + continue + } + log.LogVf("adding query arg header %v", header) + err := httpopts.AddAndValidateExtraHeader(header) + if err != nil { + log.Errf("Error adding custom query arg headers: %v", err) + } + } fhttp.OnBehalfOf(httpopts, r) if async { w.Write([]byte(fmt.Sprintf("{\"started\": %d}", runid))) ++++++ vendor.tar.gz ++++++