This repository has been archived by the owner on Apr 16, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 8
/
utils.go
149 lines (129 loc) · 3.69 KB
/
utils.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
package skynet
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"net/url"
"os"
"path/filepath"
"strings"
"gitlab.com/NebulousLabs/errors"
)
type (
// ErrorResponse contains the response for an error.
ErrorResponse struct {
// Message is the error message of the response.
Message string `json:"message"`
}
// Options contains options used for connecting to a Skynet portal and
// endpoint.
Options struct {
// EndpointPath is the relative URL path of the portal endpoint to
// contact.
EndpointPath string
// APIKey is the API password to use for authentication.
APIKey string
// CustomUserAgent is the custom user agent to use.
CustomUserAgent string
// customContentType is the custom content type to use. Set internally.
customContentType string
}
)
const (
// DefaultSkynetPortalURL is the default URL of the Skynet portal to use in
// the absence of configuration.
DefaultSkynetPortalURL = "https://siasky.net"
// URISkynetPrefix is the URI prefix for Skynet.
URISkynetPrefix = "sia://"
)
var (
// ErrResponseError is the error for a response with a status code >= 400.
ErrResponseError = errors.New("error response")
)
// DefaultOptions returns the default options with the given endpoint path.
func DefaultOptions(endpointPath string) Options {
return Options{
EndpointPath: endpointPath,
APIKey: "",
CustomUserAgent: "",
}
}
// DefaultPortalURL selects the default portal URL to use when initializing a
// client. May involve network queries to several candidate portals.
//
// TODO: This will be smarter. See
// https://github.com/NebulousLabs/skynet-docs/issues/21.
func DefaultPortalURL() string {
return DefaultSkynetPortalURL
}
// makeResponseError makes an error given an error response.
func makeResponseError(resp *http.Response) error {
body := &bytes.Buffer{}
_, err := body.ReadFrom(resp.Body)
if err != nil {
return errors.AddContext(err, "could not read from response body")
}
err = resp.Body.Close()
if err != nil {
return errors.AddContext(err, "could not close response body")
}
var apiResponse ErrorResponse
message := string(body.Bytes())
err = json.Unmarshal(body.Bytes(), &apiResponse)
if err == nil {
message = apiResponse.Message
}
context := fmt.Sprintf("%v response from %v: %v", resp.StatusCode, resp.Request.Method, message)
return errors.AddContext(ErrResponseError, context)
}
// makeURL makes a URL from the given parts.
func makeURL(portalURL, path, extraPath string, query url.Values) string {
url := fmt.Sprintf("%s/%s", strings.TrimRight(portalURL, "/"), strings.TrimLeft(path, "/"))
if extraPath != "" {
url = fmt.Sprintf("%s/%s", strings.TrimRight(url, "/"), strings.TrimLeft(extraPath, "/"))
}
if query == nil {
return url
}
params := query.Encode()
if params == "" {
return url
}
return fmt.Sprintf("%s?%s", url, query.Encode())
}
// parseResponseBody parses the response body.
func parseResponseBody(resp *http.Response) (respBody *bytes.Buffer, err error) {
defer func() {
err = errors.Extend(err, resp.Body.Close())
}()
// parse the response
respBody = &bytes.Buffer{}
_, err = respBody.ReadFrom(resp.Body)
if err != nil {
return nil, errors.AddContext(err, "could not parse response body")
}
return respBody, nil
}
// walkDirectory walks a given directory recursively, returning the paths of all
// files found.
func walkDirectory(path string) ([]string, error) {
var files []string
err := filepath.Walk(path, func(subpath string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if subpath == path {
return nil
}
if info.IsDir() {
return nil
}
files = append(files, subpath)
return nil
})
if err != nil {
return []string{}, err
}
return files, nil
}