Hello community,

here is the log from the commit of package geoipupdate for openSUSE:Factory 
checked in at 2020-11-05 21:54:47
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/geoipupdate (Old)
 and      /work/SRC/openSUSE:Factory/.geoipupdate.new.11331 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "geoipupdate"

Thu Nov  5 21:54:47 2020 rev:14 rq:846049 version:4.5.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/geoipupdate/geoipupdate.changes  2020-05-07 
14:56:35.246519254 +0200
+++ /work/SRC/openSUSE:Factory/.geoipupdate.new.11331/geoipupdate.changes       
2020-11-05 21:55:33.080099001 +0100
@@ -1,0 +2,21 @@
+Wed Nov  4 15:54:26 UTC 2020 - Paolo Stivanin <i...@paolostivanin.com>
+
+- Update to version 4.5.0:
+* We no longer use a third party library for exponential backoff
+* The edition ID is now included when there is a failure retrieving
+  a database
+* The Docker image no longer prints the generated GeoIP.conf when
+  starting up. This prevents a possible leak of the account's
+  license key
+* The minimum Go version is now 1.11.
+* Failing HTTP requests are now retried using an exponential backoff.
+  The period to keep retrying any failed request is set to 5 minutes
+  by default and can be adjusted using the new RetryFor
+  configuration option.
+* When using the go package rather than the command-line tool, the
+  null value for RetryFor will be 0 seconds, which means no retries
+  will be performed. To change that, set RetryFor explicitly in the
+  Config you provide, or obtain your Config value via
+  geoipupdate.NewConfig.
+
+-------------------------------------------------------------------

Old:
----
  geoipupdate-4.3.0.tar.gz

New:
----
  geoipupdate-4.5.0.tar.gz

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

Other differences:
------------------
++++++ geoipupdate.spec ++++++
--- /var/tmp/diff_new_pack.NgjoXk/_old  2020-11-05 21:55:33.888097185 +0100
+++ /var/tmp/diff_new_pack.NgjoXk/_new  2020-11-05 21:55:33.892097176 +0100
@@ -18,7 +18,7 @@
 
 # Common info
 Name:           geoipupdate
-Version:        4.3.0
+Version:        4.5.0
 Release:        0
 Summary:        GeoIP update client code
 License:        Apache-2.0 OR MIT
@@ -33,7 +33,7 @@
 Patch0:         disable-pandoc.patch
 %if 0%{?suse_version} >= 1500
 # Build-time parameters
-BuildRequires:  go >= 1.10
+BuildRequires:  go >= 1.11
 # Manpage
 BuildRequires:  perl%{?suse_version:-base}
 %endif

++++++ _service ++++++
--- /var/tmp/diff_new_pack.NgjoXk/_old  2020-11-05 21:55:33.952097041 +0100
+++ /var/tmp/diff_new_pack.NgjoXk/_new  2020-11-05 21:55:33.952097041 +0100
@@ -2,7 +2,7 @@
     <service name="tar_scm" mode="disabled">
         <param name="scm">git</param>
         <param name="url">git://github.com/maxmind/geoipupdate</param>
-        <param name="revision">v4.3.0</param>
+        <param name="revision">v4.5.0</param>
         <param name="exclude">.git</param>
         <param name="versionformat">@PARENT_TAG@</param>
         <param name="changesgenerate">enable</param>

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.NgjoXk/_old  2020-11-05 21:55:33.976096987 +0100
+++ /var/tmp/diff_new_pack.NgjoXk/_new  2020-11-05 21:55:33.976096987 +0100
@@ -1,6 +1,6 @@
 <servicedata>
     <service name="tar_scm">
         <param name="url">git://github.com/maxmind/geoipupdate</param>
-        <param 
name="changesrevision">09ac4548fd9311541cb0885e361eb57804b7b781</param>
+        <param 
name="changesrevision">65d57e3edea7798cd72adaafca50e96f34a61d59</param>
     </service>
 </servicedata>

