diff --git a/.circleci/config.yml b/.circleci/config.yml index 40cbefab9..57bc17cb6 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -8,7 +8,7 @@ defaultEnv: &defaultEnv docker: # specify the version - - image: docker.io/fortio/fortio.build:v69@sha256:c21ecd49fd232a4c184a04607f339c18d13151480aee779a047358f2f23e287e + - image: docker.io/fortio/fortio.build:v70@sha256:a1a0c03170d4be21a94d62b7e0b5dd966135e8888e8b2bf97eb8511eb6ee778e working_directory: /build/fortio jobs: diff --git a/Dockerfile b/Dockerfile index 4cbae1f6e..cdc91f596 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # Build the binaries in larger image -FROM docker.io/fortio/fortio.build:v69@sha256:c21ecd49fd232a4c184a04607f339c18d13151480aee779a047358f2f23e287e as build +FROM docker.io/fortio/fortio.build:v70@sha256:a1a0c03170d4be21a94d62b7e0b5dd966135e8888e8b2bf97eb8511eb6ee778e as build WORKDIR /build COPY --chown=build:build . fortio ARG MODE=install diff --git a/Dockerfile.build b/Dockerfile.build index b63710f58..1a0453479 100644 --- a/Dockerfile.build +++ b/Dockerfile.build @@ -1,5 +1,5 @@ # Dependencies and linters for build: -FROM golang:1.21.8@sha256:c82d4ad02c062cf2b393bf0374df26638c6fed3dfe52cdbd3635d4a7befab86e +FROM golang:1.22.2@sha256:c4fb952e712efd8f787bcd8e53fd66d1d83b7dc26adabc218e9eac1dbf776bdf # Need gcc for -race test (and some linters though those work with CGO_ENABLED=0) RUN apt-get -y update && \ apt-get --no-install-recommends -y upgrade && \ @@ -24,7 +24,7 @@ RUN set -x; if [ x"$(dpkg --print-architecture)" != x"s390x" ]; then \ # govulncheck RUN go install golang.org/x/vuln/cmd/govulncheck@latest WORKDIR /build -COPY .golangci.yml . +ADD https://raw.githubusercontent.com/fortio/workflows/main/golangci.yml .golangci.yml VOLUME /build RUN useradd -m build -d /build RUN chown -R build:build /build diff --git a/Dockerfile.echosrv b/Dockerfile.echosrv index 138cc6a4b..2939a0c7c 100644 --- a/Dockerfile.echosrv +++ b/Dockerfile.echosrv @@ -1,5 +1,5 @@ # Build the binaries in larger image -FROM docker.io/fortio/fortio.build:v69@sha256:c21ecd49fd232a4c184a04607f339c18d13151480aee779a047358f2f23e287e as build +FROM docker.io/fortio/fortio.build:v70@sha256:a1a0c03170d4be21a94d62b7e0b5dd966135e8888e8b2bf97eb8511eb6ee778e as build WORKDIR /build COPY . fortio RUN make -C fortio official-build-version BUILD_DIR=/build OFFICIAL_TARGET=fortio.org/fortio/echosrv diff --git a/Dockerfile.fcurl b/Dockerfile.fcurl index 522c8a2cc..7058c0f5c 100644 --- a/Dockerfile.fcurl +++ b/Dockerfile.fcurl @@ -1,5 +1,5 @@ # Build the binaries in larger image -FROM docker.io/fortio/fortio.build:v69@sha256:c21ecd49fd232a4c184a04607f339c18d13151480aee779a047358f2f23e287e as build +FROM docker.io/fortio/fortio.build:v70@sha256:a1a0c03170d4be21a94d62b7e0b5dd966135e8888e8b2bf97eb8511eb6ee778e as build WORKDIR /build COPY . fortio RUN make -C fortio official-build-version BUILD_DIR=/build OFFICIAL_TARGET=fortio.org/fortio/fcurl diff --git a/Makefile b/Makefile index 09359d5f5..6661f6ae2 100755 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ IMAGES=echosrv fcurl # plus the combo image / Dockerfile without ext. DOCKER_PREFIX := docker.io/fortio/fortio -BUILD_IMAGE_TAG := v69@sha256:c21ecd49fd232a4c184a04607f339c18d13151480aee779a047358f2f23e287e +BUILD_IMAGE_TAG := v70@sha256:a1a0c03170d4be21a94d62b7e0b5dd966135e8888e8b2bf97eb8511eb6ee778e BUILDX_PLATFORMS := linux/amd64,linux/arm64,linux/ppc64le,linux/s390x BUILDX_POSTFIX := ifeq '$(shell echo $(BUILDX_PLATFORMS) | awk -F "," "{print NF-1}")' '0' @@ -68,7 +68,7 @@ local-lint: .golangci.yml LINT_PACKAGES:=./... lint: .golangci.yml docker run -v $(CURDIR):/build/fortio $(BUILD_IMAGE) bash -c \ - "cd /build/fortio \ + "cd /build/fortio; chown build:build . \ && time make local-lint DEBUG_LINTERS=\"$(DEBUG_LINTERS)\" LINT_PACKAGES=\"$(LINT_PACKAGES)\"" docker-test: diff --git a/README.md b/README.md index cab911086..effad6458 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ - + # Fortio [![Awesome Go](https://fortio.org/mentioned-badge.svg)](https://github.com/avelino/awesome-go#networking) @@ -60,13 +60,13 @@ You can install from source: The [releases](https://github.com/fortio/fortio/releases) page has binaries for many OS/architecture combinations (see assets): ```shell -curl -L https://github.com/fortio/fortio/releases/download/v1.63.5/fortio-linux_amd64-1.63.5.tgz \ +curl -L https://github.com/fortio/fortio/releases/download/v1.63.6/fortio-linux_amd64-1.63.6.tgz \ | sudo tar -C / -xvzpf - # or the debian package -wget https://github.com/fortio/fortio/releases/download/v1.63.5/fortio_1.63.5_amd64.deb -dpkg -i fortio_1.63.5_amd64.deb +wget https://github.com/fortio/fortio/releases/download/v1.63.6/fortio_1.63.6_amd64.deb +dpkg -i fortio_1.63.6_amd64.deb # or the rpm -rpm -i https://github.com/fortio/fortio/releases/download/v1.63.5/fortio-1.63.5-1.x86_64.rpm +rpm -i https://github.com/fortio/fortio/releases/download/v1.63.6/fortio-1.63.6-1.x86_64.rpm # and more, see assets in release page ``` @@ -76,7 +76,7 @@ On a MacOS you can also install Fortio using [Homebrew](https://brew.sh/): brew install fortio ``` -On Windows, download https://github.com/fortio/fortio/releases/download/v1.63.5/fortio_win_1.63.5.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.63.6/fortio_win_1.63.6.zip and extract `fortio.exe` to any location, then using the Windows Command Prompt: ``` fortio.exe server ``` @@ -130,7 +130,7 @@ Full list of command line flags (`fortio help`):
 
