Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
seleniumhq
GitHub Repository: seleniumhq/selenium
Path: blob/trunk/javascript/selenium-webdriver/test/http/http_test.js
2885 views
1
// Licensed to the Software Freedom Conservancy (SFC) under one
2
// or more contributor license agreements. See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership. The SFC licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License. You may obtain a copy of the License at
8
//
9
// http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied. See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
18
'use strict'
19
20
const assert = require('node:assert')
21
const http = require('node:http')
22
const url = require('node:url')
23
24
const HttpClient = require('selenium-webdriver/http').HttpClient
25
const HttpRequest = require('selenium-webdriver/lib/http').Request
26
const Server = require('../../lib/test/httpserver').Server
27
28
describe('HttpClient', function () {
29
const server = new Server(function (req, res) {
30
// eslint-disable-next-line n/no-deprecated-api
31
const parsedUrl = url.parse(req.url)
32
33
if (req.method === 'GET' && req.url === '/echo') {
34
res.writeHead(200)
35
res.end(JSON.stringify(req.headers))
36
} else if (req.method === 'GET' && req.url === '/redirect') {
37
res.writeHead(303, { Location: server.url('/hello') })
38
res.end()
39
} else if (req.method === 'GET' && req.url === '/hello') {
40
res.writeHead(200, { 'content-type': 'text/plain' })
41
res.end('hello, world!')
42
} else if (req.method === 'GET' && req.url === '/chunked') {
43
res.writeHead(200, {
44
'content-type': 'text/html; charset=utf-8',
45
'transfer-encoding': 'chunked',
46
})
47
res.write('<!DOCTYPE html>')
48
setTimeout(() => res.end('<h1>Hello, world!</h1>'), 20)
49
} else if (req.method === 'GET' && req.url === '/badredirect') {
50
res.writeHead(303, {})
51
res.end()
52
} else if (req.method === 'GET' && req.url === '/protected') {
53
const denyAccess = function () {
54
res.writeHead(401, { 'WWW-Authenticate': 'Basic realm="test"' })
55
res.end('Access denied')
56
}
57
58
// eslint-disable-next-line no-useless-escape
59
const basicAuthRegExp = /^\s*basic\s+([a-z0-9\-\._~\+\/]+)=*\s*$/i
60
const auth = req.headers.authorization
61
const match = basicAuthRegExp.exec(auth || '')
62
if (!match) {
63
denyAccess()
64
return
65
}
66
67
const userNameAndPass = Buffer.from(match[1], 'base64').toString()
68
const parts = userNameAndPass.split(':', 2)
69
if (parts[0] !== 'genie' && parts[1] !== 'bottle') {
70
denyAccess()
71
return
72
}
73
74
res.writeHead(200, { 'content-type': 'text/plain' })
75
res.end('Access granted!')
76
} else if (req.method === 'GET' && parsedUrl.pathname && parsedUrl.pathname.endsWith('/proxy')) {
77
let headers = Object.assign({}, req.headers)
78
headers['x-proxy-request-uri'] = req.url
79
res.writeHead(200, headers)
80
res.end()
81
} else if (req.method === 'GET' && parsedUrl.pathname && parsedUrl.pathname.endsWith('/proxy/redirect')) {
82
let path = `/proxy${parsedUrl.search || ''}${parsedUrl.hash || ''}`
83
res.writeHead(303, { Location: path })
84
res.end()
85
} else {
86
res.writeHead(404, {})
87
res.end()
88
}
89
})
90
91
before(function () {
92
return server.start()
93
})
94
95
after(function () {
96
return server.stop()
97
})
98
99
it('can send a basic HTTP request', function () {
100
const request = new HttpRequest('GET', '/echo')
101
request.headers.set('Foo', 'Bar')
102
103
const agent = new http.Agent()
104
agent.maxSockets = 1 // Only making 1 request.
105
106
const client = new HttpClient(server.url(), agent)
107
return client.send(request).then(function (response) {
108
assert.strictEqual(200, response.status)
109
110
const headers = JSON.parse(response.body)
111
assert.strictEqual(headers['content-length'], '0')
112
assert.strictEqual(headers['connection'], 'keep-alive')
113
assert.strictEqual(headers['host'], server.host())
114
115
const regex = /^selenium\/.* \(js (windows|mac|linux)\)$/
116
assert.ok(regex.test(headers['user-agent']), `${headers['user-agent']} does not match ${regex}`)
117
118
assert.strictEqual(request.headers.get('Foo'), 'Bar')
119
assert.strictEqual(request.headers.get('Accept'), 'application/json; charset=utf-8')
120
assert.strictEqual(agent.keepAlive, false)
121
})
122
})
123
124
it('can send a basic HTTP request with custom user-agent via client_options', function () {
125
const request = new HttpRequest('GET', '/echo')
126
request.headers.set('Foo', 'Bar')
127
128
const agent = new http.Agent()
129
agent.maxSockets = 1 // Only making 1 request.
130
131
const client = new HttpClient(server.url(), agent, null, {
132
'user-agent': 'test',
133
})
134
135
return client.send(request).then(function (response) {
136
assert.strictEqual(200, response.status)
137
138
const headers = JSON.parse(response.body)
139
assert.strictEqual(headers['content-length'], '0')
140
assert.strictEqual(headers['connection'], 'keep-alive')
141
assert.strictEqual(headers['host'], server.host())
142
assert.strictEqual(headers['user-agent'], 'test')
143
144
assert.strictEqual(request.headers.get('Foo'), 'Bar')
145
assert.strictEqual(agent.keepAlive, false)
146
assert.strictEqual(request.headers.get('Accept'), 'application/json; charset=utf-8')
147
})
148
})
149
150
it('can send a basic HTTP request with keep-alive being set to true via client_options', function () {
151
const request = new HttpRequest('GET', '/echo')
152
request.headers.set('Foo', 'Bar')
153
154
const agent = new http.Agent()
155
agent.maxSockets = 1 // Only making 1 request.
156
157
const client = new HttpClient(server.url(), agent, null, {
158
'keep-alive': 'true',
159
})
160
161
return client.send(request).then(function (response) {
162
assert.strictEqual(200, response.status)
163
164
const headers = JSON.parse(response.body)
165
assert.strictEqual(headers['content-length'], '0')
166
assert.strictEqual(headers['connection'], 'keep-alive')
167
assert.strictEqual(headers['host'], server.host())
168
169
const regex = /^selenium\/.* \(js (windows|mac|linux)\)$/
170
assert.ok(regex.test(headers['user-agent']), `${headers['user-agent']} does not match ${regex}`)
171
172
assert.strictEqual(request.headers.get('Foo'), 'Bar')
173
assert.strictEqual(agent.keepAlive, true)
174
assert.strictEqual(request.headers.get('Accept'), 'application/json; charset=utf-8')
175
})
176
})
177
178
it('handles chunked responses', function () {
179
let request = new HttpRequest('GET', '/chunked')
180
181
let client = new HttpClient(server.url())
182
return client.send(request).then((response) => {
183
assert.strictEqual(200, response.status)
184
assert.strictEqual(response.body, '<!DOCTYPE html><h1>Hello, world!</h1>')
185
})
186
})
187
188
it('can use basic auth', function () {
189
// eslint-disable-next-line n/no-deprecated-api
190
const parsed = url.parse(server.url())
191
parsed.auth = 'genie:bottle'
192
193
const client = new HttpClient(url.format(parsed))
194
const request = new HttpRequest('GET', '/protected')
195
return client.send(request).then(function (response) {
196
assert.strictEqual(200, response.status)
197
assert.strictEqual(response.headers.get('content-type'), 'text/plain')
198
assert.strictEqual(response.body, 'Access granted!')
199
})
200
})
201
202
it('fails requests missing required basic auth', function () {
203
const client = new HttpClient(server.url())
204
const request = new HttpRequest('GET', '/protected')
205
return client.send(request).then(function (response) {
206
assert.strictEqual(401, response.status)
207
assert.strictEqual(response.body, 'Access denied')
208
})
209
})
210
211
it('automatically follows redirects', function () {
212
const request = new HttpRequest('GET', '/redirect')
213
const client = new HttpClient(server.url())
214
return client.send(request).then(function (response) {
215
assert.strictEqual(200, response.status)
216
assert.strictEqual(response.headers.get('content-type'), 'text/plain')
217
assert.strictEqual(response.body, 'hello, world!')
218
})
219
})
220
221
it('handles malformed redirect responses', function () {
222
const request = new HttpRequest('GET', '/badredirect')
223
const client = new HttpClient(server.url())
224
return client.send(request).then(assert.fail, function (err) {
225
assert.ok(/Failed to parse "Location"/.test(err.message), 'Not the expected error: ' + err.message)
226
})
227
})
228
229
describe('with proxy', function () {
230
it('sends request to proxy with absolute URI', function () {
231
const request = new HttpRequest('GET', '/proxy')
232
const client = new HttpClient('http://another.server.com', undefined, server.url())
233
return client.send(request).then(function (response) {
234
assert.strictEqual(200, response.status)
235
assert.strictEqual(response.headers.get('host'), 'another.server.com')
236
assert.strictEqual(response.headers.get('x-proxy-request-uri'), 'http://another.server.com/proxy')
237
})
238
})
239
240
it('uses proxy when following redirects', function () {
241
const request = new HttpRequest('GET', '/proxy/redirect')
242
const client = new HttpClient('http://another.server.com', undefined, server.url())
243
return client.send(request).then(function (response) {
244
assert.strictEqual(200, response.status)
245
assert.strictEqual(response.headers.get('host'), 'another.server.com')
246
assert.strictEqual(response.headers.get('x-proxy-request-uri'), 'http://another.server.com/proxy')
247
})
248
})
249
250
it('includes search and hash in redirect URI', function () {
251
const request = new HttpRequest('GET', '/proxy/redirect?foo#bar')
252
const client = new HttpClient('http://another.server.com', undefined, server.url())
253
return client.send(request).then(function (response) {
254
assert.strictEqual(200, response.status)
255
assert.strictEqual(response.headers.get('host'), 'another.server.com')
256
assert.strictEqual(response.headers.get('x-proxy-request-uri'), 'http://another.server.com/proxy?foo#bar')
257
})
258
})
259
})
260
})
261
262