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-28 17:00:58
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/fortio (Old)
 and      /work/SRC/openSUSE:Factory/.fortio.new.1900 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "fortio"

Mon Mar 28 17:00:58 2022 rev:5 rq:965309 version:1.24.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/fortio/fortio.changes    2022-03-25 
21:54:58.318295255 +0100
+++ /work/SRC/openSUSE:Factory/.fortio.new.1900/fortio.changes  2022-03-28 
17:01:52.369076287 +0200
@@ -1,0 +2,9 @@
+Mon Mar 28 07:10:20 UTC 2022 - ka...@b1-systems.de
+
+- Update to version 1.24.0:
+  * Fix #535: echo debug path normalization needed depending on whether debug 
path ends with / or not. also fix pprof link which is hardcoded to 
/debug/pprof/ (#537)
+  * refactor tlsoptions to common struct and share setup for both http and 
grpc (#536)
+  * Create SECURITY.md
+  * code scanning
+
+-------------------------------------------------------------------

Old:
----
  fortio-1.23.0.tar.gz

New:
----
  fortio-1.24.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ fortio.spec ++++++
--- /var/tmp/diff_new_pack.yF6lQx/_old  2022-03-28 17:01:53.065077232 +0200
+++ /var/tmp/diff_new_pack.yF6lQx/_new  2022-03-28 17:01:53.073077243 +0200
@@ -19,7 +19,7 @@
 %define __arch_install_post export NO_BRP_STRIP_DEBUG=true
 
 Name:           fortio
-Version:        1.23.0
+Version:        1.24.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.yF6lQx/_old  2022-03-28 17:01:53.113077298 +0200
+++ /var/tmp/diff_new_pack.yF6lQx/_new  2022-03-28 17:01:53.117077303 +0200
@@ -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.23.0</param>
+    <param name="revision">v1.24.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.23.0.tar.gz</param>
+    <param name="archive">fortio-1.24.0.tar.gz</param>
   </service>
 </services>
 

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.yF6lQx/_old  2022-03-28 17:01:53.145077341 +0200
+++ /var/tmp/diff_new_pack.yF6lQx/_new  2022-03-28 17:01:53.149077346 +0200
@@ -1,6 +1,6 @@
 <servicedata>
 <service name="tar_scm">
                 <param name="url">https://github.com/fortio/fortio</param>
-              <param 
name="changesrevision">8c28aec56c639807472392db3b0ebb3fd5d448ed</param></service></servicedata>
+              <param 
name="changesrevision">fb00657cd46406b6660f5fc1fa4894d6c426d295</param></service></servicedata>
 (No newline at EOF)
 

++++++ fortio-1.23.0.tar.gz -> fortio-1.24.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fortio-1.23.0/.github/workflows/codeql-analysis.yml 
new/fortio-1.24.0/.github/workflows/codeql-analysis.yml
--- old/fortio-1.23.0/.github/workflows/codeql-analysis.yml     1970-01-01 
01:00:00.000000000 +0100
+++ new/fortio-1.24.0/.github/workflows/codeql-analysis.yml     2022-03-28 
00:47:13.000000000 +0200
@@ -0,0 +1,70 @@
+# For most projects, this workflow file will not need changing; you simply need
+# to commit it to your repository.
+#
+# You may wish to alter this file to override the set of languages analyzed,
+# or to provide custom queries or build logic.
+#
+# ******** NOTE ********
+# We have attempted to detect the languages in your repository. Please check
+# the `language` matrix defined below to confirm you have the correct set of
+# supported CodeQL languages.
+#
+name: "CodeQL"
+
+on:
+  push:
+    branches: [ master ]
+  pull_request:
+    # The branches below must be a subset of the branches above
+    branches: [ master ]
+  schedule:
+    - cron: '21 5 * * 6'
+
+jobs:
+  analyze:
+    name: Analyze
+    runs-on: ubuntu-latest
+    permissions:
+      actions: read
+      contents: read
+      security-events: write
+
+    strategy:
+      fail-fast: false
+      matrix:
+        language: [ 'go', 'javascript' ]
+        # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 
'python', 'ruby' ]
+        # Learn more about CodeQL language support at 
https://git.io/codeql-language-support
+
+    steps:
+    - name: Checkout repository
+      uses: actions/checkout@v2
+
+    # Initializes the CodeQL tools for scanning.
+    - name: Initialize CodeQL
+      uses: github/codeql-action/init@v1
+      with:
+        languages: ${{ matrix.language }}
+        # If you wish to specify custom queries, you can do so here or in a 
config file.
+        # By default, queries listed here will override any specified in a 
config file.
+        # Prefix the list here with "+" to use these queries and those in the 
config file.
+        # queries: ./path/to/local/query, your-org/your-repo/queries@main
+
+    # Autobuild attempts to build any compiled languages  (C/C++, C#, or Java).
+    # If this step fails, then you should remove it and run the build manually 
(see below)
+    - name: Autobuild
+      uses: github/codeql-action/autobuild@v1
+
+    # ?????? Command-line programs to run using the OS shell.
+    # ???? https://git.io/JvXDl
+
+    # ?????? If the Autobuild fails above, remove it and uncomment the 
following three lines
+    #    and modify them (or add more) to build your code if your project
+    #    uses a compiled language
+
+    #- run: |
+    #   make bootstrap
+    #   make release
+
+    - name: Perform CodeQL Analysis
+      uses: github/codeql-action/analyze@v1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fortio-1.23.0/README.md new/fortio-1.24.0/README.md
--- old/fortio-1.23.0/README.md 2022-03-25 02:46:50.000000000 +0100
+++ new/fortio-1.24.0/README.md 2022-03-28 00:47:13.000000000 +0200
@@ -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.23.0/fortio-linux_x64-1.23.0.tgz
 \
+curl -L 
https://github.com/fortio/fortio/releases/download/v1.24.0/fortio-linux_x64-1.24.0.tgz
 \
  | sudo tar -C / -xvzpf -
 # or the debian package
-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
+wget 
https://github.com/fortio/fortio/releases/download/v1.24.0/fortio_1.24.0_amd64.deb
+dpkg -i fortio_1.24.0_amd64.deb
 # or the rpm
-rpm -i 
https://github.com/fortio/fortio/releases/download/v1.23.0/fortio-1.23.0-1.x86_64.rpm
+rpm -i 
https://github.com/fortio/fortio/releases/download/v1.24.0/fortio-1.24.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.23.0/fortio_win_1.23.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.24.0/fortio_win_1.24.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.23.0 usage:
+???????????? 1.24.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),
@@ -204,7 +204,7 @@
   -json path
         Json output to provided file path or '-' for stdout (empty = no json
 output, unless -a is used)
