• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

cinode / go / 3761031085

22 Dec 2022 08:43PM UTC coverage: 79.498%. Remained the same
3761031085

push

github

Bartek
Add codecov support

919 of 1156 relevant lines covered (79.5%)

0.87 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.24
/datastore/webconnector.go
1
package datastore
2

3
import (
4
        "context"
5
        "encoding/json"
6
        "errors"
7
        "fmt"
8
        "io"
9
        "net/http"
10

11
        "github.com/cinode/go/common"
12
        "github.com/cinode/go/internal/blobtypes/propagation"
13
)
14

15
var (
16
        ErrWebConnectionError = errors.New("connection error")
17
)
18

19
type webConnector struct {
20
        baseURL string
21
        client  *http.Client
22
}
23

24
var _ DS = (*webConnector)(nil)
25

26
// FromWeb returns Datastore implementation that connects to external url
27
func FromWeb(baseURL string, client *http.Client) DS {
1✔
28
        return &webConnector{
1✔
29
                baseURL: baseURL,
1✔
30
                client:  client,
1✔
31
        }
1✔
32
}
1✔
33

34
func (w *webConnector) Kind() string {
1✔
35
        return "Web"
1✔
36
}
1✔
37

38
func (w *webConnector) Read(ctx context.Context, name common.BlobName, output io.Writer) error {
1✔
39
        handler, err := propagation.HandlerForType(name.Type())
1✔
40
        if err != nil {
2✔
41
                return err
1✔
42
        }
1✔
43

44
        req, err := http.NewRequestWithContext(
1✔
45
                ctx,
1✔
46
                http.MethodGet,
1✔
47
                w.baseURL+name.String(),
1✔
48
                nil,
1✔
49
        )
1✔
50
        if err != nil {
2✔
51
                return err
1✔
52
        }
1✔
53

54
        res, err := w.client.Do(req)
1✔
55
        if err != nil {
1✔
56
                return err
×
57
        }
×
58
        defer res.Body.Close()
1✔
59

1✔
60
        err = w.errCheck(res)
1✔
61
        if err != nil {
2✔
62
                return err
1✔
63
        }
1✔
64

65
        return handler.Validate(
1✔
66
                name.Hash(),
1✔
67
                io.TeeReader(res.Body, output),
1✔
68
        )
1✔
69
}
70

71
func (w *webConnector) Update(ctx context.Context, name common.BlobName, r io.Reader) error {
1✔
72
        req, err := http.NewRequestWithContext(
1✔
73
                ctx,
1✔
74
                http.MethodPut,
1✔
75
                w.baseURL+name.String(),
1✔
76
                r,
1✔
77
        )
1✔
78
        if err != nil {
2✔
79
                return err
1✔
80
        }
1✔
81

82
        req.Header.Set("Content-Type", "application/octet-stream")
1✔
83
        req.Header.Set("Accept", "application/json")
1✔
84
        res, err := w.client.Do(req)
1✔
85
        if err != nil {
2✔
86
                return err
1✔
87
        }
1✔
88
        defer res.Body.Close()
1✔
89

1✔
90
        return w.errCheck(res)
1✔
91
}
92

93
func (w *webConnector) Exists(ctx context.Context, name common.BlobName) (bool, error) {
1✔
94
        req, err := http.NewRequestWithContext(
1✔
95
                ctx,
1✔
96
                http.MethodHead,
1✔
97
                w.baseURL+name.String(),
1✔
98
                nil,
1✔
99
        )
1✔
100
        if err != nil {
2✔
101
                return false, err
1✔
102
        }
1✔
103
        res, err := w.client.Do(req)
1✔
104
        if err != nil {
1✔
105
                return false, err
×
106
        }
×
107
        defer res.Body.Close()
1✔
108

1✔
109
        err = w.errCheck(res)
1✔
110
        if errors.Is(err, ErrNotFound) {
2✔
111
                return false, nil
1✔
112
        }
1✔
113

114
        if err == nil {
2✔
115
                return true, nil
1✔
116
        }
1✔
117
        return false, err
1✔
118
}
119

120
func (w *webConnector) Delete(ctx context.Context, name common.BlobName) error {
1✔
121
        req, err := http.NewRequestWithContext(
1✔
122
                ctx,
1✔
123
                http.MethodDelete,
1✔
124
                w.baseURL+name.String(),
1✔
125
                nil,
1✔
126
        )
1✔
127
        if err != nil {
2✔
128
                return err
1✔
129
        }
1✔
130

131
        res, err := w.client.Do(req)
1✔
132
        if err != nil {
1✔
133
                return err
×
134
        }
×
135
        defer res.Body.Close()
1✔
136

1✔
137
        return w.errCheck(res)
1✔
138
}
139

140
func (w *webConnector) errCheck(res *http.Response) error {
1✔
141
        if res.StatusCode == http.StatusNotFound {
2✔
142
                return ErrNotFound
1✔
143
        }
1✔
144
        if res.StatusCode == http.StatusBadRequest {
2✔
145
                msg := webErrResponse{}
1✔
146
                err := json.NewDecoder(res.Body).Decode(&msg)
1✔
147
                if err == nil {
2✔
148
                        err := webErrFromCode(msg.Code)
1✔
149
                        if err != nil {
2✔
150
                                return err
1✔
151
                        }
1✔
152
                        return fmt.Errorf(
1✔
153
                                "%w: response status code: %v (%v), error code: %v, error message: %v",
1✔
154
                                ErrWebConnectionError,
1✔
155
                                res.StatusCode,
1✔
156
                                res.Status,
1✔
157
                                msg.Code,
1✔
158
                                msg.Message,
1✔
159
                        )
1✔
160
                }
161
                // Fallthrough to code below if can't decode json error
162
        }
163
        if res.StatusCode >= 400 {
2✔
164
                return fmt.Errorf(
1✔
165
                        "%w: response status code: %v (%v)",
1✔
166
                        ErrWebConnectionError,
1✔
167
                        res.StatusCode,
1✔
168
                        res.Status,
1✔
169
                )
1✔
170
        }
1✔
171
        return nil
1✔
172
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc