mirror of
https://github.com/HeyPuter/firefox.git
synced 2026-11-13 20:14:57 -10:00
The inclusions were removed with the following very crude script and the
resulting breakage was fixed up by hand. The manual fixups did either
revert the changes done by the script, replace a generic header with a more
specific one or replace a header with a forward declaration.
find . -name "*.idl" | grep -v web-platform | grep -v third_party | while read path; do
interfaces=$(grep "^\(class\|interface\).*:.*" "$path" | cut -d' ' -f2)
if [ -n "$interfaces" ]; then
if [[ "$interfaces" == *$'\n'* ]]; then
regexp="\("
for i in $interfaces; do regexp="$regexp$i\|"; done
regexp="${regexp%%\\\|}\)"
else
regexp="$interfaces"
fi
interface=$(basename "$path")
rg -l "#include.*${interface%%.idl}.h" . | while read path2; do
hits=$(grep -v "#include.*${interface%%.idl}.h" "$path2" | grep -c "$regexp" )
if [ $hits -eq 0 ]; then
echo "Removing ${interface} from ${path2}"
grep -v "#include.*${interface%%.idl}.h" "$path2" > "$path2".tmp
mv -f "$path2".tmp "$path2"
fi
done
fi
done
Differential Revision: https://phabricator.services.mozilla.com/D55444
585 lines
17 KiB
C++
585 lines
17 KiB
C++
/* -*- Mode: c++; c-basic-offset: 2; tab-width: 20; indent-tabs-mode: nil; -*-
|
|
* 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 <algorithm>
|
|
|
|
#include "WebExecutorSupport.h"
|
|
|
|
#include "nsIChannelEventSink.h"
|
|
#include "nsIHttpChannel.h"
|
|
#include "nsIHttpChannelInternal.h"
|
|
#include "nsIHttpHeaderVisitor.h"
|
|
#include "nsIInputStream.h"
|
|
#include "nsIInterfaceRequestor.h"
|
|
#include "nsINSSErrorsService.h"
|
|
#include "nsIUploadChannel2.h"
|
|
|
|
#include "nsIDNSService.h"
|
|
#include "nsIDNSListener.h"
|
|
#include "nsIDNSRecord.h"
|
|
|
|
#include "mozilla/net/DNS.h" // for NetAddr
|
|
#include "mozilla/net/CookieSettings.h"
|
|
#include "mozilla/Preferences.h"
|
|
|
|
#include "nsNetUtil.h" // for NS_NewURI, NS_NewChannel, NS_NewStreamLoader
|
|
|
|
#include "InetAddress.h" // for java::sdk::InetAddress and java::sdk::UnknownHostException
|
|
#include "ReferrerInfo.h"
|
|
|
|
namespace mozilla {
|
|
using namespace net;
|
|
|
|
namespace widget {
|
|
|
|
static void CompleteWithError(java::GeckoResult::Param aResult,
|
|
nsresult aStatus) {
|
|
nsCOMPtr<nsINSSErrorsService> errSvc =
|
|
do_GetService("@mozilla.org/nss_errors_service;1");
|
|
MOZ_ASSERT(errSvc);
|
|
|
|
uint32_t errorClass;
|
|
nsresult rv = errSvc->GetErrorClass(aStatus, &errorClass);
|
|
if (NS_FAILED(rv)) {
|
|
errorClass = 0;
|
|
}
|
|
|
|
java::WebRequestError::LocalRef error = java::WebRequestError::FromGeckoError(
|
|
int64_t(aStatus), NS_ERROR_GET_MODULE(aStatus), errorClass);
|
|
|
|
aResult->CompleteExceptionally(error.Cast<jni::Throwable>());
|
|
}
|
|
|
|
class ByteBufferStream final : public nsIInputStream {
|
|
public:
|
|
NS_DECL_THREADSAFE_ISUPPORTS
|
|
|
|
explicit ByteBufferStream(jni::ByteBuffer::Param buffer)
|
|
: mBuffer(buffer), mPosition(0), mClosed(false) {
|
|
MOZ_ASSERT(mBuffer);
|
|
MOZ_ASSERT(mBuffer->Address());
|
|
}
|
|
|
|
NS_IMETHOD
|
|
Close() override {
|
|
mClosed = true;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHOD
|
|
Available(uint64_t* aResult) override {
|
|
if (mClosed) {
|
|
return NS_BASE_STREAM_CLOSED;
|
|
}
|
|
|
|
*aResult = (mBuffer->Capacity() - mPosition);
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHOD
|
|
Read(char* aBuf, uint32_t aCount, uint32_t* aCountRead) override {
|
|
if (mClosed) {
|
|
return NS_BASE_STREAM_CLOSED;
|
|
}
|
|
|
|
*aCountRead = uint32_t(
|
|
std::min(uint64_t(mBuffer->Capacity() - mPosition), uint64_t(aCount)));
|
|
|
|
if (*aCountRead > 0) {
|
|
memcpy(aBuf, (char*)mBuffer->Address() + mPosition, *aCountRead);
|
|
mPosition += *aCountRead;
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHOD
|
|
ReadSegments(nsWriteSegmentFun aWriter, void* aClosure, uint32_t aCount,
|
|
uint32_t* aResult) override {
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
NS_IMETHOD
|
|
IsNonBlocking(bool* aResult) override {
|
|
*aResult = false;
|
|
return NS_OK;
|
|
}
|
|
|
|
protected:
|
|
virtual ~ByteBufferStream() {}
|
|
|
|
const jni::ByteBuffer::GlobalRef mBuffer;
|
|
uint64_t mPosition;
|
|
bool mClosed;
|
|
};
|
|
|
|
NS_IMPL_ISUPPORTS(ByteBufferStream, nsIInputStream)
|
|
|
|
class HeaderVisitor final : public nsIHttpHeaderVisitor {
|
|
public:
|
|
NS_DECL_THREADSAFE_ISUPPORTS
|
|
|
|
explicit HeaderVisitor(java::WebResponse::Builder::Param aBuilder)
|
|
: mBuilder(aBuilder) {}
|
|
|
|
NS_IMETHOD
|
|
VisitHeader(const nsACString& aHeader, const nsACString& aValue) override {
|
|
mBuilder->Header(aHeader, aValue);
|
|
return NS_OK;
|
|
}
|
|
|
|
private:
|
|
virtual ~HeaderVisitor() {}
|
|
|
|
const java::WebResponse::Builder::GlobalRef mBuilder;
|
|
};
|
|
|
|
NS_IMPL_ISUPPORTS(HeaderVisitor, nsIHttpHeaderVisitor)
|
|
|
|
class StreamSupport final
|
|
: public java::GeckoInputStream::Support::Natives<StreamSupport> {
|
|
public:
|
|
typedef java::GeckoInputStream::Support::Natives<StreamSupport> Base;
|
|
using Base::AttachNative;
|
|
using Base::DisposeNative;
|
|
using Base::GetNative;
|
|
|
|
explicit StreamSupport(nsIRequest* aRequest) : mRequest(aRequest) {}
|
|
|
|
void Resume() { mRequest->Resume(); }
|
|
|
|
private:
|
|
nsCOMPtr<nsIRequest> mRequest;
|
|
};
|
|
|
|
class LoaderListener final : public nsIStreamListener,
|
|
public nsIInterfaceRequestor,
|
|
public nsIChannelEventSink {
|
|
public:
|
|
NS_DECL_THREADSAFE_ISUPPORTS
|
|
|
|
explicit LoaderListener(java::GeckoResult::Param aResult,
|
|
bool aAllowRedirects, bool testStreamFailure)
|
|
: mResult(aResult),
|
|
mTestStreamFailure(testStreamFailure),
|
|
mAllowRedirects(aAllowRedirects) {
|
|
MOZ_ASSERT(mResult);
|
|
}
|
|
|
|
NS_IMETHOD
|
|
OnStartRequest(nsIRequest* aRequest) override {
|
|
MOZ_ASSERT(!mStream);
|
|
|
|
nsresult status;
|
|
aRequest->GetStatus(&status);
|
|
if (NS_FAILED(status)) {
|
|
CompleteWithError(mResult, status);
|
|
return NS_OK;
|
|
}
|
|
|
|
StreamSupport::Init();
|
|
|
|
// We're expecting data later via OnDataAvailable, so create the stream now.
|
|
mSupport = java::GeckoInputStream::Support::New();
|
|
StreamSupport::AttachNative(mSupport,
|
|
mozilla::MakeUnique<StreamSupport>(aRequest));
|
|
|
|
mStream = java::GeckoInputStream::New(mSupport);
|
|
|
|
// Suspend the request immediately. It will be resumed when (if) someone
|
|
// tries to read the Java stream.
|
|
aRequest->Suspend();
|
|
|
|
nsresult rv = HandleWebResponse(aRequest);
|
|
if (NS_FAILED(rv)) {
|
|
CompleteWithError(mResult, rv);
|
|
return NS_OK;
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHOD
|
|
OnStopRequest(nsIRequest* aRequest, nsresult aStatusCode) override {
|
|
if (mStream) {
|
|
if (NS_FAILED(aStatusCode)) {
|
|
mStream->SendError();
|
|
} else {
|
|
mStream->SendEof();
|
|
}
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHOD
|
|
OnDataAvailable(nsIRequest* aRequest, nsIInputStream* aInputStream,
|
|
uint64_t aOffset, uint32_t aCount) override {
|
|
MOZ_ASSERT(mStream);
|
|
|
|
if (mTestStreamFailure) {
|
|
aRequest->Cancel(NS_ERROR_ABORT);
|
|
}
|
|
|
|
// We only need this for the ReadSegments call, the value is unused.
|
|
uint32_t countRead;
|
|
return aInputStream->ReadSegments(WriteSegment, this, aCount, &countRead);
|
|
}
|
|
|
|
NS_IMETHOD
|
|
GetInterface(const nsIID& aIID, void** aResultOut) override {
|
|
if (aIID.Equals(NS_GET_IID(nsIChannelEventSink))) {
|
|
*aResultOut = static_cast<nsIChannelEventSink*>(this);
|
|
NS_ADDREF_THIS();
|
|
return NS_OK;
|
|
}
|
|
|
|
return NS_ERROR_NO_INTERFACE;
|
|
}
|
|
|
|
NS_IMETHOD
|
|
AsyncOnChannelRedirect(nsIChannel* aOldChannel, nsIChannel* aNewChannel,
|
|
uint32_t flags,
|
|
nsIAsyncVerifyRedirectCallback* callback) override {
|
|
if (!mAllowRedirects) {
|
|
return NS_ERROR_ABORT;
|
|
}
|
|
|
|
callback->OnRedirectVerifyCallback(NS_OK);
|
|
return NS_OK;
|
|
}
|
|
|
|
private:
|
|
static nsresult WriteSegment(nsIInputStream* aInputStream, void* aClosure,
|
|
const char* aFromSegment, uint32_t aToOffset,
|
|
uint32_t aCount, uint32_t* aWriteCount) {
|
|
LoaderListener* self = static_cast<LoaderListener*>(aClosure);
|
|
MOZ_ASSERT(self);
|
|
MOZ_ASSERT(self->mStream);
|
|
|
|
*aWriteCount = aCount;
|
|
|
|
jni::ByteArray::LocalRef buffer = jni::ByteArray::New(
|
|
reinterpret_cast<signed char*>(const_cast<char*>(aFromSegment)),
|
|
*aWriteCount);
|
|
|
|
if (NS_FAILED(self->mStream->AppendBuffer(buffer))) {
|
|
// The stream was closed or something, abort reading this channel.
|
|
return NS_ERROR_ABORT;
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHOD
|
|
HandleWebResponse(nsIRequest* aRequest) {
|
|
nsresult rv;
|
|
nsCOMPtr<nsIHttpChannel> channel = do_QueryInterface(aRequest, &rv);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
// URI
|
|
nsCOMPtr<nsIURI> uri;
|
|
rv = channel->GetURI(getter_AddRefs(uri));
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
nsAutoCString spec;
|
|
rv = uri->GetSpec(spec);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
java::WebResponse::Builder::LocalRef builder =
|
|
java::WebResponse::Builder::New(spec);
|
|
|
|
// Status code
|
|
uint32_t statusCode;
|
|
rv = channel->GetResponseStatus(&statusCode);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
builder->StatusCode(statusCode);
|
|
|
|
// Headers
|
|
RefPtr<HeaderVisitor> visitor = new HeaderVisitor(builder);
|
|
rv = channel->VisitResponseHeaders(visitor);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
// Redirected
|
|
nsCOMPtr<nsILoadInfo> loadInfo = channel->LoadInfo();
|
|
|
|
builder->Redirected(!loadInfo->RedirectChain().IsEmpty());
|
|
|
|
// Body stream
|
|
if (mStream) {
|
|
builder->Body(mStream);
|
|
}
|
|
|
|
mResult->Complete(builder->Build());
|
|
return NS_OK;
|
|
}
|
|
|
|
virtual ~LoaderListener() {}
|
|
|
|
const java::GeckoResult::GlobalRef mResult;
|
|
java::GeckoInputStream::GlobalRef mStream;
|
|
java::GeckoInputStream::Support::GlobalRef mSupport;
|
|
const bool mTestStreamFailure;
|
|
|
|
bool mAllowRedirects;
|
|
};
|
|
|
|
NS_IMPL_ISUPPORTS(LoaderListener, nsIStreamListener, nsIInterfaceRequestor,
|
|
nsIChannelEventSink)
|
|
|
|
class DNSListener final : public nsIDNSListener {
|
|
public:
|
|
NS_DECL_THREADSAFE_ISUPPORTS
|
|
|
|
DNSListener(const nsCString& aHost, java::GeckoResult::Param aResult)
|
|
: mHost(aHost), mResult(aResult) {}
|
|
|
|
NS_IMETHOD
|
|
OnLookupComplete(nsICancelable* aRequest, nsIDNSRecord* aRecord,
|
|
nsresult aStatus) override {
|
|
if (NS_FAILED(aStatus)) {
|
|
CompleteUnknownHostError();
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult rv = CompleteWithRecord(aRecord);
|
|
if (NS_FAILED(rv)) {
|
|
CompleteUnknownHostError();
|
|
return NS_OK;
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
void CompleteUnknownHostError() {
|
|
java::sdk::UnknownHostException::LocalRef error =
|
|
java::sdk::UnknownHostException::New();
|
|
mResult->CompleteExceptionally(error.Cast<jni::Throwable>());
|
|
}
|
|
|
|
NS_IMETHOD
|
|
OnLookupByTypeComplete(nsICancelable* aRequest, nsIDNSByTypeRecord* aRecord,
|
|
nsresult aStatus) override {
|
|
MOZ_ASSERT_UNREACHABLE("unxpected nsIDNSListener callback");
|
|
return NS_ERROR_UNEXPECTED;
|
|
}
|
|
|
|
private:
|
|
nsresult CompleteWithRecord(nsIDNSRecord* aRecord) {
|
|
nsTArray<NetAddr> addrs;
|
|
nsresult rv = aRecord->GetAddresses(addrs);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
jni::ByteArray::LocalRef bytes;
|
|
auto objects =
|
|
jni::ObjectArray::New<java::sdk::InetAddress>(addrs.Length());
|
|
for (size_t i = 0; i < addrs.Length(); i++) {
|
|
const auto& addr = addrs[i];
|
|
if (addr.raw.family == AF_INET) {
|
|
bytes = jni::ByteArray::New(
|
|
reinterpret_cast<const int8_t*>(&addr.inet.ip), 4);
|
|
} else if (addr.raw.family == AF_INET6) {
|
|
bytes = jni::ByteArray::New(
|
|
reinterpret_cast<const int8_t*>(&addr.inet6.ip), 16);
|
|
} else {
|
|
// We don't handle this, skip it.
|
|
continue;
|
|
}
|
|
|
|
objects->SetElement(i,
|
|
java::sdk::InetAddress::GetByAddress(mHost, bytes));
|
|
}
|
|
|
|
mResult->Complete(objects);
|
|
return NS_OK;
|
|
}
|
|
|
|
virtual ~DNSListener() {}
|
|
|
|
const nsCString mHost;
|
|
const java::GeckoResult::GlobalRef mResult;
|
|
};
|
|
|
|
NS_IMPL_ISUPPORTS(DNSListener, nsIDNSListener)
|
|
|
|
static nsresult ConvertCacheMode(int32_t mode, int32_t& result) {
|
|
switch (mode) {
|
|
case java::WebRequest::CACHE_MODE_DEFAULT:
|
|
result = nsIHttpChannelInternal::FETCH_CACHE_MODE_DEFAULT;
|
|
break;
|
|
case java::WebRequest::CACHE_MODE_NO_STORE:
|
|
result = nsIHttpChannelInternal::FETCH_CACHE_MODE_NO_STORE;
|
|
break;
|
|
case java::WebRequest::CACHE_MODE_RELOAD:
|
|
result = nsIHttpChannelInternal::FETCH_CACHE_MODE_RELOAD;
|
|
break;
|
|
case java::WebRequest::CACHE_MODE_NO_CACHE:
|
|
result = nsIHttpChannelInternal::FETCH_CACHE_MODE_NO_CACHE;
|
|
break;
|
|
case java::WebRequest::CACHE_MODE_FORCE_CACHE:
|
|
result = nsIHttpChannelInternal::FETCH_CACHE_MODE_FORCE_CACHE;
|
|
break;
|
|
case java::WebRequest::CACHE_MODE_ONLY_IF_CACHED:
|
|
result = nsIHttpChannelInternal::FETCH_CACHE_MODE_ONLY_IF_CACHED;
|
|
break;
|
|
default:
|
|
return NS_ERROR_UNEXPECTED;
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult WebExecutorSupport::CreateStreamLoader(
|
|
java::WebRequest::Param aRequest, int32_t aFlags,
|
|
java::GeckoResult::Param aResult) {
|
|
const auto req = java::WebRequest::LocalRef(aRequest);
|
|
const auto reqBase = java::WebMessage::LocalRef(req.Cast<java::WebMessage>());
|
|
|
|
nsCOMPtr<nsIURI> uri;
|
|
nsresult rv = NS_NewURI(getter_AddRefs(uri), reqBase->Uri()->ToString());
|
|
NS_ENSURE_SUCCESS(rv, NS_ERROR_MALFORMED_URI);
|
|
|
|
nsCOMPtr<nsIChannel> channel;
|
|
rv = NS_NewChannel(getter_AddRefs(channel), uri,
|
|
nsContentUtils::GetSystemPrincipal(),
|
|
nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
|
|
nsIContentPolicy::TYPE_OTHER);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
if (aFlags & java::GeckoWebExecutor::FETCH_FLAGS_ANONYMOUS) {
|
|
channel->SetLoadFlags(nsIRequest::LOAD_ANONYMOUS);
|
|
}
|
|
|
|
nsCOMPtr<nsICookieSettings> cookieSettings = CookieSettings::Create();
|
|
MOZ_ASSERT(cookieSettings);
|
|
|
|
nsCOMPtr<nsILoadInfo> loadInfo = channel->LoadInfo();
|
|
loadInfo->SetCookieSettings(cookieSettings);
|
|
|
|
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel, &rv));
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
// Method
|
|
rv = httpChannel->SetRequestMethod(aRequest->Method()->ToCString());
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
// Headers
|
|
const auto keys = reqBase->GetHeaderKeys();
|
|
const auto values = reqBase->GetHeaderValues();
|
|
auto contentType = EmptyCString();
|
|
for (size_t i = 0; i < keys->Length(); i++) {
|
|
const auto key = jni::String::LocalRef(keys->GetElement(i))->ToCString();
|
|
const auto value =
|
|
jni::String::LocalRef(values->GetElement(i))->ToCString();
|
|
|
|
if (key.LowerCaseEqualsASCII("content-type")) {
|
|
contentType = value;
|
|
}
|
|
|
|
// We clobber any duplicate keys here because we've already merged them
|
|
// in the upstream WebRequest.
|
|
rv = httpChannel->SetRequestHeader(key, value, false /* merge */);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
}
|
|
|
|
// Body
|
|
const auto body = req->Body();
|
|
if (body) {
|
|
nsCOMPtr<nsIInputStream> stream = new ByteBufferStream(body);
|
|
|
|
nsCOMPtr<nsIUploadChannel2> uploadChannel(do_QueryInterface(channel, &rv));
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
rv = uploadChannel->ExplicitSetUploadStream(
|
|
stream, contentType, -1, aRequest->Method()->ToCString(), false);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
}
|
|
|
|
// Referrer
|
|
RefPtr<nsIURI> referrerUri;
|
|
const auto referrer = req->Referrer();
|
|
if (referrer) {
|
|
rv = NS_NewURI(getter_AddRefs(referrerUri), referrer->ToString());
|
|
NS_ENSURE_SUCCESS(rv, NS_ERROR_MALFORMED_URI);
|
|
}
|
|
|
|
nsCOMPtr<nsIReferrerInfo> referrerInfo = new dom::ReferrerInfo(referrerUri);
|
|
rv = httpChannel->SetReferrerInfoWithoutClone(referrerInfo);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
// Cache mode
|
|
nsCOMPtr<nsIHttpChannelInternal> internalChannel(
|
|
do_QueryInterface(channel, &rv));
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
int32_t cacheMode;
|
|
rv = ConvertCacheMode(req->CacheMode(), cacheMode);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
rv = internalChannel->SetFetchCacheMode(cacheMode);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
// We don't have any UI
|
|
rv = internalChannel->SetBlockAuthPrompt(true);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
const bool allowRedirects =
|
|
!(aFlags & java::GeckoWebExecutor::FETCH_FLAGS_NO_REDIRECTS);
|
|
|
|
const bool testStreamFailure =
|
|
(aFlags & java::GeckoWebExecutor::FETCH_FLAGS_STREAM_FAILURE_TEST);
|
|
|
|
// All done, set up the listener
|
|
RefPtr<LoaderListener> listener =
|
|
new LoaderListener(aResult, allowRedirects, testStreamFailure);
|
|
|
|
rv = channel->SetNotificationCallbacks(listener);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
// Finally, open the channel
|
|
rv = httpChannel->AsyncOpen(listener);
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
void WebExecutorSupport::Fetch(jni::Object::Param aRequest, int32_t aFlags,
|
|
jni::Object::Param aResult) {
|
|
const auto request = java::WebRequest::LocalRef(aRequest);
|
|
auto result = java::GeckoResult::LocalRef(aResult);
|
|
|
|
nsresult rv = CreateStreamLoader(request, aFlags, result);
|
|
if (NS_FAILED(rv)) {
|
|
CompleteWithError(result, rv);
|
|
}
|
|
}
|
|
|
|
static nsresult ResolveHost(nsCString& host, java::GeckoResult::Param result) {
|
|
nsresult rv;
|
|
nsCOMPtr<nsIDNSService> dns = do_GetService(NS_DNSSERVICE_CONTRACTID, &rv);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
nsCOMPtr<nsICancelable> cancelable;
|
|
RefPtr<DNSListener> listener = new DNSListener(host, result);
|
|
rv = dns->AsyncResolveNative(host, 0, listener, nullptr /* aListenerTarget */,
|
|
OriginAttributes(), getter_AddRefs(cancelable));
|
|
return rv;
|
|
}
|
|
|
|
void WebExecutorSupport::Resolve(jni::String::Param aUri,
|
|
jni::Object::Param aResult) {
|
|
auto result = java::GeckoResult::LocalRef(aResult);
|
|
|
|
nsCString uri = aUri->ToCString();
|
|
nsresult rv = ResolveHost(uri, result);
|
|
if (NS_FAILED(rv)) {
|
|
java::sdk::UnknownHostException::LocalRef error =
|
|
java::sdk::UnknownHostException::New();
|
|
result->CompleteExceptionally(error.Cast<jni::Throwable>());
|
|
}
|
|
}
|
|
|
|
} // namespace widget
|
|
} // namespace mozilla
|