2024-07-01 07:16:55 +00:00
|
|
|
// 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 File struct {
|
|
|
|
uri *url.URL
|
|
|
|
path string
|
|
|
|
exttype string
|
|
|
|
fileext string
|
|
|
|
readHandle *os.File
|
|
|
|
writeHandle *os.File
|
|
|
|
gzip bool
|
|
|
|
gzipWriter io.WriteCloser
|
|
|
|
gzipReader io.ReadCloser
|
|
|
|
}
|
|
|
|
|
2024-07-17 08:19:55 +00:00
|
|
|
func FilePath(u *url.URL) string {
|
2024-07-22 22:03:22 +00:00
|
|
|
return filepath.Join(u.Hostname(), u.Path)
|
2024-07-17 08:19:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func FileExists(u *url.URL) bool {
|
|
|
|
_, err := os.Stat(FilePath(u))
|
|
|
|
return err == nil
|
|
|
|
}
|
|
|
|
|
2024-07-01 07:16:55 +00:00
|
|
|
func NewFile(u *url.URL) (f *File, err error) {
|
|
|
|
f = &File {
|
|
|
|
uri: u,
|
2024-07-17 08:19:55 +00:00
|
|
|
path: FilePath(u),
|
2024-07-01 07:16:55 +00:00
|
|
|
}
|
|
|
|
f.extension()
|
|
|
|
f.DetectGzip()
|
|
|
|
|
|
|
|
if f.path == "" || f.path == "-" {
|
|
|
|
f.readHandle = os.Stdin
|
|
|
|
f.writeHandle = os.Stdout
|
|
|
|
} else {
|
2024-07-01 21:54:18 +00:00
|
|
|
if f.readHandle, err = os.OpenFile(f.Path(), os.O_RDWR|os.O_CREATE, 0644); err != nil {
|
2024-07-01 07:16:55 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
f.writeHandle = f.readHandle
|
|
|
|
}
|
|
|
|
|
|
|
|
if f.Gzip() {
|
|
|
|
f.gzipWriter = gzip.NewWriter(f.writeHandle)
|
|
|
|
if f.gzipReader, err = gzip.NewReader(f.readHandle); err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *File) extension() {
|
|
|
|
elements := strings.Split(f.path, ".")
|
|
|
|
numberOfElements := len(elements)
|
2024-07-17 08:19:55 +00:00
|
|
|
if numberOfElements > 1 {
|
|
|
|
if numberOfElements > 2 {
|
|
|
|
f.exttype = elements[numberOfElements - 2]
|
|
|
|
f.fileext = elements[numberOfElements - 1]
|
|
|
|
}
|
|
|
|
f.exttype = elements[numberOfElements - 1]
|
2024-07-01 07:16:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *File) DetectGzip() {
|
|
|
|
f.gzip = (f.uri.Query().Get("gzip") == "true" || f.fileext == "gz")
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *File) URI() *url.URL {
|
|
|
|
return f.uri
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *File) Path() string {
|
|
|
|
return f.path
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *File) Signature() (documentSignature string) {
|
|
|
|
if signatureResp, signatureErr := os.Open(fmt.Sprintf("%s.sig", f.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 (f *File) ContentType() string {
|
2024-07-17 08:19:55 +00:00
|
|
|
if f.uri.Scheme != "file" {
|
|
|
|
return f.uri.Scheme
|
|
|
|
}
|
2024-07-01 07:16:55 +00:00
|
|
|
return f.exttype
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *File) SetGzip(gzip bool) {
|
|
|
|
f.gzip = gzip
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *File) Gzip() bool {
|
|
|
|
return f.gzip
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *File) Reader() io.ReadCloser {
|
|
|
|
if f.Gzip() {
|
|
|
|
return f.gzipReader
|
|
|
|
}
|
|
|
|
return f.readHandle
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *File) Writer() io.WriteCloser {
|
|
|
|
if f.Gzip() {
|
|
|
|
return f.gzipWriter
|
|
|
|
}
|
|
|
|
return f.writeHandle
|
|
|
|
}
|