++++++ geoipupdate-4.3.0.tar.gz -> geoipupdate-4.5.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/geoipupdate-4.3.0/.github/workflows/codeql-analysis.yml 
new/geoipupdate-4.5.0/.github/workflows/codeql-analysis.yml
--- old/geoipupdate-4.3.0/.github/workflows/codeql-analysis.yml 1970-01-01 
01:00:00.000000000 +0100
+++ new/geoipupdate-4.5.0/.github/workflows/codeql-analysis.yml 2020-10-28 
22:03:38.000000000 +0100
@@ -0,0 +1,51 @@
+name: "Code scanning - action"
+
+on:
+  push:
+  pull_request:
+  schedule:
+    - cron: '0 11 * * 2'
+
+jobs:
+  CodeQL-Build:
+
+    runs-on: ubuntu-latest
+
+    steps:
+    - name: Checkout repository
+      uses: actions/checkout@v2
+      with:
+        # We must fetch at least the immediate parents so that if this is
+        # a pull request then we can checkout the head.
+        fetch-depth: 2
+
+    # If this run was triggered by a pull request event, then checkout
+    # the head of the pull request instead of the merge commit.
+    - run: git checkout HEAD^2
+      if: ${{ github.event_name == 'pull_request' }}
+      
+    # Initializes the CodeQL tools for scanning.
+    - name: Initialize CodeQL
+      uses: github/codeql-action/init@v1
+      # Override language selection by uncommenting this and choosing your 
languages
+      # with:
+      #   languages: go, javascript, csharp, python, cpp, java
+
+    # 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/geoipupdate-4.3.0/.github/workflows/go.yml 
new/geoipupdate-4.5.0/.github/workflows/go.yml
--- old/geoipupdate-4.3.0/.github/workflows/go.yml      1970-01-01 
01:00:00.000000000 +0100
+++ new/geoipupdate-4.5.0/.github/workflows/go.yml      2020-10-28 
22:03:38.000000000 +0100
@@ -0,0 +1,37 @@
+name: Go
+
+on:
+  push:
+  pull_request:
+  schedule:
+    - cron: '5 10 * * SUN'
+
+jobs:
+
+  build:
+    strategy:
+      matrix:
+        # We test back to 1.11 as we need to support old, EOL'd Go versions
+        # to build PPA packages for older versions of Ubuntu.
+        go-version: [1.11.x, 1.12.x, 1.13.x, 1.14.x, 1.15.x]
+        platform: [ubuntu-latest, macos-latest, windows-latest]
+    runs-on: ${{ matrix.platform }}
+    name: "Build ${{ matrix.go-version }} test on ${{ matrix.platform }}"
+    steps:
+      - name: Set up Go 1.x
+        uses: actions/setup-go@v2
+        with:
+          go-version: ${{ matrix.go-version }}
+        id: go
+
+      - name: Check out code into the Go module directory
+        uses: actions/checkout@v2
+
+      - name: Get dependencies
+        run: go get -v -t -d ./...
+
+      - name: Build
+        run: go build -v ./...
+
+      - name: Test
+        run: go test -race -v ./...
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/geoipupdate-4.3.0/.github/workflows/golangci-lint.yml 
new/geoipupdate-4.5.0/.github/workflows/golangci-lint.yml
--- old/geoipupdate-4.3.0/.github/workflows/golangci-lint.yml   1970-01-01 
01:00:00.000000000 +0100
+++ new/geoipupdate-4.5.0/.github/workflows/golangci-lint.yml   2020-10-28 
22:03:38.000000000 +0100
@@ -0,0 +1,18 @@
+name: golangci-lint
+
+on:
+  push:
+  pull_request:
+  schedule:
+    - cron: '5 5 * * SUN'
+
+jobs:
+  golangci:
+    name: lint
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v2
+      - name: golangci-lint
+        uses: golangci/golangci-lint-action@v2
+        with:
+          version: latest
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/geoipupdate-4.3.0/.golangci.toml 
new/geoipupdate-4.5.0/.golangci.toml
--- old/geoipupdate-4.3.0/.golangci.toml        2020-04-16 18:35:28.000000000 
+0200
+++ new/geoipupdate-4.5.0/.golangci.toml        2020-10-28 22:03:38.000000000 
+0100
@@ -5,34 +5,68 @@
 [linters]
   disable-all = true
   enable = [
+    "bodyclose",
     "deadcode",
     "depguard",
     "errcheck",
+    "exhaustive",
+    "exportloopref",
     "goconst",
     "gocyclo",
     "gocritic",
-    "gofmt",
+    "gofumpt",
     "golint",
     "gosec",
     "gosimple",
+    "govet",
     "ineffassign",
+    "lll",
     "maligned",
     "misspell",
     "nakedret",
+    "noctx",
+    "nolintlint",
+    # https://github.com/golangci/golangci-lint/issues/287
+    # "safesql",
+    "sqlclosecheck",
     "staticcheck",
     "structcheck",
+    "stylecheck",
     "typecheck",
     "unconvert",
     "unparam",
+    "unused",
     "varcheck",
-    "vet",
     "vetshadow",
   ]
 
-# This goes off for MD5 usage, which we use heavily
-[[issues.exclude-rules]]
-text = "weak cryptographic primitive"
-linters = ["gosec"]
+[linters-settings.errcheck]
+    # Ignoring Close so that we don't have to have a bunch of
+    # `defer func() { _ = r.Close() }()` constructs when we
+    # don't actually care about the error.
+    ignore = "Close,fmt:.*"
+
+[linters-settings.exhaustive]
+    default-signifies-exhaustive = true
+
+[linters-settings.gofumpt]
+    extra-rules = true
+
+[linters-settings.lll]
+    line-length = 120
+    tab-width = 4
 
 [issues]
 exclude-use-default = false
+
+  [[issues.exclude-rules]]
+  linters = [
+    "gosec"
+  ]
+  # G306 - "Expect WriteFile permissions to be 0600 or less".
+  text = "G306"
+
+  # This goes off for MD5 usage, which we use heavily
+  [[issues.exclude-rules]]
+  text = "weak cryptographic primitive"
+  linters = ["gosec"]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/geoipupdate-4.3.0/.travis.yml 
new/geoipupdate-4.5.0/.travis.yml
--- old/geoipupdate-4.3.0/.travis.yml   2020-04-16 18:35:28.000000000 +0200
+++ new/geoipupdate-4.5.0/.travis.yml   1970-01-01 01:00:00.000000000 +0100
@@ -1,33 +0,0 @@
-language: go
-
-os:
-  - linux
-  - osx
-  - windows
-
-go:
-  - "1.10.x"
-  - "1.11.x"
-  - "1.12.x"
-  - "1.13.x"
-  - "1.14.x"
-
-before_script:
-  - |
-    if [[ $TRAVIS_GO_VERSION == '1.10.x' ]]; then
-      go get -t -u ./...
-    fi
-  - |
-    if [[ $TRAVIS_GO_VERSION == '1.14.x' && $TRAVIS_OS_NAME == 'linux' ]]; then
-      curl -sfL 
https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- 
-b $(go env GOPATH)/bin
-    fi
-
-script:
-  - go test -v -race ./...
-  - |
-    if [[ $TRAVIS_GO_VERSION == '1.14.x' && $TRAVIS_OS_NAME == 'linux' ]]; then
-      golangci-lint run
-    fi
-
-env:
-  - GO111MODULE=on
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/geoipupdate-4.3.0/CHANGELOG.md 
new/geoipupdate-4.5.0/CHANGELOG.md
--- old/geoipupdate-4.3.0/CHANGELOG.md  2020-04-16 18:35:28.000000000 +0200
+++ new/geoipupdate-4.5.0/CHANGELOG.md  2020-10-28 22:03:38.000000000 +0100
@@ -1,5 +1,26 @@
 # CHANGELOG
 
+## 4.5.0 (2020-10-28)
+
+* We no longer use a third party library for exponential backoff. This
+  restores support for older Go versions.
+
+## 4.4.0 (2020-10-28)
+
+* The edition ID is now included when there is a failure retrieving a
+  database.
+* The Docker image no longer prints the generated `GeoIP.conf` when starting
+  up. This prevents a possible leak of the account's license key. Pull
+  request by Nate Gay. GitHub #109.
+* The minimum Go version is now 1.11.
+* Failing HTTP requests are now retried using an exponential backoff. The
+  period to keep retrying any failed request is set to 5 minutes by default and
+  can be adjusted using the new `RetryFor` configuration option.
+* When using the go package rather than the command-line tool, the null value
+  for `RetryFor` will be 0 seconds, which means no retries will be performed. 
To
+  change that, set `RetryFor` explicitly in the `Config` you provide, or obtain
+  your `Config` value via `geoipupdate.NewConfig`.
+
 ## 4.3.0 (2020-04-16)
 
 * First release to Docker Hub. Requested by Shun Yanaura. GitHub #24.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/geoipupdate-4.3.0/README.md 
new/geoipupdate-4.5.0/README.md
--- old/geoipupdate-4.3.0/README.md     2020-04-16 18:35:28.000000000 +0200
+++ new/geoipupdate-4.5.0/README.md     2020-10-28 22:03:38.000000000 +0100
@@ -1,7 +1,5 @@
 # GeoIP Update
 
