зеркало из https://github.com/mozilla/pjs.git
fixes bug 287648 "Unify 'request' object interface for DNS and PPS asyncResolve methods" r=biesi sr=bzbarsky
This commit is contained in:
Родитель
ec53342255
Коммит
4dd371f200
|
@ -65,6 +65,7 @@ XPIDLSRCS = \
|
|||
nsIAsyncStreamCopier.idl \
|
||||
nsISafeOutputStream.idl \
|
||||
nsIBufferedStreams.idl \
|
||||
nsICancelable.idl \
|
||||
nsIDownloader.idl \
|
||||
nsIEncodedChannel.idl \
|
||||
nsIFileStreams.idl \
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Google Inc.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2005
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Darin Fisher <darin@meer.net>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
/**
|
||||
* This interface provides a means to cancel an operation that is in progress.
|
||||
*
|
||||
* @status UNDER_REVIEW
|
||||
*/
|
||||
[scriptable, uuid(d94ac0a0-bb18-46b8-844e-84159064b0bd)]
|
||||
interface nsICancelable : nsISupports
|
||||
{
|
||||
/**
|
||||
* Call this method to request that this object abort whatever operation it
|
||||
* may be performing.
|
||||
*
|
||||
* @param aReason
|
||||
* Pass a failure code to indicate the reason why this operation is
|
||||
* being canceled. It is an error to pass a success code.
|
||||
*/
|
||||
void cancel(in nsresult aReason);
|
||||
};
|
|
@ -40,19 +40,22 @@
|
|||
|
||||
interface nsIURI;
|
||||
interface nsIProxyInfo;
|
||||
interface nsICancelable;
|
||||
|
||||
/**
|
||||
* This interface servers as a closure for nsIProtocolProxyService's
|
||||
* asyncResolve method.
|
||||
*
|
||||
* @status UNDER_REVIEW
|
||||
*/
|
||||
[scriptable, uuid(71eba501-2982-4abf-95ab-cf87afc853ad)]
|
||||
[scriptable, uuid(a9967200-f95e-45c2-beb3-9b060d874bfd)]
|
||||
interface nsIProtocolProxyCallback : nsISupports
|
||||
{
|
||||
/**
|
||||
* This method is called when proxy info is available or when an error
|
||||
* in the proxy resolution occurs.
|
||||
*
|
||||
* @param aContext
|
||||
* @param aRequest
|
||||
* The value returned from asyncResolve.
|
||||
* @param aURI
|
||||
* The URI passed to asyncResolve.
|
||||
|
@ -66,7 +69,7 @@ interface nsIProtocolProxyCallback : nsISupports
|
|||
* could not be satisfied, in which case the value of aStatus
|
||||
* indicates the reason for the failure.
|
||||
*/
|
||||
void onProxyAvailable(in nsISupports aContext,
|
||||
void onProxyAvailable(in nsICancelable aRequest,
|
||||
in nsIURI aURI,
|
||||
in nsIProxyInfo aProxyInfo,
|
||||
in nsresult aStatus);
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsICancelable;
|
||||
interface nsIProtocolProxyCallback;
|
||||
interface nsIProtocolProxyFilter;
|
||||
interface nsIProxyInfo;
|
||||
|
@ -51,7 +52,7 @@ interface nsIURI;
|
|||
*
|
||||
* @status UNDER_REVIEW
|
||||
*/
|
||||
[scriptable, uuid(faea2185-8e5b-44a8-ae8f-5fd3f20972af)]
|
||||
[scriptable, uuid(e38ab577-786e-4a7f-936b-7ae4c7d877b2)]
|
||||
interface nsIProtocolProxyService : nsISupports
|
||||
{
|
||||
/**
|
||||
|
@ -111,22 +112,10 @@ interface nsIProtocolProxyService : nsISupports
|
|||
* @param aCallback
|
||||
* The object to be notified when the result is available.
|
||||
*
|
||||
* @return a context for the operation that can be used to cancel the
|
||||
* asychronous operation. See for example cancelAsyncResolve.
|
||||
* @return An object that can be used to cancel the asychronous operation.
|
||||
*/
|
||||
nsISupports asyncResolve(in nsIURI aURI,
|
||||
in unsigned long aFlags,
|
||||
in nsIProtocolProxyCallback aCallback);
|
||||
|
||||
/**
|
||||
* This method may be used to cancel a pending asyncResolve callback. When
|
||||
* this is called, the callback object passed to asyncResolve will be
|
||||
* notified with an error condition of NS_ERROR_ABORT.
|
||||
*
|
||||
* @param aContext
|
||||
* The return value from asyncResolve.
|
||||
*/
|
||||
void cancelAsyncResolve(in nsISupports aContext);
|
||||
nsICancelable asyncResolve(in nsIURI aURI, in unsigned long aFlags,
|
||||
in nsIProtocolProxyCallback aCallback);
|
||||
|
||||
/**
|
||||
* This method may be called to construct a nsIProxyInfo instance from
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#include "nsIObserverService.h"
|
||||
#include "nsIProtocolHandler.h"
|
||||
#include "nsIProtocolProxyCallback.h"
|
||||
#include "nsICancelable.h"
|
||||
#include "nsIDNSService.h"
|
||||
#include "nsIPrefService.h"
|
||||
#include "nsIPrefBranch2.h"
|
||||
|
@ -78,21 +79,14 @@ struct nsProtocolInfo {
|
|||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#define NS_ASYNCRESOLVECONTEXT_IID \
|
||||
{ /* c5fb0580-0cea-4d6a-8f76-ae61dc644d3a */ \
|
||||
0xc5fb0580, \
|
||||
0x0cea, \
|
||||
0x4d6a, \
|
||||
{0x8f, 0x76, 0xae, 0x61, 0xdc, 0x64, 0x4d, 0x3a} \
|
||||
}
|
||||
|
||||
class nsAsyncResolveContext : public PLEvent, public nsPACManCallback
|
||||
class nsAsyncResolveRequest : public PLEvent
|
||||
, public nsPACManCallback
|
||||
, public nsICancelable
|
||||
{
|
||||
public:
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(NS_ASYNCRESOLVECONTEXT_IID)
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
nsAsyncResolveContext(nsProtocolProxyService *pps, nsIURI *uri,
|
||||
nsAsyncResolveRequest(nsProtocolProxyService *pps, nsIURI *uri,
|
||||
nsIProtocolProxyCallback *callback)
|
||||
: mStatus(NS_OK)
|
||||
, mDispatched(PR_FALSE)
|
||||
|
@ -100,43 +94,52 @@ public:
|
|||
, mURI(uri)
|
||||
, mCallback(callback)
|
||||
{
|
||||
NS_ASSERTION(mCallback, "null callback");
|
||||
PL_InitEvent(this, nsnull, HandleEvent, CleanupEvent);
|
||||
}
|
||||
|
||||
// Called on the main thread
|
||||
void SetResult(nsresult status, nsIProxyInfo *pi)
|
||||
{
|
||||
mStatus = status;
|
||||
mProxyInfo = pi;
|
||||
}
|
||||
|
||||
// Called on the main thread
|
||||
void Cancel()
|
||||
NS_IMETHOD Cancel(nsresult reason)
|
||||
{
|
||||
if (mDispatched)
|
||||
return;
|
||||
SetResult(NS_ERROR_ABORT, nsnull);
|
||||
DispatchCallback();
|
||||
NS_ENSURE_ARG(NS_FAILED(reason));
|
||||
|
||||
// If we've already called DoCallback then, nothing more to do.
|
||||
if (!mCallback)
|
||||
return NS_OK;
|
||||
|
||||
SetResult(reason, nsnull);
|
||||
return DispatchCallback();
|
||||
}
|
||||
|
||||
// Called on any thread
|
||||
nsresult DispatchCallback()
|
||||
{
|
||||
if (mDispatched) // Only need to dispatch once
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIEventQueue> eventQ;
|
||||
nsresult rv = NS_GetCurrentEventQ(getter_AddRefs(eventQ));
|
||||
if (NS_FAILED(rv)) {
|
||||
if (NS_FAILED(rv))
|
||||
NS_WARNING("could not get current event queue");
|
||||
return rv;
|
||||
else {
|
||||
NS_ADDREF_THIS();
|
||||
rv = eventQ->PostEvent(this);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("unable to dispatch callback event");
|
||||
PL_DestroyEvent(this);
|
||||
}
|
||||
else {
|
||||
mDispatched = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
NS_ADDREF_THIS();
|
||||
rv = eventQ->PostEvent(this);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("unable to dispatch callback event");
|
||||
PL_DestroyEvent(this);
|
||||
return rv;
|
||||
}
|
||||
mDispatched = PR_TRUE;
|
||||
return NS_OK;
|
||||
|
||||
mCallback = nsnull; // break possible reference cycle
|
||||
return rv;
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -145,16 +148,22 @@ private:
|
|||
// before calling DoCallback.
|
||||
void OnQueryComplete(nsresult status, const nsCString &pacString)
|
||||
{
|
||||
if (mDispatched)
|
||||
// If we've already called DoCallback then, nothing more to do.
|
||||
if (!mCallback)
|
||||
return;
|
||||
|
||||
mDispatched = PR_TRUE;
|
||||
mStatus = status;
|
||||
mPACString = pacString;
|
||||
// Provided we haven't been canceled...
|
||||
if (mStatus == NS_OK) {
|
||||
mStatus = status;
|
||||
mPACString = pacString;
|
||||
}
|
||||
|
||||
// In the cancelation case, we may still have another PLEvent in
|
||||
// the queue that wants to call DoCallback. No need to wait for
|
||||
// it, just run the callback now.
|
||||
DoCallback();
|
||||
}
|
||||
|
||||
// Called on the main thread
|
||||
void DoCallback()
|
||||
{
|
||||
// Generate proxy info from the PAC string if appropriate
|
||||
|
@ -177,8 +186,8 @@ private:
|
|||
|
||||
PR_STATIC_CALLBACK(void *) HandleEvent(PLEvent *ev)
|
||||
{
|
||||
nsAsyncResolveContext *self =
|
||||
NS_STATIC_CAST(nsAsyncResolveContext *, ev);
|
||||
nsAsyncResolveRequest *self =
|
||||
NS_STATIC_CAST(nsAsyncResolveRequest *, ev);
|
||||
if (self->mCallback)
|
||||
self->DoCallback();
|
||||
return nsnull;
|
||||
|
@ -186,8 +195,8 @@ private:
|
|||
|
||||
PR_STATIC_CALLBACK(void) CleanupEvent(PLEvent *ev)
|
||||
{
|
||||
nsAsyncResolveContext *self =
|
||||
NS_STATIC_CAST(nsAsyncResolveContext *, ev);
|
||||
nsAsyncResolveRequest *self =
|
||||
NS_STATIC_CAST(nsAsyncResolveRequest *, ev);
|
||||
NS_RELEASE(self); // balance AddRef in DispatchCallback
|
||||
}
|
||||
|
||||
|
@ -203,7 +212,7 @@ private:
|
|||
nsCOMPtr<nsIProxyInfo> mProxyInfo;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsAsyncResolveContext, nsAsyncResolveContext)
|
||||
NS_IMPL_ISUPPORTS1(nsAsyncResolveRequest, nsICancelable)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
|
@ -806,10 +815,10 @@ nsProtocolProxyService::Resolve(nsIURI *uri, PRUint32 flags,
|
|||
NS_IMETHODIMP
|
||||
nsProtocolProxyService::AsyncResolve(nsIURI *uri, PRUint32 flags,
|
||||
nsIProtocolProxyCallback *callback,
|
||||
nsISupports **result)
|
||||
nsICancelable **result)
|
||||
{
|
||||
nsCOMPtr<nsAsyncResolveContext> ctx =
|
||||
new nsAsyncResolveContext(this, uri, callback);
|
||||
nsRefPtr<nsAsyncResolveRequest> ctx =
|
||||
new nsAsyncResolveRequest(this, uri, callback);
|
||||
if (!ctx)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
|
@ -828,8 +837,7 @@ nsProtocolProxyService::AsyncResolve(nsIURI *uri, PRUint32 flags,
|
|||
ApplyFilters(uri, info, pi);
|
||||
|
||||
ctx->SetResult(NS_OK, pi);
|
||||
ctx->DispatchCallback();
|
||||
return NS_OK;
|
||||
return ctx->DispatchCallback();
|
||||
}
|
||||
|
||||
// else kick off a PAC query
|
||||
|
@ -841,15 +849,6 @@ nsProtocolProxyService::AsyncResolve(nsIURI *uri, PRUint32 flags,
|
|||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsProtocolProxyService::CancelAsyncResolve(nsISupports *context)
|
||||
{
|
||||
nsCOMPtr<nsAsyncResolveContext> ctx = do_QueryInterface(context);
|
||||
NS_ENSURE_ARG(ctx);
|
||||
ctx->Cancel();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsProtocolProxyService::NewProxyInfo(const nsACString &aType,
|
||||
const nsACString &aHost,
|
||||
|
|
|
@ -76,7 +76,7 @@ public:
|
|||
NS_HIDDEN_(nsresult) Init();
|
||||
|
||||
protected:
|
||||
friend class nsAsyncResolveContext;
|
||||
friend class nsAsyncResolveRequest;
|
||||
|
||||
~nsProtocolProxyService() NS_HIDDEN;
|
||||
|
||||
|
|
|
@ -272,10 +272,10 @@ TestResolveCallback.prototype = {
|
|||
},
|
||||
|
||||
onProxyAvailable:
|
||||
function TestResolveCallback_onProxyAvailable(ctx, uri, pi, status) {
|
||||
function TestResolveCallback_onProxyAvailable(req, uri, pi, status) {
|
||||
dump("*** uri=" + uri.spec + ", status=" + status + "\n");
|
||||
|
||||
do_check_neq(ctx, null);
|
||||
do_check_neq(req, null);
|
||||
do_check_neq(uri, null);
|
||||
do_check_eq(status, 0);
|
||||
do_check_neq(pi, null);
|
||||
|
@ -296,6 +296,7 @@ TestResolveCallback.prototype = {
|
|||
prefs.setCharPref("network.proxy.autoconfig_url", "");
|
||||
prefs.setIntPref("network.proxy.type", 0);
|
||||
|
||||
run_test_continued();
|
||||
do_test_finished();
|
||||
}
|
||||
};
|
||||
|
@ -329,7 +330,55 @@ function run_pac_test() {
|
|||
}
|
||||
do_check_eq(hit_exception, true);
|
||||
|
||||
var ctx = pps.asyncResolve(uri, 0, new TestResolveCallback());
|
||||
var req = pps.asyncResolve(uri, 0, new TestResolveCallback());
|
||||
do_test_pending();
|
||||
}
|
||||
|
||||
function TestResolveCancelationCallback() {
|
||||
}
|
||||
TestResolveCancelationCallback.prototype = {
|
||||
QueryInterface:
|
||||
function TestResolveCallback_QueryInterface(iid) {
|
||||
if (iid.equals(Components.interfaces.nsIProtocolProxyCallback) ||
|
||||
iid.equals(Components.interfaces.nsISupports))
|
||||
return this;
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
},
|
||||
|
||||
onProxyAvailable:
|
||||
function TestResolveCancelationCallback_onProxyAvailable(req, uri, pi, status) {
|
||||
dump("*** uri=" + uri.spec + ", status=" + status + "\n");
|
||||
|
||||
do_check_neq(req, null);
|
||||
do_check_neq(uri, null);
|
||||
do_check_eq(status, Components.results.NS_ERROR_ABORT);
|
||||
do_check_eq(pi, null);
|
||||
|
||||
var prefs = Components.classes["@mozilla.org/preferences-service;1"]
|
||||
.getService(Components.interfaces.nsIPrefBranch);
|
||||
prefs.setCharPref("network.proxy.autoconfig_url", "");
|
||||
prefs.setIntPref("network.proxy.type", 0);
|
||||
|
||||
run_test_continued_2();
|
||||
do_test_finished();
|
||||
}
|
||||
};
|
||||
|
||||
function run_pac_cancel_test() {
|
||||
var uri = ios.newURI("http://www.mozilla.org/", null, null);
|
||||
|
||||
// Configure PAC
|
||||
var pac = 'data:text/plain,' +
|
||||
'function FindProxyForURL(url, host) {' +
|
||||
' return "PROXY foopy:8080; DIRECT";' +
|
||||
'}';
|
||||
var prefs = Components.classes["@mozilla.org/preferences-service;1"]
|
||||
.getService(Components.interfaces.nsIPrefBranch);
|
||||
prefs.setIntPref("network.proxy.type", 2);
|
||||
prefs.setCharPref("network.proxy.autoconfig_url", pac);
|
||||
|
||||
var req = pps.asyncResolve(uri, 0, new TestResolveCancelationCallback());
|
||||
req.cancel(Components.results.NS_ERROR_ABORT);
|
||||
do_test_pending();
|
||||
}
|
||||
|
||||
|
@ -339,4 +388,13 @@ function run_test() {
|
|||
run_filter_test2();
|
||||
run_pref_test();
|
||||
run_pac_test();
|
||||
// additional tests may be added to run_test_continued
|
||||
}
|
||||
|
||||
function run_test_continued() {
|
||||
run_pac_cancel_test();
|
||||
// additional tests may be added to run_test_continued_2
|
||||
}
|
||||
|
||||
function run_test_continued_2() {
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче