cmd/golangorg: make zip contents seekable
https://golang.org/misc/cgo/stdio/testdata/fib.go fails right now because the http.FileServer wants to use Seek to find out the file size. Make that work by introducing an FS wrapper that enables seeking in an in-memory copy of the file content. Fixes golang/go#46809. Change-Id: I353905310dc74594e54e0181dc821a97992b8da7 Reviewed-on: https://go-review.googlesource.com/c/website/+/329249 Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org> Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Trust: Russ Cox <rsc@golang.org>
This commit is contained in:
Родитель
a2b5f4911c
Коммит
06fdb770f7
|
@ -6,12 +6,14 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"go/format"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
|
@ -125,8 +127,7 @@ func NewHandler(contentDir, goroot string) http.Handler {
|
|||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer z.Close()
|
||||
gorootFS = z
|
||||
gorootFS = &seekableFS{z}
|
||||
} else {
|
||||
gorootFS = osfs.DirFS(goroot)
|
||||
}
|
||||
|
@ -382,3 +383,47 @@ func (fsys unionFS) ReadDir(name string) ([]fs.DirEntry, error) {
|
|||
}
|
||||
return nil, errOut
|
||||
}
|
||||
|
||||
// A seekableFS is an FS wrapper that makes every file seekable
|
||||
// by reading it entirely into memory when it is opened and then
|
||||
// serving read operations (including seek) from the memory copy.
|
||||
type seekableFS struct {
|
||||
fs fs.FS
|
||||
}
|
||||
|
||||
func (s *seekableFS) Open(name string) (fs.File, error) {
|
||||
f, err := s.fs.Open(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
info, err := f.Stat()
|
||||
if err != nil {
|
||||
f.Close()
|
||||
return nil, err
|
||||
}
|
||||
if info.IsDir() {
|
||||
return f, nil
|
||||
}
|
||||
data, err := ioutil.ReadAll(f)
|
||||
if err != nil {
|
||||
f.Close()
|
||||
return nil, err
|
||||
}
|
||||
var sf seekableFile
|
||||
sf.File = f
|
||||
sf.Reset(data)
|
||||
return &sf, nil
|
||||
}
|
||||
|
||||
// A seekableFile is a fs.File augmented by an in-memory copy of the file data to allow use of Seek.
|
||||
type seekableFile struct {
|
||||
bytes.Reader
|
||||
fs.File
|
||||
}
|
||||
|
||||
// Read calls f.Reader.Read.
|
||||
// Both f.Reader and f.File have Read methods - a conflict - so f inherits neither.
|
||||
// This method calls the one we want.
|
||||
func (f *seekableFile) Read(b []byte) (int, error) {
|
||||
return f.Reader.Read(b)
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче