(R, trustProxy)
| 99 | } |
| 100 | |
| 101 | function buildRequestWithTrustProxy (R, trustProxy) { |
| 102 | const _Request = buildRegularRequest(R) |
| 103 | const proxyFn = getTrustProxyFn(trustProxy) |
| 104 | |
| 105 | // This is a more optimized version of decoration |
| 106 | _Request[kHasBeenDecorated] = true |
| 107 | |
| 108 | Object.defineProperties(_Request.prototype, { |
| 109 | ip: { |
| 110 | get () { |
| 111 | const addrs = proxyAddr.all(this.raw, proxyFn) |
| 112 | return addrs[addrs.length - 1] |
| 113 | } |
| 114 | }, |
| 115 | ips: { |
| 116 | get () { |
| 117 | return proxyAddr.all(this.raw, proxyFn) |
| 118 | } |
| 119 | }, |
| 120 | host: { |
| 121 | get () { |
| 122 | const socket = this.raw.socket |
| 123 | if (this.headers['x-forwarded-host'] && socket != null && proxyFn(socket.remoteAddress, 0)) { |
| 124 | return getLastEntryInMultiHeaderValue(this.headers['x-forwarded-host']) |
| 125 | } |
| 126 | /** |
| 127 | * The last fallback supports the following cases: |
| 128 | * 1. http.requireHostHeader === false |
| 129 | * 2. HTTP/1.0 without a Host Header |
| 130 | * 3. Headers schema that may remove the Host Header |
| 131 | */ |
| 132 | return this.headers.host ?? this.headers[':authority'] ?? '' |
| 133 | } |
| 134 | }, |
| 135 | protocol: { |
| 136 | get () { |
| 137 | const socket = this.raw.socket |
| 138 | if (this.headers['x-forwarded-proto'] && socket != null && proxyFn(socket.remoteAddress, 0)) { |
| 139 | return getLastEntryInMultiHeaderValue(this.headers['x-forwarded-proto']) |
| 140 | } |
| 141 | if (this.socket) { |
| 142 | return this.socket.encrypted ? 'https' : 'http' |
| 143 | } |
| 144 | } |
| 145 | } |
| 146 | }) |
| 147 | |
| 148 | return _Request |
| 149 | } |
| 150 | |
| 151 | function assertsRequestDecoration (request, name) { |
| 152 | if (!decorators.hasKey(request, name) && !decorators.exist(request, name)) { |
no test coverage detected