selenium-webdriver 0.0.24 → 0.0.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/{common/src/rb/CHANGES → CHANGES} +13 -0
- data/{common/src/rb/README → README} +1 -1
- data/{common/src/rb/lib → lib}/selenium-webdriver.rb +0 -0
- data/{common/src/rb/lib → lib}/selenium/webdriver.rb +2 -1
- data/{common/src/rb/lib → lib}/selenium/webdriver/bridge_helper.rb +0 -0
- data/{common/src/rb/lib → lib}/selenium/webdriver/child_process.rb +0 -0
- data/{chrome/src/rb/lib → lib}/selenium/webdriver/chrome.rb +0 -0
- data/{chrome/src/rb/lib → lib}/selenium/webdriver/chrome/bridge.rb +2 -2
- data/{chrome/src/rb/lib → lib}/selenium/webdriver/chrome/command_executor.rb +0 -0
- data/lib/selenium/webdriver/chrome/extension.zip +0 -0
- data/{chrome/src/rb/lib → lib}/selenium/webdriver/chrome/launcher.rb +26 -20
- data/{common/src/rb/lib → lib}/selenium/webdriver/core_ext/dir.rb +0 -0
- data/{common/src/rb/lib → lib}/selenium/webdriver/core_ext/string.rb +0 -0
- data/{common/src/rb/lib → lib}/selenium/webdriver/driver.rb +0 -0
- data/{common/src/rb/lib → lib}/selenium/webdriver/driver_extensions/takes_screenshot.rb +0 -0
- data/{common/src/rb/lib → lib}/selenium/webdriver/element.rb +0 -0
- data/{common/src/rb/lib → lib}/selenium/webdriver/error.rb +0 -0
- data/{common/src/rb/lib → lib}/selenium/webdriver/file_reaper.rb +2 -1
- data/{common/src/rb/lib → lib}/selenium/webdriver/find.rb +0 -0
- data/{firefox/src/rb/lib → lib}/selenium/webdriver/firefox.rb +2 -1
- data/{firefox/src/rb/lib → lib}/selenium/webdriver/firefox/binary.rb +32 -6
- data/{firefox/src/rb/lib → lib}/selenium/webdriver/firefox/bridge.rb +0 -0
- data/lib/selenium/webdriver/firefox/extension/webdriver.xpi +0 -0
- data/{firefox/src/rb/lib → lib}/selenium/webdriver/firefox/launcher.rb +0 -0
- data/lib/selenium/webdriver/firefox/native/linux/amd64/x_ignore_nofocus.so +0 -0
- data/lib/selenium/webdriver/firefox/native/linux/x86/x_ignore_nofocus.so +0 -0
- data/{firefox/src/rb/lib → lib}/selenium/webdriver/firefox/profile.rb +37 -72
- data/{firefox/src/rb/lib → lib}/selenium/webdriver/firefox/profiles_ini.rb +0 -0
- data/{firefox/src/rb/lib → lib}/selenium/webdriver/firefox/util.rb +0 -0
- data/{jobbie/src/rb/lib → lib}/selenium/webdriver/ie.rb +2 -2
- data/{jobbie/src/rb/lib → lib}/selenium/webdriver/ie/bridge.rb +7 -2
- data/{jobbie/src/rb/lib → lib}/selenium/webdriver/ie/lib.rb +0 -0
- data/{jobbie/prebuilt/Win32/Release → lib/selenium/webdriver/ie/native/win32}/InternetExplorerDriver.dll +0 -0
- data/lib/selenium/webdriver/ie/native/x64/InternetExplorerDriver.dll +0 -0
- data/{jobbie/src/rb/lib → lib}/selenium/webdriver/ie/util.rb +0 -0
- data/{common/src/rb/lib → lib}/selenium/webdriver/keys.rb +0 -0
- data/{common/src/rb/lib → lib}/selenium/webdriver/navigation.rb +0 -0
- data/{common/src/rb/lib → lib}/selenium/webdriver/options.rb +0 -0
- data/{common/src/rb/lib → lib}/selenium/webdriver/platform.rb +5 -1
- data/{remote/client/src/rb/lib → lib}/selenium/webdriver/remote.rb +0 -0
- data/{remote/client/src/rb/lib → lib}/selenium/webdriver/remote/bridge.rb +0 -0
- data/{remote/client/src/rb/lib → lib}/selenium/webdriver/remote/capabilities.rb +0 -0
- data/{remote/client/src/rb/lib → lib}/selenium/webdriver/remote/commands.rb +0 -0
- data/{remote/client/src/rb/lib → lib}/selenium/webdriver/remote/http/common.rb +0 -0
- data/{remote/client/src/rb/lib → lib}/selenium/webdriver/remote/http/curb.rb +0 -0
- data/{remote/client/src/rb/lib → lib}/selenium/webdriver/remote/http/default.rb +5 -1
- data/{remote/client/src/rb/lib → lib}/selenium/webdriver/remote/response.rb +0 -0
- data/{remote/client/src/rb/lib → lib}/selenium/webdriver/remote/server_error.rb +0 -0
- data/{common/src/rb/lib → lib}/selenium/webdriver/target_locator.rb +0 -0
- data/{common/src/rb/lib → lib}/selenium/webdriver/timeouts.rb +0 -0
- data/lib/selenium/webdriver/zip_helper.rb +30 -0
- metadata +73 -214
- data/COPYING +0 -204
- data/chrome/prebuilt/Win32/Release/npchromedriver.dll +0 -0
- data/chrome/prebuilt/x64/Release/npchromedriver.dll +0 -0
- data/chrome/src/extension/background.html +0 -9
- data/chrome/src/extension/background.js +0 -1029
- data/chrome/src/extension/content_script.js +0 -1488
- data/chrome/src/extension/icons/busy.png +0 -0
- data/chrome/src/extension/icons/free.png +0 -0
- data/chrome/src/extension/manifest-nonwin.json +0 -19
- data/chrome/src/extension/manifest-win.json +0 -20
- data/chrome/src/extension/utils.js +0 -231
- data/common/src/js/abstractcommandprocessor.js +0 -132
- data/common/src/js/asserts.js +0 -296
- data/common/src/js/by.js +0 -149
- data/common/src/js/command.js +0 -380
- data/common/src/js/core/Blank.html +0 -7
- data/common/src/js/core/InjectedRemoteRunner.html +0 -8
- data/common/src/js/core/RemoteRunner.html +0 -101
- data/common/src/js/core/SeleniumLog.html +0 -109
- data/common/src/js/core/TestPrompt.html +0 -145
- data/common/src/js/core/TestRunner-splash.html +0 -55
- data/common/src/js/core/TestRunner.html +0 -165
- data/common/src/js/core/icons/all.png +0 -0
- data/common/src/js/core/icons/continue.png +0 -0
- data/common/src/js/core/icons/continue_disabled.png +0 -0
- data/common/src/js/core/icons/pause.png +0 -0
- data/common/src/js/core/icons/pause_disabled.png +0 -0
- data/common/src/js/core/icons/selected.png +0 -0
- data/common/src/js/core/icons/step.png +0 -0
- data/common/src/js/core/icons/step_disabled.png +0 -0
- data/common/src/js/core/lib/cssQuery/cssQuery-p.js +0 -6
- data/common/src/js/core/lib/cssQuery/src/cssQuery-level2.js +0 -142
- data/common/src/js/core/lib/cssQuery/src/cssQuery-level3.js +0 -150
- data/common/src/js/core/lib/cssQuery/src/cssQuery-standard.js +0 -53
- data/common/src/js/core/lib/cssQuery/src/cssQuery.js +0 -356
- data/common/src/js/core/lib/prototype.js +0 -2006
- data/common/src/js/core/lib/scriptaculous/builder.js +0 -101
- data/common/src/js/core/lib/scriptaculous/controls.js +0 -815
- data/common/src/js/core/lib/scriptaculous/dragdrop.js +0 -915
- data/common/src/js/core/lib/scriptaculous/effects.js +0 -958
- data/common/src/js/core/lib/scriptaculous/scriptaculous.js +0 -47
- data/common/src/js/core/lib/scriptaculous/slider.js +0 -283
- data/common/src/js/core/lib/scriptaculous/unittest.js +0 -383
- data/common/src/js/core/lib/snapsie.js +0 -91
- data/common/src/js/core/scripts/find_matching_child.js +0 -69
- data/common/src/js/core/scripts/htmlutils.js +0 -8716
- data/common/src/js/core/scripts/injection.html +0 -72
- data/common/src/js/core/scripts/selenium-api.js +0 -3291
- data/common/src/js/core/scripts/selenium-browserbot.js +0 -2457
- data/common/src/js/core/scripts/selenium-browserdetect.js +0 -153
- data/common/src/js/core/scripts/selenium-commandhandlers.js +0 -379
- data/common/src/js/core/scripts/selenium-executionloop.js +0 -175
- data/common/src/js/core/scripts/selenium-logging.js +0 -148
- data/common/src/js/core/scripts/selenium-remoterunner.js +0 -695
- data/common/src/js/core/scripts/selenium-testrunner.js +0 -1362
- data/common/src/js/core/scripts/selenium-version.js +0 -5
- data/common/src/js/core/scripts/ui-doc.html +0 -808
- data/common/src/js/core/scripts/ui-element.js +0 -1644
- data/common/src/js/core/scripts/ui-map-sample.js +0 -979
- data/common/src/js/core/scripts/user-extensions.js +0 -3
- data/common/src/js/core/scripts/user-extensions.js.sample +0 -75
- data/common/src/js/core/scripts/xmlextras.js +0 -153
- data/common/src/js/core/selenium-logo.png +0 -0
- data/common/src/js/core/selenium-test.css +0 -43
- data/common/src/js/core/selenium.css +0 -316
- data/common/src/js/core/xpath/dom.js +0 -566
- data/common/src/js/core/xpath/javascript-xpath-0.1.11.js +0 -2816
- data/common/src/js/core/xpath/util.js +0 -549
- data/common/src/js/core/xpath/xmltoken.js +0 -149
- data/common/src/js/core/xpath/xpath.js +0 -2481
- data/common/src/js/extension/README +0 -2
- data/common/src/js/extension/dommessenger.js +0 -152
- data/common/src/js/factory.js +0 -55
- data/common/src/js/future.js +0 -141
- data/common/src/js/jsunit.js +0 -40
- data/common/src/js/jsunit/app/css/jsUnitStyle.css +0 -50
- data/common/src/js/jsunit/app/css/readme +0 -10
- data/common/src/js/jsunit/app/emptyPage.html +0 -11
- data/common/src/js/jsunit/app/jsUnitCore.js +0 -534
- data/common/src/js/jsunit/app/jsUnitMockTimeout.js +0 -81
- data/common/src/js/jsunit/app/jsUnitTestManager.js +0 -705
- data/common/src/js/jsunit/app/jsUnitTestSuite.js +0 -44
- data/common/src/js/jsunit/app/jsUnitTracer.js +0 -102
- data/common/src/js/jsunit/app/jsUnitVersionCheck.js +0 -59
- data/common/src/js/jsunit/app/main-counts-errors.html +0 -12
- data/common/src/js/jsunit/app/main-counts-failures.html +0 -13
- data/common/src/js/jsunit/app/main-counts-runs.html +0 -13
- data/common/src/js/jsunit/app/main-counts.html +0 -21
- data/common/src/js/jsunit/app/main-data.html +0 -178
- data/common/src/js/jsunit/app/main-errors.html +0 -23
- data/common/src/js/jsunit/app/main-frame.html +0 -19
- data/common/src/js/jsunit/app/main-loader.html +0 -45
- data/common/src/js/jsunit/app/main-progress.html +0 -25
- data/common/src/js/jsunit/app/main-results.html +0 -67
- data/common/src/js/jsunit/app/main-status.html +0 -13
- data/common/src/js/jsunit/app/testContainer.html +0 -16
- data/common/src/js/jsunit/app/testContainerController.html +0 -77
- data/common/src/js/jsunit/app/xbDebug.js +0 -306
- data/common/src/js/jsunit/changelog.txt +0 -60
- data/common/src/js/jsunit/css/jsUnitStyle.css +0 -83
- data/common/src/js/jsunit/images/green.gif +0 -0
- data/common/src/js/jsunit/images/logo_jsunit.gif +0 -0
- data/common/src/js/jsunit/images/powerby-transparent.gif +0 -0
- data/common/src/js/jsunit/images/red.gif +0 -0
- data/common/src/js/jsunit/licenses/JDOM_license.txt +0 -56
- data/common/src/js/jsunit/licenses/Jetty_license.html +0 -213
- data/common/src/js/jsunit/licenses/MPL-1.1.txt +0 -470
- data/common/src/js/jsunit/licenses/gpl-2.txt +0 -340
- data/common/src/js/jsunit/licenses/index.html +0 -141
- data/common/src/js/jsunit/licenses/lgpl-2.1.txt +0 -504
- data/common/src/js/jsunit/licenses/mpl-tri-license-c.txt +0 -35
- data/common/src/js/jsunit/licenses/mpl-tri-license-html.txt +0 -35
- data/common/src/js/jsunit/readme.txt +0 -19
- data/common/src/js/jsunit/testRunner.html +0 -167
- data/common/src/js/jsunit/version.txt +0 -1
- data/common/src/js/key.js +0 -117
- data/common/src/js/localcommandprocessor.js +0 -171
- data/common/src/js/testcase.js +0 -219
- data/common/src/js/timing.js +0 -89
- data/common/src/js/webdriver.js +0 -860
- data/common/src/js/webelement.js +0 -483
- data/firefox/prebuilt/Win32/Release/webdriver-firefox.dll +0 -0
- data/firefox/prebuilt/amd64/libnoblur64.so +0 -0
- data/firefox/prebuilt/i386/libnoblur.so +0 -0
- data/firefox/prebuilt/linux/Release/libwebdriver-firefox.so +0 -0
- data/firefox/prebuilt/linux64/Release/libwebdriver-firefox.so +0 -0
- data/firefox/prebuilt/nsICommandProcessor.xpt +0 -0
- data/firefox/prebuilt/nsINativeEvents.xpt +0 -0
- data/firefox/prebuilt/nsIResponseHandler.xpt +0 -0
- data/firefox/src/extension/chrome.manifest +0 -3
- data/firefox/src/extension/components/badCertListener.js +0 -295
- data/firefox/src/extension/components/dispatcher.js +0 -495
- data/firefox/src/extension/components/driver-component.js +0 -130
- data/firefox/src/extension/components/errorcode.js +0 -70
- data/firefox/src/extension/components/firefoxDriver.js +0 -831
- data/firefox/src/extension/components/json2.js +0 -273
- data/firefox/src/extension/components/keytest.html +0 -554
- data/firefox/src/extension/components/nsCommandProcessor.js +0 -684
- data/firefox/src/extension/components/promptService.js +0 -208
- data/firefox/src/extension/components/request.js +0 -219
- data/firefox/src/extension/components/response.js +0 -276
- data/firefox/src/extension/components/screenshooter.js +0 -81
- data/firefox/src/extension/components/session.js +0 -314
- data/firefox/src/extension/components/sessionstore.js +0 -226
- data/firefox/src/extension/components/socketListener.js +0 -435
- data/firefox/src/extension/components/utils.js +0 -1335
- data/firefox/src/extension/components/webLoadingListener.js +0 -57
- data/firefox/src/extension/components/webdriverserver.js +0 -110
- data/firefox/src/extension/components/wrappedElement.js +0 -706
- data/firefox/src/extension/content/fxdriver.xul +0 -30
- data/firefox/src/extension/content/server.js +0 -95
- data/firefox/src/extension/idl/nsICommandProcessor.idl +0 -38
- data/firefox/src/extension/idl/nsIResponseHandler.idl +0 -34
- data/firefox/src/extension/install.rdf +0 -29
- data/jobbie/prebuilt/x64/Release/InternetExplorerDriver.dll +0 -0
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,295 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
Copyright 2007-2009 WebDriver committers
|
|
3
|
-
Copyright 2007-2009 Google Inc.
|
|
4
|
-
Portions copyright 2007 ThoughtWorks, Inc
|
|
5
|
-
|
|
6
|
-
Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
-
you may not use this file except in compliance with the License.
|
|
8
|
-
You may obtain a copy of the License at
|
|
9
|
-
|
|
10
|
-
http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
-
|
|
12
|
-
Unless required by applicable law or agreed to in writing, software
|
|
13
|
-
distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
-
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
-
See the License for the specific language governing permissions and
|
|
16
|
-
limitations under the License.
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* @fileOverview Contains a Javascript implementation for
|
|
21
|
-
* a custom nsICertOverrideService. This class will forward requests to the
|
|
22
|
-
* original certificate override service - unless it was told to accept all
|
|
23
|
-
* of them.
|
|
24
|
-
*/
|
|
25
|
-
|
|
26
|
-
const CC = Components.classes;
|
|
27
|
-
const CI = Components.interfaces;
|
|
28
|
-
|
|
29
|
-
const CONSOLE = CC["@mozilla.org/consoleservice;1"].
|
|
30
|
-
getService(CI["nsIConsoleService"]);
|
|
31
|
-
|
|
32
|
-
function localdump(message) {
|
|
33
|
-
try {
|
|
34
|
-
CONSOLE.logStringMessage(message + "\n");
|
|
35
|
-
} catch (e) {
|
|
36
|
-
dump(message + "\n");
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
function getPreferenceFromProfile(prefName, prefDefaultValue) {
|
|
41
|
-
var prefs =
|
|
42
|
-
CC["@mozilla.org/preferences-service;1"].getService(CI["nsIPrefBranch"]);
|
|
43
|
-
|
|
44
|
-
if (!prefs.prefHasUserValue(prefName)) {
|
|
45
|
-
localdump(prefName + ' not set; defaulting to ' + prefDefaultValue);
|
|
46
|
-
return prefDefaultValue;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
var prefValue = prefs.getBoolPref(prefName);
|
|
50
|
-
localdump("Found preference for " + prefName + ": " + prefValue);
|
|
51
|
-
|
|
52
|
-
return prefValue;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
function shouldAcceptUntrustedCerts() {
|
|
56
|
-
return getPreferenceFromProfile("webdriver_accept_untrusted_certs", true);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
function shouldAssumeUntrustedIssuer() {
|
|
60
|
-
return getPreferenceFromProfile("webdriver_assume_untrusted_issuer", true);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
function WdCertOverrideService() {
|
|
64
|
-
// Defaults to true - accepting untrusted certificates.
|
|
65
|
-
// This puts the module into effect - setting it to false
|
|
66
|
-
// will delegate all calls to the original service.
|
|
67
|
-
this.acceptAll = shouldAcceptUntrustedCerts();
|
|
68
|
-
|
|
69
|
-
// If untrusted issuer is set to false by the user,
|
|
70
|
-
// the initial bitmask will not include ERROR_UNTRUSTED.
|
|
71
|
-
//
|
|
72
|
-
// See the javadoc for FirefoxProfile and documentation
|
|
73
|
-
// for fillNeededBits for further explanation.
|
|
74
|
-
var untrusted_issuer = shouldAssumeUntrustedIssuer();
|
|
75
|
-
if (untrusted_issuer) {
|
|
76
|
-
this.default_bits = this.ERROR_UNTRUSTED;
|
|
77
|
-
} else {
|
|
78
|
-
this.default_bits = 0;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
localdump("Accept untrusted certificates: " + this.acceptAll);
|
|
82
|
-
|
|
83
|
-
// UUID of the original implementor of this service.
|
|
84
|
-
var ORIGINAL_OVERRIDE_SERVICE_ID = "{67ba681d-5485-4fff-952c-2ee337ffdcd6}";
|
|
85
|
-
|
|
86
|
-
// Keep a reference to the original bad certificate listener.
|
|
87
|
-
var originalService = Components.classesByID[ORIGINAL_OVERRIDE_SERVICE_ID].
|
|
88
|
-
getService();
|
|
89
|
-
|
|
90
|
-
this.origListener_ =
|
|
91
|
-
originalService.QueryInterface(
|
|
92
|
-
Components.interfaces.nsICertOverrideService);
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
// Constants needed since WdCertOverrideService implements
|
|
96
|
-
// nsICertOverrideService
|
|
97
|
-
WdCertOverrideService.prototype = {
|
|
98
|
-
ERROR_UNTRUSTED: 1,
|
|
99
|
-
ERROR_MISMATCH: 2,
|
|
100
|
-
ERROR_TIME: 4
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
// Returns the bit needed to mask if the certificate has expired, 0 otherwise.
|
|
104
|
-
WdCertOverrideService.prototype.certificateExpiredBit_ = function
|
|
105
|
-
(theCert, verification_result) {
|
|
106
|
-
if ((verification_result & theCert.CERT_EXPIRED) != 0) {
|
|
107
|
-
localdump("Certificate expired.");
|
|
108
|
-
return this.ERROR_TIME;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
return 0;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// Returns the bit needed to mask untrusted issuers, 0 otherwise.
|
|
115
|
-
// Note that this bit is already set by default in default_bits
|
|
116
|
-
WdCertOverrideService.prototype.certificateIssuerUntrusted_ = function
|
|
117
|
-
(theCert, verification_result) {
|
|
118
|
-
if (((verification_result & theCert.ISSUER_UNKNOWN) != 0) ||
|
|
119
|
-
((verification_result & theCert.ISSUER_NOT_TRUSTED) != 0) ||
|
|
120
|
-
((verification_result & theCert.CERT_NOT_TRUSTED) != 0) ||
|
|
121
|
-
((verification_result & theCert.INVALID_CA) != 0)) {
|
|
122
|
-
localdump("Certificate issuer unknown.");
|
|
123
|
-
return this.ERROR_UNTRUSTED;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
return 0;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
// Returns the bit needed to mask mismatch between actual hostname
|
|
130
|
-
// and the hostname the certificate was issued for, 0 otherwise.
|
|
131
|
-
WdCertOverrideService.prototype.certificateHostnameMismatch_ = function
|
|
132
|
-
(theCert, aHost) {
|
|
133
|
-
commonNameRE = new RegExp(theCert.commonName.replace('*', '\\w+'));
|
|
134
|
-
if (aHost.match(commonNameRE) === null) {
|
|
135
|
-
localdump("Host name mismatch: cert: " + theCert.commonName + " get: " + aHost);
|
|
136
|
-
return this.ERROR_MISMATCH;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
return 0;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
// Given a certificate and the host it was received for, fill in the bits
|
|
143
|
-
// needed to accept this certificate for this host, even though the
|
|
144
|
-
// certificate is invalid.
|
|
145
|
-
//
|
|
146
|
-
// Note that the bitmask has to be accurate: At the moment, Firefox expects
|
|
147
|
-
// the returned bitmask to match *exactly* to the errors the certificate
|
|
148
|
-
// caused. If extra bits will be set, the untrusted certificate screen
|
|
149
|
-
// will appear.
|
|
150
|
-
WdCertOverrideService.prototype.fillNeededBits = function(aCert, aHost) {
|
|
151
|
-
var verification_bits = aCert.verifyForUsage(aCert.CERT_USAGE_SSLClient);
|
|
152
|
-
var return_bits = this.default_bits;
|
|
153
|
-
|
|
154
|
-
localdump("Certificate verification results: " + verification_bits);
|
|
155
|
-
|
|
156
|
-
return_bits = return_bits | this.certificateExpiredBit_(
|
|
157
|
-
aCert, verification_bits);
|
|
158
|
-
return_bits = return_bits | this.certificateIssuerUntrusted_(
|
|
159
|
-
aCert, verification_bits);
|
|
160
|
-
return_bits = return_bits | this.certificateHostnameMismatch_(aCert, aHost);
|
|
161
|
-
localdump("return_bits now: " + return_bits);
|
|
162
|
-
return return_bits;
|
|
163
|
-
};
|
|
164
|
-
|
|
165
|
-
// Interface functions from now on.
|
|
166
|
-
WdCertOverrideService.prototype.hasMatchingOverride = function(
|
|
167
|
-
aHostName, aPort, aCert, aOverrideBits, aIsTemporary) {
|
|
168
|
-
var retval = false;
|
|
169
|
-
|
|
170
|
-
if (this.acceptAll === true) {
|
|
171
|
-
localdump("Allowing certificate from site: " + aHostName + ":" + aPort);
|
|
172
|
-
retval = true;
|
|
173
|
-
aIsTemporary.value = false;
|
|
174
|
-
|
|
175
|
-
aOverrideBits.value = this.fillNeededBits(aCert, aHostName);
|
|
176
|
-
localdump("Override Bits: " + aOverrideBits.value);
|
|
177
|
-
} else {
|
|
178
|
-
retval = this.origListener_.hasMatchingOverride(aHostName, aPort,
|
|
179
|
-
aCert, aOverrideBits, aIsTemporary);
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
return retval;
|
|
183
|
-
};
|
|
184
|
-
|
|
185
|
-
// Delegate the rest of the functions - they are not interesting as they are not
|
|
186
|
-
// called during validation of invalid certificate normally.
|
|
187
|
-
WdCertOverrideService.prototype.clearValidityOverride = function(aHostName,
|
|
188
|
-
aPort) {
|
|
189
|
-
this.origListener_.clearValidityOverride(aHostName, aPort);
|
|
190
|
-
};
|
|
191
|
-
|
|
192
|
-
WdCertOverrideService.prototype.getAllOverrideHostsWithPorts = function(
|
|
193
|
-
aCount, aHostsWithPortsArray) {
|
|
194
|
-
this.origListener_.getAllOverrideHostsWithPorts(aCert, aHostsWithPortsArray);
|
|
195
|
-
};
|
|
196
|
-
|
|
197
|
-
WdCertOverrideService.prototype.getValidityOverride = function(
|
|
198
|
-
aHostName, aPort, aHashAlg, aFingerprint, aOverrideBits, aIsTemporary) {
|
|
199
|
-
return this.origListener_.getValidityOverride(
|
|
200
|
-
aHostName, aPort, aHashAlg, aFingerprint, aOverrideBits, aIsTemporary);
|
|
201
|
-
};
|
|
202
|
-
|
|
203
|
-
WdCertOverrideService.prototype.isCertUsedForOverrides = function(
|
|
204
|
-
aCert, aCheckTemporaries, aCheckPermanents) {
|
|
205
|
-
return this.origListener_.isCertUsedForOverrides(
|
|
206
|
-
aCert, aCheckTemporaries, aCheckPermanents);
|
|
207
|
-
};
|
|
208
|
-
|
|
209
|
-
WdCertOverrideService.prototype.rememberValidityOverride = function(
|
|
210
|
-
aHostName, aPort, aCert, aOverrideBits, aTemporary) {
|
|
211
|
-
this.origListener_.rememberValidityOverride(
|
|
212
|
-
aHostName, aPort, aCert, aOverrideBits, aTemporary);
|
|
213
|
-
};
|
|
214
|
-
|
|
215
|
-
WdCertOverrideService.prototype.QueryInterface = function(aIID) {
|
|
216
|
-
if (aIID.equals(Components.interfaces.nsICertOverrideService) ||
|
|
217
|
-
aIID.equals(Components.interfaces.nsIInterfaceRequestor) ||
|
|
218
|
-
aIID.equals(Components.interfaces.nsISupports)) {
|
|
219
|
-
return this;
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
throw Components.results.NS_ERROR_NO_INTERFACE;
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
// Service contract ID which we override
|
|
226
|
-
const CERTOVERRIDE_CONTRACT_ID = "@mozilla.org/security/certoverride;1";
|
|
227
|
-
// UUID for this instance specifically.
|
|
228
|
-
const DUMMY_CERTOVERRIDE_SERVICE_CLASS_ID =
|
|
229
|
-
Components.ID('{c8fffaba-9b7a-41aa-872d-7e7366c16715}');
|
|
230
|
-
|
|
231
|
-
var service = undefined;
|
|
232
|
-
|
|
233
|
-
var WDCertOverrideFactory = {
|
|
234
|
-
createInstance: function (aOuter, aIID) {
|
|
235
|
-
if (aOuter != null)
|
|
236
|
-
throw Components.results.NS_ERROR_NO_AGGREGATION;
|
|
237
|
-
if (service == undefined) {
|
|
238
|
-
service = new WdCertOverrideService();
|
|
239
|
-
}
|
|
240
|
-
return service;
|
|
241
|
-
}
|
|
242
|
-
};
|
|
243
|
-
|
|
244
|
-
function WDBadCertListenerModule() {
|
|
245
|
-
this.firstTime_ = true;
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
WDBadCertListenerModule.prototype.registerSelf = function(
|
|
249
|
-
aCompMgr, aFileSpec, aLocation, aType) {
|
|
250
|
-
|
|
251
|
-
if (this.firstTime_) {
|
|
252
|
-
this.firstTime_ = false;
|
|
253
|
-
throw Components.results.NS_ERROR_FACTORY_REGISTER_AGAIN;
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
localdump("Registering Override Certificate service.");
|
|
257
|
-
aCompMgr = aCompMgr.QueryInterface(
|
|
258
|
-
Components.interfaces.nsIComponentRegistrar);
|
|
259
|
-
aCompMgr.registerFactoryLocation(
|
|
260
|
-
DUMMY_CERTOVERRIDE_SERVICE_CLASS_ID, "WebDriver Override Cert Service",
|
|
261
|
-
CERTOVERRIDE_CONTRACT_ID, aFileSpec, aLocation, aType);
|
|
262
|
-
};
|
|
263
|
-
|
|
264
|
-
WDBadCertListenerModule.prototype.unregisterSelf = function(
|
|
265
|
-
aCompMgr, aLocation, aType) {
|
|
266
|
-
localdump("Un-registering Override Certificate service.");
|
|
267
|
-
aCompMgr =
|
|
268
|
-
aCompMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
|
|
269
|
-
aCompMgr.unregisterFactoryLocation(DUMMY_CERTOVERRIDE_SERVICE_CLASS_ID, aLocation);
|
|
270
|
-
};
|
|
271
|
-
|
|
272
|
-
WDBadCertListenerModule.prototype.getClassObject = function(
|
|
273
|
-
aCompMgr, aCID, aIID) {
|
|
274
|
-
if (!aIID.equals(Components.interfaces.nsIFactory))
|
|
275
|
-
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
|
|
276
|
-
|
|
277
|
-
if (aCID.equals(DUMMY_CERTOVERRIDE_SERVICE_CLASS_ID))
|
|
278
|
-
return WDCertOverrideFactory;
|
|
279
|
-
|
|
280
|
-
throw Components.results.NS_ERROR_NO_INTERFACE;
|
|
281
|
-
};
|
|
282
|
-
|
|
283
|
-
WDBadCertListenerModule.prototype.canUnload = function(aCompMgr) {
|
|
284
|
-
return true;
|
|
285
|
-
};
|
|
286
|
-
|
|
287
|
-
function NSGetModule(comMgr, fileSpec) {
|
|
288
|
-
var appInfo = Components.classes['@mozilla.org/xre/app-info;1'].
|
|
289
|
-
getService(Components.interfaces.nsIXULAppInfo);
|
|
290
|
-
var versionChecker = Components.classes['@mozilla.org/xpcom/version-comparator;1'].
|
|
291
|
-
getService(Components.interfaces.nsIVersionComparator);
|
|
292
|
-
if (versionChecker.compare(appInfo.version, '3.0') >= 0) {
|
|
293
|
-
return new WDBadCertListenerModule();
|
|
294
|
-
}
|
|
295
|
-
}
|
|
@@ -1,495 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
Copyright 2007-2010 WebDriver committers
|
|
3
|
-
Copyright 2007-2010 Google Inc.
|
|
4
|
-
|
|
5
|
-
Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
-
you may not use this file except in compliance with the License.
|
|
7
|
-
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, software
|
|
12
|
-
distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
-
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
-
See the License for the specific language governing permissions and
|
|
15
|
-
limitations under the License.
|
|
16
|
-
*/
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Dispatches commands received by the WebDriver server.
|
|
21
|
-
* @constructor
|
|
22
|
-
*/
|
|
23
|
-
function Dispatcher() {
|
|
24
|
-
this.resources_ = [];
|
|
25
|
-
this.init_();
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Utility function used to respond to a command that is recognised, but not
|
|
31
|
-
* implemented. Returns a 501.
|
|
32
|
-
* @param {Request} The request to respond to.
|
|
33
|
-
* @param {Response} Class used to send the response.
|
|
34
|
-
*/
|
|
35
|
-
Dispatcher.notImplemented = function(request, response) {
|
|
36
|
-
response.sendError(Response.NOT_IMPLEMENTED, 'Unsupported command',
|
|
37
|
-
'text/plain');
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Returns a function that translates a WebDriver HTTP request to a legacy
|
|
43
|
-
* command.
|
|
44
|
-
* @param {string} name The legacy command name.
|
|
45
|
-
* @return {function(Request, Response)} The translation function.
|
|
46
|
-
* @private
|
|
47
|
-
*/
|
|
48
|
-
Dispatcher.executeAs = function(name) {
|
|
49
|
-
return function(request, response) {
|
|
50
|
-
var json = {
|
|
51
|
-
'name': name,
|
|
52
|
-
'sessionId': {
|
|
53
|
-
'value': request.getAttribute('sessionId')
|
|
54
|
-
},
|
|
55
|
-
'parameters': JSON.parse(request.getBody() || '{}')
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
// All request attributes, excluding sessionId and parameters also passed
|
|
59
|
-
// the body payload, should be added to the parameters.
|
|
60
|
-
var attributeNames = request.getAttributeNames();
|
|
61
|
-
for (var attrName; attrName = attributeNames.shift();) {
|
|
62
|
-
if (attrName != 'sessionId' && !json['parameters'][attrName]) {
|
|
63
|
-
json['parameters'][attrName] = request.getAttribute(attrName);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
var jsonString = JSON.stringify(json);
|
|
68
|
-
var callback = function(jsonResponseString) {
|
|
69
|
-
var jsonResponse = JSON.parse(jsonResponseString);
|
|
70
|
-
// Going to need more granularity here I think.
|
|
71
|
-
if (jsonResponse.status != ErrorCode.SUCCESS) {
|
|
72
|
-
response.setStatus(Response.INTERNAL_ERROR);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
response.setContentType('application/json');
|
|
76
|
-
response.setBody(jsonResponseString);
|
|
77
|
-
response.commit();
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
// Dispatch the command.
|
|
81
|
-
Components.classes['@googlecode.com/webdriver/command-processor;1'].
|
|
82
|
-
getService(Components.interfaces.nsICommandProcessor).
|
|
83
|
-
execute(jsonString, callback);
|
|
84
|
-
};
|
|
85
|
-
};
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* Creates a special handler for translating a request for a new session to a
|
|
90
|
-
* request understood by the legacy nsICommandProcessor.
|
|
91
|
-
*/
|
|
92
|
-
Dispatcher.translateNewSession = function() {
|
|
93
|
-
return function(request, response) {
|
|
94
|
-
var callback = function(jsonResponseString) {
|
|
95
|
-
var jsonResponse = JSON.parse(jsonResponseString);
|
|
96
|
-
// Going to need more granularity here I think.
|
|
97
|
-
if (jsonResponse.status != 0) {
|
|
98
|
-
response.sendError(Response.INTERNAL_ERROR,
|
|
99
|
-
jsonResponseString, 'application/json');
|
|
100
|
-
} else {
|
|
101
|
-
var url = request.getRequestUrl();
|
|
102
|
-
response.setStatus(Response.SEE_OTHER);
|
|
103
|
-
response.setHeader('Location',
|
|
104
|
-
url.scheme + '://' + url.hostPort + url.path + '/' +
|
|
105
|
-
jsonResponse.value);
|
|
106
|
-
response.commit();
|
|
107
|
-
}
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
// Dispatch the command.
|
|
111
|
-
Components.classes['@googlecode.com/webdriver/command-processor;1'].
|
|
112
|
-
getService(Components.interfaces.nsICommandProcessor).
|
|
113
|
-
execute('{"name":"newSession"}', callback);
|
|
114
|
-
};
|
|
115
|
-
};
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* Initializes the command bindings for this dispatcher.
|
|
120
|
-
* @private
|
|
121
|
-
*/
|
|
122
|
-
Dispatcher.prototype.init_ = function() {
|
|
123
|
-
this.bind_('/config/drivers'). // Recognised, but not supported.
|
|
124
|
-
on(Request.Method.POST, Dispatcher.notImplemented);
|
|
125
|
-
|
|
126
|
-
this.bind_('/session').
|
|
127
|
-
on(Request.Method.POST, Dispatcher.translateNewSession());
|
|
128
|
-
|
|
129
|
-
this.bind_('/session/:sessionId').
|
|
130
|
-
on(Request.Method.GET, Dispatcher.executeAs('getSessionCapabilities')).
|
|
131
|
-
on(Request.Method.DELETE, Dispatcher.executeAs('quit'));
|
|
132
|
-
|
|
133
|
-
this.bind_('/session/:sessionId/window_handle').
|
|
134
|
-
on(Request.Method.GET, Dispatcher.executeAs('getCurrentWindowHandle'));
|
|
135
|
-
this.bind_('/session/:sessionId/window_handles').
|
|
136
|
-
on(Request.Method.GET, Dispatcher.executeAs('getWindowHandles'));
|
|
137
|
-
|
|
138
|
-
this.bind_('/session/:sessionId/speed').
|
|
139
|
-
on(Request.Method.GET, Dispatcher.executeAs('getSpeed')).
|
|
140
|
-
on(Request.Method.POST, Dispatcher.executeAs('setSpeed'));
|
|
141
|
-
|
|
142
|
-
this.bind_('/session/:sessionId/timeouts/implicit_wait').
|
|
143
|
-
on(Request.Method.POST, Dispatcher.executeAs('implicitlyWait'));
|
|
144
|
-
|
|
145
|
-
this.bind_('/session/:sessionId/url').
|
|
146
|
-
on(Request.Method.GET, Dispatcher.executeAs('getCurrentUrl')).
|
|
147
|
-
on(Request.Method.POST, Dispatcher.executeAs('get'));
|
|
148
|
-
|
|
149
|
-
this.bind_('/session/:sessionId/forward').
|
|
150
|
-
on(Request.Method.POST, Dispatcher.executeAs('goForward'));
|
|
151
|
-
this.bind_('/session/:sessionId/back').
|
|
152
|
-
on(Request.Method.POST, Dispatcher.executeAs('goBack'));
|
|
153
|
-
this.bind_('/session/:sessionId/refresh').
|
|
154
|
-
on(Request.Method.POST, Dispatcher.executeAs('refresh'));
|
|
155
|
-
|
|
156
|
-
this.bind_('/session/:sessionId/execute').
|
|
157
|
-
on(Request.Method.POST, Dispatcher.executeAs('executeScript'));
|
|
158
|
-
|
|
159
|
-
this.bind_('/session/:sessionId/source').
|
|
160
|
-
on(Request.Method.GET, Dispatcher.executeAs('getPageSource'));
|
|
161
|
-
this.bind_('/session/:sessionId/title').
|
|
162
|
-
on(Request.Method.GET, Dispatcher.executeAs('getTitle'));
|
|
163
|
-
|
|
164
|
-
this.bind_('/session/:sessionId/element').
|
|
165
|
-
on(Request.Method.POST, Dispatcher.executeAs('findElement'));
|
|
166
|
-
this.bind_('/session/:sessionId/elements').
|
|
167
|
-
on(Request.Method.POST, Dispatcher.executeAs('findElements'));
|
|
168
|
-
this.bind_('/session/:sessionId/element/active').
|
|
169
|
-
on(Request.Method.POST, Dispatcher.executeAs('getActiveElement'));
|
|
170
|
-
|
|
171
|
-
this.bind_('/session/:sessionId/element/:id').
|
|
172
|
-
// TODO: implement
|
|
173
|
-
on(Request.Method.GET, Dispatcher.notImplemented);
|
|
174
|
-
|
|
175
|
-
this.bind_('/session/:sessionId/element/:id/element').
|
|
176
|
-
on(Request.Method.POST, Dispatcher.executeAs('findChildElement'));
|
|
177
|
-
this.bind_('/session/:sessionId/element/:id/elements').
|
|
178
|
-
on(Request.Method.POST, Dispatcher.executeAs('findChildElements'));
|
|
179
|
-
|
|
180
|
-
this.bind_('/session/:sessionId/element/:id/click').
|
|
181
|
-
on(Request.Method.POST, Dispatcher.executeAs('clickElement'));
|
|
182
|
-
this.bind_('/session/:sessionId/element/:id/text').
|
|
183
|
-
on(Request.Method.GET, Dispatcher.executeAs('getElementText'));
|
|
184
|
-
this.bind_('/session/:sessionId/element/:id/submit').
|
|
185
|
-
on(Request.Method.POST, Dispatcher.executeAs('submitElement'));
|
|
186
|
-
|
|
187
|
-
this.bind_('/session/:sessionId/element/:id/value').
|
|
188
|
-
on(Request.Method.POST, Dispatcher.executeAs('sendKeysToElement')).
|
|
189
|
-
on(Request.Method.GET, Dispatcher.executeAs('getElementValue'));
|
|
190
|
-
|
|
191
|
-
this.bind_('/session/:sessionId/element/:id/name').
|
|
192
|
-
on(Request.Method.GET, Dispatcher.executeAs('getElementTagName'));
|
|
193
|
-
|
|
194
|
-
this.bind_('/session/:sessionId/element/:id/clear').
|
|
195
|
-
on(Request.Method.POST, Dispatcher.executeAs('clearElement'));
|
|
196
|
-
|
|
197
|
-
this.bind_('/session/:sessionId/element/:id/selected').
|
|
198
|
-
on(Request.Method.GET, Dispatcher.executeAs('isElementSelected')).
|
|
199
|
-
on(Request.Method.POST, Dispatcher.executeAs('setElementSelected'));
|
|
200
|
-
|
|
201
|
-
this.bind_('/session/:sessionId/element/:id/enabled').
|
|
202
|
-
on(Request.Method.GET, Dispatcher.executeAs('isElementEnabled'));
|
|
203
|
-
this.bind_('/session/:sessionId/element/:id/displayed').
|
|
204
|
-
on(Request.Method.GET, Dispatcher.executeAs('isElementDisplayed'));
|
|
205
|
-
|
|
206
|
-
this.bind_('/session/:sessionId/element/:id/location').
|
|
207
|
-
on(Request.Method.GET, Dispatcher.executeAs('getElementLocation'));
|
|
208
|
-
this.bind_('/session/:sessionId/element/:id/location_in_view').
|
|
209
|
-
on(Request.Method.GET, Dispatcher.executeAs(
|
|
210
|
-
'getElementLocationOnceScrolledIntoView'));
|
|
211
|
-
|
|
212
|
-
this.bind_('/session/:sessionId/element/:id/size').
|
|
213
|
-
on(Request.Method.GET, Dispatcher.executeAs('getElementSize'));
|
|
214
|
-
|
|
215
|
-
this.bind_('/session/:sessionId/element/:id/css/:propertyName').
|
|
216
|
-
on(Request.Method.GET,
|
|
217
|
-
Dispatcher.executeAs('getElementValueOfCssProperty'));
|
|
218
|
-
this.bind_('/session/:sessionId/element/:id/attribute/:name').
|
|
219
|
-
on(Request.Method.GET, Dispatcher.executeAs('getElementAttribute'));
|
|
220
|
-
this.bind_('/session/:sessionId/element/:id/equals/:other').
|
|
221
|
-
on(Request.Method.GET, Dispatcher.executeAs('elementEquals'));
|
|
222
|
-
|
|
223
|
-
this.bind_('/session/:sessionId/element/:id/toggle').
|
|
224
|
-
on(Request.Method.POST, Dispatcher.executeAs('toggleElement'));
|
|
225
|
-
this.bind_('/session/:sessionId/element/:id/hover').
|
|
226
|
-
on(Request.Method.POST, Dispatcher.executeAs('hoverOverElement'));
|
|
227
|
-
this.bind_('/session/:sessionId/element/:id/drag').
|
|
228
|
-
on(Request.Method.POST, Dispatcher.executeAs('dragElement'));
|
|
229
|
-
|
|
230
|
-
this.bind_('/session/:sessionId/cookie').
|
|
231
|
-
on(Request.Method.GET, Dispatcher.executeAs('getCookies')).
|
|
232
|
-
on(Request.Method.POST, Dispatcher.executeAs('addCookie')).
|
|
233
|
-
on(Request.Method.DELETE, Dispatcher.executeAs('deleteAllCookies'));
|
|
234
|
-
|
|
235
|
-
this.bind_('/session/:sessionId/cookie/:name').
|
|
236
|
-
on(Request.Method.DELETE, Dispatcher.executeAs('deleteCookie'));
|
|
237
|
-
|
|
238
|
-
this.bind_('/session/:sessionId/frame').
|
|
239
|
-
on(Request.Method.POST, Dispatcher.executeAs('switchToFrame'));
|
|
240
|
-
this.bind_('/session/:sessionId/window').
|
|
241
|
-
on(Request.Method.POST, Dispatcher.executeAs('switchToWindow')).
|
|
242
|
-
on(Request.Method.DELETE, Dispatcher.executeAs('close'));
|
|
243
|
-
|
|
244
|
-
this.bind_('/session/:sessionId/screenshot').
|
|
245
|
-
on(Request.Method.GET, Dispatcher.executeAs('screenshot'));
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
// --------------------------------------------------------------------------
|
|
249
|
-
// Firefox extensions to the wire protocol.
|
|
250
|
-
// --------------------------------------------------------------------------
|
|
251
|
-
|
|
252
|
-
this.bind_('/extensions/firefox/quit').
|
|
253
|
-
on(Request.Method.POST, Dispatcher.executeAs('quit'));
|
|
254
|
-
};
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
/**
|
|
258
|
-
* Binds a resource to the given path.
|
|
259
|
-
* @param {string} path The resource path.
|
|
260
|
-
* @return {Resource} The bound resource.
|
|
261
|
-
*/
|
|
262
|
-
Dispatcher.prototype.bind_ = function(path) {
|
|
263
|
-
var resource = new Resource(path);
|
|
264
|
-
this.resources_.push(resource);
|
|
265
|
-
return resource;
|
|
266
|
-
};
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
/**
|
|
271
|
-
* Dispatches a request to the appropriately registered handler.
|
|
272
|
-
* @param {Request} request The request to dispatch.
|
|
273
|
-
* @param {Response} response The request response.
|
|
274
|
-
*/
|
|
275
|
-
Dispatcher.prototype.dispatch = function(request, response) {
|
|
276
|
-
// We only support one servlet, mapped to /hub/*
|
|
277
|
-
// TODO: be more flexible.
|
|
278
|
-
var path = request.getRequestUrl().path;
|
|
279
|
-
if (path.indexOf('/hub') != 0) {
|
|
280
|
-
response.sendError(Response.NOT_FOUND);
|
|
281
|
-
return;
|
|
282
|
-
}
|
|
283
|
-
request.setServletPath('/hub');
|
|
284
|
-
path = request.getPathInfo();
|
|
285
|
-
|
|
286
|
-
var bestMatchResource;
|
|
287
|
-
for (var i = 0; i < this.resources_.length; i++) {
|
|
288
|
-
if (this.resources_[i].isResourceFor(path)) {
|
|
289
|
-
if (!bestMatchResource ||
|
|
290
|
-
bestMatchResource.getNumVariablePathSegments() <
|
|
291
|
-
this.resources_[i].getNumVariablePathSegments()) {
|
|
292
|
-
bestMatchResource = this.resources_[i];
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
if (bestMatchResource) {
|
|
298
|
-
try {
|
|
299
|
-
bestMatchResource.setRequestAttributes(request);
|
|
300
|
-
bestMatchResource.handle(request, response);
|
|
301
|
-
} catch (ex) {
|
|
302
|
-
Utils.dump(ex);
|
|
303
|
-
response.sendError(Response.INTERNAL_ERROR, JSON.stringify({
|
|
304
|
-
status: ErrorCode.UNHANDLED_ERROR,
|
|
305
|
-
value: ErrorCode.toJSON(ex)
|
|
306
|
-
}), 'application/json');
|
|
307
|
-
}
|
|
308
|
-
} else {
|
|
309
|
-
response.sendError(Response.NOT_FOUND,
|
|
310
|
-
'Unrecognized command: ' + request.getMethod() + ' ' +
|
|
311
|
-
request.getPathInfo(),
|
|
312
|
-
'text/plain');
|
|
313
|
-
}
|
|
314
|
-
};
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
/**
|
|
318
|
-
* Defines a resource in the WebDriver REST service locatable at the given path.
|
|
319
|
-
* Any path segments prefixed with a ":" indicate that segment is a variable
|
|
320
|
-
* unique to a resource. For example, in the path "/session/:sessionId",
|
|
321
|
-
* ":sessionId" is a variable that can be changed to specify different sessions.
|
|
322
|
-
* @param {!string} path The path that this resource is accessible from.
|
|
323
|
-
*/
|
|
324
|
-
function Resource(path) {
|
|
325
|
-
|
|
326
|
-
/**
|
|
327
|
-
* The request pattern that this resource is located at.
|
|
328
|
-
* @type {!string}
|
|
329
|
-
* @const
|
|
330
|
-
* @private
|
|
331
|
-
*/
|
|
332
|
-
this.path_ = path;
|
|
333
|
-
|
|
334
|
-
/**
|
|
335
|
-
* The individual path segments for this resource.
|
|
336
|
-
* @type {Array.<string>}
|
|
337
|
-
* @const
|
|
338
|
-
* @private
|
|
339
|
-
*/
|
|
340
|
-
this.pathSegments_ = path.split('/');
|
|
341
|
-
|
|
342
|
-
/**
|
|
343
|
-
* A map of handler functions, by HTTP method, that can service requests to
|
|
344
|
-
* this resource.
|
|
345
|
-
* @type {!Object}
|
|
346
|
-
* @const
|
|
347
|
-
* @private
|
|
348
|
-
*/
|
|
349
|
-
this.handlers_ = {};
|
|
350
|
-
|
|
351
|
-
for (var i = 0; i < this.pathSegments_.length; i++) {
|
|
352
|
-
if (this.pathSegments_[i].indexOf(Resource.VARIABLE_PATH_SEGMENT_PREFIX_)) {
|
|
353
|
-
this.numVariablePathSegments_ += 1;
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
};
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
/**
|
|
360
|
-
* The number of path segments for this resource that are variables.
|
|
361
|
-
* @type {number}
|
|
362
|
-
* @private
|
|
363
|
-
*/
|
|
364
|
-
Resource.prototype.numVariablePathSegments_ = 0;
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
/** @return {string} The path mapped to this resource. */
|
|
368
|
-
Resource.prototype.getPath = function() {
|
|
369
|
-
return this.path_;
|
|
370
|
-
};
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
/** @return {number} The number of variable path segments for this resource. */
|
|
374
|
-
Resource.prototype.getNumVariablePathSegments = function() {
|
|
375
|
-
return this.numVariablePathSegments_;
|
|
376
|
-
};
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
/**
|
|
380
|
-
* Sets the handler function for this resource when a request is received using
|
|
381
|
-
* the given HTTP method. This function will override any previously set
|
|
382
|
-
* handlers.
|
|
383
|
-
* @param {!Request.Method} httpMethod The request method the function can
|
|
384
|
-
* handle.
|
|
385
|
-
* @param {function(Request, Response)} handlerFn The function that will handle
|
|
386
|
-
* all requests for this resource using the given HTTP method.
|
|
387
|
-
* @return {!Resource} A self reference for chained calls.
|
|
388
|
-
*/
|
|
389
|
-
Resource.prototype.on = function(httpMethod, handlerFn) {
|
|
390
|
-
this.handlers_[httpMethod] = handlerFn;
|
|
391
|
-
return this;
|
|
392
|
-
};
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
/**
|
|
396
|
-
* Determines if this is the resource for the given path.
|
|
397
|
-
* @param {!string} path The resource path to test.
|
|
398
|
-
* @return {boolean} Whether this resource is mapped to the given path.
|
|
399
|
-
*/
|
|
400
|
-
Resource.prototype.isResourceFor = function(path) {
|
|
401
|
-
var allParts = path.split('/');
|
|
402
|
-
if (this.pathSegments_.length != allParts.length) {
|
|
403
|
-
return false;
|
|
404
|
-
}
|
|
405
|
-
for (var i = 0; i < this.pathSegments_.length; i++) {
|
|
406
|
-
if (this.pathSegments_[i] != allParts[i] &&
|
|
407
|
-
!/^:/.test(this.pathSegments_[i])) {
|
|
408
|
-
return false;
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
return true;
|
|
412
|
-
};
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
/**
|
|
416
|
-
* Sets request attributes by the named path variables for this resource. For
|
|
417
|
-
* each named path segment variable for this resource, the value of the
|
|
418
|
-
* corresponding path segment in the request will be stored as the request
|
|
419
|
-
* attribute's value.
|
|
420
|
-
* @param {Request} request The request to update.
|
|
421
|
-
*/
|
|
422
|
-
Resource.prototype.setRequestAttributes = function(request) {
|
|
423
|
-
var allParts = request.getPathInfo().split('/');
|
|
424
|
-
for (var i = 0; i < this.pathSegments_.length; i++) {
|
|
425
|
-
if (/^:/.test(this.pathSegments_[i])) {
|
|
426
|
-
var decodedValue = decodeURIComponent(allParts[i]);
|
|
427
|
-
request.setAttribute(
|
|
428
|
-
this.pathSegments_[i].replace(/^:/, ''), decodedValue);
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
};
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
/**
|
|
435
|
-
* Handles a request to this resource. Will return a 405 if this resource does
|
|
436
|
-
* not permit the HTTP method used for the request.
|
|
437
|
-
* @param {Request} request The request to handle.
|
|
438
|
-
* @param {Response} response For sending the response.
|
|
439
|
-
* @throws If this resource cannot handle the request.
|
|
440
|
-
*/
|
|
441
|
-
Resource.prototype.handle = function(request, response) {
|
|
442
|
-
if (!this.isResourceFor(request.getPathInfo())) {
|
|
443
|
-
throw Error('Request does not map to this resource:' +
|
|
444
|
-
'\n requestPath: ' + request.getPathInfo() +
|
|
445
|
-
'\n resourcePath: ' + this.path_);;
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
var requestMethod = request.getMethod();
|
|
449
|
-
|
|
450
|
-
if (requestMethod == Request.Method.OPTIONS) {
|
|
451
|
-
response.setHeader('Allow', this.getAllowedMethods_());
|
|
452
|
-
response.setStatus(Response.OK);
|
|
453
|
-
response.setBody('');
|
|
454
|
-
response.commit();
|
|
455
|
-
return;
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
if (requestMethod == Request.Method.HEAD) {
|
|
459
|
-
requestMethod = Request.Method.GET;
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
var handlerFn = this.handlers_[requestMethod];
|
|
463
|
-
if (handlerFn) {
|
|
464
|
-
handlerFn(request, response);
|
|
465
|
-
} else {
|
|
466
|
-
response.setHeader('Allow', this.getAllowedMethods_());
|
|
467
|
-
response.setContentType('text/plain');
|
|
468
|
-
response.sendError(Response.METHOD_NOT_ALLOWED,
|
|
469
|
-
'Method "' + request.getMethod() + '" not allowed for command ' +
|
|
470
|
-
'"' + this.path_ + '"');
|
|
471
|
-
}
|
|
472
|
-
};
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
/**
|
|
476
|
-
* @return {string} A comma-delimitted list of HTTP methods allowed by this
|
|
477
|
-
* resource.
|
|
478
|
-
* @private
|
|
479
|
-
*/
|
|
480
|
-
Resource.prototype.getAllowedMethods_ = function() {
|
|
481
|
-
var allowed = [];
|
|
482
|
-
for (var method in this.handlers_) {
|
|
483
|
-
allowed.push(method);
|
|
484
|
-
}
|
|
485
|
-
|
|
486
|
-
// We always respond to OPTIONS
|
|
487
|
-
allowed.push(Request.Method.OPTIONS);
|
|
488
|
-
|
|
489
|
-
// If we respond to GET, then we respond to HEAD.
|
|
490
|
-
if (Request.Method.GET in this.handlers_) {
|
|
491
|
-
allowed.push(Request.Method.HEAD);
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
return allowed.join(',');
|
|
495
|
-
};
|