Explorar el Código

Add local file abstraction

tags/v2.1.3^2
9seconds hace 4 años
padre
commit
c14a2329c5

+ 51
- 0
ipblocklist/files/http.go Ver fichero

@@ -0,0 +1,51 @@
1
+package files
2
+
3
+import (
4
+	"context"
5
+	"fmt"
6
+	"io"
7
+	"net/http"
8
+	"net/url"
9
+)
10
+
11
+type httpFile struct {
12
+	http *http.Client
13
+	url  string
14
+}
15
+
16
+func (h httpFile) Open(ctx context.Context) (io.ReadCloser, error) {
17
+	request, err := http.NewRequestWithContext(ctx, http.MethodGet, h.url, nil)
18
+	if err != nil {
19
+		panic(err)
20
+	}
21
+
22
+	response, err := h.http.Do(request)
23
+	if err != nil {
24
+		if response != nil {
25
+			io.Copy(io.Discard, response.Body)
26
+			response.Body.Close()
27
+		}
28
+
29
+		return nil, fmt.Errorf("cannot get url %s: %w", h.url, err)
30
+	}
31
+
32
+	return response.Body, nil
33
+}
34
+
35
+func NewHTTP(client *http.Client, endpoint string) (File, error) {
36
+	parsed, err := url.Parse(endpoint)
37
+	if err != nil {
38
+		return nil, fmt.Errorf("incorrect url %s: %w", endpoint, err)
39
+	}
40
+
41
+	switch parsed.Scheme {
42
+	case "http", "https":
43
+	default:
44
+		return nil, fmt.Errorf("unsupported url %s", endpoint)
45
+	}
46
+
47
+	return httpFile{
48
+		http: client,
49
+		url:  endpoint,
50
+	}, nil
51
+}

+ 10
- 0
ipblocklist/files/init.go Ver fichero

@@ -0,0 +1,10 @@
1
+package files
2
+
3
+import (
4
+	"context"
5
+	"io"
6
+)
7
+
8
+type File interface {
9
+	Open(context.Context) (io.ReadCloser, error)
10
+}

+ 30
- 0
ipblocklist/files/local.go Ver fichero

@@ -0,0 +1,30 @@
1
+package files
2
+
3
+import (
4
+	"context"
5
+	"fmt"
6
+	"io"
7
+	"io/fs"
8
+	"os"
9
+	"path/filepath"
10
+)
11
+
12
+type localFile struct {
13
+	root fs.FS
14
+	name string
15
+}
16
+
17
+func (l localFile) Open(ctx context.Context) (io.ReadCloser, error) {
18
+	return l.root.Open(l.name)
19
+}
20
+
21
+func NewLocal(path string) (File, error) {
22
+	if stat, err := os.Stat(path); os.IsNotExist(err) || stat.IsDir() || stat.Mode().Perm()&0o400 == 0 {
23
+		return nil, fmt.Errorf("%s is not a readable file", path)
24
+	}
25
+
26
+	return localFile{
27
+		root: os.DirFS(filepath.Dir(path)),
28
+		name: filepath.Base(path),
29
+	}, nil
30
+}

+ 55
- 0
ipblocklist/files/local_test.go Ver fichero

@@ -0,0 +1,55 @@
1
+package files_test
2
+
3
+import (
4
+	"context"
5
+	"io"
6
+	"path/filepath"
7
+	"strings"
8
+	"testing"
9
+
10
+	"github.com/9seconds/mtg/v2/ipblocklist/files"
11
+	"github.com/stretchr/testify/assert"
12
+	"github.com/stretchr/testify/suite"
13
+)
14
+
15
+type LocalTestSuite struct {
16
+	suite.Suite
17
+}
18
+
19
+func (suite *LocalTestSuite) GetLocalFile(name string) string {
20
+	return filepath.Join("testdata", name)
21
+}
22
+
23
+func (suite *LocalTestSuite) TestIncorrect() {
24
+	names := []string{
25
+		"absent",
26
+		"directory",
27
+	}
28
+
29
+	for _, v := range names {
30
+		value := v
31
+
32
+		suite.T().Run(v, func(t *testing.T) {
33
+			_, err := files.NewLocal(suite.GetLocalFile(value))
34
+			assert.Error(t, err)
35
+		})
36
+	}
37
+}
38
+
39
+func (suite *LocalTestSuite) TestOk() {
40
+	file, err := files.NewLocal(suite.GetLocalFile("readable"))
41
+	suite.NoError(err)
42
+
43
+	reader, err := file.Open(context.Background())
44
+	suite.NoError(err)
45
+
46
+	data, err := io.ReadAll(reader)
47
+	suite.NoError(err)
48
+
49
+	suite.Equal("Hooray!", strings.TrimSpace(string(data)))
50
+}
51
+
52
+func TestLocal(t *testing.T) {
53
+	t.Parallel()
54
+	suite.Run(t, &LocalTestSuite{})
55
+}

+ 0
- 0
ipblocklist/files/testdata/directory/.gitkeep Ver fichero


+ 1
- 0
ipblocklist/files/testdata/readable Ver fichero

@@ -0,0 +1 @@
1
+Hooray!

Loading…
Cancelar
Guardar