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

supabase / storage / 22756907554

06 Mar 2026 09:14AM UTC coverage: 76.118% (+0.04%) from 76.078%
22756907554

Pull #783

github

web-flow
Merge 14342a733 into bb602aa99
Pull Request #783: fix: log connections that timeout, abort, or send unparsable data

3963 of 5677 branches covered (69.81%)

Branch coverage included in aggregate %.

181 of 205 new or added lines in 3 files covered. (88.29%)

3 existing lines in 1 file now uncovered.

26807 of 34747 relevant lines covered (77.15%)

187.33 hits per line

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

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

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

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

2✔
10
const MAX_HEADER_LINES = 100
2✔
11

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

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

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

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

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

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

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

8✔
67
    // Extract tenantId from x-forwarded-host if multitenant
8✔
68
    if (isMultitenant && requestXForwardedHostRegExp && result.headers['x-forwarded-host']) {
8!
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
    }
×
74
  } catch {
8!
NEW
75
    // Parsing failed - return defaults
×
NEW
76
    // This catches malformed UTF-8, regex errors, etc.
×
NEW
77
  }
×
78

8✔
79
  return result
8✔
80
}
8✔
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