teldrive/internal/reader/decrypted-reader.go

110 lines
1.9 KiB
Go
Raw Normal View History

2023-12-08 05:46:06 +08:00
package reader
import (
"context"
"io"
"github.com/divyam234/teldrive/internal/crypt"
"github.com/divyam234/teldrive/pkg/types"
"github.com/gotd/td/telegram"
)
type decrpytedReader struct {
ctx context.Context
parts []types.Part
pos int
client *telegram.Client
reader io.ReadCloser
2024-03-10 22:40:09 +08:00
limit int64
err error
encryptionKey string
2023-12-08 05:46:06 +08:00
}
func NewDecryptedReader(
ctx context.Context,
client *telegram.Client,
parts []types.Part,
2024-03-10 22:40:09 +08:00
limit int64,
encryptionKey string) (io.ReadCloser, error) {
2023-12-08 05:46:06 +08:00
r := &decrpytedReader{
ctx: ctx,
parts: parts,
client: client,
2024-03-10 22:40:09 +08:00
limit: limit,
encryptionKey: encryptionKey,
2023-12-08 05:46:06 +08:00
}
res, err := r.nextPart()
if err != nil {
return nil, err
}
r.reader = res
return r, nil
}
func (r *decrpytedReader) Read(p []byte) (n int, err error) {
2024-03-10 22:40:09 +08:00
if r.err != nil {
return 0, r.err
}
if r.limit <= 0 {
return 0, io.EOF
}
2023-12-08 05:46:06 +08:00
n, err = r.reader.Read(p)
2024-03-10 22:40:09 +08:00
if err == nil {
r.limit -= int64(n)
}
if err == io.EOF {
if r.limit > 0 {
err = nil
}
2023-12-08 05:46:06 +08:00
r.pos++
if r.pos < len(r.parts) {
2024-03-10 22:40:09 +08:00
r.reader, err = newTGReader(r.ctx, r.client, r.parts[r.pos])
2023-12-08 05:46:06 +08:00
}
}
2024-03-10 22:40:09 +08:00
r.err = err
return
2023-12-08 05:46:06 +08:00
}
func (r *decrpytedReader) Close() (err error) {
if r.reader != nil {
err = r.reader.Close()
r.reader = nil
return err
}
return nil
}
func (r *decrpytedReader) nextPart() (io.ReadCloser, error) {
cipher, _ := crypt.NewCipher(r.encryptionKey, r.parts[r.pos].Salt)
return cipher.DecryptDataSeek(r.ctx,
2023-12-08 05:46:06 +08:00
func(ctx context.Context,
underlyingOffset,
underlyingLimit int64) (io.ReadCloser, error) {
var end int64
if underlyingLimit >= 0 {
end = min(r.parts[r.pos].Size-1, underlyingOffset+underlyingLimit-1)
}
2024-03-10 22:40:09 +08:00
return newTGReader(r.ctx, r.client, types.Part{
2023-12-08 05:46:06 +08:00
Start: underlyingOffset,
End: end,
Location: r.parts[r.pos].Location,
})
}, r.parts[r.pos].Start, r.parts[r.pos].End-r.parts[r.pos].Start+1)
}