-[![Build 
Status](https://travis-ci.com/maxmind/geoipupdate.svg?branch=master)](https://travis-ci.com/maxmind/geoipupdate)
-
 The GeoIP Update program performs automatic updates of GeoIP2 and GeoIP Legacy
 binary databases. CSV databases are _not_ supported.
 
@@ -70,7 +68,7 @@
 
 Download the appropriate .rpm for your system.
 
-Run `rpm -i path/to/geoipupdate_4.0.0_linux_amd64.rpm` (replacing the
+Run `rpm -Uvhi path/to/geoipupdate_4.0.0_linux_amd64.rpm` (replacing the
 version number and architecture as necessary). You will need to be root.
 This will install `geoipupdate` to `/usr/bin/geoipupdate`.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/geoipupdate-4.3.0/cmd/geoipupdate/main.go 
new/geoipupdate-4.5.0/cmd/geoipupdate/main.go
--- old/geoipupdate-4.3.0/cmd/geoipupdate/main.go       2020-04-16 
18:35:28.000000000 +0200
+++ new/geoipupdate-4.5.0/cmd/geoipupdate/main.go       2020-10-28 
22:03:38.000000000 +0100
@@ -38,7 +38,8 @@
                os.Exit(1)
        }
 
-       config, err := geoipupdate.NewConfig(args.ConfigFile, 
defaultDatabaseDirectory, args.DatabaseDirectory, args.Verbose)
+       config, err := geoipupdate.NewConfig(
+               args.ConfigFile, defaultDatabaseDirectory, 
args.DatabaseDirectory, args.Verbose)
        if err != nil {
                fatalLogger(fmt.Sprintf("error loading configuration file %s", 
args.ConfigFile), err)
        }
@@ -61,15 +62,15 @@
        for _, editionID := range config.EditionIDs {
                filename, err := geoipupdate.GetFilename(config, editionID, 
client)
                if err != nil {
-                       return errors.Wrap(err, "error retrieving filename")
+                       return errors.Wrapf(err, "error retrieving filename for 
%s", editionID)
                }
                filePath := filepath.Join(config.DatabaseDirectory, filename)
                dbWriter, err := database.NewLocalFileDatabaseWriter(filePath, 
config.LockFile, config.Verbose)
                if err != nil {
-                       return errors.Wrap(err, "error creating database 
writer")
+                       return errors.Wrapf(err, "error creating database 
writer for %s", editionID)
                }
                if err := dbReader.Get(dbWriter, editionID); err != nil {
-                       return err
+                       return errors.WithMessagef(err, "error while getting 
database for %s", editionID)
                }
        }
        return nil
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/geoipupdate-4.3.0/conf/GeoIP.conf.default 
new/geoipupdate-4.5.0/conf/GeoIP.conf.default
--- old/geoipupdate-4.3.0/conf/GeoIP.conf.default       2020-04-16 
18:35:28.000000000 +0200
+++ new/geoipupdate-4.5.0/conf/GeoIP.conf.default       2020-10-28 
22:03:38.000000000 +0100
@@ -37,3 +37,10 @@
 # Note: Once created, this lockfile is not removed from the filesystem.
 # Defaults to ".geoipupdate.lock" under the DatabaseDirectory.
 # LockFile DATADIR/.geoipupdate.lock
+
+# The amount of time to retry for when errors during HTTP transactions are
+# encountered. It can be specified as a (possibly fractional) decimal number
+# followed by a unit suffix. Valid time units are "ns", "us" (or "µs"), "ms",
+# "s", "m", "h".
+# Defaults to "5m" (5 minutes).
+# RetryFor 5m
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/geoipupdate-4.3.0/doc/GeoIP.conf.md 
new/geoipupdate-4.5.0/doc/GeoIP.conf.md
--- old/geoipupdate-4.3.0/doc/GeoIP.conf.md     2020-04-16 18:35:28.000000000 
+0200
+++ new/geoipupdate-4.5.0/doc/GeoIP.conf.md     2020-10-28 22:03:38.000000000 
+0100
@@ -65,6 +65,13 @@
     filesystem. The default is `.geoipupdate.lock` under the
     `DatabaseDirectory`.
 
+`RetryFor`
+
+:   The amount of time to retry for when errors during HTTP transactions are
+    encountered. It can be specified as a (possibly fractional) decimal number
+    followed by a unit suffix. Valid time units are `ns`, `us` (or `µs`), `ms`,
+    `s`, `m`, `h`. The default is `5m` (5 minutes).
+
 ## Deprecated settings:
 
 The following are deprecated and will be ignored if present:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/geoipupdate-4.3.0/doc/docker.md 
new/geoipupdate-4.5.0/doc/docker.md
--- old/geoipupdate-4.3.0/doc/docker.md 2020-04-16 18:35:28.000000000 +0200
+++ new/geoipupdate-4.5.0/doc/docker.md 2020-10-28 22:03:38.000000000 +0100
@@ -1,5 +1,10 @@
 # Docker
 
+## Image information
+
+The image is available on [Docker 
Hub](https://hub.docker.com/r/maxmindinc/geoipupdate).  
+The source code is available on 
[GitHub](https://github.com/maxmind/geoipupdate).
+
 ## Configuring
 
 The Docker image is configured by environment variables. The following
@@ -27,7 +32,7 @@
   of files downloaded from the server. This option is either `0` or `1`. The
   default is `0`.
 * `GEOIPUPDATE_VERBOSE` - Enable verbose mode. Prints out the steps that
-  `geoipupdate` takes.
+  `geoipupdate` takes. Set to **anything** (e.g., `1`) to enable.
 
 The environment variables can be placed in a file with one per line and
 passed in with the `--env-file` flag. Alternatively, you may pass them in
@@ -35,6 +40,8 @@
 
 ## Running
 
+### docker run
+
 Run the latest image with:
 
 ```
@@ -44,3 +51,39 @@
 `<file>` should be the environment variable file with your configuration.
 `<database directory>` should be the local directory that you want to download
 the databases to.
+
+### docker-compose
+
+Run the latest image with:
+
+```
+version: '3'
+services:
+  geoipupdate:
+    container_name: geoipupdate
+    image: maxmindinc/geoipupdate
+    restart: unless-stopped
+    environment:
+      - GEOIPUPDATE_ACCOUNT_ID=XXXXXX
+      - GEOIPUPDATE_LICENSE_KEY=XXXXXXXXXXXXXXXX
+      - 'GEOIPUPDATE_EDITION_IDS=GeoLite2-ASN GeoLite2-City GeoLite2-Country'
+      - GEOIPUPDATE_FREQUENCY=72
+    networks:
+      - geoipupdate
+    volumes:
+      - 'geoipupdate_data:/usr/share/GeoIP'
+
+networks:
+  geoipupdate:
+
+volumes:
+  geoipupdate_data:
+    driver: local
+```
+
+Note - When using docker-compose, you need to either:
+  - set `GEOIPUPDATE_FREQUENCY` equal to something greater than 0  
+  or  
+  - set `restart: on-failure`
+
+If you don't, the container will continuously restart.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/geoipupdate-4.3.0/docker/entry.sh 
new/geoipupdate-4.5.0/docker/entry.sh
--- old/geoipupdate-4.3.0/docker/entry.sh       2020-04-16 18:35:28.000000000 
+0200
+++ new/geoipupdate-4.5.0/docker/entry.sh       2020-10-28 22:03:38.000000000 
+0100
@@ -39,8 +39,6 @@
     flags="-v"
 fi
 
-cat "$conf_file"
-
 while true; do
     echo "# STATE: Running geoipupdate"
     /usr/bin/geoipupdate -d "$database_dir" -f "$conf_file" $flags
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/geoipupdate-4.3.0/go.mod new/geoipupdate-4.5.0/go.mod
--- old/geoipupdate-4.3.0/go.mod        2020-04-16 18:35:28.000000000 +0200
+++ new/geoipupdate-4.5.0/go.mod        2020-10-28 22:03:38.000000000 +0100
@@ -1,14 +1,16 @@
 module github.com/maxmind/geoipupdate/v4
 
-go 1.10
+go 1.11
 
 require (
        github.com/davecgh/go-spew v1.1.1 // indirect
-       github.com/gofrs/flock v0.7.1
-       github.com/kr/pretty v0.2.0 // indirect
+       github.com/gofrs/flock v0.8.0
+       github.com/kr/text v0.2.0 // indirect
+       github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // 
indirect
        github.com/pkg/errors v0.9.1
        github.com/spf13/pflag v1.0.5
-       github.com/stretchr/testify v1.5.1
-       gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
-       gopkg.in/yaml.v2 v2.2.7 // indirect
+       github.com/stretchr/testify v1.6.1
+       golang.org/x/sys v0.0.0-20201026173827-119d4633e4d1 // indirect
+       gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b // indirect
+       gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 // indirect
 )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/geoipupdate-4.3.0/go.sum new/geoipupdate-4.5.0/go.sum
--- old/geoipupdate-4.3.0/go.sum        2020-04-16 18:35:28.000000000 +0200
+++ new/geoipupdate-4.5.0/go.sum        2020-10-28 22:03:38.000000000 +0100
@@ -1,16 +1,16 @@
+github.com/creack/pty v1.1.9/go.mod 
h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
 github.com/davecgh/go-spew v1.1.0/go.mod 
h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 
h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod 
h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/gofrs/flock v0.7.1 h1:DP+LD/t0njgoPBvT5MJLeliUIVQR03hiKR6vezdwHlc=
-github.com/gofrs/flock v0.7.1/go.mod 
h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
-github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs=
-github.com/kr/pretty v0.2.0/go.mod 
h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
+github.com/gofrs/flock v0.8.0 h1:MSdYClljsF3PbENUUEx85nkWfJSGfzYI9yEBZOJz6CY=
+github.com/gofrs/flock v0.8.0/go.mod 
h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
 github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
 github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
 github.com/kr/text v0.1.0/go.mod 
h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
-github.com/maxmind/geoipupdate v4.0.2+incompatible 
h1:G1tXaGXl3kfFUYE9/pyico4J6OKWFL79i0XVUdbMebk=
-github.com/pkg/errors v0.9.0 h1:J8lpUdobwIeCI7OiSxHqEwJUKvJwicL5+3v1oe2Yb4k=
-github.com/pkg/errors v0.9.0/go.mod 
h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
+github.com/kr/text v0.2.0/go.mod 
h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
+github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e 
h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
+github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod 
h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
 github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
 github.com/pkg/errors v0.9.1/go.mod 
h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pmezard/go-difflib v1.0.0 
h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
@@ -19,16 +19,14 @@
 github.com/spf13/pflag v1.0.5/go.mod 
h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
 github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
 github.com/stretchr/objx v0.1.0/go.mod 
h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/testify v1.4.0 
h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
-github.com/stretchr/testify v1.4.0/go.mod 
h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
-github.com/stretchr/testify v1.5.0 
h1:DMOzIV76tmoDNE9pX6RSN0aDtCYeCg5VueieJaAo1uw=
-github.com/stretchr/testify v1.5.0/go.mod 
h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
-github.com/stretchr/testify v1.5.1 
h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
-github.com/stretchr/testify v1.5.1/go.mod 
h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
+github.com/stretchr/testify v1.6.1 
h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
+github.com/stretchr/testify v1.6.1/go.mod 
h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+golang.org/x/sys v0.0.0-20201026173827-119d4633e4d1 
h1:/DtoiOYKoQCcIFXQjz07RnWNPRCbqmSXSpgEzhC9ZHM=
+golang.org/x/sys v0.0.0-20201026173827-119d4633e4d1/go.mod 
h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod 
h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 
h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
-gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod 
h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
-gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.2.7 h1:VUgggvou5XRW9mHwD/yXxIYSMtY0zoKQf/v226p2nyo=
-gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b 
h1:QRR6H1YWRnHb4Y/HeNFCTJLFVxaq6wH4YuVdsUOr75U=
+gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod 
h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c 
h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod 
h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 
h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ=
+gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod 
h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/geoipupdate-4.3.0/pkg/geoipupdate/config.go 
new/geoipupdate-4.5.0/pkg/geoipupdate/config.go
--- old/geoipupdate-4.3.0/pkg/geoipupdate/config.go     2020-04-16 
18:35:28.000000000 +0200
+++ new/geoipupdate-4.5.0/pkg/geoipupdate/config.go     2020-10-28 
22:03:38.000000000 +0100
@@ -9,6 +9,7 @@
        "regexp"
        "strconv"
        "strings"
+       "time"
 
        "github.com/pkg/errors"
 )
@@ -24,6 +25,7 @@
        Proxy             *url.URL
        PreserveFileTimes bool
        Verbose           bool
+       RetryFor          time.Duration
 }
 
 // NewConfig parses the configuration file.
@@ -101,6 +103,12 @@
                        proxyUserPassword = value
                case "Protocol", "SkipHostnameVerification", 
"SkipPeerVerification":
                        // Deprecated.
+               case "RetryFor":
+                       dur, err := time.ParseDuration(value)
+                       if err != nil || dur < 0 {
+                               return nil, errors.Errorf("'%s' is not a valid 
duration", value)
+                       }
+                       config.RetryFor = dur
                default:
                        return nil, errors.Errorf("unknown option on line %d", 
lineNumber)
                }
@@ -124,6 +132,10 @@
 
        // Set defaults & post-process.
 
+       if _, ok := keysSeen["RetryFor"]; !ok {
+               config.RetryFor = 5 * time.Minute
+       }
+
        // Argument takes precedence.
        if databaseDirectory != "" {
                config.DatabaseDirectory = filepath.Clean(databaseDirectory)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/geoipupdate-4.3.0/pkg/geoipupdate/config_test.go 
new/geoipupdate-4.5.0/pkg/geoipupdate/config_test.go
--- old/geoipupdate-4.3.0/pkg/geoipupdate/config_test.go        2020-04-16 
18:35:28.000000000 +0200
+++ new/geoipupdate-4.5.0/pkg/geoipupdate/config_test.go        2020-10-28 
22:03:38.000000000 +0100
@@ -7,6 +7,7 @@
        "os"
        "path/filepath"
        "testing"
+       "time"
 
        "github.com/stretchr/testify/assert"
        "github.com/stretchr/testify/require"
@@ -60,6 +61,13 @@
 # Note: Once created, this lockfile is not removed from the filesystem.
 # Defaults to ".geoipupdate.lock" under the DatabaseDirectory.
 # LockFile DATADIR/.geoipupdate.lock
+
+# The amount of time to retry for when errors during HTTP transactions are
+# encountered. It can be specified as a (possibly fractional) decimal number
+# followed by a unit suffix. Valid time units are "ns", "us" (or "µs"), "ms",
+# "s", "m", "h".
+# Defaults to "5m" (5 minutes).
+# RetryFor 5m
 `,
                        Output: &Config{
                                AccountID:         42,
@@ -68,6 +76,7 @@
                                EditionIDs:        []string{"GeoLite2-Country", 
"GeoLite2-City"},
                                LockFile:          
filepath.Clean("/tmp/.geoipupdate.lock"),
                                URL:               
"https://updates.maxmind.com";,
+                               RetryFor:          5 * time.Minute,
                        },
                },
                {
@@ -119,6 +128,7 @@
                                EditionIDs:        []string{"GeoLite2-Country", 
"GeoLite2-City"},
                                LockFile:          
filepath.Clean("/tmp/.geoipupdate.lock"),
                                URL:               
"https://updates.maxmind.com";,
+                               RetryFor:          5 * time.Minute,
                        },
                },
                {
@@ -162,6 +172,8 @@
 # Note: Once created, this lockfile is not removed from the filesystem.
 # Defaults to ".geoipupdate.lock" under the DatabaseDirectory.
 LockFile /usr/lock
+
+RetryFor 10m
 `,
                        Output: &Config{
                                AccountID:         1234,
@@ -176,6 +188,7 @@
                                },
                                PreserveFileTimes: true,
                                URL:               
"https://updates.example.com";,
+                               RetryFor:          10 * time.Minute,
                        },
                },
                {
@@ -252,6 +265,20 @@
                        Err: "geoipupdate requires a valid AccountID and 
LicenseKey combination",
                },
                {
+                       Description: "RetryFor needs a unit",
+                       Input: `AccountID 42
+LicenseKey 000000000001
+RetryFor 5`,
+                       Err: "'5' is not a valid duration",
+               },
+               {
+                       Description: "RetryFor needs to be non-negative",
+                       Input: `AccountID 42
+LicenseKey 000000000001
+RetryFor -5m`,
+                       Err: "'-5m' is not a valid duration",
+               },
+               {
                        Description: "AccountID 999999 with a non-000000000000 
LicenseKey is treated normally",
                        Input: `AccountID 999999
 LicenseKey abcd
@@ -263,6 +290,7 @@
                                LicenseKey:        "abcd",
                                LockFile:          
filepath.Clean("/tmp/.geoipupdate.lock"),
                                URL:               
"https://updates.maxmind.com";,
+                               RetryFor:          5 * time.Minute,
                        },
                },
                {
@@ -281,6 +309,7 @@
                                LicenseKey:        "abcd",
                                LockFile:          
filepath.Clean("/tmp/.geoipupdate.lock"),
                                URL:               
"https://updates.maxmind.com";,
+                               RetryFor:          5 * time.Minute,
                        },
                },
                {
@@ -293,12 +322,14 @@
                                LicenseKey:        "123",
                                LockFile:          
filepath.Clean("/tmp/.geoipupdate.lock"),
                                URL:               
"https://updates.maxmind.com";,
+                               RetryFor:          5 * time.Minute,
                        },
                },
                {
                        Description: "CR line ending does not work",
                        Input:       "AccountID 0\rLicenseKey 123\rEditionIDs 
GeoIP2-City\r",
-                       Err:         `invalid account ID format: strconv.Atoi: 
parsing "0 LicenseKey 123 EditionIDs GeoIP2-City": invalid syntax`,
+                       // nolint: lll
+                       Err: `invalid account ID format: strconv.Atoi: parsing 
"0 LicenseKey 123 EditionIDs GeoIP2-City": invalid syntax`,
                },
                {
                        Description: "Multiple spaces between option and value 
works",
@@ -313,11 +344,13 @@
                                LicenseKey:        "456",
                                LockFile:          
filepath.Clean("/tmp/.geoipupdate.lock"),
                                URL:               
"https://updates.maxmind.com";,
+                               RetryFor:          5 * time.Minute,
                        },
                },
                {
                        Description: "Tabs between options and values works",
-                       Input:       
"AccountID\t123\nLicenseKey\t\t456\nEditionIDs\t\t\tGeoLite2-City\t\t\t\tGeoLite2-Country\t\t\t\t\n",
+
+                       Input: 
"AccountID\t123\nLicenseKey\t\t456\nEditionIDs\t\t\tGeoLite2-City\t\t\t\tGeoLite2-Country\t\t\t\t\n",
                        Output: &Config{
                                AccountID:         123,
                                DatabaseDirectory: filepath.Clean("/tmp"),
@@ -325,6 +358,7 @@
                                LicenseKey:        "456",
                                LockFile:          
filepath.Clean("/tmp/.geoipupdate.lock"),
                                URL:               
"https://updates.maxmind.com";,
+                               RetryFor:          5 * time.Minute,
                        },
                },
        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/geoipupdate-4.3.0/pkg/geoipupdate/database/http_reader.go 
new/geoipupdate-4.5.0/pkg/geoipupdate/database/http_reader.go
--- old/geoipupdate-4.3.0/pkg/geoipupdate/database/http_reader.go       
2020-04-16 18:35:28.000000000 +0200
+++ new/geoipupdate-4.5.0/pkg/geoipupdate/database/http_reader.go       
2020-10-28 22:03:38.000000000 +0100
@@ -1,3 +1,5 @@
+// Package database provides an abstraction over getting and writing a
+// database file.
 package database
 
 import (
@@ -11,6 +13,7 @@
        "time"
 
        "github.com/maxmind/geoipupdate/v4/pkg/geoipupdate"
+       "github.com/maxmind/geoipupdate/v4/pkg/geoipupdate/internal"
        "github.com/pkg/errors"
 )
 
@@ -18,6 +21,7 @@
 // databases.
 type HTTPDatabaseReader struct {
        client            *http.Client
+       retryFor          time.Duration
        url               string
        licenseKey        string
        accountID         int
@@ -30,6 +34,7 @@
 func NewHTTPDatabaseReader(client *http.Client, config *geoipupdate.Config) 
Reader {
        return &HTTPDatabaseReader{
                client:            client,
+               retryFor:          config.RetryFor,
                url:               config.URL,
                licenseKey:        config.LicenseKey,
                accountID:         config.AccountID,
@@ -54,7 +59,7 @@
                url.QueryEscape(destination.GetHash()),
        )
 
-       req, err := http.NewRequest(http.MethodGet, maxMindURL, nil)
+       req, err := http.NewRequest(http.MethodGet, maxMindURL, nil) // nolint: 
noctx
        if err != nil {
                return errors.Wrap(err, "error creating request")
        }
@@ -63,7 +68,7 @@
        if reader.verbose {
                log.Printf("Performing update request to %s", maxMindURL)
        }
-       response, err := reader.client.Do(req)
+       response, err := internal.MaybeRetryRequest(reader.client, 
reader.retryFor, req)
        if err != nil {
                return errors.Wrap(err, "error performing HTTP request")
        }
@@ -98,7 +103,7 @@
                }
        }()
 
-       if _, err = io.Copy(destination, gzReader); err != nil {
+       if _, err = io.Copy(destination, gzReader); err != nil { //nolint:gosec
                return errors.Wrap(err, "error writing response")
        }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/geoipupdate-4.3.0/pkg/geoipupdate/database/http_reader_test.go 
new/geoipupdate-4.5.0/pkg/geoipupdate/database/http_reader_test.go
--- old/geoipupdate-4.3.0/pkg/geoipupdate/database/http_reader_test.go  
2020-04-16 18:35:28.000000000 +0200
+++ new/geoipupdate-4.5.0/pkg/geoipupdate/database/http_reader_test.go  
2020-10-28 22:03:38.000000000 +0100
@@ -97,6 +97,7 @@
                        DownloadHeaders: map[string]string{
                                "X-Database-MD5": 
"5d41402abc4b2a76b9719d911017c592", // "hello"
                        },
+                       // nolint: lll
                        Err: `md5 of new database 
\(985ecf3d7959b146208b3dc0189b21a5\) does not match expected md5 
\(5d41402abc4b2a76b9719d911017c592\)`,
                },
                {
@@ -203,7 +204,7 @@
                                err := ioutil.WriteFile(
                                        currentDatabasePath,
                                        []byte(test.DatabaseBefore),
-                                       0644,
+                                       0600,
                                )
                                require.NoError(t, err)
                        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/geoipupdate-4.3.0/pkg/geoipupdate/database/local_file_writer.go 
new/geoipupdate-4.5.0/pkg/geoipupdate/database/local_file_writer.go
--- old/geoipupdate-4.3.0/pkg/geoipupdate/database/local_file_writer.go 
2020-04-16 18:35:28.000000000 +0200
+++ new/geoipupdate-4.5.0/pkg/geoipupdate/database/local_file_writer.go 
2020-10-28 22:03:38.000000000 +0100
@@ -31,7 +31,7 @@
 // NewLocalFileDatabaseWriter create a LocalFileDatabaseWriter. It creates the
 // necessary lock and temporary files to protect the database from concurrent
 // writes.
-func NewLocalFileDatabaseWriter(filePath string, lockFilePath string, verbose 
bool) (*LocalFileDatabaseWriter, error) {
+func NewLocalFileDatabaseWriter(filePath, lockFilePath string, verbose bool) 
(*LocalFileDatabaseWriter, error) {
        dbWriter := &LocalFileDatabaseWriter{
                filePath:     filePath,
                lockFilePath: lockFilePath,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/geoipupdate-4.3.0/pkg/geoipupdate/database/writer.go 
new/geoipupdate-4.5.0/pkg/geoipupdate/database/writer.go
--- old/geoipupdate-4.3.0/pkg/geoipupdate/database/writer.go    2020-04-16 
18:35:28.000000000 +0200
+++ new/geoipupdate-4.5.0/pkg/geoipupdate/database/writer.go    2020-10-28 
22:03:38.000000000 +0100
@@ -1,13 +1,14 @@
 package database
 
 import (
-       "github.com/gofrs/flock"
-       "github.com/pkg/errors"
        "io"
        "log"
        "os"
        "path/filepath"
        "time"
+
+       "github.com/gofrs/flock"
+       "github.com/pkg/errors"
 )
 
 // ZeroMD5 is the default value provided as an MD5 hash for a non-existent
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/geoipupdate-4.3.0/pkg/geoipupdate/database/writer_test.go 
new/geoipupdate-4.5.0/pkg/geoipupdate/database/writer_test.go
--- old/geoipupdate-4.3.0/pkg/geoipupdate/database/writer_test.go       
2020-04-16 18:35:28.000000000 +0200
+++ new/geoipupdate-4.5.0/pkg/geoipupdate/database/writer_test.go       
2020-10-28 22:03:38.000000000 +0100
@@ -1,12 +1,13 @@
 package database
 
 import (
-       "github.com/stretchr/testify/assert"
-       "github.com/stretchr/testify/require"
        "io/ioutil"
        "os"
        "path/filepath"
        "testing"
+
+       "github.com/stretchr/testify/assert"
+       "github.com/stretchr/testify/require"
 )
 
 func TestCreateLockFile(t *testing.T) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/geoipupdate-4.3.0/pkg/geoipupdate/geoip_updater.go 
new/geoipupdate-4.5.0/pkg/geoipupdate/geoip_updater.go
--- old/geoipupdate-4.3.0/pkg/geoipupdate/geoip_updater.go      2020-04-16 
18:35:28.000000000 +0200
+++ new/geoipupdate-4.5.0/pkg/geoipupdate/geoip_updater.go      2020-10-28 
22:03:38.000000000 +0100
@@ -1,3 +1,5 @@
+// Package geoipupdate provides a library for using MaxMind's GeoIP Update
+// service.
 package geoipupdate
 
 import (
@@ -9,6 +11,7 @@
        "net/http"
        "net/url"
 
+       "github.com/maxmind/geoipupdate/v4/pkg/geoipupdate/internal"
        "github.com/pkg/errors"
 )
 
@@ -16,14 +19,12 @@
 func NewClient(
        config *Config,
 ) *http.Client {
-       var client *http.Client
        transport := http.DefaultTransport
        if config.Proxy != nil {
                proxy := http.ProxyURL(config.Proxy)
                transport.(*http.Transport).Proxy = proxy
        }
-       client = &http.Client{Transport: transport}
-       return client
+       return &http.Client{Transport: transport}
 }
 
 // GetFilename looks up the filename for the given edition ID.
@@ -41,7 +42,11 @@
        if config.Verbose {
                log.Printf("Performing get filename request to %s", maxMindURL)
        }
-       res, err := client.Get(maxMindURL)
+       req, err := http.NewRequest(http.MethodGet, maxMindURL, nil) // nolint: 
noctx
+       if err != nil {
+               return "", errors.Wrap(err, "error creating HTTP request")
+       }
+       res, err := internal.MaybeRetryRequest(client, config.RetryFor, req)
        if err != nil {
                return "", errors.Wrap(err, "error performing HTTP request")
        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/geoipupdate-4.3.0/pkg/geoipupdate/geoip_updater_test.go 
new/geoipupdate-4.5.0/pkg/geoipupdate/geoip_updater_test.go
--- old/geoipupdate-4.3.0/pkg/geoipupdate/geoip_updater_test.go 2020-04-16 
18:35:28.000000000 +0200
+++ new/geoipupdate-4.5.0/pkg/geoipupdate/geoip_updater_test.go 2020-10-28 
22:03:38.000000000 +0100
@@ -1,14 +1,15 @@
 package geoipupdate
 
 import (
-       "github.com/stretchr/testify/assert"
-       "github.com/stretchr/testify/require"
        "io/ioutil"
        "net/http"
        "net/http/httptest"
        "os"
        "path/filepath"
        "testing"
+
+       "github.com/stretchr/testify/assert"
+       "github.com/stretchr/testify/require"
 )
 
 func TestGetFileName(t *testing.T) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/geoipupdate-4.3.0/pkg/geoipupdate/internal/retry.go 
new/geoipupdate-4.5.0/pkg/geoipupdate/internal/retry.go
--- old/geoipupdate-4.3.0/pkg/geoipupdate/internal/retry.go     1970-01-01 
01:00:00.000000000 +0100
+++ new/geoipupdate-4.5.0/pkg/geoipupdate/internal/retry.go     2020-10-28 
22:03:38.000000000 +0100
@@ -0,0 +1,47 @@
+// Package internal is none of your business
+package internal
+
+import (
+       "net/http"
+       "time"
+
+       "github.com/pkg/errors"
+)
+
+// MaybeRetryRequest is an internal implementation detail of this module. It
+// shouldn't be used by users of the geoipupdate Go library. You can use the
+// RetryFor field of geoipupdate.Config if you'd like to retry failed requests
+// when using the library directly.
+func MaybeRetryRequest(c *http.Client, retryFor time.Duration, req 
*http.Request) (*http.Response, error) {
+       if retryFor < 0 {
+               return nil, errors.New("negative retry duration")
+       }
+       if req.Body != nil {
+               return nil, errors.New("can't retry requests with bodies")
+       }
+       var resp *http.Response
+       var err error
+
+       start := time.Now()
+       for i := uint(0); ; i++ {
+               resp, err = c.Do(req)
+               if err == nil && resp.StatusCode < 500 {
+                       break
+               }
+
+               currentDuration := time.Since(start)
+
+               waitDuration := 200 * time.Millisecond * (1 << i)
+               if currentDuration+waitDuration > retryFor {
+                       break
+               }
+               if err == nil {
+                       _ = resp.Body.Close()
+               }
+               time.Sleep(waitDuration)
+       }
+       if err != nil {
+               return nil, errors.Wrap(err, "error performing http request")
+       }
+       return resp, nil
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/geoipupdate-4.3.0/pkg/geoipupdate/internal/retry_test.go 
new/geoipupdate-4.5.0/pkg/geoipupdate/internal/retry_test.go
--- old/geoipupdate-4.3.0/pkg/geoipupdate/internal/retry_test.go        
1970-01-01 01:00:00.000000000 +0100
+++ new/geoipupdate-4.5.0/pkg/geoipupdate/internal/retry_test.go        
2020-10-28 22:03:38.000000000 +0100
@@ -0,0 +1,71 @@
+package internal
+
+import (
+       "net/http"
+       "net/http/httptest"
+       "testing"
+       "time"
+
+       "github.com/stretchr/testify/assert"
+       "github.com/stretchr/testify/require"
+)
+
+func TestRetry(t *testing.T) {
+       {
+               n, resp, err := testRetry( // nolint: bodyclose
+                       t,
+                       func(n int, causeError func()) int {
+                               causeError()
+                               return http.StatusOK
+                       },
+               )
+               assert.Equal(t, 5, n)
+               assert.Error(t, err)
+               assert.Nil(t, resp)
+       }
+
+       {
+               n, resp, err := testRetry(
+                       t,
+                       func(n int, causeError func()) int {
+                               if n < 3 {
+                                       causeError()
+                               }
+                               return http.StatusOK
+                       },
+               )
+               assert.Equal(t, 3, n)
+               assert.NoError(t, err)
+               assert.NotNil(t, resp)
+               require.NoError(t, resp.Body.Close())
+       }
+
+       {
+               n, resp, err := testRetry(
+                       t,
+                       func(int, func()) int { return 
http.StatusInternalServerError },
+               )
+               assert.Equal(t, 5, n)
+               assert.NoError(t, err)
+               require.NoError(t, resp.Body.Close())
+       }
+}
+
+func testRetry(t *testing.T, cb func(int, func()) int) (int, *http.Response, 
error) {
+       var server *httptest.Server
+       requests := 0
+       server = httptest.NewServer(
+               http.HandlerFunc(
+                       func(rw http.ResponseWriter, r *http.Request) {
+                               requests++
+                               rw.WriteHeader(cb(requests, func() { 
server.CloseClientConnections() }))
+                       },
+               ),
+       )
+
+       req, err := http.NewRequest(http.MethodGet, server.URL, nil) // nolint: 
noctx
+       require.NoError(t, err)
+       resp, err := MaybeRetryRequest(server.Client(), 6*time.Second, req)
+       server.Close()
+       return requests, resp, err
+}

++++++ vendor.tar.gz ++++++
++++ 179273 lines of diff (skipped)


Reply via email to