-Φορτίο 1.63.5 usage:
+Φορτίο 1.63.6 usage:
         fortio command [flags] target
 where command is one of: load (load testing), server (starts ui, rest api,
  http-echo, redirect, proxies, tcp-echo, udp-echo and grpc ping servers),
diff --git a/Webtest.sh b/Webtest.sh
index a1ee0c7ef..a6645cb9d 100755
--- a/Webtest.sh
+++ b/Webtest.sh
@@ -140,7 +140,7 @@ fi
 PPROF_URL="$BASE_URL/debug/pprof/heap?debug=1"
 $CURL "$PPROF_URL" | grep -i TotalAlloc # should find this in memory profile
 # creating dummy container to hold a volume for test certs due to remote docker bind mount limitation.
-DOCKERCURLID=$(docker run -d -v $TEST_CERT_VOL --net host --name $DOCKERSECVOLNAME docker.io/fortio/fortio.build:v69@sha256:c21ecd49fd232a4c184a04607f339c18d13151480aee779a047358f2f23e287e sleep 120)
+DOCKERCURLID=$(docker run -d -v $TEST_CERT_VOL --net host --name $DOCKERSECVOLNAME docker.io/fortio/fortio.build:v70@sha256:a1a0c03170d4be21a94d62b7e0b5dd966135e8888e8b2bf97eb8511eb6ee778e sleep 120)
 # while we have something with actual curl binary do
 # Test for h2c upgrade (#562)
 docker exec $DOCKERSECVOLNAME /usr/bin/curl -v --http2 -m 10 -d foo42 http://localhost:8080/debug | tee >(cat 1>&2) | grep foo42
diff --git a/fhttp/http_client.go b/fhttp/http_client.go
index b7eb39bce..ac1964c4c 100644
--- a/fhttp/http_client.go
+++ b/fhttp/http_client.go
@@ -1088,7 +1088,13 @@ func (c *FastClient) readResponse(conn net.Conn, reusedSocket bool) {
 					// handled below as possibly normal end of stream after we read something
 					break
 				}
-				log.S(log.Error, "Read error", log.Attr("err", err), log.Attr("size", c.size), log.Attr("dest", c.dest), log.Str("url", c.url),
+				errMsg := "Read error"
+				var netErr net.Error
+				if errors.As(err, &netErr) && netErr.Timeout() {
+					errMsg = "Timeout error (incomplete/invalid response)"
+				}
+				log.S(log.Error, errMsg, log.Attr("err", err), log.Attr("size", c.size), log.Attr("header_len", c.headerLen),
+					log.Attr("dest", c.dest), log.Str("url", c.url),
 					log.Attr("thread", c.id), log.Attr("run", c.runID))
 				c.code = SocketError
 				break
diff --git a/fhttp/http_test.go b/fhttp/http_test.go
index 40a98b33a..6af3aba1d 100644
--- a/fhttp/http_test.go
+++ b/fhttp/http_test.go
@@ -592,6 +592,22 @@ func TestPayloadWithEchoBack(t *testing.T) {
 	}
 }
 
