Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 11 additions & 7 deletions internal/aws/sigv4.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
"strings"
"time"

"github.com/ryanfowler/fetch/internal/vars"
"github.com/ryanfowler/fetch/internal/core"
)

const (
Expand Down Expand Up @@ -113,25 +113,29 @@ func getPayloadHash(req *http.Request, service string) (string, error) {
return hexSha256Reader(bytes.NewReader(body))
}

func getSignedHeaders(req *http.Request) []vars.KeyVal {
out := make([]vars.KeyVal, 0, len(req.Header)+1)
out = append(out, vars.KeyVal{Key: "host", Val: req.URL.Host})
func getSignedHeaders(req *http.Request) []core.KeyVal {
out := make([]core.KeyVal, 0, len(req.Header)+1)

if _, ok := req.Header["Host"]; !ok {
out = append(out, core.KeyVal{Key: "host", Val: req.URL.Host})
}

for key, vals := range req.Header {
switch key {
case "Authorization", "Content-Length", "User-Agent":
continue
}
key = strings.ToLower(strings.TrimSpace(key))
val := strings.TrimSpace(strings.Join(vals, ","))
out = append(out, vars.KeyVal{Key: key, Val: val})
out = append(out, core.KeyVal{Key: key, Val: val})
}
slices.SortFunc(out, func(a, b vars.KeyVal) int {
slices.SortFunc(out, func(a, b core.KeyVal) int {
return strings.Compare(a.Key, b.Key)
})
return out
}

func buildCanonicalRequest(req *http.Request, headers []vars.KeyVal, payload string) []byte {
func buildCanonicalRequest(req *http.Request, headers []core.KeyVal, payload string) []byte {
var buf bytes.Buffer
buf.Grow(512)

Expand Down
43 changes: 21 additions & 22 deletions internal/cli/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,37 +13,36 @@ import (

"github.com/ryanfowler/fetch/internal/aws"
"github.com/ryanfowler/fetch/internal/client"
"github.com/ryanfowler/fetch/internal/fetch"
"github.com/ryanfowler/fetch/internal/core"
"github.com/ryanfowler/fetch/internal/printer"
"github.com/ryanfowler/fetch/internal/vars"
)

type App struct {
URL *url.URL

AWSSigv4 *aws.Config
Basic *vars.KeyVal
Basic *core.KeyVal
Bearer string
Color printer.Color
Color core.Color
Data io.Reader
DNSServer string
DryRun bool
Edit bool
Form []vars.KeyVal
Format fetch.Format
Headers []vars.KeyVal
Form []core.KeyVal
Format core.Format
Headers []core.KeyVal
Help bool
HTTP client.HTTPVersion
IgnoreStatus bool
Insecure bool
JSON bool
Method string
Multipart []vars.KeyVal
Multipart []core.KeyVal
NoEncode bool
NoPager bool
Output string
Proxy *url.URL
QueryParams []vars.KeyVal
QueryParams []core.KeyVal
Silent bool
Timeout time.Duration
TLS uint16
Expand Down Expand Up @@ -168,7 +167,7 @@ func (a *App) CLI() *CLI {
const usage = "format must be <USERNAME:PASSWORD>"
return flagValueError("basic", value, usage)
}
a.Basic = &vars.KeyVal{Key: user, Val: pass}
a.Basic = &core.KeyVal{Key: user, Val: pass}
return nil
},
},
Expand All @@ -194,16 +193,16 @@ func (a *App) CLI() *CLI {
Default: "",
Values: []string{"auto", "off", "on"},
IsSet: func() bool {
return a.Color != printer.ColorUnknown
return a.Color != core.ColorUnknown
},
Fn: func(value string) error {
switch value {
case "auto":
a.Color = printer.ColorAuto
a.Color = core.ColorAuto
case "off":
a.Color = printer.ColorOff
a.Color = core.ColorOff
case "on":
a.Color = printer.ColorOn
a.Color = core.ColorOn
default:
const usage = "must be one of [auto, off, on]"
return flagValueError("color", value, usage)
Expand Down Expand Up @@ -314,7 +313,7 @@ func (a *App) CLI() *CLI {
},
Fn: func(value string) error {
key, val, _ := cut(value, "=")
a.Form = append(a.Form, vars.KeyVal{Key: key, Val: val})
a.Form = append(a.Form, core.KeyVal{Key: key, Val: val})
return nil
},
},
Expand All @@ -326,16 +325,16 @@ func (a *App) CLI() *CLI {
Default: "",
Values: []string{"auto", "off", "on"},
IsSet: func() bool {
return a.Format != fetch.FormatUnknown
return a.Format != core.FormatUnknown
},
Fn: func(value string) error {
switch value {
case "auto":
a.Format = fetch.FormatAuto
a.Format = core.FormatAuto
case "off":
a.Format = fetch.FormatOff
a.Format = core.FormatOff
case "on":
a.Format = fetch.FormatOn
a.Format = core.FormatOn
default:
const usage = "must be one of [auto, off, on]"
return flagValueError("format", value, usage)
Expand All @@ -354,7 +353,7 @@ func (a *App) CLI() *CLI {
},
Fn: func(value string) error {
key, val, _ := cut(value, ":")
a.Headers = append(a.Headers, vars.KeyVal{Key: key, Val: val})
a.Headers = append(a.Headers, core.KeyVal{Key: key, Val: val})
return nil
},
},
Expand Down Expand Up @@ -475,7 +474,7 @@ func (a *App) CLI() *CLI {
return fmt.Errorf("file is a directory: '%s'", val[1:])
}
}
a.Multipart = append(a.Multipart, vars.KeyVal{Key: key, Val: val})
a.Multipart = append(a.Multipart, core.KeyVal{Key: key, Val: val})
return nil
},
},
Expand Down Expand Up @@ -550,7 +549,7 @@ func (a *App) CLI() *CLI {
},
Fn: func(value string) error {
key, val, _ := cut(value, "=")
a.QueryParams = append(a.QueryParams, vars.KeyVal{Key: key, Val: val})
a.QueryParams = append(a.QueryParams, core.KeyVal{Key: key, Val: val})
return nil
},
},
Expand Down
3 changes: 2 additions & 1 deletion internal/cli/cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"testing"
"unicode/utf8"

"github.com/ryanfowler/fetch/internal/core"
"github.com/ryanfowler/fetch/internal/printer"
)

Expand All @@ -13,7 +14,7 @@ func TestCLI(t *testing.T) {
if err != nil {
t.Fatalf("unable to parse cli: %s", err.Error())
}
p := printer.NewHandle(printer.ColorOff).Stdout()
p := printer.NewHandle(core.ColorOff).Stdout()

// Verify that no line of the help command is over 80 characters.
app.PrintHelp(p)
Expand Down
12 changes: 6 additions & 6 deletions internal/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import (
"time"

"github.com/ryanfowler/fetch/internal/aws"
"github.com/ryanfowler/fetch/internal/core"
"github.com/ryanfowler/fetch/internal/multipart"
"github.com/ryanfowler/fetch/internal/vars"
)

type HTTPVersion int
Expand Down Expand Up @@ -91,14 +91,14 @@ func NewClient(cfg ClientConfig) *Client {
type RequestConfig struct {
Method string
URL *url.URL
Form []vars.KeyVal
Form []core.KeyVal
Multipart *multipart.Multipart
Headers []vars.KeyVal
QueryParams []vars.KeyVal
Headers []core.KeyVal
QueryParams []core.KeyVal
Body io.Reader
NoEncode bool
AWSSigV4 *aws.Config
Basic *vars.KeyVal
Basic *core.KeyVal
Bearer string
JSON bool
XML bool
Expand Down Expand Up @@ -129,7 +129,7 @@ func (c *Client) NewRequest(ctx context.Context, cfg RequestConfig) (*http.Reque
}

req.Header.Set("Accept", "application/json,application/xml,image/webp,*/*")
req.Header.Set("User-Agent", vars.UserAgent)
req.Header.Set("User-Agent", core.UserAgent)

switch {
case cfg.JSON:
Expand Down
35 changes: 35 additions & 0 deletions internal/core/core.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package core

// Color represents the options for enabling or disabling color output.
type Color int

const (
ColorUnknown Color = iota
ColorAuto
ColorOn
ColorOff
)

// Format represents the options for enabling or disabling formatting.
type Format int

const (
FormatUnknown Format = iota
FormatAuto
FormatOff
FormatOn
)

// Verbosity represents how verbose the output should be.
type Verbosity int

const (
VSilent Verbosity = iota
VNormal
VVerbose
VExtraVerbose
)

type KeyVal struct {
Key, Val string
}
22 changes: 22 additions & 0 deletions internal/core/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package core

import (
"fmt"
"time"
)

// ErrRequestTimedOut represents the error when the request times out.
type ErrRequestTimedOut struct {
Timeout time.Duration
}

func (err ErrRequestTimedOut) Error() string {
return fmt.Sprintf("request timed out after %s", err.Timeout)
}

// SignalError represents the error when a signal is caught.
type SignalError string

func (err SignalError) Error() string {
return fmt.Sprintf("received signal: %s", string(err))
}
22 changes: 1 addition & 21 deletions internal/vars/vars.go → internal/core/vars.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
package vars
package core

import (
"encoding/json"
"fmt"
"os"
"runtime/debug"
"time"

"golang.org/x/term"
)
Expand Down Expand Up @@ -37,24 +35,6 @@ func getVersion() string {
return buildInfo.Main.Version
}

type KeyVal struct {
Key, Val string
}

type ErrRequestTimedOut struct {
Timeout time.Duration
}

func (err ErrRequestTimedOut) Error() string {
return fmt.Sprintf("request timed out after %s", err.Timeout)
}

type SignalError string

func (err SignalError) Error() string {
return fmt.Sprintf("received signal: %s", string(err))
}

func GetVersions() []byte {
type Versions struct {
Fetch string `json:"fetch"`
Expand Down
Loading
Loading