2 tofuproxy -- flexible HTTP/HTTPS proxy, TLS terminator, X.509 TOFU
3 manager, WARC/geminispace browser
4 Copyright (C) 2021-2023 Sergey Matveev <stargrave@stargrave.org>
6 This program is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, version 3 of the License.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
33 type CompressedReader struct {
40 offReader sync.WaitGroup
43 func NewCompressedReader(
44 warcPath, unCmd string,
47 ) (*CompressedReader, error) {
49 for _, off := range offsets {
50 if uOffset < offU+off.U {
56 fd, err := os.Open(warcPath)
61 if len(offsets) > 0 && offsets[0].U == 0 {
62 dict = make([]byte, offsets[0].Z)
63 if _, err = io.ReadFull(fd, dict); err != nil {
68 if _, err = fd.Seek(offZ, io.SeekStart); err != nil {
72 cmd := exec.Command(unCmd)
73 stdout, err := cmd.StdoutPipe()
81 cmd.Stdin = io.MultiReader(bytes.NewReader(dict), fd)
84 offR, offW, err := os.Pipe()
89 cmd.ExtraFiles = append(cmd.ExtraFiles, offW)
96 r := CompressedReader{
103 go r.offsetsReader(offR)
111 _, err = io.CopyN(io.Discard, stdout, uOffset-offU)
117 return &CompressedReader{cmd: cmd, fd: fd, stdout: stdout}, nil
120 func (r *CompressedReader) offsetsReader(offsets *os.File) {
121 scanner := bufio.NewScanner(offsets)
124 cols := strings.Split(l, "\t")
126 log.Println("len(cols) != 2:", l)
129 z, err := strconv.ParseUint(cols[0], 10, 64)
134 u, err := strconv.ParseUint(cols[1], 10, 64)
139 r.offsets = append(r.offsets, Offset{int64(z), int64(u)})
148 func (r *CompressedReader) Read(p []byte) (int, error) {
149 return r.stdout.Read(p)
152 func (r *CompressedReader) Close() error {
153 err := r.cmd.Process.Kill()
161 func (r *CompressedReader) Offsets() []Offset {