mirror of
https://github.com/lunchcat/sif.git
synced 2026-07-28 14:37:01 -07:00
fix(scan): stop one over-long url from dropping the wayback feed (#321)
the wayback line scanner capped each line at 1mb, so a single archived url with a huge query string made scanner.Err return ErrTooLong and the whole feed was discarded. read lines without a per-line cap, still bounded by the passiveMaxBytes read limit.
This commit is contained in:
+14
-10
@@ -181,17 +181,21 @@ func fetchWayback(ctx context.Context, client *http.Client, domain string) ([]st
|
||||
}
|
||||
|
||||
var urls []string
|
||||
scanner := bufio.NewScanner(strings.NewReader(string(body)))
|
||||
// historical urls can be long; give the scanner a generous line buffer.
|
||||
scanner.Buffer(make([]byte, 0, 64*1024), 1024*1024)
|
||||
for scanner.Scan() {
|
||||
line := strings.TrimSpace(scanner.Text())
|
||||
if line != "" {
|
||||
urls = append(urls, line)
|
||||
// read line by line without a per-line cap: a single archived url with a
|
||||
// huge query string must not abort the whole feed. overall size is already
|
||||
// bounded by the passiveMaxBytes read limit.
|
||||
reader := bufio.NewReader(strings.NewReader(string(body)))
|
||||
for {
|
||||
line, err := reader.ReadString('\n')
|
||||
if trimmed := strings.TrimSpace(line); trimmed != "" {
|
||||
urls = append(urls, trimmed)
|
||||
}
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
return nil, fmt.Errorf("read wayback lines: %w", err)
|
||||
}
|
||||
}
|
||||
if err := scanner.Err(); err != nil {
|
||||
return nil, fmt.Errorf("read wayback lines: %w", err)
|
||||
}
|
||||
return urls, nil
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ package scan
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
@@ -168,6 +169,30 @@ func TestPassive_ScopesSubdomainsToTarget(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestPassive_WaybackLongLineKeepsFeed(t *testing.T) {
|
||||
// a single archived url with a huge query string (data:/base64 blobs do
|
||||
// occur) must not discard every other harvested url.
|
||||
longURL := "http://example.com/?blob=" + strings.Repeat("a", 2*1024*1024)
|
||||
wayback := longURL + "\n" +
|
||||
"http://example.com/keep-one\n" +
|
||||
"http://example.com/keep-two\n"
|
||||
fixtureServer(t, "[]", "[]", wayback)
|
||||
|
||||
result, err := Passive("https://example.com", 5*time.Second, "")
|
||||
if err != nil {
|
||||
t.Fatalf("Passive: %v", err)
|
||||
}
|
||||
|
||||
for _, want := range []string{"http://example.com/keep-one", "http://example.com/keep-two"} {
|
||||
if !urlsContain(result.URLs, want) {
|
||||
t.Errorf("over-long wayback line dropped the feed; missing %q, got %d urls", want, len(result.URLs))
|
||||
}
|
||||
}
|
||||
if !urlsContain(result.URLs, longURL) {
|
||||
t.Errorf("the over-long url itself was dropped, got %d urls", len(result.URLs))
|
||||
}
|
||||
}
|
||||
|
||||
func TestNormalizeHost(t *testing.T) {
|
||||
tests := []struct {
|
||||
in string
|
||||
|
||||
Reference in New Issue
Block a user