Skip to content

Commit 5cd58dc

Browse files
committed
Fail with a more descriptive error if the server returns a malformed redirect
1 parent 3f2e2c8 commit 5cd58dc

File tree

3 files changed

+98
-1
lines changed

3 files changed

+98
-1
lines changed

javascript/node/selenium-webdriver/CHANGES.md

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
* Removed deprecated functions `Promise#addCallback()`,
44
`Promise#addCallbacks()`, `Promise#addErrback()`, and `Promise#addBoth()`.
5+
* Fail with a more descriptive error if the server returns a malformed redirect
56
* FIXED: 7300: Connect to ChromeDriver using the loopback address since
67
ChromeDriver 2.10.267517 binds to localhost by default.
78
* FIXED: 7339: Preserve wrapped test function's string representation for

javascript/node/selenium-webdriver/http/index.js

+9-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,15 @@ HttpClient.prototype.send = function(httpRequest, callback) {
8686
var sendRequest = function(options, callback, opt_data) {
8787
var request = http.request(options, function(response) {
8888
if (response.statusCode == 302 || response.statusCode == 303) {
89-
var location = url.parse(response.headers['location']);
89+
try {
90+
var location = url.parse(response.headers['location']);
91+
} catch (ex) {
92+
callback(Error(
93+
'Failed to parse "Location" header for server redirect: ' +
94+
ex.message + '\nResponse was: \n' +
95+
new HttpResponse(response.statusCode, response.headers, '')));
96+
return;
97+
}
9098

9199
if (!location.hostname) {
92100
location.hostname = options.host;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
// Copyright 2014 Selenium committers
2+
// Copyright 2014 Software Freedom Conservancy
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
16+
var assert = require('assert');
17+
18+
var HttpClient = require('../../http').HttpClient;
19+
var HttpRequest = require('../../_base').require('webdriver.http.Request');
20+
var Server = require('../../lib/test/httpserver').Server;
21+
var promise = require('../..').promise;
22+
var test = require('../../lib/test');
23+
24+
describe('HttpClient', function() {
25+
var server = new Server(function(req, res) {
26+
if (req.method == 'GET' && req.url == '/echo') {
27+
res.writeHead(200, req.headers);
28+
res.end();
29+
30+
} else if (req.method == 'GET' && req.url == '/redirect') {
31+
res.writeHead(303, {'Location': server.url('/hello')});
32+
res.end();
33+
34+
} else if (req.method == 'GET' && req.url == '/hello') {
35+
res.writeHead(200, {'content-type': 'text/plain'});
36+
res.end('hello, world!');
37+
38+
} else if (req.method == 'GET' && req.url == '/badredirect') {
39+
res.writeHead(303, {});
40+
res.end();
41+
42+
} else {
43+
res.writeHead(404, {});
44+
res.end();
45+
}
46+
});
47+
48+
test.before(server.start.bind(server));
49+
test.after(server.stop.bind(server));
50+
51+
test.it('can send a basic HTTP request', function() {
52+
var request = new HttpRequest('GET', '/echo');
53+
request.headers['Foo'] = 'Bar';
54+
55+
var client = new HttpClient(server.url());
56+
return promise.checkedNodeCall(client.send.bind(client, request))
57+
.then(function(response) {
58+
assert.equal(200, response.status);
59+
assert.equal(
60+
'application/json; charset=utf-8', response.headers['accept']);
61+
assert.equal('Bar', response.headers['foo']);
62+
assert.equal('0', response.headers['content-length']);
63+
assert.equal('keep-alive', response.headers['connection']);
64+
assert.equal(server.host(), response.headers['host']);
65+
});
66+
});
67+
68+
test.it('automatically follows redirects', function() {
69+
var request = new HttpRequest('GET', '/redirect');
70+
var client = new HttpClient(server.url());
71+
return promise.checkedNodeCall(client.send.bind(client, request))
72+
.then(function(response) {
73+
assert.equal(200, response.status);
74+
assert.equal('text/plain', response.headers['content-type']);
75+
assert.equal('hello, world!', response.body);
76+
});
77+
});
78+
79+
test.it('handles malformed redirect responses', function() {
80+
var request = new HttpRequest('GET', '/badredirect');
81+
var client = new HttpClient(server.url());
82+
return promise.checkedNodeCall(client.send.bind(client, request)).
83+
thenCatch(function(err) {
84+
assert.ok(/Failed to parse "Location"/.test(err.message),
85+
'Not the expected error: ' + err.message);
86+
});
87+
});
88+
});

0 commit comments

Comments
 (0)