Files
teleport/lib/web/assets.go
T
Jeff Pihach 5e68f63dec Remove support for DEBUG_ASSETS_PATH (#21346)
* Remove support for DEBUG_ASSETS_PATH now that webapps is in the same repository.

* Remove unused DebugEnvVar variable.

* Don't return an error when explicitly build without webassets.

* Create a simple util to return a http file system for apiserver tests.

* revert

* Add missing license.

* Add comment and remove lint exception.

* add in lint exception.
2023-02-08 17:27:22 +00:00

104 lines
2.3 KiB
Go

/*
Copyright 2021 Gravitational, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package web
import (
"archive/zip"
"io"
"net/http"
"os"
"strings"
"github.com/gravitational/trace"
)
// resource struct implements http.File interface on top of zip.File object
type resource struct {
reader io.ReadCloser
file *zip.File
pos int64
}
func (rsc *resource) Read(p []byte) (n int, err error) {
n, err = rsc.reader.Read(p)
rsc.pos += int64(n)
return n, err
}
func (rsc *resource) Seek(offset int64, whence int) (int64, error) {
var (
pos int64
err error
)
// zip.File does not support seeking. To implement Seek on top of it,
// we close the existing reader, re-open it, and read 'offset' bytes from
// the beginning
if err = rsc.reader.Close(); err != nil {
return 0, err
}
if rsc.reader, err = rsc.file.Open(); err != nil {
return 0, err
}
switch whence {
case io.SeekStart:
pos = offset
case io.SeekCurrent:
pos = rsc.pos + offset
case io.SeekEnd:
pos = int64(rsc.file.UncompressedSize64) + offset
}
if pos > 0 {
b := make([]byte, pos)
if _, err = rsc.reader.Read(b); err != nil {
return 0, err
}
}
rsc.pos = pos
return pos, nil
}
func (rsc *resource) Readdir(count int) ([]os.FileInfo, error) {
return nil, trace.Wrap(os.ErrPermission)
}
func (rsc *resource) Stat() (os.FileInfo, error) {
return rsc.file.FileInfo(), nil
}
func (rsc *resource) Close() (err error) {
log.Debugf("zip::Close(%s).", rsc.file.FileInfo().Name())
return rsc.reader.Close()
}
type ResourceMap map[string]*zip.File
func (rm ResourceMap) Open(name string) (http.File, error) {
log.Debugf("GET zip:%s.", name)
f, ok := rm[strings.Trim(name, "/")]
if !ok {
return nil, trace.Wrap(os.ErrNotExist)
}
reader, err := f.Open()
if err != nil {
return nil, trace.Wrap(err)
}
return &resource{
reader: reader,
file: f,
}, nil
}