2 tofuproxy -- flexible HTTP/WARC proxy with TLS certificates management
3 Copyright (C) 2021 Sergey Matveev <stargrave@stargrave.org>
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, version 3 of the License.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>.
32 type CompressedReader struct {
39 offReader sync.WaitGroup
42 func NewCompressedReader(
43 warcPath, unCmd string,
46 ) (*CompressedReader, error) {
48 for _, off := range offsets {
49 if uOffset < offU+off.U {
55 fd, err := os.Open(warcPath)
60 if len(offsets) > 0 && offsets[0].U == 0 {
61 dict = make([]byte, offsets[0].Z)
62 if _, err = io.ReadFull(fd, dict); err != nil {
67 if _, err = fd.Seek(offZ, io.SeekStart); err != nil {
71 cmd := exec.Command(unCmd)
72 stdout, err := cmd.StdoutPipe()
80 cmd.Stdin = io.MultiReader(bytes.NewReader(dict), fd)
83 offR, offW, err := os.Pipe()
88 cmd.ExtraFiles = append(cmd.ExtraFiles, offW)
95 r := CompressedReader{
102 go r.offsetsReader(offR)
110 _, err = io.CopyN(io.Discard, stdout, uOffset-offU)
116 return &CompressedReader{cmd: cmd, fd: fd, stdout: stdout}, nil
119 func (r *CompressedReader) offsetsReader(offsets *os.File) {
120 scanner := bufio.NewScanner(offsets)
123 cols := strings.Split(l, "\t")
125 log.Println("len(cols) != 2:", l)
128 z, err := strconv.ParseUint(cols[0], 10, 64)
133 u, err := strconv.ParseUint(cols[1], 10, 64)
138 r.offsets = append(r.offsets, Offset{int64(z), int64(u)})
147 func (r *CompressedReader) Read(p []byte) (int, error) {
148 return r.stdout.Read(p)
151 func (r *CompressedReader) Close() error {
152 err := r.cmd.Process.Kill()
160 func (r *CompressedReader) Offsets() []Offset {