• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

supabase / storage / 19147127865

06 Nov 2025 07:17PM UTC coverage: 77.584% (-0.2%) from 77.75%
19147127865

Pull #783

github

web-flow
Merge d0fa85cb1 into 6ba23e408
Pull Request #783: fix: log connections that timeout, abort, or send unparsable data

2025 of 2931 branches covered (69.09%)

Branch coverage included in aggregate %.

76 of 170 new or added lines in 3 files covered. (44.71%)

30 existing lines in 1 file now uncovered.

24663 of 31468 relevant lines covered (78.37%)

91.49 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

28.75
/src/internal/http/partial-http-parser.ts
1
import { getConfig } from '../../config'
1✔
2

1✔
3
const { isMultitenant, requestXForwardedHostRegExp } = getConfig()
1✔
4

1✔
5
const REQUEST_LINE_REGEX = /^([A-Z]+)\s+(\S+)(?:\s+HTTP\/[\d.]+)?$/i
1✔
6
const LINE_SPLIT_REGEX = /\r?\n/
1✔
7
// Validate header name (RFC 7230 token characters)
1✔
8
const HEADER_NAME_REGEX = /^[a-z0-9!#$%&'*+\-.^_`|~]+$/
1✔
9

1✔
10
const MAX_HEADER_LINES = 100
1✔
11

1✔
12
export interface PartialHttpData {
1✔
13
  method: string
1✔
14
  url: string
1✔
15
  headers: Record<string, string>
1✔
16
  tenantId: string
1✔
17
  length: number
1✔
18
}
1✔
19

1✔
20
/**
1✔
21
 * Parses partial HTTP request data from raw buffers.
1✔
22
 * Returns defaults if parsing fails.
1✔
23
 */
1✔
NEW
24
export function parsePartialHttp(dataChunks: Buffer[]): PartialHttpData {
×
NEW
25
  const result: PartialHttpData = {
×
NEW
26
    method: 'UNKNOWN',
×
NEW
27
    url: '/',
×
NEW
28
    headers: {},
×
NEW
29
    tenantId: isMultitenant ? 'unknown' : 'storage-single-tenant',
×
NEW
30
    length: 0,
×
NEW
31
  }
×
NEW
32

×
NEW
33
  if (dataChunks.length === 0) {
×
NEW
34
    return result
×
NEW
35
  }
×
NEW
36

×
NEW
37
  try {
×
NEW
38
    const partialData = Buffer.concat(dataChunks).toString('utf8')
×
NEW
39
    const lines = partialData.split(LINE_SPLIT_REGEX)
×
NEW
40
    result.length = partialData.length
×
NEW
41

×
NEW
42
    // Parse request line: "METHOD /path HTTP/version"
×
NEW
43
    if (lines[0]) {
×
NEW
44
      const requestLine = lines[0].match(REQUEST_LINE_REGEX)
×
NEW
45
      if (requestLine) {
×
NEW
46
        result.method = requestLine[1].toUpperCase()
×
NEW
47
        result.url = requestLine[2]
×
NEW
48
      }
×
NEW
49
    }
×
NEW
50

×
NEW
51
    // Parse headers (skip line 0, limit total lines)
×
NEW
52
    const headerLineLimit = Math.min(lines.length, MAX_HEADER_LINES + 1)
×
NEW
53
    for (let i = 1; i < headerLineLimit; i++) {
×
NEW
54
      const line = lines[i]
×
NEW
55
      if (!line || line.trim() === '') continue
×
NEW
56

×
NEW
57
      const colonIndex = line.indexOf(':')
×
NEW
58
      if (colonIndex > 0) {
×
NEW
59
        const field = line.substring(0, colonIndex).trim().toLowerCase()
×
NEW
60
        const value = line.substring(colonIndex + 1).trim()
×
NEW
61
        if (HEADER_NAME_REGEX.test(field)) {
×
NEW
62
          result.headers[field] = value
×
NEW
63
        }
×
NEW
64
      }
×
NEW
65
    }
×
NEW
66

×
NEW
67
    // Extract tenantId from x-forwarded-host if multitenant
×
NEW
68
    if (isMultitenant && requestXForwardedHostRegExp && result.headers['x-forwarded-host']) {
×
NEW
69
      const match = result.headers['x-forwarded-host'].match(requestXForwardedHostRegExp)
×
NEW
70
      if (match && match[1]) {
×
NEW
71
        result.tenantId = match[1]
×
NEW
72
      }
×
NEW
73
    }
×
NEW
74
  } catch {
×
NEW
75
    // Parsing failed - return defaults
×
NEW
76
    // This catches malformed UTF-8, regex errors, etc.
×
NEW
77
  }
×
NEW
78

×
NEW
79
  return result
×
NEW
80
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc