зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1574475 - Delete FTP code r=necko-reviewers,dragana
Differential Revision: https://phabricator.services.mozilla.com/D111246
This commit is contained in:
Родитель
b6c4d8cd4d
Коммит
824826fd4e
|
@ -1,541 +0,0 @@
|
|||
/* -*- 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
|
|
@ -1,137 +0,0 @@
|
|||
/* -*- 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
|
|
@ -1,418 +0,0 @@
|
|||
/* -*- 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
|
|
@ -1,92 +0,0 @@
|
|||
/* -*- 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
|
|
@ -1,54 +0,0 @@
|
|||
/* -*- 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
|
||||
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,4 +0,0 @@
|
|||
Test
|
||||
here
|
||||
there
|
||||
everywhere
|
|
@ -1,15 +0,0 @@
|
|||
/* -*- 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___
|
|
@ -1,50 +0,0 @@
|
|||
# -*- 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")
|
|
@ -1,213 +0,0 @@
|
|||
/* -*- 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();
|
||||
}
|
|
@ -1,115 +0,0 @@
|
|||
/* -*- 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___ */
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,254 +0,0 @@
|
|||
/* -*- 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_
|
|
@ -1,170 +0,0 @@
|
|||
/* -*- 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;
|
||||
}
|
|
@ -1,83 +0,0 @@
|
|||
/* -*- 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
|
|
@ -1,331 +0,0 @@
|
|||
/* -*- 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();
|
||||
}
|
|
@ -1,85 +0,0 @@
|
|||
/* -*- 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__
|
|
@ -1,29 +0,0 @@
|
|||
/* -*- 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);
|
||||
};
|
|
@ -1,15 +0,0 @@
|
|||
/* -*- 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);
|
||||
};
|
|
@ -1,5 +0,0 @@
|
|||
<html>
|
||||
<body>
|
||||
<h2>Click a link to the left</h2>
|
||||
</body>
|
||||
</html>
|
|
@ -1,12 +0,0 @@
|
|||
<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>
|
|
@ -1,371 +0,0 @@
|
|||
<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>
|
Загрузка…
Ссылка в новой задаче