add FileExists
This commit is contained in:
parent
ba19115390
commit
2c9e178554
116
internal/transport/buffer.go
Normal file
116
internal/transport/buffer.go
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved.
|
||||||
|
|
||||||
|
package transport
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "errors"
|
||||||
|
"path/filepath"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"net/url"
|
||||||
|
"strings"
|
||||||
|
"fmt"
|
||||||
|
"compress/gzip"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Buffer struct {
|
||||||
|
uri *url.URL
|
||||||
|
path string
|
||||||
|
exttype string
|
||||||
|
fileext string
|
||||||
|
readHandle *os.File
|
||||||
|
writeHandle *os.File
|
||||||
|
gzip bool
|
||||||
|
gzipWriter io.WriteCloser
|
||||||
|
gzipReader io.ReadCloser
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewBuffer(u *url.URL) (b *Buffer, err error) {
|
||||||
|
b = &Buffer{
|
||||||
|
uri: u,
|
||||||
|
path: filepath.Join(u.Hostname(), u.RequestURI()),
|
||||||
|
}
|
||||||
|
b.extension()
|
||||||
|
b.DetectGzip()
|
||||||
|
|
||||||
|
if b.path == "" || b.path == "-" {
|
||||||
|
b.readHandle = os.Stdin
|
||||||
|
b.writeHandle = os.Stdout
|
||||||
|
} else {
|
||||||
|
if b.readHandle, err = os.OpenFile(b.Path(), os.O_RDWR|os.O_CREATE, 0644); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
b.writeHandle = b.readHandle
|
||||||
|
}
|
||||||
|
|
||||||
|
if b.Gzip() {
|
||||||
|
b.gzipWriter = gzip.NewWriter(b.writeHandle)
|
||||||
|
if b.gzipReader, err = gzip.NewReader(b.readHandle); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Buffer) extension() {
|
||||||
|
elements := strings.Split(b.path, ".")
|
||||||
|
numberOfElements := len(elements)
|
||||||
|
if numberOfElements > 2 {
|
||||||
|
b.exttype = elements[numberOfElements - 2]
|
||||||
|
b.fileext = elements[numberOfElements - 1]
|
||||||
|
}
|
||||||
|
b.exttype = elements[numberOfElements - 1]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Buffer) DetectGzip() {
|
||||||
|
b.gzip = (b.uri.Query().Get("gzip") == "true" || b.fileext == "gz")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Buffer) URI() *url.URL {
|
||||||
|
return b.uri
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Buffer) Path() string {
|
||||||
|
return b.path
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Buffer) Signature() (documentSignature string) {
|
||||||
|
if signatureResp, signatureErr := os.Open(fmt.Sprintf("%s.sig", b.uri.String())); signatureErr == nil {
|
||||||
|
defer signatureResp.Close()
|
||||||
|
readSignatureBody, readSignatureErr := io.ReadAll(signatureResp)
|
||||||
|
if readSignatureErr == nil {
|
||||||
|
documentSignature = string(readSignatureBody)
|
||||||
|
} else {
|
||||||
|
panic(readSignatureErr)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
panic(signatureErr)
|
||||||
|
}
|
||||||
|
return documentSignature
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Buffer) ContentType() string {
|
||||||
|
return b.exttype
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Buffer) SetGzip(gzip bool) {
|
||||||
|
b.gzip = gzip
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Buffer) Gzip() bool {
|
||||||
|
return b.gzip
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Buffer) Reader() io.ReadCloser {
|
||||||
|
if b.Gzip() {
|
||||||
|
return b.gzipReader
|
||||||
|
}
|
||||||
|
return b.readHandle
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Buffer) Writer() io.WriteCloser {
|
||||||
|
if b.Gzip() {
|
||||||
|
return b.gzipWriter
|
||||||
|
}
|
||||||
|
return b.writeHandle
|
||||||
|
}
|
39
internal/transport/buffer_test.go
Normal file
39
internal/transport/buffer_test.go
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved.
|
||||||
|
|
||||||
|
package transport
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"testing"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"net/url"
|
||||||
|
"path/filepath"
|
||||||
|
)
|
||||||
|
|
||||||
|
var TransportBufferTestFile = fmt.Sprintf("%s/foo", TempDir)
|
||||||
|
|
||||||
|
func TestNewTransportBufferReader(t *testing.T) {
|
||||||
|
path := fmt.Sprintf("%s/foo", TempDir)
|
||||||
|
u, e := url.Parse(fmt.Sprintf("file://%s", path))
|
||||||
|
assert.Nil(t, e)
|
||||||
|
|
||||||
|
writeErr := os.WriteFile(path, []byte("test"), 0644)
|
||||||
|
assert.Nil(t, writeErr)
|
||||||
|
|
||||||
|
file, err := NewBuffer(u)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, file.Path(), path)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNewTransportBufferReaderExtension(t *testing.T) {
|
||||||
|
u, e := url.Parse(fmt.Sprintf("file://%s.yaml", TransportBufferTestFile))
|
||||||
|
assert.Nil(t, e)
|
||||||
|
|
||||||
|
b := &Buffer{
|
||||||
|
uri: u,
|
||||||
|
path: filepath.Join(u.Hostname(), u.RequestURI()),
|
||||||
|
}
|
||||||
|
b.extension()
|
||||||
|
assert.Equal(t, b.exttype, "yaml")
|
||||||
|
}
|
@ -25,10 +25,19 @@ type File struct {
|
|||||||
gzipReader io.ReadCloser
|
gzipReader io.ReadCloser
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func FilePath(u *url.URL) string {
|
||||||
|
return filepath.Join(u.Hostname(), u.RequestURI())
|
||||||
|
}
|
||||||
|
|
||||||
|
func FileExists(u *url.URL) bool {
|
||||||
|
_, err := os.Stat(FilePath(u))
|
||||||
|
return err == nil
|
||||||
|
}
|
||||||
|
|
||||||
func NewFile(u *url.URL) (f *File, err error) {
|
func NewFile(u *url.URL) (f *File, err error) {
|
||||||
f = &File {
|
f = &File {
|
||||||
uri: u,
|
uri: u,
|
||||||
path: filepath.Join(u.Hostname(), u.RequestURI()),
|
path: FilePath(u),
|
||||||
}
|
}
|
||||||
f.extension()
|
f.extension()
|
||||||
f.DetectGzip()
|
f.DetectGzip()
|
||||||
@ -55,12 +64,14 @@ func NewFile(u *url.URL) (f *File, err error) {
|
|||||||
func (f *File) extension() {
|
func (f *File) extension() {
|
||||||
elements := strings.Split(f.path, ".")
|
elements := strings.Split(f.path, ".")
|
||||||
numberOfElements := len(elements)
|
numberOfElements := len(elements)
|
||||||
|
if numberOfElements > 1 {
|
||||||
if numberOfElements > 2 {
|
if numberOfElements > 2 {
|
||||||
f.exttype = elements[numberOfElements - 2]
|
f.exttype = elements[numberOfElements - 2]
|
||||||
f.fileext = elements[numberOfElements - 1]
|
f.fileext = elements[numberOfElements - 1]
|
||||||
}
|
}
|
||||||
f.exttype = elements[numberOfElements - 1]
|
f.exttype = elements[numberOfElements - 1]
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (f *File) DetectGzip() {
|
func (f *File) DetectGzip() {
|
||||||
f.gzip = (f.uri.Query().Get("gzip") == "true" || f.fileext == "gz")
|
f.gzip = (f.uri.Query().Get("gzip") == "true" || f.fileext == "gz")
|
||||||
@ -90,6 +101,9 @@ func (f *File) Signature() (documentSignature string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (f *File) ContentType() string {
|
func (f *File) ContentType() string {
|
||||||
|
if f.uri.Scheme != "file" {
|
||||||
|
return f.uri.Scheme
|
||||||
|
}
|
||||||
return f.exttype
|
return f.exttype
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,6 +33,10 @@ type HTTP struct {
|
|||||||
Client *http.Client
|
Client *http.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func HTTPExists(u *url.URL) bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func (b BufferCloser) Close() error {
|
func (b BufferCloser) Close() error {
|
||||||
if b.stream != nil {
|
if b.stream != nil {
|
||||||
return b.stream.Close()
|
return b.stream.Close()
|
||||||
|
@ -27,6 +27,7 @@ type Reader struct {
|
|||||||
uri *url.URL
|
uri *url.URL
|
||||||
handle Handler
|
handle Handler
|
||||||
stream io.ReadCloser
|
stream io.ReadCloser
|
||||||
|
exists func() bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewReader(u *url.URL) (reader *Reader, e error) {
|
func NewReader(u *url.URL) (reader *Reader, e error) {
|
||||||
@ -39,8 +40,9 @@ func NewReader(u *url.URL) (reader *Reader, e error) {
|
|||||||
fallthrough
|
fallthrough
|
||||||
default:
|
default:
|
||||||
reader.handle, e = NewFile(u)
|
reader.handle, e = NewFile(u)
|
||||||
|
reader.exists = func() bool { return FileExists(u) }
|
||||||
}
|
}
|
||||||
reader.stream = reader.handle.Reader()
|
reader.SetStream(reader.handle.Reader())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,6 +58,7 @@ type Writer struct {
|
|||||||
uri *url.URL
|
uri *url.URL
|
||||||
handle Handler
|
handle Handler
|
||||||
stream io.WriteCloser
|
stream io.WriteCloser
|
||||||
|
exists func() bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewWriter(u *url.URL) (writer *Writer, e error) {
|
func NewWriter(u *url.URL) (writer *Writer, e error) {
|
||||||
@ -68,8 +71,9 @@ func NewWriter(u *url.URL) (writer *Writer, e error) {
|
|||||||
fallthrough
|
fallthrough
|
||||||
default:
|
default:
|
||||||
writer.handle, e = NewFile(u)
|
writer.handle, e = NewFile(u)
|
||||||
|
writer.exists = func() bool { return FileExists(u) }
|
||||||
}
|
}
|
||||||
writer.stream = writer.handle.Writer()
|
writer.SetStream(writer.handle.Writer())
|
||||||
return writer, e
|
return writer, e
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,6 +85,25 @@ func NewWriterURI(uri string) (writer *Writer, e error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ExistsURI(uri string) bool {
|
||||||
|
var u *url.URL
|
||||||
|
u, _ = url.Parse(uri)
|
||||||
|
return Exists(u)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Exists(u *url.URL) bool {
|
||||||
|
switch u.Scheme {
|
||||||
|
case "http", "https":
|
||||||
|
return HTTPExists(u)
|
||||||
|
case "file":
|
||||||
|
fallthrough
|
||||||
|
default:
|
||||||
|
return FileExists(u)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Reader) Exists() bool { return r.exists() }
|
||||||
|
|
||||||
func (r *Reader) Read(b []byte) (int, error) {
|
func (r *Reader) Read(b []byte) (int, error) {
|
||||||
return r.stream.Read(b)
|
return r.stream.Read(b)
|
||||||
}
|
}
|
||||||
@ -101,8 +124,13 @@ func (r *Reader) Signature() string {
|
|||||||
return r.handle.Signature()
|
return r.handle.Signature()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *Reader) SetStream(s io.ReadCloser) {
|
||||||
|
r.stream = s
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (w *Writer) Exists() bool { return w.exists() }
|
||||||
|
|
||||||
func (w *Writer) Write(b []byte) (int, error) {
|
func (w *Writer) Write(b []byte) (int, error) {
|
||||||
return w.stream.Write(b)
|
return w.stream.Write(b)
|
||||||
}
|
}
|
||||||
@ -122,3 +150,7 @@ func (w *Writer) Gzip() bool {
|
|||||||
func (w *Writer) Signature() string {
|
func (w *Writer) Signature() string {
|
||||||
return w.handle.Signature()
|
return w.handle.Signature()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *Writer) SetStream(s io.WriteCloser) {
|
||||||
|
w.stream = s
|
||||||
|
}
|
||||||
|
@ -52,13 +52,32 @@ func TestTransportReaderContentType(t *testing.T) {
|
|||||||
u, e := url.Parse(fmt.Sprintf("file://%s", path))
|
u, e := url.Parse(fmt.Sprintf("file://%s", path))
|
||||||
assert.Nil(t, e)
|
assert.Nil(t, e)
|
||||||
|
|
||||||
|
assert.False(t, Exists(u))
|
||||||
writeErr := os.WriteFile(path, []byte(testFileResourceDoc), 0644)
|
writeErr := os.WriteFile(path, []byte(testFileResourceDoc), 0644)
|
||||||
|
|
||||||
assert.Nil(t, writeErr)
|
assert.Nil(t, writeErr)
|
||||||
|
|
||||||
reader, err := NewReader(u)
|
reader, err := NewReader(u)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
assert.True(t, reader.Exists())
|
||||||
assert.NotNil(t, reader)
|
assert.NotNil(t, reader)
|
||||||
|
|
||||||
assert.Equal(t, reader.ContentType(), "yaml")
|
assert.Equal(t, reader.ContentType(), "yaml")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestTransportWriter(t *testing.T) {
|
||||||
|
path := fmt.Sprintf("%s/writefoo", TempDir)
|
||||||
|
u, e := url.Parse(fmt.Sprintf("file://%s", path))
|
||||||
|
assert.Nil(t, e)
|
||||||
|
|
||||||
|
assert.False(t, Exists(u))
|
||||||
|
writer, err := NewWriter(u)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
defer writer.Close()
|
||||||
|
assert.NotNil(t, writer)
|
||||||
|
assert.True(t, writer.Exists())
|
||||||
|
_, writeErr := writer.Write([]byte("testdata"))
|
||||||
|
assert.Nil(t, writeErr)
|
||||||
|
assert.FileExists(t, path)
|
||||||
|
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user