129 lines
2.6 KiB
Go
129 lines
2.6 KiB
Go
// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved.
|
|
|
|
package transport
|
|
|
|
import (
|
|
_ "errors"
|
|
"io"
|
|
_ "os"
|
|
"net/url"
|
|
"net/http"
|
|
"fmt"
|
|
"context"
|
|
"path/filepath"
|
|
"io/fs"
|
|
"decl/internal/identifier"
|
|
"strconv"
|
|
)
|
|
|
|
type HTTP struct {
|
|
uri *url.URL
|
|
path string
|
|
gzip bool
|
|
exttype string
|
|
fileext string
|
|
|
|
ctx context.Context
|
|
get *HTTPConnection
|
|
Client *http.Client
|
|
}
|
|
|
|
func HTTPExists(u *url.URL) bool {
|
|
resp, err := http.Head(u.String())
|
|
if err == nil && resp.StatusCode == 200 {
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
func NewHTTP(u *url.URL, ctx context.Context) (h *HTTP, err error) {
|
|
h = &HTTP {
|
|
ctx: ctx,
|
|
uri: u,
|
|
path: filepath.Join(u.Hostname(), u.RequestURI()),
|
|
Client: http.DefaultClient,
|
|
}
|
|
|
|
h.extension()
|
|
h.DetectGzip()
|
|
return
|
|
}
|
|
|
|
func (h *HTTP) extension() {
|
|
id := identifier.ID(h.path)
|
|
h.exttype, h.fileext = id.Extension()
|
|
}
|
|
|
|
func (h *HTTP) DetectGzip() {
|
|
h.gzip = (h.uri.Query().Get("gzip") == "true" || h.fileext == "gz")
|
|
}
|
|
|
|
func (h *HTTP) URI() *url.URL {
|
|
return h.uri
|
|
}
|
|
|
|
func (h *HTTP) Path() string {
|
|
return h.path
|
|
}
|
|
|
|
func (h *HTTP) Signature() (documentSignature string) {
|
|
if h.get.Response() != nil {
|
|
documentSignature = h.get.Response().Header.Get("Signature")
|
|
if documentSignature == "" {
|
|
signatureResp, signatureErr := h.Client.Get(fmt.Sprintf("%s.sig", h.uri.String()))
|
|
if signatureErr == nil {
|
|
defer signatureResp.Body.Close()
|
|
readSignatureBody, readSignatureErr := io.ReadAll(signatureResp.Body)
|
|
if readSignatureErr == nil {
|
|
documentSignature = string(readSignatureBody)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return documentSignature
|
|
}
|
|
|
|
func (h *HTTP) Stat() (info fs.FileInfo, err error) {
|
|
uri := h.uri.String()
|
|
var response *http.Response
|
|
if response, err = http.Head(uri); err != nil {
|
|
return
|
|
}
|
|
defer response.Body.Close()
|
|
|
|
if response.StatusCode > 399 {
|
|
err = ErrTransportResourceAbsent
|
|
return
|
|
}
|
|
fi := NewHTTPFileInfo(uri)
|
|
contentLength := response.Header.Get("Content-Length")
|
|
if contentLength != "" {
|
|
if fi.ContentLength, err = strconv.ParseInt(contentLength, 10, 64); err != nil {
|
|
return
|
|
}
|
|
}
|
|
if response.Header.Get("Last-Modified") != "" {
|
|
fi.LastModified, _ = http.ParseTime(response.Header.Get("Last-Modified"))
|
|
}
|
|
fi.ContentType = response.Header.Get("Content-Type")
|
|
return fi, err
|
|
}
|
|
|
|
func (h *HTTP) ContentType() (contenttype string) {
|
|
contenttype = h.get.Response().Header.Get("Content-Type")
|
|
switch contenttype {
|
|
case "application/octet-stream":
|
|
return h.exttype
|
|
default:
|
|
}
|
|
return
|
|
}
|
|
|
|
func (h *HTTP) SetGzip(gzip bool) {
|
|
h.gzip = gzip
|
|
}
|
|
|
|
func (h *HTTP) Gzip() bool {
|
|
return h.gzip
|
|
}
|