/*
-tofuproxy -- flexible HTTP/WARC proxy with TLS certificates management
+tofuproxy -- flexible HTTP proxy, TLS terminator, X.509 certificates
+ manager, WARC/Gemini browser
Copyright (C) 2021 Sergey Matveev <stargrave@stargrave.org>
This program is free software: you can redistribute it and/or modify
type Record struct {
WARCPath string
Offset int64
+ Size int64
+
Hdr Header
HdrLen int
- Size int64
+ HdrLines []string
Continuations []*Record
}
}
type SelfRecordReader struct {
- r *io.LimitedReader
- rsc io.ReadSeekCloser
+ lr *io.LimitedReader
+ rrr io.ReadCloser
}
func (srr *SelfRecordReader) Read(p []byte) (n int, err error) {
- n, err = srr.r.Read(p)
+ n, err = srr.rrr.Read(p)
if err != nil {
srr.Close()
}
}
func (srr *SelfRecordReader) Close() error {
- return srr.rsc.Close()
+ return srr.rrr.Close()
}
-func (rec *Record) selfReader(noHdr bool) (*SelfRecordReader, error) {
- rsc, err := Open(rec.WARCPath)
- if err != nil {
- return nil, err
- }
+func (rec *Record) selfReader(noHdr bool, offsets []Offset) (*SelfRecordReader, error) {
offset := rec.Offset
if noHdr {
offset += int64(rec.HdrLen)
}
- if _, err = rsc.Seek(offset, io.SeekStart); err != nil {
- rsc.Close()
+ rrr, err := Open(rec.WARCPath, offsets, offset)
+ if err != nil {
return nil, err
}
- return &SelfRecordReader{r: &io.LimitedReader{R: rsc, N: rec.Size}, rsc: rsc}, nil
+ return &SelfRecordReader{lr: &io.LimitedReader{R: rrr, N: rec.Size}, rrr: rrr}, nil
}
type RecordReader struct {
srrs []*SelfRecordReader
}
-func (rec *Record) Reader(noHdr bool) (*RecordReader, error) {
+func (rec *Record) Reader(
+ noHdr bool,
+ warcOffsets map[string][]Offset,
+) (*RecordReader, error) {
srrs := make([]*SelfRecordReader, 0, 1+len(rec.Continuations))
rs := make([]io.Reader, 0, 1+len(rec.Continuations))
for i, r := range append([]*Record{rec}, rec.Continuations...) {
if i > 0 {
noHdr = true
}
- srr, err := r.selfReader(noHdr)
+ srr, err := r.selfReader(noHdr, warcOffsets[rec.WARCPath])
if err != nil {
for _, srr := range srrs {
srr.Close()