1 // tofuproxy -- flexible HTTP/HTTPS proxy, TLS terminator, X.509 TOFU
2 // manager, WARC/geminispace browser
3 // Copyright (C) 2021-2024 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/>.
33 Continuations []*Record
36 func (rec *Record) URI() string {
37 return strings.Trim(rec.Hdr.Get("WARC-Target-URI"), "<>")
40 func (rec *Record) TotalSize() int64 {
42 for _, r := range rec.Continuations {
48 type SelfRecordReader struct {
53 func (srr *SelfRecordReader) Read(p []byte) (n int, err error) {
54 n, err = srr.lr.Read(p)
61 func (srr *SelfRecordReader) Close() error {
62 return srr.rrr.Close()
65 func (rec *Record) selfReader(noHdr bool, offsets []Offset) (*SelfRecordReader, error) {
68 offset += int64(rec.HdrLen)
70 rrr, err := Open(rec.WARCPath, offsets, offset)
76 size += int64(rec.HdrLen)
78 return &SelfRecordReader{lr: &io.LimitedReader{R: rrr, N: size}, rrr: rrr}, nil
81 type RecordReader struct {
83 srrs []*SelfRecordReader
86 func (rec *Record) Reader(
88 warcOffsets map[string][]Offset,
89 ) (*RecordReader, error) {
90 srrs := make([]*SelfRecordReader, 0, 1+len(rec.Continuations))
91 rs := make([]io.Reader, 0, 1+len(rec.Continuations))
92 for i, r := range append([]*Record{rec}, rec.Continuations...) {
96 srr, err := r.selfReader(noHdr, warcOffsets[rec.WARCPath])
98 for _, srr := range srrs {
103 srrs = append(srrs, srr)
106 return &RecordReader{r: io.MultiReader(rs...), srrs: srrs}, nil
109 func (rr *RecordReader) Read(p []byte) (n int, err error) {
110 n, err = rr.r.Read(p)
117 func (rr *RecordReader) Close() error {
118 for _, srr := range rr.srrs {