forked from SkynetLabs/go-skynet
-
Notifications
You must be signed in to change notification settings - Fork 0
/
utils.go
153 lines (134 loc) · 3.8 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
150
151
152
153
package skynet
import (
"bytes"
"context"
"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 {
HttpClient *http.Client
SkynetAPIKey string
CustomUserAgent string
customContentType string
EndpointPath 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,
SkynetAPIKey: "",
CustomUserAgent: "",
HttpClient: http.DefaultClient,
}
}
// 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
}
// ensurePrefix checks if `str` starts with `prefix` and adds it if that's not
// the case.
//
// NOTE: Taken from `skyd` - see that project for tests.
func ensurePrefix(str, prefix string) string {
if strings.HasPrefix(str, prefix) {
return str
}
return prefix + str
}
// 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")
}
if err = resp.Body.Close(); err != nil && err != context.Canceled {
return errors.AddContext(err, "could not close response body")
}
var apiResponse ErrorResponse
message := body.String()
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) (*bytes.Buffer, error) {
buf := &bytes.Buffer{}
if _, err := buf.ReadFrom(resp.Body); err != nil {
return nil, errors.AddContext(err, "could not parse response body")
}
// TODO (jay-dee7) find a graceful way to handle this
defer resp.Body.Close()
// parse the response
return buf, 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
}