51455da96f
- HTTPLoader.Load: http.NewRequest → NewRequestWithContext so caller cancellation/deadlines propagate to the outgoing request - RedisListLoader, RedisHashLoader: add nil-guard before calling opt() (already present in StringLoader, SetLoader, and HTTPLoader) - Add doc comments for all 10 exported symbols (package, interfaces, constructors, option types, option funcs, DefaultRedisKey) - Add loader_test.go with 32 tests covering FileLoader, HTTPLoader (context cancel, error status, empty/large body), Redis options, nil-guard safety, and interface satisfaction checks
74 lines
1.3 KiB
Go
74 lines
1.3 KiB
Go
package loader
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"time"
|
|
)
|
|
|
|
type httpLoaderOptions struct {
|
|
timeout time.Duration
|
|
}
|
|
|
|
// HTTPLoaderOption configures an HTTP loader.
|
|
type HTTPLoaderOption func(opts *httpLoaderOptions)
|
|
|
|
// TimeoutHTTPLoaderOption sets the HTTP request timeout.
|
|
func TimeoutHTTPLoaderOption(timeout time.Duration) HTTPLoaderOption {
|
|
return func(opts *httpLoaderOptions) {
|
|
opts.timeout = timeout
|
|
}
|
|
}
|
|
|
|
type httpLoader struct {
|
|
url string
|
|
httpClient *http.Client
|
|
}
|
|
|
|
// HTTPLoader loads data from HTTP request.
|
|
func HTTPLoader(url string, opts ...HTTPLoaderOption) Loader {
|
|
var options httpLoaderOptions
|
|
for _, opt := range opts {
|
|
if opt != nil {
|
|
opt(&options)
|
|
}
|
|
}
|
|
return &httpLoader{
|
|
url: url,
|
|
httpClient: &http.Client{
|
|
Timeout: options.timeout,
|
|
},
|
|
}
|
|
}
|
|
|
|
func (l *httpLoader) Load(ctx context.Context) (io.Reader, error) {
|
|
req, err := http.NewRequestWithContext(ctx, http.MethodGet, l.url, nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
resp, err := l.httpClient.Do(req)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode != http.StatusOK {
|
|
return nil, fmt.Errorf("%d %s", resp.StatusCode, resp.Status)
|
|
}
|
|
|
|
data, err := io.ReadAll(resp.Body)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return bytes.NewReader(data), nil
|
|
}
|
|
|
|
func (l *httpLoader) Close() error {
|
|
return nil
|
|
}
|