summaryrefslogtreecommitdiffstats
path: root/test/wpt/server/routes/network-partition-key.mjs
blob: f1203f7b63dcf68e43cb211bfd99cdcbf7869f28 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
const stash = new Map()

/**
 * @see https://github.com/web-platform-tests/wpt/blob/master/fetch/connection-pool/resources/network-partition-key.py
 * @param {Parameters<import('http').RequestListener>[0]} req
 * @param {Parameters<import('http').RequestListener>[1]} res
 * @param {URL} url
 */
export function route (req, res, { searchParams, port }) {
  res.setHeader('Cache-Control', 'no-store')

  const dispatch = searchParams.get('dispatch')
  const uuid = searchParams.get('uuid')
  const partitionId = searchParams.get('partition_id')

  if (!uuid || !dispatch || !partitionId) {
    res.statusCode = 404
    res.end('Invalid query parameters')
    return
  }

  let testFailed = false
  let requestCount = 0
  let connectionCount = 0

  if (searchParams.get('nocheck_partition') !== 'True') {
    const addressKey = `${req.socket.localAddress}|${port}`
    const serverState = stash.get(uuid) ?? {
      testFailed: false,
      requestCount: 0,
      connectionCount: 0
    }

    stash.delete(uuid)
    requestCount = serverState.requestCount + 1
    serverState.requestCount = requestCount

    if (Object.hasOwn(serverState, addressKey)) {
      if (serverState[addressKey] !== partitionId) {
        serverState.testFailed = true
      }
    } else {
      connectionCount = serverState.connectionCount + 1
      serverState.connectionCount = connectionCount
    }

    serverState[addressKey] = partitionId
    testFailed = serverState.testFailed
    stash.set(uuid, serverState)
  }

  const origin = req.headers.origin
  if (origin) {
    res.setHeader('Access-Control-Allow-Origin', origin)
    res.setHeader('Access-Control-Allow-Credentials', 'true')
  }

  if (req.method === 'OPTIONS') {
    return handlePreflight(req, res)
  }

  if (dispatch === 'fetch_file') {
    res.end()
    return
  }

  if (dispatch === 'check_partition') {
    const status = searchParams.get('status') ?? 200

    if (testFailed) {
      res.statusCode = status
      res.end('Multiple partition IDs used on a socket')
      return
    }

    let body = 'ok'
    if (searchParams.get('addcounter')) {
      body += `. Request was sent ${requestCount} times. ${connectionCount} connections were created.`
      res.statusCode = status
      res.end(body)
      return
    }
  }

  if (dispatch === 'clean_up') {
    stash.delete(uuid)
    res.statusCode = 200
    if (testFailed) {
      res.end('Test failed, but cleanup completed.')
    } else {
      res.end('cleanup complete')
    }

    return
  }

  res.statusCode = 404
  res.end('Unrecognized dispatch parameter: ' + dispatch)
}

/**
 * @param {Parameters<import('http').RequestListener>[0]} req
 * @param {Parameters<import('http').RequestListener>[1]} res
 */
function handlePreflight (req, res) {
  res.statusCode = 200
  res.setHeader('Access-Control-Allow-Methods', 'GET')
  res.setHeader('Access-Control-Allow-Headers', 'header-to-force-cors')
  res.setHeader('Access-Control-Max-Age', '86400')
  res.end('Preflight request')
}