+// Exercise the code for https://github.com/fortio/fortio/pull/914
+func TestReadtimeout(t *testing.T) {
+	// in theory we'd also redirect the log output to check we do see "Timeout error (incomplete/invalid response)"
+	// but the logger has its own tests and the switch from not covered to covered shows it's working/exercised by this test.
+	m, a := DynamicHTTPServer(false)
+	m.HandleFunc("/", EchoHandler)
+	url := fmt.Sprintf("http://localhost:%d/?delay=1s", a.Port)
+	opts := NewHTTPOptions(url)
+	opts.HTTPReqTimeOut = 100 * time.Millisecond
+	cli, _ := NewClient(opts)
+	code, _, _ := cli.Fetch(context.Background())
+	if code != -1 {
+		t.Errorf("Unexpected code %d", code)
+	}
+}
+
 // Test Post request with std client and the socket close after answering.
 func TestPayloadWithStdClientAndClosedSocket(t *testing.T) {
 	m, a := DynamicHTTPServer(false)
diff --git a/go.mod b/go.mod
index 8888ccb38..458beb8c9 100644
--- a/go.mod
+++ b/go.mod
@@ -1,12 +1,16 @@
 module fortio.org/fortio
 
-go 1.19 // As a library the current version of fortio works with 1.18 (first version with generics) but tests use 1.19 features
+// As a library the current version of fortio works with 1.18 (first version with generics) but tests use 1.19 features
+// Note we will switch soon to 1.22 for the linters
+go 1.19
+
+// toolchain go1.22.2 // this shouldn't be necessary - see https://github.com/golang/go/issues/66175#issuecomment-2010343876
 
 require (
 	fortio.org/assert v1.2.1
 	fortio.org/cli v1.5.2
 	fortio.org/dflag v1.7.1
-	fortio.org/log v1.12.1
+	fortio.org/log v1.12.2
 	fortio.org/scli v1.14.2
 	fortio.org/sets v1.0.4
 	fortio.org/testscript v0.3.1
diff --git a/go.sum b/go.sum
index dc7c25851..09eeaa2b4 100644
--- a/go.sum
+++ b/go.sum
@@ -4,8 +4,8 @@ fortio.org/cli v1.5.2 h1:MfEcHAhYyIkwG04/K1YJL946Y8/jyAjmF9WeR5ZG/5E=
 fortio.org/cli v1.5.2/go.mod h1:SdQufh5PLd6oX2EtvtzLFw++gw8zVoejD1WlwGXAvYw=
 fortio.org/dflag v1.7.1 h1:sDdYSw3py02awhgtWEtRtZvOM0UWgeDweRsXWROU3A0=
 fortio.org/dflag v1.7.1/go.mod h1:3KB1SSilm1WwYl7gydDCnV24+DQaycAusNyy06dDD+c=
-fortio.org/log v1.12.1 h1:8JNdFqOFbtifrdbqKkQZchGAoooLLr1J/tD2lYl1ZaI=
-fortio.org/log v1.12.1/go.mod h1:1tMBG/Elr6YqjmJCWiejJp2FPvXg7/9UAN0Rfpkyt1o=
+fortio.org/log v1.12.2 h1:JwLDFvEUKGfqA09fcf+mOn8kxsvwhjXV92xghxNnnwA=
+fortio.org/log v1.12.2/go.mod h1:1tMBG/Elr6YqjmJCWiejJp2FPvXg7/9UAN0Rfpkyt1o=
 fortio.org/scli v1.14.2 h1:dZEyzpC6YmCm24YSd2AvCAeMOxFEl7o4HvArFUpksIo=
 fortio.org/scli v1.14.2/go.mod h1:5wwP5rS46H3vGoCWu5XaaDSH0f0OZnHJajgxR4E6fvs=
 fortio.org/sets v1.0.4 h1:z5+qleG+9lpbpjGHvRGhfd+E5pJGsLetYl/w4pMc5MM=
diff --git a/release/Dockerfile.in b/release/Dockerfile.in
index 528034a37..af25b1710 100644
--- a/release/Dockerfile.in
+++ b/release/Dockerfile.in
@@ -1,5 +1,5 @@
 # Concatenated after ../Dockerfile to create the tgz
-FROM docker.io/fortio/fortio.build:v69@sha256:c21ecd49fd232a4c184a04607f339c18d13151480aee779a047358f2f23e287e as stage
+FROM docker.io/fortio/fortio.build:v70@sha256:a1a0c03170d4be21a94d62b7e0b5dd966135e8888e8b2bf97eb8511eb6ee778e as stage
 ARG archs="amd64 arm64 ppc64le s390x"
 ENV archs=${archs}
 # Build image defaults to build user, switch back to root for