Spies = make([]string, 0)
SpiesM sync.RWMutex
- Restricted = make(map[string][]string)
+ Restricted = make(map[string][]string)
RestrictedM sync.RWMutex
)
// tofuproxy -- flexible HTTP/HTTPS proxy, TLS terminator, X.509 TOFU
// manager, WARC/geminispace browser
-// Copyright (C) 2021-2024 Sergey Matveev <stargrave@stargrave.org>
+// Copyright (C) 2021-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
"crypto/x509/pkix"
"encoding/pem"
"flag"
- "io"
"log"
"math/big"
"os"
notAfter := notBefore.Add(365 * 24 * time.Hour)
serialRaw := make([]byte, 16)
- if _, err := io.ReadFull(rand.Reader, serialRaw); err != nil {
- log.Fatalln(err)
- }
+ rand.Read(serialRaw)
serial := big.NewInt(0)
serial = serial.SetBytes(serialRaw)
// tofuproxy -- flexible HTTP/HTTPS proxy, TLS terminator, X.509 TOFU
// manager, WARC/geminispace browser
-// Copyright (C) 2021-2024 Sergey Matveev <stargrave@stargrave.org>
+// Copyright (C) 2021-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
"fmt"
"log"
- "go.cypherpunks.ru/ucspi"
+ "go.cypherpunks.su/ucspi/v2"
ttls "go.stargrave.org/tofuproxy/tls"
)
// tofuproxy -- flexible HTTP/HTTPS proxy, TLS terminator, X.509 TOFU
// manager, WARC/geminispace browser
-// Copyright (C) 2021-2024 Sergey Matveev <stargrave@stargrave.org>
+// Copyright (C) 2021-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
"net"
"net/http"
- "go.cypherpunks.ru/ucspi"
+ "go.cypherpunks.su/ucspi/v2"
"go.stargrave.org/tofuproxy"
"go.stargrave.org/tofuproxy/fifos"
"go.stargrave.org/tofuproxy/rounds"
// tofuproxy -- flexible HTTP/HTTPS proxy, TLS terminator, X.509 TOFU
// manager, WARC/geminispace browser
-// Copyright (C) 2021-2024 Sergey Matveev <stargrave@stargrave.org>
+// Copyright (C) 2021-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// warc-extract -- WARC files data extractor
-// Copyright (C) 2021-2024 Sergey Matveev <stargrave@stargrave.org>
+// Copyright (C) 2021-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// tofuproxy -- flexible HTTP/HTTPS proxy, TLS terminator, X.509 TOFU
// manager, WARC/geminispace browser
-// Copyright (C) 2021-2024 Sergey Matveev <stargrave@stargrave.org>
+// Copyright (C) 2021-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@multitable {XXXXX} {XXXX-XX-XX} {XXXX KiB} {meta4 tar pgp ssh}
@headitem Version @tab Date @tab Size @tab Tarball
+@item 0.6.0 @tab 2024-04-21 @tab 651 KiB @tab
+ @url{download/tofuproxy-0.6.0.tar.zst.meta4, meta4}
+ @url{download/tofuproxy-0.6.0.tar.zst, tar}
+ @url{download/tofuproxy-0.6.0.tar.zst.asc, pgp}
+ @url{download/tofuproxy-0.6.0.tar.zst.sig, ssh}
+
@item 0.5.0 @tab 2024-04-18 @tab 651 KiB @tab
@url{download/tofuproxy-0.5.0.tar.zst.meta4, meta4}
@url{download/tofuproxy-0.5.0.tar.zst, tar}
@settitle tofuproxy
@copying
-Copyright @copyright{} 2021-2024 @email{stargrave@@stargrave.org, Sergey Matveev}
+Copyright @copyright{} 2021-2025 @email{stargrave@@stargrave.org, Sergey Matveev}
@end copying
@node Top
@item
Full TLS connection termination between Web-servers and
@command{tofuproxy} itself. TLS 1.3, session resumption, GOST
-cryptography (if built with @url{http://www.gostls13.cypherpunks.ru/,
+cryptography (if built with @url{http://www.gostls13.cypherpunks.su/,
gostls13}) support. Connection between @command{tofuproxy} and browser
itself uses ephemeral on-the-fly generated certificates with proper
domain name.
@file{.netrc}.
@item
-Permanent HTTP redirects are replaces with non-refreshing HTML page with
+Permanent HTTP redirects are replaced with non-refreshing HTML page with
the link, to make you explicitly allow that step. Temporary redirects
-are followed if it is neither @url{https://newsboat.org/, Newsboat}
-nor @url{https://www.feeder.stargrave.org/, go.stargrave.org/feeder}
-user-agent, not image paths.
+are followed if it is neither @url{https://www.feeder.stargrave.org/, go.stargrave.org/feeder}
+user-agent, nor image paths.
@item
JPEG XL, AVIF and WebP images are transparently transcoded to PNG,
Its fingerprint: @code{SHA256:NIDt9iZUizwivY3GoxmGvbQTH7mz/dmV7ZFOXeYfa2o}.
@example
-$ ssh-keygen -Y verify -f PUBKEY-SSH.pub -I tofuproxy@@cypherpunks.ru -n file \
+$ ssh-keygen -Y verify -f PUBKEY-SSH.pub -I tofuproxy@@stargrave.org -n file \
-s tofuproxy-@value{VERSION}.tar.zst.sig <tofuproxy-@value{VERSION}.tar.zst
@end example
@item I am tired that everyone provides very limited certificates trust
management capabilities, like either certificate or SPKI
@url{https://en.wikipedia.org/wiki/Certificate_pinning, pinning} with
-@url{https://en.wikipedia.org/wiki/Trust_on_first_use, TOFU}. Even my
-beloved @url{https://en.wikipedia.org/wiki/Xombrero, Xombrero} browser
-still pins only the whole certificate, but its public key would be much
-more sufficient and convenient to work with.
+@url{https://en.wikipedia.org/wiki/Trust_on_first_use, TOFU}.
@item I am tired that many clients provides very few information about
certificates and connections at all.
not friendly with TLS connections, obviously. Or use yet another
browser-specific plugin.
-@item Xombrero sometimes has problems with HTTP-based authorization.
-
@item Hardly anyone does
@url{https://en.wikipedia.org/wiki/DNS-based_Authentication_of_Named_Entities, DANE}
checks.
Why the hell people just do not send PostScript documents instead!?
@item And wonderful @url{http://jpegxl.info/, JPEG XL} image format is
-not supported by most browsers. Even pretty old
-@url{https://developers.google.com/speed/webp, WebP}, that has highest
-compression ratio for lossless screenshots, is not supported everywhere,
-especially on old browsers.
-@url{https://aomediacodec.github.io/av1-avif/, AVIF} could be useful too.
+not supported by all browsers. Even pretty old
+@url{https://developers.google.com/speed/webp, WebP}, is not supported
+everywhere, especially on old browsers.
@item None of web browsers has ability to view web archives
(@url{https://en.wikipedia.org/wiki/Web_ARChive, WARC}s). And most of
// tofuproxy -- flexible HTTP/HTTPS proxy, TLS terminator, X.509 TOFU
// manager, WARC/geminispace browser
-// Copyright (C) 2021-2024 Sergey Matveev <stargrave@stargrave.org>
+// Copyright (C) 2021-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
)
func readLinesFromFIFO(p string) []string {
- fd, err := os.OpenFile(p, os.O_RDONLY, os.FileMode(0666))
+ fd, err := os.OpenFile(p, os.O_RDONLY, os.FileMode(0o666))
if err != nil {
log.Fatalln(err)
}
// tofuproxy -- flexible HTTP/HTTPS proxy, TLS terminator, X.509 TOFU
// manager, WARC/geminispace browser
-// Copyright (C) 2021-2024 Sergey Matveev <stargrave@stargrave.org>
+// Copyright (C) 2021-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
func del(l *sync.RWMutex, deleter func(string), p string) {
for {
- fd, err := os.OpenFile(p, os.O_RDONLY, os.FileMode(0666))
+ fd, err := os.OpenFile(p, os.O_RDONLY, os.FileMode(0o666))
if err != nil {
log.Fatalln(err)
}
// tofuproxy -- flexible HTTP/HTTPS proxy, TLS terminator, X.509 TOFU
// manager, WARC/geminispace browser
-// Copyright (C) 2021-2024 Sergey Matveev <stargrave@stargrave.org>
+// Copyright (C) 2021-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
func list(l *sync.RWMutex, m map[string]string, p string) {
for {
- fd, err := os.OpenFile(p, os.O_WRONLY|os.O_APPEND, os.FileMode(0666))
+ fd, err := os.OpenFile(p, os.O_WRONLY|os.O_APPEND, os.FileMode(0o666))
if err != nil {
log.Fatalln(err)
}
func listHTTPAuth(p string) {
for {
- fd, err := os.OpenFile(p, os.O_WRONLY|os.O_APPEND, os.FileMode(0666))
+ fd, err := os.OpenFile(p, os.O_WRONLY|os.O_APPEND, os.FileMode(0o666))
if err != nil {
log.Fatalln(err)
}
func listTLSAuth(p string) {
for {
- fd, err := os.OpenFile(p, os.O_WRONLY|os.O_APPEND, os.FileMode(0666))
+ fd, err := os.OpenFile(p, os.O_WRONLY|os.O_APPEND, os.FileMode(0o666))
if err != nil {
log.Fatalln(err)
}
caches.TLSAuthCacheM.RLock()
+ var cert *x509.Certificate
for host, tlsCert := range caches.TLSAuthCache {
subj := "NONE"
if len(tlsCert.Certificate) != 0 {
- cert, err := x509.ParseCertificate(tlsCert.Certificate[0])
+ cert, err = x509.ParseCertificate(tlsCert.Certificate[0])
if err != nil {
log.Fatalln(err)
}
// tofuproxy -- flexible HTTP/HTTPS proxy, TLS terminator, X.509 TOFU
// manager, WARC/geminispace browser
-// Copyright (C) 2021-2024 Sergey Matveev <stargrave@stargrave.org>
+// Copyright (C) 2021-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
"os"
"time"
- "go.cypherpunks.ru/tai64n/v2"
+ "go.cypherpunks.su/tai64n/v4"
)
var (
)
func logger(c chan string, p string) {
- tai := new(tai64n.TAI64N)
+ var tai tai64n.TAI64N
for {
- fd, err := os.OpenFile(p, os.O_WRONLY|os.O_APPEND, os.FileMode(0666))
+ fd, err := os.OpenFile(p, os.O_WRONLY|os.O_APPEND, os.FileMode(0o666))
if err != nil {
log.Fatalln(err)
}
_, err = fd.WriteString(s + "\n")
} else {
tai.FromTime(time.Now())
- _, err = fd.WriteString(tai64n.Encode(tai[:]) + " " + s + "\n")
+ _, err = fd.WriteString(tai.Encode() + " " + s + "\n")
}
if err != nil {
break
// tofuproxy -- flexible HTTP/HTTPS proxy, TLS terminator, X.509 TOFU
// manager, WARC/geminispace browser
-// Copyright (C) 2021-2024 Sergey Matveev <stargrave@stargrave.org>
+// Copyright (C) 2021-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
func listRestricted(p string) {
for {
- fd, err := os.OpenFile(p, os.O_WRONLY|os.O_APPEND, os.FileMode(0666))
+ fd, err := os.OpenFile(p, os.O_WRONLY|os.O_APPEND, os.FileMode(0o666))
if err != nil {
log.Fatalln(err)
}
// tofuproxy -- flexible HTTP/HTTPS proxy, TLS terminator, X.509 TOFU
// manager, WARC/geminispace browser
-// Copyright (C) 2021-2024 Sergey Matveev <stargrave@stargrave.org>
+// Copyright (C) 2021-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
func listSpies(p string) {
for {
- fd, err := os.OpenFile(p, os.O_WRONLY|os.O_APPEND, os.FileMode(0666))
+ fd, err := os.OpenFile(p, os.O_WRONLY|os.O_APPEND, os.FileMode(0o666))
if err != nil {
log.Fatalln(err)
}
// tofuproxy -- flexible HTTP/HTTPS proxy, TLS terminator, X.509 TOFU
// manager, WARC/geminispace browser
-// Copyright (C) 2021-2024 Sergey Matveev <stargrave@stargrave.org>
+// Copyright (C) 2021-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// tofuproxy -- flexible HTTP/HTTPS proxy, TLS terminator, X.509 TOFU
// manager, WARC/geminispace browser
-// Copyright (C) 2021-2024 Sergey Matveev <stargrave@stargrave.org>
+// Copyright (C) 2021-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
"log"
"strings"
- "go.cypherpunks.ru/ucspi"
+ "go.cypherpunks.su/ucspi/v2"
"go.stargrave.org/tofuproxy/caches"
)
// tofuproxy -- flexible HTTP/HTTPS proxy, TLS terminator, X.509 TOFU
// manager, WARC/geminispace browser
-// Copyright (C) 2021-2024 Sergey Matveev <stargrave@stargrave.org>
+// Copyright (C) 2021-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
func listWARCs(p string) {
for {
- fd, err := os.OpenFile(p, os.O_WRONLY|os.O_APPEND, os.FileMode(0666))
+ fd, err := os.OpenFile(p, os.O_WRONLY|os.O_APPEND, os.FileMode(0o666))
if err != nil {
log.Fatalln(err)
}
module go.stargrave.org/tofuproxy
-go 1.21
+go 1.24
require (
github.com/dustin/go-humanize v1.0.1
- github.com/miekg/dns v1.1.57
- go.cypherpunks.ru/netrc v0.1.0
- go.cypherpunks.ru/tai64n/v2 v2.0.1
- go.cypherpunks.ru/ucspi v0.1.0
+ github.com/miekg/dns v1.1.63
+ go.cypherpunks.su/netrc/v2 v2.0.0
+ go.cypherpunks.su/tai64n/v4 v4.1.0
+ go.cypherpunks.su/ucspi/v2 v2.0.0
)
require (
- golang.org/x/mod v0.14.0 // indirect
- golang.org/x/net v0.19.0 // indirect
- golang.org/x/sys v0.15.0 // indirect
- golang.org/x/tools v0.16.0 // indirect
+ golang.org/x/mod v0.23.0 // indirect
+ golang.org/x/net v0.35.0 // indirect
+ golang.org/x/sync v0.11.0 // indirect
+ golang.org/x/sys v0.30.0 // indirect
+ golang.org/x/tools v0.30.0 // indirect
)
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
-github.com/miekg/dns v1.1.57 h1:Jzi7ApEIzwEPLHWRcafCN9LZSBbqQpxjt/wpgvg7wcM=
-github.com/miekg/dns v1.1.57/go.mod h1:uqRjCRUuEAA6qsOiJvDd+CFo/vW+y5WR6SNmHE55hZk=
-go.cypherpunks.ru/netrc v0.1.0 h1:dzaSh4lgpPXvLzUME/hTSegg+Uw1aPEmC79fxbPLFGk=
-go.cypherpunks.ru/netrc v0.1.0/go.mod h1:ZmQaL9ENEII++WQooelccr33XZcBhKd8VgtcICf4SIE=
-go.cypherpunks.ru/tai64n/v2 v2.0.1 h1:AnwUUgi0EixZcr6nzjUaOy2DFInFwbNRkBkgon4oJfU=
-go.cypherpunks.ru/tai64n/v2 v2.0.1/go.mod h1:Jlva0YVJBpaRFAJ4jfY4BXVPuav0GMyGXzYPSKCCCL0=
-go.cypherpunks.ru/ucspi v0.1.0 h1:1w0E1mSf5oo3ozSSRUZN8Mf4/Ba18S3q7c5CDeCuHZA=
-go.cypherpunks.ru/ucspi v0.1.0/go.mod h1:mrkWllR0o0B/BocrUAL4DhcKLPK6XycObSswHUL5m6s=
-golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0=
-golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
-golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c=
-golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U=
-golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE=
-golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
-golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
-golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
-golang.org/x/tools v0.16.0 h1:GO788SKMRunPIBCXiQyo2AaexLstOrVhuAL5YwsckQM=
-golang.org/x/tools v0.16.0/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0=
+github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
+github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/miekg/dns v1.1.63 h1:8M5aAw6OMZfFXTT7K5V0Eu5YiiL8l7nUAkyN6C9YwaY=
+github.com/miekg/dns v1.1.63/go.mod h1:6NGHfjhpmr5lt3XPLuyfDJi5AXbNIPM9PY6H6sF1Nfs=
+go.cypherpunks.su/netrc/v2 v2.0.0 h1:IWJ0fPcQoccn8VbqzAQf1/4rj8zw0Bf6X5kAkzwEd48=
+go.cypherpunks.su/netrc/v2 v2.0.0/go.mod h1:F5Ea8ii3R9dNUE0ixE61OYIhvJQVLLdIJjrU/3qROjw=
+go.cypherpunks.su/tai64n/v4 v4.1.0 h1:jW0EyklKXpSy9DSFMcDbu7XuLlMkn6kkpNWiMG6UT5c=
+go.cypherpunks.su/tai64n/v4 v4.1.0/go.mod h1:/uKUdhLOy8UciRKpapPaFXSOoa/SiXjs3XsDDpAz7OA=
+go.cypherpunks.su/ucspi/v2 v2.0.0 h1:Ha/0xfi0nXL/4xdiXqKbHdbXWE/qKcnXux4hG7c/lwM=
+go.cypherpunks.su/ucspi/v2 v2.0.0/go.mod h1:GIIOgXFLLze7hG1sAmXmPNTopVrAaFi5m+GMUA72fXY=
+golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM=
+golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
+golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8=
+golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk=
+golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
+golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
+golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
+golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY=
+golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY=
// tofuproxy -- flexible HTTP/HTTPS proxy, TLS terminator, X.509 TOFU
// manager, WARC/geminispace browser
-// Copyright (C) 2021-2024 Sergey Matveev <stargrave@stargrave.org>
+// Copyright (C) 2021-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
"os/exec"
"strings"
- "go.cypherpunks.ru/netrc"
+ "go.cypherpunks.su/netrc/v2"
ttls "go.stargrave.org/tofuproxy/tls"
)
var b bytes.Buffer
userInit, passInit := netrc.Find(host)
fmt.Fprintf(&b, `
-tk_setPalette grey
wm title . "Unauthorized: %s"
label .luser -text "User"
chmod +x build state-init fifos/ensure fifos/multitail cmd/zstd/build
cd ..
-tar cvf tofuproxy-"$release".tar --uid=0 --gid=0 --numeric-owner tofuproxy-"$release"
+detpax tofuproxy-"$release" >tofuproxy-"$release".tar
zstd -22 --ultra -v tofuproxy-"$release".tar
tarball=tofuproxy-"$release".tar.zst
ssh-keygen -Y sign -f ~/.ssh/sign/tofuproxy@stargrave.org -n file $tarball
// tofuproxy -- flexible HTTP/HTTPS proxy, TLS terminator, X.509 TOFU
// manager, WARC/geminispace browser
-// Copyright (C) 2021-2024 Sergey Matveev <stargrave@stargrave.org>
+// Copyright (C) 2021-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// tofuproxy -- flexible HTTP/HTTPS proxy, TLS terminator, X.509 TOFU
// manager, WARC/geminispace browser
-// Copyright (C) 2021-2024 Sergey Matveev <stargrave@stargrave.org>
+// Copyright (C) 2021-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
!strings.Contains(req.Header.Get("Accept"), ContentTypeGemini) {
w.Header().Add("Content-Type", "text/html")
w.WriteHeader(http.StatusOK)
- raw, err := io.ReadAll(br)
+ var raw []byte
+ raw, err = io.ReadAll(br)
if err != nil {
log.Printf("%s: can not read response body: %+v\n", req.URL, err)
return false, err
<html><head><title>%d (%s)</title></head><body>
`, code, codeName)
pre := false
- for _, line := range strings.Split(string(raw), "\n") {
+ for line := range strings.SplitSeq(string(raw), "\n") {
if strings.HasPrefix(line, "```") {
if pre {
buf.WriteString("</pre>\n")
// tofuproxy -- flexible HTTP/HTTPS proxy, TLS terminator, X.509 TOFU
// manager, WARC/geminispace browser
-// Copyright (C) 2021-2024 Sergey Matveev <stargrave@stargrave.org>
+// Copyright (C) 2021-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// tofuproxy -- flexible HTTP/HTTPS proxy, TLS terminator, X.509 TOFU
// manager, WARC/geminispace browser
-// Copyright (C) 2021-2024 Sergey Matveev <stargrave@stargrave.org>
+// Copyright (C) 2021-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// tofuproxy -- flexible HTTP/HTTPS proxy, TLS terminator, X.509 TOFU
// manager, WARC/geminispace browser
-// Copyright (C) 2021-2024 Sergey Matveev <stargrave@stargrave.org>
+// Copyright (C) 2021-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
}
func isFeeder(req *http.Request) bool {
- if strings.Contains(req.Header.Get("User-Agent"), "newsboat/") {
- return true
- }
- if strings.Contains(req.Header.Get("User-Agent"), "stargrave.org-feeder/") {
- return true
- }
- return false
+ return strings.Contains(req.Header.Get("User-Agent"), "stargrave.org-feeder/")
}
func RoundRedirectHTML(
// tofuproxy -- flexible HTTP/HTTPS proxy, TLS terminator, X.509 TOFU
// manager, WARC/geminispace browser
-// Copyright (C) 2021-2024 Sergey Matveev <stargrave@stargrave.org>
+// Copyright (C) 2021-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// tofuproxy -- flexible HTTP/HTTPS proxy, TLS terminator, X.509 TOFU
// manager, WARC/geminispace browser
-// Copyright (C) 2021-2024 Sergey Matveev <stargrave@stargrave.org>
+// Copyright (C) 2021-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// tofuproxy -- flexible HTTP/HTTPS proxy, TLS terminator, X.509 TOFU
// manager, WARC/geminispace browser
-// Copyright (C) 2021-2024 Sergey Matveev <stargrave@stargrave.org>
+// Copyright (C) 2021-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// tofuproxy -- flexible HTTP/HTTPS proxy, TLS terminator, X.509 TOFU
// manager, WARC/geminispace browser
-// Copyright (C) 2021-2024 Sergey Matveev <stargrave@stargrave.org>
+// Copyright (C) 2021-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// tofuproxy -- flexible HTTP/HTTPS proxy, TLS terminator, X.509 TOFU
// manager, WARC/geminispace browser
-// Copyright (C) 2021-2024 Sergey Matveev <stargrave@stargrave.org>
+// Copyright (C) 2021-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// tofuproxy -- flexible HTTP/HTTPS proxy, TLS terminator, X.509 TOFU
// manager, WARC/geminispace browser
-// Copyright (C) 2021-2024 Sergey Matveev <stargrave@stargrave.org>
+// Copyright (C) 2021-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// tofuproxy -- flexible HTTP/HTTPS proxy, TLS terminator, X.509 TOFU
// manager, WARC/geminispace browser
-// Copyright (C) 2021-2024 Sergey Matveev <stargrave@stargrave.org>
+// Copyright (C) 2021-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// tofuproxy -- flexible HTTP/HTTPS proxy, TLS terminator, X.509 TOFU
// manager, WARC/geminispace browser
-// Copyright (C) 2021-2024 Sergey Matveev <stargrave@stargrave.org>
+// Copyright (C) 2021-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
"fmt"
"net"
- "go.cypherpunks.ru/ucspi"
+ "go.cypherpunks.su/ucspi/v2"
"go.stargrave.org/tofuproxy/fifos"
)
// tofuproxy -- flexible HTTP/HTTPS proxy, TLS terminator, X.509 TOFU
// manager, WARC/geminispace browser
-// Copyright (C) 2021-2024 Sergey Matveev <stargrave@stargrave.org>
+// Copyright (C) 2021-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
"strconv"
"strings"
- "go.cypherpunks.ru/ucspi"
+ "go.cypherpunks.su/ucspi/v2"
"go.stargrave.org/tofuproxy/caches"
"go.stargrave.org/tofuproxy/fifos"
)
}
var b bytes.Buffer
fmt.Fprintf(&b, `
-tk_setPalette grey
wm title . "TLS client authentication: %s"
set lb [listbox .lb]
tlsCerts = append(tlsCerts, nil)
for i, ent := range ents {
p := filepath.Join(CCerts, ent.Name())
- _, cert, err := ucspi.CertificateFromFile(p)
+ var cert *x509.Certificate
+ _, cert, err = ucspi.CertificateFromFile(p)
if err != nil {
log.Fatalln(err)
}
- prv, err := ucspi.PrivateKeyFromFile(p)
+ var prv any
+ prv, err = ucspi.PrivateKeyFromFile(p)
if err != nil {
log.Fatalln(err)
}
// tofuproxy -- flexible HTTP/HTTPS proxy, TLS terminator, X.509 TOFU
// manager, WARC/geminispace browser
-// Copyright (C) 2021-2024 Sergey Matveev <stargrave@stargrave.org>
+// Copyright (C) 2021-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
"strings"
"sync"
- "go.cypherpunks.ru/ucspi"
+ "go.cypherpunks.su/ucspi/v2"
"go.stargrave.org/tofuproxy/caches"
"go.stargrave.org/tofuproxy/fifos"
)
set certsTheir [certsDecode $certsTheir]
set certsOur [certsDecode $certsOur]
-tk_setPalette grey
wm title . $host
proc paginator {i delta t l certs} {
// tofuproxy -- flexible HTTP/HTTPS proxy, TLS terminator, X.509 TOFU
// manager, WARC/geminispace browser
-// Copyright (C) 2021-2024 Sergey Matveev <stargrave@stargrave.org>
+// Copyright (C) 2021-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
fifos.LogVarious <- fmt.Sprintf(
"%s %s\tHTTP authorization required", req.Method, req.URL.Host,
)
- user, pass, err := authDialog(host, resp.Header.Get("WWW-Authenticate"))
+ var user, pass string
+ user, pass, err = authDialog(host, resp.Header.Get("WWW-Authenticate"))
if err != nil {
caches.HTTPAuthCacheM.Unlock()
fifos.LogErr <- fmt.Sprintf("%s\t%s", req.URL.Host, err.Error())
}
}
- for _, round := range []Round{
- rounds.RoundDenyFonts,
- rounds.RoundTranscodeWebP,
- rounds.RoundTranscodeJXL,
- rounds.RoundTranscodeAVIF,
- rounds.RoundRedirectHTML,
- } {
- cont, err := round(host, resp, w, req)
- if err != nil {
- http.Error(w, err.Error(), http.StatusBadGateway)
- return
- }
- if !cont {
- return
+ {
+ var cont bool
+ for _, round := range []Round{
+ rounds.RoundDenyFonts,
+ rounds.RoundTranscodeWebP,
+ rounds.RoundTranscodeJXL,
+ rounds.RoundTranscodeAVIF,
+ rounds.RoundRedirectHTML,
+ } {
+ cont, err = round(host, resp, w, req)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusBadGateway)
+ return
+ }
+ if !cont {
+ return
+ }
}
}
// tofuproxy -- flexible HTTP/HTTPS proxy, TLS terminator, X.509 TOFU
// manager, WARC/geminispace browser
-// Copyright (C) 2021-2024 Sergey Matveev <stargrave@stargrave.org>
+// Copyright (C) 2021-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
)
type CompressedReader struct {
- cmd *exec.Cmd
- fd *os.File
- stdout io.ReadCloser
- offsets []Offset
-
+ stdout io.ReadCloser
+ cmd *exec.Cmd
+ fd *os.File
offW *os.File
+ offsets []Offset
offReader sync.WaitGroup
}
cmd.Stdin = io.MultiReader(bytes.NewReader(dict), fd)
}
if offsets == nil {
- offR, offW, err := os.Pipe()
+ var offR, offW *os.File
+ offR, offW, err = os.Pipe()
if err != nil {
fd.Close()
return nil, err
// tofuproxy -- flexible HTTP/HTTPS proxy, TLS terminator, X.509 TOFU
// manager, WARC/geminispace browser
-// Copyright (C) 2021-2024 Sergey Matveev <stargrave@stargrave.org>
+// Copyright (C) 2021-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
gr := GZIPReader{r: r}
go func() {
z.Multistream(false)
- var offset, offsetPrev int64
+ var offset, offsetPrev, written int64
for {
- written, err := io.Copy(w, z)
+ written, err = io.Copy(w, z)
if err != nil {
w.CloseWithError(err)
return
// tofuproxy -- flexible HTTP/HTTPS proxy, TLS terminator, X.509 TOFU
// manager, WARC/geminispace browser
-// Copyright (C) 2021-2024 Sergey Matveev <stargrave@stargrave.org>
+// Copyright (C) 2021-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// tofuproxy -- flexible HTTP/HTTPS proxy, TLS terminator, X.509 TOFU
// manager, WARC/geminispace browser
-// Copyright (C) 2021-2024 Sergey Matveev <stargrave@stargrave.org>
+// Copyright (C) 2021-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// tofuproxy -- flexible HTTP/HTTPS proxy, TLS terminator, X.509 TOFU
// manager, WARC/geminispace browser
-// Copyright (C) 2021-2024 Sergey Matveev <stargrave@stargrave.org>
+// Copyright (C) 2021-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
Path string
rrr RawRecordReader
br *bufio.Reader
- offset int64
prevRec *Record
offsets []Offset
+ offset int64
}
func NewReader(warcPath string) (*Reader, error) {
return err
}
r.offset += int64(r.prevRec.HdrLen) + r.prevRec.Size
- for i := 0; i < 2; i++ {
+ for range 2 {
line, err := r.br.ReadString('\n')
if err != nil {
return err
hdrLen := len(line)
hdr := NewHeader()
for {
- line, err := r.br.ReadString('\n')
+ var line string
+ line, err = r.br.ReadString('\n')
if err != nil {
return nil, nil, err
}
// tofuproxy -- flexible HTTP/HTTPS proxy, TLS terminator, X.509 TOFU
// manager, WARC/geminispace browser
-// Copyright (C) 2021-2024 Sergey Matveev <stargrave@stargrave.org>
+// Copyright (C) 2021-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
)
type Record struct {
- WARCPath string
- Offset int64
- Size int64
-
- Hdr Header
- HdrLen int
- HdrLines []string
-
+ WARCPath string
+ Hdr Header
+ HdrLines []string
Continuations []*Record
+ Offset int64
+ Size int64
+ HdrLen int
}
func (rec *Record) URI() string {
// tofuproxy -- flexible HTTP/HTTPS proxy, TLS terminator, X.509 TOFU
// manager, WARC/geminispace browser
-// Copyright (C) 2021-2024 Sergey Matveev <stargrave@stargrave.org>
+// Copyright (C) 2021-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// tofuproxy -- flexible HTTP/HTTPS proxy, TLS terminator, X.509 TOFU
// manager, WARC/geminispace browser
-// Copyright (C) 2021-2024 Sergey Matveev <stargrave@stargrave.org>
+// Copyright (C) 2021-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
var uris map[string]*Record
var offsets []Offset
dec := gob.NewDecoder(fd)
- if err := dec.Decode(&uris); err != nil {
+ if err = dec.Decode(&uris); err != nil {
return err
}
- if err := dec.Decode(&offsets); err != nil {
+ if err = dec.Decode(&offsets); err != nil {
return err
}
WARCsM.Lock()
log.Println("loaded marshalled index:", warcPath+IndexExt)
return nil
}
- if err != nil && !errors.Is(err, fs.ErrNotExist) {
+ if !errors.Is(err, fs.ErrNotExist) {
return err
}
r, err := NewReader(warcPath)
fd, err := os.OpenFile(
p+tmpSuffix,
os.O_WRONLY|os.O_CREATE|os.O_EXCL,
- os.FileMode(0666),
+ os.FileMode(0o666),
)
if err != nil {
return err
// tofuproxy -- flexible HTTP/HTTPS proxy, TLS terminator, X.509 TOFU
// manager, WARC/geminispace browser
-// Copyright (C) 2021-2024 Sergey Matveev <stargrave@stargrave.org>
+// Copyright (C) 2021-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by