fix the handling of compressed files: ensure the gzip writer is closed before the file
This commit is contained in:
parent
a34f83e684
commit
d359d8bfab
@ -13,6 +13,7 @@ _ "errors"
|
|||||||
"fmt"
|
"fmt"
|
||||||
"compress/gzip"
|
"compress/gzip"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
|
"decl/internal/ext"
|
||||||
)
|
)
|
||||||
|
|
||||||
type File struct {
|
type File struct {
|
||||||
@ -98,6 +99,7 @@ func NewFileWriter(u *url.URL) (f *FileWriter, err error) {
|
|||||||
}
|
}
|
||||||
f.extension()
|
f.extension()
|
||||||
f.DetectGzip()
|
f.DetectGzip()
|
||||||
|
slog.Info("transport.NewFileWriter()", "file", f.File)
|
||||||
exists := FileExists(u)
|
exists := FileExists(u)
|
||||||
slog.Info("transport.NewFileWriter()", "file", f, "error", err, "exists", exists)
|
slog.Info("transport.NewFileWriter()", "file", f, "error", err, "exists", exists)
|
||||||
|
|
||||||
@ -110,7 +112,7 @@ func NewFileWriter(u *url.URL) (f *FileWriter, err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if f.Gzip() {
|
if f.Gzip() {
|
||||||
f.gzipWriter = gzip.NewWriter(f.writeHandle)
|
f.gzipWriter = ext.WriteAddCloser(gzip.NewWriter(f.writeHandle), func() error { return f.writeHandle.Close() })
|
||||||
}
|
}
|
||||||
slog.Info("transport.NewFileWriter()", "file", f, "error", err)
|
slog.Info("transport.NewFileWriter()", "file", f, "error", err)
|
||||||
return
|
return
|
||||||
@ -139,7 +141,7 @@ func NewFile(u *url.URL) (f *File, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if f.Gzip() {
|
if f.Gzip() {
|
||||||
f.gzipWriter = gzip.NewWriter(f.writeHandle)
|
f.gzipWriter = ext.WriteAddCloser(gzip.NewWriter(f.writeHandle), func() error { return f.writeHandle.Close() })
|
||||||
if exists {
|
if exists {
|
||||||
if f.gzipReader, err = gzip.NewReader(f.readHandle); err != nil {
|
if f.gzipReader, err = gzip.NewReader(f.readHandle); err != nil {
|
||||||
return
|
return
|
||||||
@ -164,7 +166,7 @@ func (f *File) extension() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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" || f.exttype == "tgz" || f.exttype == "gz" || f.fileext == "tgz")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *File) URI() *url.URL {
|
func (f *File) URI() *url.URL {
|
||||||
|
@ -7,8 +7,11 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"io"
|
||||||
"net/url"
|
"net/url"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"compress/gzip"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
var TransportFileTestFile = fmt.Sprintf("%s/foo", TempDir)
|
var TransportFileTestFile = fmt.Sprintf("%s/foo", TempDir)
|
||||||
@ -37,3 +40,35 @@ func TestNewTransportFileReaderExtension(t *testing.T) {
|
|||||||
f.extension()
|
f.extension()
|
||||||
assert.Equal(t, f.exttype, "yaml")
|
assert.Equal(t, f.exttype, "yaml")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Use transport to write a compressed file then verify it.
|
||||||
|
func TestTransportFileGzipWriter(t *testing.T) {
|
||||||
|
var content strings.Builder
|
||||||
|
var testValue string = "write a compressed plaintext file"
|
||||||
|
|
||||||
|
path := TempDir.FilePath("foo.tgz")
|
||||||
|
u, e := url.Parse(fmt.Sprintf("file://%s", path))
|
||||||
|
assert.Nil(t, e)
|
||||||
|
|
||||||
|
fw, err := NewFileWriter(u)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, "tgz", fw.File.exttype)
|
||||||
|
|
||||||
|
assert.True(t, fw.Gzip())
|
||||||
|
|
||||||
|
writer := fw.Writer()
|
||||||
|
writer.Write([]byte(testValue))
|
||||||
|
assert.Nil(t, writer.Close())
|
||||||
|
|
||||||
|
assert.True(t, TempDir.FileExists("foo.tgz"))
|
||||||
|
|
||||||
|
r, openErr := TempDir.Open("foo.tgz")
|
||||||
|
assert.Nil(t, openErr)
|
||||||
|
gzipReader, gzipErr := gzip.NewReader(r)
|
||||||
|
assert.Nil(t, gzipErr)
|
||||||
|
_, readErr := io.Copy(&content, gzipReader)
|
||||||
|
assert.Nil(t, readErr)
|
||||||
|
assert.Equal(t, content.String(), testValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ type Handler interface {
|
|||||||
URI() *url.URL
|
URI() *url.URL
|
||||||
ContentType() string
|
ContentType() string
|
||||||
SetGzip(bool)
|
SetGzip(bool)
|
||||||
|
DetectGzip()
|
||||||
Gzip() bool
|
Gzip() bool
|
||||||
Signature() string
|
Signature() string
|
||||||
Stat() (fs.FileInfo, error)
|
Stat() (fs.FileInfo, error)
|
||||||
@ -138,6 +139,8 @@ func (r *Reader) SetGzip(value bool) {
|
|||||||
r.handle.SetGzip(value)
|
r.handle.SetGzip(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *Reader) DetectGzip() { r.handle.DetectGzip() }
|
||||||
|
|
||||||
func (r *Reader) Gzip() bool {
|
func (r *Reader) Gzip() bool {
|
||||||
return r.handle.Gzip()
|
return r.handle.Gzip()
|
||||||
}
|
}
|
||||||
@ -196,6 +199,8 @@ func (w *Writer) SetGzip(value bool) {
|
|||||||
w.handle.SetGzip(value)
|
w.handle.SetGzip(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *Writer) DetectGzip() { w.handle.DetectGzip() }
|
||||||
|
|
||||||
func (w *Writer) Gzip() bool {
|
func (w *Writer) Gzip() bool {
|
||||||
return w.handle.Gzip()
|
return w.handle.Gzip()
|
||||||
}
|
}
|
||||||
|
@ -9,9 +9,10 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"log"
|
"log"
|
||||||
|
"decl/internal/tempdir"
|
||||||
)
|
)
|
||||||
|
|
||||||
var TempDir string
|
var TempDir tempdir.Path = "testtransportfile"
|
||||||
|
|
||||||
var testFileResourceDoc string = `
|
var testFileResourceDoc string = `
|
||||||
resources:
|
resources:
|
||||||
@ -23,19 +24,19 @@ resources:
|
|||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
var err error
|
var err error
|
||||||
TempDir, err = os.MkdirTemp("", "testtransportfile")
|
err = TempDir.Create()
|
||||||
if err != nil || TempDir == "" {
|
if err != nil || TempDir == "" {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
rc := m.Run()
|
rc := m.Run()
|
||||||
|
|
||||||
os.RemoveAll(TempDir)
|
TempDir.Remove()
|
||||||
os.Exit(rc)
|
os.Exit(rc)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNewTransportReader(t *testing.T) {
|
func TestNewTransportReader(t *testing.T) {
|
||||||
path := fmt.Sprintf("%s/foo", TempDir)
|
path := TempDir.FilePath("foo")
|
||||||
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)
|
||||||
|
|
||||||
@ -48,7 +49,7 @@ func TestNewTransportReader(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestTransportReaderContentType(t *testing.T) {
|
func TestTransportReaderContentType(t *testing.T) {
|
||||||
path := fmt.Sprintf("%s/foo.jx.yaml", TempDir)
|
path := TempDir.FilePath("foo.jx.yaml")
|
||||||
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)
|
||||||
|
|
||||||
@ -66,7 +67,7 @@ func TestTransportReaderContentType(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestTransportReaderDir(t *testing.T) {
|
func TestTransportReaderDir(t *testing.T) {
|
||||||
u, e := url.Parse(fmt.Sprintf("file://%s", TempDir))
|
u, e := url.Parse(fmt.Sprintf("file://%s", string(TempDir)))
|
||||||
assert.Nil(t, e)
|
assert.Nil(t, e)
|
||||||
|
|
||||||
reader, err := NewReader(u)
|
reader, err := NewReader(u)
|
||||||
@ -76,7 +77,7 @@ func TestTransportReaderDir(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestTransportWriter(t *testing.T) {
|
func TestTransportWriter(t *testing.T) {
|
||||||
path := fmt.Sprintf("%s/writefoo", TempDir)
|
path := TempDir.FilePath("writefoo")
|
||||||
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)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user