Skip to content

Commit

Permalink
Performing checksums after downloading the file.
Browse files Browse the repository at this point in the history
  • Loading branch information
Harisabdullah committed Aug 7, 2023
1 parent c4d505b commit 0191e17
Showing 1 changed file with 65 additions and 0 deletions.
65 changes: 65 additions & 0 deletions ipinfo/cmd_download.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package main

import (
"compress/gzip"
"crypto/sha256"
"encoding/json"
"errors"
"fmt"
"io"
Expand All @@ -17,6 +19,14 @@ import (

const dbDownloadURL = "https://ipinfo.io/data/free/"

type ChecksumResponse struct {
Checksums struct {
MD5 string `json:"md5"`
SHA1 string `json:"sha1"`
SHA256 string `json:"sha256"`
} `json:"checksums"`
}

var completionsDownload = &complete.Command{
Flags: map[string]complete.Predictor{
"-c": predict.Nothing,
Expand Down Expand Up @@ -136,6 +146,26 @@ func cmdDownload() error {

url := fmt.Sprintf("%s%s.%s?token=%s", dbDownloadURL, dbName, format, token)
err := downloadDb(url, fileName, format, fZip)

// check if checksums match.
checksumUrl := fmt.Sprintf("%s%s.%s/checksums?token=%s", dbDownloadURL, dbName, format, token)
// fetch checksums from API.
checksumResponse, err := fetchChecksums(checksumUrl)
if err != nil {
return err
}

// compute checksum of downloaded file.
localChecksum, err := computeSHA256(fileName)
if err != nil {
return err
}

// compare checksums.
if localChecksum != checksumResponse.Checksums.SHA256 {
return errors.New("checksums do not match. File might be corrupted")
}

if err != nil {
return err
}
Expand Down Expand Up @@ -238,3 +268,38 @@ func unzipWrite(file *os.File, data io.Reader) error {

return nil
}

func computeSHA256(filepath string) (string, error) {
file, err := os.Open(filepath)
if err != nil {
return "", err
}
defer file.Close()

hasher := sha256.New()
if _, err := io.Copy(hasher, file); err != nil {
return "", err
}

return fmt.Sprintf("%x", hasher.Sum(nil)), nil
}

func fetchChecksums(url string) (*ChecksumResponse, error) {
resp, err := http.Get(url)
if err != nil {
return nil, err
}
defer resp.Body.Close()

body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}

var checksumResponse ChecksumResponse
if err := json.Unmarshal(body, &checksumResponse); err != nil {
return nil, err
}

return &checksumResponse, nil
}

0 comments on commit 0191e17

Please sign in to comment.