-  -k    Do not verify certs in https connections
+  -k    Do not verify certs in https/tls/grpc connections
   -keepalive
         Keep connection alive (only for fast http 1.1) (default true)
   -key Path
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fortio-1.23.0/SECURITY.md 
new/fortio-1.24.0/SECURITY.md
--- old/fortio-1.23.0/SECURITY.md       1970-01-01 01:00:00.000000000 +0100
+++ new/fortio-1.24.0/SECURITY.md       2022-03-28 00:47:13.000000000 +0200
@@ -0,0 +1,12 @@
+# Security Policy
+
+## Supported Versions
+
+| Version | Supported          |
+| ------- | ------------------ |
+| 1.23.x   | :white_check_mark: |
+
+
+## Reporting a Vulnerability
+
+Please open in Issue or contact the main author directly at ldemailly at gmail
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fortio-1.23.0/bincommon/commonflags.go 
new/fortio-1.24.0/bincommon/commonflags.go
--- old/fortio-1.23.0/bincommon/commonflags.go  2022-03-25 02:46:50.000000000 
+0100
+++ new/fortio-1.24.0/bincommon/commonflags.go  2022-03-28 00:47:13.000000000 
+0200
@@ -64,7 +64,7 @@
        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 (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")
+       httpsInsecureFlag   = flag.Bool("k", false, "Do not verify certs in 
https/tls/grpc connections")
        httpsInsecureFlagL  = flag.Bool("https-insecure", false, "Long form of 
the -k flag")
        resolve             = flag.String("resolve", "", "Resolve host name to 
this `IP`")
        headersFlags        headersFlagList
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fortio-1.23.0/fgrpc/grpcrunner.go 
new/fortio-1.24.0/fgrpc/grpcrunner.go
--- old/fortio-1.23.0/fgrpc/grpcrunner.go       2022-03-25 02:46:50.000000000 
+0100
+++ new/fortio-1.24.0/fgrpc/grpcrunner.go       2022-03-28 00:47:13.000000000 
+0200
@@ -16,7 +16,6 @@
 
 import (
        "context"
-       "crypto/tls"
        "fmt"
        "net"
        "os"
@@ -25,6 +24,7 @@
        "strings"
        "time"
 
+       "fortio.org/fortio/fhttp"
        "fortio.org/fortio/fnet"
        "fortio.org/fortio/log"
        "fortio.org/fortio/periodic"
@@ -38,20 +38,14 @@
 // it will override the virtual host name of authority in requests.
 func Dial(o *GRPCRunnerOptions) (conn *grpc.ClientConn, err error) {
        var opts []grpc.DialOption
-       switch {
-       case o.CACert != "":
-               var creds credentials.TransportCredentials
-               creds, err = credentials.NewClientTLSFromFile(o.CACert, 
o.CertOverride)
+       if o.CACert != "" || strings.HasPrefix(o.Destination, fnet.PrefixHTTPS) 
{
+               tlsConfig, err := o.TLSOptions.TLSClientConfig()
                if err != nil {
-                       log.Errf("Invalid TLS credentials: %v\n", err)
                        return nil, err
                }
-               log.Infof("Using CA certificate %v to construct TLS 
credentials", o.CACert)
-               opts = append(opts, grpc.WithTransportCredentials(creds))
-       case strings.HasPrefix(o.Destination, fnet.PrefixHTTPS):
-               creds := credentials.NewTLS(&tls.Config{InsecureSkipVerify: 
o.Insecure}) // nolint: gosec // explicit flag
-               opts = append(opts, grpc.WithTransportCredentials(creds))
-       default:
+               tlsConfig.ServerName = o.CertOverride
+               opts = append(opts, 
grpc.WithTransportCredentials(credentials.NewTLS(tlsConfig)))
+       } else {
                opts = append(opts, grpc.WithInsecure())
        }
        serverAddr := grpcDestination(o.Destination)
@@ -114,18 +108,16 @@
 // options.
 type GRPCRunnerOptions struct {
        periodic.RunnerOptions
+       fhttp.TLSOptions
        Destination        string
        Service            string        // Service to be checked when using 
grpc health check
        Profiler           string        // file to save profiles to. defaults 
to no profiling
        Payload            string        // Payload to be sent for grpc ping 
service
        Streams            int           // number of streams. total go 
routines and data streams will be streams*numthreads.
        Delay              time.Duration // Delay to be sent when using grpc 
ping service
-       CACert             string        // Path to CA certificate for grpc TLS
        CertOverride       string        // Override the cert virtual host of 
authority for testing
-       Insecure           bool          // Allow unknown CA / self signed
        AllowInitialErrors bool          // whether initial errors don't cause 
an abort
        UsePing            bool          // use our own Ping proto for grpc 
load instead of standard health check one.
-       UnixDomainSocket   string        // unix domain socket path to use for 
physical connection instead of Destination
 }
 
 // RunGRPCTest runs an http test and returns the aggregated stats.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fortio-1.23.0/fgrpc/grpcrunner_test.go 
new/fortio-1.24.0/fgrpc/grpcrunner_test.go
--- old/fortio-1.23.0/fgrpc/grpcrunner_test.go  2022-03-25 02:46:50.000000000 
+0100
+++ new/fortio-1.24.0/fgrpc/grpcrunner_test.go  2022-03-28 00:47:13.000000000 
+0200
@@ -20,6 +20,7 @@
        "testing"
        "time"
 
+       "fortio.org/fortio/fhttp"
        "fortio.org/fortio/fnet"
        "fortio.org/fortio/log"
        "fortio.org/fortio/periodic"
@@ -68,15 +69,15 @@
                        name: "valid secure runner",
                        runnerOpts: GRPCRunnerOptions{
                                Destination: sDest,
-                               CACert:      caCrt,
+                               TLSOptions:  fhttp.TLSOptions{CACert: caCrt},
                        },
                        expect: true,
                },
                {
                        name: "valid unix domain socket runner",
                        runnerOpts: GRPCRunnerOptions{
-                               Destination:      uDest,
-                               UnixDomainSocket: uPath.String(),
+                               Destination: uDest,
+                               TLSOptions:  fhttp.TLSOptions{UnixDomainSocket: 
uPath.String()},
                        },
                        expect: true,
                },
@@ -129,7 +130,7 @@
                        name: "invalid name in secure runner cert",
                        runnerOpts: GRPCRunnerOptions{
                                Destination:  sDest,
-                               CACert:       caCrt,
+                               TLSOptions:   fhttp.TLSOptions{CACert: caCrt},
                                CertOverride: "invalidName",
                        },
                        expect: false,
@@ -138,7 +139,7 @@
                        name: "invalid cert for secure runner",
                        runnerOpts: GRPCRunnerOptions{
                                Destination: sDest,
-                               CACert:      "../missing/cert.crt",
+                               TLSOptions:  fhttp.TLSOptions{CACert: 
"../missing/cert.crt"},
                        },
                        expect: false,
                },
@@ -240,7 +241,7 @@
                        name: "secure runner",
                        runnerOpts: GRPCRunnerOptions{
                                Destination: sDest,
-                               CACert:      caCrt,
+                               TLSOptions:  fhttp.TLSOptions{CACert: caCrt},
                        },
                },
                {
@@ -253,14 +254,14 @@
                        name: "invalid secure runner to insecure server",
                        runnerOpts: GRPCRunnerOptions{
                                Destination: iDest,
-                               CACert:      caCrt,
+                               TLSOptions:  fhttp.TLSOptions{CACert: caCrt},
                        },
                },
                {
                        name: "invalid name in runner cert",
                        runnerOpts: GRPCRunnerOptions{
                                Destination:  sDest,
-                               CACert:       caCrt,
+                               TLSOptions:   fhttp.TLSOptions{CACert: caCrt},
                                CertOverride: "invalidName",
                        },
                },
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fortio-1.23.0/fgrpc/pingsrv.go 
new/fortio-1.24.0/fgrpc/pingsrv.go
--- old/fortio-1.23.0/fgrpc/pingsrv.go  2022-03-25 02:46:50.000000000 +0100
+++ new/fortio-1.24.0/fgrpc/pingsrv.go  2022-03-28 00:47:13.000000000 +0200
@@ -21,6 +21,7 @@
        "os"
        "time"
 
+       "fortio.org/fortio/fhttp"
        "fortio.org/fortio/fnet"
        "fortio.org/fortio/log"
        "fortio.org/fortio/stats"
@@ -105,8 +106,8 @@
 
 // PingClientCall calls the ping service (presumably running as PingServer on
 // the destination). returns the average round trip in seconds.
-func PingClientCall(serverAddr, cacert string, n int, payload string, delay 
time.Duration, insecure bool) (float64, error) {
-       o := GRPCRunnerOptions{Destination: serverAddr, CACert: cacert, 
Insecure: insecure}
+func PingClientCall(serverAddr string, n int, payload string, delay 
time.Duration, tlsOpts *fhttp.TLSOptions) (float64, error) {
+       o := GRPCRunnerOptions{Destination: serverAddr, TLSOptions: *tlsOpts}
        conn, err := Dial(&o) // somehow this never seem to error out, error 
comes later
        if err != nil {
                return -1, err // error already logged
@@ -163,9 +164,9 @@
 
 // GrpcHealthCheck makes a grpc client call to the standard grpc health check
 // service.
-func GrpcHealthCheck(serverAddr, cacert string, svcname string, n int, 
insecure bool) (*HealthResultMap, error) {
+func GrpcHealthCheck(serverAddr, svcname string, n int, tlsOpts 
*fhttp.TLSOptions) (*HealthResultMap, error) {
        log.Debugf("GrpcHealthCheck for %s svc '%s', %d iterations", 
serverAddr, svcname, n)
-       o := GRPCRunnerOptions{Destination: serverAddr, CACert: cacert, 
Insecure: insecure}
+       o := GRPCRunnerOptions{Destination: serverAddr, TLSOptions: *tlsOpts}
        conn, err := Dial(&o)
        if err != nil {
                return nil, err
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fortio-1.23.0/fgrpc/pingsrv_test.go 
new/fortio-1.24.0/fgrpc/pingsrv_test.go
--- old/fortio-1.23.0/fgrpc/pingsrv_test.go     2022-03-25 02:46:50.000000000 
+0100
+++ new/fortio-1.24.0/fgrpc/pingsrv_test.go     2022-03-28 00:47:13.000000000 
+0200
@@ -21,6 +21,7 @@
        "testing"
        "time"
 
+       "fortio.org/fortio/fhttp"
        "fortio.org/fortio/log"
        "google.golang.org/grpc/credentials"
        "google.golang.org/grpc/health/grpc_health_v1"
@@ -31,7 +32,10 @@
 }
 
 func TestPingServer(t *testing.T) {
-       TLSInsecure := false
+       TLSSecure := &fhttp.TLSOptions{CACert: caCrt, Insecure: false}
+       TLSSecureMissingCert := &fhttp.TLSOptions{Insecure: false}
+       TLSSecureBadCert := &fhttp.TLSOptions{CACert: failCrt, Insecure: true}
+       TLSInsecure := &fhttp.TLSOptions{Insecure: true}
        iPort := PingServerTCP("0", "", "", "foo", 0)
        iAddr := fmt.Sprintf("localhost:%d", iPort)
        t.Logf("insecure grpc ping server running, will connect to %s", iAddr)
@@ -39,7 +43,7 @@
        sAddr := fmt.Sprintf("localhost:%d", sPort)
        t.Logf("secure grpc ping server running, will connect to %s", sAddr)
        delay := 100 * time.Millisecond
-       latency, err := PingClientCall(iAddr, "", 7, "test payload", delay, 
TLSInsecure)
+       latency, err := PingClientCall(iAddr, 7, "test payload", delay, 
TLSInsecure)
        if err != nil || latency < delay.Seconds() || latency > 
10.*delay.Seconds() {
                t.Errorf("Unexpected result %f, %v with ping calls and delay of 
%v", latency, err, delay)
        }
@@ -49,29 +53,29 @@
                t.Errorf("Unexpected result %f, %v with ping calls", latency, 
err)
        }
        */
-       if latency, err := PingClientCall(sAddr, caCrt, 7, "test payload", 0, 
TLSInsecure); err != nil || latency <= 0 {
+       if latency, err := PingClientCall(sAddr, 7, "test payload", 0, 
TLSSecure); err != nil || latency <= 0 {
                t.Errorf("Unexpected result %f, %v with ping calls", latency, 
err)
        }
-       if latency, err := PingClientCall(iAddr, caCrt, 1, "", 0, TLSInsecure); 
err == nil {
+       if latency, err := PingClientCall(iAddr, 1, "", 0, TLSSecure); err == 
nil {
                t.Errorf("Should have had an error instead of result %f for 
secure ping to insecure port", latency)
        }
-       if _, err := PingClientCall("https://"+sAddr, "", 1, "", 0, true); err 
!= nil {
+       if _, err := PingClientCall("https://"+sAddr, 1, "", 0, TLSInsecure); 
err != nil {
                t.Errorf("Should have had no error for secure with bad cert and 
insecure flag: %v", err)
        }
-       if latency, err := PingClientCall("https://"+sAddr, "", 1, "", 0, 
false); err == nil {
+       if latency, err := PingClientCall("https://"+sAddr, 1, "", 0, 
TLSSecureMissingCert); err == nil {
                t.Errorf("Should have had error for secure with bad cert and no 
insecure flag: %v", latency)
        }
-       if latency, err := PingClientCall(sAddr, "", 1, "", 0, TLSInsecure); 
err == nil {
+       if latency, err := PingClientCall(sAddr, 1, "", 0, TLSInsecure); err == 
nil {
                t.Errorf("Should have had an error instead of result %f for 
insecure ping to secure port", latency)
        }
        if creds, err := credentials.NewServerTLSFromFile(failCrt, failKey); 
err == nil {
                t.Errorf("Should have had an error instead of result %f for 
ping server", creds)
        }
        serving := grpc_health_v1.HealthCheckResponse_SERVING.String()
-       if r, err := GrpcHealthCheck(iAddr, "", "", 1, TLSInsecure); err != nil 
|| (*r)[serving] != 1 {
+       if r, err := GrpcHealthCheck(iAddr, "", 1, TLSInsecure); err != nil || 
(*r)[serving] != 1 {
                t.Errorf("Unexpected result %+v, %v with empty service health 
check", r, err)
        }
-       if r, err := GrpcHealthCheck(sAddr, caCrt, "", 1, TLSInsecure); err != 
nil || (*r)[serving] != 1 {
+       if r, err := GrpcHealthCheck(sAddr, "", 1, TLSSecure); err != nil || 
(*r)[serving] != 1 {
                t.Errorf("Unexpected result %+v, %v with empty service health 
check", r, err)
        }
        /* re-enable once we get https://demo.fortio.org/
@@ -79,19 +83,19 @@
                t.Errorf("Unexpected result %+v, %v with empty service health 
check", r, err)
        }
        */
-       if r, err := GrpcHealthCheck(iAddr, "", "foo", 3, TLSInsecure); err != 
nil || (*r)[serving] != 3 {
+       if r, err := GrpcHealthCheck(iAddr, "foo", 3, TLSInsecure); err != nil 
|| (*r)[serving] != 3 {
                t.Errorf("Unexpected result %+v, %v with health check for same 
service as started (foo)", r, err)
        }
-       if r, err := GrpcHealthCheck(sAddr, caCrt, "foo", 3, TLSInsecure); err 
!= nil || (*r)[serving] != 3 {
+       if r, err := GrpcHealthCheck(sAddr, "foo", 3, TLSSecure); err != nil || 
(*r)[serving] != 3 {
                t.Errorf("Unexpected result %+v, %v with health check for same 
service as started (foo)", r, err)
        }
-       if r, err := GrpcHealthCheck(iAddr, "", "willfail", 1, TLSInsecure); 
err == nil || r != nil {
+       if r, err := GrpcHealthCheck(iAddr, "willfail", 1, TLSInsecure); err == 
nil || r != nil {
                t.Errorf("Was expecting error when using unknown service, 
didn't get one, got %+v", r)
        }
-       if r, err := GrpcHealthCheck(sAddr, caCrt, "willfail", 1, TLSInsecure); 
err == nil || r != nil {
+       if r, err := GrpcHealthCheck(sAddr, "willfail", 1, TLSSecure); err == 
nil || r != nil {
                t.Errorf("Was expecting error when using unknown service, 
didn't get one, got %+v", r)
        }
-       if r, err := GrpcHealthCheck(sAddr, failCrt, "willfail", 1, 
TLSInsecure); err == nil {
+       if r, err := GrpcHealthCheck(sAddr, "willfail", 1, TLSSecureBadCert); 
err == nil {
                t.Errorf("Was expecting dial error when using invalid 
certificate, didn't get one, got %+v", r)
        }
        // 2nd server on same port should fail to bind:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fortio-1.23.0/fhttp/http_client.go 
new/fortio-1.24.0/fhttp/http_client.go
--- old/fortio-1.23.0/fhttp/http_client.go      2022-03-25 02:46:50.000000000 
+0100
+++ new/fortio-1.24.0/fhttp/http_client.go      2022-03-28 00:47:13.000000000 
+0200
@@ -19,7 +19,6 @@
        "bytes"
        "context"
        "crypto/tls"
-       "crypto/x509"
        "errors"
        "fmt"
        "io"
@@ -160,6 +159,7 @@
 
 // HTTPOptions holds the common options of both http clients and the headers.
 type HTTPOptions struct {
+       TLSOptions
        URL               string
        NumConnections    int  // num connections (for std client)
        Compression       bool // defaults to no compression, only used by std 
client
@@ -167,28 +167,21 @@
        HTTP10            bool // defaults to http1.1
        DisableKeepAlive  bool // so default is keep alive
        AllowHalfClose    bool // if not keepalive, whether to half close after 
request
-       Insecure          bool // do not verify certs for https
        FollowRedirects   bool // For the Std Client only: follow redirects.
        initDone          bool
        https             bool   // whether URLSchemeCheck determined this was 
an https:// call or not
-       CACert            string // `Path` to a custom CA certificate file to 
be used
-       Cert              string // `Path` to the certificate file to be used
-       Key               string // `Path` to the key file used
        Resolve           string // resolve Common Name to this ip when use CN 
as target url
        // ExtraHeaders to be added to each request (UserAgent and headers set 
through AddAndValidateExtraHeader()).
        extraHeaders http.Header
        // Host is treated specially, remember that virtual header separately.
-       hostOverride   string
-       HTTPReqTimeOut time.Duration // timeout value for http request
-
-       UserCredentials string // user credentials for authorization
-       ContentType     string // indicates request body type, implies POST 
instead of GET
-       Payload         []byte // body for http request, implies POST if not 
empty.
-
-       UnixDomainSocket string // Path of unix domain socket to use instead of 
host:port from URL
-       LogErrors        bool   // whether to log non 2xx code as they occur or 
not
-       ID               int    // id to use for logging (thread id when used 
as a runner)
-       SequentialWarmup bool   // whether to do http(s) runs warmup 
sequentially or in parallel (new default is //)
+       hostOverride     string
+       HTTPReqTimeOut   time.Duration // timeout value for http request
+       UserCredentials  string        // user credentials for authorization
+       ContentType      string        // indicates request body type, implies 
POST instead of GET
+       Payload          []byte        // body for http request, implies POST 
if not empty.
+       LogErrors        bool          // whether to log non 2xx code as they 
occur or not
+       ID               int           // id to use for logging (thread id when 
used as a runner)
+       SequentialWarmup bool          // whether to do http(s) runs warmup 
sequentially or in parallel (new default is //)
 }
 
 // ResetHeaders resets all the headers, including the User-Agent: one (and the 
Host: logical special header).
@@ -439,11 +432,12 @@
                },
                TLSHandshakeTimeout: o.HTTPReqTimeOut,
        }
-       tr.TLSClientConfig, err = o.TLSClientConfig()
-       if err != nil {
-               return nil, err
+       if o.https {
+               tr.TLSClientConfig, err = o.TLSOptions.TLSClientConfig()
+               if err != nil {
+                       return nil, err
+               }
        }
-
        client := Client{
                url:                  o.URL,
                path:                 req.URL.Path,
@@ -470,43 +464,6 @@
        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.
@@ -599,15 +556,17 @@
                log.Errf("Bad url '%s' : %v", urlString, err)
                return nil, err
        }
-       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,
+               https: o.https,
+       }
+       if o.https {
+               bc.tlsConfig, err = o.TLSOptions.TLSClientConfig()
+               if err != nil {
+                       return nil, err
+               }
        }
        bc.buffer = make([]byte, BufferSizeKb*1024)
        if bc.port == "" {
@@ -640,8 +599,8 @@
        if customHostHeader {
                host = o.hostOverride
        }
-       if tlsConfig != nil {
-               tlsConfig.ServerName = host
+       if bc.tlsConfig != nil {
+               bc.tlsConfig.ServerName = host
        }
        var buf bytes.Buffer
        buf.WriteString(method + " " + url.RequestURI() + " HTTP/" + proto + 
"\r\n")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fortio-1.23.0/fhttp/http_server.go 
new/fortio-1.24.0/fhttp/http_server.go
--- old/fortio-1.23.0/fhttp/http_server.go      2022-03-25 02:46:50.000000000 
+0100
+++ new/fortio-1.24.0/fhttp/http_server.go      2022-03-28 00:47:13.000000000 
+0200
@@ -339,6 +339,11 @@
        w.Header().Set("Cache-Control", "max-age=365000000, immutable")
 }
 
+// EchoDebugPath returns the additional echo handler path behind debugPath (ie 
/debug -> /debug/echo/).
+func EchoDebugPath(debugPath string) string {
+       return strings.TrimSuffix(debugPath, "/") + "/echo/"
+}
+
 // Serve starts a debug / echo http server on the given port.
 // Returns the mux and addr where the listening socket is bound.
 // The .Port can be retrieved from it when requesting the 0 port as
@@ -351,7 +356,7 @@
        }
        if debugPath != "" {
                mux.HandleFunc(debugPath, DebugHandler)
-               mux.HandleFunc(strings.TrimSuffix(debugPath, "/")+"/echo/", 
EchoHandler) // Fix #524
+               mux.HandleFunc(EchoDebugPath(debugPath), EchoHandler) // Fix 
#524
        }
        mux.HandleFunc("/", EchoHandler)
        return mux, addr
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fortio-1.23.0/fhttp/http_test.go 
new/fortio-1.24.0/fhttp/http_test.go
--- old/fortio-1.23.0/fhttp/http_test.go        2022-03-25 02:46:50.000000000 
+0100
+++ new/fortio-1.24.0/fhttp/http_test.go        2022-03-28 00:47:13.000000000 
+0200
@@ -579,7 +579,7 @@
        if addr == nil {
                t.Fatalf("Error for Serve for %s", uds)
        }
-       o := HTTPOptions{UnixDomainSocket: uds, URL: 
"http://foo.bar:123/debug1"}
+       o := HTTPOptions{TLSOptions: TLSOptions{UnixDomainSocket: uds}, URL: 
"http://foo.bar:123/debug1"}
        client, _ := NewClient(&o)
        code, data, _ := client.Fetch()
        if code != http.StatusOK {
@@ -1415,7 +1415,7 @@
                o := HTTPOptions{
                        DisableFastClient: tst.fastClient,
                        URL:               expiredURL,
-                       Insecure:          tst.insecure,
+                       TLSOptions:        TLSOptions{Insecure: tst.insecure},
                }
                code, _ := Fetch(&o)
                if code != tst.code {
@@ -1446,7 +1446,7 @@
                o := HTTPOptions{
                        DisableFastClient: tst.fastClient,
                        URL:               url,
-                       Insecure:          tst.insecure,
+                       TLSOptions:        TLSOptions{Insecure: tst.insecure},
                        Resolve:           "127.0.0.1",
                }
                code, _ := Fetch(&o)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fortio-1.23.0/fhttp/http_utils.go 
new/fortio-1.24.0/fhttp/http_utils.go
--- old/fortio-1.23.0/fhttp/http_utils.go       2022-03-25 02:46:50.000000000 
+0100
+++ new/fortio-1.24.0/fhttp/http_utils.go       2022-03-28 00:47:13.000000000 
+0200
@@ -15,10 +15,13 @@
 package fhttp // import "fortio.org/fortio/fhttp"
 
 import (
+       "crypto/tls"
+       "crypto/x509"
        "encoding/base64"
        "flag"
        "html/template"
        "io"
+       "io/ioutil"
        "math/rand"
        "net/http"
        "strconv"
@@ -33,6 +36,49 @@
        "fortio.org/fortio/stats"
 )
 
+// TLSOptions are common TLS related options between https and grpc.
+type TLSOptions struct {
+       Insecure         bool   // Do not verify certs
+       CACert           string // `Path` to a custom CA certificate file to be 
used
+       Cert             string // `Path` to the certificate file to be used
+       Key              string // `Path` to the key file used
+       UnixDomainSocket string // `Path`` of unix domain socket to use instead 
of host:port
+}
+
+// TLSClientConfig creates a tls.Config based on input TLSOptions.
+// For https, ServerName is set later (once host is determined after URL 
parsing
+// and depending on hostOverride).
+func (to *TLSOptions) TLSClientConfig() (*tls.Config, error) {
+       var res *tls.Config
+
+       res = &tls.Config{MinVersion: tls.VersionTLS12}
+       if to.Insecure {
+               log.LogVf("Using insecure https")
+               res.InsecureSkipVerify = true
+       }
+       if len(to.Cert) > 0 && len(to.Key) > 0 {
+               cert, err := tls.LoadX509KeyPair(to.Cert, to.Key)
+               if err != nil {
+                       log.Errf("LoadX509KeyPair error for cert %v / key %v: 
%v", to.Cert, to.Key, err)
+                       return nil, err
+               }
+               res.Certificates = []tls.Certificate{cert}
+       }
+       if len(to.CACert) > 0 {
+               // Load CA cert
+               caCert, err := ioutil.ReadFile(to.CACert)
+               if err != nil {
+                       log.Errf("Unable to read CA from %v: %v", to.CACert, 
err)
+                       return nil, err
+               }
+               log.LogVf("Using custom CA from %v", to.CACert)
+               caCertPool := x509.NewCertPool()
+               caCertPool.AppendCertsFromPEM(caCert)
+               res.RootCAs = caCertPool
+       }
+       return res, nil
+}
+
 // Used for the fast case insensitive search.
 const toUpperMask = ^byte('a' - 'A')
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fortio-1.23.0/fortio_main.go 
new/fortio-1.24.0/fortio_main.go
--- old/fortio-1.23.0/fortio_main.go    2022-03-25 02:46:50.000000000 +0100
+++ new/fortio-1.24.0/fortio_main.go    2022-03-28 00:47:13.000000000 +0200
@@ -420,16 +420,14 @@
                o := fgrpc.GRPCRunnerOptions{
                        RunnerOptions:      ro,
                        Destination:        url,
-                       CACert:             *bincommon.CACertFlag,
-                       Insecure:           bincommon.TLSInsecure(),
                        Service:            *healthSvcFlag,
                        Streams:            *streamsFlag,
                        AllowInitialErrors: *allowInitialErrorsFlag,
                        Payload:            httpOpts.PayloadString(),
                        Delay:              *pingDelayFlag,
                        UsePing:            *doPingLoadFlag,
-                       UnixDomainSocket:   httpOpts.UnixDomainSocket,
                }
+               o.TLSOptions = httpOpts.TLSOptions
                res, err = fgrpc.RunGRPCTest(&o)
        } else if strings.HasPrefix(url, tcprunner.TCPURLPrefix) {
                o := tcprunner.RunnerOptions{
@@ -514,13 +512,12 @@
        if count <= 0 {
                count = 1
        }
-       cert := *bincommon.CACertFlag
+       httpOpts := bincommon.SharedHTTPOptions()
        var err error
        if *doHealthFlag {
-               _, err = fgrpc.GrpcHealthCheck(host, cert, *healthSvcFlag, 
count, bincommon.TLSInsecure())
+               _, err = fgrpc.GrpcHealthCheck(host, *healthSvcFlag, count, 
&httpOpts.TLSOptions)
        } else {
-               httpOpts := bincommon.SharedHTTPOptions()
-               _, err = fgrpc.PingClientCall(host, cert, count, 
httpOpts.PayloadString(), *pingDelayFlag, httpOpts.Insecure)
+               _, err = fgrpc.PingClientCall(host, count, 
httpOpts.PayloadString(), *pingDelayFlag, &httpOpts.TLSOptions)
        }
        if err != nil {
                // already logged
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fortio-1.23.0/ui/restHandler.go 
new/fortio-1.24.0/ui/restHandler.go
--- old/fortio-1.23.0/ui/restHandler.go 2022-03-25 02:46:50.000000000 +0100
+++ new/fortio-1.24.0/ui/restHandler.go 2022-03-28 00:47:13.000000000 +0200
@@ -247,8 +247,8 @@
                        Destination:   url,
                        UsePing:       grpcPing,
                        Delay:         grpcPingDelay,
-                       Insecure:      httpopts.Insecure,
                }
+               o.TLSOptions = httpopts.TLSOptions
                if grpcSecure {
                        o.Destination = fhttp.AddHTTPS(url)
                }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fortio-1.23.0/ui/templates/main.html 
new/fortio-1.24.0/ui/templates/main.html
--- old/fortio-1.23.0/ui/templates/main.html    2022-03-25 02:46:50.000000000 
+0100
+++ new/fortio-1.24.0/ui/templates/main.html    2022-03-28 00:47:13.000000000 
+0200
@@ -95,9 +95,9 @@
 </form>
 <p><i>Or</i></p>
 <a href="{{.DebugPath}}">debug</a> and <a href="{{.DebugPath}}?env=dump">debug 
with env dump</a>
-and <a href="{{.DebugPath}}/pprof/">Internal PPROF</a>
+and <a href="/debug/pprof/">Internal PPROF</a>
 and <a href="flags">Command line flags</a>
-and <a href="{{.DebugPath}}/echo/">Additional echo handler under 
{{.DebugPath}}/echo/</a> (supports all the
+and <a href="{{.EchoDebugPath}}">Additional echo handler under 
{{.EchoDebugPath}}</a> (supports all the
 query arguments mentioned on the <a 
href="https://github.com/fortio/fortio#server-urls-and-features";>Echo url 
features</a> github doc)
 <p><i>Or</i></p>
 <form action="sync">
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fortio-1.23.0/ui/uihandler.go 
new/fortio-1.24.0/ui/uihandler.go
--- old/fortio-1.23.0/ui/uihandler.go   2022-03-25 02:46:50.000000000 +0100
+++ new/fortio-1.24.0/ui/uihandler.go   2022-03-28 00:47:13.000000000 +0200
@@ -65,7 +65,8 @@
        uiPath      string // absolute (base)
        logoPath    string // relative
        chartJSPath string // relative
-       debugPath   string // mostly relative
+       debugPath   string // absolute
+       echoPath    string // absolute
        fetchPath   string // this one is absolute
        // Used to construct default URL to self.
        urlHostPort string
@@ -239,6 +240,7 @@
                        Version                     string
                        LogoPath                    string
                        DebugPath                   string
+                       EchoDebugPath               string
                        ChartJSPath                 string
                        StartTime                   string
                        TargetURL                   string
@@ -250,7 +252,7 @@
                        DoStop                      bool
                        DoLoad                      bool
                }{
-                       r, defaultHeaders, version.Short(), logoPath, 
debugPath, chartJSPath,
+                       r, defaultHeaders, version.Short(), logoPath, 
debugPath, echoPath, chartJSPath,
                        startTime.Format(time.ANSIC), url, labels, runid,
                        fhttp.RoundDuration(time.Since(startTime)), durSeconds, 
urlHostPort, mode == stop, mode == run,
                })
@@ -287,8 +289,8 @@
                                Destination:   url,
                                UsePing:       grpcPing,
                                Delay:         grpcPingDelay,
-                               Insecure:      httpsInsecure,
                        }
+                       o.TLSOptions = httpopts.TLSOptions
                        if grpcSecure {
                                o.Destination = fhttp.AddHTTPS(url)
                        }
@@ -895,7 +897,8 @@
                log.Warnf("Adding missing trailing / to UI path '%s'", uiPath)
                uiPath += "/"
        }
-       debugPath = ".." + debugpath // TODO: calculate actual path if not same 
number of directories
+       debugPath = debugpath
+       echoPath = fhttp.EchoDebugPath(debugpath)
        mux.HandleFunc(uiPath, Handler)
        fetchPath = uiPath + fetchURI
        // For backward compatibility with http:// only fetcher

++++++ vendor.tar.gz ++++++

Reply via email to