mirror of
https://github.com/gocsaf/csaf.git
synced 2025-12-22 11:55:40 +01:00
Add extra http header support to downloader and checker.
This commit is contained in:
parent
732383561b
commit
51fba46893
7 changed files with 117 additions and 41 deletions
|
|
@ -19,6 +19,7 @@ import (
|
|||
"html/template"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
"github.com/csaf-poc/csaf_distribution/util"
|
||||
|
|
@ -29,15 +30,16 @@ import (
|
|||
var reportHTML string
|
||||
|
||||
type options struct {
|
||||
Output string `short:"o" long:"output" description:"File name of the generated report" value-name:"REPORT-FILE"`
|
||||
Format string `short:"f" long:"format" choice:"json" choice:"html" description:"Format of report" default:"json"`
|
||||
Insecure bool `long:"insecure" description:"Do not check TLS certificates from provider"`
|
||||
ClientCert *string `long:"client-cert" description:"TLS client certificate file (PEM encoded data)" value-name:"CERT-FILE"`
|
||||
ClientKey *string `long:"client-key" description:"TLS client private key file (PEM encoded data)" value-name:"KEY-FILE"`
|
||||
Version bool `long:"version" description:"Display version of the binary"`
|
||||
Verbose bool `long:"verbose" short:"v" description:"Verbose output"`
|
||||
Rate *float64 `long:"rate" short:"r" description:"The average upper limit of https operations per second"`
|
||||
Years *uint `long:"years" short:"y" description:"Number of years to look back from now" value-name:"YEARS"`
|
||||
Output string `short:"o" long:"output" description:"File name of the generated report" value-name:"REPORT-FILE"`
|
||||
Format string `short:"f" long:"format" choice:"json" choice:"html" description:"Format of report" default:"json"`
|
||||
Insecure bool `long:"insecure" description:"Do not check TLS certificates from provider"`
|
||||
ClientCert *string `long:"client-cert" description:"TLS client certificate file (PEM encoded data)" value-name:"CERT-FILE"`
|
||||
ClientKey *string `long:"client-key" description:"TLS client private key file (PEM encoded data)" value-name:"KEY-FILE"`
|
||||
Version bool `long:"version" description:"Display version of the binary"`
|
||||
Verbose bool `long:"verbose" short:"v" description:"Verbose output"`
|
||||
Rate *float64 `long:"rate" short:"r" description:"The average upper limit of https operations per second"`
|
||||
Years *uint `long:"years" short:"y" description:"Number of years to look back from now" value-name:"YEARS"`
|
||||
ExtraHeader http.Header `long:"header" short:"H" description:"One or more extra HTTP header fields"`
|
||||
|
||||
clientCerts []tls.Certificate
|
||||
}
|
||||
|
|
|
|||
|
|
@ -351,24 +351,30 @@ func (p *processor) httpClient() util.Client {
|
|||
TLSClientConfig: &tlsConfig,
|
||||
}
|
||||
|
||||
var client util.Client
|
||||
client := util.Client(&hClient)
|
||||
|
||||
// Add extra headers.
|
||||
if len(p.opts.ExtraHeader) > 0 {
|
||||
client = &util.HeaderClient{
|
||||
Client: client,
|
||||
Header: p.opts.ExtraHeader,
|
||||
}
|
||||
}
|
||||
|
||||
// Add optional URL logging.
|
||||
if p.opts.Verbose {
|
||||
client = &util.LoggingClient{Client: &hClient}
|
||||
} else {
|
||||
client = &hClient
|
||||
client = &util.LoggingClient{Client: client}
|
||||
}
|
||||
|
||||
if p.opts.Rate == nil {
|
||||
p.client = client
|
||||
return client
|
||||
}
|
||||
|
||||
p.client = &util.LimitingClient{
|
||||
Client: client,
|
||||
Limiter: rate.NewLimiter(rate.Limit(*p.opts.Rate), 1),
|
||||
// Add optional rate limiting.
|
||||
if p.opts.Rate != nil {
|
||||
client = &util.LimitingClient{
|
||||
Client: client,
|
||||
Limiter: rate.NewLimiter(rate.Limit(*p.opts.Rate), 1),
|
||||
}
|
||||
}
|
||||
|
||||
p.client = client
|
||||
return p.client
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -64,24 +64,30 @@ func (d *downloader) httpClient() util.Client {
|
|||
}
|
||||
}
|
||||
|
||||
var client util.Client
|
||||
client := util.Client(&hClient)
|
||||
|
||||
// Add extra headers.
|
||||
if len(d.opts.ExtraHeader) > 0 {
|
||||
client = &util.HeaderClient{
|
||||
Client: client,
|
||||
Header: d.opts.ExtraHeader,
|
||||
}
|
||||
}
|
||||
|
||||
// Add optional URL logging.
|
||||
if d.opts.Verbose {
|
||||
client = &util.LoggingClient{Client: &hClient}
|
||||
} else {
|
||||
client = &hClient
|
||||
client = &util.LoggingClient{Client: client}
|
||||
}
|
||||
|
||||
if d.opts.Rate == nil {
|
||||
d.client = client
|
||||
return client
|
||||
}
|
||||
|
||||
d.client = &util.LimitingClient{
|
||||
Client: client,
|
||||
Limiter: rate.NewLimiter(rate.Limit(*d.opts.Rate), 1),
|
||||
// Add optional rate limiting.
|
||||
if d.opts.Rate != nil {
|
||||
client = &util.LimitingClient{
|
||||
Client: client,
|
||||
Limiter: rate.NewLimiter(rate.Limit(*d.opts.Rate), 1),
|
||||
}
|
||||
}
|
||||
|
||||
d.client = client
|
||||
return d.client
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ package main
|
|||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
"github.com/csaf-poc/csaf_distribution/util"
|
||||
|
|
@ -19,11 +20,12 @@ import (
|
|||
)
|
||||
|
||||
type options struct {
|
||||
Directory *string `short:"d" long:"directory" description:"Directory to store the downloaded files in"`
|
||||
Insecure bool `long:"insecure" description:"Do not check TLS certificates from provider"`
|
||||
Version bool `long:"version" description:"Display version of the binary"`
|
||||
Verbose bool `long:"verbose" short:"v" description:"Verbose output"`
|
||||
Rate *float64 `long:"rate" short:"r" description:"The average upper limit of https operations per second"`
|
||||
Directory *string `short:"d" long:"directory" description:"Directory to store the downloaded files in"`
|
||||
Insecure bool `long:"insecure" description:"Do not check TLS certificates from provider"`
|
||||
Version bool `long:"version" description:"Display version of the binary"`
|
||||
Verbose bool `long:"verbose" short:"v" description:"Verbose output"`
|
||||
Rate *float64 `long:"rate" short:"r" description:"The average upper limit of https operations per second"`
|
||||
ExtraHeader http.Header `long:"header" short:"H" description:"One or more extra HTTP header fields"`
|
||||
}
|
||||
|
||||
func errCheck(err error) {
|
||||
|
|
|
|||
|
|
@ -15,13 +15,14 @@ Application Options:
|
|||
-v, --verbose Verbose output
|
||||
-r, --rate= The average upper limit of https operations per second
|
||||
-y, --years=YEARS Number of years to look back from now
|
||||
-H, --header= One or more extra HTTP header fields
|
||||
|
||||
Help Options:
|
||||
-h, --help Show this help message
|
||||
```
|
||||
|
||||
Usage example:
|
||||
` ./csaf_checker example.com -f html --rate=5.3 -o check-results.html`
|
||||
` ./csaf_checker example.com -f html --rate=5.3 -H apikey:SECRET -o check-results.html`
|
||||
|
||||
Each performed check has a return type of either 0,1 or 2:
|
||||
```
|
||||
|
|
|
|||
|
|
@ -4,8 +4,7 @@ A tool to download CSAF content from a specific domain/provider.
|
|||
### Usage
|
||||
|
||||
```
|
||||
Usage:
|
||||
csaf_downloader [OPTIONS] domain...
|
||||
csaf_downloader [OPTIONS] domain...
|
||||
|
||||
Application Options:
|
||||
-d, --directory= Directory to store the downloaded files in
|
||||
|
|
@ -13,6 +12,7 @@ Application Options:
|
|||
--version Display version of the binary
|
||||
-v, --verbose Verbose output
|
||||
-r, --rate= The average upper limit of https operations per second
|
||||
-H, --header= One or more extra HTTP header fields
|
||||
|
||||
Help Options:
|
||||
-h, --help Show this help message
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import (
|
|||
"log"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/time/rate"
|
||||
)
|
||||
|
|
@ -38,6 +39,64 @@ type LimitingClient struct {
|
|||
Limiter *rate.Limiter
|
||||
}
|
||||
|
||||
// HeaderClient adds extra HTTP header fields to the ou going requests.
|
||||
type HeaderClient struct {
|
||||
Client
|
||||
Header http.Header
|
||||
}
|
||||
|
||||
// Do implements the respective method of the [Client] interface.
|
||||
func (hc *HeaderClient) Do(req *http.Request) (*http.Response, error) {
|
||||
// Maybe this overly careful but this minimizes
|
||||
// potential side effects in the caller.
|
||||
orig := req.Header
|
||||
defer func() { req.Header = orig }()
|
||||
|
||||
// Work on a copy.
|
||||
req.Header = req.Header.Clone()
|
||||
|
||||
for key, values := range hc.Header {
|
||||
for _, v := range values {
|
||||
req.Header.Add(key, v)
|
||||
}
|
||||
}
|
||||
return hc.Client.Do(req)
|
||||
}
|
||||
|
||||
// Get implements the respective method of the [Client] interface.
|
||||
func (hc *HeaderClient) Get(url string) (*http.Response, error) {
|
||||
req, err := http.NewRequest(http.MethodGet, url, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return hc.Do(req)
|
||||
}
|
||||
|
||||
// Head implements the respective method of the [Client] interface.
|
||||
func (hc *HeaderClient) Head(url string) (*http.Response, error) {
|
||||
req, err := http.NewRequest(http.MethodHead, url, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return hc.Do(req)
|
||||
}
|
||||
|
||||
// Post implements the respective method of the [Client] interface.
|
||||
func (hc *HeaderClient) Post(url, contentType string, body io.Reader) (*http.Response, error) {
|
||||
req, err := http.NewRequest(http.MethodPost, url, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Set("Content-Type", contentType)
|
||||
return hc.Do(req)
|
||||
}
|
||||
|
||||
// PostForm implements the respective method of the [Client] interface.
|
||||
func (hc *HeaderClient) PostForm(url string, data url.Values) (*http.Response, error) {
|
||||
return hc.Post(
|
||||
url, "application/x-www-form-urlencoded", strings.NewReader(data.Encode()))
|
||||
}
|
||||
|
||||
// Do implements the respective method of the Client interface.
|
||||
func (lc *LoggingClient) Do(req *http.Request) (*http.Response, error) {
|
||||
log.Printf("[DO]: %s\n", req.URL.String())
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue