Backed out 8 changesets (bug 1574475, bug 1699222) for build bustages on moz.build . CLOSED TREE
Backed out changeset 6c2c039872b3 (bug 1574475) Backed out changeset 8a2a04743c5f (bug 1699222) Backed out changeset 9437c60798d6 (bug 1574475) Backed out changeset 7ef1884ac11b (bug 1574475) Backed out changeset ec8c237d5298 (bug 1574475) Backed out changeset 4a760b3f5d53 (bug 1574475) Backed out changeset b229b0eea1e7 (bug 1574475) Backed out changeset 03d34a2f10a6 (bug 1574475)
This commit is contained in:
@@ -72,10 +72,6 @@ var ProxyPolicies = {
|
||||
);
|
||||
}
|
||||
|
||||
if (param.FTPProxy) {
|
||||
log.warn("FTPProxy support was removed in bug 1574475");
|
||||
}
|
||||
|
||||
function setProxyHostAndPort(type, address) {
|
||||
let url;
|
||||
try {
|
||||
@@ -100,10 +96,14 @@ var ProxyPolicies = {
|
||||
// network code. That pref only controls if the checkbox is checked, and
|
||||
// then we must manually set the other values.
|
||||
if (param.UseHTTPProxyForAllProtocols) {
|
||||
param.SSLProxy = param.SOCKSProxy = param.HTTPProxy;
|
||||
param.FTPProxy = param.SSLProxy = param.SOCKSProxy = param.HTTPProxy;
|
||||
}
|
||||
}
|
||||
|
||||
if (param.FTPProxy) {
|
||||
setProxyHostAndPort("ftp", param.FTPProxy);
|
||||
}
|
||||
|
||||
if (param.SSLProxy) {
|
||||
setProxyHostAndPort("ssl", param.SSLProxy);
|
||||
}
|
||||
|
||||
@@ -79,6 +79,7 @@ add_task(async function test_proxy_addresses() {
|
||||
policies: {
|
||||
Proxy: {
|
||||
HTTPProxy: "http.proxy.example.com:10",
|
||||
FTPProxy: "ftp.proxy.example.com:20",
|
||||
SSLProxy: "ssl.proxy.example.com:30",
|
||||
SOCKSProxy: "socks.proxy.example.com:40",
|
||||
},
|
||||
@@ -86,6 +87,7 @@ add_task(async function test_proxy_addresses() {
|
||||
});
|
||||
|
||||
checkProxyPref("http", "http.proxy.example.com", 10);
|
||||
checkProxyPref("ftp", "ftp.proxy.example.com", 20);
|
||||
checkProxyPref("ssl", "ssl.proxy.example.com", 30);
|
||||
checkProxyPref("socks", "socks.proxy.example.com", 40);
|
||||
|
||||
@@ -95,8 +97,6 @@ add_task(async function test_proxy_addresses() {
|
||||
policies: {
|
||||
Proxy: {
|
||||
HTTPProxy: "http.proxy.example.com:10",
|
||||
// FTP support was removed in bug 1574475
|
||||
// Setting an FTPProxy should result in a warning but should not fail
|
||||
FTPProxy: "ftp.proxy.example.com:20",
|
||||
SSLProxy: "ssl.proxy.example.com:30",
|
||||
SOCKSProxy: "socks.proxy.example.com:40",
|
||||
@@ -106,18 +106,7 @@ add_task(async function test_proxy_addresses() {
|
||||
});
|
||||
|
||||
checkProxyPref("http", "http.proxy.example.com", 10);
|
||||
checkProxyPref("ftp", "http.proxy.example.com", 10);
|
||||
checkProxyPref("ssl", "http.proxy.example.com", 10);
|
||||
checkProxyPref("socks", "http.proxy.example.com", 10);
|
||||
|
||||
// Make sure the FTPProxy setting did nothing
|
||||
Assert.equal(
|
||||
Preferences.has("network.proxy.ftp"),
|
||||
false,
|
||||
"network.proxy.ftp should not be set"
|
||||
);
|
||||
Assert.equal(
|
||||
Preferences.has("network.proxy.ftp_port"),
|
||||
false,
|
||||
"network.proxy.ftp_port should not be set"
|
||||
);
|
||||
});
|
||||
|
||||
@@ -19,6 +19,8 @@ Preferences.addAll([
|
||||
{ id: "network.proxy.type", type: "int" },
|
||||
{ id: "network.proxy.http", type: "string" },
|
||||
{ id: "network.proxy.http_port", type: "int" },
|
||||
{ id: "network.proxy.ftp", type: "string" },
|
||||
{ id: "network.proxy.ftp_port", type: "int" },
|
||||
{ id: "network.proxy.ssl", type: "string" },
|
||||
{ id: "network.proxy.ssl_port", type: "int" },
|
||||
{ id: "network.proxy.socks", type: "string" },
|
||||
@@ -29,6 +31,8 @@ Preferences.addAll([
|
||||
{ id: "network.proxy.share_proxy_settings", type: "bool" },
|
||||
{ id: "signon.autologin.proxy", type: "bool" },
|
||||
{ id: "pref.advanced.proxies.disable_button.reload", type: "bool" },
|
||||
{ id: "network.proxy.backup.ftp", type: "string" },
|
||||
{ id: "network.proxy.backup.ftp_port", type: "int" },
|
||||
{ id: "network.proxy.backup.ssl", type: "string" },
|
||||
{ id: "network.proxy.backup.ssl_port", type: "int" },
|
||||
{ id: "network.trr.mode", type: "int" },
|
||||
@@ -133,7 +137,7 @@ var gConnectionsDialog = {
|
||||
);
|
||||
|
||||
// If the port is 0 and the proxy server is specified, focus on the port and cancel submission.
|
||||
for (let prefName of ["http", "ssl", "socks"]) {
|
||||
for (let prefName of ["http", "ssl", "ftp", "socks"]) {
|
||||
let proxyPortPref = Preferences.get(
|
||||
"network.proxy." + prefName + "_port"
|
||||
);
|
||||
@@ -155,16 +159,27 @@ var gConnectionsDialog = {
|
||||
|
||||
// In the case of a shared proxy preference, backup the current values and update with the HTTP value
|
||||
if (shareProxiesPref.value) {
|
||||
var proxyServerURLPref = Preferences.get("network.proxy.ssl");
|
||||
var proxyPortPref = Preferences.get("network.proxy.ssl_port");
|
||||
var backupServerURLPref = Preferences.get("network.proxy.backup.ssl");
|
||||
var backupPortPref = Preferences.get("network.proxy.backup.ssl_port");
|
||||
var proxyPrefs = ["ssl", "ftp"];
|
||||
for (var i = 0; i < proxyPrefs.length; ++i) {
|
||||
var proxyServerURLPref = Preferences.get(
|
||||
"network.proxy." + proxyPrefs[i]
|
||||
);
|
||||
var proxyPortPref = Preferences.get(
|
||||
"network.proxy." + proxyPrefs[i] + "_port"
|
||||
);
|
||||
var backupServerURLPref = Preferences.get(
|
||||
"network.proxy.backup." + proxyPrefs[i]
|
||||
);
|
||||
var backupPortPref = Preferences.get(
|
||||
"network.proxy.backup." + proxyPrefs[i] + "_port"
|
||||
);
|
||||
backupServerURLPref.value =
|
||||
backupServerURLPref.value || proxyServerURLPref.value;
|
||||
backupPortPref.value = backupPortPref.value || proxyPortPref.value;
|
||||
proxyServerURLPref.value = httpProxyURLPref.value;
|
||||
proxyPortPref.value = httpProxyPortPref.value;
|
||||
}
|
||||
}
|
||||
|
||||
this.sanitizeNoProxiesPref();
|
||||
},
|
||||
@@ -251,7 +266,7 @@ var gConnectionsDialog = {
|
||||
var shareProxiesPref = Preferences.get(
|
||||
"network.proxy.share_proxy_settings"
|
||||
);
|
||||
var proxyPrefs = ["ssl", "socks"];
|
||||
var proxyPrefs = ["ssl", "ftp", "socks"];
|
||||
for (var i = 0; i < proxyPrefs.length; ++i) {
|
||||
var proxyServerURLPref = Preferences.get(
|
||||
"network.proxy." + proxyPrefs[i]
|
||||
@@ -612,6 +627,12 @@ var gConnectionsDialog = {
|
||||
setSyncFromPrefListener("networkProxySSL_Port", () =>
|
||||
this.readProxyProtocolPref("ssl", true)
|
||||
);
|
||||
setSyncFromPrefListener("networkProxyFTP", () =>
|
||||
this.readProxyProtocolPref("ftp", false)
|
||||
);
|
||||
setSyncFromPrefListener("networkProxyFTP_Port", () =>
|
||||
this.readProxyProtocolPref("ftp", true)
|
||||
);
|
||||
setSyncFromPrefListener("networkProxySOCKS", () =>
|
||||
this.readProxyProtocolPref("socks", false)
|
||||
);
|
||||
|
||||
@@ -82,6 +82,17 @@
|
||||
preference="network.proxy.ssl_port"/>
|
||||
</hbox>
|
||||
</html:div>
|
||||
<html:div class="proxy-grid-row">
|
||||
<hbox pack="end">
|
||||
<label data-l10n-id="connection-proxy-ftp" control="networkProxyFTP"/>
|
||||
</hbox>
|
||||
<hbox align="center">
|
||||
<html:input id="networkProxyFTP" type="text" style="-moz-box-flex: 1;" preference="network.proxy.ftp"/>
|
||||
<label data-l10n-id="connection-proxy-ftp-port" control="networkProxyFTP_Port"/>
|
||||
<html:input id="networkProxyFTP_Port" class="proxy-port-input" hidespinbuttons="true" type="number" min="0" max="65535" size="5"
|
||||
preference="network.proxy.ftp_port"/>
|
||||
</hbox>
|
||||
</html:div>
|
||||
<separator class="thin"/>
|
||||
<html:div class="proxy-grid-row">
|
||||
<hbox pack="end">
|
||||
|
||||
@@ -44,6 +44,8 @@ const API_PROXY_PREFS = [
|
||||
"network.proxy.http",
|
||||
"network.proxy.http_port",
|
||||
"network.proxy.share_proxy_settings",
|
||||
"network.proxy.ftp",
|
||||
"network.proxy.ftp_port",
|
||||
"network.proxy.ssl",
|
||||
"network.proxy.ssl_port",
|
||||
"network.proxy.socks",
|
||||
|
||||
@@ -708,6 +708,7 @@
|
||||
connection-proxy-option-manual.label,
|
||||
connection-proxy-http,
|
||||
connection-proxy-https,
|
||||
connection-proxy-ftp,
|
||||
connection-proxy-http-port,
|
||||
connection-proxy-socks,
|
||||
connection-proxy-socks4,
|
||||
|
||||
@@ -17,7 +17,7 @@ function test() {
|
||||
registerCleanupFunction(function() {
|
||||
Services.prefs.setIntPref("network.proxy.type", oldNetworkProxyType);
|
||||
Services.prefs.clearUserPref("network.proxy.share_proxy_settings");
|
||||
for (let proxyType of ["http", "ssl", "socks"]) {
|
||||
for (let proxyType of ["http", "ssl", "ftp", "socks"]) {
|
||||
Services.prefs.clearUserPref("network.proxy." + proxyType);
|
||||
Services.prefs.clearUserPref("network.proxy." + proxyType + "_port");
|
||||
if (proxyType == "http") {
|
||||
@@ -37,7 +37,7 @@ function test() {
|
||||
*/
|
||||
open_preferences(async function tabOpened(aContentWindow) {
|
||||
let dialog, dialogClosingPromise, dialogElement;
|
||||
let proxyTypePref, sharePref, httpPref, httpPortPref;
|
||||
let proxyTypePref, sharePref, httpPref, httpPortPref, ftpPref, ftpPortPref;
|
||||
|
||||
// Convenient function to reset the variables for the new window
|
||||
async function setDoc() {
|
||||
@@ -63,6 +63,8 @@ function test() {
|
||||
sharePref = dialog.Preferences.get("network.proxy.share_proxy_settings");
|
||||
httpPref = dialog.Preferences.get("network.proxy.http");
|
||||
httpPortPref = dialog.Preferences.get("network.proxy.http_port");
|
||||
ftpPref = dialog.Preferences.get("network.proxy.ftp");
|
||||
ftpPortPref = dialog.Preferences.get("network.proxy.ftp_port");
|
||||
}
|
||||
|
||||
// This batch of tests should not close the dialog
|
||||
@@ -77,10 +79,13 @@ function test() {
|
||||
|
||||
// Testing HTTP port 0 + FTP port 80 with share off
|
||||
sharePref.value = false;
|
||||
ftpPref.value = "localhost";
|
||||
ftpPortPref.value = 80;
|
||||
dialogElement.acceptDialog();
|
||||
|
||||
// Testing HTTP port 80 + FTP port 0 with share off
|
||||
httpPortPref.value = 80;
|
||||
ftpPortPref.value = 0;
|
||||
dialogElement.acceptDialog();
|
||||
|
||||
// From now on, the dialog should close since we are giving it legitimate inputs.
|
||||
@@ -89,14 +94,17 @@ function test() {
|
||||
|
||||
// Both ports 80, share on
|
||||
httpPortPref.value = 80;
|
||||
ftpPortPref.value = 80;
|
||||
dialogElement.acceptDialog();
|
||||
|
||||
// HTTP 80, FTP 0, with share on
|
||||
await setDoc();
|
||||
proxyTypePref.value = 1;
|
||||
sharePref.value = true;
|
||||
ftpPref.value = "localhost";
|
||||
httpPref.value = "localhost";
|
||||
httpPortPref.value = 80;
|
||||
ftpPortPref.value = 0;
|
||||
dialogElement.acceptDialog();
|
||||
|
||||
// HTTP host empty, port 0 with share on
|
||||
|
||||
@@ -15,7 +15,7 @@ function test() {
|
||||
Services.prefs.setIntPref("network.proxy.type", oldNetworkProxyType);
|
||||
Services.prefs.clearUserPref("browser.preferences.instantApply");
|
||||
Services.prefs.clearUserPref("network.proxy.share_proxy_settings");
|
||||
for (let proxyType of ["http", "ssl", "socks"]) {
|
||||
for (let proxyType of ["http", "ssl", "ftp", "socks"]) {
|
||||
Services.prefs.clearUserPref("network.proxy." + proxyType);
|
||||
Services.prefs.clearUserPref("network.proxy." + proxyType + "_port");
|
||||
if (proxyType == "http") {
|
||||
|
||||
@@ -40,6 +40,12 @@ add_task(async function checkCtrlWorks() {
|
||||
],
|
||||
];
|
||||
|
||||
if (Services.prefs.getBoolPref("network.ftp.enabled")) {
|
||||
// Include FTP testcase only if FTP protocol handler is enabled, otherwise
|
||||
// the test would hang on external application chooser popup.
|
||||
testcases.push(["ftp://example", "ftp://example/", { ctrlKey: true }]);
|
||||
}
|
||||
|
||||
// Disable autoFill for this test, since it could mess up the results.
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
|
||||
@@ -44,6 +44,11 @@ connection-proxy-https = HTTPS Proxy
|
||||
connection-proxy-ssl-port = Port
|
||||
.accesskey = o
|
||||
|
||||
connection-proxy-ftp = FTP Proxy
|
||||
.accesskey = F
|
||||
connection-proxy-ftp-port = Port
|
||||
.accesskey = r
|
||||
|
||||
connection-proxy-socks = SOCKS Host
|
||||
.accesskey = C
|
||||
connection-proxy-socks-port = Port
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
#include "nsIThreadRetargetableRequest.h"
|
||||
#include "nsContentUtils.h"
|
||||
|
||||
#include "ftpCore.h"
|
||||
#include "nsIStringBundle.h"
|
||||
#include "nsIProtocolHandler.h"
|
||||
|
||||
@@ -1149,6 +1150,8 @@ NS_IMETHODIMP nsWebBrowserPersist::OnStatus(nsIRequest* request,
|
||||
switch (status) {
|
||||
case NS_NET_STATUS_RESOLVING_HOST:
|
||||
case NS_NET_STATUS_RESOLVED_HOST:
|
||||
case NS_NET_STATUS_BEGIN_FTP_TRANSACTION:
|
||||
case NS_NET_STATUS_END_FTP_TRANSACTION:
|
||||
case NS_NET_STATUS_CONNECTING_TO:
|
||||
case NS_NET_STATUS_CONNECTED_TO:
|
||||
case NS_NET_STATUS_TLS_HANDSHAKE_STARTING:
|
||||
|
||||
@@ -170,6 +170,11 @@ XPC_MSG_DEF(NS_ERROR_REMOTE_XUL , "Attempt to access remote
|
||||
XPC_MSG_DEF(NS_ERROR_LOAD_SHOWED_ERRORPAGE , "The load caused an error page to be displayed.")
|
||||
XPC_MSG_DEF(NS_ERROR_BLOCKED_BY_POLICY , "The request was blocked by a policy set by the system administrator.")
|
||||
|
||||
XPC_MSG_DEF(NS_ERROR_FTP_LOGIN , "FTP error while logging in")
|
||||
XPC_MSG_DEF(NS_ERROR_FTP_CWD , "FTP error while changing directory")
|
||||
XPC_MSG_DEF(NS_ERROR_FTP_PASV , "FTP error while changing to passive mode")
|
||||
XPC_MSG_DEF(NS_ERROR_FTP_PWD , "FTP error while retrieving current directory")
|
||||
XPC_MSG_DEF(NS_ERROR_FTP_LIST , "FTP error while retrieving a directory listing")
|
||||
XPC_MSG_DEF(NS_ERROR_UNKNOWN_HOST , "The lookup of the hostname failed")
|
||||
XPC_MSG_DEF(NS_ERROR_DNS_LOOKUP_QUEUE_FULL , "The DNS lookup queue is full")
|
||||
XPC_MSG_DEF(NS_ERROR_UNKNOWN_PROXY_HOST , "The lookup of the proxy hostname failed")
|
||||
|
||||
@@ -1194,6 +1194,7 @@ pref("javascript.options.dump_stack_on_debuggee_would_run", false);
|
||||
pref("javascript.options.dynamicImport", true);
|
||||
|
||||
// advanced prefs
|
||||
pref("advanced.mailftp", false);
|
||||
pref("image.animation_mode", "normal");
|
||||
|
||||
// If this pref is true, prefs in the logging.config branch will be cleared on
|
||||
@@ -1490,6 +1491,14 @@ pref("network.http.send_window_size", 1024);
|
||||
// There is also image.http.accept which works in scope of image.
|
||||
pref("network.http.accept", "");
|
||||
|
||||
// default values for FTP
|
||||
// in a DSCP environment this should be 40 (0x28, or AF11), per RFC-4594,
|
||||
// Section 4.8 "High-Throughput Data Service Class", and 80 (0x50, or AF22)
|
||||
// per Section 4.7 "Low-Latency Data Service Class".
|
||||
pref("network.ftp.data.qos", 0);
|
||||
pref("network.ftp.control.qos", 0);
|
||||
pref("network.ftp.enabled", false);
|
||||
|
||||
// The max time to spend on xpcom events between two polls in ms.
|
||||
pref("network.sts.max_time_for_events_between_two_polls", 100);
|
||||
|
||||
@@ -1753,6 +1762,9 @@ pref("network.dns.offline-localhost", true);
|
||||
// A negative value will keep the thread alive forever.
|
||||
pref("network.dns.resolver-thread-extra-idle-time-seconds", 60);
|
||||
|
||||
// Idle timeout for ftp control connections - 5 minute default
|
||||
pref("network.ftp.idleConnectionTimeout", 300);
|
||||
|
||||
// enables the prefetch service (i.e., prefetching of <link rel="next"> and
|
||||
// <link rel="prefetch"> URLs).
|
||||
pref("network.prefetch-next", true);
|
||||
@@ -1875,6 +1887,8 @@ pref("network.http.tailing.total-max", 45000);
|
||||
// Enable or disable the whole fix from bug 1563538
|
||||
pref("network.http.spdy.bug1563538", true);
|
||||
|
||||
pref("network.proxy.ftp", "");
|
||||
pref("network.proxy.ftp_port", 0);
|
||||
pref("network.proxy.http", "");
|
||||
pref("network.proxy.http_port", 0);
|
||||
pref("network.proxy.ssl", "");
|
||||
|
||||
@@ -107,7 +107,7 @@ interface nsIProtocolHandler : nsISupports
|
||||
|
||||
/**
|
||||
* standard full URI with authority component and concept of relative
|
||||
* URIs (http, ...)
|
||||
* URIs (http, ftp, ...)
|
||||
*/
|
||||
const unsigned long URI_STD = 0;
|
||||
|
||||
@@ -136,7 +136,7 @@ interface nsIProtocolHandler : nsISupports
|
||||
|
||||
/**
|
||||
* This protocol handler can be proxied using a http proxy (e.g., http,
|
||||
* etc.). nsIIOService::newChannelFromURI will feed URIs from this
|
||||
* ftp, etc.). nsIIOService::newChannelFromURI will feed URIs from this
|
||||
* protocol handler to the HTTP protocol handler instead. This flag is
|
||||
* ignored if ALLOWS_PROXY is not set.
|
||||
*/
|
||||
|
||||
@@ -769,6 +769,7 @@ nsProtocolProxyService::nsProtocolProxyService()
|
||||
: mFilterLocalHosts(false),
|
||||
mProxyConfig(PROXYCONFIG_DIRECT),
|
||||
mHTTPProxyPort(-1),
|
||||
mFTPProxyPort(-1),
|
||||
mHTTPSProxyPort(-1),
|
||||
mSOCKSProxyPort(-1),
|
||||
mSOCKSProxyVersion(4),
|
||||
@@ -1003,6 +1004,12 @@ void nsProtocolProxyService::PrefsChanged(nsIPrefBranch* prefBranch,
|
||||
if (!pref || !strcmp(pref, PROXY_PREF("ssl_port")))
|
||||
proxy_GetIntPref(prefBranch, PROXY_PREF("ssl_port"), mHTTPSProxyPort);
|
||||
|
||||
if (!pref || !strcmp(pref, PROXY_PREF("ftp")))
|
||||
proxy_GetStringPref(prefBranch, PROXY_PREF("ftp"), mFTPProxyHost);
|
||||
|
||||
if (!pref || !strcmp(pref, PROXY_PREF("ftp_port")))
|
||||
proxy_GetIntPref(prefBranch, PROXY_PREF("ftp_port"), mFTPProxyPort);
|
||||
|
||||
if (!pref || !strcmp(pref, PROXY_PREF("socks")))
|
||||
proxy_GetStringPref(prefBranch, PROXY_PREF("socks"), mSOCKSProxyTarget);
|
||||
|
||||
@@ -2199,6 +2206,12 @@ nsresult nsProtocolProxyService::Resolve_Internal(nsIChannel* channel,
|
||||
host = &mHTTPSProxyHost;
|
||||
type = kProxyType_HTTP;
|
||||
port = mHTTPSProxyPort;
|
||||
} else if (!mFTPProxyHost.IsEmpty() && mFTPProxyPort > 0 &&
|
||||
!(flags & RESOLVE_IGNORE_URI_SCHEME) &&
|
||||
info.scheme.EqualsLiteral("ftp")) {
|
||||
host = &mFTPProxyHost;
|
||||
type = kProxyType_HTTP;
|
||||
port = mFTPProxyPort;
|
||||
} else if (!mSOCKSProxyTarget.IsEmpty() &&
|
||||
(IsHostLocalTarget(mSOCKSProxyTarget) || mSOCKSProxyPort > 0)) {
|
||||
host = &mSOCKSProxyTarget;
|
||||
|
||||
@@ -377,6 +377,9 @@ class nsProtocolProxyService final : public nsIProtocolProxyService2,
|
||||
nsCString mHTTPProxyHost;
|
||||
int32_t mHTTPProxyPort;
|
||||
|
||||
nsCString mFTPProxyHost;
|
||||
int32_t mFTPProxyPort;
|
||||
|
||||
nsCString mHTTPSProxyHost;
|
||||
int32_t mHTTPSProxyPort;
|
||||
|
||||
|
||||
@@ -295,6 +295,14 @@ Classes = [
|
||||
'headers': ['mozilla/net/nsFileProtocolHandler.h'],
|
||||
'init_method': 'Init',
|
||||
},
|
||||
{
|
||||
'cid': '{25029490-f132-11d2-9588-00805f369f95}',
|
||||
'contract_ids': ['@mozilla.org/network/protocol;1?name=ftp'],
|
||||
'singleton': True,
|
||||
'type': 'nsFtpProtocolHandler',
|
||||
'headers': ['/netwerk/protocol/ftp/nsFtpProtocolHandler.h'],
|
||||
'init_method': 'Init',
|
||||
},
|
||||
{
|
||||
'cid': '{4f47e42e-4d23-4dd3-bfda-eb29255e9ea3}',
|
||||
'contract_ids': ['@mozilla.org/network/protocol;1?name=http'],
|
||||
|
||||
@@ -29,6 +29,7 @@ LOCAL_INCLUDES += [
|
||||
"/netwerk/protocol/about",
|
||||
"/netwerk/protocol/data",
|
||||
"/netwerk/protocol/file",
|
||||
"/netwerk/protocol/ftp",
|
||||
"/netwerk/protocol/http",
|
||||
"/netwerk/protocol/res",
|
||||
"/netwerk/protocol/viewsource",
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
include protocol PHttpChannel;
|
||||
include protocol PFTPChannel;
|
||||
include protocol PChildToParentStream;
|
||||
include BlobTypes;
|
||||
include ClientIPCTypes;
|
||||
@@ -386,6 +387,31 @@ struct ConsoleReportCollected {
|
||||
nsString[] stringParams;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// FTP IPDL structs
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
struct FTPChannelOpenArgs
|
||||
{
|
||||
URIParams uri;
|
||||
uint64_t startPos;
|
||||
nsCString entityID;
|
||||
IPCStream? uploadStream;
|
||||
LoadInfoArgs? loadInfo;
|
||||
uint32_t loadFlags;
|
||||
};
|
||||
|
||||
struct FTPChannelConnectArgs
|
||||
{
|
||||
uint32_t channelId;
|
||||
};
|
||||
|
||||
union FTPChannelCreationArgs
|
||||
{
|
||||
FTPChannelOpenArgs; // For AsyncOpen: the common case.
|
||||
FTPChannelConnectArgs; // Used for redirected-to channels
|
||||
};
|
||||
|
||||
struct CookieStruct
|
||||
{
|
||||
nsCString name;
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "mozilla/dom/BrowserChild.h"
|
||||
#include "mozilla/net/HttpChannelChild.h"
|
||||
#include "mozilla/net/CookieServiceChild.h"
|
||||
#include "mozilla/net/FTPChannelChild.h"
|
||||
#include "mozilla/net/DataChannelChild.h"
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
# include "mozilla/net/GIOChannelChild.h"
|
||||
@@ -127,6 +128,22 @@ bool NeckoChild::DeallocPAltDataOutputStreamChild(
|
||||
return true;
|
||||
}
|
||||
|
||||
PFTPChannelChild* NeckoChild::AllocPFTPChannelChild(
|
||||
PBrowserChild* aBrowser, const SerializedLoadContext& aSerialized,
|
||||
const FTPChannelCreationArgs& aOpenArgs) {
|
||||
// We don't allocate here: see FTPChannelChild::AsyncOpen()
|
||||
MOZ_CRASH("AllocPFTPChannelChild should not be called");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool NeckoChild::DeallocPFTPChannelChild(PFTPChannelChild* channel) {
|
||||
MOZ_ASSERT(IsNeckoChild(), "DeallocPFTPChannelChild called by non-child!");
|
||||
|
||||
FTPChannelChild* child = static_cast<FTPChannelChild*>(channel);
|
||||
child->ReleaseIPDLReference();
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
PGIOChannelChild* NeckoChild::AllocPGIOChannelChild(
|
||||
PBrowserChild* aBrowser, const SerializedLoadContext& aSerialized,
|
||||
|
||||
@@ -38,6 +38,10 @@ class NeckoChild : public PNeckoChild {
|
||||
|
||||
PCookieServiceChild* AllocPCookieServiceChild();
|
||||
bool DeallocPCookieServiceChild(PCookieServiceChild*);
|
||||
PFTPChannelChild* AllocPFTPChannelChild(
|
||||
PBrowserChild* aBrowser, const SerializedLoadContext& aSerialized,
|
||||
const FTPChannelCreationArgs& aOpenArgs);
|
||||
bool DeallocPFTPChannelChild(PFTPChannelChild*);
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
PGIOChannelChild* AllocPGIOChannelChild(
|
||||
PBrowserChild* aBrowser, const SerializedLoadContext& aSerialized,
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "mozilla/net/NeckoParent.h"
|
||||
#include "mozilla/net/HttpChannelParent.h"
|
||||
#include "mozilla/net/CookieServiceParent.h"
|
||||
#include "mozilla/net/FTPChannelParent.h"
|
||||
#include "mozilla/net/WebSocketChannelParent.h"
|
||||
#include "mozilla/net/WebSocketEventListenerParent.h"
|
||||
#include "mozilla/net/DataChannelParent.h"
|
||||
@@ -125,6 +126,16 @@ static already_AddRefed<nsIPrincipal> GetRequestingPrincipal(
|
||||
return GetRequestingPrincipal(args.loadInfo());
|
||||
}
|
||||
|
||||
static already_AddRefed<nsIPrincipal> GetRequestingPrincipal(
|
||||
const FTPChannelCreationArgs& aArgs) {
|
||||
if (aArgs.type() != FTPChannelCreationArgs::TFTPChannelOpenArgs) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const FTPChannelOpenArgs& args = aArgs.get_FTPChannelOpenArgs();
|
||||
return GetRequestingPrincipal(args.loadInfo());
|
||||
}
|
||||
|
||||
const char* NeckoParent::GetValidatedOriginAttributes(
|
||||
const SerializedLoadContext& aSerialized, PContentParent* aContent,
|
||||
nsIPrincipal* aRequestingPrincipal, OriginAttributes& aAttrs) {
|
||||
@@ -267,6 +278,47 @@ bool NeckoParent::DeallocPAltDataOutputStreamParent(
|
||||
return true;
|
||||
}
|
||||
|
||||
PFTPChannelParent* NeckoParent::AllocPFTPChannelParent(
|
||||
PBrowserParent* aBrowser, const SerializedLoadContext& aSerialized,
|
||||
const FTPChannelCreationArgs& aOpenArgs) {
|
||||
nsCOMPtr<nsIPrincipal> requestingPrincipal =
|
||||
GetRequestingPrincipal(aOpenArgs);
|
||||
|
||||
nsCOMPtr<nsILoadContext> loadContext;
|
||||
const char* error = CreateChannelLoadContext(
|
||||
aBrowser, Manager(), aSerialized, requestingPrincipal, loadContext);
|
||||
if (error) {
|
||||
printf_stderr(
|
||||
"NeckoParent::AllocPFTPChannelParent: "
|
||||
"FATAL error: %s: KILLING CHILD PROCESS\n",
|
||||
error);
|
||||
return nullptr;
|
||||
}
|
||||
PBOverrideStatus overrideStatus =
|
||||
PBOverrideStatusFromLoadContext(aSerialized);
|
||||
FTPChannelParent* p = new FTPChannelParent(BrowserParent::GetFrom(aBrowser),
|
||||
loadContext, overrideStatus);
|
||||
p->AddRef();
|
||||
return p;
|
||||
}
|
||||
|
||||
bool NeckoParent::DeallocPFTPChannelParent(PFTPChannelParent* channel) {
|
||||
FTPChannelParent* p = static_cast<FTPChannelParent*>(channel);
|
||||
p->Release();
|
||||
return true;
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult NeckoParent::RecvPFTPChannelConstructor(
|
||||
PFTPChannelParent* aActor, PBrowserParent* aBrowser,
|
||||
const SerializedLoadContext& aSerialized,
|
||||
const FTPChannelCreationArgs& aOpenArgs) {
|
||||
FTPChannelParent* p = static_cast<FTPChannelParent*>(aActor);
|
||||
if (!p->Init(aOpenArgs)) {
|
||||
return IPC_FAIL_NO_REASON(this);
|
||||
}
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
already_AddRefed<PDocumentChannelParent>
|
||||
NeckoParent::AllocPDocumentChannelParent(
|
||||
const MaybeDiscarded<BrowsingContext>& aContext,
|
||||
|
||||
@@ -110,6 +110,14 @@ class NeckoParent : public PNeckoParent {
|
||||
bool DeallocPAltDataOutputStreamParent(PAltDataOutputStreamParent* aActor);
|
||||
|
||||
bool DeallocPCookieServiceParent(PCookieServiceParent*);
|
||||
PFTPChannelParent* AllocPFTPChannelParent(
|
||||
PBrowserParent* aBrowser, const SerializedLoadContext& aSerialized,
|
||||
const FTPChannelCreationArgs& aOpenArgs);
|
||||
virtual mozilla::ipc::IPCResult RecvPFTPChannelConstructor(
|
||||
PFTPChannelParent* aActor, PBrowserParent* aBrowser,
|
||||
const SerializedLoadContext& aSerialized,
|
||||
const FTPChannelCreationArgs& aOpenArgs) override;
|
||||
bool DeallocPFTPChannelParent(PFTPChannelParent*);
|
||||
PWebSocketParent* AllocPWebSocketParent(
|
||||
PBrowserParent* browser, const SerializedLoadContext& aSerialized,
|
||||
const uint32_t& aSerial);
|
||||
|
||||
@@ -9,6 +9,7 @@ include protocol PContent;
|
||||
include protocol PHttpChannel;
|
||||
include protocol PCookieService;
|
||||
include protocol PBrowser;
|
||||
include protocol PFTPChannel;
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
include protocol PGIOChannel;
|
||||
#endif
|
||||
@@ -54,6 +55,7 @@ nested(upto inside_cpow) sync protocol PNecko
|
||||
manager PContent;
|
||||
manages PHttpChannel;
|
||||
manages PCookieService;
|
||||
manages PFTPChannel;
|
||||
manages PWebSocket;
|
||||
manages PWebSocketEventListener;
|
||||
manages PTCPSocket;
|
||||
@@ -80,6 +82,8 @@ parent:
|
||||
async PHttpChannel(nullable PBrowser browser,
|
||||
SerializedLoadContext loadContext,
|
||||
HttpChannelCreationArgs args);
|
||||
async PFTPChannel(nullable PBrowser browser, SerializedLoadContext loadContext,
|
||||
FTPChannelCreationArgs args);
|
||||
|
||||
async PWebSocket(nullable PBrowser browser, SerializedLoadContext loadContext,
|
||||
uint32_t aSerialID);
|
||||
|
||||
541
netwerk/protocol/ftp/FTPChannelChild.cpp
Normal file
541
netwerk/protocol/ftp/FTPChannelChild.cpp
Normal file
@@ -0,0 +1,541 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set sw=2 ts=8 et tw=80 : */
|
||||
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/net/NeckoChild.h"
|
||||
#include "mozilla/net/FTPChannelChild.h"
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
#include "mozilla/dom/DocGroup.h"
|
||||
#include "mozilla/dom/BrowserChild.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsFtpProtocolHandler.h"
|
||||
#include "nsIBrowserChild.h"
|
||||
#include "nsStringStream.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "base/compiler_specific.h"
|
||||
#include "mozilla/ipc/IPCStreamUtils.h"
|
||||
#include "mozilla/ipc/URIUtils.h"
|
||||
#include "SerializedLoadContext.h"
|
||||
#include "mozilla/ipc/BackgroundUtils.h"
|
||||
#include "nsIURIMutator.h"
|
||||
#include "nsContentSecurityManager.h"
|
||||
#include "mozilla/ScopeExit.h"
|
||||
|
||||
using mozilla::dom::ContentChild;
|
||||
using namespace mozilla::ipc;
|
||||
|
||||
#undef LOG
|
||||
#define LOG(args) MOZ_LOG(gFTPLog, mozilla::LogLevel::Debug, args)
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
FTPChannelChild::FTPChannelChild(nsIURI* aUri)
|
||||
: mIPCOpen(false),
|
||||
mEventQ(new ChannelEventQueue(static_cast<nsIFTPChannel*>(this))),
|
||||
mCanceled(false),
|
||||
mSuspendCount(0),
|
||||
mIsPending(false),
|
||||
mLastModifiedTime(0),
|
||||
mStartPos(0),
|
||||
mSuspendSent(false) {
|
||||
LOG(("Creating FTPChannelChild @%p\n", this));
|
||||
// grab a reference to the handler to ensure that it doesn't go away.
|
||||
NS_ADDREF(gFtpHandler);
|
||||
SetURI(aUri);
|
||||
|
||||
// We could support thread retargeting, but as long as we're being driven by
|
||||
// IPDL on the main thread it doesn't buy us anything.
|
||||
DisallowThreadRetargeting();
|
||||
}
|
||||
|
||||
FTPChannelChild::~FTPChannelChild() {
|
||||
LOG(("Destroying FTPChannelChild @%p\n", this));
|
||||
gFtpHandler->Release();
|
||||
}
|
||||
|
||||
void FTPChannelChild::AddIPDLReference() {
|
||||
MOZ_ASSERT(!mIPCOpen, "Attempt to retain more than one IPDL reference");
|
||||
mIPCOpen = true;
|
||||
AddRef();
|
||||
}
|
||||
|
||||
void FTPChannelChild::ReleaseIPDLReference() {
|
||||
MOZ_ASSERT(mIPCOpen, "Attempt to release nonexistent IPDL reference");
|
||||
mIPCOpen = false;
|
||||
Release();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// FTPChannelChild::nsISupports
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED(FTPChannelChild, nsBaseChannel, nsIFTPChannel,
|
||||
nsIUploadChannel, nsIResumableChannel,
|
||||
nsIProxiedChannel, nsIChildChannel)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NS_IMETHODIMP
|
||||
FTPChannelChild::GetLastModifiedTime(PRTime* aLastModifiedTime) {
|
||||
*aLastModifiedTime = mLastModifiedTime;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FTPChannelChild::SetLastModifiedTime(PRTime aLastModifiedTime) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FTPChannelChild::ResumeAt(uint64_t aStartPos, const nsACString& aEntityID) {
|
||||
NS_ENSURE_TRUE(!mIsPending, NS_ERROR_IN_PROGRESS);
|
||||
mStartPos = aStartPos;
|
||||
mEntityID = aEntityID;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FTPChannelChild::GetEntityID(nsACString& aEntityID) {
|
||||
aEntityID = mEntityID;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FTPChannelChild::GetProxyInfo(nsIProxyInfo** aProxyInfo) { DROP_DEAD(); }
|
||||
|
||||
NS_IMETHODIMP FTPChannelChild::GetHttpProxyConnectResponseCode(
|
||||
int32_t* aResponseCode) {
|
||||
DROP_DEAD();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FTPChannelChild::SetUploadStream(nsIInputStream* aStream,
|
||||
const nsACString& aContentType,
|
||||
int64_t aContentLength) {
|
||||
NS_ENSURE_TRUE(!mIsPending, NS_ERROR_IN_PROGRESS);
|
||||
mUploadStream = aStream;
|
||||
// NOTE: contentLength is intentionally ignored here.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FTPChannelChild::GetUploadStream(nsIInputStream** aStream) {
|
||||
NS_ENSURE_ARG_POINTER(aStream);
|
||||
*aStream = mUploadStream;
|
||||
NS_IF_ADDREF(*aStream);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FTPChannelChild::AsyncOpen(nsIStreamListener* aListener) {
|
||||
nsCOMPtr<nsIStreamListener> listener = aListener;
|
||||
nsresult rv =
|
||||
nsContentSecurityManager::doContentSecurityCheck(this, listener);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
LOG(("FTPChannelChild::AsyncOpen [this=%p]\n", this));
|
||||
|
||||
NS_ENSURE_TRUE((gNeckoChild), NS_ERROR_FAILURE);
|
||||
NS_ENSURE_TRUE(
|
||||
!static_cast<ContentChild*>(gNeckoChild->Manager())->IsShuttingDown(),
|
||||
NS_ERROR_FAILURE);
|
||||
NS_ENSURE_ARG_POINTER(listener);
|
||||
NS_ENSURE_TRUE(!mIsPending, NS_ERROR_IN_PROGRESS);
|
||||
NS_ENSURE_TRUE(!mWasOpened, NS_ERROR_ALREADY_OPENED);
|
||||
|
||||
// Port checked in parent, but duplicate here so we can return with error
|
||||
// immediately, as we've done since before e10s.
|
||||
rv = NS_CheckPortSafety(nsBaseChannel::URI()); // Need to disambiguate,
|
||||
// because in the child ipdl,
|
||||
// a typedef URI is defined...
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
mozilla::dom::BrowserChild* browserChild = nullptr;
|
||||
nsCOMPtr<nsIBrowserChild> iBrowserChild;
|
||||
NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup,
|
||||
NS_GET_IID(nsIBrowserChild),
|
||||
getter_AddRefs(iBrowserChild));
|
||||
GetCallback(iBrowserChild);
|
||||
if (iBrowserChild) {
|
||||
browserChild =
|
||||
static_cast<mozilla::dom::BrowserChild*>(iBrowserChild.get());
|
||||
}
|
||||
|
||||
mListener = listener;
|
||||
|
||||
// add ourselves to the load group.
|
||||
if (mLoadGroup) mLoadGroup->AddRequest(this, nullptr);
|
||||
|
||||
mozilla::ipc::AutoIPCStream autoStream;
|
||||
autoStream.Serialize(mUploadStream,
|
||||
static_cast<ContentChild*>(gNeckoChild->Manager()));
|
||||
|
||||
uint32_t loadFlags = 0;
|
||||
GetLoadFlags(&loadFlags);
|
||||
|
||||
FTPChannelOpenArgs openArgs;
|
||||
SerializeURI(nsBaseChannel::URI(), openArgs.uri());
|
||||
openArgs.startPos() = mStartPos;
|
||||
openArgs.entityID() = mEntityID;
|
||||
openArgs.uploadStream() = autoStream.TakeOptionalValue();
|
||||
openArgs.loadFlags() = loadFlags;
|
||||
|
||||
nsCOMPtr<nsILoadInfo> loadInfo = LoadInfo();
|
||||
rv = mozilla::ipc::LoadInfoToLoadInfoArgs(loadInfo, &openArgs.loadInfo());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// This must happen before the constructor message is sent.
|
||||
SetupNeckoTarget();
|
||||
|
||||
gNeckoChild->SendPFTPChannelConstructor(
|
||||
this, browserChild, IPC::SerializedLoadContext(this), openArgs);
|
||||
|
||||
// The socket transport layer in the chrome process now has a logical ref to
|
||||
// us until OnStopRequest is called.
|
||||
AddIPDLReference();
|
||||
|
||||
mIsPending = true;
|
||||
mWasOpened = true;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FTPChannelChild::IsPending(bool* aResult) {
|
||||
*aResult = mIsPending;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult FTPChannelChild::OpenContentStream(bool aAsync,
|
||||
nsIInputStream** aStream,
|
||||
nsIChannel** aChannel) {
|
||||
MOZ_CRASH("FTPChannel*Child* should never have OpenContentStream called!");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// FTPChannelChild::PFTPChannelChild
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
mozilla::ipc::IPCResult FTPChannelChild::RecvOnStartRequest(
|
||||
const nsresult& aChannelStatus, const int64_t& aContentLength,
|
||||
const nsCString& aContentType, const PRTime& aLastModified,
|
||||
const nsCString& aEntityID, const URIParams& aURI) {
|
||||
LOG(("FTPChannelChild::RecvOnStartRequest [this=%p]\n", this));
|
||||
|
||||
mEventQ->RunOrEnqueue(new NeckoTargetChannelFunctionEvent(
|
||||
this, [self = UnsafePtr<FTPChannelChild>(this), aChannelStatus,
|
||||
aContentLength, aContentType, aLastModified, aEntityID, aURI]() {
|
||||
self->DoOnStartRequest(aChannelStatus, aContentLength, aContentType,
|
||||
aLastModified, aEntityID, aURI);
|
||||
}));
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
void FTPChannelChild::DoOnStartRequest(const nsresult& aChannelStatus,
|
||||
const int64_t& aContentLength,
|
||||
const nsCString& aContentType,
|
||||
const PRTime& aLastModified,
|
||||
const nsCString& aEntityID,
|
||||
const URIParams& aURI) {
|
||||
mDuringOnStart = true;
|
||||
RefPtr<FTPChannelChild> self = this;
|
||||
auto clearDuringFlag =
|
||||
mozilla::MakeScopeExit([self] { self->mDuringOnStart = false; });
|
||||
|
||||
LOG(("FTPChannelChild::DoOnStartRequest [this=%p]\n", this));
|
||||
|
||||
if (!mCanceled && NS_SUCCEEDED(mStatus)) {
|
||||
mStatus = aChannelStatus;
|
||||
}
|
||||
|
||||
mContentLength = aContentLength;
|
||||
SetContentType(aContentType);
|
||||
mLastModifiedTime = aLastModified;
|
||||
mEntityID = aEntityID;
|
||||
|
||||
nsCString spec;
|
||||
nsCOMPtr<nsIURI> uri = DeserializeURI(aURI);
|
||||
nsresult rv = uri->GetSpec(spec);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// Changes nsBaseChannel::URI()
|
||||
rv = NS_MutateURI(mURI).SetSpec(spec).Finalize(mURI);
|
||||
if (NS_FAILED(rv)) {
|
||||
Cancel(rv);
|
||||
}
|
||||
} else {
|
||||
Cancel(rv);
|
||||
}
|
||||
|
||||
AutoEventEnqueuer ensureSerialDispatch(mEventQ);
|
||||
rv = mListener->OnStartRequest(this);
|
||||
if (NS_FAILED(rv)) Cancel(rv);
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult FTPChannelChild::RecvOnDataAvailable(
|
||||
const nsresult& aChannelStatus, const nsCString& aData,
|
||||
const uint64_t& aOffset, const uint32_t& aCount) {
|
||||
LOG(("FTPChannelChild::RecvOnDataAvailable [this=%p]\n", this));
|
||||
|
||||
mEventQ->RunOrEnqueue(new NeckoTargetChannelFunctionEvent(
|
||||
this, [self = UnsafePtr<FTPChannelChild>(this), aChannelStatus, aData,
|
||||
aOffset, aCount]() {
|
||||
self->DoOnDataAvailable(aChannelStatus, aData, aOffset, aCount);
|
||||
}));
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
void FTPChannelChild::DoOnDataAvailable(const nsresult& aChannelStatus,
|
||||
const nsCString& aData,
|
||||
const uint64_t& aOffset,
|
||||
const uint32_t& aCount) {
|
||||
LOG(("FTPChannelChild::DoOnDataAvailable [this=%p]\n", this));
|
||||
|
||||
if (!mCanceled && NS_SUCCEEDED(mStatus)) {
|
||||
mStatus = aChannelStatus;
|
||||
}
|
||||
|
||||
if (mCanceled) {
|
||||
return;
|
||||
}
|
||||
|
||||
// NOTE: the OnDataAvailable contract requires the client to read all the data
|
||||
// in the inputstream. This code relies on that ('data' will go away after
|
||||
// this function). Apparently the previous, non-e10s behavior was to actually
|
||||
// support only reading part of the data, allowing later calls to read the
|
||||
// rest.
|
||||
nsCOMPtr<nsIInputStream> stringStream;
|
||||
nsresult rv =
|
||||
NS_NewByteInputStream(getter_AddRefs(stringStream),
|
||||
Span(aData).To(aCount), NS_ASSIGNMENT_DEPEND);
|
||||
if (NS_FAILED(rv)) {
|
||||
Cancel(rv);
|
||||
return;
|
||||
}
|
||||
|
||||
AutoEventEnqueuer ensureSerialDispatch(mEventQ);
|
||||
rv = mListener->OnDataAvailable(this, stringStream, aOffset, aCount);
|
||||
if (NS_FAILED(rv)) {
|
||||
Cancel(rv);
|
||||
}
|
||||
stringStream->Close();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult FTPChannelChild::RecvOnStopRequest(
|
||||
const nsresult& aChannelStatus, const nsCString& aErrorMsg,
|
||||
const bool& aUseUTF8) {
|
||||
LOG(("FTPChannelChild::RecvOnStopRequest [this=%p status=%" PRIx32 "]\n",
|
||||
this, static_cast<uint32_t>(aChannelStatus)));
|
||||
|
||||
mEventQ->RunOrEnqueue(new NeckoTargetChannelFunctionEvent(
|
||||
this, [self = UnsafePtr<FTPChannelChild>(this), aChannelStatus, aErrorMsg,
|
||||
aUseUTF8]() {
|
||||
self->DoOnStopRequest(aChannelStatus, aErrorMsg, aUseUTF8);
|
||||
}));
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
void FTPChannelChild::DoOnStopRequest(const nsresult& aChannelStatus,
|
||||
const nsCString& aErrorMsg,
|
||||
bool aUseUTF8) {
|
||||
LOG(("FTPChannelChild::DoOnStopRequest [this=%p status=%" PRIx32 "]\n", this,
|
||||
static_cast<uint32_t>(aChannelStatus)));
|
||||
|
||||
if (!mCanceled) mStatus = aChannelStatus;
|
||||
|
||||
{ // Ensure that all queued ipdl events are dispatched before
|
||||
// we initiate protocol deletion below.
|
||||
mIsPending = false;
|
||||
AutoEventEnqueuer ensureSerialDispatch(mEventQ);
|
||||
(void)mListener->OnStopRequest(this, aChannelStatus);
|
||||
|
||||
mListener = nullptr;
|
||||
|
||||
if (mLoadGroup) {
|
||||
mLoadGroup->RemoveRequest(this, nullptr, aChannelStatus);
|
||||
}
|
||||
}
|
||||
|
||||
// This calls NeckoChild::DeallocPFTPChannelChild(), which deletes |this| if
|
||||
// IPDL holds the last reference. Don't rely on |this| existing after here!
|
||||
Send__delete__(this);
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult FTPChannelChild::RecvFailedAsyncOpen(
|
||||
const nsresult& aStatusCode) {
|
||||
LOG(("FTPChannelChild::RecvFailedAsyncOpen [this=%p status=%" PRIx32 "]\n",
|
||||
this, static_cast<uint32_t>(aStatusCode)));
|
||||
mEventQ->RunOrEnqueue(new NeckoTargetChannelFunctionEvent(
|
||||
this, [self = UnsafePtr<FTPChannelChild>(this), aStatusCode]() {
|
||||
self->DoFailedAsyncOpen(aStatusCode);
|
||||
}));
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
void FTPChannelChild::DoFailedAsyncOpen(const nsresult& aStatusCode) {
|
||||
LOG(("FTPChannelChild::DoFailedAsyncOpen [this=%p status=%" PRIx32 "]\n",
|
||||
this, static_cast<uint32_t>(aStatusCode)));
|
||||
mStatus = aStatusCode;
|
||||
|
||||
if (mLoadGroup) {
|
||||
mLoadGroup->RemoveRequest(this, nullptr, aStatusCode);
|
||||
}
|
||||
|
||||
if (mListener) {
|
||||
mListener->OnStartRequest(this);
|
||||
mIsPending = false;
|
||||
mListener->OnStopRequest(this, aStatusCode);
|
||||
} else {
|
||||
mIsPending = false;
|
||||
}
|
||||
|
||||
mListener = nullptr;
|
||||
|
||||
if (mIPCOpen) {
|
||||
Send__delete__(this);
|
||||
}
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult FTPChannelChild::RecvDeleteSelf() {
|
||||
mEventQ->RunOrEnqueue(new NeckoTargetChannelFunctionEvent(
|
||||
this,
|
||||
[self = UnsafePtr<FTPChannelChild>(this)]() { self->DoDeleteSelf(); }));
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
void FTPChannelChild::DoDeleteSelf() {
|
||||
if (mIPCOpen) {
|
||||
Send__delete__(this);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FTPChannelChild::Cancel(nsresult aStatus) {
|
||||
LOG(("FTPChannelChild::Cancel [this=%p]\n", this));
|
||||
if (mCanceled) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
mCanceled = true;
|
||||
mStatus = aStatus;
|
||||
if (mIPCOpen) {
|
||||
SendCancel(aStatus);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FTPChannelChild::Suspend() {
|
||||
NS_ENSURE_TRUE(mIPCOpen, NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
LOG(("FTPChannelChild::Suspend [this=%p]\n", this));
|
||||
|
||||
// SendSuspend only once, when suspend goes from 0 to 1.
|
||||
if (!mSuspendCount++) {
|
||||
SendSuspend();
|
||||
mSuspendSent = true;
|
||||
}
|
||||
mEventQ->Suspend();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FTPChannelChild::Resume() {
|
||||
NS_ENSURE_TRUE(mIPCOpen, NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
LOG(("FTPChannelChild::Resume [this=%p]\n", this));
|
||||
|
||||
// SendResume only once, when suspend count drops to 0.
|
||||
if (!--mSuspendCount && mSuspendSent) {
|
||||
SendResume();
|
||||
}
|
||||
mEventQ->Resume();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// FTPChannelChild::nsIChildChannel
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NS_IMETHODIMP
|
||||
FTPChannelChild::ConnectParent(uint32_t aId) {
|
||||
NS_ENSURE_TRUE((gNeckoChild), NS_ERROR_FAILURE);
|
||||
NS_ENSURE_TRUE(
|
||||
!static_cast<ContentChild*>(gNeckoChild->Manager())->IsShuttingDown(),
|
||||
NS_ERROR_FAILURE);
|
||||
|
||||
LOG(("FTPChannelChild::ConnectParent [this=%p]\n", this));
|
||||
|
||||
mozilla::dom::BrowserChild* browserChild = nullptr;
|
||||
nsCOMPtr<nsIBrowserChild> iBrowserChild;
|
||||
NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup,
|
||||
NS_GET_IID(nsIBrowserChild),
|
||||
getter_AddRefs(iBrowserChild));
|
||||
GetCallback(iBrowserChild);
|
||||
if (iBrowserChild) {
|
||||
browserChild =
|
||||
static_cast<mozilla::dom::BrowserChild*>(iBrowserChild.get());
|
||||
}
|
||||
|
||||
// This must happen before the constructor message is sent.
|
||||
SetupNeckoTarget();
|
||||
|
||||
// The socket transport in the chrome process now holds a logical ref to us
|
||||
// until OnStopRequest, or we do a redirect, or we hit an IPDL error.
|
||||
AddIPDLReference();
|
||||
|
||||
FTPChannelConnectArgs connectArgs(aId);
|
||||
|
||||
if (!gNeckoChild->SendPFTPChannelConstructor(
|
||||
this, browserChild, IPC::SerializedLoadContext(this), connectArgs)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FTPChannelChild::CompleteRedirectSetup(nsIStreamListener* aListener) {
|
||||
LOG(("FTPChannelChild::CompleteRedirectSetup [this=%p]\n", this));
|
||||
|
||||
NS_ENSURE_TRUE(!mIsPending, NS_ERROR_IN_PROGRESS);
|
||||
NS_ENSURE_TRUE(!mWasOpened, NS_ERROR_ALREADY_OPENED);
|
||||
|
||||
mIsPending = true;
|
||||
mWasOpened = true;
|
||||
mListener = aListener;
|
||||
|
||||
// add ourselves to the load group.
|
||||
if (mLoadGroup) {
|
||||
mLoadGroup->AddRequest(this, nullptr);
|
||||
}
|
||||
|
||||
// We already have an open IPDL connection to the parent. If on-modify-request
|
||||
// listeners or load group observers canceled us, let the parent handle it
|
||||
// and send it back to us naturally.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void FTPChannelChild::SetupNeckoTarget() {
|
||||
if (mNeckoTarget) {
|
||||
return;
|
||||
}
|
||||
nsCOMPtr<nsILoadInfo> loadInfo = LoadInfo();
|
||||
mNeckoTarget =
|
||||
nsContentUtils::GetEventTargetByLoadInfo(loadInfo, TaskCategory::Network);
|
||||
if (!mNeckoTarget) {
|
||||
return;
|
||||
}
|
||||
|
||||
gNeckoChild->SetEventTargetForActor(this, mNeckoTarget);
|
||||
}
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
||||
137
netwerk/protocol/ftp/FTPChannelChild.h
Normal file
137
netwerk/protocol/ftp/FTPChannelChild.h
Normal file
@@ -0,0 +1,137 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set sw=2 ts=8 et tw=80 : */
|
||||
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_net_FTPChannelChild_h
|
||||
#define mozilla_net_FTPChannelChild_h
|
||||
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/net/PFTPChannelChild.h"
|
||||
#include "mozilla/net/ChannelEventQueue.h"
|
||||
#include "nsBaseChannel.h"
|
||||
#include "nsIFTPChannel.h"
|
||||
#include "nsIUploadChannel.h"
|
||||
#include "nsIProxiedChannel.h"
|
||||
#include "nsIResumableChannel.h"
|
||||
#include "nsIChildChannel.h"
|
||||
#include "nsIEventTarget.h"
|
||||
|
||||
#include "nsIStreamListener.h"
|
||||
#include "mozilla/net/PrivateBrowsingChannel.h"
|
||||
|
||||
class nsIEventTarget;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
namespace net {
|
||||
|
||||
// This class inherits logic from nsBaseChannel that is not needed for an
|
||||
// e10s child channel, but it works. At some point we could slice up
|
||||
// nsBaseChannel and have a new class that has only the common logic for
|
||||
// nsFTPChannel/FTPChannelChild.
|
||||
|
||||
class FTPChannelChild final : public PFTPChannelChild,
|
||||
public nsBaseChannel,
|
||||
public nsIFTPChannel,
|
||||
public nsIUploadChannel,
|
||||
public nsIResumableChannel,
|
||||
public nsIProxiedChannel,
|
||||
public nsIChildChannel {
|
||||
public:
|
||||
typedef ::nsIStreamListener nsIStreamListener;
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIFTPCHANNEL
|
||||
NS_DECL_NSIUPLOADCHANNEL
|
||||
NS_DECL_NSIRESUMABLECHANNEL
|
||||
NS_DECL_NSIPROXIEDCHANNEL
|
||||
NS_DECL_NSICHILDCHANNEL
|
||||
|
||||
NS_IMETHOD Cancel(nsresult aStatus) override;
|
||||
NS_IMETHOD Suspend() override;
|
||||
NS_IMETHOD Resume() override;
|
||||
|
||||
explicit FTPChannelChild(nsIURI* aUri);
|
||||
|
||||
void AddIPDLReference();
|
||||
void ReleaseIPDLReference();
|
||||
|
||||
NS_IMETHOD AsyncOpen(nsIStreamListener* aListener) override;
|
||||
|
||||
// Note that we handle this ourselves, overriding the nsBaseChannel
|
||||
// default behavior, in order to be e10s-friendly.
|
||||
NS_IMETHOD IsPending(bool* aResult) override;
|
||||
|
||||
nsresult OpenContentStream(bool aAsync, nsIInputStream** aStream,
|
||||
nsIChannel** aChannel) override;
|
||||
|
||||
bool IsSuspended() const;
|
||||
|
||||
protected:
|
||||
virtual ~FTPChannelChild();
|
||||
|
||||
mozilla::ipc::IPCResult RecvOnStartRequest(const nsresult& aChannelStatus,
|
||||
const int64_t& aContentLength,
|
||||
const nsCString& aContentType,
|
||||
const PRTime& aLastModified,
|
||||
const nsCString& aEntityID,
|
||||
const URIParams& aURI) override;
|
||||
mozilla::ipc::IPCResult RecvOnDataAvailable(const nsresult& aChannelStatus,
|
||||
const nsCString& aData,
|
||||
const uint64_t& aOffset,
|
||||
const uint32_t& aCount) override;
|
||||
mozilla::ipc::IPCResult RecvOnStopRequest(const nsresult& aChannelStatus,
|
||||
const nsCString& aErrorMsg,
|
||||
const bool& aUseUTF8) override;
|
||||
mozilla::ipc::IPCResult RecvFailedAsyncOpen(
|
||||
const nsresult& aStatusCode) override;
|
||||
mozilla::ipc::IPCResult RecvDeleteSelf() override;
|
||||
|
||||
void DoOnStartRequest(const nsresult& aChannelStatus,
|
||||
const int64_t& aContentLength,
|
||||
const nsCString& aContentType,
|
||||
const PRTime& aLastModified, const nsCString& aEntityID,
|
||||
const URIParams& aURI);
|
||||
void DoOnDataAvailable(const nsresult& aChannelStatus, const nsCString& aData,
|
||||
const uint64_t& aOffset, const uint32_t& aCount);
|
||||
void DoOnStopRequest(const nsresult& StatusCode, const nsCString& aErrorMsg,
|
||||
bool aUseUTF8);
|
||||
void DoFailedAsyncOpen(const nsresult& aStatusCode);
|
||||
void DoDeleteSelf();
|
||||
|
||||
void SetupNeckoTarget() override;
|
||||
|
||||
friend class NeckoTargetChannelFunctionEvent;
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIInputStream> mUploadStream;
|
||||
|
||||
bool mIPCOpen;
|
||||
const RefPtr<ChannelEventQueue> mEventQ;
|
||||
|
||||
bool mCanceled;
|
||||
uint32_t mSuspendCount;
|
||||
bool mIsPending;
|
||||
|
||||
// This will only be true while DoOnStartRequest is in progress.
|
||||
// It is used to enforce that DivertToParent is only called during that time.
|
||||
bool mDuringOnStart = false;
|
||||
|
||||
PRTime mLastModifiedTime;
|
||||
uint64_t mStartPos;
|
||||
nsCString mEntityID;
|
||||
|
||||
// Set if SendSuspend is called. Determines if SendResume is needed when
|
||||
// diverting callbacks to parent.
|
||||
bool mSuspendSent;
|
||||
};
|
||||
|
||||
inline bool FTPChannelChild::IsSuspended() const { return mSuspendCount != 0; }
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_net_FTPChannelChild_h
|
||||
418
netwerk/protocol/ftp/FTPChannelParent.cpp
Normal file
418
netwerk/protocol/ftp/FTPChannelParent.cpp
Normal file
@@ -0,0 +1,418 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set sw=2 ts=8 et tw=80 : */
|
||||
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/net/FTPChannelParent.h"
|
||||
#include "nsStringStream.h"
|
||||
#include "mozilla/net/ChannelEventQueue.h"
|
||||
#include "mozilla/dom/BrowserParent.h"
|
||||
#include "nsFTPChannel.h"
|
||||
#include "nsNetCID.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsQueryObject.h"
|
||||
#include "nsFtpProtocolHandler.h"
|
||||
#include "nsIAuthPrompt.h"
|
||||
#include "nsIAuthPromptProvider.h"
|
||||
#include "nsIHttpChannelInternal.h"
|
||||
#include "nsISecureBrowserUI.h"
|
||||
#include "nsIForcePendingChannel.h"
|
||||
#include "mozilla/ipc/IPCStreamUtils.h"
|
||||
#include "mozilla/ipc/URIUtils.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#include "SerializedLoadContext.h"
|
||||
#include "mozilla/ipc/BackgroundUtils.h"
|
||||
#include "mozilla/LoadInfo.h"
|
||||
#include "mozilla/dom/ContentParent.h"
|
||||
|
||||
using namespace mozilla::dom;
|
||||
using namespace mozilla::ipc;
|
||||
|
||||
#undef LOG
|
||||
#define LOG(args) MOZ_LOG(gFTPLog, mozilla::LogLevel::Debug, args)
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
FTPChannelParent::FTPChannelParent(dom::BrowserParent* aIframeEmbedding,
|
||||
nsILoadContext* aLoadContext,
|
||||
PBOverrideStatus aOverrideStatus)
|
||||
: mIPCClosed(false),
|
||||
mLoadContext(aLoadContext),
|
||||
mPBOverride(aOverrideStatus),
|
||||
mStatus(NS_OK),
|
||||
mBrowserParent(aIframeEmbedding),
|
||||
mUseUTF8(false) {
|
||||
nsIProtocolHandler* handler;
|
||||
CallGetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "ftp", &handler);
|
||||
MOZ_ASSERT(handler, "no ftp handler");
|
||||
|
||||
mEventQ = new ChannelEventQueue(static_cast<nsIParentChannel*>(this));
|
||||
}
|
||||
|
||||
FTPChannelParent::~FTPChannelParent() { gFtpHandler->Release(); }
|
||||
|
||||
void FTPChannelParent::ActorDestroy(ActorDestroyReason why) {
|
||||
// We may still have refcount>0 if the channel hasn't called OnStopRequest
|
||||
// yet, but we must not send any more msgs to child.
|
||||
mIPCClosed = true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// FTPChannelParent::nsISupports
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NS_IMPL_ISUPPORTS(FTPChannelParent, nsIStreamListener, nsIParentChannel,
|
||||
nsIInterfaceRequestor, nsIRequestObserver,
|
||||
nsIChannelEventSink, nsIFTPChannelParentInternal)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// FTPChannelParent::PFTPChannelParent
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// FTPChannelParent methods
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool FTPChannelParent::Init(const FTPChannelCreationArgs& aArgs) {
|
||||
switch (aArgs.type()) {
|
||||
case FTPChannelCreationArgs::TFTPChannelOpenArgs: {
|
||||
const FTPChannelOpenArgs& a = aArgs.get_FTPChannelOpenArgs();
|
||||
return DoAsyncOpen(a.uri(), a.startPos(), a.entityID(), a.uploadStream(),
|
||||
a.loadInfo(), a.loadFlags());
|
||||
}
|
||||
case FTPChannelCreationArgs::TFTPChannelConnectArgs: {
|
||||
const FTPChannelConnectArgs& cArgs = aArgs.get_FTPChannelConnectArgs();
|
||||
return ConnectChannel(cArgs.channelId());
|
||||
}
|
||||
default:
|
||||
MOZ_ASSERT_UNREACHABLE("unknown open type");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool FTPChannelParent::DoAsyncOpen(const URIParams& aURI,
|
||||
const uint64_t& aStartPos,
|
||||
const nsCString& aEntityID,
|
||||
const Maybe<IPCStream>& aUploadStream,
|
||||
const Maybe<LoadInfoArgs>& aLoadInfoArgs,
|
||||
const uint32_t& aLoadFlags) {
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsIURI> uri = DeserializeURI(aURI);
|
||||
if (!uri) return false;
|
||||
|
||||
#ifdef DEBUG
|
||||
LOG(("FTPChannelParent DoAsyncOpen [this=%p uri=%s]\n", this,
|
||||
uri->GetSpecOrDefault().get()));
|
||||
#endif
|
||||
|
||||
nsCOMPtr<nsIIOService> ios(do_GetIOService(&rv));
|
||||
if (NS_FAILED(rv)) {
|
||||
return SendFailedAsyncOpen(rv);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsILoadInfo> loadInfo;
|
||||
rv = mozilla::ipc::LoadInfoArgsToLoadInfo(aLoadInfoArgs,
|
||||
getter_AddRefs(loadInfo));
|
||||
if (NS_FAILED(rv)) {
|
||||
return SendFailedAsyncOpen(rv);
|
||||
}
|
||||
|
||||
OriginAttributes attrs;
|
||||
rv = loadInfo->GetOriginAttributes(&attrs);
|
||||
if (NS_FAILED(rv)) {
|
||||
return SendFailedAsyncOpen(rv);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIChannel> chan;
|
||||
rv = NS_NewChannelInternal(getter_AddRefs(chan), uri, loadInfo, nullptr,
|
||||
nullptr, nullptr, aLoadFlags, ios);
|
||||
|
||||
if (NS_FAILED(rv)) return SendFailedAsyncOpen(rv);
|
||||
|
||||
mChannel = chan;
|
||||
|
||||
// later on mChannel may become an HTTP channel (we'll be redirected to one
|
||||
// if we're using a proxy), but for now this is safe
|
||||
nsFtpChannel* ftpChan = static_cast<nsFtpChannel*>(mChannel.get());
|
||||
|
||||
if (mPBOverride != kPBOverride_Unset) {
|
||||
ftpChan->SetPrivate(mPBOverride == kPBOverride_Private ? true : false);
|
||||
}
|
||||
rv = ftpChan->SetNotificationCallbacks(this);
|
||||
if (NS_FAILED(rv)) return SendFailedAsyncOpen(rv);
|
||||
|
||||
nsCOMPtr<nsIInputStream> upload = DeserializeIPCStream(aUploadStream);
|
||||
if (upload) {
|
||||
// contentType and contentLength are ignored
|
||||
rv = ftpChan->SetUploadStream(upload, ""_ns, 0);
|
||||
if (NS_FAILED(rv)) return SendFailedAsyncOpen(rv);
|
||||
}
|
||||
|
||||
rv = ftpChan->ResumeAt(aStartPos, aEntityID);
|
||||
if (NS_FAILED(rv)) return SendFailedAsyncOpen(rv);
|
||||
|
||||
rv = ftpChan->AsyncOpen(this);
|
||||
|
||||
if (NS_FAILED(rv)) return SendFailedAsyncOpen(rv);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FTPChannelParent::ConnectChannel(const uint64_t& channelId) {
|
||||
nsresult rv;
|
||||
|
||||
LOG(("Looking for a registered channel [this=%p, id=%" PRIx64 "]", this,
|
||||
channelId));
|
||||
|
||||
nsCOMPtr<nsIChannel> channel;
|
||||
rv = NS_LinkRedirectChannels(channelId, this, getter_AddRefs(channel));
|
||||
if (NS_SUCCEEDED(rv)) mChannel = channel;
|
||||
|
||||
LOG((" found channel %p, rv=%08" PRIx32, mChannel.get(),
|
||||
static_cast<uint32_t>(rv)));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult FTPChannelParent::RecvCancel(const nsresult& status) {
|
||||
if (mChannel) mChannel->Cancel(status);
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult FTPChannelParent::RecvSuspend() {
|
||||
if (mChannel) {
|
||||
mChannel->Suspend();
|
||||
}
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult FTPChannelParent::RecvResume() {
|
||||
if (mChannel) {
|
||||
mChannel->Resume();
|
||||
}
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// FTPChannelParent::nsIRequestObserver
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NS_IMETHODIMP
|
||||
FTPChannelParent::OnStartRequest(nsIRequest* aRequest) {
|
||||
LOG(("FTPChannelParent::OnStartRequest [this=%p]\n", this));
|
||||
|
||||
nsCOMPtr<nsIChannel> chan = do_QueryInterface(aRequest);
|
||||
MOZ_ASSERT(chan);
|
||||
NS_ENSURE_TRUE(chan, NS_ERROR_UNEXPECTED);
|
||||
|
||||
// Send down any permissions which are relevant to this URL if we are
|
||||
// performing a document load.
|
||||
if (!mIPCClosed) {
|
||||
PContentParent* pcp = Manager()->Manager();
|
||||
MOZ_ASSERT(pcp, "We should have a manager if our IPC isn't closed");
|
||||
DebugOnly<nsresult> rv =
|
||||
static_cast<ContentParent*>(pcp)->AboutToLoadHttpFtpDocumentForChild(
|
||||
chan);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
}
|
||||
|
||||
int64_t contentLength;
|
||||
chan->GetContentLength(&contentLength);
|
||||
nsCString contentType;
|
||||
chan->GetContentType(contentType);
|
||||
nsresult channelStatus = NS_OK;
|
||||
chan->GetStatus(&channelStatus);
|
||||
|
||||
nsCString entityID;
|
||||
nsCOMPtr<nsIResumableChannel> resChan = do_QueryInterface(aRequest);
|
||||
MOZ_ASSERT(
|
||||
resChan); // both FTP and HTTP should implement nsIResumableChannel
|
||||
if (resChan) {
|
||||
resChan->GetEntityID(entityID);
|
||||
}
|
||||
|
||||
PRTime lastModified = 0;
|
||||
nsCOMPtr<nsIFTPChannel> ftpChan = do_QueryInterface(aRequest);
|
||||
if (ftpChan) {
|
||||
ftpChan->GetLastModifiedTime(&lastModified);
|
||||
}
|
||||
nsCOMPtr<nsIHttpChannelInternal> httpChan = do_QueryInterface(aRequest);
|
||||
if (httpChan) {
|
||||
Unused << httpChan->GetLastModifiedTime(&lastModified);
|
||||
}
|
||||
|
||||
URIParams uriparam;
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
chan->GetURI(getter_AddRefs(uri));
|
||||
SerializeURI(uri, uriparam);
|
||||
|
||||
if (mIPCClosed ||
|
||||
!SendOnStartRequest(channelStatus, contentLength, contentType,
|
||||
lastModified, entityID, uriparam)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FTPChannelParent::OnStopRequest(nsIRequest* aRequest, nsresult aStatusCode) {
|
||||
LOG(("FTPChannelParent::OnStopRequest: [this=%p status=%" PRIu32 "]\n", this,
|
||||
static_cast<uint32_t>(aStatusCode)));
|
||||
|
||||
if (mIPCClosed || !SendOnStopRequest(aStatusCode, mErrorMsg, mUseUTF8)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// FTPChannelParent::nsIStreamListener
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NS_IMETHODIMP
|
||||
FTPChannelParent::OnDataAvailable(nsIRequest* aRequest,
|
||||
nsIInputStream* aInputStream,
|
||||
uint64_t aOffset, uint32_t aCount) {
|
||||
LOG(("FTPChannelParent::OnDataAvailable [this=%p]\n", this));
|
||||
|
||||
nsCString data;
|
||||
nsresult rv = NS_ReadInputStreamToString(aInputStream, data, aCount);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsresult channelStatus = NS_OK;
|
||||
mChannel->GetStatus(&channelStatus);
|
||||
|
||||
if (mIPCClosed || !SendOnDataAvailable(channelStatus, data, aOffset, aCount))
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// FTPChannelParent::nsIParentChannel
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NS_IMETHODIMP
|
||||
FTPChannelParent::SetParentListener(ParentChannelListener* aListener) {
|
||||
// Do not need ptr to ParentChannelListener.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FTPChannelParent::NotifyClassificationFlags(uint32_t aClassificationFlags,
|
||||
bool aIsThirdParty) {
|
||||
// One day, this should probably be filled in.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FTPChannelParent::NotifyFlashPluginStateChanged(
|
||||
nsIHttpChannel::FlashPluginState aState) {
|
||||
// One day, this should probably be filled in.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FTPChannelParent::SetClassifierMatchedInfo(const nsACString& aList,
|
||||
const nsACString& aProvider,
|
||||
const nsACString& aFullHash) {
|
||||
// One day, this should probably be filled in.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FTPChannelParent::SetClassifierMatchedTrackingInfo(
|
||||
const nsACString& aLists, const nsACString& aFullHashes) {
|
||||
// One day, this should probably be filled in.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FTPChannelParent::Delete() {
|
||||
if (mIPCClosed || !SendDeleteSelf()) return NS_ERROR_UNEXPECTED;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FTPChannelParent::GetRemoteType(nsACString& aRemoteType) {
|
||||
if (!CanSend()) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
dom::PContentParent* pcp = Manager()->Manager();
|
||||
aRemoteType = static_cast<dom::ContentParent*>(pcp)->GetRemoteType();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// FTPChannelParent::nsIInterfaceRequestor
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NS_IMETHODIMP
|
||||
FTPChannelParent::GetInterface(const nsIID& uuid, void** result) {
|
||||
if (uuid.Equals(NS_GET_IID(nsIAuthPromptProvider)) ||
|
||||
uuid.Equals(NS_GET_IID(nsISecureBrowserUI))) {
|
||||
if (mBrowserParent) {
|
||||
return mBrowserParent->QueryInterface(uuid, result);
|
||||
}
|
||||
} else if (uuid.Equals(NS_GET_IID(nsIAuthPrompt)) ||
|
||||
uuid.Equals(NS_GET_IID(nsIAuthPrompt2))) {
|
||||
nsCOMPtr<nsIAuthPromptProvider> provider(do_QueryObject(mBrowserParent));
|
||||
if (provider) {
|
||||
nsresult rv = provider->GetAuthPrompt(
|
||||
nsIAuthPromptProvider::PROMPT_NORMAL, uuid, result);
|
||||
if (NS_FAILED(rv)) {
|
||||
return NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// Only support nsILoadContext if child channel's callbacks did too
|
||||
if (uuid.Equals(NS_GET_IID(nsILoadContext)) && mLoadContext) {
|
||||
nsCOMPtr<nsILoadContext> copy = mLoadContext;
|
||||
copy.forget(result);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return QueryInterface(uuid, result);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// FTPChannelParent::nsIChannelEventSink
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NS_IMETHODIMP
|
||||
FTPChannelParent::AsyncOnChannelRedirect(
|
||||
nsIChannel* oldChannel, nsIChannel* newChannel, uint32_t redirectFlags,
|
||||
nsIAsyncVerifyRedirectCallback* callback) {
|
||||
nsCOMPtr<nsIFTPChannel> ftpChan = do_QueryInterface(newChannel);
|
||||
if (!ftpChan) {
|
||||
// when FTP is set to use HTTP proxying, we wind up getting redirected to an
|
||||
// HTTP channel.
|
||||
nsCOMPtr<nsIHttpChannel> httpChan = do_QueryInterface(newChannel);
|
||||
if (!httpChan) return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
mChannel = newChannel;
|
||||
callback->OnRedirectVerifyCallback(NS_OK);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FTPChannelParent::SetErrorMsg(const char* aMsg, bool aUseUTF8) {
|
||||
mErrorMsg = aMsg;
|
||||
mUseUTF8 = aUseUTF8;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//---------------------
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
||||
92
netwerk/protocol/ftp/FTPChannelParent.h
Normal file
92
netwerk/protocol/ftp/FTPChannelParent.h
Normal file
@@ -0,0 +1,92 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set sw=2 ts=8 et tw=80 : */
|
||||
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_net_FTPChannelParent_h
|
||||
#define mozilla_net_FTPChannelParent_h
|
||||
|
||||
#include "mozilla/net/PFTPChannelParent.h"
|
||||
#include "mozilla/net/NeckoParent.h"
|
||||
#include "nsIParentChannel.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsIChannelEventSink.h"
|
||||
#include "nsIFTPChannelParentInternal.h"
|
||||
|
||||
class nsILoadContext;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
namespace dom {
|
||||
class BrowserParent;
|
||||
} // namespace dom
|
||||
|
||||
namespace net {
|
||||
class ChannelEventQueue;
|
||||
|
||||
class FTPChannelParent final : public PFTPChannelParent,
|
||||
public nsIParentChannel,
|
||||
public nsIInterfaceRequestor,
|
||||
public nsIChannelEventSink,
|
||||
public nsIFTPChannelParentInternal {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIREQUESTOBSERVER
|
||||
NS_DECL_NSISTREAMLISTENER
|
||||
NS_DECL_NSIPARENTCHANNEL
|
||||
NS_DECL_NSIINTERFACEREQUESTOR
|
||||
NS_DECL_NSICHANNELEVENTSINK
|
||||
|
||||
FTPChannelParent(dom::BrowserParent* aIframeEmbedding,
|
||||
nsILoadContext* aLoadContext,
|
||||
PBOverrideStatus aOverrideStatus);
|
||||
|
||||
bool Init(const FTPChannelCreationArgs& aOpenArgs);
|
||||
|
||||
NS_IMETHOD SetErrorMsg(const char* aMsg, bool aUseUTF8) override;
|
||||
|
||||
protected:
|
||||
virtual ~FTPChannelParent();
|
||||
|
||||
bool DoAsyncOpen(const URIParams& aURI, const uint64_t& aStartPos,
|
||||
const nsCString& aEntityID,
|
||||
const Maybe<IPCStream>& aUploadStream,
|
||||
const Maybe<LoadInfoArgs>& aLoadInfoArgs,
|
||||
const uint32_t& aLoadFlags);
|
||||
|
||||
// used to connect redirected-to channel in parent with just created
|
||||
// ChildChannel. Used during HTTP->FTP redirects.
|
||||
bool ConnectChannel(const uint64_t& channelId);
|
||||
|
||||
virtual mozilla::ipc::IPCResult RecvCancel(const nsresult& status) override;
|
||||
virtual mozilla::ipc::IPCResult RecvSuspend() override;
|
||||
virtual mozilla::ipc::IPCResult RecvResume() override;
|
||||
|
||||
virtual void ActorDestroy(ActorDestroyReason why) override;
|
||||
|
||||
// if configured to use HTTP proxy for FTP, this can an an HTTP channel.
|
||||
nsCOMPtr<nsIChannel> mChannel;
|
||||
|
||||
bool mIPCClosed;
|
||||
|
||||
nsCOMPtr<nsILoadContext> mLoadContext;
|
||||
|
||||
PBOverrideStatus mPBOverride;
|
||||
|
||||
// Set to the canceled status value if the main channel was canceled.
|
||||
nsresult mStatus;
|
||||
|
||||
RefPtr<mozilla::dom::BrowserParent> mBrowserParent;
|
||||
|
||||
RefPtr<ChannelEventQueue> mEventQ;
|
||||
|
||||
nsCString mErrorMsg;
|
||||
bool mUseUTF8;
|
||||
};
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_net_FTPChannelParent_h
|
||||
54
netwerk/protocol/ftp/PFTPChannel.ipdl
Normal file
54
netwerk/protocol/ftp/PFTPChannel.ipdl
Normal file
@@ -0,0 +1,54 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set sw=2 ts=8 et tw=80 ft=cpp : */
|
||||
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
include protocol PNecko;
|
||||
include URIParams;
|
||||
|
||||
//FIXME: bug #792908 (NeckoChannelParams already included by PNecko)
|
||||
include NeckoChannelParams;
|
||||
|
||||
using PRTime from "prtime.h";
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
async protocol PFTPChannel
|
||||
{
|
||||
manager PNecko;
|
||||
|
||||
parent:
|
||||
// Note: channels are opened during construction, so no open method here:
|
||||
// see PNecko.ipdl
|
||||
|
||||
async __delete__();
|
||||
|
||||
async Cancel(nsresult status);
|
||||
async Suspend();
|
||||
async Resume();
|
||||
|
||||
child:
|
||||
async OnStartRequest(nsresult aChannelStatus,
|
||||
int64_t aContentLength,
|
||||
nsCString aContentType,
|
||||
PRTime aLastModified,
|
||||
nsCString aEntityID,
|
||||
URIParams aURI);
|
||||
async OnDataAvailable(nsresult channelStatus,
|
||||
nsCString data,
|
||||
uint64_t offset,
|
||||
uint32_t count);
|
||||
async OnStopRequest(nsresult channelStatus,
|
||||
nsCString aErrorMsg,
|
||||
bool aUseUTF8);
|
||||
async FailedAsyncOpen(nsresult statusCode);
|
||||
|
||||
async DeleteSelf();
|
||||
};
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
||||
|
||||
3933
netwerk/protocol/ftp/doc/rfc959.txt
Normal file
3933
netwerk/protocol/ftp/doc/rfc959.txt
Normal file
File diff suppressed because it is too large
Load Diff
4
netwerk/protocol/ftp/doc/testdoc
Normal file
4
netwerk/protocol/ftp/doc/testdoc
Normal file
@@ -0,0 +1,4 @@
|
||||
Test
|
||||
here
|
||||
there
|
||||
everywhere
|
||||
15
netwerk/protocol/ftp/ftpCore.h
Normal file
15
netwerk/protocol/ftp/ftpCore.h
Normal file
@@ -0,0 +1,15 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef __ftpCore_h___
|
||||
#define __ftpCore_h___
|
||||
|
||||
#include "nsError.h"
|
||||
|
||||
/**
|
||||
* Status nsresult codes
|
||||
*/
|
||||
|
||||
#endif // __ftpCore_h___
|
||||
50
netwerk/protocol/ftp/moz.build
Normal file
50
netwerk/protocol/ftp/moz.build
Normal file
@@ -0,0 +1,50 @@
|
||||
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
with Files("**"):
|
||||
BUG_COMPONENT = ("Core", "Networking: FTP")
|
||||
|
||||
XPIDL_SOURCES += [
|
||||
"nsIFTPChannel.idl",
|
||||
"nsIFTPChannelParentInternal.idl",
|
||||
]
|
||||
|
||||
XPIDL_MODULE = "necko_ftp"
|
||||
|
||||
EXPORTS += [
|
||||
"ftpCore.h",
|
||||
]
|
||||
|
||||
EXPORTS.mozilla.net += [
|
||||
"FTPChannelChild.h",
|
||||
"FTPChannelParent.h",
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
"FTPChannelChild.cpp",
|
||||
"FTPChannelParent.cpp",
|
||||
"nsFTPChannel.cpp",
|
||||
"nsFtpConnectionThread.cpp",
|
||||
"nsFtpControlConnection.cpp",
|
||||
"nsFtpProtocolHandler.cpp",
|
||||
]
|
||||
|
||||
IPDL_SOURCES += [
|
||||
"PFTPChannel.ipdl",
|
||||
]
|
||||
|
||||
include("/ipc/chromium/chromium-config.mozbuild")
|
||||
|
||||
FINAL_LIBRARY = "xul"
|
||||
|
||||
LOCAL_INCLUDES += [
|
||||
"/netwerk/base",
|
||||
]
|
||||
|
||||
if CONFIG["CC_TYPE"] in ("clang", "gcc"):
|
||||
CXXFLAGS += ["-Wno-error=shadow"]
|
||||
|
||||
include("/tools/fuzzing/libfuzzer-config.mozbuild")
|
||||
213
netwerk/protocol/ftp/nsFTPChannel.cpp
Normal file
213
netwerk/protocol/ftp/nsFTPChannel.cpp
Normal file
@@ -0,0 +1,213 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=4 sts=2 sw=2 et cin: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsFTPChannel.h"
|
||||
#include "nsFtpConnectionThread.h" // defines nsFtpState
|
||||
|
||||
#include "nsThreadUtils.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::net;
|
||||
extern LazyLogModule gFTPLog;
|
||||
|
||||
// There are two transport connections established for an
|
||||
// ftp connection. One is used for the command channel , and
|
||||
// the other for the data channel. The command channel is the first
|
||||
// connection made and is used to negotiate the second, data, channel.
|
||||
// The data channel is driven by the command channel and is either
|
||||
// initiated by the server (PORT command) or by the client (PASV command).
|
||||
// Client initiation is the most common case and is attempted first.
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED(nsFtpChannel, nsBaseChannel, nsIUploadChannel,
|
||||
nsIResumableChannel, nsIFTPChannel,
|
||||
nsIProxiedChannel, nsIForcePendingChannel,
|
||||
nsISupportsWeakReference)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFtpChannel::SetUploadStream(nsIInputStream* stream,
|
||||
const nsACString& contentType,
|
||||
int64_t contentLength) {
|
||||
NS_ENSURE_TRUE(!Pending(), NS_ERROR_IN_PROGRESS);
|
||||
|
||||
mUploadStream = stream;
|
||||
|
||||
// NOTE: contentLength is intentionally ignored here.
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFtpChannel::GetUploadStream(nsIInputStream** aStream) {
|
||||
NS_ENSURE_ARG_POINTER(aStream);
|
||||
nsCOMPtr<nsIInputStream> stream = mUploadStream;
|
||||
stream.forget(aStream);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFtpChannel::ResumeAt(uint64_t aStartPos, const nsACString& aEntityID) {
|
||||
NS_ENSURE_TRUE(!Pending(), NS_ERROR_IN_PROGRESS);
|
||||
mEntityID = aEntityID;
|
||||
mStartPos = aStartPos;
|
||||
mResumeRequested = (mStartPos || !mEntityID.IsEmpty());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFtpChannel::GetEntityID(nsACString& entityID) {
|
||||
if (mEntityID.IsEmpty()) return NS_ERROR_NOT_RESUMABLE;
|
||||
|
||||
entityID = mEntityID;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
NS_IMETHODIMP
|
||||
nsFtpChannel::GetProxyInfo(nsIProxyInfo** aProxyInfo) {
|
||||
nsCOMPtr<nsIProxyInfo> info = ProxyInfo();
|
||||
info.forget(aProxyInfo);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsFtpChannel::GetHttpProxyConnectResponseCode(
|
||||
int32_t* aResponseCode) {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
nsresult nsFtpChannel::OpenContentStream(bool async, nsIInputStream** result,
|
||||
nsIChannel** channel) {
|
||||
if (!async) return NS_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
RefPtr<nsFtpState> state = new nsFtpState();
|
||||
|
||||
nsresult rv = state->Init(this);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
state.forget(result);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool nsFtpChannel::GetStatusArg(nsresult status, nsString& statusArg) {
|
||||
nsAutoCString host;
|
||||
URI()->GetHost(host);
|
||||
CopyUTF8toUTF16(host, statusArg);
|
||||
return true;
|
||||
}
|
||||
|
||||
void nsFtpChannel::OnCallbacksChanged() { mFTPEventSink = nullptr; }
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
namespace {
|
||||
|
||||
class FTPEventSinkProxy final : public nsIFTPEventSink {
|
||||
~FTPEventSinkProxy() = default;
|
||||
|
||||
public:
|
||||
explicit FTPEventSinkProxy(nsIFTPEventSink* aTarget)
|
||||
: mTarget(aTarget), mEventTarget(GetCurrentEventTarget()) {}
|
||||
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
NS_DECL_NSIFTPEVENTSINK
|
||||
|
||||
class OnFTPControlLogRunnable : public Runnable {
|
||||
public:
|
||||
OnFTPControlLogRunnable(nsIFTPEventSink* aTarget, bool aServer,
|
||||
const char* aMessage)
|
||||
: mozilla::Runnable("FTPEventSinkProxy::OnFTPControlLogRunnable"),
|
||||
mTarget(aTarget),
|
||||
mServer(aServer),
|
||||
mMessage(aMessage) {}
|
||||
|
||||
NS_DECL_NSIRUNNABLE
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIFTPEventSink> mTarget;
|
||||
bool mServer;
|
||||
nsCString mMessage;
|
||||
};
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIFTPEventSink> mTarget;
|
||||
nsCOMPtr<nsIEventTarget> mEventTarget;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(FTPEventSinkProxy, nsIFTPEventSink)
|
||||
|
||||
NS_IMETHODIMP
|
||||
FTPEventSinkProxy::OnFTPControlLog(bool aServer, const char* aMsg) {
|
||||
RefPtr<OnFTPControlLogRunnable> r =
|
||||
new OnFTPControlLogRunnable(mTarget, aServer, aMsg);
|
||||
return mEventTarget->Dispatch(r, NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FTPEventSinkProxy::OnFTPControlLogRunnable::Run() {
|
||||
mTarget->OnFTPControlLog(mServer, mMessage.get());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void nsFtpChannel::GetFTPEventSink(nsCOMPtr<nsIFTPEventSink>& aResult) {
|
||||
if (!mFTPEventSink) {
|
||||
nsCOMPtr<nsIFTPEventSink> ftpSink;
|
||||
GetCallback(ftpSink);
|
||||
if (ftpSink) {
|
||||
mFTPEventSink = new FTPEventSinkProxy(ftpSink);
|
||||
}
|
||||
}
|
||||
aResult = mFTPEventSink;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFtpChannel::ForcePending(bool aForcePending) {
|
||||
// Set true here so IsPending will return true.
|
||||
// Required for callback diversion from child back to parent. In such cases
|
||||
// OnStopRequest can be called in the parent before callbacks are diverted
|
||||
// back from the child to the listener in the parent.
|
||||
mForcePending = aForcePending;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFtpChannel::IsPending(bool* result) {
|
||||
*result = Pending();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool nsFtpChannel::Pending() const {
|
||||
return nsBaseChannel::Pending() || mForcePending;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFtpChannel::Suspend() {
|
||||
LOG(("nsFtpChannel::Suspend [this=%p]\n", this));
|
||||
NS_ENSURE_TRUE(Pending(), NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
++mSuspendCount;
|
||||
return nsBaseChannel::Suspend();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFtpChannel::Resume() {
|
||||
LOG(("nsFtpChannel::Resume [this=%p]\n", this));
|
||||
NS_ENSURE_TRUE(mSuspendCount > 0, NS_ERROR_UNEXPECTED);
|
||||
--mSuspendCount;
|
||||
return nsBaseChannel::Resume();
|
||||
}
|
||||
115
netwerk/protocol/ftp/nsFTPChannel.h
Normal file
115
netwerk/protocol/ftp/nsFTPChannel.h
Normal file
@@ -0,0 +1,115 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=4 sw=2 sts=2 et cindent: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef nsFTPChannel_h___
|
||||
#define nsFTPChannel_h___
|
||||
|
||||
#include "nsBaseChannel.h"
|
||||
|
||||
#include "nsString.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIFTPChannel.h"
|
||||
#include "nsIForcePendingChannel.h"
|
||||
#include "nsIUploadChannel.h"
|
||||
#include "nsIProxyInfo.h"
|
||||
#include "nsIProxiedChannel.h"
|
||||
#include "nsIResumableChannel.h"
|
||||
#include "nsWeakReference.h"
|
||||
|
||||
class nsIURI;
|
||||
|
||||
class nsFtpChannel final : public nsBaseChannel,
|
||||
public nsIFTPChannel,
|
||||
public nsIUploadChannel,
|
||||
public nsIResumableChannel,
|
||||
public nsIProxiedChannel,
|
||||
public nsIForcePendingChannel,
|
||||
public nsSupportsWeakReference {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIUPLOADCHANNEL
|
||||
NS_DECL_NSIRESUMABLECHANNEL
|
||||
NS_DECL_NSIPROXIEDCHANNEL
|
||||
|
||||
nsFtpChannel(nsIURI* uri, nsIProxyInfo* pi)
|
||||
: mProxyInfo(pi),
|
||||
mStartPos(0),
|
||||
mResumeRequested(false),
|
||||
mLastModifiedTime(0),
|
||||
mForcePending(false),
|
||||
mSuspendCount(0) {
|
||||
SetURI(uri);
|
||||
}
|
||||
|
||||
void UpdateURI(nsIURI* aURI) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(NS_IsMainThread(), "Not thread-safe.");
|
||||
mURI = aURI;
|
||||
}
|
||||
|
||||
nsIProxyInfo* ProxyInfo() { return mProxyInfo; }
|
||||
|
||||
void SetProxyInfo(nsIProxyInfo* pi) { mProxyInfo = pi; }
|
||||
|
||||
NS_IMETHOD IsPending(bool* result) override;
|
||||
|
||||
// This is a short-cut to calling nsIRequest::IsPending().
|
||||
// Overrides Pending in nsBaseChannel.
|
||||
bool Pending() const override;
|
||||
|
||||
// Were we asked to resume a download?
|
||||
bool ResumeRequested() { return mResumeRequested; }
|
||||
|
||||
// Download from this byte offset
|
||||
uint64_t StartPos() { return mStartPos; }
|
||||
|
||||
// ID of the entity to resume downloading
|
||||
const nsCString& EntityID() { return mEntityID; }
|
||||
void SetEntityID(const nsACString& entityID) { mEntityID = entityID; }
|
||||
|
||||
NS_IMETHOD GetLastModifiedTime(PRTime* lastModifiedTime) override {
|
||||
*lastModifiedTime = mLastModifiedTime;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHOD SetLastModifiedTime(PRTime lastModifiedTime) override {
|
||||
mLastModifiedTime = lastModifiedTime;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Data stream to upload
|
||||
nsIInputStream* UploadStream() { return mUploadStream; }
|
||||
|
||||
// Helper function for getting the nsIFTPEventSink.
|
||||
void GetFTPEventSink(nsCOMPtr<nsIFTPEventSink>& aResult);
|
||||
|
||||
NS_IMETHOD Suspend() override;
|
||||
NS_IMETHOD Resume() override;
|
||||
|
||||
public:
|
||||
NS_IMETHOD ForcePending(bool aForcePending) override;
|
||||
|
||||
protected:
|
||||
virtual ~nsFtpChannel() = default;
|
||||
virtual nsresult OpenContentStream(bool async, nsIInputStream** result,
|
||||
nsIChannel** channel) override;
|
||||
virtual bool GetStatusArg(nsresult status, nsString& statusArg) override;
|
||||
virtual void OnCallbacksChanged() override;
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIProxyInfo> mProxyInfo;
|
||||
nsCOMPtr<nsIFTPEventSink> mFTPEventSink;
|
||||
nsCOMPtr<nsIInputStream> mUploadStream;
|
||||
uint64_t mStartPos;
|
||||
nsCString mEntityID;
|
||||
bool mResumeRequested;
|
||||
PRTime mLastModifiedTime;
|
||||
bool mForcePending;
|
||||
|
||||
// Current suspension depth for this channel object
|
||||
uint32_t mSuspendCount;
|
||||
};
|
||||
|
||||
#endif /* nsFTPChannel_h___ */
|
||||
1950
netwerk/protocol/ftp/nsFtpConnectionThread.cpp
Normal file
1950
netwerk/protocol/ftp/nsFtpConnectionThread.cpp
Normal file
File diff suppressed because it is too large
Load Diff
254
netwerk/protocol/ftp/nsFtpConnectionThread.h
Normal file
254
netwerk/protocol/ftp/nsFtpConnectionThread.h
Normal file
@@ -0,0 +1,254 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef __nsFtpConnectionThread__h_
|
||||
#define __nsFtpConnectionThread__h_
|
||||
|
||||
#include "nsBaseContentStream.h"
|
||||
|
||||
#include "nsString.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIAsyncInputStream.h"
|
||||
#include "nsITransport.h"
|
||||
#include "mozilla/net/DNS.h"
|
||||
#include "nsFtpControlConnection.h"
|
||||
#include "nsIProtocolProxyCallback.h"
|
||||
|
||||
// ftp server types
|
||||
#define FTP_GENERIC_TYPE 0
|
||||
#define FTP_UNIX_TYPE 1
|
||||
#define FTP_VMS_TYPE 8
|
||||
#define FTP_NT_TYPE 9
|
||||
#define FTP_OS2_TYPE 11
|
||||
|
||||
// ftp states
|
||||
typedef enum _FTP_STATE {
|
||||
///////////////////////
|
||||
//// Internal states
|
||||
FTP_INIT,
|
||||
FTP_COMMAND_CONNECT,
|
||||
FTP_READ_BUF,
|
||||
FTP_ERROR,
|
||||
FTP_COMPLETE,
|
||||
|
||||
///////////////////////
|
||||
//// Command channel connection setup states
|
||||
FTP_S_USER,
|
||||
FTP_R_USER,
|
||||
FTP_S_PASS,
|
||||
FTP_R_PASS,
|
||||
FTP_S_SYST,
|
||||
FTP_R_SYST,
|
||||
FTP_S_ACCT,
|
||||
FTP_R_ACCT,
|
||||
FTP_S_TYPE,
|
||||
FTP_R_TYPE,
|
||||
FTP_S_CWD,
|
||||
FTP_R_CWD,
|
||||
FTP_S_SIZE,
|
||||
FTP_R_SIZE,
|
||||
FTP_S_MDTM,
|
||||
FTP_R_MDTM,
|
||||
FTP_S_REST,
|
||||
FTP_R_REST,
|
||||
FTP_S_RETR,
|
||||
FTP_R_RETR,
|
||||
FTP_S_STOR,
|
||||
FTP_R_STOR,
|
||||
FTP_S_LIST,
|
||||
FTP_R_LIST,
|
||||
FTP_S_PASV,
|
||||
FTP_R_PASV,
|
||||
FTP_S_PWD,
|
||||
FTP_R_PWD,
|
||||
FTP_S_FEAT,
|
||||
FTP_R_FEAT,
|
||||
FTP_S_OPTS,
|
||||
FTP_R_OPTS
|
||||
} FTP_STATE;
|
||||
|
||||
// higher level ftp actions
|
||||
typedef enum _FTP_ACTION { GET, PUT } FTP_ACTION;
|
||||
|
||||
class nsFtpChannel;
|
||||
class nsICancelable;
|
||||
class nsIProxyInfo;
|
||||
class nsIStreamListener;
|
||||
|
||||
// The nsFtpState object is the content stream for the channel. It implements
|
||||
// nsIInputStreamCallback, so it can read data from the control connection. It
|
||||
// implements nsITransportEventSink so it can mix status events from both the
|
||||
// control connection and the data connection.
|
||||
|
||||
class nsFtpState final : public nsBaseContentStream,
|
||||
public nsIInputStreamCallback,
|
||||
public nsITransportEventSink,
|
||||
public nsIRequestObserver,
|
||||
public nsFtpControlConnectionListener,
|
||||
public nsIProtocolProxyCallback {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIINPUTSTREAMCALLBACK
|
||||
NS_DECL_NSITRANSPORTEVENTSINK
|
||||
NS_DECL_NSIREQUESTOBSERVER
|
||||
NS_DECL_NSIPROTOCOLPROXYCALLBACK
|
||||
|
||||
// Override input stream methods:
|
||||
NS_IMETHOD CloseWithStatus(nsresult status) override;
|
||||
NS_IMETHOD Available(uint64_t* result) override;
|
||||
NS_IMETHOD ReadSegments(nsWriteSegmentFun fun, void* closure, uint32_t count,
|
||||
uint32_t* result) override;
|
||||
|
||||
// nsFtpControlConnectionListener methods:
|
||||
virtual void OnControlDataAvailable(const char* data,
|
||||
uint32_t dataLen) override;
|
||||
virtual void OnControlError(nsresult status) override;
|
||||
|
||||
nsFtpState();
|
||||
nsresult Init(nsFtpChannel* channel);
|
||||
|
||||
protected:
|
||||
// Notification from nsBaseContentStream::AsyncWait
|
||||
virtual void OnCallbackPending() override;
|
||||
|
||||
private:
|
||||
virtual ~nsFtpState();
|
||||
|
||||
///////////////////////////////////
|
||||
// BEGIN: STATE METHODS
|
||||
nsresult S_user();
|
||||
FTP_STATE R_user();
|
||||
nsresult S_pass();
|
||||
FTP_STATE R_pass();
|
||||
nsresult S_syst();
|
||||
FTP_STATE R_syst();
|
||||
nsresult S_acct();
|
||||
FTP_STATE R_acct();
|
||||
|
||||
nsresult S_type();
|
||||
FTP_STATE R_type();
|
||||
nsresult S_cwd();
|
||||
FTP_STATE R_cwd();
|
||||
|
||||
nsresult S_size();
|
||||
FTP_STATE R_size();
|
||||
nsresult S_mdtm();
|
||||
FTP_STATE R_mdtm();
|
||||
nsresult S_list();
|
||||
FTP_STATE R_list();
|
||||
|
||||
nsresult S_rest();
|
||||
FTP_STATE R_rest();
|
||||
nsresult S_retr();
|
||||
FTP_STATE R_retr();
|
||||
nsresult S_stor();
|
||||
FTP_STATE R_stor();
|
||||
nsresult S_pasv();
|
||||
FTP_STATE R_pasv();
|
||||
nsresult S_pwd();
|
||||
FTP_STATE R_pwd();
|
||||
nsresult S_feat();
|
||||
FTP_STATE R_feat();
|
||||
nsresult S_opts();
|
||||
FTP_STATE R_opts();
|
||||
// END: STATE METHODS
|
||||
///////////////////////////////////
|
||||
|
||||
// internal methods
|
||||
void MoveToNextState(FTP_STATE nextState);
|
||||
nsresult Process();
|
||||
|
||||
void KillControlConnection();
|
||||
nsresult StopProcessing();
|
||||
nsresult EstablishControlConnection();
|
||||
nsresult SendFTPCommand(const nsACString& command);
|
||||
void ConvertFilespecToVMS(nsCString& fileSpec);
|
||||
void ConvertDirspecToVMS(nsCString& fileSpec);
|
||||
void ConvertDirspecFromVMS(nsCString& fileSpec);
|
||||
nsresult BuildStreamConverter(nsIStreamListener** convertStreamListener);
|
||||
nsresult SetContentType();
|
||||
|
||||
/**
|
||||
* This method is called to kick-off the FTP state machine. mState is
|
||||
* reset to FTP_COMMAND_CONNECT, and the FTP state machine progresses from
|
||||
* there. This method is initially called (indirectly) from the channel's
|
||||
* AsyncOpen implementation.
|
||||
*/
|
||||
void Connect();
|
||||
|
||||
///////////////////////////////////
|
||||
// Private members
|
||||
|
||||
nsCOMPtr<nsIProxiedProtocolHandler> mHandler; // Ref to gFtpHandler
|
||||
|
||||
// ****** state machine vars
|
||||
FTP_STATE mState; // the current state
|
||||
FTP_STATE mNextState; // the next state
|
||||
bool mKeepRunning; // thread event loop boolean
|
||||
int32_t mResponseCode; // the last command response code
|
||||
nsCString mResponseMsg; // the last command response text
|
||||
|
||||
// ****** channel/transport/stream vars
|
||||
RefPtr<nsFtpControlConnection>
|
||||
mControlConnection; // cacheable control connection (owns mCPipe)
|
||||
bool mReceivedControlData;
|
||||
bool mTryingCachedControl; // retrying the password
|
||||
bool mRETRFailed; // Did we already try a RETR and it failed?
|
||||
uint64_t mFileSize;
|
||||
nsCString mModTime;
|
||||
|
||||
// ****** consumer vars
|
||||
RefPtr<nsFtpChannel>
|
||||
mChannel; // our owning FTP channel we pass through our events
|
||||
nsCOMPtr<nsIProxyInfo> mProxyInfo;
|
||||
|
||||
// ****** connection cache vars
|
||||
int32_t mServerType; // What kind of server are we talking to
|
||||
|
||||
// ****** protocol interpretation related state vars
|
||||
nsString mUsername; // username
|
||||
nsString mPassword; // password
|
||||
FTP_ACTION mAction; // the higher level action (GET/PUT)
|
||||
bool mAnonymous; // try connecting anonymous (default)
|
||||
bool mRetryPass; // retrying the password
|
||||
bool mStorReplyReceived; // FALSE if waiting for STOR
|
||||
// completion status from server
|
||||
bool mRlist1xxReceived; // TRUE if we have received a LIST 1xx
|
||||
// response from the server
|
||||
bool mRretr1xxReceived; // TRUE if we have received a RETR 1xx
|
||||
// response from the server
|
||||
bool mRstor1xxReceived; // TRUE if we have received a STOR 1xx
|
||||
// response from the server
|
||||
nsresult mInternalError; // represents internal state errors
|
||||
bool mReconnectAndLoginAgain;
|
||||
bool mCacheConnection;
|
||||
|
||||
// ****** URI vars
|
||||
int32_t mPort; // the port to connect to
|
||||
nsString mFilename; // url filename (if any)
|
||||
nsCString mPath; // the url's path
|
||||
nsCString mPwd; // login Path
|
||||
|
||||
// ****** other vars
|
||||
nsCOMPtr<nsITransport> mDataTransport;
|
||||
nsCOMPtr<nsIAsyncInputStream> mDataStream;
|
||||
nsCOMPtr<nsIRequest> mUploadRequest;
|
||||
bool mAddressChecked;
|
||||
bool mServerIsIPv6;
|
||||
bool mUseUTF8;
|
||||
|
||||
mozilla::net::NetAddr mServerAddress;
|
||||
|
||||
// ***** control read gvars
|
||||
nsresult mControlStatus;
|
||||
nsCString mControlReadCarryOverBuf;
|
||||
|
||||
nsCString mSuppliedEntityID;
|
||||
|
||||
nsCOMPtr<nsICancelable> mProxyRequest;
|
||||
bool mDeferredCallbackPending;
|
||||
};
|
||||
|
||||
#endif //__nsFtpConnectionThread__h_
|
||||
170
netwerk/protocol/ftp/nsFtpControlConnection.cpp
Normal file
170
netwerk/protocol/ftp/nsFtpControlConnection.cpp
Normal file
@@ -0,0 +1,170 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsIOService.h"
|
||||
#include "nsFtpControlConnection.h"
|
||||
#include "nsFtpProtocolHandler.h"
|
||||
#include "mozilla/Logging.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsISocketTransportService.h"
|
||||
#include "nsISocketTransport.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsNetCID.h"
|
||||
#include "nsTArray.h"
|
||||
#include <algorithm>
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::net;
|
||||
|
||||
extern LazyLogModule gFTPLog;
|
||||
#define LOG(args) MOZ_LOG(gFTPLog, mozilla::LogLevel::Debug, args)
|
||||
#define LOG_INFO(args) MOZ_LOG(gFTPLog, mozilla::LogLevel::Info, args)
|
||||
|
||||
//
|
||||
// nsFtpControlConnection implementation ...
|
||||
//
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsFtpControlConnection, nsIInputStreamCallback)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFtpControlConnection::OnInputStreamReady(nsIAsyncInputStream* stream) {
|
||||
char data[4096];
|
||||
|
||||
// Consume data whether we have a listener or not.
|
||||
uint64_t avail64;
|
||||
uint32_t avail = 0;
|
||||
nsresult rv = stream->Available(&avail64);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
avail = (uint32_t)std::min(avail64, (uint64_t)sizeof(data));
|
||||
|
||||
uint32_t n;
|
||||
rv = stream->Read(data, avail, &n);
|
||||
if (NS_SUCCEEDED(rv)) avail = n;
|
||||
}
|
||||
|
||||
// It's important that we null out mListener before calling one of its
|
||||
// methods as it may call WaitData, which would queue up another read.
|
||||
|
||||
RefPtr<nsFtpControlConnectionListener> listener;
|
||||
listener.swap(mListener);
|
||||
|
||||
if (!listener) return NS_OK;
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
listener->OnControlError(rv);
|
||||
} else {
|
||||
listener->OnControlDataAvailable(data, avail);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsFtpControlConnection::nsFtpControlConnection(const nsACString& host,
|
||||
uint32_t port)
|
||||
: mServerType(0),
|
||||
mSuspendedWrite(0),
|
||||
mSessionId(gFtpHandler->GetSessionId()),
|
||||
mUseUTF8(false),
|
||||
mHost(host),
|
||||
mPort(port) {
|
||||
LOG_INFO(("FTP:CC created @%p", this));
|
||||
}
|
||||
|
||||
nsFtpControlConnection::~nsFtpControlConnection() {
|
||||
LOG_INFO(("FTP:CC destroyed @%p", this));
|
||||
}
|
||||
|
||||
bool nsFtpControlConnection::IsAlive() {
|
||||
if (!mSocket) return false;
|
||||
|
||||
bool isAlive = false;
|
||||
mSocket->IsAlive(&isAlive);
|
||||
return isAlive;
|
||||
}
|
||||
nsresult nsFtpControlConnection::Connect(nsIProxyInfo* proxyInfo,
|
||||
nsITransportEventSink* eventSink) {
|
||||
if (mSocket) return NS_OK;
|
||||
|
||||
// build our own
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsISocketTransportService> sts =
|
||||
do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = sts->CreateTransport(nsTArray<nsCString>(), mHost, mPort, proxyInfo,
|
||||
nullptr,
|
||||
getter_AddRefs(mSocket)); // the command transport
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
mSocket->SetQoSBits(gFtpHandler->GetControlQoSBits());
|
||||
|
||||
// proxy transport events back to current thread
|
||||
if (eventSink) mSocket->SetEventSink(eventSink, GetCurrentEventTarget());
|
||||
|
||||
// open buffered, blocking output stream to socket. so long as commands
|
||||
// do not exceed 1024 bytes in length, the writing thread (the main thread)
|
||||
// will not block. this should be OK.
|
||||
rv = mSocket->OpenOutputStream(nsITransport::OPEN_BLOCKING, 1024, 1,
|
||||
getter_AddRefs(mSocketOutput));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// open buffered, non-blocking/asynchronous input stream to socket.
|
||||
nsCOMPtr<nsIInputStream> inStream;
|
||||
rv = mSocket->OpenInputStream(0, nsIOService::gDefaultSegmentSize,
|
||||
nsIOService::gDefaultSegmentCount,
|
||||
getter_AddRefs(inStream));
|
||||
if (NS_SUCCEEDED(rv)) mSocketInput = do_QueryInterface(inStream);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult nsFtpControlConnection::WaitData(
|
||||
nsFtpControlConnectionListener* listener) {
|
||||
LOG(("FTP:(%p) wait data [listener=%p]\n", this, listener));
|
||||
|
||||
// If listener is null, then simply disconnect the listener. Otherwise,
|
||||
// ensure that we are listening.
|
||||
if (!listener) {
|
||||
mListener = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_ENSURE_STATE(mSocketInput);
|
||||
|
||||
mListener = listener;
|
||||
return mSocketInput->AsyncWait(this, 0, 0, GetCurrentEventTarget());
|
||||
}
|
||||
|
||||
nsresult nsFtpControlConnection::Disconnect(nsresult status) {
|
||||
if (!mSocket) return NS_OK; // already disconnected
|
||||
|
||||
LOG_INFO(("FTP:(%p) CC disconnecting (%" PRIx32 ")", this,
|
||||
static_cast<uint32_t>(status)));
|
||||
|
||||
if (NS_FAILED(status)) {
|
||||
// break cyclic reference!
|
||||
mSocket->Close(status);
|
||||
mSocket = nullptr;
|
||||
mSocketInput->AsyncWait(nullptr, 0, 0, nullptr); // clear any observer
|
||||
mSocketInput = nullptr;
|
||||
mSocketOutput = nullptr;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsFtpControlConnection::Write(const nsACString& command) {
|
||||
NS_ENSURE_STATE(mSocketOutput);
|
||||
|
||||
uint32_t len = command.Length();
|
||||
uint32_t cnt;
|
||||
nsresult rv = mSocketOutput->Write(command.Data(), len, &cnt);
|
||||
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (len != cnt) return NS_ERROR_FAILURE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
83
netwerk/protocol/ftp/nsFtpControlConnection.h
Normal file
83
netwerk/protocol/ftp/nsFtpControlConnection.h
Normal file
@@ -0,0 +1,83 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set et ts=4 sts=2 sw=2 cin: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef nsFtpControlConnection_h___
|
||||
#define nsFtpControlConnection_h___
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
#include "nsISocketTransport.h"
|
||||
#include "nsIAsyncInputStream.h"
|
||||
#include "nsString.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
|
||||
class nsIOutputStream;
|
||||
class nsIProxyInfo;
|
||||
class nsITransportEventSink;
|
||||
|
||||
class nsFtpControlConnectionListener : public nsISupports {
|
||||
public:
|
||||
/**
|
||||
* Called when a chunk of data arrives on the control connection.
|
||||
* @param data
|
||||
* The new data or null if an error occurred.
|
||||
* @param dataLen
|
||||
* The data length in bytes.
|
||||
*/
|
||||
virtual void OnControlDataAvailable(const char* data, uint32_t dataLen) = 0;
|
||||
|
||||
/**
|
||||
* Called when an error occurs on the control connection.
|
||||
* @param status
|
||||
* A failure code providing more info about the error.
|
||||
*/
|
||||
virtual void OnControlError(nsresult status) = 0;
|
||||
};
|
||||
|
||||
class nsFtpControlConnection final : public nsIInputStreamCallback {
|
||||
~nsFtpControlConnection();
|
||||
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIINPUTSTREAMCALLBACK
|
||||
|
||||
nsFtpControlConnection(const nsACString& host, uint32_t port);
|
||||
|
||||
nsresult Connect(nsIProxyInfo* proxyInfo, nsITransportEventSink* eventSink);
|
||||
nsresult Disconnect(nsresult status);
|
||||
nsresult Write(const nsACString& command);
|
||||
|
||||
bool IsAlive();
|
||||
|
||||
nsITransport* Transport() { return mSocket; }
|
||||
|
||||
/**
|
||||
* Call this function to be notified asynchronously when there is data
|
||||
* available for the socket. The listener passed to this method replaces
|
||||
* any existing listener, and the listener can be null to disconnect the
|
||||
* previous listener.
|
||||
*/
|
||||
nsresult WaitData(nsFtpControlConnectionListener* listener);
|
||||
|
||||
uint32_t mServerType; // what kind of server is it.
|
||||
nsString mPassword;
|
||||
int32_t mSuspendedWrite;
|
||||
nsCString mPwd;
|
||||
uint32_t mSessionId;
|
||||
bool mUseUTF8;
|
||||
|
||||
private:
|
||||
nsCString mHost;
|
||||
uint32_t mPort;
|
||||
|
||||
nsCOMPtr<nsISocketTransport> mSocket;
|
||||
nsCOMPtr<nsIOutputStream> mSocketOutput;
|
||||
nsCOMPtr<nsIAsyncInputStream> mSocketInput;
|
||||
|
||||
RefPtr<nsFtpControlConnectionListener> mListener;
|
||||
};
|
||||
|
||||
#endif
|
||||
331
netwerk/protocol/ftp/nsFtpProtocolHandler.cpp
Normal file
331
netwerk/protocol/ftp/nsFtpProtocolHandler.cpp
Normal file
@@ -0,0 +1,331 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/net/NeckoChild.h"
|
||||
#include "mozilla/net/FTPChannelChild.h"
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::net;
|
||||
|
||||
#include "nsFtpProtocolHandler.h"
|
||||
#include "nsFTPChannel.h"
|
||||
#include "mozilla/Logging.h"
|
||||
#include "nsIPrefBranch.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsEscape.h"
|
||||
#include "nsAlgorithm.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//
|
||||
// Log module for FTP Protocol logging...
|
||||
//
|
||||
// To enable logging (see prlog.h for full details):
|
||||
//
|
||||
// set MOZ_LOG=nsFtp:5
|
||||
// set MOZ_LOG_FILE=ftp.log
|
||||
//
|
||||
// This enables LogLevel::Debug level information and places all output in
|
||||
// the file ftp.log.
|
||||
//
|
||||
LazyLogModule gFTPLog("nsFtp");
|
||||
#undef LOG
|
||||
#define LOG(args) MOZ_LOG(gFTPLog, mozilla::LogLevel::Debug, args)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#define IDLE_TIMEOUT_PREF "network.ftp.idleConnectionTimeout"
|
||||
#define IDLE_CONNECTION_LIMIT 8 /* TODO pref me */
|
||||
|
||||
#define ENABLED_PREF "network.ftp.enabled"
|
||||
#define QOS_DATA_PREF "network.ftp.data.qos"
|
||||
#define QOS_CONTROL_PREF "network.ftp.control.qos"
|
||||
|
||||
nsFtpProtocolHandler* gFtpHandler = nullptr;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
nsFtpProtocolHandler::nsFtpProtocolHandler()
|
||||
: mIdleTimeout(-1),
|
||||
mEnabled(true),
|
||||
mSessionId(0),
|
||||
mControlQoSBits(0x00),
|
||||
mDataQoSBits(0x00) {
|
||||
LOG(("FTP:creating handler @%p\n", this));
|
||||
|
||||
gFtpHandler = this;
|
||||
}
|
||||
|
||||
nsFtpProtocolHandler::~nsFtpProtocolHandler() {
|
||||
LOG(("FTP:destroying handler @%p\n", this));
|
||||
|
||||
NS_ASSERTION(mRootConnectionList.Length() == 0, "why wasn't Observe called?");
|
||||
|
||||
gFtpHandler = nullptr;
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsFtpProtocolHandler, nsIProtocolHandler,
|
||||
nsIProxiedProtocolHandler, nsIObserver,
|
||||
nsISupportsWeakReference)
|
||||
|
||||
nsresult nsFtpProtocolHandler::Init() {
|
||||
if (IsNeckoChild()) NeckoChild::InitNeckoChild();
|
||||
|
||||
if (mIdleTimeout == -1) {
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIPrefBranch> branch =
|
||||
do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = branch->GetIntPref(IDLE_TIMEOUT_PREF, &mIdleTimeout);
|
||||
if (NS_FAILED(rv)) mIdleTimeout = 5 * 60; // 5 minute default
|
||||
|
||||
rv = branch->AddObserver(IDLE_TIMEOUT_PREF, this, true);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = branch->GetBoolPref(ENABLED_PREF, &mEnabled);
|
||||
if (NS_FAILED(rv)) mEnabled = true;
|
||||
|
||||
rv = branch->AddObserver(ENABLED_PREF, this, true);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
int32_t val;
|
||||
rv = branch->GetIntPref(QOS_DATA_PREF, &val);
|
||||
if (NS_SUCCEEDED(rv)) mDataQoSBits = (uint8_t)clamped(val, 0, 0xff);
|
||||
|
||||
rv = branch->AddObserver(QOS_DATA_PREF, this, true);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = branch->GetIntPref(QOS_CONTROL_PREF, &val);
|
||||
if (NS_SUCCEEDED(rv)) mControlQoSBits = (uint8_t)clamped(val, 0, 0xff);
|
||||
|
||||
rv = branch->AddObserver(QOS_CONTROL_PREF, this, true);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIObserverService> observerService =
|
||||
mozilla::services::GetObserverService();
|
||||
if (observerService) {
|
||||
observerService->AddObserver(this, "network:offline-about-to-go-offline",
|
||||
true);
|
||||
|
||||
observerService->AddObserver(this, "net:clear-active-logins", true);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsIProtocolHandler methods:
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFtpProtocolHandler::GetScheme(nsACString& result) {
|
||||
result.AssignLiteral("ftp");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFtpProtocolHandler::GetDefaultPort(int32_t* result) {
|
||||
*result = 21;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFtpProtocolHandler::GetProtocolFlags(uint32_t* result) {
|
||||
*result = URI_STD | ALLOWS_PROXY | ALLOWS_PROXY_HTTP | URI_LOADABLE_BY_ANYONE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFtpProtocolHandler::NewChannel(nsIURI* url, nsILoadInfo* aLoadInfo,
|
||||
nsIChannel** result) {
|
||||
return NewProxiedChannel(url, nullptr, 0, nullptr, aLoadInfo, result);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFtpProtocolHandler::NewProxiedChannel(nsIURI* uri, nsIProxyInfo* proxyInfo,
|
||||
uint32_t proxyResolveFlags,
|
||||
nsIURI* proxyURI,
|
||||
nsILoadInfo* aLoadInfo,
|
||||
nsIChannel** result) {
|
||||
if (!mEnabled) {
|
||||
return NS_ERROR_UNKNOWN_PROTOCOL;
|
||||
}
|
||||
|
||||
NS_ENSURE_ARG_POINTER(uri);
|
||||
RefPtr<nsBaseChannel> channel;
|
||||
if (IsNeckoChild())
|
||||
channel = new FTPChannelChild(uri);
|
||||
else
|
||||
channel = new nsFtpChannel(uri, proxyInfo);
|
||||
|
||||
// set the loadInfo on the new channel
|
||||
nsresult rv = channel->SetLoadInfo(aLoadInfo);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
channel.forget(result);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFtpProtocolHandler::AllowPort(int32_t port, const char* scheme,
|
||||
bool* _retval) {
|
||||
*_retval = (port == 21 || port == 22);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// connection cache methods
|
||||
|
||||
void nsFtpProtocolHandler::Timeout(nsITimer* aTimer, void* aClosure) {
|
||||
LOG(("FTP:timeout reached for %p\n", aClosure));
|
||||
|
||||
bool found = gFtpHandler->mRootConnectionList.RemoveElement(aClosure);
|
||||
if (!found) {
|
||||
NS_ERROR("timerStruct not found");
|
||||
return;
|
||||
}
|
||||
|
||||
timerStruct* s = (timerStruct*)aClosure;
|
||||
delete s;
|
||||
}
|
||||
|
||||
nsresult nsFtpProtocolHandler::RemoveConnection(
|
||||
nsIURI* aKey, nsFtpControlConnection** _retval) {
|
||||
NS_ASSERTION(_retval, "null pointer");
|
||||
NS_ASSERTION(aKey, "null pointer");
|
||||
|
||||
*_retval = nullptr;
|
||||
|
||||
nsAutoCString spec;
|
||||
aKey->GetPrePath(spec);
|
||||
|
||||
LOG(("FTP:removing connection for %s\n", spec.get()));
|
||||
|
||||
timerStruct* ts = nullptr;
|
||||
uint32_t i;
|
||||
bool found = false;
|
||||
|
||||
for (i = 0; i < mRootConnectionList.Length(); ++i) {
|
||||
ts = mRootConnectionList[i];
|
||||
if (strcmp(spec.get(), ts->key) == 0) {
|
||||
found = true;
|
||||
mRootConnectionList.RemoveElementAt(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) return NS_ERROR_FAILURE;
|
||||
|
||||
// swap connection ownership
|
||||
ts->conn.forget(_retval);
|
||||
delete ts;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsFtpProtocolHandler::InsertConnection(nsIURI* aKey,
|
||||
nsFtpControlConnection* aConn) {
|
||||
NS_ASSERTION(aConn, "null pointer");
|
||||
NS_ASSERTION(aKey, "null pointer");
|
||||
|
||||
if (aConn->mSessionId != mSessionId) return NS_ERROR_FAILURE;
|
||||
|
||||
nsAutoCString spec;
|
||||
aKey->GetPrePath(spec);
|
||||
|
||||
LOG(("FTP:inserting connection for %s\n", spec.get()));
|
||||
|
||||
timerStruct* ts = new timerStruct();
|
||||
if (!ts) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
nsCOMPtr<nsITimer> timer;
|
||||
nsresult rv = NS_NewTimerWithFuncCallback(
|
||||
getter_AddRefs(timer), nsFtpProtocolHandler::Timeout, ts,
|
||||
mIdleTimeout * 1000, nsITimer::TYPE_REPEATING_SLACK,
|
||||
"nsFtpProtocolHandler::InsertConnection");
|
||||
if (NS_FAILED(rv)) {
|
||||
delete ts;
|
||||
return rv;
|
||||
}
|
||||
|
||||
ts->key = ToNewCString(spec, mozilla::fallible);
|
||||
if (!ts->key) {
|
||||
delete ts;
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
// ts->conn is a RefPtr
|
||||
ts->conn = aConn;
|
||||
ts->timer = timer;
|
||||
|
||||
//
|
||||
// limit number of idle connections. if limit is reached, then prune
|
||||
// eldest connection with matching key. if none matching, then prune
|
||||
// eldest connection.
|
||||
//
|
||||
if (mRootConnectionList.Length() == IDLE_CONNECTION_LIMIT) {
|
||||
uint32_t i;
|
||||
for (i = 0; i < mRootConnectionList.Length(); ++i) {
|
||||
timerStruct* candidate = mRootConnectionList[i];
|
||||
if (strcmp(candidate->key, ts->key) == 0) {
|
||||
mRootConnectionList.RemoveElementAt(i);
|
||||
delete candidate;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (mRootConnectionList.Length() == IDLE_CONNECTION_LIMIT) {
|
||||
timerStruct* eldest = mRootConnectionList[0];
|
||||
mRootConnectionList.RemoveElementAt(0);
|
||||
delete eldest;
|
||||
}
|
||||
}
|
||||
|
||||
mRootConnectionList.AppendElement(ts);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsIObserver
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFtpProtocolHandler::Observe(nsISupports* aSubject, const char* aTopic,
|
||||
const char16_t* aData) {
|
||||
LOG(("FTP:observing [%s]\n", aTopic));
|
||||
|
||||
if (!strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID)) {
|
||||
nsCOMPtr<nsIPrefBranch> branch = do_QueryInterface(aSubject);
|
||||
if (!branch) {
|
||||
NS_ERROR("no prefbranch");
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
int32_t val;
|
||||
nsresult rv = branch->GetIntPref(IDLE_TIMEOUT_PREF, &val);
|
||||
if (NS_SUCCEEDED(rv)) mIdleTimeout = val;
|
||||
bool enabled;
|
||||
rv = branch->GetBoolPref(ENABLED_PREF, &enabled);
|
||||
if (NS_SUCCEEDED(rv)) mEnabled = enabled;
|
||||
|
||||
rv = branch->GetIntPref(QOS_DATA_PREF, &val);
|
||||
if (NS_SUCCEEDED(rv)) mDataQoSBits = (uint8_t)clamped(val, 0, 0xff);
|
||||
|
||||
rv = branch->GetIntPref(QOS_CONTROL_PREF, &val);
|
||||
if (NS_SUCCEEDED(rv)) mControlQoSBits = (uint8_t)clamped(val, 0, 0xff);
|
||||
} else if (!strcmp(aTopic, "network:offline-about-to-go-offline")) {
|
||||
ClearAllConnections();
|
||||
} else if (!strcmp(aTopic, "net:clear-active-logins")) {
|
||||
ClearAllConnections();
|
||||
mSessionId++;
|
||||
} else {
|
||||
MOZ_ASSERT_UNREACHABLE("unexpected topic");
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void nsFtpProtocolHandler::ClearAllConnections() {
|
||||
uint32_t i;
|
||||
for (i = 0; i < mRootConnectionList.Length(); ++i)
|
||||
delete mRootConnectionList[i];
|
||||
mRootConnectionList.Clear();
|
||||
}
|
||||
85
netwerk/protocol/ftp/nsFtpProtocolHandler.h
Normal file
85
netwerk/protocol/ftp/nsFtpProtocolHandler.h
Normal file
@@ -0,0 +1,85 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef nsFtpProtocolHandler_h__
|
||||
#define nsFtpProtocolHandler_h__
|
||||
|
||||
#include "nsFtpControlConnection.h"
|
||||
#include "nsIProxiedProtocolHandler.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsITimer.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsWeakReference.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class nsFtpProtocolHandler final : public nsIProxiedProtocolHandler,
|
||||
public nsIObserver,
|
||||
public nsSupportsWeakReference {
|
||||
public:
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
NS_DECL_NSIPROTOCOLHANDLER
|
||||
NS_DECL_NSIPROXIEDPROTOCOLHANDLER
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
nsFtpProtocolHandler();
|
||||
|
||||
nsresult Init();
|
||||
|
||||
// FTP Connection list access
|
||||
nsresult InsertConnection(nsIURI* aKey, nsFtpControlConnection* aConn);
|
||||
nsresult RemoveConnection(nsIURI* aKey, nsFtpControlConnection** aConn);
|
||||
uint32_t GetSessionId() { return mSessionId; }
|
||||
|
||||
uint8_t GetDataQoSBits() { return mDataQoSBits; }
|
||||
uint8_t GetControlQoSBits() { return mControlQoSBits; }
|
||||
|
||||
private:
|
||||
virtual ~nsFtpProtocolHandler();
|
||||
|
||||
// Stuff for the timer callback function
|
||||
struct timerStruct {
|
||||
nsCOMPtr<nsITimer> timer;
|
||||
RefPtr<nsFtpControlConnection> conn;
|
||||
char* key;
|
||||
|
||||
timerStruct() : key(nullptr) {}
|
||||
|
||||
~timerStruct() {
|
||||
if (timer) timer->Cancel();
|
||||
if (key) free(key);
|
||||
if (conn) {
|
||||
conn->Disconnect(NS_ERROR_ABORT);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static void Timeout(nsITimer* aTimer, void* aClosure);
|
||||
void ClearAllConnections();
|
||||
|
||||
nsTArray<timerStruct*> mRootConnectionList;
|
||||
|
||||
int32_t mIdleTimeout;
|
||||
bool mEnabled;
|
||||
|
||||
// When "clear active logins" is performed, all idle connection are dropped
|
||||
// and mSessionId is incremented. When nsFtpState wants to insert idle
|
||||
// connection we refuse to cache if its mSessionId is different (i.e.
|
||||
// control connection had been created before last "clear active logins" was
|
||||
// performed.
|
||||
uint32_t mSessionId;
|
||||
|
||||
uint8_t mControlQoSBits;
|
||||
uint8_t mDataQoSBits;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
extern nsFtpProtocolHandler* gFtpHandler;
|
||||
|
||||
#include "mozilla/Logging.h"
|
||||
extern mozilla::LazyLogModule gFTPLog;
|
||||
|
||||
#endif // !nsFtpProtocolHandler_h__
|
||||
29
netwerk/protocol/ftp/nsIFTPChannel.idl
Normal file
29
netwerk/protocol/ftp/nsIFTPChannel.idl
Normal file
@@ -0,0 +1,29 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
/**
|
||||
* This interface may be used to determine if a channel is a FTP channel.
|
||||
*/
|
||||
[scriptable, uuid(07f0d5cd-1fd5-4aa3-b6fc-665bdc5dbf9f)]
|
||||
interface nsIFTPChannel : nsISupports
|
||||
{
|
||||
attribute PRTime lastModifiedTime;
|
||||
};
|
||||
|
||||
/**
|
||||
* This interface may be defined as a notification callback on the FTP
|
||||
* channel. It allows a consumer to receive a log of the FTP control
|
||||
* connection conversation.
|
||||
*/
|
||||
[scriptable, uuid(455d4234-0330-43d2-bbfb-99afbecbfeb0)]
|
||||
interface nsIFTPEventSink : nsISupports
|
||||
{
|
||||
/**
|
||||
* XXX document this method! (see bug 328915)
|
||||
*/
|
||||
void OnFTPControlLog(in boolean server, in string msg);
|
||||
};
|
||||
15
netwerk/protocol/ftp/nsIFTPChannelParentInternal.idl
Normal file
15
netwerk/protocol/ftp/nsIFTPChannelParentInternal.idl
Normal file
@@ -0,0 +1,15 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
/**
|
||||
* This is an internal interface for FTP parent channel.
|
||||
*/
|
||||
[builtinclass, uuid(87b58410-83cb-42a7-b57b-27c07ef828d7)]
|
||||
interface nsIFTPChannelParentInternal : nsISupports
|
||||
{
|
||||
void setErrorMsg(in string msg, in boolean useUTF8);
|
||||
};
|
||||
5
netwerk/protocol/ftp/test/frametest/contents.html
Normal file
5
netwerk/protocol/ftp/test/frametest/contents.html
Normal file
@@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
<h2>Click a link to the left</h2>
|
||||
</body>
|
||||
</html>
|
||||
12
netwerk/protocol/ftp/test/frametest/index.html
Normal file
12
netwerk/protocol/ftp/test/frametest/index.html
Normal file
@@ -0,0 +1,12 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>FTP Frameset Test</title>
|
||||
|
||||
</head>
|
||||
|
||||
<frameset cols="30%,70%" name="ftp_main_frame">
|
||||
<frame src="menu.html" name="ftp_menu" scrolling="yes" marginwidth="0" marginheight="0" noresize>
|
||||
<frame src="contents.html" name="ftp_content" scrolling="YES" marginwidth="0" marginheight="0" noresize>
|
||||
</frameset>
|
||||
|
||||
</html>
|
||||
371
netwerk/protocol/ftp/test/frametest/menu.html
Normal file
371
netwerk/protocol/ftp/test/frametest/menu.html
Normal file
@@ -0,0 +1,371 @@
|
||||
<html>
|
||||
|
||||
<script language="javascript">
|
||||
/* eslint-disable no-unsanitized/method */
|
||||
<!--
|
||||
|
||||
function add_location(url) {
|
||||
// faster to do this in one assignment, but who really cares.
|
||||
|
||||
var string = '<LI> <a href=\"javascript: ftp_open(\'';
|
||||
string += url;
|
||||
string += '\')\"';
|
||||
string += 'onmouseover=\"window.status=\'ftp://';
|
||||
string += url;
|
||||
string += '\'; return true; \">';
|
||||
string += url;
|
||||
string += "</a>";
|
||||
document.writeln(string);
|
||||
}
|
||||
|
||||
function ftp_open(url) {
|
||||
url = "ftp://" + url;
|
||||
parent.ftp_content.location = url;
|
||||
}
|
||||
|
||||
// I like this format.
|
||||
document.writeln("<pre>");
|
||||
|
||||
document.writeln("<br><OL><b>Company sites</b>");
|
||||
add_location("ftp.mozilla.org");
|
||||
add_location("ftp.sun.com");
|
||||
add_location("ftp.iplanet.com");
|
||||
add_location("ftp.netscape.com");
|
||||
add_location("ftp.apple.com");
|
||||
add_location("ftp.microsoft.com");
|
||||
add_location("ftp.netmanage.com");
|
||||
|
||||
document.writeln("</OL><br><OL><b>Misc sites</b>");
|
||||
add_location("cal044202.student.utwente.nl");
|
||||
add_location("download.intel.com");
|
||||
add_location("fddisunsite.oit.unc.edu");
|
||||
add_location("ftp.abas.de");
|
||||
add_location("ftp.acm.org");
|
||||
add_location("ftp.acomp.hu");
|
||||
add_location("ftp.acri.fr");
|
||||
add_location("ftp.alaska.edu");
|
||||
add_location("ftp.altera.com");
|
||||
add_location("ftp.amsat.org");
|
||||
add_location("ftp.amtp.cam.ac.uk");
|
||||
add_location("ftp.ar.freebsd.org");
|
||||
add_location("ftp.ari.net");
|
||||
add_location("ftp.arl.mil");
|
||||
add_location("ftp.astro.ulg.ac.be");
|
||||
add_location("ftp.avery-zweckform.com");
|
||||
add_location("ftp.awi-bremerhaven.de");
|
||||
add_location("ftp.axime-is.fr");
|
||||
add_location("ftp.ba.cnr.it");
|
||||
add_location("ftp.bath.ac.uk");
|
||||
add_location("ftp.bic.mni.mcgill.ca");
|
||||
add_location("ftp.biomed.ruhr-uni-bochum.de");
|
||||
add_location("ftp.boerde.de");
|
||||
add_location("ftp.bond.edu.au");
|
||||
add_location("ftp.boulder.ibm.com");
|
||||
add_location("ftp.brics.dk");
|
||||
add_location("ftp.bris.ac.uk");
|
||||
add_location("ftp.cablelabs.com");
|
||||
add_location("ftp.cac.psu.edu");
|
||||
add_location("ftp.cadpoint.se");
|
||||
add_location("ftp.cas.cz");
|
||||
add_location("ftp.cciw.ca");
|
||||
add_location("ftp.ccs.queensu.ca");
|
||||
add_location("ftp.ccsi.com");
|
||||
add_location("ftp.cdrom.com");
|
||||
add_location("ftp.cea.fr");
|
||||
add_location("ftp.celestial.com");
|
||||
add_location("ftp.cert.fr");
|
||||
add_location("ftp.cgd.ucar.edu");
|
||||
add_location("ftp.chiba-u.ac.jp");
|
||||
add_location("ftp.cis.ksu.edu");
|
||||
add_location("ftp.citi2.fr");
|
||||
add_location("ftp.cityline.net");
|
||||
add_location("ftp.cnam.fr");
|
||||
add_location("ftp.cohesive.com");
|
||||
add_location("ftp.contrib.net");
|
||||
add_location("ftp.create.ucsb.edu");
|
||||
add_location("ftp.cronyx.ru");
|
||||
add_location("ftp.cs.arizona.edu");
|
||||
add_location("ftp.cs.colorado.edu");
|
||||
add_location("ftp.cs.concordia.ca");
|
||||
add_location("ftp.cs.helsinki.fi");
|
||||
add_location("ftp.cs.jhu.edu");
|
||||
add_location("ftp.cs.monash.edu.au");
|
||||
add_location("ftp.cs.ohiou.edu");
|
||||
add_location("ftp.cs.rug.nl");
|
||||
add_location("ftp.cs.toronto.edu");
|
||||
add_location("ftp.cs.umanitoba.ca");
|
||||
add_location("ftp.cs.uni-dortmund.de");
|
||||
add_location("ftp.cs.vu.nl");
|
||||
add_location("ftp.cse.cuhk.edu.hk");
|
||||
add_location("ftp.cse.unsw.edu.au");
|
||||
add_location("ftp.csse.monash.edu.au");
|
||||
add_location("ftp.csus.edu");
|
||||
add_location("ftp.cullasaja.com");
|
||||
add_location("ftp.daimi.au.dk");
|
||||
add_location("ftp.dcs.qmw.ac.uk");
|
||||
add_location("ftp.delorie.com");
|
||||
add_location("ftp.dementia.org");
|
||||
add_location("ftp.dfki.uni-kl.de");
|
||||
add_location("ftp.dgs.monash.edu.au");
|
||||
add_location("ftp.dis.strath.ac.uk");
|
||||
add_location("ftp.dosis.uni-dortmund.de");
|
||||
add_location("ftp.duke.edu");
|
||||
add_location("ftp.duplexx.com");
|
||||
add_location("ftp.ece.ucdavis.edu");
|
||||
add_location("ftp.ee.lbl.gov");
|
||||
add_location("ftp.ee.rochester.edu");
|
||||
add_location("ftp.ee.uts.edu.au");
|
||||
add_location("ftp.efrei.fr");
|
||||
add_location("ftp.elet.polimi.it");
|
||||
add_location("ftp.elite.net");
|
||||
add_location("ftp.embl-hamburg.de");
|
||||
add_location("ftp.eng.buffalo.edu");
|
||||
add_location("ftp.engr.uark.edu");
|
||||
add_location("ftp.eni.co.jp");
|
||||
add_location("ftp.enst-bretagne.fr");
|
||||
add_location("ftp.epix.net");
|
||||
add_location("ftp.eskimo.com");
|
||||
add_location("ftp.essential.org");
|
||||
add_location("ftp.eunet.fi");
|
||||
add_location("ftp.eurexpo.com");
|
||||
add_location("ftp.ex.ac.uk");
|
||||
add_location("ftp.faximum.com");
|
||||
add_location("ftp.fernuni-hagen.de");
|
||||
add_location("ftp.fh-dortmund.de");
|
||||
add_location("ftp.fit.qut.edu.au");
|
||||
add_location("ftp.forum.swarthmore.edu");
|
||||
add_location("ftp.fsu.edu");
|
||||
add_location("ftp.ftp.epson.com");
|
||||
add_location("ftp.fu-berlin.de");
|
||||
add_location("ftp.fujixerox.co.jp");
|
||||
add_location("ftp.game.org");
|
||||
add_location("ftp.ge.ucl.ac.uk");
|
||||
add_location("ftp.genetics.wisc.edu");
|
||||
add_location("ftp.geo.uu.nl");
|
||||
add_location("ftp.geom.umn.edu");
|
||||
add_location("ftp.gfdl.gov");
|
||||
add_location("ftp.gigo.com");
|
||||
add_location("ftp.giss.nasa.gov");
|
||||
add_location("ftp.globalnet.co.uk");
|
||||
add_location("ftp.gnu.org");
|
||||
add_location("ftp.gnu.vbs.at");
|
||||
add_location("ftp.gps.caltech.edu");
|
||||
add_location("ftp.grau-wzs.de");
|
||||
add_location("ftp.gsoc.dlr.de");
|
||||
add_location("ftp.gutenberg.org");
|
||||
add_location("ftp.hawaii.edu");
|
||||
add_location("ftp.hep.net");
|
||||
add_location("ftp.hgc.edu");
|
||||
add_location("ftp.hgmp.mrc.ac.uk");
|
||||
add_location("ftp.hugin.dk");
|
||||
add_location("ftp.ic.tsu.ru");
|
||||
add_location("ftp.icce.rug.nl");
|
||||
add_location("ftp.icon-stl.net");
|
||||
add_location("ftp.icor.fr");
|
||||
add_location("ftp.ics.uci.edu");
|
||||
add_location("ftp.idsia.ch");
|
||||
add_location("ftp.ifm.liu.se");
|
||||
add_location("ftp.ifm.uni-kiel.de");
|
||||
add_location("ftp.iglou.com");
|
||||
add_location("ftp.ign.fr");
|
||||
add_location("ftp.imag.fr");
|
||||
add_location("ftp.inel.gov");
|
||||
add_location("ftp.inf.ethz.ch");
|
||||
add_location("ftp.inf.puc-rio.br");
|
||||
add_location("ftp.infoflex.se");
|
||||
add_location("ftp.informatik.rwth-aachen.de");
|
||||
add_location("ftp.informatik.uni-bremen.de");
|
||||
add_location("ftp.informatik.uni-hannover.de");
|
||||
add_location("ftp.infoscandic.se");
|
||||
add_location("ftp.intel.com");
|
||||
add_location("ftp.intergraph.com");
|
||||
add_location("ftp.ionet.net");
|
||||
add_location("ftp.ipc.chiba-u.ac.jp");
|
||||
add_location("ftp.ips.cs.tu-bs.de");
|
||||
add_location("ftp.iram.rwth-aachen.de");
|
||||
add_location("ftp.is.co.za");
|
||||
add_location("ftp.isoc.org");
|
||||
add_location("ftp.iteso.mx");
|
||||
add_location("ftp.ivd.uni-stuttgart.de");
|
||||
add_location("ftp.iway.fr");
|
||||
add_location("ftp.jcu.edu.au");
|
||||
add_location("ftp.jhuapl.edu");
|
||||
add_location("ftp.jpix.ad.jp");
|
||||
add_location("ftp.karlin.mff.cuni.cz");
|
||||
add_location("ftp.kfu.com");
|
||||
add_location("ftp.kfunigraz.ac.at");
|
||||
add_location("ftp.khm.de");
|
||||
add_location("ftp.ki.se");
|
||||
add_location("ftp.komkon.org");
|
||||
add_location("ftp.laas.fr");
|
||||
add_location("ftp.lanl.gov");
|
||||
add_location("ftp.lantronix.com");
|
||||
add_location("ftp.lava.net");
|
||||
add_location("ftp.lcs.mit.edu");
|
||||
add_location("ftp.legend.co.uk");
|
||||
add_location("ftp.leidenuniv.nl");
|
||||
add_location("ftp.let.rug.nl");
|
||||
add_location("ftp.linux.co.uk");
|
||||
add_location("ftp.linux.unife.it");
|
||||
add_location("ftp.liv.ac.uk");
|
||||
add_location("ftp.livingston.com");
|
||||
add_location("ftp.lnt.e-technik.tu-muenchen.de");
|
||||
add_location("ftp.lsu.edu");
|
||||
add_location("ftp.lth.se");
|
||||
add_location("ftp.lysator.liu.se");
|
||||
add_location("ftp.mailbase.ac.uk");
|
||||
add_location("ftp.mainstream.net");
|
||||
add_location("ftp.maricopa.edu");
|
||||
add_location("ftp.math.fu-berlin.de");
|
||||
add_location("ftp.math.hr");
|
||||
add_location("ftp.math.utah.edu");
|
||||
add_location("ftp.mathematik.uni-marburg.de");
|
||||
add_location("ftp.maths.tcd.ie");
|
||||
add_location("ftp.maths.usyd.edu.au");
|
||||
add_location("ftp.mathworks.com");
|
||||
add_location("ftp.mbb.ki.se");
|
||||
add_location("ftp.mbt.ru");
|
||||
add_location("ftp.mcs.net");
|
||||
add_location("ftp.mcs.vuw.ac.nz");
|
||||
add_location("ftp.media.mit.edu");
|
||||
add_location("ftp.meme.com");
|
||||
add_location("ftp.merl.com");
|
||||
add_location("ftp.microport.com");
|
||||
add_location("ftp.mms.de");
|
||||
add_location("ftp.mpce.mq.edu.au");
|
||||
add_location("ftp.mpgn.com");
|
||||
add_location("ftp.mpipf-muenchen.mpg.de");
|
||||
add_location("ftp.mscf.uky.edu");
|
||||
add_location("ftp.natinst.com");
|
||||
add_location("ftp.ncsa.uiuc.edu");
|
||||
add_location("ftp.net-tel.co.uk");
|
||||
add_location("ftp.net.cmu.edu");
|
||||
add_location("ftp.netsw.org");
|
||||
add_location("ftp.new-york.net");
|
||||
add_location("ftp.nis.net");
|
||||
add_location("ftp.nlm.nih.gov");
|
||||
add_location("ftp.nmt.edu");
|
||||
add_location("ftp.noao.edu");
|
||||
add_location("ftp.ntnu.no");
|
||||
add_location("ftp.nwu.edu");
|
||||
add_location("ftp.nysaes.cornell.edu");
|
||||
add_location("ftp.observ.u-bordeaux.fr");
|
||||
add_location("ftp.oit.unc.edu");
|
||||
add_location("ftp.oldenbourg.de");
|
||||
add_location("ftp.omg.unb.ca");
|
||||
add_location("ftp.onecall.net");
|
||||
add_location("ftp.ornl.gov");
|
||||
add_location("ftp.ozone.fmi.fi");
|
||||
add_location("ftp.pacific.net.hk");
|
||||
add_location("ftp.panix.com");
|
||||
add_location("ftp.pcnet.com");
|
||||
add_location("ftp.phred.org");
|
||||
add_location("ftp.pnl.gov");
|
||||
add_location("ftp.prairienet.org");
|
||||
add_location("ftp.proxad.net");
|
||||
add_location("ftp.proximity.com.au");
|
||||
add_location("ftp.psg.com");
|
||||
add_location("ftp.psy.uq.edu.au");
|
||||
add_location("ftp.psychologie.uni-freiburg.de");
|
||||
add_location("ftp.pwr.wroc.pl");
|
||||
add_location("ftp.python.org");
|
||||
add_location("ftp.quantum.de");
|
||||
add_location("ftp.ra.phy.cam.ac.uk");
|
||||
add_location("ftp.rasip.fer.hr");
|
||||
add_location("ftp.rbgkew.org.uk");
|
||||
add_location("ftp.rcsb.org");
|
||||
add_location("ftp.realtime.net");
|
||||
add_location("ftp.red-bean.com");
|
||||
add_location("ftp.redac.co.uk");
|
||||
add_location("ftp.redac.fr");
|
||||
add_location("ftp.rediris.es");
|
||||
add_location("ftp.rgn.it");
|
||||
add_location("ftp.rice.edu");
|
||||
add_location("ftp.rkk.hu");
|
||||
add_location("ftp.robelle.com");
|
||||
add_location("ftp.rose.hp.com");
|
||||
add_location("ftp.rt66.com");
|
||||
add_location("ftp.ruhr-uni-bochum.de");
|
||||
add_location("ftp.rz.uni-frankfurt.de");
|
||||
add_location("ftp.sat.dundee.ac.uk");
|
||||
add_location("ftp.saugus.net");
|
||||
add_location("ftp.schrodinger.com");
|
||||
add_location("ftp.science-computing.de");
|
||||
add_location("ftp.science.unitn.it");
|
||||
add_location("ftp.sco.com");
|
||||
add_location("ftp.scs.leeds.ac.uk");
|
||||
add_location("ftp.scsr.nevada.edu");
|
||||
add_location("ftp.sd.monash.edu.au");
|
||||
add_location("ftp.sdv.fr");
|
||||
add_location("ftp.selapo.vwl.uni-muenchen.de");
|
||||
add_location("ftp.serv.net");
|
||||
add_location("ftp.sgi.leeds.ac.uk");
|
||||
add_location("ftp.shore.net");
|
||||
add_location("ftp.socsci.auc.dk");
|
||||
add_location("ftp.space.net");
|
||||
add_location("ftp.spec.org");
|
||||
add_location("ftp.stallion.com");
|
||||
add_location("ftp.starnet.de");
|
||||
add_location("ftp.stat.math.ethz.ch");
|
||||
add_location("ftp.stat.umn.edu");
|
||||
add_location("ftp.std.com");
|
||||
add_location("ftp.structchem.uni-essen.de");
|
||||
add_location("ftp.sunsite.org.uk");
|
||||
add_location("ftp.syd.dms.csiro.au");
|
||||
add_location("ftp.tapr.org");
|
||||
add_location("ftp.teco.uni-karlsruhe.de");
|
||||
add_location("ftp.tenon.com");
|
||||
add_location("ftp.tierzucht.uni-kiel.de");
|
||||
add_location("ftp.tnt.uni-hannover.de");
|
||||
add_location("ftp.tu-clausthal.de");
|
||||
add_location("ftp.uci.edu");
|
||||
add_location("ftp.ucsd.edu");
|
||||
add_location("ftp.udel.edu");
|
||||
add_location("ftp.uec.ac.jp");
|
||||
add_location("ftp.uibk.ac.at");
|
||||
add_location("ftp.uit.co.uk");
|
||||
add_location("ftp.uji.es");
|
||||
add_location("ftp.uke.uni-hamburg.de");
|
||||
add_location("ftp.ulcc.ac.uk");
|
||||
add_location("ftp.um.es");
|
||||
add_location("ftp.umi.cs.tu-bs.de");
|
||||
add_location("ftp.uni-augsburg.de");
|
||||
add_location("ftp.uni-dortmund.de");
|
||||
add_location("ftp.uni-hannover.de");
|
||||
add_location("ftp.uni-magdeburg.de");
|
||||
add_location("ftp.unidata.ucar.edu");
|
||||
add_location("ftp.unige.ch");
|
||||
add_location("ftp.univ-aix.fr");
|
||||
add_location("ftp.upc.es");
|
||||
add_location("ftp.uradio.ku.dk");
|
||||
add_location("ftp.uralexpress.ru");
|
||||
add_location("ftp.urc.ac.ru");
|
||||
add_location("ftp.ut.ee");
|
||||
add_location("ftp.uunet.ca");
|
||||
add_location("ftp.uwo.ca");
|
||||
add_location("ftp.vaxxine.com");
|
||||
add_location("ftp.visi.com");
|
||||
add_location("ftp.vub.ac.be");
|
||||
add_location("ftp.wfu.edu");
|
||||
add_location("ftp.win.tue.nl");
|
||||
add_location("ftp.wolfe.net");
|
||||
add_location("sunsite.cnlab-switch.ch");
|
||||
add_location("sunsite.sut.ac.jp");
|
||||
add_location("ftp.cuhk.edu.hk");
|
||||
add_location("ftp.cetis.hvu.nl");
|
||||
add_location("ftp.clinet.fi");
|
||||
add_location("ftp.gamma.ru");
|
||||
add_location("ftp.itv.se");
|
||||
add_location("ftp.cs.rpi.edu");
|
||||
add_location("ftp.carrier.kiev.ua");
|
||||
add_location("ftp.rosnet.ru");
|
||||
add_location("ftp.nsk.su");
|
||||
add_location("ftp.southcom.com.au");
|
||||
|
||||
// -->
|
||||
|
||||
</script>
|
||||
<body>
|
||||
<br><br><br>
|
||||
</body>
|
||||
</html>
|
||||
@@ -4,7 +4,7 @@
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
DIRS += ["about", "data", "file"]
|
||||
DIRS += ["about", "data", "file", "ftp"]
|
||||
if CONFIG["MOZ_WIDGET_TOOLKIT"] == "gtk":
|
||||
DIRS += ["gio"]
|
||||
DIRS += ["http", "res", "viewsource", "websocket"]
|
||||
|
||||
@@ -22,7 +22,7 @@ XPCOMUtils.defineLazyGetter(this, "systemSettings", function() {
|
||||
if (aPort != -1) {
|
||||
return "SOCKS5 http://localhost:9050";
|
||||
}
|
||||
if (aScheme == "http") {
|
||||
if (aScheme == "http" || aScheme == "ftp") {
|
||||
return "PROXY http://localhost:8080";
|
||||
}
|
||||
if (aScheme == "https") {
|
||||
@@ -85,6 +85,15 @@ add_task(async function testHttpsProxy() {
|
||||
equal(pi.type, "https", "Expected proxy type to be https");
|
||||
});
|
||||
|
||||
if (Services.prefs.getBoolPref("network.ftp.enabled")) {
|
||||
add_task(async function testFtpProxy() {
|
||||
let pi = await TestProxyTypeByURI("ftp://ftp.mozilla.org/");
|
||||
equal(pi.host, "localhost", "Expected proxy host to be localhost");
|
||||
equal(pi.port, 8080, "Expected proxy port to be 8080");
|
||||
equal(pi.type, "http", "Expected proxy type to be http");
|
||||
});
|
||||
}
|
||||
|
||||
add_task(async function testSocksProxy() {
|
||||
let pi = await TestProxyTypeByURI("http://www.mozilla.org:1234/");
|
||||
equal(pi.host, "localhost", "Expected proxy host to be localhost");
|
||||
|
||||
@@ -9,6 +9,9 @@
|
||||
"use strict";
|
||||
|
||||
var URIs = ["http://example.org", "https://example.org"];
|
||||
if (Services.prefs.getBoolPref("network.ftp.enabled")) {
|
||||
URIs.push("ftp://example.org");
|
||||
}
|
||||
|
||||
function* getChannels() {
|
||||
for (let u of URIs) {
|
||||
|
||||
21
netwerk/test/unit/test_disabled_ftp.js
Normal file
21
netwerk/test/unit/test_disabled_ftp.js
Normal file
@@ -0,0 +1,21 @@
|
||||
"use strict";
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
Services.prefs.clearUserPref("network.ftp.enabled");
|
||||
});
|
||||
|
||||
add_task(async function ftp_disabled() {
|
||||
Services.prefs.setBoolPref("network.ftp.enabled", false);
|
||||
Services.prefs.setBoolPref("network.protocol-handler.external.ftp", false);
|
||||
|
||||
Assert.throws(
|
||||
() => {
|
||||
NetUtil.newChannel({
|
||||
uri: "ftp://ftp.de.debian.org/",
|
||||
loadUsingSystemPrincipal: true,
|
||||
}).QueryInterface(Ci.nsIHttpChannel);
|
||||
},
|
||||
/NS_ERROR_UNKNOWN_PROTOCOL/,
|
||||
"creating the FTP channel must throw"
|
||||
);
|
||||
});
|
||||
@@ -426,6 +426,7 @@ skip-if = socketprocess_networking
|
||||
run-sequentially = one http2 node proxy is used for all tests, this test is using global session counter
|
||||
skip-if = os == "android"
|
||||
[test_head_request_no_response_body.js]
|
||||
[test_disabled_ftp.js]
|
||||
[test_cache_204_response.js]
|
||||
[test_http3.js]
|
||||
# asan - bug 1616239
|
||||
|
||||
@@ -22,6 +22,12 @@ const {
|
||||
WebDriverSession,
|
||||
} = ChromeUtils.import("chrome://marionette/content/session.js");
|
||||
|
||||
// FTP protocol handler is needed for ftpProxy tests
|
||||
registerCleanupFunction(function() {
|
||||
Preferences.reset("network.ftp.enabled");
|
||||
});
|
||||
Preferences.set("network.ftp.enabled", true);
|
||||
|
||||
add_test(function test_WebDriverSession_ctor() {
|
||||
const session = new WebDriverSession();
|
||||
|
||||
@@ -151,6 +157,7 @@ add_test(function test_Proxy_ctor() {
|
||||
"proxyType",
|
||||
"httpProxy",
|
||||
"sslProxy",
|
||||
"ftpProxy",
|
||||
"socksProxy",
|
||||
"socksVersion",
|
||||
"proxyAutoconfigUrl",
|
||||
@@ -200,7 +207,7 @@ add_test(function test_Proxy_init() {
|
||||
equal(Preferences.get("network.proxy.type"), 5);
|
||||
|
||||
// manual
|
||||
for (let proxy of ["http", "ssl", "socks"]) {
|
||||
for (let proxy of ["ftp", "http", "ssl", "socks"]) {
|
||||
p = new Proxy();
|
||||
p.proxyType = "manual";
|
||||
p.noProxy = ["foo", "bar"];
|
||||
@@ -251,7 +258,7 @@ add_test(function test_Proxy_toJSON() {
|
||||
p.proxyType = "manual";
|
||||
deepEqual(p.toJSON(), { proxyType: "manual" });
|
||||
|
||||
for (let proxy of ["httpProxy", "sslProxy", "socksProxy"]) {
|
||||
for (let proxy of ["ftpProxy", "httpProxy", "sslProxy", "socksProxy"]) {
|
||||
let expected = { proxyType: "manual" };
|
||||
|
||||
p = new Proxy();
|
||||
@@ -329,7 +336,7 @@ add_test(function test_Proxy_fromJSON() {
|
||||
p.proxyType = "manual";
|
||||
deepEqual(p, Proxy.fromJSON({ proxyType: "manual" }));
|
||||
|
||||
for (let proxy of ["httpProxy", "sslProxy", "socksProxy"]) {
|
||||
for (let proxy of ["httpProxy", "sslProxy", "ftpProxy", "socksProxy"]) {
|
||||
let manual = { proxyType: "manual" };
|
||||
|
||||
// invalid hosts
|
||||
@@ -387,7 +394,7 @@ add_test(function test_Proxy_fromJSON() {
|
||||
if (proxy === "socksProxy") {
|
||||
p[`${proxy}Port`] = null;
|
||||
} else {
|
||||
let default_ports = { httpProxy: 80, sslProxy: 443 };
|
||||
let default_ports = { ftpProxy: 21, httpProxy: 80, sslProxy: 443 };
|
||||
|
||||
p[`${proxy}Port`] = default_ports[proxy];
|
||||
}
|
||||
|
||||
@@ -70,6 +70,15 @@ ExtensionPreferencesManager.addSetting("contextMenuShowEvent", {
|
||||
},
|
||||
});
|
||||
|
||||
ExtensionPreferencesManager.addSetting("ftpProtocolEnabled", {
|
||||
permission: "browserSettings",
|
||||
prefNames: ["network.ftp.enabled"],
|
||||
|
||||
setCallback(value) {
|
||||
return { [this.prefNames[0]]: value };
|
||||
},
|
||||
});
|
||||
|
||||
ExtensionPreferencesManager.addSetting("imageAnimationBehavior", {
|
||||
permission: "browserSettings",
|
||||
prefNames: ["image.animation_mode"],
|
||||
@@ -247,7 +256,7 @@ this.browserSettings = class extends ExtensionAPI {
|
||||
name: "ftpProtocolEnabled",
|
||||
readOnly: true,
|
||||
callback() {
|
||||
return false;
|
||||
return Services.prefs.getBoolPref("network.ftp.enabled");
|
||||
},
|
||||
}),
|
||||
homepageOverride: getSettingsAPI({
|
||||
|
||||
@@ -31,6 +31,7 @@ const PROXY_TYPES_MAP = new Map([
|
||||
const DEFAULT_PORTS = new Map([
|
||||
["http", 80],
|
||||
["ssl", 443],
|
||||
["ftp", 21],
|
||||
["socks", 1080],
|
||||
]);
|
||||
|
||||
@@ -41,6 +42,8 @@ ExtensionPreferencesManager.addSetting("proxy.settings", {
|
||||
"network.proxy.http",
|
||||
"network.proxy.http_port",
|
||||
"network.proxy.share_proxy_settings",
|
||||
"network.proxy.ftp",
|
||||
"network.proxy.ftp_port",
|
||||
"network.proxy.ssl",
|
||||
"network.proxy.ssl_port",
|
||||
"network.proxy.socks",
|
||||
@@ -65,7 +68,7 @@ ExtensionPreferencesManager.addSetting("proxy.settings", {
|
||||
"network.http.proxy.respect-be-conservative": value.respectBeConservative,
|
||||
};
|
||||
|
||||
for (let prop of ["http", "ssl", "socks"]) {
|
||||
for (let prop of ["http", "ftp", "ssl", "socks"]) {
|
||||
if (value[prop]) {
|
||||
let url = new URL(`http://${value[prop]}`);
|
||||
prefs[`network.proxy.${prop}`] = url.hostname;
|
||||
@@ -204,7 +207,7 @@ this.proxy = class extends ExtensionAPI {
|
||||
);
|
||||
}
|
||||
|
||||
for (let prop of ["http", "ssl", "socks"]) {
|
||||
for (let prop of ["http", "ftp", "ssl", "socks"]) {
|
||||
let host = Services.prefs.getCharPref(`network.proxy.${prop}`);
|
||||
let port = Services.prefs.getIntPref(
|
||||
`network.proxy.${prop}_port`
|
||||
@@ -260,10 +263,12 @@ this.proxy = class extends ExtensionAPI {
|
||||
// Match what about:preferences does with proxy settings
|
||||
// since the proxy service does not check the value
|
||||
// of share_proxy_settings.
|
||||
value.ssl = value.http;
|
||||
for (let prop of ["ftp", "ssl"]) {
|
||||
value[prop] = value.http;
|
||||
}
|
||||
}
|
||||
|
||||
for (let prop of ["http", "ssl", "socks"]) {
|
||||
for (let prop of ["http", "ftp", "ssl", "socks"]) {
|
||||
let host = value[prop];
|
||||
if (host) {
|
||||
try {
|
||||
|
||||
@@ -56,8 +56,7 @@
|
||||
},
|
||||
"ftpProtocolEnabled": {
|
||||
"$ref": "types.Setting",
|
||||
"description": "Returns whether the FTP protocol is enabled. Read-only.",
|
||||
"deprecated": "FTP support was removed from Firefox in bug 1574475"
|
||||
"description": "Returns whether the FTP protocol is enabled. Read-only."
|
||||
},
|
||||
"homepageOverride": {
|
||||
"$ref": "types.Setting",
|
||||
|
||||
@@ -214,14 +214,11 @@ add_task(async function test_browser_settings() {
|
||||
});
|
||||
}
|
||||
|
||||
// Bug 1699222 When the pref is removed, the API needs to be updated to always
|
||||
// return false. At that time it should be deprecated as well.
|
||||
extension.sendMessage("get", "ftpProtocolEnabled");
|
||||
let data = await extension.awaitMessage("settingData");
|
||||
equal(data.value, false);
|
||||
equal(
|
||||
data.levelOfControl,
|
||||
"not_controllable",
|
||||
`ftpProtocolEnabled is not controllable.`
|
||||
);
|
||||
equal(data.value, Services.prefs.getBoolPref("network.ftp.enabled"));
|
||||
|
||||
await testSetting("newTabPosition", "afterCurrent", {
|
||||
"browser.tabs.insertRelatedAfterCurrent": false,
|
||||
|
||||
@@ -52,6 +52,8 @@ add_task(async function test_browser_settings() {
|
||||
"network.proxy.http": "",
|
||||
"network.proxy.http_port": 0,
|
||||
"network.proxy.share_proxy_settings": false,
|
||||
"network.proxy.ftp": "",
|
||||
"network.proxy.ftp_port": 0,
|
||||
"network.proxy.ssl": "",
|
||||
"network.proxy.ssl_port": 0,
|
||||
"network.proxy.socks": "",
|
||||
@@ -133,6 +135,7 @@ add_task(async function test_browser_settings() {
|
||||
socksVersion: 5,
|
||||
passthrough: "",
|
||||
http: "",
|
||||
ftp: "",
|
||||
ssl: "",
|
||||
socks: "",
|
||||
respectBeConservative: true,
|
||||
@@ -229,12 +232,15 @@ add_task(async function test_browser_settings() {
|
||||
{
|
||||
proxyType: "manual",
|
||||
http: "http://www.mozilla.org:8080",
|
||||
ftp: "http://www.mozilla.org:1234",
|
||||
httpProxyAll: true,
|
||||
},
|
||||
{
|
||||
"network.proxy.type": proxySvc.PROXYCONFIG_MANUAL,
|
||||
"network.proxy.http": "www.mozilla.org",
|
||||
"network.proxy.http_port": 8080,
|
||||
"network.proxy.ftp": "www.mozilla.org",
|
||||
"network.proxy.ftp_port": 8080,
|
||||
"network.proxy.ssl": "www.mozilla.org",
|
||||
"network.proxy.ssl_port": 8080,
|
||||
"network.proxy.share_proxy_settings": true,
|
||||
@@ -242,6 +248,7 @@ add_task(async function test_browser_settings() {
|
||||
{
|
||||
proxyType: "manual",
|
||||
http: "www.mozilla.org:8080",
|
||||
ftp: "www.mozilla.org:8080",
|
||||
ssl: "www.mozilla.org:8080",
|
||||
socks: "",
|
||||
httpProxyAll: true,
|
||||
@@ -265,6 +272,8 @@ add_task(async function test_browser_settings() {
|
||||
"network.proxy.http": "www.mozilla.org",
|
||||
"network.proxy.http_port": 8080,
|
||||
"network.proxy.share_proxy_settings": false,
|
||||
"network.proxy.ftp": "www.mozilla.org",
|
||||
"network.proxy.ftp_port": 8081,
|
||||
"network.proxy.ssl": "www.mozilla.org",
|
||||
"network.proxy.ssl_port": 8082,
|
||||
"network.proxy.socks": "mozilla.org",
|
||||
@@ -272,17 +281,6 @@ add_task(async function test_browser_settings() {
|
||||
"network.proxy.socks_version": 4,
|
||||
"network.proxy.no_proxies_on": ".mozilla.org",
|
||||
"network.http.proxy.respect-be-conservative": true,
|
||||
},
|
||||
{
|
||||
proxyType: "manual",
|
||||
http: "www.mozilla.org:8080",
|
||||
httpProxyAll: false,
|
||||
// ftp: "www.mozilla.org:8081", // This line should not be sent back
|
||||
ssl: "www.mozilla.org:8082",
|
||||
socks: "mozilla.org:8083",
|
||||
socksVersion: 4,
|
||||
passthrough: ".mozilla.org",
|
||||
respectBeConservative: true,
|
||||
}
|
||||
);
|
||||
|
||||
@@ -290,6 +288,7 @@ add_task(async function test_browser_settings() {
|
||||
{
|
||||
proxyType: "manual",
|
||||
http: "http://www.mozilla.org",
|
||||
ftp: "ftp://www.mozilla.org",
|
||||
ssl: "https://www.mozilla.org",
|
||||
socks: "mozilla.org",
|
||||
socksVersion: 4,
|
||||
@@ -301,6 +300,8 @@ add_task(async function test_browser_settings() {
|
||||
"network.proxy.http": "www.mozilla.org",
|
||||
"network.proxy.http_port": 80,
|
||||
"network.proxy.share_proxy_settings": false,
|
||||
"network.proxy.ftp": "www.mozilla.org",
|
||||
"network.proxy.ftp_port": 21,
|
||||
"network.proxy.ssl": "www.mozilla.org",
|
||||
"network.proxy.ssl_port": 443,
|
||||
"network.proxy.socks": "mozilla.org",
|
||||
@@ -313,6 +314,7 @@ add_task(async function test_browser_settings() {
|
||||
proxyType: "manual",
|
||||
http: "www.mozilla.org:80",
|
||||
httpProxyAll: false,
|
||||
ftp: "www.mozilla.org:21",
|
||||
ssl: "www.mozilla.org:443",
|
||||
socks: "mozilla.org:1080",
|
||||
socksVersion: 4,
|
||||
@@ -325,6 +327,7 @@ add_task(async function test_browser_settings() {
|
||||
{
|
||||
proxyType: "manual",
|
||||
http: "http://www.mozilla.org:80",
|
||||
ftp: "ftp://www.mozilla.org:21",
|
||||
ssl: "https://www.mozilla.org:443",
|
||||
socks: "mozilla.org:1080",
|
||||
socksVersion: 4,
|
||||
@@ -336,6 +339,8 @@ add_task(async function test_browser_settings() {
|
||||
"network.proxy.http": "www.mozilla.org",
|
||||
"network.proxy.http_port": 80,
|
||||
"network.proxy.share_proxy_settings": false,
|
||||
"network.proxy.ftp": "www.mozilla.org",
|
||||
"network.proxy.ftp_port": 21,
|
||||
"network.proxy.ssl": "www.mozilla.org",
|
||||
"network.proxy.ssl_port": 443,
|
||||
"network.proxy.socks": "mozilla.org",
|
||||
@@ -348,6 +353,7 @@ add_task(async function test_browser_settings() {
|
||||
proxyType: "manual",
|
||||
http: "www.mozilla.org:80",
|
||||
httpProxyAll: false,
|
||||
ftp: "www.mozilla.org:21",
|
||||
ssl: "www.mozilla.org:443",
|
||||
socks: "mozilla.org:1080",
|
||||
socksVersion: 4,
|
||||
@@ -360,6 +366,7 @@ add_task(async function test_browser_settings() {
|
||||
{
|
||||
proxyType: "manual",
|
||||
http: "http://www.mozilla.org:80",
|
||||
ftp: "ftp://www.mozilla.org:80",
|
||||
ssl: "https://www.mozilla.org:80",
|
||||
socks: "mozilla.org:80",
|
||||
socksVersion: 4,
|
||||
@@ -371,6 +378,8 @@ add_task(async function test_browser_settings() {
|
||||
"network.proxy.http": "www.mozilla.org",
|
||||
"network.proxy.http_port": 80,
|
||||
"network.proxy.share_proxy_settings": false,
|
||||
"network.proxy.ftp": "www.mozilla.org",
|
||||
"network.proxy.ftp_port": 80,
|
||||
"network.proxy.ssl": "www.mozilla.org",
|
||||
"network.proxy.ssl_port": 80,
|
||||
"network.proxy.socks": "mozilla.org",
|
||||
@@ -383,6 +392,7 @@ add_task(async function test_browser_settings() {
|
||||
proxyType: "manual",
|
||||
http: "www.mozilla.org:80",
|
||||
httpProxyAll: false,
|
||||
ftp: "www.mozilla.org:80",
|
||||
ssl: "www.mozilla.org:80",
|
||||
socks: "mozilla.org:80",
|
||||
socksVersion: 4,
|
||||
@@ -396,6 +406,7 @@ add_task(async function test_browser_settings() {
|
||||
{
|
||||
proxyType: "none",
|
||||
http: "",
|
||||
ftp: "",
|
||||
ssl: "",
|
||||
socks: "",
|
||||
socksVersion: 5,
|
||||
@@ -406,6 +417,8 @@ add_task(async function test_browser_settings() {
|
||||
"network.proxy.type": proxySvc.PROXYCONFIG_DIRECT,
|
||||
"network.proxy.http": "",
|
||||
"network.proxy.http_port": 0,
|
||||
"network.proxy.ftp": "",
|
||||
"network.proxy.ftp_port": 0,
|
||||
"network.proxy.ssl": "",
|
||||
"network.proxy.ssl_port": 0,
|
||||
"network.proxy.socks": "",
|
||||
@@ -539,6 +552,8 @@ add_task(async function test_proxy_settings_permissions() {
|
||||
"network.proxy.type",
|
||||
"network.proxy.http",
|
||||
"network.proxy.http_port",
|
||||
"network.proxy.ftp",
|
||||
"network.proxy.ftp_port",
|
||||
"network.proxy.ssl",
|
||||
"network.proxy.ssl_port",
|
||||
"network.proxy.socks",
|
||||
@@ -574,6 +589,7 @@ add_task(async function test_proxy_settings_permissions() {
|
||||
proxyType: "manual",
|
||||
http: "www.mozilla.org:8080",
|
||||
httpProxyAll: false,
|
||||
ftp: "www.mozilla.org:8081",
|
||||
ssl: "www.mozilla.org:8082",
|
||||
socks: "mozilla.org:8083",
|
||||
socksVersion: 4,
|
||||
@@ -591,6 +607,7 @@ add_task(async function test_proxy_settings_permissions() {
|
||||
proxyType: "manual",
|
||||
http: "www.mozilla.org:8080",
|
||||
httpProxyAll: false,
|
||||
ftp: "www.mozilla.org:8081",
|
||||
ssl: "www.mozilla.org:8082",
|
||||
socks: "mozilla.org:8083",
|
||||
socksVersion: 4,
|
||||
|
||||
@@ -249,7 +249,26 @@ add_task(async function test_passthrough() {
|
||||
await ext1.unload();
|
||||
});
|
||||
|
||||
add_task(async function test_ftp() {
|
||||
Services.prefs.setBoolPref("network.ftp.enabled", true);
|
||||
let extension = await getExtension({
|
||||
host: "1.2.3.4",
|
||||
port: 8888,
|
||||
type: "http",
|
||||
});
|
||||
|
||||
let proxyInfo = await getProxyInfo("ftp://somewhere.mozilla.org/");
|
||||
|
||||
equal(proxyInfo.host, "1.2.3.4", `proxy host correct`);
|
||||
equal(proxyInfo.port, "8888", `proxy port correct`);
|
||||
equal(proxyInfo.type, "http", `proxy type correct`);
|
||||
|
||||
await extension.unload();
|
||||
Services.prefs.clearUserPref("network.ftp.enabled");
|
||||
});
|
||||
|
||||
add_task(async function test_ftp_disabled() {
|
||||
Services.prefs.setBoolPref("network.ftp.enabled", false);
|
||||
let extension = await getExtension({
|
||||
host: "1.2.3.4",
|
||||
port: 8888,
|
||||
@@ -265,6 +284,7 @@ add_task(async function test_ftp_disabled() {
|
||||
);
|
||||
|
||||
await extension.unload();
|
||||
Services.prefs.clearUserPref("network.ftp.enabled");
|
||||
});
|
||||
|
||||
add_task(async function test_ws() {
|
||||
|
||||
@@ -119,12 +119,19 @@ add_task(async function test_match_url_filters() {
|
||||
// Port filter: standard (implicit) ports.
|
||||
{ shouldPass, filters: [{ ports: [443] }], url: "https://mozilla.org" },
|
||||
{ shouldPass, filters: [{ ports: [80] }], url: "http://mozilla.org" },
|
||||
{
|
||||
shouldPass,
|
||||
filters: [{ ports: [21] }],
|
||||
url: "ftp://ftp.mozilla.org",
|
||||
prefs: [["network.ftp.enabled", true]],
|
||||
},
|
||||
|
||||
// Port matching unknown protocols will fail.
|
||||
{
|
||||
shouldFail,
|
||||
filters: [{ ports: [21] }],
|
||||
url: "ftp://ftp.mozilla.org",
|
||||
prefs: [["network.ftp.enabled", false]],
|
||||
},
|
||||
|
||||
// Port filter: schemes without a default port.
|
||||
|
||||
@@ -362,6 +362,14 @@ with modules["NETWORK"]:
|
||||
# probably in the process of being torn down.
|
||||
errors["NS_ERROR_DOCSHELL_DYING"] = FAILURE(78)
|
||||
|
||||
# FTP specific error codes:
|
||||
|
||||
errors["NS_ERROR_FTP_LOGIN"] = FAILURE(21)
|
||||
errors["NS_ERROR_FTP_CWD"] = FAILURE(22)
|
||||
errors["NS_ERROR_FTP_PASV"] = FAILURE(23)
|
||||
errors["NS_ERROR_FTP_PWD"] = FAILURE(24)
|
||||
errors["NS_ERROR_FTP_LIST"] = FAILURE(28)
|
||||
|
||||
# DNS specific error codes:
|
||||
|
||||
# The lookup of a hostname failed. This generally refers to the hostname
|
||||
@@ -418,6 +426,10 @@ with modules["NETWORK"]:
|
||||
# should NOT free it.
|
||||
errors["NS_SUCCESS_ADOPTED_DATA"] = SUCCESS(90)
|
||||
|
||||
# FTP
|
||||
errors["NS_NET_STATUS_BEGIN_FTP_TRANSACTION"] = SUCCESS(27)
|
||||
errors["NS_NET_STATUS_END_FTP_TRANSACTION"] = SUCCESS(28)
|
||||
|
||||
# This success code may be returned by nsIAuthModule::getNextToken to
|
||||
# indicate that the authentication is finished and thus there's no need
|
||||
# to call getNextToken again.
|
||||
|
||||
Reference in New Issue
Block a user