Compare commits

..

3 Commits

Author SHA1 Message Date
dougt%netscape.com
5e8f4ed5d2 1. Removing printf's
2. Reducing buffer size to 4k
3. Implementing ReadSegments in the nsFileStreams.


git-svn-id: svn://10.0.0.236/branches/FILE_TRANSPORT_2_03282001_BRANCH@90768 18797224-902f-48f8-a5cc-f745e15eee43
2001-03-29 08:54:15 +00:00
dougt%netscape.com
7b7e8cd5b1 Landing First Cut of Darin's New File Transport. Needs penty of love and care.
git-svn-id: svn://10.0.0.236/branches/FILE_TRANSPORT_2_03282001_BRANCH@90720 18797224-902f-48f8-a5cc-f745e15eee43
2001-03-29 01:21:13 +00:00
(no author)
08102d1fde This commit was manufactured by cvs2svn to create branch
'FILE_TRANSPORT_2_03282001_BRANCH'.

git-svn-id: svn://10.0.0.236/branches/FILE_TRANSPORT_2_03282001_BRANCH@90678 18797224-902f-48f8-a5cc-f745e15eee43
2001-03-28 20:57:01 +00:00
388 changed files with 23229 additions and 104276 deletions

View File

@@ -0,0 +1,32 @@
#
# The contents of this file are subject to the Netscape 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/NPL/
#
# 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 Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
#
DEPTH = ../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
DIRS = public src
include $(topsrcdir)/config/rules.mk

View File

@@ -0,0 +1,31 @@
#!gmake
#
# The contents of this file are subject to the Netscape 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/NPL/
#
# 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 Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
DEPTH = ..\..
MODULE = necko
DIRS= \
public \
src \
$(NULL)
include <$(DEPTH)\config\rules.mak>

View File

@@ -0,0 +1,8 @@
#
# This is a list of local files which get copied to the mozilla:dist directory
#
netCore.h
nsNetUtil.h
nsUnixColorPrintf.h
nsIPasswordManagerUtils.h

View File

@@ -0,0 +1,33 @@
#
# This is a list of local files which get copied to the mozilla:dist directory
#
nsIAuthenticator.idl
nsIChannel.idl
nsIFileChannel.idl
nsIDownloader.idl
nsIFileTransportService.idl
nsIPasswordManager.idl
nsIPrompt.idl
nsIProtocolProxyService.idl
nsIProxyAutoConfig.idl
nsIProxyAutoConfigUtils.idl
nsIProxy.idl
nsIRequest.idl
nsISocketTransportService.idl
nsIStreamIO.idl
nsIStreamIOChannel.idl
nsIStreamListener.idl
nsITransport.idl
nsIStreamLoader.idl
nsIDownloader.idl
nsIStreamObserver.idl
nsIStreamProvider.idl
nsIURI.idl
nsIURL.idl
nsIURLParser.idl
nsIWebFilters.idl
nsISecurityEventSink.idl
nsISecretDecoderRing.idl
nsISecureBrowserUI.idl
nsISecurityManagerComponent.idl

View File

@@ -0,0 +1 @@
security-prefs.js

View File

@@ -0,0 +1,82 @@
#
# The contents of this file are subject to the Netscape 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/NPL/
#
# 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 Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
#
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = necko
XPIDLSRCS = \
nsIAuthenticator.idl \
nsIChannel.idl \
nsIFileChannel.idl \
nsIDownloader.idl \
nsIFileStreams.idl \
nsIFileTransportService.idl \
nsIIOService.idl \
nsILoadGroup.idl \
nsINetModRegEntry.idl \
nsINetModuleMgr.idl \
nsINetNotify.idl \
nsIPasswordManager.idl \
nsIProgressEventSink.idl \
nsIPrompt.idl \
nsIProtocolHandler.idl \
nsIProtocolProxyService.idl \
nsIProxy.idl \
nsIProxyAutoConfig.idl \
nsIProxyAutoConfigUtils.idl \
nsIRequest.idl \
nsITransport.idl \
nsISocketTransport.idl \
nsISocketTransportService.idl \
nsIStreamIO.idl \
nsIStreamIOChannel.idl \
nsIStreamObserver.idl \
nsIStreamListener.idl \
nsIStreamProvider.idl \
nsIStreamLoader.idl \
nsIURI.idl \
nsIURL.idl \
nsIURLParser.idl \
nsIWebFilters.idl \
nsISecurityEventSink.idl \
nsISecretDecoderRing.idl \
nsISecureBrowserUI.idl \
nsISecurityManagerComponent.idl \
nsICachingChannel.idl \
$(NULL)
EXPORTS = \
netCore.h \
nsNetUtil.h \
nsUnixColorPrintf.h \
nsIPasswordManagerUtils.h \
$(NULL)
PREF_JS_EXPORTS = $(srcdir)/security-prefs.js
include $(topsrcdir)/config/rules.mk

View File

@@ -0,0 +1,84 @@
#!gmake
#
# The contents of this file are subject to the Netscape 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/NPL/
#
# 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 Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
MODULE = necko
DEPTH = ..\..\..
include <$(DEPTH)/config/config.mak>
EXPORTS = \
netCore.h \
nsNetUtil.h \
nsUnixColorPrintf.h \
nsIPasswordManagerUtils.h \
$(NULL)
XPIDLSRCS = \
.\nsIAuthenticator.idl \
.\nsIChannel.idl \
.\nsIFileChannel.idl \
.\nsIFileStreams.idl \
.\nsIFileTransportService.idl \
.\nsIIOService.idl \
.\nsILoadGroup.idl \
.\nsINetModRegEntry.idl \
.\nsINetModuleMgr.idl \
.\nsINetNotify.idl \
.\nsIPasswordManager.idl \
.\nsIProgressEventSink.idl \
.\nsIPrompt.idl \
.\nsIProtocolHandler.idl \
.\nsIProtocolProxyService.idl \
.\nsIProxyAutoConfig.idl \
.\nsIProxyAutoConfigUtils.idl \
.\nsIProxy.idl \
.\nsIRequest.idl \
.\nsITransport.idl \
.\nsISocketTransport.idl \
.\nsISocketTransportService.idl \
.\nsIStreamIO.idl \
.\nsIStreamIOChannel.idl \
.\nsIStreamObserver.idl \
.\nsIStreamListener.idl \
.\nsIStreamProvider.idl \
.\nsIStreamLoader.idl \
.\nsIStreamProvider.idl \
.\nsITransport.idl \
.\nsIDownloader.idl \
.\nsIURI.idl \
.\nsIURL.idl \
.\nsIURLParser.idl \
.\nsIWebFilters.idl \
.\nsISecurityEventSink.idl \
.\nsISecretDecoderRing.idl \
.\nsISecureBrowserUI.idl \
.\nsISecurityManagerComponent.idl \
.\nsICachingChannel.idl \
$(NULL)
include <$(DEPTH)/config/rules.mak>
$(DEPTH)\netwerk\dist\include:
-mkdir $(DEPTH)\netwerk\dist
-mkdir $(DEPTH)\netwerk\dist\include
install::
$(MAKE_INSTALL) .\security-prefs.js $(DIST)\bin\defaults\pref

View File

@@ -0,0 +1,71 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef __netCore_h__
#define __netCore_h__
#include "nsError.h"
/* networking error codes */
// NET RANGE: 1 -20
// FTP RANGE: 21-30
// HTTP RANGE: 31-40
// DNS RANGE: 41-50
// SOCKET RANGE 51-60
// CACHE RANGE: 61-70
// XXX Why can't we put all Netwerk error codes in one file to help avoid collisions?
#define NS_ERROR_ALREADY_CONNECTED \
NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 11)
#define NS_ERROR_NOT_CONNECTED \
NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 12)
/* NS_ERROR_CONNECTION_REFUSED and NS_ERROR_NET_TIMEOUT moved to nsISocketTransportService.idl */
#define NS_ERROR_IN_PROGRESS \
NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 15)
#define NS_ERROR_OFFLINE \
NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 16)
#undef NS_NET
#ifdef _IMPL_NS_NET
#if defined(XP_PC) && !defined(XP_OS2)
#define NS_NET _declspec(dllexport)
#else /* !XP_PC */
#define NS_NET
#endif /* !XP_PC */
#else /* !_IMPL_NS_NET */
#if defined(XP_PC) && !defined(XP_OS2)
#define NS_NET _declspec(dllimport)
#else /* !XP_PC */
#define NS_NET
#endif /* !XP_PC */
#endif /* !_IMPL_NS_NET */
// Where most necko status messages come from:
#define NECKO_MSGS_URL "chrome://necko/locale/necko.properties"
#endif // __netCore_h__

View File

@@ -0,0 +1,78 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* 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 code.
*
* The Initial Developer of the Original Code is Zero-Knowledge Systems,
* Inc. Portions created by Zero-Knowledge are Copyright (C) 2000
* Zero-Knowledge Systems, Inc. All Rights Reserved.
*
* Contributor(s):
*/
#include "nsISupports.idl"
#include "nsIPrompt.idl"
#include "nsIURL.idl"
[scriptable,uuid(adf74d2a-1dd1-11b2-b129-f3154be37959)]
interface nsIAuthenticator : nsISupports
{
/**
* @param uri The URI for which authentication is required.
* @param uri The protocol, for selecting authentication-style. Variant
* protocols, such as http/https and imap/imaps will likely all
* use the primary protocol name ("http", "imap"), to reduce
*
* @param challenge The complete value of the WWW-Authenticate header from
* the response.
* @param username The username provided in the prehost portion of the URI,
* if any.
* @param password The password provided in the prehost portion of the URI,
* if any.
* @param prompter The standard prompter for interacting with the user.
* @param
* @return The complete authentication value to return. For Basic HTTP
* auth, as an example, the returned string would be
* "Basic BASE64(<user>:<pass>)". The format is dependent on the
* provided protocol parameter.
*/
string authenticate(in nsIURI uri, in string protocol, in string challenge,
in wstring username, in wstring password,
in nsIPrompt prompter);
/**
* No interaction with the user required. This indicates that the
* authenticate method can be called with a null prompter argument, though
* calling code should strive to provide it if at all possible. (While
* interaction with the user may not be _required_, it might still be
* desire
*/
const PRUint32 INTERACTION_NONE = 0;
/**
* Standard username and optional password required, and the caller should
* prompt for it.
*/
const PRUint32 INTERACTION_STANDARD = 1;
/**
* Custom interaction required: Mozilla must provide a non-null prompter
* argument when calling authenticate.
*/
const PRUint32 INTERACTION_CUSTOM = 2;
/**
* What kind of interaction with the user does this authentication method
* require?
*/
readonly attribute PRUint32 interactionType;
};

View File

@@ -0,0 +1,76 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Darin Fisher <darin@netscape.com> (original author)
*/
#include "nsISupports.idl"
interface nsIFile;
/**
* A channel may optionally implement this interface to allow clients
* to effect its behavior with respect to how it uses the cache service.
*
* This interface provides:
* 1) Support for "stream as file" semantics (for JAR and plugins).
* 2) Support for "pinning" cached data in the cache (for printing and save-as).
*/
[scriptable, uuid(b1f95f5e-ee05-4434-9d34-89a935d7feef)]
interface nsICachingChannel : nsISupports
{
/**
* Set/get the cache token... uniquely identifies the data in the cache.
* Holding a reference to this token prevents the cached data from being
* removed. A cache token retrieved from a particular instance of
* nsICachingChannel could be set on another instance of nsICachingChannel
* provided the underlying implementations are compatible. The implemen-
* tation of nsICachingChannel would be expected to only read from the
* cache entry identified by the cache token and not try to validate it.
*
* The cache token can be treated as an opaque object; however, it can be
* QI'd to a nsICacheEntryDescriptor if more detailed information about the
* cache entry is needed.
*/
attribute nsISupports cacheToken;
/**
* Set/get the cache key... uniquely identifies the data in the cache.
* Holding a reference to this key DOES NOT prevent the cached data from
* being removed. It is otherwise similar to the cacheToken.
*/
attribute nsISupports cacheKey;
/**
* Specifies whether or not the data should be cached to a file. This
* may fail if the disk cache is not present. The value of this attribute
* is usually only settable during the processing of a channel's
* OnStartRequest. The default value of this attribute depends on the
* particular implementation of nsICachingChannel.
*/
attribute boolean cacheAsFile;
/**
* Get the "file" where the cached data can be found. This is valid for
* as long as a reference to the cache token is held. This may return
* an error if cacheAsFile is false.
*/
readonly attribute nsIFile cacheFile;
};

View File

@@ -0,0 +1,237 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsIRequest.idl"
interface nsIURI;
interface nsIInputStream;
interface nsIOutputStream;
interface nsIStreamObserver;
interface nsIStreamListener;
interface nsIStreamProvider;
interface nsILoadGroup;
interface nsIInterfaceRequestor;
interface nsIStreamIO;
typedef unsigned long nsLoadFlags;
/**
* The nsIChannel interface allows the user to construct get requests for
* specific protocols, and manage them in a uniform way. Once a channel
* is created (via nsIIOService::NewChannel), parameters for that request
* may be set by using the channel attributes, or by QueryInterfacing to a
* subclass of nsIChannel for protocol-specific parameters. Then the actual
* request can be issued in one of several ways:
*
* - AsyncOpen is used for asynchronous reading, calling back the
* user's stream listener.
* - Open is used for synchronous read on the underlying channel.
*
* After a request has been completed, the channel is still valid for
* accessing protocol-specific results. For example, QueryInterfacing to
* nsIHTTPChannel allows response headers to be retrieved that result from
* http transactions.
*
*/
[scriptable, uuid(1788e79e-f947-11d3-8cda-0060b0fc14a3)]
interface nsIChannel : nsIRequest
{
////////////////////////////////////////////////////////////////////////////
// nsIChannel accessors
////////////////////////////////////////////////////////////////////////////
/**
* Returns the original URL used to construct the channel.
* This is used in the case of a redirect or URI "resolution" (e.g.
* resolving a resource: URI to a file: URI) so that the original
* pre-redirect URI can still be obtained.
*
* Note that this is distinctly different from the http referrer
* (referring URI) which is typically the page that contained the
* original URI (accessible from nsIHTTPChannel).
*/
attribute nsIURI originalURI;
/**
* Returns the URL to which the channel currently refers. If a redirect
* or URI resolution occurs, this accessor returns the current location
* to which the channel is referring.
*/
attribute nsIURI URI;
/**
* Accesses the owner corresponding to the entity that is
* responsible for this channel. Used by security code to grant
* or deny privileges to mobile code loaded from this channel.
*
* Note: This is a strong reference to the owner, so if the owner is also
* holding a pointer to the channel, care must be taken to explicitly drop
* its reference to the channel -- otherwise a leak will result.
*/
attribute nsISupports owner;
/**
* Accesses the load group in which the channel is a currently a member.
*/
attribute nsILoadGroup loadGroup;
/**
* Accesses the load attributes for the channel. E.g. setting the load
* attributes with the LOAD_QUIET bit set causes the loading process to
* not deliver status notifications to the program performing the load,
* and to not contribute to keeping any nsILoadGroup it may be contained
* in from firing its OnLoadComplete notification.
*/
attribute nsLoadFlags loadAttributes;
/**
* Accesses the capabilities callbacks of the channel. This is set by clients
* who wish to provide a means to receive progress, status and protocol-specific
* notifications.
*/
attribute nsIInterfaceRequestor notificationCallbacks;
/**
* Any security information about this channel. This can be null.
*/
readonly attribute nsISupports securityInfo;
/**
* Returns the content MIME type of the channel if available. Note that the
* content type can often be wrongly specified (wrong file extension, wrong
* MIME type, wrong document type stored on a server, etc.) and the caller
* most likely wants to verify with the actual data.
*/
attribute string contentType;
/**
* Returns the length of the data associated with the channel if available.
* If the length is unknown then -1 is returned.
*/
attribute long contentLength;
/**
* Open is used for synchronous read on the channel.
**/
nsIInputStream open();
/** AsyncOpen is used for asynchronous reading, calling back the
* user's stream listener.
**/
void asyncOpen(in nsIStreamListener listener, in nsISupports ctxt);
////////////////////////////////////////////////////////////////////////////
// Below are Load attribute flags which may be or'd together.
////////////////////////////////////////////////////////////////////////////
/**
* Note that more will follow for each protocol's implementation of a channel,
* although channel writers have to be careful to not let the flag bits
* overlap. Otherwise, users won't be able to create a single flag word
* of load attributes that applies to a number of different channel types.
*/
/**
* No special load attributes -- use defaults:
*/
const unsigned long LOAD_NORMAL = 0;
/**
* Don't deliver status notifications to the nsIProgressEventSink, or keep
* this load from completing the nsILoadGroup it may belong to:
*/
const unsigned long LOAD_BACKGROUND = 1 << 0;
/**
* Used exclusively by the uriloader and docshell to indicate whether or
* not this channel corresponds to the toplevel document.
*/
const unsigned long LOAD_DOCUMENT_URI = 1 << 1;
/**
* If the end consumer for this load has been retargeted after discovering
* it's content, this flag will be set:
*/
const unsigned long LOAD_RETARGETED_DOCUMENT_URI = 1 << 2;
////////////////////////////////////////////////////////////////////////////
/**
* The following flags control caching behavior. Not all protocols pay
* attention to all these flags, but they are applicable to more than one
* protocol, so they are defined here.
*/
/**
* Don't store data in the disk cache. This can be used to preserve
* privacy, e.g. so that no https transactions are recorded, or to avoid
* caching a stream to disk that is already stored in a local file,
* e.g. the mailbox: protocol.
*/
const unsigned long INHIBIT_PERSISTENT_CACHING = 1 << 8;
/**
* Force an end-to-end download of content data from the origin server (and
* any intervening proxies that sit between it and the client), e.g. this
* flag is used for a shift-reload.
*/
const unsigned long FORCE_RELOAD = 1 << 9;
/**
* Force revalidation with server (or proxy) to verify that cached content
* is up-to-date, e.g. by comparing last-modified date on server with that
* of the cached version. For example, this flag is used when the reload
* button is pressed.
*/
const unsigned long FORCE_VALIDATION = 1 << 10;
/**
* If the CACHE_AS_FILE flag is set, any stream content is stored in the
* cache as a single disk file. Content will not be cached in the memory
* cache nor will it be stored in any other type of cache, e.g. a flat-file
* cache database. This is used to implement the jar protocol handler and
* to provide the stream-as-file semantics required by the classic browser
* plugin API.
*/
const unsigned long CACHE_AS_FILE = 1 << 11;
/**
* When cache data is potentially out of date, it can be revalidated with
* the origin server to see if the content needs to be reloaded. The
* following four flags control how often this validation occurs.
* These flags are commonly used for "normal" loading. Note that
* the VALIDATE_HEURISTICALLY and VALIDATE_ONCE_PER_SESSION flags can be
* combined to validate heuristically but no more than once per session.
*/
const unsigned long VALIDATE_NEVER = 1 << 12;
const unsigned long VALIDATE_ALWAYS = 1 << 13;
const unsigned long VALIDATE_ONCE_PER_SESSION = 1 << 14;
const unsigned long VALIDATE_HEURISTICALLY = 1 << 15;
/**
* This flag is used to tell the webshell not to cancel the load in cases
* when the channel is receiving multipart/replace document
*/
const unsigned long LOAD_REPLACE = 1 << 16;
};

View File

@@ -0,0 +1,61 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsISupports.idl"
#include "nsIChannel.idl"
interface nsIURI;
interface nsILoadGroup;
interface nsIStreamLoader;
interface nsIInterfaceRequestor;
interface nsIFile;
interface nsIDownloader;
[scriptable, uuid(6e0fc962-4a6f-4fa6-831f-8c26c554407f)]
interface nsIDownloadObserver : nsISupports
{
void onDownloadComplete(in nsIDownloader downloader,
in nsISupports ctxt,
in nsresult status,
in nsIFile result);
};
[scriptable, uuid(9632cc0d-864d-4f92-b7e5-bd8097c4e9a5)]
interface nsIDownloader : nsISupports
{
void init(in nsIURI uri,
in nsIDownloadObserver completionObserver,
in nsISupports ctxt,
in boolean synchronous,
in nsILoadGroup loadGroup,
in nsIInterfaceRequestor notificationCallbacks,
in nsLoadFlags loadAttributes);
};
%{C++
#define NS_DOWNLOADER_CID \
{ /* 510a86bb-6019-4ed1-bb4f-965cffd23ece*/ \
0x510a86bb, 0x6019, 0x4ed1, { 0xbb, 0x4f, 0x96, 0x5c, 0xff, 0xd2, 0x3e, 0xce } \
}
%}

View File

@@ -0,0 +1,30 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsISupports.idl"
[scriptable, uuid(fb65fd70-1881-11d3-9337-00104ba0fd40)]
interface nsIEventSinkGetter : nsISupports
{
nsISupports getEventSink(in string command, in nsIIDRef eventSinkIID);
};

View File

@@ -0,0 +1,82 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
interface nsIFile;
#include "nsIChannel.idl"
#include "nsIURL.idl"
/**
* nsIFileURL is used for the file: protocol, and gives access to the
* underlying nsIFile object.
*/
[scriptable, uuid(d26b2e2e-1dd1-11b2-88f3-8545a7ba7949)]
interface nsIFileURL : nsIURL
{
attribute nsIFile file;
};
/**
* nsIFileChannel is an interface that allows for the initialization
* of a simple nsIChannel that is constructed from a single nsIFile and
* associated content type.
*/
[scriptable, uuid(68a26506-f947-11d3-8cda-0060b0fc14a3)]
interface nsIFileChannel : nsIChannel
{
/**
* Values for ioFlags parameters to be or'd together.
* (From prio.h)
*/
const long NS_RDONLY = 0x01;
const long NS_WRONLY = 0x02;
const long NS_RDWR = 0x04;
const long NS_CREATE_FILE = 0x08;
const long NS_APPEND = 0x10;
const long NS_TRUNCATE = 0x20;
const long NS_SYNC = 0x40;
const long NS_EXCL = 0x80;
void init(in nsIFile file,
in long ioFlags,
in long perm);
readonly attribute nsIFile file;
attribute long ioFlags;
attribute long permissions;
};
%{C++
#define NS_LOCALFILECHANNEL_CLASSNAME "Local File Channel"
#define NS_LOCALFILECHANNEL_CONTRACTID "@mozilla.org/network/local-file-channel;1"
#define NS_LOCALFILECHANNEL_CID \
{ /* 6d5b2d44-f947-11d3-8cda-0060b0fc14a3 */ \
0x6d5b2d44, \
0xf947, \
0x11d3, \
{0x8c, 0xda, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \
}
%}
////////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,241 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsIInputStream.idl"
#include "nsIOutputStream.idl"
#include "nsILocalFile.idl"
[scriptable, uuid(e3d56a20-c7ec-11d3-8cda-0060b0fc14a3)]
interface nsIFileInputStream : nsIInputStream
{
void init(in nsIFile file, in long ioFlags, in long perm);
};
[scriptable, uuid(e6f68040-c7ec-11d3-8cda-0060b0fc14a3)]
interface nsIFileOutputStream : nsIOutputStream
{
void init(in nsIFile file, in long ioFlags, in long perm);
};
[scriptable, uuid(e9de5df0-c7ec-11d3-8cda-0060b0fc14a3)]
interface nsISeekableStream : nsISupports
{
// correspond to PRSeekWhence values
const long NS_SEEK_SET = 0;
const long NS_SEEK_CUR = 1;
const long NS_SEEK_END = 2;
void seek(in long whence, in long offset);
unsigned long tell();
};
[scriptable, uuid(616f5b48-da09-11d3-8cda-0060b0fc14a3)]
interface nsIBufferedInputStream : nsIInputStream
{
void init(in nsIInputStream fillFromStream,
in unsigned long bufferSize);
};
[scriptable, uuid(6476378a-da09-11d3-8cda-0060b0fc14a3)]
interface nsIBufferedOutputStream : nsIOutputStream
{
void init(in nsIOutputStream sinkToStream,
in unsigned long bufferSize);
};
%{C++
////////////////////////////////////////////////////////////////////////////////
#define NS_LOCALFILEINPUTSTREAM_CLASSNAME "Local File Input Stream"
#define NS_LOCALFILEINPUTSTREAM_CONTRACTID "@mozilla.org/network/file-input-stream;1"
#define NS_LOCALFILEINPUTSTREAM_CID \
{ /* be9a53ae-c7e9-11d3-8cda-0060b0fc14a3 */ \
0xbe9a53ae, \
0xc7e9, \
0x11d3, \
{0x8c, 0xda, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \
}
#define NS_LOCALFILEOUTPUTSTREAM_CLASSNAME "Local File Output Stream"
#define NS_LOCALFILEOUTPUTSTREAM_CONTRACTID "@mozilla.org/network/file-output-stream;1"
#define NS_LOCALFILEOUTPUTSTREAM_CID \
{ /* c272fee0-c7e9-11d3-8cda-0060b0fc14a3 */ \
0xc272fee0, \
0xc7e9, \
0x11d3, \
{0x8c, 0xda, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \
}
////////////////////////////////////////////////////////////////////////////////
#define NS_BUFFEREDINPUTSTREAM_CLASSNAME "Buffered Input Stream"
#define NS_BUFFEREDINPUTSTREAM_CONTRACTID "@mozilla.org/network/buffered-input-stream;1"
#define NS_BUFFEREDINPUTSTREAM_CID \
{ /* 9226888e-da08-11d3-8cda-0060b0fc14a3 */ \
0x9226888e, \
0xda08, \
0x11d3, \
{0x8c, 0xda, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \
}
#define NS_BUFFEREDOUTPUTSTREAM_CLASSNAME "Buffered Output Stream"
#define NS_BUFFEREDOUTPUTSTREAM_CONTRACTID "@mozilla.org/network/buffered-output-stream;1"
#define NS_BUFFEREDOUTPUTSTREAM_CID \
{ /* 9868b4ce-da08-11d3-8cda-0060b0fc14a3 */ \
0x9868b4ce, \
0xda08, \
0x11d3, \
{0x8c, 0xda, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \
}
////////////////////////////////////////////////////////////////////////////////
// move to nsNetUtil.h later...
#include "nsILoadGroup.h"
#include "nsIInterfaceRequestor.h"
#include "nsCOMPtr.h"
#include "nsIServiceManager.h"
#include "nsIFileChannel.h"
#include "nsILocalFile.h"
#include "nsIInputStream.h"
#include "nsIOutputStream.h"
#include "prio.h" // for read/write flags, permissions, etc.
// This will QI the file argument to an nsILocalFile in the Init method.
inline nsresult
NS_NewLocalFileChannel(nsIFileChannel **result,
nsIFile* file,
PRInt32 ioFlags = -1,
PRInt32 perm = -1)
{
nsresult rv;
nsCOMPtr<nsIFileChannel> channel;
static NS_DEFINE_CID(kLocalFileChannelCID, NS_LOCALFILECHANNEL_CID);
rv = nsComponentManager::CreateInstance(kLocalFileChannelCID,
nsnull,
NS_GET_IID(nsIFileChannel),
getter_AddRefs(channel));
if (NS_FAILED(rv)) return rv;
rv = channel->Init(file, ioFlags, perm);
if (NS_FAILED(rv)) return rv;
*result = channel;
NS_ADDREF(*result);
return NS_OK;
}
// This will QI the file argument to an nsILocalFile in the Init method.
inline nsresult
NS_NewLocalFileInputStream(nsIInputStream* *result,
nsIFile* file,
PRInt32 ioFlags = -1,
PRInt32 perm = -1)
{
nsresult rv;
nsCOMPtr<nsIFileInputStream> in;
static NS_DEFINE_CID(kLocalFileInputStreamCID, NS_LOCALFILEINPUTSTREAM_CID);
rv = nsComponentManager::CreateInstance(kLocalFileInputStreamCID,
nsnull,
NS_GET_IID(nsIFileInputStream),
getter_AddRefs(in));
if (NS_FAILED(rv)) return rv;
rv = in->Init(file, ioFlags, perm);
if (NS_FAILED(rv)) return rv;
*result = in;
NS_ADDREF(*result);
return NS_OK;
}
// This will QI the file argument to an nsILocalFile in the Init method.
inline nsresult
NS_NewLocalFileOutputStream(nsIOutputStream* *result,
nsIFile* file,
PRInt32 ioFlags = -1,
PRInt32 perm = -1)
{
nsresult rv;
nsCOMPtr<nsIFileOutputStream> out;
static NS_DEFINE_CID(kLocalFileOutputStreamCID, NS_LOCALFILEOUTPUTSTREAM_CID);
rv = nsComponentManager::CreateInstance(kLocalFileOutputStreamCID,
nsnull,
NS_GET_IID(nsIFileOutputStream),
getter_AddRefs(out));
if (NS_FAILED(rv)) return rv;
rv = out->Init(file, ioFlags, perm);
if (NS_FAILED(rv)) return rv;
*result = out;
NS_ADDREF(*result);
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
inline nsresult
NS_NewBufferedInputStream(nsIInputStream* *result,
nsIInputStream* str,
PRUint32 bufferSize)
{
nsresult rv;
nsCOMPtr<nsIBufferedInputStream> in;
static NS_DEFINE_CID(kBufferedInputStreamCID, NS_BUFFEREDINPUTSTREAM_CID);
rv = nsComponentManager::CreateInstance(kBufferedInputStreamCID,
nsnull,
NS_GET_IID(nsIBufferedInputStream),
getter_AddRefs(in));
if (NS_FAILED(rv)) return rv;
rv = in->Init(str, bufferSize);
if (NS_FAILED(rv)) return rv;
*result = in;
NS_ADDREF(*result);
return NS_OK;
}
inline nsresult
NS_NewBufferedOutputStream(nsIOutputStream* *result,
nsIOutputStream* str,
PRUint32 bufferSize)
{
nsresult rv;
nsCOMPtr<nsIBufferedOutputStream> out;
static NS_DEFINE_CID(kBufferedOutputStreamCID, NS_BUFFEREDOUTPUTSTREAM_CID);
rv = nsComponentManager::CreateInstance(kBufferedOutputStreamCID,
nsnull,
NS_GET_IID(nsIBufferedOutputStream),
getter_AddRefs(out));
if (NS_FAILED(rv)) return rv;
rv = out->Init(str, bufferSize);
if (NS_FAILED(rv)) return rv;
*result = out;
NS_ADDREF(*result);
return NS_OK;
}
%}

View File

@@ -0,0 +1,84 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsISupports.idl"
%{C++
#include "nsFileSpec.h"
%}
interface nsITransport;
interface nsIEventSinkGetter;
interface nsIInputStream;
interface nsIRunnable;
interface nsIFile;
interface nsIStreamIO;
[scriptable, uuid(57211a60-8c45-11d3-93ac-00104ba0fd40)]
interface nsIFileTransportService : nsISupports
{
nsITransport createTransport(in nsIFile file,
in long ioFlags,
in long perm);
// This version can be used with an existing input stream to serve
// as a data pump:
nsITransport createTransportFromStream(in string name,
in nsIInputStream fromStream,
in string contentType,
in long contentLength);
nsITransport createTransportFromStreamIO(in nsIStreamIO io);
void dispatchRequest(in nsIRunnable runnable);
void processPendingRequests();
void shutdown();
/**
* Total number of transports currently alive
*/
readonly attribute unsigned long totalTransportCount;
/**
* A number of transports with I/O operation currently in-progress
*/
readonly attribute unsigned long inUseTransportCount;
/**
* A number of transports connected/opened
*/
readonly attribute unsigned long connectedTransportCount;
};
%{C++
#define NS_FILETRANSPORTSERVICE_CID \
{ /* 2bb2b250-ea35-11d2-931b-00104ba0fd40 */ \
0x2bb2b250, \
0xea35, \
0x11d2, \
{0x93, 0x1b, 0x00, 0x10, 0x4b, 0xa0, 0xfd, 0x40} \
}
/**
* Status nsresult codes: used with nsIProgressEventSink::OnStatus
*/
#define NS_NET_STATUS_READ_FROM NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 8)
#define NS_NET_STATUS_WROTE_TO NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 9)
%}

View File

@@ -0,0 +1,196 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsISupports.idl"
#include "nsIChannel.idl"
interface nsIProtocolHandler;
interface nsIURI;
interface nsIInterfaceRequestor;
interface nsIStreamObserver;
interface nsIStreamListener;
interface nsIEventQueue;
interface nsIBufferInputStream;
interface nsIInputStream;
interface nsIBufferOutputStream;
interface nsIFileChannel;
interface nsILoadGroup;
interface nsILoadGroupObserver;
interface nsIFile;
interface nsIInputStream;
interface nsIOutputStream;
[scriptable, uuid(ab7c3a84-d488-11d3-8cda-0060b0fc14a3)]
interface nsIIOService : nsISupports
{
/**
* Returns a protocol handler for a given URI scheme.
*
* @param scheme URI scheme
* @return reference to nsIProtcolHandler
*/
nsIProtocolHandler getProtocolHandler(in string scheme);
/**
* This method constructs a new URI by first determining the scheme
* of the URI spec, and then delegating the construction of the URI
* to the protocol handler for that scheme. QueryInterface can be used
* on the resulting URI object to obtain a more specific type of URI.
*
* @param aSpec URI spec (http, ftp, etc)
* @param aBaseURI nsIURI to construct the actual URI from
* @return reference to a new nsIURI object
*/
nsIURI newURI(in string aSpec, in nsIURI aBaseURI);
/**
* Creates a channel for a given URI. The notificationCallbacks argument
* is used to obtain the appropriate callbacks for the URI's protocol from the
* application.
*
* @param originalURI - Specifies the original URI which caused the creation
* of this channel. This can occur when the construction of one channel
* (e.g. for resource:) causes another channel to be created on its behalf
* (e.g. a file: channel), or if a redirect occurs, causing the current
* URL to become different from the original URL. If NULL, the aURI parameter
* will be used as the originalURI instead.
*
* @param aURI - nsIURI to make a channel from
* @return a reference to the new nsIChannel object
*/
nsIChannel newChannelFromURI(in nsIURI aURI);
/**
* Convenience routine that first creates a URI by calling NewURI, and
* then passes the URI to NewChannelFromURI.
*
* @param originalURI - Specifies the original URI which caused the creation
* of this channel. This can occur when the construction of one channel
* (e.g. for resource:) causes another channel to be created on its behalf
* (e.g. a file: channel), or if a redirect occurs, causing the current
* URL to become different from the original URL. If NULL, the aURI parameter
* will be used as the originalURI instead.
*
* @param aSpec URI spec to select the appropriate protocol handler
* @param aBaseURI a base URI to create a channel to
* @return a reference to the new nsIChannel object
*/
nsIChannel newChannel(in string aSpec, in nsIURI aBaseURI);
/**
* Returns true if networking is in "offline" mode. When in offline mode, attempts
* to access the network will fail (although this is not necessarily corrolated with
* whether there is actually a network available -- that's hard to detect without
* causing the dialer to come up).
*/
attribute boolean offline;
////////////////////////////////////////////////////////////////////////////
// URL parsing utilities
/**
* Utility for protocol implementors -- extracts the scheme from a URL
* string, consistently and according to spec.
* @param urlString - the URL string to parse
* @param schemeStartPos - the resulting starting position of the scheme substring
* (may skip over whitespace)
* @param schemeEndPos - the resulting ending position of the scheme substring
* (the position of the colon)
* @param scheme - an allocated substring containing the scheme. If this parameter
* is null going into the routine, then the scheme is not allocated and
* returned. Free with nsCRT::free.
*
* @return NS_OK - if successful
* @return NS_ERROR_MALFORMED_URI - if the urlString is not of the right form
*/
void extractScheme(in string urlString,
out unsigned long schemeStartPos,
out unsigned long schemeEndPos,
out string scheme);
/**
* Constants for the mask in the call to Escape
*/
const short url_Scheme = (1<<0);
const short url_Username = (1<<1);
const short url_Password = (1<<2);
const short url_Host = (1<<3);
const short url_Directory = (1<<4);
const short url_FileBaseName = (1<<5);
const short url_FileExtension = (1<<6);
const short url_Param = (1<<7);
const short url_Query = (1<<8);
const short url_Ref = (1<<9);
const short url_Forced = (1<<10);
/**
* Encode characters into % escaped hexcodes.
*
* @param str a string to convert from
* @param mask a mask of flags to tell the converter which part of the url to escape
* @return escaped string
*/
string escape(in string str, in short mask);
/**
* Decode % escaped hex codes into character values.
*
* @param str a string to unescape from
* @return resulted unescaped string
*/
string unescape(in string str);
/**
* Get port from string.
*
* @param str URI-style string
* @return port number
*/
long extractPort(in string str);
/**
* Resolves a relative path string containing "." and ".."
* with respect to a base path (assumed to already be resolved).
* For example, resolving "../../foo/./bar/../baz.html" w.r.t.
* "/a/b/c/d/e/" yields "/a/b/c/foo/baz.html". Attempting to
* ascend above the base results in the NS_ERROR_MALFORMED_URI
* exception. If basePath is null, it treats it as "/".
*
* @param relativePath a relative URI
* @param basePath a base URI
* @return a new string, representing canonical uri
*/
string resolveRelativePath(in string relativePath,
in string basePath);
};
%{C++
#define NS_IOSERVICE_CID \
{ /* 9ac9e770-18bc-11d3-9337-00104ba0fd40 */ \
0x9ac9e770, \
0x18bc, \
0x11d3, \
{0x93, 0x37, 0x00, 0x10, 0x4b, 0xa0, 0xfd, 0x40} \
}
%}

View File

@@ -0,0 +1,106 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsIRequest.idl"
interface nsIChannel;
interface nsIRequest;
interface nsISimpleEnumerator;
interface nsIStreamObserver;
interface nsIStreamListener;
interface nsIInputStream;
[scriptable, uuid(60fdf550-5392-11d3-9a97-0080c7cb1080)]
interface nsILoadGroupListenerFactory : nsISupports
{
nsIStreamListener createLoadGroupListener(in nsIStreamListener alistener);
};
/**
* A load group maintains a collection of active URL requests.
*
* @status UNDER_REVIEW
*/
[scriptable, uuid(19845248-29ab-11d3-8cce-0060b0fc14a3)]
interface nsILoadGroup : nsIRequest
{
void init(in nsIStreamObserver observer);
/**
* Accesses the default load attributes for the group, returned as
* a flag word. Setting the default load attributes will cause them
* to be applied to each new channel inserted into the group.
*/
attribute unsigned long defaultLoadAttributes;
/**
* Accesses the default load channel for the group. Each time a number
* of request are added to a group, the DefaultLoadChannel may be set
* to indicate that all of the requests are related to a particular URL.
*/
attribute nsIRequest defaultLoadRequest;
/**
* Adds a new request to the group. This will cause the default load
* attributes to be applied to that request. If the request added is
* the first request in the group, the group's observer's OnStartRequest
* method is called.
*/
void addRequest(in nsIRequest request,
in nsISupports ctxt);
/**
* Removes a request from the group. If the request removed is
* the last request in the group, the group's observer's OnStopRequest
* method is called.
*/
void removeRequest(in nsIRequest request,
in nsISupports ctxt,
in nsresult status,
in wstring statusArg);
/**
* Returns the requests contained directly in this group.
* Enumerator element type: nsIRequest.
*/
readonly attribute nsISimpleEnumerator requests;
attribute nsIStreamObserver groupObserver;
attribute nsILoadGroupListenerFactory groupListenerFactory;
readonly attribute unsigned long activeCount;
};
%{C++
#define NS_LOADGROUP_CID \
{ /* e1c61582-2a84-11d3-8cce-0060b0fc14a3 */ \
0xe1c61582, \
0x2a84, \
0x11d3, \
{0x8c, 0xce, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \
}
%}

View File

@@ -0,0 +1,47 @@
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
/* This interface defines a registry entry for the networking libraries
* external module registry. */
#include "nsISupports.idl"
#include "nsINetNotify.idl"
interface nsIEventQueue;
interface nsINetModRegEntry;
interface nsINetNotify;
%{ C++
// {F126BD90-1472-11d3-A15A-0050041CAF44}
#define NS_NETMODREGENTRY_CID \
{ 0xf126bd90, 0x1472, 0x11d3, { 0xa1, 0x5a, 0x0, 0x50, 0x4, 0x1c, 0xaf, 0x44 } }
%}
[scriptable, uuid(9F482BD0-1476-11d3-A15A-0050041CAF44)]
interface nsINetModRegEntry : nsISupports
{
readonly attribute nsINetNotify syncProxy;
readonly attribute nsINetNotify asyncProxy;
readonly attribute string topic;
boolean equals(in nsINetModRegEntry aEntry);
};

View File

@@ -0,0 +1,80 @@
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
/* The nsINetModuleMgr singleton service allows external module to register
* themselves with the networking library to receive events they want to
* receive.
*
* An external module that is interested in being notified when a particular
* networking level event occurs would register with this service, and
* implement the appropriate interface(s) that correspond to the events they
* want to receive. These interfaces are defined by networking internal
* components (for example, http would define a notification interface that
* the external cookies module would implement).
*/
#include "nsISupports.idl"
#include "nsIEnumerator.idl"
#include "nsINetNotify.idl"
interface nsIEventQueue;
%{ C++
// {4EBDAFE0-13BA-11d3-A15A-0050041CAF44}
#define NS_NETMODULEMGR_CID \
{ 0x4ebdafe0, 0x13ba, 0x11d3, { 0xa1, 0x5a, 0x0, 0x50, 0x4, 0x1c, 0xaf, 0x44 } }
// The list of available CONTRACTIDS to register for notification on.
#define NS_NETWORK_MODULE_MANAGER_HTTP_REQUEST_CONTRACTID "@mozilla.org/network/moduleMgr/http/request;1"
#define NS_NETWORK_MODULE_MANAGER_HTTP_RESPONSE_CONTRACTID "@mozilla.org/network/moduleMgr/http/response;1"
%}
[scriptable, uuid(ff9ead40-0ef2-11d3-9de6-0010a4053fd0)]
interface nsINetModuleMgr : nsISupports {
// Register the external module to receive notifications.
//
// ARGUMENTS:
// aTopic: The internal component that the external module wants to monitor.
// aNotify: The external module interface methods to be called when an event is fired.
//
// RETURNS: nsresult
void registerModule(in string aTopic, in nsINetNotify aNotify);
// Unregister the external module. Removes the nsINetModuleMgr binding between
// internal component and external module.
//
// ARGUMENTS:
// aTopic: The internal component being monitored.
// aNotify: The external modules notification module.
//
// RETURNS: nsresult
void unregisterModule(in string aTopic, in nsINetNotify aNotify);
// Enumerates all the registered modules for the specified topic.
//
// ARGUMENTS:
// aTopic: the component to get all the notifiers for.
// aEnumerator: the array of notifiers.
void enumerateModules(in string aTopic, out nsISimpleEnumerator aEnumerator);
};

View File

@@ -0,0 +1,28 @@
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsISupports.idl"
[uuid(4A3019E0-1CF3-11d3-A15B-0050041CAF44)]
interface nsINetNotify : nsISupports {
};

View File

@@ -0,0 +1,38 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* 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 Zero-Knowledge
* Systems, Inc. Portions created by Zero-Knowledge are Copyright
* (C) 2000 Zero-Knowledge Systems, Inc. All Rights Reserved.
*
* Contributor(s):
*/
#include "nsISupports.idl"
/**
* Interface for password management (aka single-signon) componentry.
*/
/* XXXshaver these came from the old wallet interfaces, and seem questionable */
native nsAutoString(nsAutoString);
[ref] native nsAutoStringRef(nsAutoString);
[scriptable, uuid(110c808c-1dd2-11b2-8de5-814d4485c444)]
interface nsIPasswordManager : nsISupports {
void removeUser(in string key, in wstring user);
void storePassword(in string key, in wstring user, in wstring pass);
[noscript] void getSignonListForViewer(in nsAutoStringRef aSignonList);
[noscript] void getRejectListForViewer(in nsAutoStringRef aRejectList);
};

View File

@@ -0,0 +1,30 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* 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 Zero-Knowledge
* Systems, Inc. Portions created by Zero-Knowledge are Copyright
* (C) 2000 Zero-Knowledge Systems, Inc. All Rights Reserved.
*
* Contributor(s):
*/
#ifndef NSIPASSWORDMANAGERUTILS_H__
#define NSIPASSWORDMANAGERUTILS_H__
#include "nsIPasswordManager.h"
/* XXX love me, rayw, love me true */
#define PASSWORDMANAGER_CONTRACTID "@mozilla.org/network/password-manager;1"
#endif /* NSIPASSWORDMANAGERUTILS_H__ */

View File

@@ -0,0 +1,60 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsISupports.idl"
interface nsIURI;
interface nsIRequest;
/**
* An instance of nsIFfpEventSink should be passed as the eventSink
* argument of nsINetService::NewConnection for ftp URLs. It defines
* the callbacks to the application program (the html parser).
*/
[scriptable, uuid(dd47ee00-18c2-11d3-9337-00104ba0fd40)]
interface nsIProgressEventSink : nsISupports
{
/**
* Notify the EventSink that progress has occurred for the URL load.<BR>
*/
void onProgress(in nsIRequest request,
in nsISupports ctxt,
in unsigned long aProgress,
in unsigned long aProgressMax);
/**
* Notify the EventSink with a status message for the URL load.<BR>
* @param status - A status code denoting the type of notification. This
* can be a message to be displayed (e.g. for file I/O,
* STATUS_READ_FROM, or STATUS_WROTE_TO), or can be an event
* to be programmatically handled.
* @param statusArg - An argument or arguments to the status notification.
* These arguments will be formatted into any status or error
* message. Multiple arguments can be passed by delimiting them
* with newline ('\n') characters.
*/
void onStatus(in nsIRequest request,
in nsISupports ctxt,
in nsresult status,
in wstring statusArg);
};

View File

@@ -0,0 +1,133 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
/**
* @status UNDER_REVIEW
*/
#include "nsISupports.idl"
[scriptable, uuid(a63f70c0-148b-11d3-9333-00104ba0fd40)]
interface nsIPrompt : nsISupports
{
/**
* Puts up an alert dialog with an OK button.
*/
void alert(in wstring dialogTitle,
in wstring text);
/**
* Puts up an alert dialog with an OK button.
*/
void alertCheck(in wstring dialogTitle,
in wstring text,
in wstring checkMsg,
out boolean checkValue);
/**
* Puts up a dialog with OK and Cancel buttons.
* @return true for OK, false for Cancel
*/
boolean confirm(in wstring dialogTitle,
in wstring text);
/**
* Puts up a dialog with OK and Cancel buttons, and
* a message with a single checkbox.
* @return true for OK, false for Cancel
*/
boolean confirmCheck(in wstring dialogTitle,
in wstring text,
in wstring checkMsg,
out boolean checkValue);
/**
* Values for the savePassword parameter to prompt, promptPassword and
* promptUsernameAndPassword.
*/
const PRUint32 SAVE_PASSWORD_NEVER = 0;
const PRUint32 SAVE_PASSWORD_FOR_SESSION = 1;
const PRUint32 SAVE_PASSWORD_PERMANENTLY = 2;
/**
* Puts up a text input dialog with OK and Cancel buttons.
* @return true for OK, false for Cancel
*/
boolean prompt(in wstring dialogTitle,
in wstring text,
in wstring passwordRealm,
in PRUint32 savePassword,
in wstring defaultText,
out wstring result);
/**
* Puts up a username/password dialog with OK and Cancel buttons.
* @return true for OK, false for Cancel
*/
boolean promptUsernameAndPassword(in wstring dialogTitle,
in wstring text,
in wstring passwordRealm,
in PRUint32 savePassword,
out wstring user,
out wstring pwd);
/**
* Puts up a password dialog with OK and Cancel buttons.
* @return true for OK, false for Cancel
*/
boolean promptPassword(in wstring dialogTitle,
in wstring text,
in wstring passwordRealm,
in PRUint32 savePassword,
out wstring pwd);
/**
* Puts up a dialog box which has a list box of strings
*/
boolean select(in wstring dialogTitle,
in wstring text,
in PRUint32 count,
[array, size_is(count)] in wstring selectList,
out long outSelection);
/**
* Put up a universal dialog
*/
void universalDialog(in wstring titleMessage,
in wstring dialogTitle, /* e.g., alert, confirm, prompt, prompt password */
in wstring text, /* main message for dialog */
in wstring checkboxMsg, /* message for checkbox */
in wstring button0Text, /* text for first button */
in wstring button1Text, /* text for second button */
in wstring button2Text, /* text for third button */
in wstring button3Text, /* text for fourth button */
in wstring editfield1Msg, /*message for first edit field */
in wstring editfield2Msg, /* message for second edit field */
inout wstring editfield1Value, /* initial and final value for first edit field */
inout wstring editfield2Value, /* initial and final value for second edit field */
in wstring iconURL, /* url of icon to be displayed in dialog */
inout boolean checkboxState, /* initial and final state of checkbox */
in PRInt32 numberButtons, /* total number of buttons (0 to 4) */
in PRInt32 numberEditfields, /* total number of edit fields (0 to 2) */
in PRInt32 editField1Password, /* ??? */
out PRInt32 buttonPressed); /* number of button that was pressed (0 to 3) */
};

View File

@@ -0,0 +1,71 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsISupports.idl"
#include "nsIChannel.idl"
interface nsIURI;
[scriptable, uuid(15fd6940-8ea7-11d3-93ad-00104ba0fd40)]
interface nsIProtocolHandler : nsISupports
{
readonly attribute string scheme;
/**
* Default Port will be the port that this protocol normally
* uses. If a port does not make sense for the protocol (eg about://)
* -1 will be returned.
*/
readonly attribute long defaultPort;
/**
* Makes a URI object that is suitable for loading by this protocol.
* In the usual case (when only the accessors provided by nsIURI are
* needed), this method just constructs a standard URI using the
* component manager with kStandardURLCID. aBaseURI may be nsnull.
*/
nsIURI newURI(in string aSpec, in nsIURI aBaseURI);
/**
* Constructs a new channel for this protocol handler.
*
* @param originalURI - Specifies the original URI which caused the creation
* of this channel. This can occur when the construction of one channel
* (e.g. for resource:) causes another channel to be created on its behalf
* (e.g. a file: channel), or if a redirect occurs, causing the current
* URL to become different from the original URL. If NULL, the aURI parameter
* will be used as the originalURI instead.
*/
nsIChannel newChannel(in nsIURI aURI);
};
%{C++
#define NS_NETWORK_PROTOCOL_CONTRACTID "@mozilla.org/network/protocol;1"
#define NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX NS_NETWORK_PROTOCOL_CONTRACTID "?name="
#define NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX_LENGTH 37 // nsCRT::strlen(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX)
// Unknown Protocol Error
#define NS_ERROR_UNKNOWN_PROTOCOL NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 18)
%}

View File

@@ -0,0 +1,47 @@
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsISupports.idl"
#include "nsIURI.idl"
#include "nsIProxy.idl"
%{C++
#define NS_PROTOCOLPROXYSERVICE_CID \
{ /* E9B301C0-E0E4-11d3-A1A8-0050041CAF44 */ \
0xe9b301c0, 0xe0e4, 0x11d3, { 0xa1, 0xa8, 0x0, 0x50, 0x4, 0x1c, 0xaf, 0x44 } }
%}
[scriptable, uuid(495CC980-E0D4-11d3-A1A8-0050041CAF44)]
interface nsIProtocolProxyService : nsISupports
{
readonly attribute PRBool proxyEnabled;
void examineForProxy(in nsIURI aURI, in nsIProxy aProxy);
/**
* Add additional items in the "No proxy for" list. This is above
* the list specified the user-pref.
*/
void addNoProxyFor(in string host, in long port);
void removeNoProxyFor(in string host, in long port);
};

View File

@@ -0,0 +1,43 @@
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
/*
The nsIProxy interface allows setting and getting of proxy host and port.
This is for use by protocol handlers. If you are writing a protocol handler
and would like to support proxy behaviour then derive from this as well as
the nsIProtocolHandler class.
-Gagan Saksena 02/25/99
*/
#include "nsISupports.idl"
[scriptable, uuid(0492D011-CD2F-11d2-B013-006097BFC036)]
interface nsIProxy : nsISupports
{
attribute string proxyHost;
/* -1 on Set call indicates switch to default port */
attribute long proxyPort;
attribute string proxyType;
};

View File

@@ -0,0 +1,58 @@
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
/**
The nsIProxyAutoConfig interface is used for setting arbitrary proxy
configurations based on the specified URL.
Note this interface wraps (at least in a the implementation) the older
hacks of proxy auto config.
- Gagan Saksena 04/23/00
*/
#include "nsISupports.idl"
interface nsIURI;
[scriptable, uuid(26fae72a-1dd2-11b2-9dd9-cb3e0c2c79ba)]
interface nsIProxyAutoConfig : nsISupports
{
/**
* Get the proxy for the specified host
*/
void ProxyForURL(in nsIURI uri, out string host, out long port, out string type);
};
%{C++
#define NS_PROXY_AUTO_CONFIG_CID \
{ /* 63ac8c66-1dd2-11b2-b070-84d00d3eaece */ \
0x63ac8c66, \
0x1dd2, \
0x11b2, \
{0xb0, 0x70, 0x84, 0xd0, 0x0d, 0x3e, 0xae, 0xce} \
}
#define NS_PROXY_AUTO_CONFIG_CONTRACTID \
"@mozilla.org/network/proxy_autoconfig;1"
%}

View File

@@ -0,0 +1,59 @@
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
/**
* The nsIProxyAutoConfigUtils interface is used for the proxy auto config
* utility functions like isPlainHostName, dnsDomainIs, etc.
*
* This interface wraps the older hacks of proxy auto config utility
* functions. Most of the string comparisons are now deprecated.
*
* For more information look at-
* TODO - put the correct URL here...!
* http://www.mozilla.org/docs/netlib/pac.html
*
* - Gagan Saksena 04/23/00
*/
#include "nsISupports.idl"
[scriptable, uuid(fe3896e8-1dd1-11b2-821f-83b84e1466f6)]
interface nsIProxyAutoConfigUtils : nsISupports
{
/**
* Hostname based conditions.
*/
void isResolvable(in string host,
out PRBool result);
void isInNet(in string host,
in string pattern,
in string mask,
out PRBool result);
/**
* Utility functions.
*/
void DNSResolve(in string host,
out string ipaddress);
void myIPAddress(out string ipaddress);
};

View File

@@ -0,0 +1,72 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsISupports.idl"
/**
* @status UNDER_REVIEW
*/
[scriptable, uuid(F2CAABA0-2F25-11d3-A164-0050041CAF44)]
interface nsIRequest : nsISupports
{
/**
* Returns the name of the request. Often this is the URL of the request.
*/
readonly attribute wstring name;
/**
* Returns true if the request is pending (active). Returns false
* after completion or successful calling Cancel. Suspended requests
* are still considered pending.
*/
boolean isPending();
/**
* Returns any error status associated with the request.
*/
readonly attribute nsresult status;
/**
* Cancels the current request. This will close any open input or
* output streams and terminate any async requests. Users should
* normally pass NS_BINDING_ABORTED, although other errors may also
* be passed. The error passed in will become the value of the
* status attribute.
*/
void cancel(in nsresult status);
/**
* Suspends the current requests. This may have the effect of closing
* any underlying transport (in order to free up resources), although
* any open streams remain logically opened and will continue delivering
* data when the transport is resumed.
*/
void suspend();
/**
* Resumes the current request. This may have the effect of re-opening
* any underlying transport and will resume the delivery of data to
* any open streams.
*/
void resume();
};

View File

@@ -0,0 +1,66 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* thayes@netscape.com
* bryner@netscape.com
*
* This is a generic security interface to encrypt and decrypt buffers.
* Specific security extensions will need to implement this.
*/
#include "nsISupports.idl"
/* Buffer type - for storing 8-bit octet values */
[ptr] native buffer(unsigned char);
[scriptable, uuid(0EC80360-075C-11d4-9FD4-00C04F1B83D8)]
interface nsISecretDecoderRing: nsISupports {
/* Encrypt a buffer - callable only from C++ */
[noscript] long encrypt(in buffer data, in long dataLen, out buffer result);
/* Decrypt a buffer - callable only from C++ */
[noscript] long decrypt(in buffer data, in long dataLen, out buffer result);
/* Encrypt nul-terminated string to BASE64 output */
string encryptString(in string text);
/* Decrypt BASE64 input to nul-terminated string output */
/* There is no check for embedded nul values in the decrypted output */
string decryptString(in string crypt);
/* Prompt the user to change the password on the SDR key */
void changePassword();
/* Logout of the security device that protects the SDR key */
void logout();
};
/*
* Configuration interface for the Secret Decoder Ring
* - this interface allows setting the window that will be
* used as parent for dialog windows (such as password prompts)
*/
[scriptable, uuid(01D8C0F0-0CCC-11d4-9FDD-000064657374)]
interface nsISecretDecoderRingConfig: nsISupports {
void setWindow(in nsISupports w);
};

View File

@@ -0,0 +1,40 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Hubbie Shaw
* Doug Turner <dougt@netscape.com>
*/
#include "nsISupports.idl"
interface nsIDOMWindowInternal;
interface nsIDOMElement;
[scriptable, uuid(081e31e0-a144-11d3-8c7c-00609792278c)]
interface nsSecureBrowserUI : nsISupports
{
void init(in nsIDOMWindowInternal window, in nsIDOMElement button);
void displayPageInfoUI();
};
%{C++
#define NS_SECURE_BROWSER_UI_CONTRACTID "@mozilla.org/secure_browser_ui;1"
#define NS_SECURE_BROWSER_UI_CLASSNAME "Mozilla Secure Browser UI Handler"
%}

View File

@@ -0,0 +1,43 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsISupports.idl"
interface nsIURI;
[scriptable, uuid(a71aee68-dd38-4736-bd79-035fea1a1ec6)]
interface nsISecurityEventSink : nsISupports
{
/**
* Fired when a security change occurs due to page transitions,
* or end document load. This interface should be called by
* a security package (eg Netscape Personal Security Manager)
* to notify nwIWebProgressListeners that security state has
* changed. State flags are in nsIWebProgressListener.idl
*/
void onSecurityChange(in nsISupports i_Context, in long state);
};

View File

@@ -0,0 +1,46 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Hubbie Shaw
* Doug Turner <dougt@netscape.com>
* Mitch Stoltz <mstoltz@netscape.com>
* Brian Ryner <bryner@netscape.com>
*/
#include "nsISupports.idl"
[scriptable, uuid(3ef604be-1dd2-11b2-92cc-faae57e1901a)]
interface nsISecurityManagerComponent : nsISupports
{
/**
* Display the Security Advisor.
*/
string GetPassword();
void displaySecurityAdvisor();
};
%{C++
#define PSM_COMPONENT_CONTRACTID "@mozilla.org/psm;1"
#define PSM_COMPONENT_CLASSNAME "Mozilla PSM Component"
%}

View File

@@ -0,0 +1,73 @@
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsITransport.idl"
[scriptable, uuid(785CA0F0-C39E-11d3-9ED6-0010A4053FD0)]
interface nsISocketTransport : nsITransport
{
readonly attribute string host;
readonly attribute long port;
/**
*
*/
attribute boolean reuseConnection;
/**
* socket read/write timeout in seconds; 0 = no timeout
*/
attribute unsigned long socketTimeout;
/**
* socket connect timeout in seconds; 0 = no timeout
*/
attribute unsigned long socketConnectTimeout;
/**
* Is used to tell the channel to stop reading data after a certain point;
* needed by HTTP/1.1
*/
attribute long bytesExpected;
attribute unsigned long reuseCount;
/**
* Checks if the socket is still alive
*
* @param seconds amount of time after which the socket is always deemed to be
* dead (no further checking is done in this case); seconds = 0
* will cause it not to do the timeout checking at all
*/
boolean isAlive (in unsigned long seconds);
/**
* maximum amount of time in seconds the transport is allowed to stay alive
* while connected (0 - default; no maximum idle timeout)
*/
attribute unsigned long idleTimeout;
/**
* the string representation of the underlying ip address. Caller
* is responsible for de-allocating the returned string.
*/
[noscript] string GetIPStr(in unsigned long aStrLen);
};

View File

@@ -0,0 +1,112 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsISupports.idl"
interface nsITransport;
interface nsIEventSinkGetter;
interface nsIChannel;
[scriptable, uuid(05331390-6884-11d3-9382-00104ba0fd40)]
interface nsISocketTransportService : nsISupports
{
/**
* Creates a transport for a specified host and port.
* The eventSinkGetter is used to get the appropriate callbacks
* for the socket activity from the application. These include
* the progress and the status messages like "Contacting host.."
* etc. The printHost contains the actual hostname (and not the
* proxy) for displaying in status messages.
*/
nsITransport createTransport(in string host,
in long port,
in string proxyHost,
in long proxyPort,
in unsigned long bufferSegmentSize,
in unsigned long bufferMaxSize);
nsITransport createTransportOfType(in string socketType,
in string host,
in long port,
in string proxyHost,
in long proxyPort,
in unsigned long bufferSegmentSize,
in unsigned long bufferMaxSize);
nsITransport createTransportOfTypes(in unsigned long typeCount,
[array, size_is(typeCount)] in string socketTypes,
in string host,
in long port,
in string proxyHost,
in long proxyPort,
in unsigned long bufferSegmentSize,
in unsigned long bufferMaxSize);
/**
* Returns true if the specified transport is good enough for
* being used again. The situations in which this may return false
* include- an error including server resets, an explicit
* Connection: close header (for HTTP) and timeouts!
*/
boolean reuseTransport(in nsITransport i_Transport);
void init ();
void shutdown();
void wakeup (in nsITransport i_Transport);
/**
* Total number of nsSocketTransport objects currently alive
*/
readonly attribute unsigned long totalTransportCount;
/**
* A number of nsSocketTransport objects with I/O operation currently in-progress
*/
readonly attribute unsigned long inUseTransportCount;
/**
* A number of nsSocketTransport objects connected (this may include keep-alive idle connections)
*/
readonly attribute unsigned long connectedTransportCount;
};
%{C++
#define NS_SOCKETTRANSPORTSERVICE_CID \
{ /* c07e81e0-ef12-11d2-92b6-00105a1b0d64 */ \
0xc07e81e0, \
0xef12, \
0x11d2, \
{0x92, 0xb6, 0x00, 0x10, 0x5a, 0x1b, 0x0d, 0x64} \
}
#define NS_ERROR_CONNECTION_REFUSED NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 13)
#define NS_ERROR_NET_TIMEOUT NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 14)
/**
* Status nsresult codes: used with nsIProgressEventSink::OnStatus
*/
#define NS_NET_STATUS_RESOLVING_HOST NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 3)
#define NS_NET_STATUS_CONNECTED_TO NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 4)
#define NS_NET_STATUS_SENDING_TO NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 5)
#define NS_NET_STATUS_RECEIVING_FROM NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 6)
#define NS_NET_STATUS_CONNECTING_TO NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 7)
%}

View File

@@ -0,0 +1,183 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsISupports.idl"
interface nsIInputStream;
interface nsIOutputStream;
interface nsIURI;
interface nsIFile;
/**
* nsIStreamIO is an abstract interface that gives access to input and output
* streams on an object. Perhaps the most interesting subclass of this is
* nsIFileIO which allows access to input and output streams to files.
*/
[scriptable, uuid(d6c01ab2-0d04-11d4-986e-00c04fa0cf4a)]
interface nsIStreamIO : nsISupports
{
/**
* Logically opens a stream I/O object, returning its content type
* and length. If either of these are unknown, the value -1 is returned.
*/
void open(out string contentType,
out long contentLength);
/**
* Logically closes a stream I/O object. A status value is passed in
* to indicate a successful close (NS_OK) or failure.
*/
void close(in nsresult status);
/**
* Gets an input stream from a stream I/O object.
*/
readonly attribute nsIInputStream inputStream;
/**
* Gets an output stream from a stream I/O object.
*/
readonly attribute nsIOutputStream outputStream;
/**
* Returns the 'name' of a stream I/O object. This name is often
* used for display purposes.
*/
readonly attribute string name;
};
////////////////////////////////////////////////////////////////////////////////
// nsIFileIO
/**
* nsIFileIO specializes nsIStreamIO to allow initialization from an nsIFile
* object. For this implementation, the name attribute will correspond to the
* path to the file.
*/
[scriptable, uuid(2a45fb42-0d06-11d4-986e-00c04fa0cf4a)]
interface nsIFileIO : nsIStreamIO
{
void init(in nsIFile file,
in long ioFlags,
in long perm);
readonly attribute nsIFile file;
};
%{C++
#include "nsCOMPtr.h"
#include "nsIComponentManager.h"
#define NS_FILEIO_CLASSNAME "File I/O"
#define NS_FILEIO_CONTRACTID "@mozilla.org/network/file-io;1"
#define NS_FILEIO_CID \
{ /* 0965ce3e-0d06-11d4-986e-00c04fa0cf4a */ \
0x0965ce3e, \
0x0d06, \
0x11d4, \
{0x98, 0x6e, 0x00, 0xc0, 0x4f, 0xa0, 0xcf, 0x4a} \
}
inline nsresult
NS_NewFileIO(nsIFileIO **result,
nsIFile* file,
PRInt32 ioFlags = -1,
PRInt32 perm = -1)
{
nsresult rv;
nsCOMPtr<nsIFileIO> fileIO;
static NS_DEFINE_CID(kFileIOCID, NS_FILEIO_CID);
rv = nsComponentManager::CreateInstance(kFileIOCID,
nsnull,
NS_GET_IID(nsIFileIO),
getter_AddRefs(fileIO));
if (NS_FAILED(rv)) return rv;
rv = fileIO->Init(file, ioFlags, perm);
if (NS_FAILED(rv)) return rv;
*result = fileIO;
NS_ADDREF(*result);
return NS_OK;
}
%}
////////////////////////////////////////////////////////////////////////////////
// nsIInputStreamIO
/**
* nsIInputStreamIO specializes nsIStreamIO to allow initialization from an
* input stream, name, content type and length. Note that attempts to access
* the output stream of an nsIInputStreamIO will fail. This implementation
* is provided as a convenience, to avoid the need to implement the complete
* nsIStreamIO interface, when all you need is the input stream part.
*/
[scriptable, uuid(2d64af08-0d06-11d4-986e-00c04fa0cf4a)]
interface nsIInputStreamIO : nsIStreamIO
{
void init(in string name,
in nsIInputStream input,
in string contentType,
in long contentLength);
};
%{C++
#define NS_INPUTSTREAMIO_CLASSNAME "Input Stream I/O"
#define NS_INPUTSTREAMIO_CONTRACTID "@mozilla.org/network/input-stream-io;1"
#define NS_INPUTSTREAMIO_CID \
{ /* 0f5e1198-0d06-11d4-986e-00c04fa0cf4a */ \
0x0f5e1198, \
0x0d06, \
0x11d4, \
{0x98, 0x6e, 0x00, 0xc0, 0x4f, 0xa0, 0xcf, 0x4a} \
}
inline nsresult
NS_NewInputStreamIO(nsIInputStreamIO* *result,
const char* name,
nsIInputStream* inStr,
const char* contentType,
PRInt32 contentLength)
{
nsresult rv;
nsCOMPtr<nsIInputStreamIO> io;
static NS_DEFINE_CID(kInputStreamIOCID, NS_INPUTSTREAMIO_CID);
rv = nsComponentManager::CreateInstance(kInputStreamIOCID,
nsnull,
NS_GET_IID(nsIInputStreamIO),
getter_AddRefs(io));
if (NS_FAILED(rv)) return rv;
rv = io->Init(name, inStr, contentType, contentLength);
if (NS_FAILED(rv)) return rv;
*result = io;
NS_ADDREF(*result);
return NS_OK;
}
%}
////////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,52 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
interface nsIURI;
interface nsIStreamIO;
#include "nsIChannel.idl"
/**
* nsIStreamIOChannel specializes nsIChannel to allow a simple channel to be
* constructed from an nsIStreamIO object and a URL.
*/
[scriptable, uuid(308362ce-0d06-11d4-986e-00c04fa0cf4a)]
interface nsIStreamIOChannel : nsIChannel
{
void init(in nsIURI uri, in nsIStreamIO io);
};
%{C++
#define NS_STREAMIOCHANNEL_CLASSNAME "Stream I/O Channel"
#define NS_STREAMIOCHANNEL_CONTRACTID "@mozilla.org/network/stream-io-channel;1"
#define NS_STREAMIOCHANNEL_CID \
{ /* 6ddb050c-0d04-11d4-986e-00c04fa0cf4a */ \
0x6ddb050c, \
0x0d04, \
0x11d4, \
{0x98, 0x6e, 0x00, 0xc0, 0x4f, 0xa0, 0xcf, 0x4a} \
}
%}
////////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,132 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsIStreamObserver.idl"
interface nsIRequest;
interface nsIInputStream;
interface nsIOutputStream;
interface nsIEventQueue;
/**
* The nsIChannel::AsyncRead notification handler. It accepts
* data from the channel, when the channel is ready to provide it.
*/
[scriptable, uuid(1a637020-1482-11d3-9333-00104ba0fd40)]
interface nsIStreamListener : nsIStreamObserver
{
/**
* Called when there is data to be read from the channel.
*
* @param request - the request returned by AsyncRead
* @param ctxt - opaque parameter passed to AsyncRead
* @param input - temporary input stream for reading data chunk
* @param offset - current stream position (informational)
* @param count - number of bytes that can be read without blocking
*
* @return NS_OK - if successfully read something.
* @return NS_BASE_STREAM_CLOSED - if done reading data. NOTE: this is
* NOT equivalent to reading zero bytes and returning NS_OK.
* @return NS_BASE_STREAM_WOULD_BLOCK - if no data can be read at
* this time. This implicitly calls Suspend on the channel. Call
* Resume on the channel to continue the AsyncRead when more data
* becomes available.
* @return <other-error> - if failure.
*/
void onDataAvailable(in nsIRequest request,
in nsISupports ctxt,
in nsIInputStream input,
in unsigned long offset,
in unsigned long count);
};
/**
* A stream listener proxy is used to ship data over to another thread specified
* by the thread's event queue. The "true" stream listener's methods are
* invoked on the other thread.
*
* This interface only provides the initialization needed after construction.
* Otherwise, these objects may be used as a nsIStreamListener.
*/
[scriptable, uuid(e400e688-6b54-4a84-8c4e-56b40281981a)]
interface nsIStreamListenerProxy : nsIStreamListener
{
/**
* Initializes an nsIStreamListenerProxy.
*
* @param listener - receives listener notifications on the other thread
* @param eventQ - may be NULL indicating the calling thread's event queue
* @param bufferSegmentSize - passing zero indicates the default
* @param bufferMaxSize - passing zero indicates the default
*/
void init(in nsIStreamListener listener,
in nsIEventQueue eventQ,
in unsigned long bufferSegmentSize,
in unsigned long bufferMaxSize);
};
/**
* A simple stream listener can be used with AsyncRead to supply data to
* a output stream.
*/
[scriptable, uuid(a9b84f6a-0824-4278-bae6-bfca0570a26e)]
interface nsISimpleStreamListener : nsIStreamListener
{
/**
* Initialize the simple stream listener.
*
* @param sink - data will be read from the channel to this output stream
* @param observer - optional stream observer (can be NULL)
*/
void init(in nsIOutputStream sink,
in nsIStreamObserver observer);
};
/**
* An asynchronous stream listener is used to ship data over to another thread specified
* by the thread's event queue. The receiver stream listener is then used to receive
* the notifications on the other thread.
*
* This interface only provides the initialization needed after construction. Otherwise,
* these objects are used simply as nsIStreamListener.
*/
[scriptable, uuid(1b012ade-91bf-11d3-8cd9-0060b0fc14a3)]
interface nsIAsyncStreamListener : nsIStreamListener
{
/**
* Initializes an nsIAsyncStreamListener.
* @param eventQueue - may be null indicating the calling thread's event queue
*/
void init(in nsIStreamListener receiver,
in nsIEventQueue eventQueue);
};
/**
* As data "flows" into a stream listener tee, it is copied to the output stream
* and then forwarded onto the real listener.
*/
[scriptable, uuid(fb683e76-d42b-41a4-8ae6-65a6c2b146e5)]
interface nsIStreamListenerTee : nsIStreamListener
{
void init(in nsIStreamListener listener,
in nsIOutputStream sink);
};

View File

@@ -0,0 +1,72 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsISupports.idl"
#include "nsIChannel.idl"
interface nsIRequest;
interface nsIURI;
interface nsILoadGroup;
interface nsIStreamObserver;
interface nsIStreamLoader;
interface nsIInterfaceRequestor;
[scriptable, uuid(359F7990-D4E9-11d3-A1A5-0050041CAF44)]
interface nsIStreamLoaderObserver : nsISupports
{
void onStreamComplete(in nsIStreamLoader loader,
in nsISupports ctxt,
in nsresult status,
in unsigned long resultLength,
[size_is(resultLength)] in string result);
};
[scriptable, uuid(31d37360-8e5a-11d3-93ad-00104ba0fd40)]
interface nsIStreamLoader : nsISupports
{
void init(in nsIURI uri,
in nsIStreamLoaderObserver completionObserver,
in nsISupports ctxt,
in nsILoadGroup loadGroup,
in nsIInterfaceRequestor notificationCallbacks,
in nsLoadFlags loadAttributes);
/**
* Gets the number of bytes read so far.
*/
readonly attribute unsigned long numBytesRead;
/**
* Gets the request that loaded this file
*/
readonly attribute nsIRequest request;
};
%{C++
#define NS_STREAMLOADER_CID \
{ /* 5BA6D920-D4E9-11d3-A1A5-0050041CAF44 */ \
0x5ba6d920, 0xd4e9, 0x11d3, { 0xa1, 0xa5, 0x0, 0x50, 0x4, 0x1c, 0xaf, 0x44 } \
}
%}

View File

@@ -0,0 +1,106 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsISupports.idl"
interface nsIRequest;
interface nsIEventQueue;
/**
* nsIStreamObserver
*
* @status UNDER_REVIEW
*/
[scriptable, uuid(fd91e2e0-1481-11d3-9333-00104ba0fd40)]
interface nsIStreamObserver : nsISupports
{
/**
* Called to signify the beginning of an asynchronous request.
*
* @param request - request being observed
* @param ctxt - user specified data passed to AsyncRead/Write
*/
void onStartRequest(in nsIRequest request,
in nsISupports ctxt);
/**
* Called to signify the end of an asynchronous request. This
* call is always preceded by a call to onStartRequest.
*
* @param request - request being observed
* @param ctxt - user specified data passed to AsyncRead/Write
* @param statusCode - reason for stopping (NS_OK if completed successfully)
* @param statusText - human readable reason for stopping (can be NULL)
*/
void onStopRequest(in nsIRequest request,
in nsISupports ctxt,
in nsresult statusCode,
in wstring statusText);
};
/**
* A stream observer proxy is used to ship data over to another thread specified
* by the thread's event queue. The "true" stream observer's methods are
* invoked on the other thread.
*
* This interface only provides the initialization needed after construction. Otherwise,
* these objects are used simply as nsIStreamObserver's.
*/
[scriptable, uuid(3c9b532e-db84-4ecf-aa6a-4d38a9c4c5f0)]
interface nsIStreamObserverProxy : nsIStreamObserver
{
/**
* Initializes an nsIStreamObserverProxy.
*
* @param observer - receives observer notifications on the other thread
* @param eventQ - may be NULL indicating the calling thread's event queue
*/
void init(in nsIStreamObserver observer,
in nsIEventQueue eventQ);
};
/**
* An asynchronous stream observer is used to ship data over to another thread specified
* by the thread's event queue. The receiver stream observer is then used to receive
* the notifications on the other thread.
*
* This interface only provides the initialization needed after construction. Otherwise,
* these objects are used simply as nsIStreamObservers.
*/
[scriptable, uuid(a28dc590-91b3-11d3-8cd9-0060b0fc14a3)]
interface nsIAsyncStreamObserver : nsIStreamObserver
{
/**
* Initializes an nsIAsyncStreamObserver.
* @param eventQueue - may be null indicating the calling thread's event queue
*/
void init(in nsIStreamObserver receiver,
in nsIEventQueue eventQueue);
};
%{C++
// Generic status codes for OnStopRequest:
#define NS_BINDING_SUCCEEDED NS_OK
#define NS_BINDING_FAILED NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 1)
#define NS_BINDING_ABORTED NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 2)
%}

View File

@@ -0,0 +1,100 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsIStreamObserver.idl"
interface nsIChannel;
interface nsIInputStream;
interface nsIOutputStream;
interface nsIEventQueue;
/**
* The nsIChannel::AsyncWrite notification handler. It provides
* data to the channel, when the channel is ready to accept it.
*/
[scriptable, uuid(d10ef7a9-b728-43d4-9c49-74172186d691)]
interface nsIStreamProvider : nsIStreamObserver
{
/**
* Called when data may be written to the channel.
*
* @param request - the request returned by AsyncWrite
* @param ctxt - opaque parameter passed to AsyncWrite
* @param output - output stream for writing data chunk
* @param offset - current stream position (informational)
* @param count - number of bytes that can be written without blocking
*
* @return NS_OK - if successfully wrote something.
* @return NS_BASE_STREAM_CLOSED - if done writing data. NOTE: this is
* NOT equivalent to writing zero bytes and returning NS_OK.
* @return NS_BASE_STREAM_WOULD_BLOCK - if no data can be written at
* this time. This implicitly calls Suspend on the channel. Call
* Resume on the channel to continue the AsyncWrite when more data
* becomes available.
* @return <other-error> - if failure.
*/
void onDataWritable(in nsIRequest request,
in nsISupports ctxt,
in nsIOutputStream output,
in unsigned long offset,
in unsigned long count);
};
/**
* A stream provider proxy is used to ship data over to another thread specified
* by the thread's event queue. The "true" stream provider's methods are
* invoked on the other thread.
*
* This interface only provides the initialization needed after construction.
* Otherwise, these objects may be used as a nsIStreamProvider.
*/
[scriptable, uuid(5c3b0bac-605a-49ac-880e-5c8b993f7d2b)]
interface nsIStreamProviderProxy : nsIStreamProvider
{
/**
* Initializes an nsIStreamProviderProxy.
*
* @param provider - receives provider notifications on the other thread.
* @param eventQ - may be NULL indicating the calling thread's event queue.
*/
void init(in nsIStreamProvider provider,
in nsIEventQueue eventQ,
in unsigned long bufferSegmentSize,
in unsigned long bufferMaxSize);
};
/**
* A simple stream provider can be used with AsyncWrite to supply data from
* an existing input stream.
*/
[scriptable, uuid(c20bb3b9-0755-4eff-9222-3537f9e89082)]
interface nsISimpleStreamProvider : nsIStreamProvider
{
/**
* Initialize the simple stream provider.
*
* @param - data will be read from this input stream to the channel
* @param - optional stream observer (can be NULL)
*/
void init(in nsIInputStream source,
in nsIStreamObserver observer);
};

View File

@@ -0,0 +1,120 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsISupports.idl"
#include "nsIRequest.idl"
interface nsIStreamListener;
interface nsIStreamProvider;
interface nsIInputStream;
interface nsIOutputStream;
interface nsIInterfaceRequestor;
[scriptable, uuid(fd01f9a4-d492-4cf8-b76e-160ffc8c01e8)]
interface nsITransport : nsISupports
{
/**
* Get security info for this transport.
*/
readonly attribute nsISupports securityInfo;
/**
* Get/set notificationCallbacks for this transport.
*/
readonly attribute nsIInterfaceRequestor notificationCallbacks;
void setNotificationCallbacks(in nsIInterfaceRequestor callbacks,
in boolean isBackground);
/**
* Open an input stream on this transport.
*
* @param offset - read starting at this offset
* @param count - read this many bytes (pass PRUint32(-1) if unlimited)
* @param flags - optional transport specific flags
*/
nsIInputStream openInputStream(in unsigned long offset,
in unsigned long count,
in unsigned long flags);
/**
* Open an output stream on this transport.
*
* @param offset - write starting at this offset
* @param count - write no more than this many bytes (pass PRUint32(-1) if unlimited)
* @param flags - optional transport specific flags
*/
nsIOutputStream openOutputStream(in unsigned long offset,
in unsigned long count,
in unsigned long flags);
/**
* Asynchronously read data from the transport.
*
* @param listener - notify this listener when data is available
* @param ctxt - opaque parameter passed to listener methods
* @param offset - read starting at this offset
* @param count - read this many bytes (pass PRUint32(-1) if unlimited)
* @param flags - optional transport specific flags
*/
nsIRequest asyncRead(in nsIStreamListener listener,
in nsISupports ctxt,
in unsigned long offset,
in unsigned long count,
in unsigned long flags);
/**
* Asynchronously write data to the transport.
*
* @param provider - notify this provider when data can be written
* @param ctxt - opaque parameter passed to provider methods
* @param offset - write starting at this offset
* @param count - write no more than this many bytes (pass PRUint32(-1) if unlimited)
* @param flags - optional transport specific flags
*/
nsIRequest asyncWrite(in nsIStreamProvider provider,
in nsISupports ctxt,
in unsigned long offset,
in unsigned long count,
in unsigned long flags);
/**
* Callbacks from asyncRead and asyncWrite may be proxied from a
* background thread (if one exists) to the thread which initiated
* the request. This is the expected behavior of such a nsITransport
* implementation. A caller of asyncRead or asyncWrite can explicitly
* ask the transport to not proxy the callback. The caller must then
* be prepared to handle callbacks on any thread.
*/
const unsigned long DONT_PROXY_STREAM_OBSERVER = 1 << 0;
const unsigned long DONT_PROXY_STREAM_LISTENER = 1 << 1;
const unsigned long DONT_PROXY_STREAM_PROVIDER = 1 << 1;
};
[scriptable, uuid(d7abf5a4-ce72-482a-9217-a219a905c019)]
interface nsITransportRequest : nsIRequest
{
/**
* Get the transport associated with this request.
*/
readonly attribute nsITransport transport;
};

View File

@@ -0,0 +1,195 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Original Author: Gagan Saksena <gagan@netscape.com>
*
* Contributor(s):
*/
#include "nsISupports.idl"
/**
* URIs are essentially structured names for things -- anything.
* This interface provides accessors to destructure those names.
*
* This interface follows Tim Berners-Lee's URI spec:
*
* http://www.w3.org/Addressing/URI/URI_Overview.html
*
* essentially:
*
* ftp://username:password@hostname:portnumber/pathname
* \ / \ / \ / \ /\ /
* - --------------- ------ -------- -------
* | | | | |
* | | | | Path
* | | | Port
* | | Host /
* | PreHost /
* Scheme /
* \ /
* --------------------------------
* |
* PrePath
*
* The subclass nsIURL provides a means to open an input or output
* stream to a URI as a source/destination, as well as providing additional
* accessors to destructure the path, query and reference portions typically
* associated with URLs.
*
* @status UNDER_REVIEW
*/
%{C++
#undef GetPort // XXX Windows!
#undef SetPort // XXX Windows!
#ifdef XP_OS2 // OS2 has UNKNOWN problems :)
#undef UNKNOWN
#endif
%}
[scriptable, uuid(07a22cc0-0ce5-11d3-9331-00104ba0fd40)]
interface nsIURI : nsISupports
{
/**
* Returns a string representation of the URI. Setting the spec
* causes the new spec to be parsed, initializing the URI. Setting
* the spec (or any of the accessors) causes also any currently
* open streams on the URI's channel to be closed.
*/
attribute string spec;
/**
* The prePath returns the stuff before the path
* (e.g. protocol://user:password@host:port/). This is useful for
* authentication, or managing sessions.
*/
attribute string prePath;
/**
* The Scheme is the protocol to which this URI refers. Setting
* the scheme is a special operation that builds up an equivalent
* URI string from the new scheme and all the other URI attributes
* and passes the it to the nsIOService to create a new URI for
* the new scheme.
*/
attribute string scheme;
/**
* The PreHost portion includes elements like the optional
* username:password, or maybe other scheme specific items.
*/
attribute string preHost;
attribute string username;
attribute string password;
/**
* The Host is the internet domain name to which this URI refers.
* Note that it could be an IP address as well.
*/
attribute string host;
/**
* A return value of -1 indicates that no port value is set and the
* implementor of the specific scheme will use its default port.
* Similarly setting a value of -1 indicates that the default is to be used.
* Thus as an example:
* for HTTP, Port 80 is same as a return value of -1.
* However after setting a port (even if its default), the port number will
* appear in the ToNewCString function.
*/
attribute long port;
/**
* Note that the path includes the leading '/' Thus if no path is
* available the Path accessor will return a "/"
* For SetPath if none is provided, one would be prefixed to the path.
*/
attribute string path;
/**
* Note that this comparison is only on char* level. Use
* the scheme specific URI to do a more thorough check. For example,
* in HTTP:
* http://foo.com:80 == http://foo.com
* but this function through nsIURI alone will not return equality
* for this case.
*/
boolean equals(in nsIURI other);
/**
* An optimization to do scheme checks without requiring the users of nsIURI
* to GetScheme thereby saving extra allocating and freeing. Returns true if
* the schemes match (case ignored). Note that for unknown cases this will
* always return false.
*/
boolean schemeIs(in string scheme);
/**
* Clones the current URI. The newly created URI will be in a closed
* state even if the underlying channel of the cloned URI is open.
* Cloning allows the current location to be retained since once the
* channel is opened the URI may get redirected to a new location.
*/
nsIURI clone();
/**
* This method resolves a relative string into an absolute URI string,
* using the URI as the base.
*
* This method subsumes the deprecated method nsIIOService::MakeAbsolute.
*/
string resolve(in string relativePath);
};
%{C++
// Malformed URI Error
#define NS_ERROR_MALFORMED_URI NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 10)
/**
* Protocol writers can obtain a very basic (ok, degenerate) implementation
* of nsIURI by calling the component manager with NS_SIMPLEURI_CID. The
* implementation returned will only parse things of the form:
*
* about:cache
* \ / \ /
* --- ---
* | |
* Scheme Path
*
* where the path is everything after the colon. Note that this is probably
* only useful for cases like about: or javascript: URIs.
*
* *** What you most likely will want is NS_STANDARDURL_CID which is much more
* full featured. Look at nsIURL.idl for more details.
*/
#define NS_SIMPLEURI_CID \
{ /* e0da1d70-2f7b-11d3-8cd0-0060b0fc14a3 */ \
0xe0da1d70, \
0x2f7b, \
0x11d3, \
{0x8c, 0xd0, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \
}
%}

View File

@@ -0,0 +1,161 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Original Author: Gagan Saksena <gagan@netscape.com>
*
* Contributor(s):
*/
#include "nsIURI.idl"
/**
* The nsIURL interface provides convenience methods that further
* break down the path portion of nsIURI:
*
* http://directory/fileBaseName.fileExtension?query
* http://directory/fileBaseName.fileExtension#ref
* http://directory/fileBaseName.fileExtension;param
* \ \ /
* \ -----------------------
* \ | /
* \ fileName /
* ----------------------------
* |
* filePath
*
* @status UNDER_REVIEW
*/
[scriptable, uuid(d6116970-8034-11d3-9399-00104ba0fd40)]
interface nsIURL : nsIURI
{
////////////////////////////////////////////////////////////////////////////
// The path attribute is broken down into the following attributes:
// filePath, param, query, and ref:
/**
* Returns a path including the directory and file portions of a
* URL. E.g. The filePath of "http://foo/bar.html#baz" is
* "/foo/bar.html".
*/
attribute string filePath;
/**
* Returns the parameters specified after the ; in the URL.
*
*/
attribute string param;
/**
* Returns the query portion (the part after the "?") of the URL.
* If there isn't one, an empty string is returned.
*/
attribute string query;
/**
* Returns the reference portion (the part after the "#") of the URL.
* If there isn't one, an empty string is returned.
*/
attribute string ref;
////////////////////////////////////////////////////////////////////////////
// The filePath attribute is further broken down into the following
// attributes: directory, file:
/**
* Returns the directory portion of a URL.
* If the URL denotes a path to a directory and not a file,
* e.g. http://foo/bar/, then the Directory attribute accesses
* the complete /foo/bar/ portion, and the FileName is the
* empty string. If the trailing slash is omitted, then the
* Directory is /foo/ and the file is bar (i.e. this is a
* syntactic, not a semantic breakdown of the Path).
* And hence dont rely on this for something to be a definitely
* be a file. But you can get just the leading directory portion
* for sure.
*/
attribute string directory;
/**
* Returns the file name portion of a URL.
* If the URL denotes a path to a directory and not a file,
* e.g. http://foo/bar/, then the Directory attribute accesses
* the complete /foo/bar/ portion, and the FileName is the
* empty string. Note that this is purely based on searching
* for the last trailing slash. And hence dont rely on this to
* be a definite file.
*/
attribute string fileName;
////////////////////////////////////////////////////////////////////////////
// The fileName attribute is further broken down into the following
// attributes: fileName, fileExtension:
attribute string fileBaseName;
/**
* Returns the file extension portion of a filename in a url.
* If a file extension does not exist, the empty string is returned.
*/
attribute string fileExtension;
/**
* Returns the query portion (the part after the "?") of the URL
* without unescaping the string.
* If there isn't one, an empty string is returned.
*/
readonly attribute string escapedQuery;
};
////////////////////////////////////////////////////////////////////////////////
/**
* Protocol writers can obtain a default nsIURL implementation by calling the
* component manager with NS_STANDARDURL_CID. The implementation returned will
* only implement the set of accessors specified by nsIURL. After obtaining the
* instance from the component manager, the Init routine must be called on it
* to initialize it from the user's URL spec.
*/
[scriptable, uuid(8793370a-311f-11d4-9876-00c04fa0cf4a)]
interface nsIStandardURL : nsISupports
{
const unsigned long URLTYPE_STANDARD = 1;
const unsigned long URLTYPE_AUTHORITY = 2;
const unsigned long URLTYPE_NO_AUTHORITY = 3;
void init(in unsigned long urlType,
in long defaultPort,
in string initialSpec,
in nsIURI initialBaseURI);
};
%{C++
#define NS_STANDARDURL_CID \
{ /* de9472d0-8034-11d3-9399-00104ba0fd40 */ \
0xde9472d0, \
0x8034, \
0x11d3, \
{0x93, 0x99, 0x00, 0x10, 0x4b, 0xa0, 0xfd, 0x40} \
}
%}
////////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,125 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Andreas Otte
*
* Contributor(s):
*/
#include "nsISupports.idl"
/**
* nsIURLParser is the abstract base class for parsing URLs
*/
[scriptable, uuid(4b4975f9-f128-47fd-b11e-88402233cbdf)]
interface nsIURLParser : nsISupports
{
/**
* Parses a URL and thinks it is parsing the scheme
*/
void ParseAtScheme(in string i_Spec,
out string o_Scheme,
out string o_Username,
out string o_Password,
out string o_Host,
out long o_Port,
out string o_Path);
/**
* Parses a URL and thinks it is parsing the prehost
*/
void ParseAtPreHost(in string i_Spec,
out string o_Username,
out string o_Password,
out string o_Host,
out long o_Port,
out string o_Path);
/**
* Parses a URL and thinks it is parsing the host
*/
void ParseAtHost(in string i_Spec,
out string o_Host,
out long o_Port,
out string o_Path);
/**
* Parses a URL and thinks it is parsing the port
*/
void ParseAtPort(in string i_Spec,
out long o_Port,
out string o_Path);
/**
* Parses a URL and thinks it is parsing the path
*/
void ParseAtPath(in string i_Spec,
out string o_Path);
/**
* Parses a URL-path and thinks it is parsing the directory
*/
void ParseAtDirectory(in string i_Path,
out string o_Directory,
out string o_FileBaseName,
out string o_FileExtension,
out string o_Param,
out string o_Query,
out string o_Ref);
/**
* Parses the URL-PreHost into its components
*/
void ParsePreHost(in string i_PreHost,
out string o_Username,
out string o_Password);
/**
* Parses the URL-Filename into its components
*/
void ParseFileName(in string i_FileName,
out string o_FileBaseName,
out string o_FileExtension);
};
%{C++
#define NS_STANDARDURLPARSER_CID \
{ /* dbf72351-4fd8-46f0-9dbc-fa5ba60a30c5 */ \
0xdbf72351, \
0x4fd8, \
0x46f0, \
{0x9d, 0xbc, 0xfa, 0x5b, 0xa6, 0x0a, 0x30, 0x5c} \
}
#define NS_AUTHORITYURLPARSER_CID \
{ /* 90012125-1616-4fa1-ae14-4e7fa5766eb6 */ \
0x90012125, \
0x1616, \
0x4fa1, \
{0xae, 0x14, 0x4e, 0x7f, 0xa5, 0x76, 0x6e, 0xb6} \
}
#define NS_NOAUTHORITYURLPARSER_CID \
{ /* 9eeb1b89-c87e-4404-9de6-dbd41aeaf3d7 */ \
0x9eeb1b89, \
0xc87e, \
0x4404, \
{0x9d, 0xe6, 0xdb, 0xd4, 0x1a, 0xea, 0xf3, 0xd7} \
}
%}

View File

@@ -0,0 +1,52 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
/**
* The nsIWebFilters is a simple interface for determining if the specified
* uri is allowed to load or not.
* - Gagan Saksena 05/04/00
*/
#include "nsISupports.idl"
interface nsIURI;
[scriptable, uuid(ee9d42f2-1dd1-11b2-b909-b34b63e205e8)]
interface nsIWebFilters : nsISupports
{
/**
* allowLoading the specified uri.
*/
boolean allowLoading(in nsIURI uri);
};
%{C++
#define NS_WEBFILTERS_CID \
{ /* 4677ea1e-1dd2-11b2-8654-e836efb6995c */ \
0x4677ea1e, \
0x1dd2, \
0x11b2, \
{0x86, 0x54, 0xe8, 0x36, 0xef, 0xb6, 0x99, 0x5c} \
}
#define NS_WEBFILTERS_CONTRACTID "@mozilla.org/network/filters;1"
%}

View File

@@ -0,0 +1,622 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsNetUtil_h__
#define nsNetUtil_h__
#include "nsIURI.h"
#include "netCore.h"
#include "nsIInputStream.h"
#include "nsIOutputStream.h"
#include "nsIStreamListener.h"
#include "nsIStreamProvider.h"
#include "nsILoadGroup.h"
#include "nsIInterfaceRequestor.h"
#include "nsString.h"
#include "nsReadableUtils.h"
#include "nsIIOService.h"
#include "nsIServiceManager.h"
#include "nsIChannel.h"
#include "nsIStreamIOChannel.h"
#include "nsITransport.h"
#include "nsMemory.h"
#include "nsCOMPtr.h"
#include "nsIHTTPProtocolHandler.h"
#include "nsIDownloader.h"
#include "nsIStreamLoader.h"
#include "nsIStreamIO.h"
#include "nsIPipe.h"
#include "nsXPIDLString.h"
#include "prio.h" // for read/write flags, permissions, etc.
#include "nsNetCID.h"
// Helper, to simplify getting the I/O service.
inline const nsGetServiceByCID
do_GetIOService(nsresult* error = 0)
{
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
return nsGetServiceByCID(kIOServiceCID, 0, error);
}
inline nsresult
NS_NewURI(nsIURI* *result,
const char* spec,
nsIURI* baseURI = nsnull,
nsIIOService* ioService = nsnull) // pass in nsIIOService to optimize callers
{
nsresult rv;
nsCOMPtr<nsIIOService> serv;
if (ioService == nsnull) {
serv = do_GetIOService(&rv);
if (NS_FAILED(rv)) return rv;
ioService = serv.get();
}
return ioService->NewURI(spec, baseURI, result);
}
inline nsresult
NS_NewURI(nsIURI* *result,
const nsAReadableString& spec,
nsIURI* baseURI = nsnull,
nsIIOService* ioService = nsnull) // pass in nsIIOService to optimize callers
{
char* specStr = ToNewUTF8String(spec); // this forces a single byte char*
if (specStr == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
nsresult rv = NS_NewURI(result, specStr, baseURI, ioService);
nsMemory::Free(specStr);
return rv;
}
inline nsresult
NS_OpenURI(nsIChannel* *result,
nsIURI* uri,
nsIIOService* ioService = nsnull, // pass in nsIIOService to optimize callers
nsILoadGroup* loadGroup = nsnull,
nsIInterfaceRequestor* notificationCallbacks = nsnull,
nsLoadFlags loadAttributes = NS_STATIC_CAST(nsLoadFlags, nsIChannel::LOAD_NORMAL))
{
nsresult rv;
nsCOMPtr<nsIIOService> serv;
if (ioService == nsnull) {
serv = do_GetIOService(&rv);
if (NS_FAILED(rv)) return rv;
ioService = serv.get();
}
nsIChannel* channel = nsnull;
rv = ioService->NewChannelFromURI(uri, &channel);
if (NS_FAILED(rv)) return rv;
if (loadGroup) {
rv = channel->SetLoadGroup(loadGroup);
if (NS_FAILED(rv)) return rv;
}
if (notificationCallbacks) {
rv = channel->SetNotificationCallbacks(notificationCallbacks);
if (NS_FAILED(rv)) return rv;
}
if (loadAttributes != nsIChannel::LOAD_NORMAL) {
rv = channel->SetLoadAttributes(loadAttributes);
if (NS_FAILED(rv)) return rv;
}
*result = channel;
return rv;
}
// Use this function with CAUTION. And do not use it on
// the UI thread. It creates a stream that blocks when
// you Read() from it and blocking the UI thread is
// illegal. If you don't want to implement a full
// blown asyncrhonous consumer (via nsIStreamListener)
// look at nsIStreamLoader instead.
inline nsresult
NS_OpenURI(nsIInputStream* *result,
nsIURI* uri,
nsIIOService* ioService = nsnull, // pass in nsIIOService to optimize callers
nsILoadGroup* loadGroup = nsnull,
nsIInterfaceRequestor* notificationCallbacks = nsnull,
nsLoadFlags loadAttributes = NS_STATIC_CAST(nsLoadFlags, nsIChannel::LOAD_NORMAL))
{
nsresult rv;
nsCOMPtr<nsIChannel> channel;
rv = NS_OpenURI(getter_AddRefs(channel), uri, ioService,
loadGroup, notificationCallbacks, loadAttributes);
if (NS_FAILED(rv)) return rv;
nsIInputStream* inStr;
rv = channel->Open(&inStr);
if (NS_FAILED(rv)) return rv;
*result = inStr;
return rv;
}
inline nsresult
NS_OpenURI(nsIStreamListener* aConsumer,
nsISupports* context,
nsIURI* uri,
nsIIOService* ioService = nsnull, // pass in nsIIOService to optimize callers
nsILoadGroup* loadGroup = nsnull,
nsIInterfaceRequestor* notificationCallbacks = nsnull,
nsLoadFlags loadAttributes = NS_STATIC_CAST(nsLoadFlags, nsIChannel::LOAD_NORMAL))
{
nsresult rv;
nsCOMPtr<nsIChannel> channel;
rv = NS_OpenURI(getter_AddRefs(channel), uri, ioService,
loadGroup, notificationCallbacks, loadAttributes);
if (NS_FAILED(rv)) return rv;
rv = channel->AsyncOpen(aConsumer, context);
return rv;
}
inline nsresult
NS_MakeAbsoluteURI(char* *result,
const char* spec,
nsIURI* baseURI = nsnull,
nsIIOService* ioService = nsnull) // pass in nsIIOService to optimize callers
{
NS_ASSERTION(baseURI, "It doesn't make sense to not supply a base URI");
if (spec == nsnull)
return baseURI->GetSpec(result);
return baseURI->Resolve(spec, result);
}
inline nsresult
NS_MakeAbsoluteURI(nsAWritableString& result,
const nsAReadableString& spec,
nsIURI* baseURI = nsnull,
nsIIOService* ioService = nsnull) // pass in nsIIOService to optimize callers
{
char* resultStr;
char* specStr = ToNewUTF8String(spec);
if (!specStr) {
return NS_ERROR_OUT_OF_MEMORY;
}
nsresult rv = NS_MakeAbsoluteURI(&resultStr, specStr, baseURI, ioService);
nsMemory::Free(specStr);
if (NS_FAILED(rv)) return rv;
result.Assign(NS_ConvertUTF8toUCS2(resultStr));
nsMemory::Free(resultStr);
return rv;
}
inline nsresult
NS_NewPostDataStream(nsIInputStream **result,
PRBool isFile,
const char *data,
PRUint32 encodeFlags,
nsIIOService* ioService = nsnull) // pass in nsIIOService to optimize callers
{
nsresult rv;
nsCOMPtr<nsIIOService> serv;
if (ioService == nsnull) {
serv = do_GetIOService(&rv);
if (NS_FAILED(rv)) return rv;
ioService = serv.get();
}
nsCOMPtr<nsIProtocolHandler> handler;
rv = ioService->GetProtocolHandler("http", getter_AddRefs(handler));
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIHTTPProtocolHandler> http = do_QueryInterface(handler, &rv);
if (NS_FAILED(rv)) return rv;
return http->NewPostDataStream(isFile, data, encodeFlags, result);
}
inline nsresult
NS_NewStreamIOChannel(nsIStreamIOChannel **result,
nsIURI* uri,
nsIStreamIO* io)
{
nsresult rv;
nsCOMPtr<nsIStreamIOChannel> channel;
static NS_DEFINE_CID(kStreamIOChannelCID, NS_STREAMIOCHANNEL_CID);
rv = nsComponentManager::CreateInstance(kStreamIOChannelCID,
nsnull,
NS_GET_IID(nsIStreamIOChannel),
getter_AddRefs(channel));
if (NS_FAILED(rv)) return rv;
rv = channel->Init(uri, io);
if (NS_FAILED(rv)) return rv;
*result = channel;
NS_ADDREF(*result);
return NS_OK;
}
inline nsresult
NS_NewInputStreamChannel(nsIChannel **result,
nsIURI* uri,
nsIInputStream* inStr,
const char* contentType,
PRInt32 contentLength)
{
nsresult rv;
nsXPIDLCString spec;
rv = uri->GetSpec(getter_Copies(spec));
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIInputStreamIO> io;
rv = NS_NewInputStreamIO(getter_AddRefs(io), spec, inStr,
contentType, contentLength);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIStreamIOChannel> channel;
rv = NS_NewStreamIOChannel(getter_AddRefs(channel), uri, io);
if (NS_FAILED(rv)) return rv;
*result = channel;
NS_ADDREF(*result);
return NS_OK;
}
inline nsresult
NS_NewLoadGroup(nsILoadGroup* *result, nsIStreamObserver* obs)
{
nsresult rv;
nsCOMPtr<nsILoadGroup> group;
static NS_DEFINE_CID(kLoadGroupCID, NS_LOADGROUP_CID);
rv = nsComponentManager::CreateInstance(kLoadGroupCID, nsnull,
NS_GET_IID(nsILoadGroup),
getter_AddRefs(group));
if (NS_FAILED(rv)) return rv;
rv = group->Init(obs);
if (NS_FAILED(rv)) return rv;
*result = group;
NS_ADDREF(*result);
return NS_OK;
}
inline nsresult
NS_NewDownloader(nsIDownloader* *result,
nsIURI* uri,
nsIDownloadObserver* observer,
nsISupports* context = nsnull,
PRBool synchronous = PR_FALSE,
nsILoadGroup* loadGroup = nsnull,
nsIInterfaceRequestor* notificationCallbacks = nsnull,
nsLoadFlags loadAttributes = NS_STATIC_CAST(nsLoadFlags, nsIChannel::LOAD_NORMAL))
{
nsresult rv;
nsCOMPtr<nsIDownloader> downloader;
static NS_DEFINE_CID(kDownloaderCID, NS_DOWNLOADER_CID);
rv = nsComponentManager::CreateInstance(kDownloaderCID,
nsnull,
NS_GET_IID(nsIDownloader),
getter_AddRefs(downloader));
if (NS_FAILED(rv)) return rv;
rv = downloader->Init(uri, observer, context, synchronous, loadGroup,
notificationCallbacks, loadAttributes);
if (NS_FAILED(rv)) return rv;
*result = downloader;
NS_ADDREF(*result);
return rv;
}
inline nsresult
NS_NewStreamLoader(nsIStreamLoader* *result,
nsIURI* uri,
nsIStreamLoaderObserver* observer,
nsISupports* context = nsnull,
nsILoadGroup* loadGroup = nsnull,
nsIInterfaceRequestor* notificationCallbacks = nsnull,
nsLoadFlags loadAttributes = NS_STATIC_CAST(nsLoadFlags, nsIChannel::LOAD_NORMAL))
{
nsresult rv;
nsCOMPtr<nsIStreamLoader> loader;
static NS_DEFINE_CID(kStreamLoaderCID, NS_STREAMLOADER_CID);
rv = nsComponentManager::CreateInstance(kStreamLoaderCID,
nsnull,
NS_GET_IID(nsIStreamLoader),
getter_AddRefs(loader));
if (NS_FAILED(rv)) return rv;
rv = loader->Init(uri, observer, context, loadGroup,
notificationCallbacks, loadAttributes);
if (NS_FAILED(rv)) return rv;
*result = loader;
NS_ADDREF(*result);
return rv;
}
inline nsresult
NS_NewStreamObserverProxy(nsIStreamObserver **aResult,
nsIStreamObserver *aObserver,
nsIEventQueue *aEventQ=nsnull)
{
NS_ENSURE_ARG_POINTER(aResult);
nsresult rv;
nsCOMPtr<nsIStreamObserverProxy> proxy;
static NS_DEFINE_CID(kStreamObserverProxyCID, NS_STREAMOBSERVERPROXY_CID);
rv = nsComponentManager::CreateInstance(kStreamObserverProxyCID,
nsnull,
NS_GET_IID(nsIStreamObserverProxy),
getter_AddRefs(proxy));
if (NS_FAILED(rv)) return rv;
rv = proxy->Init(aObserver, aEventQ);
if (NS_FAILED(rv)) return rv;
return CallQueryInterface(proxy, aResult);
}
inline nsresult
NS_NewStreamListenerProxy(nsIStreamListener **aResult,
nsIStreamListener *aListener,
nsIEventQueue *aEventQ=nsnull,
PRUint32 aBufferSegmentSize=0,
PRUint32 aBufferMaxSize=0)
{
NS_ENSURE_ARG_POINTER(aResult);
nsresult rv;
nsCOMPtr<nsIStreamListenerProxy> proxy;
static NS_DEFINE_CID(kStreamListenerProxyCID, NS_STREAMLISTENERPROXY_CID);
rv = nsComponentManager::CreateInstance(kStreamListenerProxyCID,
nsnull,
NS_GET_IID(nsIStreamListenerProxy),
getter_AddRefs(proxy));
if (NS_FAILED(rv)) return rv;
rv = proxy->Init(aListener, aEventQ, aBufferSegmentSize, aBufferMaxSize);
if (NS_FAILED(rv)) return rv;
NS_ADDREF(*aResult = proxy);
return NS_OK;
}
inline nsresult
NS_NewStreamProviderProxy(nsIStreamProvider **aResult,
nsIStreamProvider *aProvider,
nsIEventQueue *aEventQ=nsnull,
PRUint32 aBufferSegmentSize=0,
PRUint32 aBufferMaxSize=0)
{
NS_ENSURE_ARG_POINTER(aResult);
nsresult rv;
nsCOMPtr<nsIStreamProviderProxy> proxy;
static NS_DEFINE_CID(kStreamProviderProxyCID, NS_STREAMPROVIDERPROXY_CID);
rv = nsComponentManager::CreateInstance(kStreamProviderProxyCID,
nsnull,
NS_GET_IID(nsIStreamProviderProxy),
getter_AddRefs(proxy));
if (NS_FAILED(rv)) return rv;
rv = proxy->Init(aProvider, aEventQ, aBufferSegmentSize, aBufferMaxSize);
if (NS_FAILED(rv)) return rv;
NS_ADDREF(*aResult = proxy);
return NS_OK;
}
inline nsresult
NS_NewSimpleStreamListener(nsIStreamListener **aResult,
nsIOutputStream *aSink,
nsIStreamObserver *aObserver=nsnull)
{
NS_ENSURE_ARG_POINTER(aResult);
nsresult rv;
nsCOMPtr<nsISimpleStreamListener> listener;
static NS_DEFINE_CID(kSimpleStreamListenerCID, NS_SIMPLESTREAMLISTENER_CID);
rv = nsComponentManager::CreateInstance(kSimpleStreamListenerCID,
nsnull,
NS_GET_IID(nsISimpleStreamListener),
getter_AddRefs(listener));
if (NS_FAILED(rv)) return rv;
rv = listener->Init(aSink, aObserver);
if (NS_FAILED(rv)) return rv;
NS_ADDREF(*aResult = listener);
return NS_OK;
}
inline nsresult
NS_NewSimpleStreamProvider(nsIStreamProvider **aResult,
nsIInputStream *aSource,
nsIStreamObserver *aObserver=nsnull)
{
NS_ENSURE_ARG_POINTER(aResult);
nsresult rv;
nsCOMPtr<nsISimpleStreamProvider> provider;
static NS_DEFINE_CID(kSimpleStreamProviderCID, NS_SIMPLESTREAMPROVIDER_CID);
rv = nsComponentManager::CreateInstance(kSimpleStreamProviderCID,
nsnull,
NS_GET_IID(nsISimpleStreamProvider),
getter_AddRefs(provider));
if (NS_FAILED(rv)) return rv;
rv = provider->Init(aSource, aObserver);
if (NS_FAILED(rv)) return rv;
NS_ADDREF(*aResult = provider);
return NS_OK;
}
// Depracated, prefer NS_NewStreamObserverProxy
inline nsresult
NS_NewAsyncStreamObserver(nsIStreamObserver **result,
nsIStreamObserver *receiver,
nsIEventQueue *eventQueue)
{
nsresult rv;
nsCOMPtr<nsIAsyncStreamObserver> obs;
static NS_DEFINE_CID(kAsyncStreamObserverCID, NS_ASYNCSTREAMOBSERVER_CID);
rv = nsComponentManager::CreateInstance(kAsyncStreamObserverCID,
nsnull,
NS_GET_IID(nsIAsyncStreamObserver),
getter_AddRefs(obs));
if (NS_FAILED(rv)) return rv;
rv = obs->Init(receiver, eventQueue);
if (NS_FAILED(rv)) return rv;
NS_ADDREF(*result = obs);
return NS_OK;
}
// Depracated, prefer NS_NewStreamListenerProxy
inline nsresult
NS_NewAsyncStreamListener(nsIStreamListener **result,
nsIStreamListener *receiver,
nsIEventQueue *eventQueue)
{
nsresult rv;
nsCOMPtr<nsIAsyncStreamListener> lsnr;
static NS_DEFINE_CID(kAsyncStreamListenerCID, NS_ASYNCSTREAMLISTENER_CID);
rv = nsComponentManager::CreateInstance(kAsyncStreamListenerCID,
nsnull,
NS_GET_IID(nsIAsyncStreamListener),
getter_AddRefs(lsnr));
if (NS_FAILED(rv)) return rv;
rv = lsnr->Init(receiver, eventQueue);
if (NS_FAILED(rv)) return rv;
NS_ADDREF(*result = lsnr);
return NS_OK;
}
// Depracated, prefer a true synchonous implementation
inline nsresult
NS_NewSyncStreamListener(nsIInputStream **aInStream,
nsIOutputStream **aOutStream,
nsIStreamListener **aResult)
{
nsresult rv;
NS_ENSURE_ARG_POINTER(aInStream);
NS_ENSURE_ARG_POINTER(aOutStream);
nsCOMPtr<nsIInputStream> pipeIn;
nsCOMPtr<nsIOutputStream> pipeOut;
rv = NS_NewPipe(getter_AddRefs(pipeIn),
getter_AddRefs(pipeOut),
4*1024, // NS_SYNC_STREAM_LISTENER_SEGMENT_SIZE
32*1024); // NS_SYNC_STREAM_LISTENER_BUFFER_SIZE
if (NS_FAILED(rv)) return rv;
rv = NS_NewSimpleStreamListener(aResult, pipeOut);
if (NS_FAILED(rv)) return rv;
NS_ADDREF(*aInStream = pipeIn);
NS_ADDREF(*aOutStream = pipeOut);
return NS_OK;
}
//
// Calls AsyncWrite on the specified transport, with a stream provider that
// reads data from the specified input stream.
//
inline nsresult
NS_AsyncWriteFromStream(nsIRequest **aRequest,
nsITransport *aTransport,
nsIInputStream *aSource,
PRUint32 aOffset=0,
PRUint32 aCount=0,
PRUint32 aFlags=0,
nsIStreamObserver *aObserver=NULL,
nsISupports *aContext=NULL)
{
NS_ENSURE_ARG_POINTER(aTransport);
nsresult rv;
nsCOMPtr<nsIStreamProvider> provider;
rv = NS_NewSimpleStreamProvider(getter_AddRefs(provider),
aSource,
aObserver);
if (NS_FAILED(rv)) return rv;
//
// We can safely allow the transport impl to bypass proxying the provider
// since we are using a simple stream provider.
//
// A simple stream provider masks the OnDataWritable from consumers.
// Moreover, it makes an assumption about the underlying nsIInputStream
// implementation: namely, that it is thread-safe and blocking.
//
// So, let's always make this optimization.
//
aFlags |= nsITransport::DONT_PROXY_STREAM_PROVIDER;
return aTransport->AsyncWrite(provider, aContext,
aOffset,
aCount,
aFlags,
getter_AddRefs(aRequest));
}
//
// Calls AsyncRead on the specified transport, with a stream listener that
// writes data to the specified output stream.
//
inline nsresult
NS_AsyncReadToStream(nsIRequest **aRequest,
nsITransport *aTransport,
nsIOutputStream *aSink,
PRUint32 aOffset=0,
PRUint32 aCount=0,
PRUint32 aFlags=0,
nsIStreamObserver *aObserver=NULL,
nsISupports *aContext=NULL)
{
NS_ENSURE_ARG_POINTER(aTransport);
nsresult rv;
nsCOMPtr<nsIStreamListener> listener;
rv = NS_NewSimpleStreamListener(getter_AddRefs(listener),
aSink,
aObserver);
if (NS_FAILED(rv)) return rv;
return aTransport->AsyncRead(listener, aContext,
aOffset,
aCount,
aFlags,
getter_AddRefs(aRequest));
}
#endif // nsNetUtil_h__

View File

@@ -0,0 +1,100 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef _nsUnixColorPrintf_h_
#define _nsUnixColorPrintf_h_
#if defined(XP_UNIX) && defined(NS_DEBUG)
#define STARTGRAY "\033[1;30m"
#define STARTRED "\033[1;31m"
#define STARTGREEN "\033[1;32m"
#define STARTYELLOW "\033[1;33m"
#define STARTBLUE "\033[1;34m"
#define STARTMAGENTA "\033[1;35m"
#define STARTCYAN "\033[1;36m"
#define STARTUNDERLINE "\033[4m"
#define STARTREVERSE "\033[7m"
#define ENDCOLOR "\033[0m"
#define PRINTF_GRAY nsUnixColorPrintf __color_printf(STARTGREY)
#define PRINTF_RED nsUnixColorPrintf __color_printf(STARTRED)
#define PRINTF_GREEN nsUnixColorPrintf __color_printf(STARTGREEN)
#define PRINTF_YELLOW nsUnixColorPrintf __color_printf(STARTYELLOW)
#define PRINTF_BLUE nsUnixColorPrintf __color_printf(STARTBLUE)
#define PRINTF_MAGENTA nsUnixColorPrintf __color_printf(STARTMAGENTA)
#define PRINTF_CYAN nsUnixColorPrintf __color_printf(STARTCYAN)
#define PRINTF_UNDERLINE nsUnixColorPrintf __color_printf(STARTUNDERLINE)
#define PRINTF_REVERSE nsUnixColorPrintf __color_printf(STARTREVERSE)
/*
The nsUnixColorPrintf is a handy set of color term codes to change
the color of console texts for easier spotting. As of now this is
Unix and Debug only.
Usage is simple.
See examples in
mozilla/netwerk/protocol/http/src/nsHTTPHandler.cpp
-Gagan Saksena 11/01/99
*/
class nsUnixColorPrintf
{
public:
nsUnixColorPrintf(const char* colorCode)
{
printf("%s",colorCode);
}
~nsUnixColorPrintf()
{
printf("%s",ENDCOLOR);
}
};
#else // XP_UNIX
#define STARTGRAY ""
#define STARTRED ""
#define STARTGREEN ""
#define STARTYELLOW ""
#define STARTBLUE ""
#define STARTMAGENTA ""
#define STARTCYAN ""
#define STARTUNDERLINE ""
#define STARTREVERSE ""
#define ENDCOLOR ""
#define PRINTF_GRAY
#define PRINTF_RED
#define PRINTF_GREEN
#define PRINTF_YELLOW
#define PRINTF_BLUE
#define PRINTF_MAGENTA
#define PRINTF_CYAN
#define PRINTF_UNDERLINE
#define PRINTF_REVERSE
#endif // XP_UNIX
#endif // nsUnixColorPrintf

View File

@@ -0,0 +1,15 @@
pref("general.useragent.security", "U");
pref("security.enable_ssl2", true);
pref("security.enable_ssl3", true);
pref("security.default_personal_cert", "Select Automatically");
pref("security.ask_for_password", 0);
pref("security.password_lifetime", 30);
pref("security.warn_entering_secure", true);
pref("security.warn_leaving_secure", true);
pref("security.warn_viewing_mixed", true);
pref("security.warn_submit_insecure", true);
pref("security.ui.enable", true);

View File

@@ -0,0 +1,72 @@
#
# The contents of this file are subject to the Netscape 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/NPL/
#
# 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 Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
#
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = necko
LIBRARY_NAME = neckobase_s
REQUIRES = xpcom string exthandler mimetype intl locale nkcache pref
CPPSRCS = \
nsURLHelper.cpp \
nsFileStreams.cpp \
nsBufferedStreams.cpp \
nsIOService.cpp \
nsSocketTransport.cpp \
nsSocketTransportService.cpp \
nsFileTransport.cpp \
nsFileTransportService.cpp \
nsSimpleStreamListener.cpp \
nsSimpleStreamProvider.cpp \
nsStreamObserverProxy.cpp \
nsStreamListenerProxy.cpp \
nsStreamProviderProxy.cpp \
nsStdURLParser.cpp \
nsAuthURLParser.cpp \
nsNoAuthURLParser.cpp \
nsStdURL.cpp \
nsSimpleURI.cpp \
nsNetModuleMgr.cpp \
nsNetModRegEntry.cpp \
nsLoadGroup.cpp \
nsInputStreamChannel.cpp \
nsDirectoryIndexStream.cpp \
nsStreamLoader.cpp \
nsDownloader.cpp \
nsProtocolProxyService.cpp \
nsProxyAutoConfigUtils.cpp \
nsAsyncStreamListener.cpp \
nsStorageTransport.cpp \
nsStreamListenerTee.cpp \
$(NULL)
# we don't want the shared lib, but we want to force the creation of a
# static lib.
override NO_SHARED_LIB=1
override NO_STATIC_LIB=
include $(topsrcdir)/config/rules.mk

View File

@@ -0,0 +1,72 @@
# The contents of this file are subject to the Netscape 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/NPL/
#
# 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 Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
MODULE = necko
DEPTH = ..\..\..
include <$(DEPTH)/config/config.mak>
LCFLAGS = -DWIN32_LEAN_AND_MEAN -D_IMPL_NS_NET
LIBRARY_NAME=neckobase_s
CPP_OBJS = \
.\$(OBJDIR)\nsURLHelper.obj \
.\$(OBJDIR)\nsFileStreams.obj \
.\$(OBJDIR)\nsBufferedStreams.obj \
.\$(OBJDIR)\nsIOService.obj \
.\$(OBJDIR)\nsSocketTransport.obj \
.\$(OBJDIR)\nsSocketTransportService.obj \
.\$(OBJDIR)\nsFileTransport.obj \
.\$(OBJDIR)\nsFileTransportService.obj \
.\$(OBJDIR)\nsSimpleStreamListener.obj \
.\$(OBJDIR)\nsSimpleStreamProvider.obj \
.\$(OBJDIR)\nsStreamObserverProxy.obj \
.\$(OBJDIR)\nsStreamListenerProxy.obj \
.\$(OBJDIR)\nsStreamProviderProxy.obj \
.\$(OBJDIR)\nsStdURLParser.obj \
.\$(OBJDIR)\nsAuthURLParser.obj \
.\$(OBJDIR)\nsNoAuthURLParser.obj \
.\$(OBJDIR)\nsStdURL.obj \
.\$(OBJDIR)\nsSimpleURI.obj \
.\$(OBJDIR)\nsNetModuleMgr.obj \
.\$(OBJDIR)\nsNetModRegEntry.obj \
.\$(OBJDIR)\nsLoadGroup.obj \
.\$(OBJDIR)\nsInputStreamChannel.obj \
.\$(OBJDIR)\nsDirectoryIndexStream.obj \
.\$(OBJDIR)\nsStreamLoader.obj \
.\$(OBJDIR)\nsDownloader.obj \
.\$(OBJDIR)\nsProtocolProxyService.obj \
.\$(OBJDIR)\nsProxyAutoConfigUtils.obj \
.\$(OBJDIR)\nsAsyncStreamListener.obj \
.\$(OBJDIR)\nsStorageTransport.obj \
.\$(OBJDIR)\nsStreamListenerTee.obj \
$(NULL)
INCS = $(INCS) \
-I$(DEPTH)\dist\include \
$(NULL)
include <$(DEPTH)\config\rules.mak>
install:: $(LIBRARY)
$(MAKE_INSTALL) $(LIBRARY) $(DIST)\lib
clobber::
$(RM) $(DIST)\lib\$(LIBRARY_NAME).lib

View File

@@ -0,0 +1,483 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsAsyncStreamListener.h"
#include "nsIInputStream.h"
#include "nsString.h"
#include "nsCRT.h"
#include "nsIEventQueueService.h"
#include "nsIIOService.h"
#include "nsIServiceManager.h"
#include "nsIChannel.h"
#include "prlog.h"
static NS_DEFINE_CID(kEventQueueService, NS_EVENTQUEUESERVICE_CID);
#if defined(PR_LOGGING)
PRLogModuleInfo* gStreamEventLog = 0;
#endif
// prevent name conflicts
#define nsStreamListenerEvent nsStreamListenerEvent0
#define nsOnStartRequestEvent nsOnStartRequestEvent0
#define nsOnStopRequestEvent nsOnStopRequestEvent0
#define nsOnDataAvailableEvent nsOnDataAvailableEvent0
////////////////////////////////////////////////////////////////////////////////
class nsStreamListenerEvent
{
public:
nsStreamListenerEvent(nsAsyncStreamObserver* listener,
nsIRequest* request, nsISupports* context);
virtual ~nsStreamListenerEvent();
nsresult Fire(nsIEventQueue* aEventQ);
NS_IMETHOD HandleEvent() = 0;
protected:
static void PR_CALLBACK HandlePLEvent(PLEvent* aEvent);
static void PR_CALLBACK DestroyPLEvent(PLEvent* aEvent);
nsAsyncStreamObserver* mListener;
nsIRequest* mRequest;
nsISupports* mContext;
PLEvent mEvent;
};
#define GET_STREAM_LISTENER_EVENT(_this) \
((nsStreamListenerEvent*)((char*)(_this) - offsetof(nsStreamListenerEvent, mEvent)))
////////////////////////////////////////////////////////////////////////////////
nsStreamListenerEvent::nsStreamListenerEvent(nsAsyncStreamObserver* listener,
nsIRequest* request, nsISupports* context)
: mListener(listener), mRequest(request), mContext(context)
{
MOZ_COUNT_CTOR(nsStreamListenerEvent);
NS_IF_ADDREF(mListener);
NS_IF_ADDREF(mRequest);
NS_IF_ADDREF(mContext);
}
nsStreamListenerEvent::~nsStreamListenerEvent()
{
MOZ_COUNT_DTOR(nsStreamListenerEvent);
NS_IF_RELEASE(mListener);
NS_IF_RELEASE(mRequest);
NS_IF_RELEASE(mContext);
}
void PR_CALLBACK nsStreamListenerEvent::HandlePLEvent(PLEvent* aEvent)
{
nsStreamListenerEvent* ev = GET_STREAM_LISTENER_EVENT(aEvent);
NS_ASSERTION(nsnull != ev,"null event.");
nsresult rv = ev->HandleEvent();
//
// If the consumer fails, then cancel the transport. This is necessary
// in case where the socket transport is blocked waiting for room in the
// pipe, but the consumer fails without consuming all the data.
//
// Unless the transport is cancelled, it will block forever, waiting for
// the pipe to empty...
//
if (NS_FAILED(rv)) {
nsresult cancelRv = ev->mRequest->Cancel(rv);
NS_ASSERTION(NS_SUCCEEDED(cancelRv), "Cancel failed");
}
}
void PR_CALLBACK nsStreamListenerEvent::DestroyPLEvent(PLEvent* aEvent)
{
nsStreamListenerEvent* ev = GET_STREAM_LISTENER_EVENT(aEvent);
NS_ASSERTION(nsnull != ev, "null event.");
delete ev;
}
nsresult
nsStreamListenerEvent::Fire(nsIEventQueue* aEventQueue)
{
NS_PRECONDITION(nsnull != aEventQueue, "nsIEventQueue for thread is null");
PL_InitEvent(&mEvent,
nsnull,
(PLHandleEventProc) nsStreamListenerEvent::HandlePLEvent,
(PLDestroyEventProc) nsStreamListenerEvent::DestroyPLEvent);
PRStatus status = aEventQueue->PostEvent(&mEvent);
return status == PR_SUCCESS ? NS_OK : NS_ERROR_FAILURE;
}
////////////////////////////////////////////////////////////////////////////////
NS_IMPL_THREADSAFE_ISUPPORTS2(nsAsyncStreamObserver,
nsIAsyncStreamObserver,
nsIStreamObserver)
NS_IMPL_ADDREF_INHERITED(nsAsyncStreamListener, nsAsyncStreamObserver);
NS_IMPL_RELEASE_INHERITED(nsAsyncStreamListener, nsAsyncStreamObserver);
NS_IMETHODIMP
nsAsyncStreamListener::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
if (!aInstancePtr) return NS_ERROR_NULL_POINTER;
if (aIID.Equals(NS_GET_IID(nsIAsyncStreamListener))) {
*aInstancePtr = NS_STATIC_CAST(nsIAsyncStreamListener*, this);
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(NS_GET_IID(nsIStreamListener))) {
*aInstancePtr = NS_STATIC_CAST(nsIStreamListener*, this);
NS_ADDREF_THIS();
return NS_OK;
}
return nsAsyncStreamObserver::QueryInterface(aIID, aInstancePtr);
}
NS_IMETHODIMP
nsAsyncStreamObserver::Init(nsIStreamObserver* aObserver, nsIEventQueue* aEventQ)
{
nsresult rv = NS_OK;
NS_ASSERTION(aObserver, "null observer");
mReceiver = aObserver;
NS_WITH_SERVICE(nsIEventQueueService, eventQService, kEventQueueService, &rv);
if (NS_FAILED(rv))
return rv;
rv = eventQService->ResolveEventQueue(aEventQ, getter_AddRefs(mEventQueue));
return rv;
}
////////////////////////////////////////////////////////////////////////////////
//
// OnStartRequest...
//
////////////////////////////////////////////////////////////////////////////////
class nsOnStartRequestEvent : public nsStreamListenerEvent
{
public:
nsOnStartRequestEvent(nsAsyncStreamObserver* listener,
nsIRequest* request, nsISupports* context)
: nsStreamListenerEvent(listener, request, context) {}
virtual ~nsOnStartRequestEvent() {}
NS_IMETHOD HandleEvent();
};
NS_IMETHODIMP
nsOnStartRequestEvent::HandleEvent()
{
#if defined(PR_LOGGING)
if (!gStreamEventLog)
gStreamEventLog = PR_NewLogModule("netlibStreamEvent");
PR_LOG(gStreamEventLog, PR_LOG_DEBUG,
("netlibEvent: Handle Start [event=%x]", this));
#endif
nsIStreamObserver* receiver = (nsIStreamObserver*)mListener->GetReceiver();
if (receiver == nsnull) {
// must have already called OnStopRequest (it clears the receiver)
return NS_ERROR_FAILURE;
}
nsresult status;
nsresult rv = mRequest->GetStatus(&status);
NS_ASSERTION(NS_SUCCEEDED(rv), "GetStatus failed");
rv = receiver->OnStartRequest(mRequest, mContext);
return rv;
}
NS_IMETHODIMP
nsAsyncStreamObserver::OnStartRequest(nsIRequest *request, nsISupports* context)
{
nsresult rv;
nsOnStartRequestEvent* event =
new nsOnStartRequestEvent(this, request, context);
if (event == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
#if defined(PR_LOGGING)
PLEventQueue *equeue;
mEventQueue->GetPLEventQueue(&equeue);
char ts[80];
sprintf(ts, "nsAsyncStreamObserver: Start [this=%lx queue=%lx",
(long)this, (long)equeue);
if (!gStreamEventLog)
gStreamEventLog = PR_NewLogModule("netlibStreamEvent");
PR_LOG(gStreamEventLog, PR_LOG_DEBUG,
("nsAsyncStreamObserver: Start [this=%x queue=%x event=%x]",
this, equeue, event));
#endif
rv = event->Fire(mEventQueue);
if (NS_FAILED(rv)) goto failed;
return rv;
failed:
delete event;
return rv;
}
////////////////////////////////////////////////////////////////////////////////
//
// OnStopRequest
//
////////////////////////////////////////////////////////////////////////////////
class nsOnStopRequestEvent : public nsStreamListenerEvent
{
public:
nsOnStopRequestEvent(nsAsyncStreamObserver* listener,
nsISupports* context, nsIRequest* request)
: nsStreamListenerEvent(listener, request, context),
mStatus(NS_OK) {}
virtual ~nsOnStopRequestEvent();
nsresult Init(nsresult aStatus, const PRUnichar* aStatusArg);
NS_IMETHOD HandleEvent();
protected:
nsresult mStatus;
nsString mStatusArg;
};
nsOnStopRequestEvent::~nsOnStopRequestEvent()
{
}
nsresult
nsOnStopRequestEvent::Init(nsresult aStatus, const PRUnichar* aStatusArg)
{
mStatus = aStatus;
mStatusArg = aStatusArg;
return NS_OK;
}
NS_IMETHODIMP
nsOnStopRequestEvent::HandleEvent()
{
#if defined(PR_LOGGING)
if (!gStreamEventLog)
gStreamEventLog = PR_NewLogModule("netlibStreamEvent");
PR_LOG(gStreamEventLog, PR_LOG_DEBUG,
("netlibEvent: Handle Stop [event=%x]", this));
#endif
nsIStreamObserver* receiver = (nsIStreamObserver*)mListener->GetReceiver();
if (receiver == nsnull) {
// must have already called OnStopRequest (it clears the receiver)
return NS_ERROR_FAILURE;
}
nsresult status = NS_OK;
nsresult rv = mRequest->GetStatus(&status);
NS_ASSERTION(NS_SUCCEEDED(rv), "GetStatus failed");
//
// If the consumer returned a failure code, then pass it out in the
// OnStopRequest(...) notification...
//
if (NS_SUCCEEDED(rv) && NS_FAILED(status)) {
mStatus = status;
}
rv = receiver->OnStopRequest(mRequest, mContext, mStatus, mStatusArg.GetUnicode());
// Call clear on the listener to make sure it's cleanup is done on the correct thread
mListener->Clear();
return rv;
}
NS_IMETHODIMP
nsAsyncStreamObserver::OnStopRequest(nsIRequest* request, nsISupports* context,
nsresult aStatus, const PRUnichar* aStatusArg)
{
nsresult rv;
//
// Fire the OnStopRequest(...) regardless of what the current
// Status is...
//
nsOnStopRequestEvent* event =
new nsOnStopRequestEvent(this, context, request);
if (event == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
rv = event->Init(aStatus, aStatusArg);
if (NS_FAILED(rv)) goto failed;
#if defined(PR_LOGGING)
PLEventQueue *equeue;
mEventQueue->GetPLEventQueue(&equeue);
if (!gStreamEventLog)
gStreamEventLog = PR_NewLogModule("netlibStreamEvent");
PR_LOG(gStreamEventLog, PR_LOG_DEBUG,
("nsAsyncStreamObserver: Stop [this=%x queue=%x event=%x]",
this, equeue, event));
#endif
rv = event->Fire(mEventQueue);
if (NS_FAILED(rv)) goto failed;
return rv;
failed:
delete event;
return rv;
}
////////////////////////////////////////////////////////////////////////////////
//
// OnDataAvailable
//
////////////////////////////////////////////////////////////////////////////////
class nsOnDataAvailableEvent : public nsStreamListenerEvent
{
public:
nsOnDataAvailableEvent(nsAsyncStreamObserver* listener,
nsIRequest* request, nsISupports* context)
: nsStreamListenerEvent(listener, request, context),
mIStream(nsnull), mLength(0) {}
virtual ~nsOnDataAvailableEvent();
nsresult Init(nsIInputStream* aIStream, PRUint32 aSourceOffset,
PRUint32 aLength);
NS_IMETHOD HandleEvent();
protected:
nsIInputStream* mIStream;
PRUint32 mSourceOffset;
PRUint32 mLength;
};
nsOnDataAvailableEvent::~nsOnDataAvailableEvent()
{
NS_RELEASE(mIStream);
}
nsresult
nsOnDataAvailableEvent::Init(nsIInputStream* aIStream, PRUint32 aSourceOffset,
PRUint32 aLength)
{
mSourceOffset = aSourceOffset;
mLength = aLength;
mIStream = aIStream;
NS_ADDREF(mIStream);
return NS_OK;
}
NS_IMETHODIMP
nsOnDataAvailableEvent::HandleEvent()
{
#if defined(PR_LOGGING)
if (!gStreamEventLog)
gStreamEventLog = PR_NewLogModule("netlibStreamEvent");
PR_LOG(gStreamEventLog, PR_LOG_DEBUG,
("netlibEvent: Handle Data [event=%x]", this));
#endif
nsIStreamListener* receiver = (nsIStreamListener*)mListener->GetReceiver();
if (receiver == nsnull) {
// must have already called OnStopRequest (it clears the receiver)
return NS_ERROR_FAILURE;
}
nsresult status;
nsresult rv = mRequest->GetStatus(&status);
NS_ASSERTION(NS_SUCCEEDED(rv), "GetStatus failed");
//
// Only send OnDataAvailable(... ) notifications if all previous calls
// have succeeded...
//
if (NS_SUCCEEDED(rv) && NS_SUCCEEDED(status)) {
rv = receiver->OnDataAvailable(mRequest, mContext,
mIStream, mSourceOffset, mLength);
}
else {
NS_WARNING("not calling OnDataAvailable");
}
return rv;
}
NS_IMETHODIMP
nsAsyncStreamListener::OnDataAvailable(nsIRequest* request, nsISupports* context,
nsIInputStream *aIStream,
PRUint32 aSourceOffset,
PRUint32 aLength)
{
nsresult rv;
nsOnDataAvailableEvent* event =
new nsOnDataAvailableEvent(this, request, context);
if (event == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
rv = event->Init(aIStream, aSourceOffset, aLength);
if (NS_FAILED(rv)) goto failed;
#if defined(PR_LOGGING)
PLEventQueue *equeue;
mEventQueue->GetPLEventQueue(&equeue);
if (!gStreamEventLog)
gStreamEventLog = PR_NewLogModule("netlibStreamEvent");
PR_LOG(gStreamEventLog, PR_LOG_DEBUG,
("nsAsyncStreamObserver: Data [this=%x queue=%x event=%x]",
this, equeue, event));
#endif
rv = event->Fire(mEventQueue);
if (NS_FAILED(rv)) goto failed;
return rv;
failed:
delete event;
return rv;
}
////////////////////////////////////////////////////////////////////////////////
NS_METHOD
nsAsyncStreamObserver::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{
if (aOuter)
return NS_ERROR_NO_AGGREGATION;
nsAsyncStreamObserver* l = new nsAsyncStreamObserver();
if (l == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(l);
nsresult rv = l->QueryInterface(aIID, aResult);
NS_RELEASE(l);
return rv;
}
NS_METHOD
nsAsyncStreamListener::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{
if (aOuter)
return NS_ERROR_NO_AGGREGATION;
nsAsyncStreamListener* l = new nsAsyncStreamListener();
if (l == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(l);
nsresult rv = l->QueryInterface(aIID, aResult);
NS_RELEASE(l);
return rv;
}
////////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,108 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsAsyncStreamListener_h__
#define nsAsyncStreamListener_h__
#include "nsIStreamListener.h"
#include "nsCOMPtr.h"
#include "nsIEventQueue.h"
#include "nsIStreamObserver.h"
#include "nsIStreamListener.h"
#include "nsIRequest.h"
////////////////////////////////////////////////////////////////////////////////
class nsAsyncStreamObserver : public nsIAsyncStreamObserver
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSISTREAMOBSERVER
NS_DECL_NSIASYNCSTREAMOBSERVER
// nsAsyncStreamObserver methods:
nsAsyncStreamObserver()
{
NS_INIT_REFCNT();
}
virtual ~nsAsyncStreamObserver() {}
static NS_METHOD
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
nsISupports* GetReceiver() { return mReceiver.get(); }
void Clear() { mReceiver = nsnull; }
protected:
nsCOMPtr<nsIEventQueue> mEventQueue;
nsCOMPtr<nsIStreamObserver> mReceiver;
};
////////////////////////////////////////////////////////////////////////////////
class nsAsyncStreamListener : public nsAsyncStreamObserver,
public nsIAsyncStreamListener
{
public:
NS_DECL_ISUPPORTS_INHERITED
// nsIStreamListener methods:
NS_IMETHOD OnStartRequest(nsIRequest* request,
nsISupports* context)
{
return nsAsyncStreamObserver::OnStartRequest(request, context);
}
NS_IMETHOD OnStopRequest(nsIRequest* request,
nsISupports* context,
nsresult aStatus, const PRUnichar* aStatusArg)
{
return nsAsyncStreamObserver::OnStopRequest(request, context, aStatus, aStatusArg);
}
NS_IMETHOD OnDataAvailable(nsIRequest* request, nsISupports* context,
nsIInputStream *aIStream,
PRUint32 aSourceOffset,
PRUint32 aLength);
// nsIAsyncStreamListener methods:
NS_IMETHOD Init(nsIStreamListener* aListener, nsIEventQueue* aEventQ) {
return nsAsyncStreamObserver::Init(aListener, aEventQ);
}
// nsAsyncStreamListener methods:
nsAsyncStreamListener() {
MOZ_COUNT_CTOR(nsAsyncStreamListener);
}
virtual ~nsAsyncStreamListener() {
MOZ_COUNT_DTOR(nsAsyncStreamListener);
}
static NS_METHOD
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
};
////////////////////////////////////////////////////////////////////////////////
#endif // nsAsyncStreamListener_h__

View File

@@ -0,0 +1,593 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Andreas Otte.
*
* Contributor(s):
*/
#include "nsAuthURLParser.h"
#include "nsURLHelper.h"
#include "nsCRT.h"
#include "nsString.h"
#include "prprf.h"
#include "prnetdb.h" // IPv6 support
NS_IMPL_THREADSAFE_ISUPPORTS1(nsAuthURLParser, nsIURLParser)
nsAuthURLParser::~nsAuthURLParser()
{
}
NS_METHOD
nsAuthURLParser::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{
if (aOuter)
return NS_ERROR_NO_AGGREGATION;
nsAuthURLParser* p = new nsAuthURLParser();
if (p == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(p);
nsresult rv = p->QueryInterface(aIID, aResult);
NS_RELEASE(p);
return rv;
}
nsresult
nsAuthURLParser::ParseAtScheme(const char* i_Spec, char* *o_Scheme,
char* *o_Username, char* *o_Password,
char* *o_Host, PRInt32 *o_Port, char* *o_Path)
{
nsresult rv = NS_OK;
NS_PRECONDITION( (nsnull != i_Spec), "Parse called on empty url!");
if (!i_Spec)
return NS_ERROR_MALFORMED_URI;
int len = PL_strlen(i_Spec);
if (len >= 2 && *i_Spec == '/' && *(i_Spec+1) == '/') // No Scheme
{
rv = ParseAtPreHost(i_Spec, o_Username, o_Password, o_Host, o_Port,
o_Path);
return rv;
}
static const char delimiters[] = "/:@?#["; //this order is optimized.
char* brk = PL_strpbrk(i_Spec, delimiters);
if (!brk) // everything is a host
{
rv = ExtractString((char*)i_Spec, o_Host, len);
ToLowerCase(*o_Host);
return rv;
} else
len = PL_strlen(brk);
switch (*brk)
{
case '/' :
case '?' :
case '#' :
// If the URL starts with a slash then everything is a path
if (brk == i_Spec)
{
rv = ParseAtPath(brk, o_Path);
return rv;
}
else // The first part is host, so its host/path
{
rv = ExtractString((char*)i_Spec, o_Host, (brk - i_Spec));
if (NS_FAILED(rv))
return rv;
ToLowerCase(*o_Host);
rv = ParseAtPath(brk, o_Path);
return rv;
}
break;
case ':' :
if (len >= 2 && *(brk+1) == '/') {
// Standard http://... or malformed http:/...
rv = ExtractString((char*)i_Spec, o_Scheme, (brk - i_Spec));
if (NS_FAILED(rv))
return rv;
ToLowerCase(*o_Scheme);
rv = ParseAtPreHost(brk+1, o_Username, o_Password, o_Host,
o_Port, o_Path);
return rv;
} else {
// Could be host:port, so try conversion to number
PRInt32 port = ExtractPortFrom(brk+1);
if (port > 0)
{
rv = ExtractString((char*)i_Spec, o_Host, (brk - i_Spec));
if (NS_FAILED(rv))
return rv;
ToLowerCase(*o_Host);
rv = ParseAtPort(brk+1, o_Port, o_Path);
return rv;
} else {
// No, it's not a number try scheme:host...
rv = ExtractString((char*)i_Spec, o_Scheme,
(brk - i_Spec));
if (NS_FAILED(rv))
return rv;
ToLowerCase(*o_Scheme);
rv = ParseAtPreHost(brk+1, o_Username, o_Password, o_Host,
o_Port, o_Path);
return rv;
}
}
break;
case '@' :
rv = ParseAtPreHost(i_Spec, o_Username, o_Password, o_Host,
o_Port, o_Path);
return rv;
break;
case '[' :
if (brk == i_Spec) {
rv = ParseAtHost(i_Spec, o_Host, o_Port, o_Path);
if (rv != NS_ERROR_MALFORMED_URI) return rv;
// Try something else
CRTFREEIF(*o_Host);
*o_Port = -1;
}
rv = ParseAtPath(i_Spec, o_Path);
return rv;
default:
NS_ASSERTION(0, "This just can't be!");
break;
}
return NS_OK;
}
nsresult
nsAuthURLParser::ParseAtPreHost(const char* i_Spec, char* *o_Username,
char* *o_Password, char* *o_Host,
PRInt32 *o_Port, char* *o_Path)
{
nsresult rv = NS_OK;
// Skip leading two slashes
char* fwdPtr= (char*) i_Spec;
if (fwdPtr && (*fwdPtr != '\0') && (*fwdPtr == '/'))
fwdPtr++;
if (fwdPtr && (*fwdPtr != '\0') && (*fwdPtr == '/'))
fwdPtr++;
static const char delimiters[] = "/:@?#[";
char* brk = PL_strpbrk(fwdPtr, delimiters);
char* brk2 = nsnull;
if (!brk)
{
rv = ParseAtHost(fwdPtr, o_Host, o_Port, o_Path);
return rv;
}
char* e_PreHost = nsnull;
switch (*brk)
{
case ':' :
// this maybe the : of host:port or username:password
// look if the next special char is @
brk2 = PL_strpbrk(brk+1, delimiters);
if (!brk2)
{
rv = ParseAtHost(fwdPtr, o_Host, o_Port, o_Path);
return rv;
}
switch (*brk2)
{
case '@' :
rv = ExtractString(fwdPtr, &e_PreHost, (brk2 - fwdPtr));
if (NS_FAILED(rv)) {
CRTFREEIF(e_PreHost);
return rv;
}
rv = ParsePreHost(e_PreHost,o_Username,o_Password);
CRTFREEIF(e_PreHost);
if (NS_FAILED(rv))
return rv;
rv = ParseAtHost(brk2+1, o_Host, o_Port, o_Path);
break;
default:
rv = ParseAtHost(fwdPtr, o_Host, o_Port, o_Path);
return rv;
}
break;
case '@' :
rv = ExtractString(fwdPtr, &e_PreHost, (brk - fwdPtr));
if (NS_FAILED(rv)) {
CRTFREEIF(e_PreHost);
return rv;
}
rv = ParsePreHost(e_PreHost,o_Username,o_Password);
CRTFREEIF(e_PreHost);
if (NS_FAILED(rv))
return rv;
rv = ParseAtHost(brk+1, o_Host, o_Port, o_Path);
break;
case '[' :
if (brk == fwdPtr) {
rv = ParseAtHost(fwdPtr, o_Host, o_Port, o_Path);
if (rv != NS_ERROR_MALFORMED_URI) return rv;
// Try something else
CRTFREEIF(*o_Host);
*o_Port = -1;
}
rv = ParseAtPath(fwdPtr, o_Path);
return rv;
default:
rv = ParseAtHost(fwdPtr, o_Host, o_Port, o_Path);
}
return rv;
}
nsresult
nsAuthURLParser::ParseAtHost(const char* i_Spec, char* *o_Host,
PRInt32 *o_Port, char* *o_Path)
{
nsresult rv = NS_OK;
int len = PL_strlen(i_Spec);
static const char delimiters[] = ":/?#"; //this order is optimized.
const char* fwdPtr= i_Spec;
PRNetAddr netaddr;
if (fwdPtr && *fwdPtr == '[') {
// Possible IPv6 address
fwdPtr = strchr(fwdPtr+1, ']');
if (fwdPtr && (fwdPtr[1] == '\0' || strchr(delimiters, fwdPtr[1]))) {
rv = ExtractString((char*)i_Spec+1, o_Host, (fwdPtr - i_Spec - 1));
if (NS_FAILED(rv))
return rv;
rv = PR_StringToNetAddr(*o_Host, &netaddr);
if (rv != PR_SUCCESS || netaddr.raw.family != PR_AF_INET6) {
// try something else
CRTFREEIF(*o_Host);
} else {
ToLowerCase(*o_Host);
fwdPtr++;
switch (*fwdPtr)
{
case '\0': // everything is a host
return NS_OK;
case '/' :
case '?' :
case '#' :
rv = ParseAtPath(fwdPtr, o_Path);
return rv;
case ':' :
rv = ParseAtPort(fwdPtr+1, o_Port, o_Path);
return rv;
default:
NS_ASSERTION(0, "This just can't be!");
break;
}
}
}
}
char* brk = PL_strpbrk(i_Spec, delimiters);
if (!brk) // everything is a host
{
rv = ExtractString((char*)i_Spec, o_Host, len);
if (PL_strlen(*o_Host)==0) {
return NS_ERROR_MALFORMED_URI;
}
ToLowerCase(*o_Host);
return rv;
}
switch (*brk)
{
case '/' :
case '?' :
case '#' :
// Get the Host, the rest is Path
rv = ExtractString((char*)i_Spec, o_Host, (brk - i_Spec));
if (NS_FAILED(rv))
return rv;
if (PL_strlen(*o_Host)==0) {
return NS_ERROR_MALFORMED_URI;
}
ToLowerCase(*o_Host);
rv = ParseAtPath(brk, o_Path);
return rv;
break;
case ':' :
// Get the Host
rv = ExtractString((char*)i_Spec, o_Host, (brk - i_Spec));
if (NS_FAILED(rv))
return rv;
if (PL_strlen(*o_Host)==0) {
return NS_ERROR_MALFORMED_URI;
}
ToLowerCase(*o_Host);
rv = ParseAtPort(brk+1, o_Port, o_Path);
return rv;
break;
default:
NS_ASSERTION(0, "This just can't be!");
break;
}
return NS_OK;
}
nsresult
nsAuthURLParser::ParseAtPort(const char* i_Spec, PRInt32 *o_Port,
char* *o_Path)
{
nsresult rv = NS_OK;
static const char delimiters[] = "/?#"; //this order is optimized.
char* brk = PL_strpbrk(i_Spec, delimiters);
if (!brk) // everything is a Port
{
if (PL_strlen(i_Spec)==0) {
*o_Port = -1;
return NS_OK;
} else {
*o_Port = ExtractPortFrom(i_Spec);
if (*o_Port <= 0)
return NS_ERROR_MALFORMED_URI;
else
return NS_OK;
}
}
char* e_Port = nsnull;
switch (*brk)
{
case '/' :
case '?' :
case '#' :
// Get the Port, the rest is Path
rv = ExtractString((char*)i_Spec, &e_Port, brk-i_Spec);
if (NS_FAILED(rv)) {
CRTFREEIF(e_Port);
return rv;
}
if (PL_strlen(e_Port)==0) {
*o_Port = -1;
} else {
*o_Port = ExtractPortFrom(e_Port);
if (*o_Port <= 0)
return NS_ERROR_MALFORMED_URI;
}
CRTFREEIF(e_Port);
rv = ParseAtPath(brk, o_Path);
return rv;
break;
default:
NS_ASSERTION(0, "This just can't be!");
break;
}
return NS_OK;
}
nsresult
nsAuthURLParser::ParseAtPath(const char* i_Spec, char* *o_Path)
{
// Just write the path and check for a starting /
nsCAutoString dir;
if ('/' != *i_Spec)
dir += "/";
dir += i_Spec;
*o_Path = dir.ToNewCString();
return (*o_Path ? NS_OK : NS_ERROR_OUT_OF_MEMORY);
}
nsresult
nsAuthURLParser::ParseAtDirectory(const char* i_Path, char* *o_Directory,
char* *o_FileBaseName, char* *o_FileExtension,
char* *o_Param, char* *o_Query, char* *o_Ref)
{
// Cleanout
CRTFREEIF(*o_Directory);
CRTFREEIF(*o_FileBaseName);
CRTFREEIF(*o_FileExtension);
CRTFREEIF(*o_Param);
CRTFREEIF(*o_Query);
CRTFREEIF(*o_Ref);
nsresult rv = NS_OK;
// Parse the Path into its components
if (!i_Path)
{
DupString(o_Directory, "/");
return (o_Directory ? NS_OK : NS_ERROR_OUT_OF_MEMORY);
}
char* dirfile = nsnull;
char* options = nsnull;
int len = PL_strlen(i_Path);
/* Factor out the optionpart with ;?# */
static const char delimiters[] = ";?#"; // for param, query and ref
char* brk = PL_strpbrk(i_Path, delimiters);
if (!brk) // Everything is just path and filename
{
DupString(&dirfile, i_Path);
}
else
{
int dirfileLen = brk - i_Path;
ExtractString((char*)i_Path, &dirfile, dirfileLen);
len -= dirfileLen;
ExtractString((char*)i_Path + dirfileLen, &options, len);
brk = options;
}
/* now that we have broken up the path treat every part differently */
/* first dir+file */
char* file;
int dlen = PL_strlen(dirfile);
if (dlen == 0)
{
DupString(o_Directory, "/");
file = dirfile;
} else {
CoaleseDirs(dirfile);
// Get length again
dlen = PL_strlen(dirfile);
// First find the last slash
file = PL_strrchr(dirfile, '/');
if (!file)
{
DupString(o_Directory, "/");
file = dirfile;
}
// If its not the same as the first slash then extract directory
if (file != dirfile)
{
ExtractString(dirfile, o_Directory, (file - dirfile)+1);
if (*dirfile != '/') {
nsCAutoString dir;
dir += "/" ;
dir += *o_Directory;
CRTFREEIF(*o_Directory);
*o_Directory = dir.ToNewCString();
}
} else {
DupString(o_Directory, "/");
}
}
/* Extract FileBaseName and FileExtension */
if (dlen > 0) {
// Look again if there was a slash
char* slash = PL_strrchr(dirfile, '/');
char* e_FileName = nsnull;
if (slash) {
if (dirfile+dlen-1>slash)
ExtractString(slash+1, &e_FileName, dlen-(slash-dirfile+1));
} else {
// Use the full String as Filename
ExtractString(dirfile, &e_FileName, dlen);
}
rv = ParseFileName(e_FileName,o_FileBaseName,o_FileExtension);
CRTFREEIF(e_FileName);
}
// Now take a look at the options. "#" has precedence over "?"
// which has precedence over ";"
if (options) {
// Look for "#" first. Everything following it is in the ref
brk = PL_strchr(options, '#');
if (brk) {
int pieceLen = len - (brk + 1 - options);
ExtractString(brk+1, o_Ref, pieceLen);
len -= pieceLen + 1;
*brk = '\0';
}
// Now look for "?"
brk = PL_strchr(options, '?');
if (brk) {
int pieceLen = len - (brk + 1 - options);
ExtractString(brk+1, o_Query, pieceLen);
len -= pieceLen + 1;
*brk = '\0';
}
// Now look for ';'
brk = PL_strchr(options, ';');
if (brk) {
int pieceLen = len - (brk + 1 - options);
ExtractString(brk+1, o_Param, pieceLen);
len -= pieceLen + 1;
*brk = '\0';
}
}
nsCRT::free(dirfile);
nsCRT::free(options);
return rv;
}
nsresult
nsAuthURLParser::ParsePreHost(const char* i_PreHost, char* *o_Username,
char* *o_Password)
{
nsresult rv = NS_OK;
if (!i_PreHost) {
*o_Username = nsnull;
*o_Password = nsnull;
return rv;
}
// Search for :
static const char delimiters[] = ":";
char* brk = PL_strpbrk(i_PreHost, delimiters);
if (brk)
{
rv = ExtractString((char*)i_PreHost, o_Username, (brk - i_PreHost));
if (NS_FAILED(rv))
return rv;
rv = ExtractString(brk+1, o_Password,
(i_PreHost+PL_strlen(i_PreHost) - brk - 1));
} else {
CRTFREEIF(*o_Password);
rv = DupString(o_Username, i_PreHost);
}
return rv;
}
nsresult
nsAuthURLParser::ParseFileName(const char* i_FileName, char* *o_FileBaseName,
char* *o_FileExtension)
{
nsresult rv = NS_OK;
if (!i_FileName) {
*o_FileBaseName = nsnull;
*o_FileExtension = nsnull;
return rv;
}
// Search for FileExtension
// Search for last .
// Ignore . at the beginning
char* brk = PL_strrchr(i_FileName+1, '.');
if (brk)
{
rv = ExtractString((char*)i_FileName, o_FileBaseName,
(brk - i_FileName));
if (NS_FAILED(rv))
return rv;
rv = ExtractString(brk + 1, o_FileExtension,
(i_FileName+PL_strlen(i_FileName) - brk - 1));
} else {
rv = DupString(o_FileBaseName, i_FileName);
}
return rv;
}

View File

@@ -0,0 +1,51 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsAuthURLParser_h__
#define nsAuthURLParser_h__
#include "nsIURLParser.h"
#include "nsIURI.h"
#include "nsAgg.h"
#include "nsCRT.h"
class nsAuthURLParser : public nsIURLParser
{
public:
NS_DECL_ISUPPORTS
///////////////////////////////////////////////////////////////////////////
// nsAuthURLParser methods:
nsAuthURLParser() {
NS_INIT_REFCNT();
}
virtual ~nsAuthURLParser();
static NS_METHOD
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
///////////////////////////////////////////////////////////////////////////
// nsIURLParser methods:
NS_DECL_NSIURLPARSER
};
#endif // nsAuthURLParser_h__

View File

@@ -0,0 +1,418 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsBufferedStreams.h"
#include "nsCRT.h"
////////////////////////////////////////////////////////////////////////////////
// nsBufferedStream
nsBufferedStream::nsBufferedStream()
: mBuffer(nsnull),
mBufferStartOffset(0),
mCursor(0),
mFillPoint(0),
mStream(nsnull)
{
NS_INIT_REFCNT();
}
nsBufferedStream::~nsBufferedStream()
{
Close();
}
NS_IMPL_THREADSAFE_ISUPPORTS1(nsBufferedStream, nsISeekableStream);
nsresult
nsBufferedStream::Init(nsISupports* stream, PRUint32 bufferSize)
{
NS_ASSERTION(stream, "need to supply a stream");
NS_ASSERTION(mStream == nsnull, "already inited");
mStream = stream;
NS_ADDREF(mStream);
mBufferSize = bufferSize;
mBufferStartOffset = 0;
mCursor = 0;
mBuffer = new char[bufferSize];
if (mBuffer == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
}
nsresult
nsBufferedStream::Close()
{
nsresult rv = NS_OK;
if (mBuffer) {
delete[] mBuffer;
mBuffer = nsnull;
mBufferSize = 0;
mBufferStartOffset = 0;
mCursor = 0;
}
return rv;
}
NS_IMETHODIMP
nsBufferedStream::Seek(PRInt32 whence, PRInt32 offset)
{
if (mStream == nsnull)
return NS_BASE_STREAM_CLOSED;
// If the underlying stream isn't a random access store, then fail early.
// We could possibly succeed for the case where the seek position denotes
// something that happens to be read into the buffer, but that would make
// the failure data-dependent.
nsresult rv;
nsCOMPtr<nsISeekableStream> ras = do_QueryInterface(mStream, &rv);
if (NS_FAILED(rv)) return rv;
PRInt32 absPos;
switch (whence) {
case nsISeekableStream::NS_SEEK_SET:
absPos = offset;
break;
case nsISeekableStream::NS_SEEK_CUR:
absPos = mBufferStartOffset + mCursor + offset;
break;
case nsISeekableStream::NS_SEEK_END:
absPos = -1;
break;
default:
NS_NOTREACHED("bogus seek whence parameter");
return NS_ERROR_UNEXPECTED;
}
if ((PRInt32)mBufferStartOffset <= absPos
&& absPos < (PRInt32)(mBufferStartOffset + mFillPoint)) {
mCursor = absPos - mBufferStartOffset;
return NS_OK;
}
rv = Flush();
if (NS_FAILED(rv)) return rv;
rv = ras->Seek(whence, offset);
if (NS_FAILED(rv)) return rv;
if (absPos == -1) {
// then we had the SEEK_END case, above
rv = ras->Tell(&mBufferStartOffset);
if (NS_FAILED(rv)) return rv;
}
else {
mBufferStartOffset = absPos;
}
mCursor = 0;
mFillPoint = 0;
return Fill();
}
NS_IMETHODIMP
nsBufferedStream::Tell(PRUint32 *result)
{
if (mStream == nsnull)
return NS_BASE_STREAM_CLOSED;
*result = mBufferStartOffset + mCursor;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsBufferedInputStream
NS_IMPL_ISUPPORTS_INHERITED2(nsBufferedInputStream,
nsBufferedStream,
nsIInputStream,
nsIBufferedInputStream);
NS_METHOD
nsBufferedInputStream::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{
NS_ENSURE_NO_AGGREGATION(aOuter);
nsBufferedInputStream* stream = new nsBufferedInputStream();
if (stream == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(stream);
nsresult rv = stream->QueryInterface(aIID, aResult);
NS_RELEASE(stream);
return rv;
}
NS_IMETHODIMP
nsBufferedInputStream::Init(nsIInputStream* stream, PRUint32 bufferSize)
{
return nsBufferedStream::Init(stream, bufferSize);
}
NS_IMETHODIMP
nsBufferedInputStream::Close()
{
nsresult rv1 = NS_OK, rv2;
if (mStream) {
rv1 = Source()->Close();
NS_RELEASE(mStream);
}
rv2 = nsBufferedStream::Close();
if (NS_FAILED(rv1)) return rv1;
return rv2;
}
NS_IMETHODIMP
nsBufferedInputStream::Available(PRUint32 *result)
{
*result = mFillPoint - mCursor;
return NS_OK;
}
NS_IMETHODIMP
nsBufferedInputStream::Read(char * buf, PRUint32 count, PRUint32 *result)
{
nsresult rv = NS_OK;
PRUint32 read = 0;
while (count > 0) {
PRUint32 amt = PR_MIN(count, mFillPoint - mCursor);
if (amt > 0) {
nsCRT::memcpy(buf + read, mBuffer + mCursor, amt);
read += amt;
count -= amt;
mCursor += amt;
}
else {
rv = Fill();
if (NS_FAILED(rv)) break;
}
}
*result = read;
return (read > 0 || rv == NS_BASE_STREAM_CLOSED) ? NS_OK : rv;
}
NS_IMETHODIMP
nsBufferedInputStream::ReadSegments(nsWriteSegmentFun writer, void * closure, PRUint32 count, PRUint32 *result)
{
nsresult rv = NS_OK;
*result = 0;
while (count > 0) {
PRUint32 amt = PR_MIN(count, mFillPoint - mCursor);
if (amt > 0) {
PRUint32 read = 0;
rv = writer (this, closure, mBuffer + mCursor, mCursor,
amt, &read);
if (NS_FAILED(rv)) break;
*result += read;
count -= read;
mCursor += read;
}
else {
rv = Fill();
if (NS_FAILED(rv)) break;
}
}
return (*result > 0 || rv == NS_BASE_STREAM_CLOSED) ? NS_OK : rv;
}
NS_IMETHODIMP
nsBufferedInputStream::GetNonBlocking(PRBool *aNonBlocking)
{
NS_NOTREACHED("GetNonBlocking");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsBufferedInputStream::GetObserver(nsIInputStreamObserver * *aObserver)
{
NS_NOTREACHED("GetObserver");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsBufferedInputStream::SetObserver(nsIInputStreamObserver * aObserver)
{
NS_NOTREACHED("SetObserver");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsBufferedInputStream::Fill()
{
nsresult rv;
PRUint32 rem = mFillPoint - mCursor;
if (rem > 0) {
// slide the remainder down to the start of the buffer
// |<------------->|<--rem-->|<--->|
// b c f s
nsCRT::memcpy(mBuffer, mBuffer + mCursor, rem);
}
mBufferStartOffset += mCursor;
mFillPoint = rem;
mCursor = 0;
PRUint32 amt;
rv = Source()->Read(mBuffer + mFillPoint, mBufferSize - mFillPoint, &amt);
if (NS_FAILED(rv)) return rv;
mFillPoint += amt;
return amt > 0 ? NS_OK : NS_BASE_STREAM_CLOSED;
}
////////////////////////////////////////////////////////////////////////////////
// nsBufferedOutputStream
NS_IMPL_ISUPPORTS_INHERITED2(nsBufferedOutputStream,
nsBufferedStream,
nsIOutputStream,
nsIBufferedOutputStream);
NS_METHOD
nsBufferedOutputStream::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{
NS_ENSURE_NO_AGGREGATION(aOuter);
nsBufferedOutputStream* stream = new nsBufferedOutputStream();
if (stream == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(stream);
nsresult rv = stream->QueryInterface(aIID, aResult);
NS_RELEASE(stream);
return rv;
}
NS_IMETHODIMP
nsBufferedOutputStream::Init(nsIOutputStream* stream, PRUint32 bufferSize)
{
mFillPoint = bufferSize; // always fill to the end for buffered output streams
return nsBufferedStream::Init(stream, bufferSize);
}
NS_IMETHODIMP
nsBufferedOutputStream::Close()
{
nsresult rv1, rv2 = NS_OK, rv3;
rv1 = Flush();
// If we fail to Flush all the data, then we close anyway and drop the
// remaining data in the buffer. We do this because it's what Unix does
// for fclose and close. However, we report the error from Flush anyway.
if (mStream) {
rv2 = Sink()->Close();
NS_RELEASE(mStream);
}
rv3 = nsBufferedStream::Close();
if (NS_FAILED(rv1)) return rv1;
if (NS_FAILED(rv2)) return rv2;
return rv3;
}
NS_IMETHODIMP
nsBufferedOutputStream::Write(const char *buf, PRUint32 count, PRUint32 *result)
{
nsresult rv = NS_OK;
PRUint32 written = 0;
while (count > 0) {
PRUint32 amt = PR_MIN(count, mFillPoint - mCursor);
if (amt > 0) {
nsCRT::memcpy(mBuffer + mCursor, buf + written, amt);
written += amt;
count -= amt;
mCursor += amt;
}
else {
rv = Flush();
if (NS_FAILED(rv)) break;
}
}
*result = written;
return (written > 0) ? NS_OK : rv;
}
NS_IMETHODIMP
nsBufferedOutputStream::Flush(void)
{
nsresult rv;
PRUint32 amt;
if (!mStream) {
// Stream already cancelled/flushed; probably because of error.
return NS_OK;
}
rv = Sink()->Write(mBuffer, mCursor, &amt);
if (NS_FAILED(rv)) return rv;
mBufferStartOffset += amt;
if (mCursor == amt) {
mCursor = 0;
return NS_OK; // flushed everything
}
// slide the remainder down to the start of the buffer
// |<-------------->|<---|----->|
// b a c s
PRUint32 rem = mCursor - amt;
nsCRT::memcpy(mBuffer, mBuffer + amt, rem);
mCursor = rem;
return NS_ERROR_FAILURE; // didn't flush all
}
NS_IMETHODIMP
nsBufferedOutputStream::WriteFrom(nsIInputStream *inStr, PRUint32 count, PRUint32 *_retval)
{
NS_NOTREACHED("WriteFrom");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsBufferedOutputStream::WriteSegments(nsReadSegmentFun reader, void * closure, PRUint32 count, PRUint32 *_retval)
{
NS_NOTREACHED("WriteSegments");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsBufferedOutputStream::GetNonBlocking(PRBool *aNonBlocking)
{
if (mStream)
return Sink()->GetNonBlocking(aNonBlocking);
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsBufferedOutputStream::SetNonBlocking(PRBool aNonBlocking)
{
if (mStream)
return Sink()->SetNonBlocking(aNonBlocking);
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsBufferedOutputStream::GetObserver(nsIOutputStreamObserver * *aObserver)
{
NS_NOTREACHED("GetObserver");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsBufferedOutputStream::SetObserver(nsIOutputStreamObserver * aObserver)
{
NS_NOTREACHED("SetObserver");
return NS_ERROR_NOT_IMPLEMENTED;
}
////////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,115 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsBufferedStreams_h__
#define nsBufferedStreams_h__
#include "nsIFileStreams.h"
#include "nsIInputStream.h"
#include "nsIOutputStream.h"
#include "nsCOMPtr.h"
////////////////////////////////////////////////////////////////////////////////
class nsBufferedStream : public nsISeekableStream
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSISEEKABLESTREAM
nsBufferedStream();
virtual ~nsBufferedStream();
nsresult Close();
protected:
nsresult Init(nsISupports* stream, PRUint32 bufferSize);
NS_IMETHOD Fill() = 0;
NS_IMETHOD Flush() = 0;
protected:
PRUint32 mBufferSize;
char* mBuffer;
// mBufferStartOffset is the offset relative to the start of mStream:
PRUint32 mBufferStartOffset;
// mCursor is the read cursor for input streams, or write cursor for
// output streams, and is relative to mBufferStartOffset:
PRUint32 mCursor;
// mFillPoint is the amount available in the buffer for input streams,
// or the end of the buffer for output streams, and is relative to
// mBufferStartOffset:
PRUint32 mFillPoint;
nsISupports* mStream; // cast to appropriate subclass
};
////////////////////////////////////////////////////////////////////////////////
class nsBufferedInputStream : public nsBufferedStream,
public nsIBufferedInputStream
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIINPUTSTREAM
NS_DECL_NSIBUFFEREDINPUTSTREAM
nsBufferedInputStream() : nsBufferedStream() {}
virtual ~nsBufferedInputStream() {}
static NS_METHOD
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
nsIInputStream* Source() {
return (nsIInputStream*)mStream;
}
protected:
NS_IMETHOD Fill();
NS_IMETHOD Flush() { return NS_OK; } // no-op for input streams
};
////////////////////////////////////////////////////////////////////////////////
class nsBufferedOutputStream : public nsBufferedStream,
public nsIBufferedOutputStream
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIOUTPUTSTREAM
NS_DECL_NSIBUFFEREDOUTPUTSTREAM
nsBufferedOutputStream() : nsBufferedStream() {}
virtual ~nsBufferedOutputStream() { nsBufferedOutputStream::Close(); }
static NS_METHOD
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
nsIOutputStream* Sink() {
return (nsIOutputStream*)mStream;
}
protected:
NS_IMETHOD Fill() { return NS_OK; } // no-op for output streams
};
////////////////////////////////////////////////////////////////////////////////
#endif // nsBufferedStreams_h__

View File

@@ -0,0 +1,298 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
/*
The converts a filesystem directory into an "HTTP index" stream per
Lou Montulli's original spec:
http://www.area.com/~roeber/file_format.html
*/
#include "nsEscape.h"
#include "nsDirectoryIndexStream.h"
#include "nsXPIDLString.h"
#include "prio.h"
#include "prlog.h"
#include "prlong.h"
#ifdef PR_LOGGING
static PRLogModuleInfo* gLog;
#endif
nsDirectoryIndexStream::nsDirectoryIndexStream()
: mOffset(0)
{
NS_INIT_REFCNT();
#ifdef PR_LOGGING
if (! gLog)
gLog = PR_NewLogModule("nsDirectoryIndexStream");
#endif
PR_LOG(gLog, PR_LOG_DEBUG,
("nsDirectoryIndexStream[%p]: created", this));
}
nsresult
nsDirectoryIndexStream::Init(nsIFile* aDir)
{
nsresult rv;
PRBool isDir;
rv = aDir->IsDirectory(&isDir);
if (NS_FAILED(rv)) return rv;
NS_PRECONDITION(isDir, "not a directory");
if (!isDir)
return NS_ERROR_ILLEGAL_VALUE;
#ifdef PR_LOGGING
if (PR_LOG_TEST(gLog, PR_LOG_DEBUG)) {
nsXPIDLCString path;
aDir->GetPath(getter_Copies(path));
PR_LOG(gLog, PR_LOG_DEBUG,
("nsDirectoryIndexStream[%p]: initialized on %s",
this, (const char*) path));
}
#endif
mDir = aDir;
// Sigh. We have to allocate on the heap because there are no
// assignment operators defined.
rv = mDir->GetDirectoryEntries(getter_AddRefs(mIter));
if (NS_FAILED(rv)) return rv;
mBuf = "200: filename content-length last-modified file-type\n";
return NS_OK;
}
nsDirectoryIndexStream::~nsDirectoryIndexStream()
{
PR_LOG(gLog, PR_LOG_DEBUG,
("nsDirectoryIndexStream[%p]: destroyed", this));
}
nsresult
nsDirectoryIndexStream::Create(nsIFile* aDir, nsIInputStream** aResult)
{
nsDirectoryIndexStream* result = new nsDirectoryIndexStream();
if (! result)
return NS_ERROR_OUT_OF_MEMORY;
nsresult rv;
rv = result->Init(aDir);
if (NS_FAILED(rv)) {
delete result;
return rv;
}
*aResult = result;
NS_ADDREF(*aResult);
return NS_OK;
}
NS_IMPL_ISUPPORTS1(nsDirectoryIndexStream, nsIInputStream)
NS_IMETHODIMP
nsDirectoryIndexStream::Close()
{
return NS_OK;
}
NS_IMETHODIMP
nsDirectoryIndexStream::Available(PRUint32* aLength)
{
// Lie, and tell the caller that the stream is endless (until we
// actually don't have anything left).
PRBool more;
nsresult rv = mIter->HasMoreElements(&more);
if (NS_FAILED(rv)) return rv;
if (more) {
*aLength = PRUint32(-1);
return NS_OK;
}
else {
*aLength = 0;
return NS_OK;
}
}
NS_IMETHODIMP
nsDirectoryIndexStream::Read(char* aBuf, PRUint32 aCount, PRUint32* aReadCount)
{
PRUint32 nread = 0;
// If anything is enqueued (or left-over) in mBuf, then feed it to
// the reader first.
while (mOffset < (PRInt32)mBuf.Length() && aCount != 0) {
*(aBuf++) = char(mBuf.CharAt(mOffset++));
--aCount;
++nread;
}
// Room left?
if (aCount > 0) {
mOffset = 0;
mBuf.Truncate();
// Okay, now we'll suck stuff off of our iterator into the mBuf...
while (PRUint32(mBuf.Length()) < aCount) {
PRBool more;
nsresult rv = mIter->HasMoreElements(&more);
if (NS_FAILED(rv)) return rv;
if (!more) break;
nsCOMPtr<nsISupports> cur;
rv = mIter->GetNext(getter_AddRefs(cur));
nsCOMPtr<nsIFile> current = do_QueryInterface(cur, &rv);
if (NS_FAILED(rv)) return rv;
#ifdef PR_LOGGING
if (PR_LOG_TEST(gLog, PR_LOG_DEBUG)) {
nsXPIDLCString path;
current->GetPath(getter_Copies(path));
PR_LOG(gLog, PR_LOG_DEBUG,
("nsDirectoryIndexStream[%p]: iterated %s",
this, (const char*) path));
}
#endif
// rjc: don't return hidden files/directories!
PRBool hidden;
rv = current->IsHidden(&hidden);
if (NS_FAILED(rv)) return rv;
if (hidden) {
PR_LOG(gLog, PR_LOG_DEBUG,
("nsDirectoryIndexStream[%p]: skipping hidden file/directory",
this));
continue;
}
PRInt64 fileSize;
PRInt64 fileInfoModifyTime;
rv = current->GetFileSize( &fileSize );
if (NS_FAILED(rv)) return rv;
PROffset32 fileInfoSize;
LL_L2I( fileInfoSize,fileSize );
rv = current->GetLastModificationDate( &fileInfoModifyTime );
if (NS_FAILED(rv)) return rv;
mBuf += "201: ";
// The "filename" field
{
char* leafname;
rv = current->GetLeafName(&leafname);
if (NS_FAILED(rv)) return rv;
if (leafname) {
char* escaped = nsEscape(leafname, url_Path);
if (escaped) {
mBuf += escaped;
mBuf.Append(' ');
nsCRT::free(escaped);
}
nsCRT::free(leafname);
}
}
// The "content-length" field
mBuf.AppendInt(fileInfoSize, 10);
mBuf.Append(' ');
// The "last-modified" field
PRExplodedTime tm;
PR_ExplodeTime(fileInfoModifyTime, PR_GMTParameters, &tm);
{
char buf[64];
PR_FormatTimeUSEnglish(buf, sizeof(buf), "%a,%%20%d%%20%b%%20%Y%%20%H:%M:%S%%20GMT ", &tm);
mBuf.Append(buf);
}
// The "file-type" field
PRBool isFile;
rv = current->IsFile(&isFile);
if (NS_FAILED(rv)) return rv;
if (isFile) {
mBuf += "FILE ";
}
else {
PRBool isDir;
rv = current->IsDirectory(&isDir);
if (NS_FAILED(rv)) return rv;
if (isDir) {
mBuf += "DIRECTORY ";
}
else {
PRBool isLink;
rv = current->IsSymlink(&isLink);
if (NS_FAILED(rv)) return rv;
if (isLink) {
mBuf += "SYMBOLIC-LINK ";
}
}
}
mBuf.Append('\n');
}
// ...and once we've either run out of directory entries, or
// filled up the buffer, then we'll push it to the reader.
while (mOffset < (PRInt32)mBuf.Length() && aCount != 0) {
*(aBuf++) = char(mBuf.CharAt(mOffset++));
--aCount;
++nread;
}
}
*aReadCount = nread;
return NS_OK;
}
NS_IMETHODIMP
nsDirectoryIndexStream::ReadSegments(nsWriteSegmentFun writer, void * closure, PRUint32 count, PRUint32 *_retval)
{
NS_NOTREACHED("ReadSegments");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsDirectoryIndexStream::GetNonBlocking(PRBool *aNonBlocking)
{
NS_NOTREACHED("GetNonBlocking");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsDirectoryIndexStream::GetObserver(nsIInputStreamObserver * *aObserver)
{
NS_NOTREACHED("GetObserver");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsDirectoryIndexStream::SetObserver(nsIInputStreamObserver * aObserver)
{
NS_NOTREACHED("SetObserver");
return NS_ERROR_NOT_IMPLEMENTED;
}

View File

@@ -0,0 +1,56 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsDirectoryIndexStream_h__
#define nsDirectoryIndexStream_h__
#include "nsIFile.h"
#include "nsString.h"
#include "nsIInputStream.h"
#include "nsCOMPtr.h"
class nsDirectoryIndexStream : public nsIInputStream
{
protected:
nsCAutoString mBuf;
PRInt32 mOffset;
nsCOMPtr<nsIFile> mDir;
nsCOMPtr<nsISimpleEnumerator> mIter;
nsDirectoryIndexStream();
nsresult Init(nsIFile* aDir);
virtual ~nsDirectoryIndexStream();
public:
static nsresult
Create(nsIFile* aDir, nsIInputStream** aStreamResult);
// nsISupportsInterface
NS_DECL_ISUPPORTS
// nsIInputStream interface
NS_DECL_NSIINPUTSTREAM
};
#endif // nsDirectoryIndexStream_h__

View File

@@ -0,0 +1,178 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsDownloader.h"
#include "nsIInputStream.h"
#include "nsIURL.h"
#include "nsNetUtil.h"
#include "nsIChannel.h"
#include "nsIFileChannel.h"
#include "nsProxiedService.h"
#include "nsIFile.h"
#include "nsXPIDLString.h"
#include "nsCacheManager.h"
#include "nsICachedNetData.h"
#include "nsIStreamAsFile.h"
static NS_DEFINE_CID(kProxyObjectManagerCID, NS_PROXYEVENT_MANAGER_CID);
static NS_DEFINE_CID(kNetworkCacheManagerCID, NS_CACHE_MANAGER_CID);
NS_IMETHODIMP
nsDownloader::Init(nsIURI* aURL,
nsIDownloadObserver* aObserver,
nsISupports* aContext,
PRBool aIsSynchronous,
nsILoadGroup* aGroup,
nsIInterfaceRequestor* aNotificationCallbacks,
nsLoadFlags aLoadAttributes)
{
nsresult rv;
mObserver = aObserver;
mContext = aContext;
nsCOMPtr<nsIFile> localFile;
nsCOMPtr<nsIChannel> channel;
aLoadAttributes |= nsIChannel::CACHE_AS_FILE;
rv = NS_OpenURI(getter_AddRefs(channel), aURL, nsnull, aGroup, aNotificationCallbacks,
aLoadAttributes);
if (NS_SUCCEEDED(rv) && channel)
{
nsCOMPtr<nsIFileChannel> fc = do_QueryInterface(channel);
if (fc)
rv = fc->GetFile(getter_AddRefs(localFile));
}
if (mObserver && (NS_FAILED(rv) || localFile))
{
if (aIsSynchronous)
return mObserver->OnDownloadComplete(this, mContext, rv, localFile);
else
{
// If the open failed or the file is local, call the observer.
// don't callback synchronously as it puts the caller
// in a recursive situation and breaks the asynchronous
// semantics of nsIDownloader
nsresult rv2 = NS_OK;
NS_WITH_SERVICE(nsIProxyObjectManager, pIProxyObjectManager,
kProxyObjectManagerCID, &rv);
if (NS_FAILED(rv2)) return rv2;
nsCOMPtr<nsIDownloadObserver> pObserver;
rv2 = pIProxyObjectManager->GetProxyForObject(NS_CURRENT_EVENTQ,
NS_GET_IID(nsIDownloadObserver), mObserver,
PROXY_ASYNC | PROXY_ALWAYS, getter_AddRefs(pObserver));
if (NS_FAILED(rv2)) return rv2;
return pObserver->OnDownloadComplete(this, mContext, rv, localFile);
}
}
return channel->AsyncOpen(this, aContext);
}
NS_METHOD
nsDownloader::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{
if (aOuter) return NS_ERROR_NO_AGGREGATION;
nsDownloader* it = new nsDownloader();
if (it == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(it);
nsresult rv = it->QueryInterface(aIID, aResult);
NS_RELEASE(it);
return rv;
}
NS_IMPL_ISUPPORTS3(nsDownloader, nsIDownloader,
nsIStreamObserver, nsIStreamListener)
NS_IMETHODIMP
nsDownloader::OnStartRequest(nsIRequest *request, nsISupports *ctxt)
{
return NS_OK;
}
NS_IMETHODIMP
nsDownloader::OnStopRequest(nsIRequest *request, nsISupports *ctxt,
nsresult aStatus, const PRUnichar* aStatusArg)
{
nsCOMPtr<nsIFile> file;
if (NS_SUCCEEDED(aStatus))
{
nsresult rv;
nsCOMPtr<nsIURI> uri;
nsCOMPtr<nsIChannel> channel = do_QueryInterface(request, &rv);
if (NS_FAILED(rv)) return rv;
rv = channel->GetURI(getter_AddRefs(uri));
if (NS_FAILED(rv)) return rv;
nsXPIDLCString spec;
rv = uri->GetSpec(getter_Copies(spec));
if (NS_FAILED(rv)) return rv;
NS_WITH_SERVICE(nsINetDataCacheManager, cacheMgr, kNetworkCacheManagerCID, &rv);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsICachedNetData> cachedData;
rv = cacheMgr->GetCachedNetData(spec, nsnull, 0, nsINetDataCacheManager::CACHE_AS_FILE,
getter_AddRefs(cachedData));
if (NS_SUCCEEDED(rv))
{
nsCOMPtr<nsIStreamAsFile> streamAsFile;
streamAsFile = do_QueryInterface(cachedData, &rv);
if (NS_FAILED(rv)) return rv;
rv = streamAsFile->GetFile(getter_AddRefs(file));
if (NS_FAILED(rv)) return rv;
}
}
return mObserver->OnDownloadComplete(this, mContext, aStatus, file);
}
#define BUF_SIZE 1024
NS_IMETHODIMP
nsDownloader::OnDataAvailable(nsIRequest *request, nsISupports *ctxt,
nsIInputStream *inStr,
PRUint32 sourceOffset, PRUint32 count)
{
// This function simply disposes of the data as it's read in.
// We assume it's already been cached and that's what we're interested in.
nsresult rv = NS_OK;
char buffer[BUF_SIZE];
PRUint32 len, lenRead;
rv = inStr->Available(&len);
if (NS_FAILED(rv)) return rv;
while (len > 0) {
lenRead = PR_MIN(len, BUF_SIZE);
rv = inStr->Read(buffer, lenRead, &lenRead);
if (NS_FAILED(rv) || lenRead == 0) {
return rv;
}
len -= lenRead;
}
return rv;
}

View File

@@ -0,0 +1,53 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsDownloader_h__
#define nsDownloader_h__
#include "nsIDownloader.h"
#include "nsIStreamListener.h"
#include "nsCOMPtr.h"
#include "nsString.h"
class nsDownloader : public nsIDownloader,
public nsIStreamListener
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIDOWNLOADER
NS_DECL_NSISTREAMOBSERVER
NS_DECL_NSISTREAMLISTENER
nsDownloader() { NS_INIT_REFCNT();} ;
virtual ~nsDownloader() {};
static NS_METHOD
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
protected:
nsCOMPtr<nsIDownloadObserver> mObserver;
nsCOMPtr<nsISupports> mContext; // the observer's context
/// nsCOMPtr<nsILoadGroup> mLoadGroup;
};
#endif // nsDownloader_h__

View File

@@ -0,0 +1,572 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsFileStreams.h"
#include "nsILocalFile.h"
#include "nsXPIDLString.h"
#include "prerror.h"
#include "nsCRT.h"
#include "nsInt64.h"
#include "nsCExternalHandlerService.h"
#include "nsIMIMEService.h"
#include "nsIFile.h"
#include "nsDirectoryIndexStream.h"
#include "nsMimeTypes.h"
#define NS_NO_INPUT_BUFFERING 1 // see http://bugzilla.mozilla.org/show_bug.cgi?id=41067
#if defined(PR_LOGGING)
//
// Log module for nsFileTransport logging...
//
// To enable logging (see prlog.h for full details):
//
// set NSPR_LOG_MODULES=nsFileIO:5
// set NSPR_LOG_FILE=nspr.log
//
// this enables PR_LOG_DEBUG level information and places all output in
// the file nspr.log
//
PRLogModuleInfo* gFileIOLog = nsnull;
#endif /* PR_LOGGING */
////////////////////////////////////////////////////////////////////////////////
// nsFileIO
#define NS_INPUT_STREAM_BUFFER_SIZE (16 * 1024)
#define NS_OUTPUT_STREAM_BUFFER_SIZE (64 * 1024)
NS_IMPL_THREADSAFE_ISUPPORTS2(nsFileIO,
nsIFileIO,
nsIStreamIO)
nsFileIO::nsFileIO()
: mIOFlags(0),
mPerm(0),
mStatus(NS_OK)
{
NS_INIT_REFCNT();
#if defined(PR_LOGGING)
//
// Initialize the global PRLogModule for socket transport logging
// if necessary...
//
if (nsnull == gFileIOLog) {
gFileIOLog = PR_NewLogModule("nsFileIO");
}
mSpec = nsnull;
#endif /* PR_LOGGING */
}
nsFileIO::~nsFileIO()
{
(void)Close(NS_OK);
#ifdef PR_LOGGING
if (mSpec) nsCRT::free(mSpec);
#endif
}
NS_METHOD
nsFileIO::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{
if (aOuter)
return NS_ERROR_NO_AGGREGATION;
nsFileIO* io = new nsFileIO();
if (io == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(io);
nsresult rv = io->QueryInterface(aIID, aResult);
NS_RELEASE(io);
return rv;
}
NS_IMETHODIMP
nsFileIO::Init(nsIFile* file, PRInt32 ioFlags, PRInt32 perm)
{
NS_ASSERTION(file, "File must not be null");
if (file == nsnull)
return NS_ERROR_NOT_INITIALIZED;
mFile = file;
mIOFlags = ioFlags;
mPerm = perm;
#ifdef PR_LOGGING
nsresult rv = mFile->GetPath(&mSpec);
NS_ASSERTION(NS_SUCCEEDED(rv), "GetSpec failed");
#endif
return NS_OK;
}
NS_IMETHODIMP
nsFileIO::GetFile(nsIFile* *aFile)
{
*aFile = mFile;
NS_ADDREF(*aFile);
return NS_OK;
}
NS_IMETHODIMP
nsFileIO::Open(char **contentType, PRInt32 *contentLength)
{
NS_ASSERTION(mFile, "File must not be null");
if (mFile == nsnull)
return NS_ERROR_NOT_INITIALIZED;
*contentLength = 0;
*contentType = nsnull;
// don't actually open the file here -- we'll do it on demand in the
// GetInputStream/GetOutputStream methods
nsresult rv = NS_OK;
PRBool exist;
rv = mFile->Exists(&exist);
if (NS_FAILED(rv))
return rv;
if (!exist)
return NS_ERROR_FILE_NOT_FOUND;
// We'll try to use the file's length, if it has one. If not,
// assume the file to be special, and set the content length
// to -1, which means "read the stream until exhausted".
PRInt64 size;
rv = mFile->GetFileSize(&size);
if (NS_SUCCEEDED(rv)) {
*contentLength = nsInt64(size);
if (! *contentLength)
*contentLength = -1;
}
else
*contentLength = -1;
PRBool isDir;
rv = mFile->IsDirectory(&isDir);
if (NS_SUCCEEDED(rv) && isDir) {
// Directories turn into an HTTP-index stream, with
// unbounded (i.e., read 'til the stream says it's done)
// length.
*contentType = nsCRT::strdup(APPLICATION_HTTP_INDEX_FORMAT);
*contentLength = -1;
}
else {
nsCOMPtr<nsIMIMEService> mimeServ (do_GetService(NS_MIMESERVICE_CONTRACTID, &rv));
if (NS_SUCCEEDED(rv)) {
rv = mimeServ->GetTypeFromFile(mFile, contentType);
}
if (NS_FAILED(rv)) {
// if all else fails treat it as text/html?
*contentType = nsCRT::strdup(UNKNOWN_CONTENT_TYPE);
if (*contentType == nsnull)
rv = NS_ERROR_OUT_OF_MEMORY;
else
rv = NS_OK;
}
}
PR_LOG(gFileIOLog, PR_LOG_DEBUG,
("nsFileIO: logically opening %s: type=%s len=%d",
mSpec, *contentType, *contentLength));
return rv;
}
NS_IMETHODIMP
nsFileIO::Close(nsresult status)
{
if (mFile) {
PR_LOG(gFileIOLog, PR_LOG_DEBUG,
("nsFileIO: logically closing %s: status=%x",
mSpec, status));
mFile = nsnull;
}
mStatus = status;
return NS_OK;
}
NS_IMETHODIMP
nsFileIO::GetInputStream(nsIInputStream * *aInputStream)
{
NS_ASSERTION(mFile, "File must not be null");
if (mFile == nsnull)
return NS_ERROR_NOT_INITIALIZED;
nsresult rv;
PRBool isDir;
rv = mFile->IsDirectory(&isDir);
if (NS_SUCCEEDED(rv) && isDir) {
rv = nsDirectoryIndexStream::Create(mFile, aInputStream);
PR_LOG(gFileIOLog, PR_LOG_DEBUG,
("nsFileIO: opening local dir %s for input (%x)",
mSpec, rv));
return rv;
}
nsFileInputStream* fileIn = new nsFileInputStream();
if (fileIn == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(fileIn);
rv = fileIn->Init(mFile, mIOFlags, mPerm);
if (NS_SUCCEEDED(rv)) {
#ifdef NS_NO_INPUT_BUFFERING
*aInputStream = fileIn;
NS_ADDREF(*aInputStream);
#else
rv = NS_NewBufferedInputStream(aInputStream,
fileIn, NS_OUTPUT_STREAM_BUFFER_SIZE);
#endif
}
NS_RELEASE(fileIn);
PR_LOG(gFileIOLog, PR_LOG_DEBUG,
("nsFileIO: opening local file %s for input (%x)",
mSpec, rv));
return rv;
}
NS_IMETHODIMP
nsFileIO::GetOutputStream(nsIOutputStream * *aOutputStream)
{
NS_ASSERTION(mFile, "File must not be null");
if (mFile == nsnull)
return NS_ERROR_NOT_INITIALIZED;
nsresult rv;
PRBool isDir;
rv = mFile->IsDirectory(&isDir);
if (NS_SUCCEEDED(rv) && isDir) {
return NS_ERROR_FAILURE;
}
nsFileOutputStream* fileOut = new nsFileOutputStream();
if (fileOut == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(fileOut);
rv = fileOut->Init(mFile, mIOFlags, mPerm);
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIOutputStream> bufStr;
#ifdef NS_NO_OUTPUT_BUFFERING
*aOutputStream = fileOut;
NS_ADDREF(*aOutputStream);
#else
rv = NS_NewBufferedOutputStream(aOutputStream,
fileOut, NS_OUTPUT_STREAM_BUFFER_SIZE);
#endif
}
NS_RELEASE(fileOut);
PR_LOG(gFileIOLog, PR_LOG_DEBUG,
("nsFileIO: opening local file %s for output (%x)",
mSpec, rv));
return rv;
}
NS_IMETHODIMP
nsFileIO::GetName(char* *aName)
{
NS_ASSERTION(mFile, "File must not be null");
if (mFile == nsnull)
return NS_ERROR_NOT_INITIALIZED;
return mFile->GetPath(aName);
}
////////////////////////////////////////////////////////////////////////////////
// nsFileStream
nsFileStream::nsFileStream()
: mFD(nsnull)
{
NS_INIT_REFCNT();
}
nsFileStream::~nsFileStream()
{
Close();
}
NS_IMPL_THREADSAFE_ISUPPORTS1(nsFileStream, nsISeekableStream);
nsresult
nsFileStream::Close()
{
if (mFD) {
PR_Close(mFD);
mFD = nsnull;
}
return NS_OK;
}
NS_IMETHODIMP
nsFileStream::Seek(PRInt32 whence, PRInt32 offset)
{
if (mFD == nsnull)
return NS_BASE_STREAM_CLOSED;
PRInt32 cnt = PR_Seek(mFD, offset, (PRSeekWhence)whence);
if (cnt == -1) {
return NS_ErrorAccordingToNSPR();
}
return NS_OK;
}
NS_IMETHODIMP
nsFileStream::Tell(PRUint32 *result)
{
if (mFD == nsnull)
return NS_BASE_STREAM_CLOSED;
PRInt32 cnt = PR_Seek(mFD, 0, PR_SEEK_CUR);
if (cnt == -1) {
return NS_ErrorAccordingToNSPR();
}
*result = cnt;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsFileInputStream
NS_IMPL_ISUPPORTS_INHERITED2(nsFileInputStream,
nsFileStream,
nsIInputStream,
nsIFileInputStream);
NS_METHOD
nsFileInputStream::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{
NS_ENSURE_NO_AGGREGATION(aOuter);
nsFileInputStream* stream = new nsFileInputStream();
if (stream == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(stream);
nsresult rv = stream->QueryInterface(aIID, aResult);
NS_RELEASE(stream);
return rv;
}
NS_IMETHODIMP
nsFileInputStream::Init(nsIFile* file, PRInt32 ioFlags, PRInt32 perm)
{
NS_ASSERTION(mFD == nsnull, "already inited");
if (mFD != nsnull)
return NS_ERROR_FAILURE;
nsresult rv;
nsCOMPtr<nsILocalFile> localFile = do_QueryInterface(file, &rv);
if (NS_FAILED(rv)) return rv;
if (ioFlags == -1)
ioFlags = PR_RDONLY;
if (perm == -1)
perm = 0;
return localFile->OpenNSPRFileDesc(ioFlags, perm, &mFD);
}
NS_IMETHODIMP
nsFileInputStream::Close()
{
return nsFileStream::Close();
}
NS_IMETHODIMP
nsFileInputStream::Available(PRUint32 *result)
{
if (mFD == nsnull)
return NS_BASE_STREAM_CLOSED;
PRInt32 avail = PR_Available(mFD);
if (avail == -1) {
return NS_ErrorAccordingToNSPR();
}
*result = avail;
return NS_OK;
}
NS_IMETHODIMP
nsFileInputStream::Read(char * buf, PRUint32 count, PRUint32 *result)
{
if (mFD == nsnull)
return NS_BASE_STREAM_CLOSED;
PRInt32 cnt = PR_Read(mFD, buf, count);
if (cnt == -1) {
return NS_ErrorAccordingToNSPR();
}
*result = cnt;
return NS_OK;
}
NS_IMETHODIMP
nsFileInputStream::ReadSegments(nsWriteSegmentFun writer, void * closure, PRUint32 count, PRUint32 *_retval)
{
char *readBuf = (char *)nsMemory::Alloc(count);
PRUint32 nBytes;
if (!readBuf)
return NS_ERROR_OUT_OF_MEMORY;
nsresult rv = Read(readBuf, count, &nBytes);
*_retval = 0;
if (NS_SUCCEEDED(rv)) {
rv = writer(this, closure, readBuf, 0, nBytes, _retval);
NS_ASSERTION(nBytes == *_retval, "Didn't write all Data.");
}
nsMemory::Free(readBuf);
return rv;
}
NS_IMETHODIMP
nsFileInputStream::GetNonBlocking(PRBool *aNonBlocking)
{
NS_NOTREACHED("GetNonBlocking");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsFileInputStream::GetObserver(nsIInputStreamObserver * *aObserver)
{
NS_NOTREACHED("GetObserver");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsFileInputStream::SetObserver(nsIInputStreamObserver * aObserver)
{
NS_NOTREACHED("SetObserver");
return NS_ERROR_NOT_IMPLEMENTED;
}
////////////////////////////////////////////////////////////////////////////////
// nsFileOutputStream
NS_IMPL_ISUPPORTS_INHERITED2(nsFileOutputStream,
nsFileStream,
nsIOutputStream,
nsIFileOutputStream);
NS_METHOD
nsFileOutputStream::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{
NS_ENSURE_NO_AGGREGATION(aOuter);
nsFileOutputStream* stream = new nsFileOutputStream();
if (stream == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(stream);
nsresult rv = stream->QueryInterface(aIID, aResult);
NS_RELEASE(stream);
return rv;
}
NS_IMETHODIMP
nsFileOutputStream::Init(nsIFile* file, PRInt32 ioFlags, PRInt32 perm)
{
NS_ASSERTION(mFD == nsnull, "already inited");
if (mFD != nsnull)
return NS_ERROR_FAILURE;
nsresult rv;
nsCOMPtr<nsILocalFile> localFile = do_QueryInterface(file, &rv);
if (NS_FAILED(rv)) return rv;
if (ioFlags == -1)
ioFlags = PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE;
if (perm <= 0)
perm = 0664;
return localFile->OpenNSPRFileDesc(ioFlags, perm, &mFD);
}
NS_IMETHODIMP
nsFileOutputStream::Close()
{
return nsFileStream::Close();
}
NS_IMETHODIMP
nsFileOutputStream::Write(const char *buf, PRUint32 count, PRUint32 *result)
{
if (mFD == nsnull)
return NS_BASE_STREAM_CLOSED;
PRInt32 cnt = PR_Write(mFD, buf, count);
if (cnt == -1) {
return NS_ErrorAccordingToNSPR();
}
*result = cnt;
return NS_OK;
}
NS_IMETHODIMP
nsFileOutputStream::Flush(void)
{
if (mFD == nsnull)
return NS_BASE_STREAM_CLOSED;
PRInt32 cnt = PR_Sync(mFD);
if (cnt == -1) {
return NS_ErrorAccordingToNSPR();
}
return NS_OK;
}
NS_IMETHODIMP
nsFileOutputStream::WriteFrom(nsIInputStream *inStr, PRUint32 count, PRUint32 *_retval)
{
NS_NOTREACHED("WriteFrom");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsFileOutputStream::WriteSegments(nsReadSegmentFun reader, void * closure, PRUint32 count, PRUint32 *_retval)
{
NS_NOTREACHED("WriteSegments");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsFileOutputStream::GetNonBlocking(PRBool *aNonBlocking)
{
*aNonBlocking = PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP
nsFileOutputStream::SetNonBlocking(PRBool aNonBlocking)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsFileOutputStream::GetObserver(nsIOutputStreamObserver * *aObserver)
{
NS_NOTREACHED("GetObserver");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsFileOutputStream::SetObserver(nsIOutputStreamObserver * aObserver)
{
NS_NOTREACHED("SetObserver");
return NS_ERROR_NOT_IMPLEMENTED;
}
////////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,113 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsFileStreams_h__
#define nsFileStreams_h__
#include "nsIFileStreams.h"
#include "nsIFile.h"
#include "nsIChannel.h"
#include "nsIInputStream.h"
#include "nsIOutputStream.h"
#include "nsIStreamIO.h"
#include "nsCOMPtr.h"
#include "prlog.h"
////////////////////////////////////////////////////////////////////////////////
class nsFileIO : public nsIFileIO
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSISTREAMIO
NS_DECL_NSIFILEIO
nsFileIO();
virtual ~nsFileIO();
static NS_METHOD
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
protected:
nsCOMPtr<nsIFile> mFile;
PRInt32 mIOFlags;
PRInt32 mPerm;
nsresult mStatus;
#ifdef PR_LOGGING
char* mSpec;
#endif
};
////////////////////////////////////////////////////////////////////////////////
class nsFileStream : public nsISeekableStream
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSISEEKABLESTREAM
nsFileStream();
virtual ~nsFileStream();
nsresult Close();
protected:
PRFileDesc* mFD;
};
////////////////////////////////////////////////////////////////////////////////
class nsFileInputStream : public nsFileStream,
public nsIFileInputStream
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIINPUTSTREAM
NS_DECL_NSIFILEINPUTSTREAM
nsFileInputStream() : nsFileStream() {}
virtual ~nsFileInputStream() {}
static NS_METHOD
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
};
////////////////////////////////////////////////////////////////////////////////
class nsFileOutputStream : public nsFileStream,
public nsIFileOutputStream
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIOUTPUTSTREAM
NS_DECL_NSIFILEOUTPUTSTREAM
nsFileOutputStream() : nsFileStream() {}
virtual ~nsFileOutputStream() { nsFileOutputStream::Close(); }
static NS_METHOD
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
};
////////////////////////////////////////////////////////////////////////////////
#endif // nsFileStreams_h__

View File

@@ -0,0 +1,975 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Darin Fisher <darin@netscape.com>
*/
#include "nsFileTransport.h"
#include "nsFileTransportService.h"
#include "netCore.h"
#include "nsIFileStreams.h"
#include "nsIProxyObjectManager.h"
#include "nsIEventQueueService.h"
#include "nsNetUtil.h"
static NS_DEFINE_CID(kFileTransportServiceCID, NS_FILETRANSPORTSERVICE_CID);
static NS_DEFINE_CID(kProxyObjectManagerCID, NS_PROXYEVENT_MANAGER_CID);
static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
//////////////////////////////////////////////////////////////////////////////////
#if defined(PR_LOGGING)
static PRLogModuleInfo *gFileTransportLog = nsnull;
#endif
#define LOG(args) PR_LOG(gFileTransportLog, PR_LOG_DEBUG, args)
//////////////////////////////////////////////////////////////////////////////////
//
// An nsFileTransportSourceWrapper captures the number of bytes read from an
// input stream.
//
class nsFileTransportSourceWrapper : public nsIInputStream
{
public:
NS_DECL_ISUPPORTS
nsFileTransportSourceWrapper() : mBytesRead(0) {NS_INIT_ISUPPORTS();}
virtual ~nsFileTransportSourceWrapper() {}
//
// nsIInputStream implementation...
//
NS_IMETHOD Close() {
return mSource->Close();
}
NS_IMETHOD Available(PRUint32 *aCount) {
return mSource->Available(aCount);
}
NS_IMETHOD Read(char *aBuf, PRUint32 aCount, PRUint32 *aBytesRead) {
nsresult rv = mSource->Read(aBuf, aCount, aBytesRead);
if (NS_SUCCEEDED(rv))
mBytesRead += *aBytesRead;
return rv;
}
NS_IMETHOD ReadSegments(nsWriteSegmentFun aWriter, void *aClosure,
PRUint32 aCount, PRUint32 *aBytesRead) {
nsresult rv = mSource->ReadSegments(aWriter, aClosure, aCount, aBytesRead);
if (NS_SUCCEEDED(rv))
mBytesRead += *aBytesRead;
return rv;
}
NS_IMETHOD GetNonBlocking(PRBool *aValue) {
return mSource->GetNonBlocking(aValue);
}
NS_IMETHOD GetObserver(nsIInputStreamObserver **aObserver) {
return mSource->GetObserver(aObserver);
}
NS_IMETHOD SetObserver(nsIInputStreamObserver *aObserver) {
return mSource->SetObserver(aObserver);
}
//
// Helper functions
//
void SetSource(nsIInputStream *aSource) {
mSource = aSource;
}
PRUint32 GetBytesRead() {
return mBytesRead;
}
protected:
//
// State variables
//
PRUint32 mBytesRead;
nsCOMPtr<nsIInputStream> mSource;
};
// This must be threadsafe since different threads can run the same transport
NS_IMPL_THREADSAFE_ISUPPORTS1(nsFileTransportSourceWrapper, nsIInputStream)
//////////////////////////////////////////////////////////////////////////////////
//
// An nsFileTransportSinkWrapper captures the number of bytes written to an
// output stream.
//
class nsFileTransportSinkWrapper : public nsIOutputStream
{
public:
NS_DECL_ISUPPORTS
nsFileTransportSinkWrapper() : mBytesWritten(0) {NS_INIT_ISUPPORTS();}
virtual ~nsFileTransportSinkWrapper() {}
//
// nsIInputStream implementation...
//
NS_IMETHOD Close() {
return mSink->Close();
}
NS_IMETHOD Flush() {
return mSink->Flush();
}
NS_IMETHOD Write(const char *aBuf, PRUint32 aCount, PRUint32 *aBytesWritten) {
nsresult rv = mSink->Write(aBuf, aCount, aBytesWritten);
if (NS_SUCCEEDED(rv))
mBytesWritten += *aBytesWritten;
return rv;
}
NS_IMETHOD WriteFrom(nsIInputStream *aSource, PRUint32 aCount, PRUint32 *aBytesWritten) {
nsresult rv = mSink->WriteFrom(aSource, aCount, aBytesWritten);
if (NS_SUCCEEDED(rv))
mBytesWritten += *aBytesWritten;
return rv;
}
NS_IMETHOD WriteSegments(nsReadSegmentFun aReader, void *aClosure,
PRUint32 aCount, PRUint32 *aBytesWritten) {
nsresult rv = mSink->WriteSegments(aReader, aClosure, aCount, aBytesWritten);
if (NS_SUCCEEDED(rv))
mBytesWritten += *aBytesWritten;
return rv;
}
NS_IMETHOD GetNonBlocking(PRBool *aValue) {
return mSink->GetNonBlocking(aValue);
}
NS_IMETHOD SetNonBlocking(PRBool aValue) {
return mSink->SetNonBlocking(aValue);
}
NS_IMETHOD GetObserver(nsIOutputStreamObserver **aObserver) {
return mSink->GetObserver(aObserver);
}
NS_IMETHOD SetObserver(nsIOutputStreamObserver *aObserver) {
return mSink->SetObserver(aObserver);
}
//
// Helper functions
//
void SetSink(nsIOutputStream *aSink) {
mSink = aSink;
}
PRUint32 GetBytesWritten() {
return mBytesWritten;
}
protected:
//
// State variables
//
PRUint32 mBytesWritten;
nsCOMPtr<nsIOutputStream> mSink;
};
// This must be threadsafe since different threads can run the same transport
NS_IMPL_THREADSAFE_ISUPPORTS1(nsFileTransportSinkWrapper, nsIOutputStream)
//////////////////////////////////////////////////////////////////////////////////
nsFileTransport::nsFileTransport()
: mContentType(nsnull)
, mBufferMaxSize(NS_FILE_TRANSPORT_DEFAULT_BUFFER_SIZE)
, mXferState(CLOSED)
, mRunState(RUNNING)
, mStatus(NS_OK)
, mOffset(0)
, mTotalAmount(-1)
, mTransferAmount(-1)
, mSourceWrapper(nsnull)
, mSinkWrapper(nsnull)
, mService(nsnull)
, mEventPending(PR_FALSE)
{
NS_INIT_ISUPPORTS();
#if defined(PR_LOGGING)
if (!gFileTransportLog)
gFileTransportLog = PR_NewLogModule("nsFileTransport");
#endif
}
nsresult
nsFileTransport::Init(nsFileTransportService *aService, nsIFile* file, PRInt32 ioFlags, PRInt32 perm)
{
nsresult rv;
nsCOMPtr<nsIFileIO> io;
rv = NS_NewFileIO(getter_AddRefs(io), file, ioFlags, perm);
if (NS_FAILED(rv)) return rv;
return Init(aService, io);
}
nsresult
nsFileTransport::Init(nsFileTransportService *aService, const char* name, nsIInputStream* inStr,
const char* contentType, PRInt32 contentLength)
{
nsresult rv;
nsCOMPtr<nsIInputStreamIO> io;
rv = NS_NewInputStreamIO(getter_AddRefs(io),
name, inStr, contentType, contentLength);
if (NS_FAILED(rv)) return rv;
return Init(aService, io);
}
nsresult
nsFileTransport::Init(nsFileTransportService *aService, nsIStreamIO* io)
{
nsresult rv = NS_OK;
mStreamIO = io;
nsXPIDLCString name;
rv = mStreamIO->GetName(getter_Copies(name));
mStreamName = NS_STATIC_CAST(const char*, name);
NS_ASSERTION(NS_SUCCEEDED(rv), "GetName failed");
NS_ADDREF(mService = aService);
PR_AtomicIncrement(&mService->mTotalTransports);
return rv;
}
nsFileTransport::~nsFileTransport()
{
if (mXferState != CLOSED)
DoClose();
NS_ASSERTION(mSourceWrapper == nsnull, "transport not closed");
NS_ASSERTION(mSink == nsnull, "transport not closed");
NS_ASSERTION(mSinkWrapper == nsnull, "transport not closed");
if (mContentType) {
nsCRT::free(mContentType);
mContentType = nsnull;
}
NS_IF_RELEASE(mService);
}
NS_IMPL_THREADSAFE_ISUPPORTS3(nsFileTransport,
nsITransport,
nsITransportRequest,
nsIRequest)
NS_METHOD
nsFileTransport::Create(nsISupports* aOuter, const nsIID& aIID, void* *aResult)
{
nsFileTransport* fc = new nsFileTransport();
if (fc == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(fc);
nsresult rv = fc->QueryInterface(aIID, aResult);
NS_RELEASE(fc);
return rv;
}
////////////////////////////////////////////////////////////////////////////////
// From nsIRequest
////////////////////////////////////////////////////////////////////////////////
NS_IMETHODIMP
nsFileTransport::GetName(PRUnichar* *result)
{
nsString name;
name.AppendWithConversion(mStreamName);
*result = name.ToNewUnicode();
return *result ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
}
NS_IMETHODIMP
nsFileTransport::IsPending(PRBool *result)
{
*result = mXferState != CLOSED;
return NS_OK;
}
NS_IMETHODIMP
nsFileTransport::GetStatus(nsresult *status)
{
NS_ENSURE_ARG_POINTER(status);
*status = mStatus;
return NS_OK;
}
NS_IMETHODIMP
nsFileTransport::Cancel(nsresult status)
{
mStatus = status;
mRunState = CANCELED;
LOG(("nsFileTransport: Cancel [this=%x %s]\n", this, mStreamName.get()));
return Dispatch();
}
NS_IMETHODIMP
nsFileTransport::Suspend()
{
if (mRunState == CANCELED)
return NS_OK;
LOG(("nsFileTransport: Suspend [this=%x %s]\n", this, mStreamName.get()));
mRunState = SUSPENDED;
mService->AddSuspendedTransport(this);
return NS_OK;
}
NS_IMETHODIMP
nsFileTransport::Resume()
{
if (mRunState == CANCELED)
return NS_OK;
LOG(("nsFileTransport: Resume [this=%x %s]\n", this, mStreamName.get()));
mRunState = RUNNING;
mService->RemoveSuspendedTransport(this);
return Dispatch();
}
////////////////////////////////////////////////////////////////////////////////
// From nsITransportRequest
////////////////////////////////////////////////////////////////////////////////
NS_IMETHODIMP
nsFileTransport::GetTransport(nsITransport **result)
{
NS_ENSURE_ARG_POINTER(result);
NS_ADDREF(*result = this);
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// From nsITransport
////////////////////////////////////////////////////////////////////////////////
NS_IMETHODIMP
nsFileTransport::OpenInputStream(PRUint32 aTransferOffset,
PRUint32 aTransferCount,
PRUint32 aFlags,
nsIInputStream **aResult)
{
NS_ENSURE_ARG_POINTER(aResult);
NS_ASSERTION(aTransferCount == ULONG_MAX, "need to wrap input stream in one that truncates");
nsresult rv = mStreamIO->GetInputStream(aResult);
if (NS_SUCCEEDED(rv) && aTransferOffset) {
nsCOMPtr<nsISeekableStream> seekable(do_QueryInterface(*aResult, &rv));
if (NS_SUCCEEDED(rv) && seekable) {
rv = seekable->Seek(nsISeekableStream::NS_SEEK_SET, aTransferOffset);
}
}
return rv;
}
NS_IMETHODIMP
nsFileTransport::OpenOutputStream(PRUint32 aTransferOffset,
PRUint32 aTransferCount,
PRUint32 aFlags,
nsIOutputStream **aResult)
{
NS_ENSURE_ARG_POINTER(aResult);
NS_ASSERTION(aTransferCount == ULONG_MAX, "need to wrap output stream in one that truncates");
nsresult rv = mStreamIO->GetOutputStream(aResult);
if (NS_SUCCEEDED(rv) && aTransferOffset) {
nsCOMPtr<nsISeekableStream> seekable(do_QueryInterface(*aResult, &rv));
if (NS_SUCCEEDED(rv) && seekable) {
rv = seekable->Seek(nsISeekableStream::NS_SEEK_SET, aTransferOffset);
}
}
return rv;
}
NS_IMETHODIMP
nsFileTransport::AsyncRead(nsIStreamListener *aListener,
nsISupports *aContext,
PRUint32 aTransferOffset,
PRUint32 aTransferCount,
PRUint32 aFlags,
nsIRequest **aResult)
{
NS_ENSURE_ARG_POINTER(aResult);
if (mXferState != CLOSED)
return NS_ERROR_IN_PROGRESS;
NS_ASSERTION(aListener, "need to supply an nsIStreamListener");
NS_ASSERTION(mContext == nsnull, "context not released");
mListener = aListener;
mContext = aContext;
mOffset = aTransferOffset;
mTransferAmount = aTransferCount;
mXferState = OPEN_FOR_READ;
LOG(("nsFileTransport: AsyncRead [this=%x %s] mOffset=%d mTransferAmount=%d\n",
this, mStreamName.get(), mOffset, mTransferAmount));
NS_ADDREF(*aResult = this);
return Dispatch();
}
NS_IMETHODIMP
nsFileTransport::AsyncWrite(nsIStreamProvider *aProvider,
nsISupports *aContext,
PRUint32 aTransferOffset,
PRUint32 aTransferCount,
PRUint32 aFlags,
nsIRequest **aResult)
{
NS_ENSURE_ARG_POINTER(aResult);
LOG(("nsFileTransport: AsyncWrite [this=%x, provider=%x]\n",
this, aProvider));
if (mXferState != CLOSED)
return NS_ERROR_IN_PROGRESS;
NS_ASSERTION(aProvider, "need to supply an nsIStreamProvider");
NS_ASSERTION(mContext == nsnull, "context not released");
mProvider = aProvider;
mContext = aContext;
mOffset = aTransferOffset;
mTransferAmount = aTransferCount;
mXferState = OPEN_FOR_WRITE;
LOG(("nsFileTransport: AsyncWrite [this=%x %s] mOffset=%d mTransferAmount=%d\n",
this, mStreamName.get(), mOffset, mTransferAmount));
NS_ADDREF(*aResult = this);
return Dispatch();
}
//-----------------------------------------------------------------------------
// internal methods
//-----------------------------------------------------------------------------
nsresult
nsFileTransport::Dispatch()
{
if (mEventPending)
return NS_OK;
if (!mEventQ) {
nsresult rv;
nsCOMPtr<nsIEventQueueService> serv =
do_GetService(kEventQueueServiceCID, &rv);
if (NS_FAILED(rv)) return rv;
rv = serv->GetThreadEventQueue(NS_CURRENT_THREAD,
getter_AddRefs(mEventQ));
if (NS_FAILED(rv)) return rv;
}
PLEvent *event = new PLEvent();
PL_InitEvent(event, this,
(PLHandleEventProc) nsFileTransport::HandlePLEvent,
(PLDestroyEventProc) nsFileTransport::DestroyPLEvent);
mEventPending = PR_TRUE;
NS_ADDREF(this);
PRStatus status = mEventQ->PostEvent(event);
return status == PR_SUCCESS ? NS_OK : NS_ERROR_FAILURE;
}
void PR_CALLBACK
nsFileTransport::HandlePLEvent(PLEvent *event)
{
nsFileTransport *self = (nsFileTransport *) PL_GetEventOwner(event);
if (self)
self->HandleEvent();
NS_RELEASE(self);
}
void PR_CALLBACK
nsFileTransport::DestroyPLEvent(PLEvent *event)
{
delete event;
}
void
nsFileTransport::HandleEvent()
{
LOG(("nsFileTransport::HandleEvent [this=%x]\n", this));
mEventPending = PR_FALSE;
if (mRunState == SUSPENDED)
return;
if (mXferState != CLOSED) {
//
// Change transfer state if canceled.
//
if (mRunState == CANCELED) {
if (mXferState == READING)
mXferState = END_READ;
else if (mXferState == WRITING)
mXferState = END_WRITE;
else
mXferState = CLOSING;
}
while (Process());
}
LOG(("nsFileTransport: Leaving Run [xferState=%d runState=%d]\n",
mXferState, mRunState));
if (mXferState != CLOSED)
Dispatch();
}
PRBool
nsFileTransport::Process()
{
// return TRUE to cause Process to be re-run immediately
LOG(("nsFileTransport: Inside Process [this=%x state=%x status=%x]\n",
this, mXferState, mStatus));
switch (mXferState) {
case OPEN_FOR_READ: {
mStatus = mStreamIO->Open(&mContentType, &mTotalAmount);
LOG(("nsFileTransport: OPEN_FOR_READ [this=%x %s] status=%x\n", this, mStreamName.get(), mStatus));
if (mListener) {
nsresult rv = mListener->OnStartRequest(this, mContext); // always send the start notification
if (NS_SUCCEEDED(mStatus))
mStatus = rv;
}
mXferState = NS_FAILED(mStatus) ? END_READ : START_READ;
return PR_TRUE;
}
case START_READ: {
LOG(("nsFileTransport: START_READ [this=%x %s]\n", this, mStreamName.get()));
PR_AtomicIncrement(&mService->mInUseTransports);
nsCOMPtr<nsIInputStream> source;
mStatus = mStreamIO->GetInputStream(getter_AddRefs(source));
if (NS_FAILED(mStatus)) {
LOG(("nsFileTransport: mStreamIO->GetInputStream() failed [this=%x rv=%x]\n",
this, mStatus));
mXferState = END_READ;
return PR_TRUE;
}
if (mOffset > 0) {
// if we need to set a starting offset, QI for the nsISeekableStream
// and set it
nsCOMPtr<nsISeekableStream> ras = do_QueryInterface(source, &mStatus);
if (NS_FAILED(mStatus)) {
mXferState = END_READ;
return PR_TRUE;
}
// for now, assume the offset is always relative to the start of the
// file (position 0) so use PR_SEEK_SET
mStatus = ras->Seek(PR_SEEK_SET, mOffset);
if (NS_FAILED(mStatus)) {
mXferState = END_READ;
return PR_TRUE;
}
}
if (!mSourceWrapper) {
//
// Allocate an input stream wrapper to capture the number of bytes
// read from source.
//
NS_NEWXPCOM(mSourceWrapper, nsFileTransportSourceWrapper);
if (!mSourceWrapper) {
mStatus = NS_ERROR_OUT_OF_MEMORY;
mXferState = END_READ;
return PR_TRUE;
}
NS_ADDREF(mSourceWrapper);
mSourceWrapper->SetSource(source);
}
// capture the total amount for progress information
if (mTransferAmount < 0) {
mTransferAmount = mTotalAmount;
} else
mTotalAmount = mTransferAmount;
mXferState = READING;
break;
}
case READING: {
//
// Read at most mBufferMaxSize.
//
PRInt32 transferAmt = mBufferMaxSize;
if (mTransferAmount >= 0)
transferAmt = PR_MIN(transferAmt, mTransferAmount);
LOG(("nsFileTransport: READING [this=%x %s] transferAmt=%u mBufferMaxSize=%u\n",
this, mStreamName.get(), transferAmt, mBufferMaxSize));
PRUint32 offset = mSourceWrapper->GetBytesRead();
//
// Give the listener a chance to read at most transferAmt bytes from
// the source input stream.
//
nsresult status = mListener->OnDataAvailable(this, mContext,
mSourceWrapper,
mOffset, transferAmt);
//
// Handle the various return codes.
//
if (status == NS_BASE_STREAM_WOULD_BLOCK) {
LOG(("nsFileTransport: READING [this=%x %s] listener would block; suspending self.\n",
this, mStreamName.get()));
mStatus = NS_OK;
mRunState = SUSPENDED;
}
else if (status == NS_BASE_STREAM_CLOSED) {
LOG(("nsFileTransport: READING [this=%x %s] done reading file.\n",
this, mStreamName.get()));
mStatus = NS_OK;
mXferState = END_READ;
}
else if (NS_FAILED(status)) {
LOG(("nsFileTransport: READING [this=%x %s] error reading file.\n",
this, mStreamName.get()));
mStatus = status;
mXferState = END_READ;
}
else {
//
// get the number of bytes read
//
PRUint32 total = mSourceWrapper->GetBytesRead() - offset;
offset += total;
mOffset += total;
if (mTransferAmount > 0)
mTransferAmount -= total;
if (total == 0 || mTransferAmount == 0) {
LOG(("nsFileTransport: READING [this=%x %s] done reading file.\n",
this, mStreamName.get()));
mXferState = END_READ;
}
else
LOG(("nsFileTransport: READING [this=%x %s] read %u bytes [offset=%u]\n",
this, mStreamName.get(), total, mOffset));
if (mProgress)
mProgress->OnProgress(this, mContext, offset,
PR_MAX(mTotalAmount, 0));
}
if (mXferState != READING)
return PR_TRUE;
break;
}
case END_READ: {
PR_AtomicDecrement(&mService->mInUseTransports);
LOG(("nsFileTransport: END_READ [this=%x %s] status=%x\n",
this, mStreamName.get(), mStatus));
if (mTransferAmount > 0 && NS_SUCCEEDED(mStatus)) {
//
// This happens when the requested read amount is more than the amount
// of the data in the stream/file, or if the listener returned
// NS_BASE_STREAM_CLOSED.
//
mStatus = NS_BASE_STREAM_CLOSED;
}
if (mListener) {
mListener->OnStopRequest(this, mContext, mStatus, nsnull);
mListener = 0;
}
if (mProgress) {
nsAutoString fileName;
fileName.AssignWithConversion(mStreamName);
mProgress->OnStatus(this, mContext,
NS_NET_STATUS_READ_FROM,
fileName.GetUnicode());
}
mContext = 0;
// close the data source
NS_IF_RELEASE(mSourceWrapper);
mSourceWrapper = nsnull;
mXferState = CLOSING;
return PR_TRUE;
}
case OPEN_FOR_WRITE: {
LOG(("nsFileTransport: OPEN_FOR_WRITE [this=%x %s]\n",
this, mStreamName.get()));
mStatus = mStreamIO->Open(&mContentType, &mTotalAmount);
if (mProvider) {
// always send the start notification
nsresult rv = mProvider->OnStartRequest(this, mContext);
if (NS_SUCCEEDED(mStatus))
mStatus = rv;
}
mXferState = NS_FAILED(mStatus) ? END_WRITE : START_WRITE;
return PR_TRUE;
}
case START_WRITE: {
LOG(("nsFileTransport: START_WRITE [this=%x %s]\n",
this, mStreamName.get()));
PR_AtomicIncrement(&mService->mInUseTransports);
mStatus = mStreamIO->GetOutputStream(getter_AddRefs(mSink));
if (NS_FAILED(mStatus)) {
mXferState = END_WRITE;
return PR_TRUE;
}
if (mOffset > 0) {
// If we need to set a starting offset, QI for the nsISeekableStream
// and set it.
nsCOMPtr<nsISeekableStream> ras = do_QueryInterface(mSink, &mStatus);
if (NS_FAILED(mStatus)) {
mXferState = END_WRITE;
return PR_TRUE;
}
// For now, assume the offset is always relative to the start of the
// file (position 0) so use PR_SEEK_SET.
mStatus = ras->Seek(PR_SEEK_SET, mOffset);
if (NS_FAILED(mStatus)) {
mXferState = END_WRITE;
return PR_TRUE;
}
mOffset = 0;
}
if (!mSinkWrapper) {
//
// Allocate an output stream wrapper to capture the number of bytes
// written to mSink.
//
NS_NEWXPCOM(mSinkWrapper, nsFileTransportSinkWrapper);
if (!mSinkWrapper) {
mStatus = NS_ERROR_OUT_OF_MEMORY;
mXferState = END_WRITE;
return PR_TRUE;
}
NS_ADDREF(mSinkWrapper);
mSinkWrapper->SetSink(mSink);
}
mXferState = WRITING;
break;
}
case WRITING: {
//
// Write at most mBufferMaxSize
//
PRUint32 transferAmt = mBufferMaxSize;
if (mTransferAmount >= 0)
transferAmt = PR_MIN(transferAmt, (PRUint32)mTransferAmount);
PRUint32 offset = mSinkWrapper->GetBytesWritten();
//
// Ask the provider for data
//
nsresult status = mProvider->OnDataWritable(this, mContext,
mSinkWrapper,
mOffset, transferAmt);
//
// Handle the various return codes.
//
if (status == NS_BASE_STREAM_WOULD_BLOCK) {
LOG(("nsFileTransport: WRITING [this=%x %s] provider would block; suspending self.\n",
this, mStreamName.get()));
mStatus = NS_OK;
mRunState = SUSPENDED;
}
else if (status == NS_BASE_STREAM_CLOSED) {
LOG(("nsFileTransport: WRITING [this=%x %s] no more data to be written.\n",
this, mStreamName.get()));
mStatus = NS_OK;
mXferState = END_WRITE;
}
else if (NS_FAILED(status)) {
LOG(("nsFileTransport: WRITING [this=%x %s] provider failed.\n",
this, mStreamName.get()));
mStatus = status;
mXferState = END_WRITE;
}
else {
//
// Get the number of bytes written
//
PRUint32 total = mSinkWrapper->GetBytesWritten() - offset;
offset += total;
mOffset += total;
if (mTransferAmount > 0)
mTransferAmount -= total;
if (total == 0 || mTransferAmount == 0) {
LOG(("nsFileTransport: WRITING [this=%x %s] done writing file.\n",
this, mStreamName.get()));
mXferState = END_WRITE;
}
else
LOG(("nsFileTransport: WRITING [this=%x %s] wrote %u bytes [offset=%u]\n",
this, mStreamName.get(), total, mOffset));
if (mProgress)
mProgress->OnProgress(this, mContext, offset,
PR_MAX(mTotalAmount, 0));
}
if (mXferState != WRITING)
return PR_TRUE;
break;
}
case END_WRITE: {
LOG(("nsFileTransport: END_WRITE [this=%x %s] status=%x\n",
this, mStreamName.get(), mStatus));
PR_AtomicDecrement(&mService->mInUseTransports);
if (mTransferAmount > 0 && NS_SUCCEEDED(mStatus)) {
// This happens when the requested write amount is more than the amount
// of the data in the stream/file.
mStatus = NS_BASE_STREAM_CLOSED;
}
if (mSink) {
mSink->Flush();
mSink = 0;
}
NS_IF_RELEASE(mSinkWrapper);
mSinkWrapper = nsnull;
if (mProvider) {
mProvider->OnStopRequest(this, mContext, mStatus, nsnull);
mProvider = 0;
}
if (mProgress) {
nsAutoString fileName; fileName.AssignWithConversion(mStreamName);
nsresult rv = mProgress->OnStatus(this, mContext,
NS_NET_STATUS_WROTE_TO,
fileName.GetUnicode());
NS_ASSERTION(NS_SUCCEEDED(rv), "unexpected OnStatus failure");
}
mContext = 0;
mXferState = CLOSING;
return PR_TRUE;
}
case CLOSING: {
DoClose();
break;
}
case CLOSED: {
NS_NOTREACHED("trying to continue a quiescent file transfer");
break;
}
}
LOG(("nsFileTransport: Leaving Process [this=%x state=%x status=%x]\n",
this, mXferState, mStatus));
return PR_FALSE;
}
void
nsFileTransport::DoClose(void)
{
LOG(("nsFileTransport: CLOSING [this=%x %s] status=%x\n",
this, mStreamName.get(), mStatus));
if (mStreamIO) {
nsresult rv = mStreamIO->Close(mStatus);
NS_ASSERTION(NS_SUCCEEDED(rv), "unexpected Close failure");
mStreamIO = 0;
}
mXferState = CLOSED;
PR_AtomicDecrement(&mService->mConnectedTransports);
}
NS_IMETHODIMP
nsFileTransport::GetSecurityInfo(nsISupports * *aSecurityInfo)
{
*aSecurityInfo = nsnull;
return NS_OK;
}
NS_IMETHODIMP
nsFileTransport::GetNotificationCallbacks(nsIInterfaceRequestor** aCallbacks)
{
NS_ENSURE_ARG_POINTER(aCallbacks);
*aCallbacks = mNotificationCallbacks;
NS_IF_ADDREF(*aCallbacks);
return NS_OK;
}
NS_IMETHODIMP
nsFileTransport::SetNotificationCallbacks(nsIInterfaceRequestor* aCallbacks,
PRBool isBackground)
{
mNotificationCallbacks = aCallbacks;
mProgress = 0;
if (!mNotificationCallbacks || isBackground) return NS_OK;
nsCOMPtr<nsIProgressEventSink> sink(do_GetInterface(mNotificationCallbacks));
if (!sink) return NS_ERROR_FAILURE;
nsresult rv;
NS_WITH_SERVICE(nsIProxyObjectManager,
proxyMgr, kProxyObjectManagerCID, &rv);
if (NS_FAILED(rv)) return rv;
return proxyMgr->GetProxyForObject(NS_UI_THREAD_EVENTQ, // primordial thread - should change?
NS_GET_IID(nsIProgressEventSink),
sink,
PROXY_ASYNC | PROXY_ALWAYS,
getter_AddRefs(mProgress));
}
////////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,140 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Darin Fisher <darin@netscape.com>
*/
#ifndef nsFileTransport_h__
#define nsFileTransport_h__
#include "nsFileTransportService.h"
#include "nsITransport.h"
#include "nsIRequest.h"
#include "nsCOMPtr.h"
#include "nsIStreamListener.h"
#include "nsIStreamProvider.h"
#include "nsIProgressEventSink.h"
#include "nsIInputStream.h"
#include "nsIOutputStream.h"
#include "nsIStreamIO.h"
#include "nsIInterfaceRequestor.h"
#include "nsIFile.h"
#include "nsIEventQueue.h"
#include "plevent.h"
#include "prlog.h"
class nsFileTransportSourceWrapper;
class nsFileTransportSinkWrapper;
class nsFileTransport : public nsITransport,
public nsITransportRequest
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSITRANSPORT
NS_DECL_NSIREQUEST
NS_DECL_NSITRANSPORTREQUEST
nsFileTransport();
// Always make the destructor virtual:
virtual ~nsFileTransport();
// Define a Create method to be used with a factory:
static NS_METHOD
Create(nsISupports* aOuter, const nsIID& aIID, void* *aResult);
nsresult Init(nsFileTransportService *aService, nsIFile* file,
PRInt32 ioFlags,
PRInt32 perm);
nsresult Init(nsFileTransportService *aService, const char* name,
nsIInputStream* fromStream,
const char* contentType,
PRInt32 contentLength);
nsresult Init(nsFileTransportService *aService, nsIStreamIO* io);
enum XferState {
CLOSED,
OPEN_FOR_READ,
START_READ,
READING,
END_READ,
OPEN_FOR_WRITE,
START_WRITE,
WRITING,
END_WRITE,
CLOSING
};
enum RunState {
RUNNING,
SUSPENDED,
CANCELED
};
protected:
nsresult Dispatch();
void HandleEvent();
PRBool Process();
void DoClose();
static void PR_CALLBACK HandlePLEvent(PLEvent *);
static void PR_CALLBACK DestroyPLEvent(PLEvent *);
protected:
nsCOMPtr<nsIProgressEventSink> mProgress;
nsCOMPtr<nsIInterfaceRequestor> mNotificationCallbacks;
nsCOMPtr<nsIStreamIO> mStreamIO;
char *mContentType;
PRUint32 mBufferMaxSize;
nsCOMPtr<nsISupports> mContext;
// mXferState is only changed by the file transport thread:
XferState mXferState;
// mRunState is only changed by the user's thread, but looked at by the
// file transport thread:
RunState mRunState;
// state variables:
nsresult mStatus;
PRUint32 mOffset;
PRInt32 mTotalAmount;
PRInt32 mTransferAmount;
// reading state variables:
nsCOMPtr<nsIStreamListener> mListener;
nsFileTransportSourceWrapper *mSourceWrapper;
// writing state variables:
nsCOMPtr<nsIStreamProvider> mProvider;
nsCOMPtr<nsIOutputStream> mSink;
nsFileTransportSinkWrapper *mSinkWrapper;
nsCString mStreamName;
nsFileTransportService *mService;
nsCOMPtr<nsIEventQueue> mEventQ;
PRPackedBool mEventPending;
};
#define NS_FILE_TRANSPORT_DEFAULT_BUFFER_SIZE (4*1024)
#endif /* !defined(nsFileTransport_h__) */

View File

@@ -0,0 +1,223 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsFileTransport.h"
#include "nsFileTransportService.h"
#include "nsIURL.h"
#include "nsCRT.h"
#include "nsIComponentManager.h"
#include "nsIServiceManager.h"
#include "nsIProgressEventSink.h"
//#include "nsIThreadPool.h"
#include "nsISupportsArray.h"
#include "nsFileSpec.h"
#include "nsAutoLock.h"
static NS_DEFINE_CID(kStandardURLCID, NS_STANDARDURL_CID);
////////////////////////////////////////////////////////////////////////////////
nsFileTransportService::nsFileTransportService()
: mConnectedTransports(0)
, mTotalTransports(0)
, mInUseTransports(0)
{
NS_INIT_REFCNT();
}
#define NS_FILE_TRANSPORT_WORKER_STACK_SIZE (64 * 1024) /* (8*1024) */
nsresult
nsFileTransportService::Init()
{
/*
nsresult rv;
rv = NS_NewThreadPool(getter_AddRefs(mPool),
NS_FILE_TRANSPORT_WORKER_COUNT_MIN,
NS_FILE_TRANSPORT_WORKER_COUNT_MAX,
NS_FILE_TRANSPORT_WORKER_STACK_SIZE);
return rv;
*/
return NS_OK;
}
nsFileTransportService::~nsFileTransportService()
{
}
NS_IMPL_THREADSAFE_ISUPPORTS1(nsFileTransportService, nsFileTransportService);
NS_METHOD
nsFileTransportService::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{
if (aOuter)
return NS_ERROR_NO_AGGREGATION;
nsFileTransportService* ph = new nsFileTransportService();
if (ph == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(ph);
nsresult rv = ph->Init();
if (NS_SUCCEEDED(rv)) {
rv = ph->QueryInterface(aIID, aResult);
}
NS_RELEASE(ph);
return rv;
}
////////////////////////////////////////////////////////////////////////////////
NS_IMETHODIMP
nsFileTransportService::CreateTransport(nsIFile* file,
PRInt32 ioFlags,
PRInt32 perm,
nsITransport** result)
{
nsresult rv;
nsFileTransport* trans = new nsFileTransport();
if (trans == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(trans);
rv = trans->Init(this, file, ioFlags, perm);
if (NS_FAILED(rv)) {
NS_RELEASE(trans);
return rv;
}
*result = trans;
return NS_OK;
}
NS_IMETHODIMP
nsFileTransportService::CreateTransportFromStream(const char* name,
nsIInputStream *fromStream,
const char* contentType,
PRInt32 contentLength,
nsITransport** result)
{
nsresult rv;
nsFileTransport* trans = new nsFileTransport();
if (trans == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(trans);
rv = trans->Init(this, name, fromStream, contentType, contentLength);
if (NS_FAILED(rv)) {
NS_RELEASE(trans);
return rv;
}
*result = trans;
return NS_OK;
}
NS_IMETHODIMP
nsFileTransportService::CreateTransportFromStreamIO(nsIStreamIO *io,
nsITransport **result)
{
nsresult rv;
nsFileTransport* trans = new nsFileTransport();
if (trans == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(trans);
rv = trans->Init(this, io);
if (NS_FAILED(rv)) {
NS_RELEASE(trans);
return rv;
}
*result = trans;
return NS_OK;
}
nsresult
nsFileTransportService::ProcessPendingRequests(void)
{
return NS_OK; //return mPool->ProcessPendingRequests();
}
nsresult
nsFileTransportService::Shutdown(void)
{
PRUint32 count;
mSuspendedTransportList.Count(&count);
for (PRUint32 i=0; i<count; i++) {
nsCOMPtr<nsISupports> supports;
mSuspendedTransportList.GetElementAt(i, getter_AddRefs(supports));
nsCOMPtr<nsIRequest> trans = do_QueryInterface(supports);
trans->Cancel(NS_BINDING_ABORTED);
}
mSuspendedTransportList.Clear();
return NS_OK; //mPool->Shutdown();
}
nsresult
nsFileTransportService::DispatchRequest(nsIRunnable* runnable)
{
return NS_OK; //mPool->DispatchRequest(runnable);
}
////////////////////////////////////////////////////////////////////////////////
nsresult
nsFileTransportService::AddSuspendedTransport(nsITransport* trans)
{
NS_STATIC_CAST(nsISupportsArray*, &mSuspendedTransportList)->AppendElement(trans);
return NS_OK;
}
nsresult
nsFileTransportService::RemoveSuspendedTransport(nsITransport* trans)
{
NS_STATIC_CAST(nsISupportsArray*, &mSuspendedTransportList)->RemoveElement(trans);
return NS_OK;
}
NS_IMETHODIMP
nsFileTransportService::GetTotalTransportCount(PRUint32 * o_TransCount)
{
if (!o_TransCount)
return NS_ERROR_NULL_POINTER;
*o_TransCount = (PRUint32) mTotalTransports;
return NS_OK;
}
NS_IMETHODIMP
nsFileTransportService::GetConnectedTransportCount(PRUint32 * o_TransCount)
{
if (!o_TransCount)
return NS_ERROR_NULL_POINTER;
*o_TransCount = (PRUint32) mConnectedTransports;
return NS_OK;
}
NS_IMETHODIMP
nsFileTransportService::GetInUseTransportCount(PRUint32 * o_TransCount)
{
if (!o_TransCount)
return NS_ERROR_NULL_POINTER;
*o_TransCount = (PRUint32) mInUseTransports;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,61 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsFileTransportService_h___
#define nsFileTransportService_h___
#include "nsIFileTransportService.h"
//#include "nsIThreadPool.h"
#include "nsSupportsArray.h"
#define NS_FILE_TRANSPORT_WORKER_COUNT_MIN 1
#define NS_FILE_TRANSPORT_WORKER_COUNT_MAX 4//16
class nsFileTransportService : public nsIFileTransportService
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIFILETRANSPORTSERVICE
// nsFileTransportService methods:
nsFileTransportService();
virtual ~nsFileTransportService();
static NS_METHOD
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
nsresult Init();
PRInt32 mConnectedTransports;
PRInt32 mTotalTransports;
PRInt32 mInUseTransports;
nsresult AddSuspendedTransport(nsITransport* trans);
nsresult RemoveSuspendedTransport(nsITransport* trans);
nsSupportsArray mSuspendedTransportList;
protected:
// nsCOMPtr<nsIThreadPool> mPool;
};
#endif /* nsFileTransportService_h___ */

View File

@@ -0,0 +1,134 @@
/* -*- Mode: Java; tab-width: 4; c-basic-offset: 4; -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
/*
Script for simple URI based filtering.
To add a new filter scroll down to the
last function (FilterMain) in this file.
- Gagan Saksena 05/04/00
*/
const kFILTERS_CONTRACTID = "@mozilla.org/network/filters;1";
const kFILTERS_CID = Components.ID("{4677ea1e-1dd2-11b2-8654-e836efb6995c}");
const nsIWebFilters = Components.interfaces.nsIWebFilters;
const nsIURI = Components.interfaces.nsIURI;
function debug(msg)
{
dump(msg + "\n");
}
function nsFilterManager() {};
nsFilterManager.prototype = {
allowLoading: function(uri) {
return FilterMain(uri);
}
}
var filterModule = new Object();
filterModule.registerSelf =
function (compMgr, fileSpec, location, type) {
dump("*** Registering Web Filters (a Javascript module!)\n");
compMgr.registerComponentWithType(kFILTERS_CID,
"Javascript Web Filters",
kFILTERS_CONTRACTID,
fileSpec, location,
true, true, type);
}
filterModule.getClassObject =
function (compMgr, cid, iid) {
if (!cid.equals(kFILTERS_CID))
throw Components.results.NS_ERROR_NO_INTERFACE;
if (!iid.equals(Components.interfaces.nsIFactory))
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
return filtersFactory;
}
filterModule.canUnload =
function(compMgr) {
dump("*** Unloading Web Filters...\n");
return true;
}
var filtersFactory = new Object();
filtersFactory.createInstance =
function (outer, iid) {
if (outer != null)
throw Components.results.NS_ERROR_NO_AGGREGATION;
if (!iid.equals(nsIWebFilters) &&
!iid.equals(Components.interfaces.nsISupports)) {
// shouldn't this be NO_INTERFACE?
throw Components.results.NS_ERROR_INVALID_ARG;
}
return FilterMan;
}
function NSGetModule(compMgr, fileSpec) {
return filterModule;
}
var FilterMan= new nsFilterManager();
// -----------------------------------------------------------------
// Sample block hosts list...
var blockHosts = new Array(
"ad.linkexchange.com",
".tv.com",
"doubleclick.net"
);
// The main filter function! Use the arrays above to build more...
// @return true if you want it to load.
// @return false if you don't like that uri.
function FilterMain(url) {
uri = url.QueryInterface(nsIURI);
try {
/* Commented since currently only HTTP asks for filters...
// Always let the non-relevant ones go...!
// otherwise it would mess up your skin (chrome/resource and such...)
if ((uri.scheme).search("http") == -1)
return true;
*/
// Sample host matches- uri.host
for (var i=0; i < blockHosts.length; ++i) {
if (String(uri.host).search(blockHosts[i]) != -1)
return false;
}
}
catch (ex) { // any problems just continue
return true;
}
return true;
}

View File

@@ -0,0 +1,501 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsIOService.h"
#include "nsIProtocolHandler.h"
#include "nscore.h"
#include "nsIServiceManager.h"
#include "nsIEventQueueService.h"
#include "nsIFileTransportService.h"
#include "nsIURI.h"
#include "nsIStreamListener.h"
#include "prprf.h"
#include "nsLoadGroup.h"
#include "nsInputStreamChannel.h"
#include "nsXPIDLString.h"
#include "nsIErrorService.h"
#include "netCore.h"
#include "nsIObserverService.h"
static NS_DEFINE_CID(kFileTransportService, NS_FILETRANSPORTSERVICE_CID);
static NS_DEFINE_CID(kEventQueueService, NS_EVENTQUEUESERVICE_CID);
static NS_DEFINE_CID(kSocketTransportServiceCID, NS_SOCKETTRANSPORTSERVICE_CID);
static NS_DEFINE_CID(kDNSServiceCID, NS_DNSSERVICE_CID);
static NS_DEFINE_CID(kErrorServiceCID, NS_ERRORSERVICE_CID);
////////////////////////////////////////////////////////////////////////////////
nsIOService::nsIOService()
: mOffline(PR_FALSE)
{
NS_INIT_REFCNT();
}
nsresult
nsIOService::Init()
{
nsresult rv = NS_OK;
// Hold onto the eventQueue service. We do not want any eventqueues to go away
// when we shutdown until we process all remaining transports
if (NS_SUCCEEDED(rv))
mEventQueueService = do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID, &rv);
// We need to get references to these services so that we can shut them
// down later. If we wait until the nsIOService is being shut down,
// GetService will fail at that point.
rv = nsServiceManager::GetService(kSocketTransportServiceCID,
NS_GET_IID(nsISocketTransportService),
getter_AddRefs(mSocketTransportService));
if (NS_FAILED(rv)) return rv;
rv = nsServiceManager::GetService(kFileTransportService,
NS_GET_IID(nsIFileTransportService),
getter_AddRefs(mFileTransportService));
if (NS_FAILED(rv)) return rv;
rv = nsServiceManager::GetService(kDNSServiceCID,
NS_GET_IID(nsIDNSService),
getter_AddRefs(mDNSService));
// XXX hack until xpidl supports error info directly (http://bugzilla.mozilla.org/show_bug.cgi?id=13423)
nsCOMPtr<nsIErrorService> errorService = do_GetService(kErrorServiceCID, &rv);
if (NS_SUCCEEDED(rv)) {
rv = errorService->RegisterErrorStringBundle(NS_ERROR_MODULE_NETWORK, NECKO_MSGS_URL);
if (NS_FAILED(rv)) return rv;
rv = errorService->RegisterErrorStringBundleKey(NS_NET_STATUS_READ_FROM, "ReadFrom");
if (NS_FAILED(rv)) return rv;
rv = errorService->RegisterErrorStringBundleKey(NS_NET_STATUS_WROTE_TO, "WroteTo");
if (NS_FAILED(rv)) return rv;
rv = errorService->RegisterErrorStringBundleKey(NS_NET_STATUS_RESOLVING_HOST, "ResolvingHost");
if (NS_FAILED(rv)) return rv;
rv = errorService->RegisterErrorStringBundleKey(NS_NET_STATUS_CONNECTED_TO, "ConnectedTo");
if (NS_FAILED(rv)) return rv;
rv = errorService->RegisterErrorStringBundleKey(NS_NET_STATUS_SENDING_TO, "SendingTo");
if (NS_FAILED(rv)) return rv;
rv = errorService->RegisterErrorStringBundleKey(NS_NET_STATUS_RECEIVING_FROM, "ReceivingFrom");
if (NS_FAILED(rv)) return rv;
rv = errorService->RegisterErrorStringBundleKey(NS_NET_STATUS_CONNECTING_TO, "ConnectingTo");
if (NS_FAILED(rv)) return rv;
}
return rv;
}
nsIOService::~nsIOService()
{
(void)SetOffline(PR_TRUE);
if (mFileTransportService)
(void)mFileTransportService->Shutdown();
}
NS_METHOD
nsIOService::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{
static nsISupports *_rValue = nsnull;
nsresult rv;
NS_ENSURE_NO_AGGREGATION(aOuter);
if (_rValue)
{
NS_ADDREF (_rValue);
*aResult = _rValue;
return NS_OK;
}
nsIOService* _ios = new nsIOService();
if (_ios == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(_ios);
rv = _ios->Init();
if (NS_FAILED(rv))
{
delete _ios;
return rv;
}
rv = _ios->QueryInterface(aIID, aResult);
if (NS_FAILED(rv))
{
delete _ios;
return rv;
}
_rValue = NS_STATIC_CAST (nsISupports*, *aResult);
NS_RELEASE (_rValue);
_rValue = nsnull;
return rv;
}
NS_IMPL_THREADSAFE_ISUPPORTS1(nsIOService, nsIIOService);
////////////////////////////////////////////////////////////////////////////////
#define MAX_SCHEME_LENGTH 64 // XXX big enough?
#define MAX_NET_CONTRACTID_LENGTH (MAX_SCHEME_LENGTH + NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX_LENGTH + 1)
NS_IMETHODIMP
nsIOService::CacheProtocolHandler(const char *scheme, nsIProtocolHandler *handler)
{
for (unsigned int i=0; i<NS_N(gScheme); i++)
{
if (!nsCRT::strcasecmp(scheme, gScheme[i]))
{
nsresult rv;
NS_ASSERTION(!mWeakHandler[i], "Protocol handler already cached");
// Make sure the handler supports weak references.
nsCOMPtr<nsISupportsWeakReference> factoryPtr = do_QueryInterface(handler, &rv);
if (!factoryPtr)
{
// Dont cache handlers that dont support weak reference as
// there is real danger of a circular reference.
#ifdef DEBUG_dp
printf("DEBUG: %s protcol handler doesn't support weak ref. Not cached.\n", scheme);
#endif /* DEBUG_dp */
return NS_ERROR_FAILURE;
}
mWeakHandler[i] = getter_AddRefs(NS_GetWeakReference(handler));
return NS_OK;
}
}
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsIOService::GetCachedProtocolHandler(const char *scheme, nsIProtocolHandler **result)
{
for (unsigned int i=0; i<NS_N(gScheme); i++)
{
if (!nsCRT::strcasecmp(scheme, gScheme[i]))
if (mWeakHandler[i])
{
nsCOMPtr<nsIProtocolHandler> temp = do_QueryReferent(mWeakHandler[i]);
if (temp)
{
*result = temp.get();
NS_ADDREF(*result);
return NS_OK;
}
}
}
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsIOService::GetProtocolHandler(const char* scheme, nsIProtocolHandler* *result)
{
nsresult rv;
NS_ASSERTION(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX_LENGTH
== nsCRT::strlen(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX),
"need to fix NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX_LENGTH");
NS_ENSURE_ARG_POINTER(scheme);
// XXX we may want to speed this up by introducing our own protocol
// scheme -> protocol handler mapping, avoiding the string manipulation
// and service manager stuff
rv = GetCachedProtocolHandler(scheme, result);
if (NS_SUCCEEDED(rv)) return NS_OK;
char buf[MAX_NET_CONTRACTID_LENGTH];
nsCAutoString contractID(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX);
contractID += scheme;
contractID.ToLowerCase();
contractID.ToCString(buf, MAX_NET_CONTRACTID_LENGTH);
rv = nsServiceManager::GetService(buf, NS_GET_IID(nsIProtocolHandler), (nsISupports **)result);
if (NS_FAILED(rv))
{
// okay we don't have a protocol handler to handle this url type, so use the default protocol handler.
// this will cause urls to get dispatched out to the OS ('cause we can't do anything with them) when
// we try to read from a channel created by the default protocol handler.
rv = nsServiceManager::GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX"default", NS_GET_IID(nsIProtocolHandler), (nsISupports **)result);
if (NS_FAILED(rv)) return NS_ERROR_UNKNOWN_PROTOCOL;
}
CacheProtocolHandler(scheme, *result);
return NS_OK;
}
NS_IMETHODIMP
nsIOService::ExtractScheme(const char* inURI, PRUint32 *startPos,
PRUint32 *endPos, char* *scheme)
{
return ExtractURLScheme(inURI, startPos, endPos, scheme);
}
nsresult
nsIOService::NewURI(const char* aSpec, nsIURI* aBaseURI,
nsIURI* *result, nsIProtocolHandler* *hdlrResult)
{
nsresult rv;
nsIURI* base;
NS_ENSURE_ARG_POINTER(aSpec);
char* scheme;
rv = ExtractScheme(aSpec, nsnull, nsnull, &scheme);
if (NS_SUCCEEDED(rv)) {
// then aSpec is absolute
// ignore aBaseURI in this case
base = nsnull;
}
else {
// then aSpec is relative
if (aBaseURI == nsnull)
return NS_ERROR_MALFORMED_URI;
rv = aBaseURI->GetScheme(&scheme);
if (NS_FAILED(rv)) return rv;
base = aBaseURI;
}
nsCOMPtr<nsIProtocolHandler> handler;
rv = GetProtocolHandler(scheme, getter_AddRefs(handler));
nsCRT::free(scheme);
if (NS_FAILED(rv)) return rv;
if (hdlrResult) {
*hdlrResult = handler;
NS_ADDREF(*hdlrResult);
}
return handler->NewURI(aSpec, base, result);
}
NS_IMETHODIMP
nsIOService::NewURI(const char* aSpec, nsIURI* aBaseURI,
nsIURI* *result)
{
return NewURI(aSpec, aBaseURI, result, nsnull);
}
NS_IMETHODIMP
nsIOService::NewChannelFromURI(nsIURI *aURI, nsIChannel **result)
{
nsresult rv;
NS_ENSURE_ARG_POINTER(aURI);
nsXPIDLCString scheme;
rv = aURI->GetScheme(getter_Copies(scheme));
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIProtocolHandler> handler;
rv = GetProtocolHandler((const char*)scheme, getter_AddRefs(handler));
if (NS_FAILED(rv)) return rv;
rv = handler->NewChannel(aURI, result);
return rv;
}
NS_IMETHODIMP
nsIOService::NewChannel(const char *aSpec, nsIURI *aBaseURI, nsIChannel **result)
{
nsresult rv;
nsCOMPtr<nsIURI> uri;
nsCOMPtr<nsIProtocolHandler> handler;
rv = NewURI(aSpec, aBaseURI, getter_AddRefs(uri), getter_AddRefs(handler));
if (NS_FAILED(rv)) return rv;
rv = handler->NewChannel(uri, result);
return rv;
}
NS_IMETHODIMP
nsIOService::GetOffline(PRBool *offline)
{
*offline = mOffline;
return NS_OK;
}
NS_IMETHODIMP
nsIOService::SetOffline(PRBool offline)
{
nsCOMPtr<nsIObserverService>
observerService(do_GetService(NS_OBSERVERSERVICE_CONTRACTID));
nsresult rv1 = NS_OK;
nsresult rv2 = NS_OK;
if (offline) {
// don't care if notification fails
if (observerService)
(void)observerService->Notify(this,
NS_LITERAL_STRING("network:offline-status-changed").get(),
NS_LITERAL_STRING("offline").get());
mOffline = PR_TRUE; // indicate we're trying to shutdown
// be sure to try and shutdown both (even if the first fails)
if (mDNSService)
rv1 = mDNSService->Shutdown(); // shutdown dns service first, because it has callbacks for socket transport
if (mSocketTransportService)
rv2 = mSocketTransportService->Shutdown();
if (NS_FAILED(rv1)) return rv1;
if (NS_FAILED(rv2)) return rv2;
}
else if (!offline && mOffline) {
// go online
if (mDNSService)
rv1 = mDNSService->Init();
if (NS_FAILED(rv2)) return rv1;
if (mSocketTransportService)
rv2 = mSocketTransportService->Init(); //XXX should we shutdown the dns service?
if (NS_FAILED(rv2)) return rv1;
mOffline = PR_FALSE; // indicate success only AFTER we've
// brought up the services
// don't care if notification fails
if (observerService)
(void)observerService->Notify(this,
NS_LITERAL_STRING("network:offline-status-changed").get(),
NS_LITERAL_STRING("online").get());
}
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// URL parsing utilities
/* encode characters into % escaped hexcodes */
/* use the following masks to specify which
part of an URL you want to escape:
url_Scheme = 1
url_Username = 2
url_Password = 4
url_Host = 8
url_Directory = 16
url_FileBaseName = 32
url_FileExtension = 64
url_Param = 128
url_Query = 256
url_Ref = 512
*/
/* by default this function will not escape parts of a string
that already look escaped, which means it already includes
a valid hexcode. This is done to avoid multiple escapes of
a string. Use the following mask to force escaping of a
string:
url_Forced = 1024
*/
NS_IMETHODIMP
nsIOService::Escape(const char *str, PRInt16 mask, char** result)
{
nsCAutoString esc_str;
nsresult rv = nsURLEscape((char*)str,mask,esc_str);
CRTFREEIF(*result);
if (NS_FAILED(rv))
return rv;
*result = esc_str.ToNewCString();
if (!*result)
return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
}
NS_IMETHODIMP
nsIOService::Unescape(const char *str, char **result)
{
return nsURLUnescape((char*)str,result);
}
NS_IMETHODIMP
nsIOService::ExtractPort(const char *str, PRInt32 *result)
{
PRInt32 returnValue = -1;
*result = (0 < PR_sscanf(str, "%d", &returnValue)) ? returnValue : -1;
return NS_OK;
}
NS_IMETHODIMP
nsIOService::ResolveRelativePath(const char *relativePath, const char* basePath,
char **result)
{
nsCAutoString name;
nsCAutoString path(basePath);
PRBool needsDelim = PR_FALSE;
if ( !path.IsEmpty() ) {
PRUnichar last = path.Last();
needsDelim = !(last == '/' || last == '\\' );
}
PRBool end = PR_FALSE;
char c;
while (!end) {
c = *relativePath++;
switch (c) {
case '\0':
case '#':
case ';':
case '?':
end = PR_TRUE;
// fall through...
case '/':
case '\\':
// delimiter found
if (name.Equals("..")) {
// pop path
PRInt32 pos = path.RFind("/");
if (pos > 0) {
path.Truncate(pos + 1);
path += name;
}
else {
return NS_ERROR_MALFORMED_URI;
}
}
else if (name.Equals(".") || name.Equals("")) {
// do nothing
}
else {
// append name to path
if (needsDelim)
path += "/";
path += name;
needsDelim = PR_TRUE;
}
name = "";
break;
default:
// append char to name
name += c;
}
}
// append anything left on relativePath (e.g. #..., ;..., ?...)
if (c != '\0')
path += --relativePath;
*result = path.ToNewCString();
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,78 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsIOService_h__
#define nsIOService_h__
#include "nsIIOService.h"
#include "nsString.h"
#include "nsISocketTransportService.h"
#include "nsIFileTransportService.h"
#include "nsIDNSService.h"
#include "nsCOMPtr.h"
#include "nsURLHelper.h"
#include "nsWeakPtr.h"
#include "nsIEventQueueService.h"
#define NS_N(x) (sizeof(x)/sizeof(*x))
static const char *gScheme[] = {"chrome", "resource", "file", "http"};
class nsIOService : public nsIIOService
{
public:
NS_DECL_ISUPPORTS
// nsIIOService methods:
NS_DECL_NSIIOSERVICE
// nsIOService methods:
nsIOService();
virtual ~nsIOService();
static NS_METHOD
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
nsresult Init();
nsresult NewURI(const char* aSpec, nsIURI* aBaseURI,
nsIURI* *result, nsIProtocolHandler* *hdlrResult);
protected:
NS_METHOD GetCachedProtocolHandler(const char *scheme,
nsIProtocolHandler* *hdlrResult);
NS_METHOD CacheProtocolHandler(const char *scheme,
nsIProtocolHandler* hdlr);
protected:
PRBool mOffline;
nsCOMPtr<nsISocketTransportService> mSocketTransportService;
nsCOMPtr<nsIFileTransportService> mFileTransportService;
nsCOMPtr<nsIDNSService> mDNSService;
nsCOMPtr<nsIEventQueueService> mEventQueueService;
// Cached protocol handlers
nsWeakPtr mWeakHandler[NS_N(gScheme)];
};
#endif // nsIOService_h__

View File

@@ -0,0 +1,561 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsInputStreamChannel.h"
#include "nsCOMPtr.h"
#include "nsIIOService.h"
#include "nsIServiceManager.h"
#include "nsIFileTransportService.h"
#include "netCore.h"
#include "nsXPIDLString.h"
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
static NS_DEFINE_CID(kFileTransportServiceCID, NS_FILETRANSPORTSERVICE_CID);
////////////////////////////////////////////////////////////////////////////////
// nsInputStreamIO methods:
NS_IMPL_THREADSAFE_ISUPPORTS2(nsInputStreamIO,
nsIInputStreamIO,
nsIStreamIO)
nsInputStreamIO::nsInputStreamIO()
: mName(nsnull), mContentType(nsnull), mContentLength(-1), mStatus(NS_OK)
{
NS_INIT_REFCNT();
}
nsInputStreamIO::~nsInputStreamIO()
{
(void)Close(NS_OK);
if (mName) nsCRT::free(mName);
if (mContentType) nsCRT::free(mContentType);
}
NS_METHOD
nsInputStreamIO::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{
if (aOuter)
return NS_ERROR_NO_AGGREGATION;
nsInputStreamIO* io = new nsInputStreamIO();
if (io == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(io);
nsresult rv = io->QueryInterface(aIID, aResult);
NS_RELEASE(io);
return rv;
}
NS_IMETHODIMP
nsInputStreamIO::Init(const char* name, nsIInputStream* input,
const char* contentType, PRInt32 contentLength)
{
mName = nsCRT::strdup(name);
if (mName == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
mInputStream = input;
if (contentType) {
mContentType = nsCRT::strdup(contentType);
const char *constContentType = mContentType;
if (!constContentType) return NS_ERROR_OUT_OF_MEMORY;
char* semicolon = PL_strchr(constContentType, ';');
CBufDescriptor cbd(constContentType,
PR_TRUE,
semicolon ? (semicolon-constContentType) + 1: PL_strlen(constContentType), // capacity
semicolon ? (semicolon-constContentType) : PL_strlen(constContentType));
nsCAutoString(cbd).ToLowerCase();
}
mContentLength = contentLength;
return NS_OK;
}
NS_IMETHODIMP
nsInputStreamIO::Open(char **contentType, PRInt32 *contentLength)
{
*contentType = nsCRT::strdup(mContentType);
if (*contentType == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
*contentLength = mContentLength;
return NS_OK;
}
NS_IMETHODIMP
nsInputStreamIO::Close(nsresult status)
{
mStatus = status;
if (mInputStream)
return mInputStream->Close();
else
return NS_OK;
}
NS_IMETHODIMP
nsInputStreamIO::GetInputStream(nsIInputStream * *aInputStream)
{
*aInputStream = mInputStream;
NS_ADDREF(*aInputStream);
return NS_OK;
}
NS_IMETHODIMP
nsInputStreamIO::GetOutputStream(nsIOutputStream * *aOutputStream)
{
// this method should never be called
NS_NOTREACHED("nsInputStreamIO::GetOutputStream");
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsInputStreamIO::GetName(char* *aName)
{
*aName = nsCRT::strdup(mName);
return *aName ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
}
////////////////////////////////////////////////////////////////////////////////
// nsStreamIOChannel methods:
nsStreamIOChannel::nsStreamIOChannel()
: mContentType(nsnull), mContentLength(-1),
mBufferSegmentSize(0), mBufferMaxSize(0),
mLoadAttributes(LOAD_NORMAL), mStatus(NS_OK)
{
NS_INIT_REFCNT();
}
nsStreamIOChannel::~nsStreamIOChannel()
{
if (mContentType) nsCRT::free(mContentType);
}
NS_METHOD
nsStreamIOChannel::Create(nsISupports *aOuter, REFNSIID aIID,
void **aResult)
{
if (aOuter)
return NS_ERROR_NO_AGGREGATION;
nsStreamIOChannel* channel = new nsStreamIOChannel();
if (channel == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(channel);
nsresult rv = channel->QueryInterface(aIID, aResult);
NS_RELEASE(channel);
return rv;
}
NS_IMETHODIMP
nsStreamIOChannel::Init(nsIURI* uri, nsIStreamIO* io)
{
mURI = uri;
mStreamIO = io;
return NS_OK;
}
NS_INTERFACE_MAP_BEGIN(nsStreamIOChannel)
NS_INTERFACE_MAP_ENTRY(nsIStreamIOChannel)
NS_INTERFACE_MAP_ENTRY(nsIChannel)
NS_INTERFACE_MAP_ENTRY(nsIRequest)
NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
NS_INTERFACE_MAP_ENTRY(nsIStreamProvider)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIStreamObserver, nsIStreamListener)
NS_INTERFACE_MAP_ENTRY(nsIProgressEventSink)
NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStreamListener)
NS_INTERFACE_MAP_END_THREADSAFE
NS_IMPL_THREADSAFE_ADDREF(nsStreamIOChannel)
NS_IMPL_THREADSAFE_RELEASE(nsStreamIOChannel)
NS_IMETHODIMP
nsStreamIOChannel::GetName(PRUnichar* *result)
{
nsresult rv;
nsXPIDLCString urlStr;
rv = mURI->GetSpec(getter_Copies(urlStr));
if (NS_FAILED(rv)) return rv;
nsString name;
name.AppendWithConversion(urlStr);
*result = name.ToNewUnicode();
return *result ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
}
NS_IMETHODIMP
nsStreamIOChannel::IsPending(PRBool *result)
{
if (mRequest)
return mRequest->IsPending(result);
*result = PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP
nsStreamIOChannel::GetStatus(nsresult *status)
{
*status = mStatus;
// if we don't have a status error of our own to report
// then we should propogate the status error of the underlying
// file transport (if we have one)
if (NS_SUCCEEDED(mStatus) && mRequest)
mRequest->GetStatus(status);
return NS_OK;
}
NS_IMETHODIMP
nsStreamIOChannel::Cancel(nsresult status)
{
NS_ASSERTION(NS_FAILED(status), "shouldn't cancel with a success code");
mStatus = status;
if (mRequest)
return mRequest->Cancel(status);
return NS_OK;
}
NS_IMETHODIMP
nsStreamIOChannel::Suspend(void)
{
if (mRequest)
return mRequest->Suspend();
return NS_OK;
}
NS_IMETHODIMP
nsStreamIOChannel::Resume(void)
{
if (mRequest)
return mRequest->Resume();
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsIChannel implementation:
////////////////////////////////////////////////////////////////////////////////
NS_IMETHODIMP
nsStreamIOChannel::GetOriginalURI(nsIURI* *aURI)
{
*aURI = mOriginalURI ? mOriginalURI : mURI;
NS_IF_ADDREF(*aURI);
return NS_OK;
}
NS_IMETHODIMP
nsStreamIOChannel::SetOriginalURI(nsIURI* aURI)
{
mOriginalURI = aURI;
return NS_OK;
}
NS_IMETHODIMP
nsStreamIOChannel::GetURI(nsIURI* *aURI)
{
*aURI = mURI;
NS_IF_ADDREF(*aURI);
return NS_OK;
}
NS_IMETHODIMP
nsStreamIOChannel::SetURI(nsIURI* aURI)
{
mURI = aURI;
return NS_OK;
}
NS_IMETHODIMP
nsStreamIOChannel::Open(nsIInputStream **result)
{
return mStreamIO->GetInputStream(result);
}
NS_IMETHODIMP
nsStreamIOChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *ctxt)
{
nsresult rv;
NS_ASSERTION(listener, "no listener");
SetListener(listener);
if (mLoadGroup) {
nsCOMPtr<nsILoadGroupListenerFactory> factory;
//
// Create a load group "proxy" listener...
//
rv = mLoadGroup->GetGroupListenerFactory(getter_AddRefs(factory));
if (factory) {
nsIStreamListener *newListener;
rv = factory->CreateLoadGroupListener(GetListener(), &newListener);
if (NS_SUCCEEDED(rv)) {
mUserObserver = newListener;
NS_RELEASE(newListener);
}
}
rv = mLoadGroup->AddRequest(this, nsnull);
if (NS_FAILED(rv)) return rv;
}
if (mFileTransport == nsnull) {
NS_WITH_SERVICE(nsIFileTransportService, fts, kFileTransportServiceCID, &rv);
if (NS_FAILED(rv)) goto done;
rv = fts->CreateTransportFromStreamIO(mStreamIO, getter_AddRefs(mFileTransport));
if (NS_FAILED(rv)) goto done;
}
// Hook up the notification callbacks InterfaceRequestor...
{
nsCOMPtr<nsIInterfaceRequestor> requestor =
do_QueryInterface(NS_STATIC_CAST(nsIRequest*, this));
rv = mFileTransport->SetNotificationCallbacks
(requestor, (mLoadAttributes & nsIChannel::LOAD_BACKGROUND));
if (NS_FAILED(rv)) goto done;
}
#if 0
if (mContentType == nsnull) {
rv = mStreamIO->Open(&mContentType, &mContentLength);
if (NS_FAILED(rv)) goto done;
}
#endif
rv = mFileTransport->AsyncRead(this, ctxt, 0, PRUint32(-1), 0, getter_AddRefs(mRequest));
done:
if (NS_FAILED(rv)) {
nsresult rv2;
rv2 = mLoadGroup->RemoveRequest(this, ctxt, rv, nsnull);
NS_ASSERTION(NS_SUCCEEDED(rv2), "RemoveRequest failed");
// release the transport so that we don't think we're in progress
mFileTransport = nsnull;
}
return rv;
}
NS_IMETHODIMP
nsStreamIOChannel::GetLoadAttributes(nsLoadFlags *aLoadAttributes)
{
*aLoadAttributes = mLoadAttributes;
return NS_OK;
}
NS_IMETHODIMP
nsStreamIOChannel::SetLoadAttributes(nsLoadFlags aLoadAttributes)
{
mLoadAttributes = aLoadAttributes;
return NS_OK;
}
NS_IMETHODIMP
nsStreamIOChannel::GetLoadGroup(nsILoadGroup* *aLoadGroup)
{
*aLoadGroup = mLoadGroup.get();
NS_IF_ADDREF(*aLoadGroup);
return NS_OK;
}
NS_IMETHODIMP
nsStreamIOChannel::SetLoadGroup(nsILoadGroup* aLoadGroup)
{
mLoadGroup = aLoadGroup;
return NS_OK;
}
NS_IMETHODIMP
nsStreamIOChannel::GetOwner(nsISupports* *aOwner)
{
*aOwner = mOwner.get();
NS_IF_ADDREF(*aOwner);
return NS_OK;
}
NS_IMETHODIMP
nsStreamIOChannel::SetOwner(nsISupports* aOwner)
{
mOwner = aOwner;
return NS_OK;
}
NS_IMETHODIMP
nsStreamIOChannel::GetNotificationCallbacks(nsIInterfaceRequestor* *aNotificationCallbacks)
{
*aNotificationCallbacks = mCallbacks.get();
NS_IF_ADDREF(*aNotificationCallbacks);
return NS_OK;
}
NS_IMETHODIMP
nsStreamIOChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aNotificationCallbacks)
{
nsresult rv = NS_OK;
mCallbacks = aNotificationCallbacks;
mProgressSink = do_GetInterface(mCallbacks);
return rv;
}
NS_IMETHODIMP
nsStreamIOChannel::GetSecurityInfo(nsISupports * *aSecurityInfo)
{
*aSecurityInfo = nsnull;
return NS_OK;
}
NS_IMETHODIMP
nsStreamIOChannel::GetContentType(char * *aContentType)
{
nsresult rv;
if (mContentType == nsnull) {
rv = mStreamIO->Open(&mContentType, &mContentLength);
if (NS_FAILED(rv)) return rv;
}
*aContentType = nsCRT::strdup(mContentType);
if (*aContentType == nsnull) {
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;
}
NS_IMETHODIMP
nsStreamIOChannel::SetContentType(const char *aContentType)
{
mContentType = nsCRT::strdup(aContentType);
if (*aContentType == nsnull) {
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;
}
NS_IMETHODIMP
nsStreamIOChannel::GetContentLength(PRInt32 *aContentLength)
{
nsresult rv;
if (mContentType == nsnull) {
rv = mStreamIO->Open(&mContentType, &mContentLength);
if (NS_FAILED(rv)) return rv;
}
*aContentLength = mContentLength;
return NS_OK;
}
NS_IMETHODIMP
nsStreamIOChannel::SetContentLength(PRInt32 aContentLength)
{
mContentLength = aContentLength;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsIStreamObserver implementation:
////////////////////////////////////////////////////////////////////////////////
NS_IMETHODIMP
nsStreamIOChannel::OnStartRequest(nsIRequest *request, nsISupports* context)
{
NS_ASSERTION(mUserObserver, "No listener...");
return mUserObserver->OnStartRequest(this, context);
}
NS_IMETHODIMP
nsStreamIOChannel::OnStopRequest(nsIRequest *request, nsISupports* context,
nsresult aStatus, const PRUnichar* aStatusArg)
{
nsresult rv;
if (mUserObserver) {
rv = mUserObserver->OnStopRequest(this, context, aStatus, aStatusArg);
if (NS_FAILED(rv)) return rv;
}
if (mLoadGroup) {
if (NS_SUCCEEDED(rv)) {
rv = mLoadGroup->RemoveRequest(this, context, aStatus, aStatusArg);
if (NS_FAILED(rv)) return rv;
}
}
// Release the reference to the consumer stream listener...
mUserObserver = null_nsCOMPtr();
mFileTransport = null_nsCOMPtr();
return mStreamIO->Close(aStatus);
}
////////////////////////////////////////////////////////////////////////////////
// nsIStreamListener implementation:
////////////////////////////////////////////////////////////////////////////////
NS_IMETHODIMP
nsStreamIOChannel::OnDataAvailable(nsIRequest *request, nsISupports* context,
nsIInputStream *aIStream, PRUint32 aSourceOffset,
PRUint32 aLength)
{
return GetListener()->OnDataAvailable(this, context, aIStream,
aSourceOffset, aLength);
}
////////////////////////////////////////////////////////////////////////////////
// nsIStreamProvider implementation:
////////////////////////////////////////////////////////////////////////////////
NS_IMETHODIMP
nsStreamIOChannel::OnDataWritable(nsIRequest *request, nsISupports *context,
nsIOutputStream *aOStream,
PRUint32 aOffset, PRUint32 aLength)
{
return GetProvider()->OnDataWritable(this, context, aOStream,
aOffset, aLength);
}
////////////////////////////////////////////////////////////////////////////////
// nsIProgressEventSink implementation:
////////////////////////////////////////////////////////////////////////////////
NS_IMETHODIMP
nsStreamIOChannel::OnProgress(nsIRequest *request, nsISupports *context,
PRUint32 progress, PRUint32 progressMax)
{
if (mProgressSink)
mProgressSink->OnProgress(request, context, progress, progressMax);
return NS_OK;
}
NS_IMETHODIMP
nsStreamIOChannel::OnStatus(nsIRequest *request, nsISupports *context,
nsresult status, const PRUnichar *statusText)
{
if (mProgressSink)
mProgressSink->OnStatus(request, context, status, statusText);
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsIInterfaceRequestor implementation:
////////////////////////////////////////////////////////////////////////////////
NS_IMETHODIMP
nsStreamIOChannel::GetInterface(const nsIID &iid, void **result)
{
if (iid.Equals(NS_GET_IID(nsIProgressEventSink)))
return QueryInterface(iid, result);
return NS_ERROR_NO_INTERFACE;
}
////////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,109 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsInputStreamChannel_h__
#define nsInputStreamChannel_h__
#include "nsIStreamIOChannel.h"
#include "nsIInputStream.h"
#include "nsIURI.h"
#include "nsCRT.h"
#include "nsILoadGroup.h"
#include "nsIStreamListener.h"
#include "nsIStreamProvider.h"
#include "nsIInterfaceRequestor.h"
#include "nsIProgressEventSink.h"
#include "nsIStreamIO.h"
#include "nsITransport.h"
class nsInputStreamIO : public nsIInputStreamIO
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSISTREAMIO
NS_DECL_NSIINPUTSTREAMIO
nsInputStreamIO();
virtual ~nsInputStreamIO();
static NS_METHOD
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
protected:
char* mName;
nsCOMPtr<nsIInputStream> mInputStream;
char* mContentType;
PRInt32 mContentLength;
nsresult mStatus;
};
////////////////////////////////////////////////////////////////////////////////
class nsStreamIOChannel : public nsIStreamIOChannel,
public nsIStreamListener,
public nsIStreamProvider,
public nsIProgressEventSink,
public nsIInterfaceRequestor
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIREQUEST
NS_DECL_NSICHANNEL
NS_DECL_NSISTREAMIOCHANNEL
NS_DECL_NSISTREAMOBSERVER
NS_DECL_NSISTREAMLISTENER
NS_DECL_NSISTREAMPROVIDER
NS_DECL_NSIPROGRESSEVENTSINK
NS_DECL_NSIINTERFACEREQUESTOR
nsStreamIOChannel();
virtual ~nsStreamIOChannel();
static NS_METHOD
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
protected:
nsIStreamListener* GetListener() { return (nsIStreamListener*)mUserObserver.get(); }
void SetListener(nsIStreamListener* listener) { mUserObserver = listener; }
nsIStreamProvider* GetProvider() { return (nsIStreamProvider*)mUserObserver.get(); }
void SetProvider(nsIStreamProvider* provider) { mUserObserver = provider; }
protected:
nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
nsCOMPtr<nsIProgressEventSink> mProgressSink;
nsCOMPtr<nsIURI> mOriginalURI;
nsCOMPtr<nsIURI> mURI;
char* mContentType;
PRInt32 mContentLength;
nsCOMPtr<nsIStreamIO> mStreamIO;
nsCOMPtr<nsILoadGroup> mLoadGroup;
nsCOMPtr<nsISupports> mOwner;
nsCOMPtr<nsITransport> mFileTransport;
nsCOMPtr<nsIRequest> mRequest;
nsCOMPtr<nsIStreamObserver> mUserObserver;
PRUint32 mBufferSegmentSize;
PRUint32 mBufferMaxSize;
PRUint32 mLoadAttributes;
nsresult mStatus;
};
#endif // nsInputStreamChannel_h__

View File

@@ -0,0 +1,660 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsLoadGroup.h"
#include "nsIStreamObserver.h"
#include "nsIChannel.h"
#include "nsISupportsArray.h"
#include "nsEnumeratorUtils.h"
#include "nsIServiceManager.h"
#include "nsIEventQueueService.h"
#include "nsCOMPtr.h"
#include "nsIURI.h"
#include "prlog.h"
#include "nsCRT.h"
#include "netCore.h"
#include "nsXPIDLString.h"
#include "nsString.h"
#if defined(PR_LOGGING)
//
// Log module for nsILoadGroup logging...
//
// To enable logging (see prlog.h for full details):
//
// set NSPR_LOG_MODULES=LoadGroup:5
// set NSPR_LOG_FILE=nspr.log
//
// this enables PR_LOG_DEBUG level information and places all output in
// the file nspr.log
//
PRLogModuleInfo* gLoadGroupLog = nsnull;
#endif /* PR_LOGGING */
////////////////////////////////////////////////////////////////////////////////
nsLoadGroup::nsLoadGroup(nsISupports* outer)
: mDefaultLoadAttributes(nsIChannel::LOAD_NORMAL),
mForegroundCount(0),
mRequests(nsnull),
mStatus(NS_OK)
{
NS_INIT_AGGREGATED(outer);
#if defined(PR_LOGGING)
//
// Initialize the global PRLogModule for nsILoadGroup logging
// if necessary...
//
if (nsnull == gLoadGroupLog) {
gLoadGroupLog = PR_NewLogModule("LoadGroup");
}
#endif /* PR_LOGGING */
PR_LOG(gLoadGroupLog, PR_LOG_DEBUG,
("LOADGROUP [%x]: Created.\n", this));
}
nsLoadGroup::~nsLoadGroup()
{
nsresult rv;
rv = Cancel(NS_BINDING_ABORTED);
NS_ASSERTION(NS_SUCCEEDED(rv), "Cancel failed");
NS_IF_RELEASE(mRequests);
mDefaultLoadRequest = null_nsCOMPtr();
PR_LOG(gLoadGroupLog, PR_LOG_DEBUG,
("LOADGROUP [%x]: Destroyed.\n", this));
}
nsresult nsLoadGroup::Init()
{
return NS_NewISupportsArray(&mRequests);
}
NS_METHOD
nsLoadGroup::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{
NS_ENSURE_ARG_POINTER(aResult);
NS_ENSURE_PROPER_AGGREGATION(aOuter, aIID);
nsresult rv;
nsLoadGroup* group = new nsLoadGroup(aOuter);
if (group == nsnull) {
*aResult = nsnull;
return NS_ERROR_OUT_OF_MEMORY;
}
rv = group->Init();
if (NS_SUCCEEDED(rv)) {
rv = group->AggregatedQueryInterface(aIID, aResult);
}
if (NS_FAILED(rv)) {
delete group;
}
return rv;
}
////////////////////////////////////////////////////////////////////////////////
// nsISupports methods:
NS_IMPL_AGGREGATED(nsLoadGroup);
NS_IMETHODIMP
nsLoadGroup::AggregatedQueryInterface(const nsIID& aIID, void** aInstancePtr)
{
NS_ENSURE_ARG_POINTER(aInstancePtr);
if (aIID.Equals(NS_GET_IID(nsISupports)))
*aInstancePtr = GetInner();
else if (aIID.Equals(NS_GET_IID(nsILoadGroup)) ||
aIID.Equals(NS_GET_IID(nsIRequest)) ||
aIID.Equals(NS_GET_IID(nsISupports))) {
*aInstancePtr = NS_STATIC_CAST(nsILoadGroup*, this);
}
else if (aIID.Equals(NS_GET_IID(nsISupportsWeakReference))) {
*aInstancePtr = NS_STATIC_CAST(nsISupportsWeakReference*,this);
}
else {
*aInstancePtr = nsnull;
return NS_NOINTERFACE;
}
NS_ADDREF((nsISupports*)*aInstancePtr);
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsIRequest methods:
NS_IMETHODIMP
nsLoadGroup::GetName(PRUnichar* *result)
{
// XXX is this the right "name" for a load group?
*result = nsnull;
if (mDefaultLoadRequest) {
nsXPIDLString nameStr;
nsresult rv = mDefaultLoadRequest->GetName(getter_Copies(nameStr));
if (NS_SUCCEEDED(rv)) {
nsString name;
name.Assign(nameStr);
*result = name.ToNewUnicode();
return *result ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
}
}
return NS_OK;
}
NS_IMETHODIMP
nsLoadGroup::IsPending(PRBool *aResult)
{
if (mForegroundCount > 0) {
*aResult = PR_TRUE;
} else {
*aResult = PR_FALSE;
}
return NS_OK;
}
NS_IMETHODIMP
nsLoadGroup::GetStatus(nsresult *status)
{
if (NS_SUCCEEDED(mStatus) && mDefaultLoadRequest)
return mDefaultLoadRequest->GetStatus(status);
*status = mStatus;
return NS_OK;
}
NS_IMETHODIMP
nsLoadGroup::Cancel(nsresult status)
{
NS_ASSERTION(NS_FAILED(status), "shouldn't cancel with a success code");
nsresult rv, firstError;
PRUint32 count;
// set the load group status to our cancel status while we cancel
// all our requests...once the cancel is done, we'll reset it...
mStatus = status;
rv = mRequests->Count(&count);
if (NS_FAILED(rv)) return rv;
firstError = NS_OK;
if (count) {
nsIRequest* request;
//
// Operate the elements from back to front so that if items get
// get removed from the list it won't affect our iteration
//
while (count > 0) {
request = NS_STATIC_CAST(nsIRequest*, mRequests->ElementAt(--count));
NS_ASSERTION(request, "NULL request found in list.");
if (!request) {
continue;
}
#if defined(PR_LOGGING)
nsXPIDLString nameStr;
request->GetName(getter_Copies(nameStr));
PR_LOG(gLoadGroupLog, PR_LOG_DEBUG,
("LOADGROUP [%x]: Canceling request %x %s.\n",
this, request, NS_ConvertUCS2toUTF8(nameStr).get()));
#endif /* PR_LOGGING */
//
// Remove the request from the load group... This may cause
// the OnStopRequest notification to fire...
//
// XXX: What should the context and error message be?
//
(void)RemoveRequest(request, nsnull, status, nsnull);
// Cancel the request...
rv = request->Cancel(status);
// Remember the first failure and return it...
if (NS_FAILED(rv) && NS_SUCCEEDED(firstError)) {
firstError = rv;
}
NS_RELEASE(request);
}
#if defined(DEBUG)
(void)mRequests->Count(&count);
NS_ASSERTION(count == 0, "Request list is not empty.");
NS_ASSERTION(mForegroundCount == 0, "Foreground URLs are active.");
#endif /* DEBUG */
}
mStatus = NS_OK;
return firstError;
}
NS_IMETHODIMP
nsLoadGroup::Suspend()
{
nsresult rv, firstError;
PRUint32 count;
rv = mRequests->Count(&count);
if (NS_FAILED(rv)) return rv;
firstError = NS_OK;
//
// Operate the elements from back to front so that if items get
// get removed from the list it won't affect our iteration
//
while (count > 0) {
nsIRequest* request = NS_STATIC_CAST(nsIRequest*, mRequests->ElementAt(--count));
NS_ASSERTION(request, "NULL request found in list.");
if (!request) {
continue;
}
#if defined(PR_LOGGING)
nsXPIDLString nameStr;
request->GetName(getter_Copies(nameStr));
PR_LOG(gLoadGroupLog, PR_LOG_DEBUG,
("LOADGROUP [%x]: Suspending request %x %s.\n",
this, request, NS_ConvertUCS2toUTF8(nameStr).get()));
#endif /* PR_LOGGING */
// Suspend the request...
rv = request->Suspend();
// Remember the first failure and return it...
if (NS_FAILED(rv) && NS_SUCCEEDED(firstError)) {
firstError = rv;
}
NS_RELEASE(request);
}
return firstError;
}
NS_IMETHODIMP
nsLoadGroup::Resume()
{
nsresult rv, firstError;
PRUint32 count;
rv = mRequests->Count(&count);
if (NS_FAILED(rv)) return rv;
firstError = NS_OK;
//
// Operate the elements from back to front so that if items get
// get removed from the list it won't affect our iteration
//
while (count > 0) {
nsIRequest* request = NS_STATIC_CAST(nsIRequest*, mRequests->ElementAt(--count));
NS_ASSERTION(request, "NULL request found in list.");
if (!request) {
continue;
}
#if defined(PR_LOGGING)
nsXPIDLString nameStr;
request->GetName(getter_Copies(nameStr));
PR_LOG(gLoadGroupLog, PR_LOG_DEBUG,
("LOADGROUP [%x]: Resuming request %x %s.\n",
this, request, NS_ConvertUCS2toUTF8(nameStr).get()));
#endif /* PR_LOGGING */
// Resume the request...
rv = request->Resume();
// Remember the first failure and return it...
if (NS_FAILED(rv) && NS_SUCCEEDED(firstError)) {
firstError = rv;
}
NS_RELEASE(request);
}
return firstError;
}
////////////////////////////////////////////////////////////////////////////////
// nsILoadGroup methods:
NS_IMETHODIMP
nsLoadGroup::Init(nsIStreamObserver *aObserver)
{
nsresult rv;
rv = SetGroupObserver(aObserver);
return rv;
}
NS_IMETHODIMP
nsLoadGroup::GetDefaultLoadAttributes(PRUint32 *aDefaultLoadAttributes)
{
*aDefaultLoadAttributes = mDefaultLoadAttributes;
return NS_OK;
}
NS_IMETHODIMP
nsLoadGroup::SetDefaultLoadAttributes(PRUint32 aDefaultLoadAttributes)
{
mDefaultLoadAttributes = aDefaultLoadAttributes;
return NS_OK;
}
NS_IMETHODIMP
nsLoadGroup::GetDefaultLoadRequest(nsIRequest * *aRequest)
{
*aRequest = mDefaultLoadRequest;
NS_IF_ADDREF(*aRequest);
return NS_OK;
}
NS_IMETHODIMP
nsLoadGroup::SetDefaultLoadRequest(nsIRequest *aRequest)
{
mDefaultLoadRequest = aRequest;
return NS_OK;
}
NS_IMETHODIMP
nsLoadGroup::AddRequest(nsIRequest *request, nsISupports* ctxt)
{
nsresult rv;
#if defined(PR_LOGGING)
PRUint32 count = 0;
(void)mRequests->Count(&count);
nsXPIDLString nameStr;
request->GetName(getter_Copies(nameStr));
PR_LOG(gLoadGroupLog, PR_LOG_DEBUG,
("LOADGROUP [%x]: Adding request %x %s (count=%d).\n",
this, request, NS_ConvertUCS2toUTF8(nameStr).get(), count));
#endif /* PR_LOGGING */
nsLoadFlags flags;
rv = MergeLoadAttributes(request, flags);
if (NS_FAILED(rv)) return rv;
//
// Add the request to the list of active requests...
//
// XXX this method incorrectly returns a bool
//
rv = mRequests->AppendElement(request) ? NS_OK : NS_ERROR_FAILURE;
if (NS_FAILED(rv)) return rv;
if (!(flags & nsIChannel::LOAD_BACKGROUND)) {
// Update the count of foreground URIs..
mForegroundCount += 1;
//
// Fire the OnStartRequest notification out to the observer...
//
// If the notification fails then DO NOT add the request to
// the load group.
//
nsCOMPtr<nsIStreamObserver> observer (do_QueryReferent(mObserver));
if (observer) {
PR_LOG(gLoadGroupLog, PR_LOG_DEBUG,
("LOADGROUP [%x]: Firing OnStartRequest for request %x."
"(foreground count=%d).\n",
this, request, mForegroundCount));
rv = observer->OnStartRequest(request, ctxt);
if (NS_FAILED(rv)) {
PR_LOG(gLoadGroupLog, PR_LOG_ERROR,
("LOADGROUP [%x]: OnStartRequest for request %x FAILED.\n",
this, request));
//
// The URI load has been canceled by the observer. Clean up
// the damage...
//
// XXX this method incorrectly returns a bool
//
rv = mRequests->RemoveElement(request) ? NS_OK : NS_ERROR_FAILURE;
mForegroundCount -= 1;
}
}
}
return rv;
}
NS_IMETHODIMP
nsLoadGroup::RemoveRequest(nsIRequest *request, nsISupports* ctxt,
nsresult aStatus, const PRUnichar* aStatusArg)
{
nsresult rv;
#if defined(PR_LOGGING)
PRUint32 count = 0;
(void)mRequests->Count(&count);
nsXPIDLString nameStr;
request->GetName(getter_Copies(nameStr));
PR_LOG(gLoadGroupLog, PR_LOG_DEBUG,
("LOADGROUP [%x]: Removing request %x %s status %x (count=%d).\n",
this, request, NS_ConvertUCS2toUTF8(nameStr).get(), aStatus, count-1));
#endif /* PR_LOGGING */
//
// Remove the request from the group. If this fails, it means that
// the request was *not* in the group so do not update the foreground
// count or it will get messed up...
//
//
// XXX this method incorrectly returns a bool
//
rv = mRequests->RemoveElement(request) ? NS_OK : NS_ERROR_FAILURE;
if (NS_FAILED(rv)) {
PR_LOG(gLoadGroupLog, PR_LOG_ERROR,
("LOADGROUP [%x]: Unable to remove request %x. Not in group!\n",
this, request));
return rv;
}
nsLoadFlags flags;
nsCOMPtr<nsIChannel> aChannel = do_QueryInterface(request, &rv);
if (NS_FAILED(rv))
return NS_ERROR_FAILURE;
rv = aChannel->GetLoadAttributes(&flags);
if (NS_FAILED(rv)) return rv;
if (!(flags & nsIChannel::LOAD_BACKGROUND)) {
NS_ASSERTION(mForegroundCount > 0, "ForegroundCount messed up");
mForegroundCount -= 1;
// Fire the OnStopRequest out to the observer...
nsCOMPtr<nsIStreamObserver> observer (do_QueryReferent(mObserver));
if (observer) {
PR_LOG(gLoadGroupLog, PR_LOG_DEBUG,
("LOADGROUP [%x]: Firing OnStopRequest for request %x."
"(foreground count=%d).\n",
this, request, mForegroundCount));
rv = observer->OnStopRequest(request, ctxt, aStatus, aStatusArg);
if (NS_FAILED(rv)) {
PR_LOG(gLoadGroupLog, PR_LOG_ERROR,
("LOADGROUP [%x]: OnStopRequest for request %x FAILED.\n",
this, request));
}
}
}
return rv;
}
NS_IMETHODIMP
nsLoadGroup::GetRequests(nsISimpleEnumerator * *aRequests)
{
return NS_NewArrayEnumerator(aRequests, mRequests);
}
NS_IMETHODIMP
nsLoadGroup::GetGroupListenerFactory(nsILoadGroupListenerFactory * *aFactory)
{
if (mGroupListenerFactory) {
mGroupListenerFactory->QueryReferent(NS_GET_IID(nsILoadGroupListenerFactory), (void**)aFactory);
}
return NS_OK;
}
NS_IMETHODIMP
nsLoadGroup::SetGroupListenerFactory(nsILoadGroupListenerFactory *aFactory)
{
mGroupListenerFactory = getter_AddRefs(NS_GetWeakReference(aFactory));
return NS_OK;
}
NS_IMETHODIMP
nsLoadGroup::SetGroupObserver(nsIStreamObserver* aObserver)
{
nsresult rv = NS_OK;
// Release the old observer (if any...)
mObserver = null_nsCOMPtr();
#if 0
if (aObserver) {
nsCOMPtr<nsIEventQueue> eventQueue;
NS_WITH_SERVICE(nsIEventQueueService, eventQService, kEventQueueService, &rv);
if (NS_FAILED(rv)) return rv;
rv = eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, getter_AddRefs(eventQueue));
if (NS_FAILED(rv)) return rv;
rv = NS_NewAsyncStreamObserver(getter_AddRefs(mObserver),
eventQueue, aObserver);
}
#else
//mObserver = aObserver;
mObserver = getter_AddRefs(NS_GetWeakReference(aObserver));
#endif
return rv;
}
NS_IMETHODIMP
nsLoadGroup::GetGroupObserver(nsIStreamObserver* *aResult)
{
nsCOMPtr<nsIStreamObserver> observer (do_QueryReferent(mObserver));
*aResult = observer;
NS_IF_ADDREF(*aResult);
return NS_OK;
}
NS_IMETHODIMP
nsLoadGroup::GetActiveCount(PRUint32* aResult)
{
*aResult = mForegroundCount;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
nsresult nsLoadGroup::MergeLoadAttributes(nsIRequest *aRequest, nsLoadFlags& outFlags)
{
nsresult rv;
nsLoadFlags flags, oldFlags;
nsCOMPtr<nsIChannel> aChannel = do_QueryInterface(aRequest, &rv);
if (NS_FAILED(rv))
return NS_ERROR_FAILURE;
rv = aChannel->GetLoadAttributes(&flags);
if (NS_FAILED(rv))
return rv;
oldFlags = flags;
//
// Inherit the group cache validation policy (bits 12-15)
//
if ( !((nsIChannel::VALIDATE_NEVER |
nsIChannel::VALIDATE_ALWAYS |
nsIChannel::VALIDATE_ONCE_PER_SESSION |
nsIChannel::VALIDATE_HEURISTICALLY) & flags)) {
flags |= (nsIChannel::VALIDATE_NEVER |
nsIChannel::VALIDATE_ALWAYS |
nsIChannel::VALIDATE_ONCE_PER_SESSION |
nsIChannel::VALIDATE_HEURISTICALLY) & mDefaultLoadAttributes;
}
//
// Inherit the group reload policy (bits 9-10)
//
if (!(nsIChannel::FORCE_VALIDATION & flags)) {
flags |= (nsIChannel::FORCE_VALIDATION & mDefaultLoadAttributes);
}
if (!(nsIChannel::FORCE_RELOAD & flags)) {
flags |= (nsIChannel::FORCE_RELOAD & mDefaultLoadAttributes);
}
//
// Inherit the group persistent cache policy (bit 8)
//
if (!(nsIChannel::INHIBIT_PERSISTENT_CACHING & flags)) {
flags |= (nsIChannel::INHIBIT_PERSISTENT_CACHING & mDefaultLoadAttributes);
}
//
// Inherit the group loading policy (bit 0)
//
if (!(nsIChannel::LOAD_BACKGROUND & flags)) {
flags |= (nsIChannel::LOAD_BACKGROUND & mDefaultLoadAttributes);
}
if (flags != oldFlags) {
rv = aChannel->SetLoadAttributes(flags);
}
outFlags = flags;
return rv;
}

View File

@@ -0,0 +1,78 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsLoadGroup_h__
#define nsLoadGroup_h__
#include "nsILoadGroup.h"
#include "nsIChannel.h"
#include "nsIStreamListener.h"
#include "nsAgg.h"
#include "nsCOMPtr.h"
#include "nsWeakPtr.h"
#include "nsWeakReference.h"
class nsISupportsArray;
class nsLoadGroup : public nsILoadGroup,
public nsSupportsWeakReference
{
public:
NS_DECL_AGGREGATED
////////////////////////////////////////////////////////////////////////////
// nsIRequest methods:
NS_DECL_NSIREQUEST
////////////////////////////////////////////////////////////////////////////
// nsILoadGroup methods:
NS_DECL_NSILOADGROUP
////////////////////////////////////////////////////////////////////////////
// nsLoadGroup methods:
nsLoadGroup(nsISupports* outer);
static NS_METHOD
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
protected:
virtual ~nsLoadGroup();
nsresult Init();
nsresult MergeLoadAttributes(nsIRequest *aRequest, nsLoadFlags& flags);
protected:
PRUint32 mDefaultLoadAttributes;
PRUint32 mForegroundCount;
nsCOMPtr<nsIRequest> mDefaultLoadRequest;
nsISupportsArray* mRequests;
nsWeakPtr mObserver;
// nsCOMPtr<nsIStreamObserver> mObserver;
nsWeakPtr mGroupListenerFactory;
nsresult mStatus;
};
#endif // nsLoadGroup_h__

View File

@@ -0,0 +1,194 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsNetModRegEntry.h"
#include "nsCRT.h"
#include "plstr.h"
#include "nsAutoLock.h"
#include "nsMemory.h"
#include "nsIServiceManager.h"
#include "nsIEventQueueService.h"
#include "nsIProxyObjectManager.h"
static NS_DEFINE_IID(kProxyObjectManagerCID, NS_PROXYEVENT_MANAGER_CID);
static NS_DEFINE_IID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
//////////////////////////////
//// nsISupports
//////////////////////////////
NS_IMPL_THREADSAFE_ISUPPORTS1(nsNetModRegEntry, nsINetModRegEntry);
//////////////////////////////
//// nsINetModRegEntry
//////////////////////////////
NS_IMETHODIMP
nsNetModRegEntry::GetSyncProxy(nsINetNotify **aNotify)
{
nsAutoMonitor mon(mMonitor);
if (mSyncProxy)
{
*aNotify = mSyncProxy;
NS_ADDREF(*aNotify);
return NS_OK;
}
nsresult rv = BuildProxy(PR_TRUE);
if (NS_SUCCEEDED(rv))
{
*aNotify = mSyncProxy;
NS_ADDREF(*aNotify);
}
return rv;
}
NS_IMETHODIMP
nsNetModRegEntry::GetAsyncProxy(nsINetNotify **aNotify)
{
nsAutoMonitor mon(mMonitor);
if (mAsyncProxy)
{
*aNotify = mAsyncProxy;
NS_ADDREF(*aNotify);
return NS_OK;
}
nsresult rv = BuildProxy(PR_FALSE);
if (NS_SUCCEEDED(rv))
{
*aNotify = mAsyncProxy;
NS_ADDREF(*aNotify);
}
return rv;
}
NS_IMETHODIMP
nsNetModRegEntry::GetTopic(char **topic)
{
nsAutoMonitor mon(mMonitor);
if (mTopic)
{
*topic = (char *) nsMemory::Clone(mTopic, nsCRT::strlen(mTopic) + 1);
return NS_OK;
}
return NS_ERROR_NULL_POINTER;
}
NS_IMETHODIMP
nsNetModRegEntry::Equals(nsINetModRegEntry* aEntry, PRBool *_retVal)
{
nsresult rv = NS_OK;
*_retVal = PR_FALSE;
char* topic;
rv = aEntry->GetTopic(&topic);
if (NS_FAILED(rv))
return rv;
if (topic && PL_strcmp(topic, mTopic))
{
nsCOMPtr<nsINetNotify> aSyncProxy;
rv = aEntry->GetSyncProxy(getter_AddRefs(aSyncProxy));
if(aSyncProxy == mSyncProxy)
{
*_retVal = PR_TRUE;
}
nsMemory::Free(topic);
}
return rv;
}
//////////////////////////////
//// nsNetModRegEntry
//////////////////////////////
nsNetModRegEntry::nsNetModRegEntry(const char *aTopic,
nsINetNotify *aNotify,
nsresult *result)
{
NS_INIT_REFCNT();
mTopic = new char [PL_strlen(aTopic) + 1];
PL_strcpy(mTopic, aTopic);
mAsyncProxy = nsnull;
mSyncProxy = nsnull;
mRealNotifier = aNotify;
NS_WITH_SERVICE(nsIEventQueueService, eventQService, kEventQueueServiceCID, result);
if (NS_FAILED(*result)) return;
*result = eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, getter_AddRefs(mEventQ));
mMonitor = nsAutoMonitor::NewMonitor("nsNetModRegEntry");
}
nsresult
nsNetModRegEntry::BuildProxy(PRBool sync)
{
if (mEventQ == nsnull)
return NS_ERROR_NULL_POINTER;
nsresult result;
NS_WITH_SERVICE( nsIProxyObjectManager, proxyManager, kProxyObjectManagerCID, &result);
if (NS_FAILED(result))
return result;
if (sync)
{
result = proxyManager->GetProxyForObject( mEventQ,
NS_GET_IID(nsINetNotify),
mRealNotifier,
PROXY_SYNC | PROXY_ALWAYS,
getter_AddRefs(mSyncProxy));
}
else
{
result = proxyManager->GetProxyForObject( mEventQ,
NS_GET_IID(nsINetNotify),
mRealNotifier,
PROXY_ASYNC | PROXY_ALWAYS,
getter_AddRefs(mAsyncProxy));
}
return result;
}
nsNetModRegEntry::~nsNetModRegEntry()
{
delete [] mTopic;
nsAutoMonitor::DestroyMonitor(mMonitor);
}

View File

@@ -0,0 +1,58 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef ___nsNetModRegEntry_h___
#define ___nsNetModRegEntry_h___
#include "nsINetModRegEntry.h"
#include "prlock.h"
#include "nsIEventQueue.h"
#include "nsCOMPtr.h"
class nsNetModRegEntry : public nsINetModRegEntry {
public:
// nsISupports
NS_DECL_ISUPPORTS
// nsINetModRegEntry
NS_IMETHOD GetSyncProxy(nsINetNotify * *aSyncProxy);
NS_IMETHOD GetAsyncProxy(nsINetNotify * *aAsyncProxy);
NS_IMETHOD GetTopic(char * *aTopic);
NS_IMETHOD Equals(nsINetModRegEntry* aEntry, PRBool *_retVal);
// nsNetModRegEntry
nsNetModRegEntry(const char *aTopic, nsINetNotify *aNotify, nsresult *result);
virtual ~nsNetModRegEntry();
protected:
char *mTopic;
nsCOMPtr<nsINetNotify> mRealNotifier;
nsCOMPtr<nsINetNotify> mSyncProxy;
nsCOMPtr<nsINetNotify> mAsyncProxy;
nsCOMPtr<nsIEventQueue> mEventQ;
nsresult BuildProxy(PRBool sync);
PRMonitor* mMonitor;
};
#endif //___nsNetModRegEntry_h___

View File

@@ -0,0 +1,204 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsAutoLock.h"
#include "nsNetModuleMgr.h"
#include "nsNetModRegEntry.h"
#include "nsEnumeratorUtils.h" // for nsArrayEnumerator
#include "nsString.h"
#include "nsXPIDLString.h"
#include "nsIEventQueue.h"
nsNetModuleMgr* nsNetModuleMgr::gManager;
///////////////////////////////////
//// nsISupports
///////////////////////////////////
NS_IMPL_THREADSAFE_ISUPPORTS1(nsNetModuleMgr, nsINetModuleMgr);
///////////////////////////////////
//// nsINetModuleMgr
///////////////////////////////////
NS_IMETHODIMP
nsNetModuleMgr::RegisterModule(const char *aTopic, nsINetNotify *aNotify)
{
nsresult rv;
PRUint32 cnt;
// XXX before registering an object for a particular topic
// XXX QI the nsINetNotify interface passed in for the interfaces
// XXX supported by the topic.
nsAutoMonitor mon(mMonitor);
nsNetModRegEntry *newEntry = new nsNetModRegEntry(aTopic, aNotify, &rv);
if (!newEntry)
return NS_ERROR_OUT_OF_MEMORY;
if (NS_FAILED(rv)) {
delete newEntry;
return rv;
}
nsCOMPtr<nsINetModRegEntry> newEntryI = do_QueryInterface(newEntry, &rv);
if (NS_FAILED(rv)) {
delete newEntry;
return rv;
}
// Check for a previous registration
mEntries->Count(&cnt);
for (PRUint32 i = 0; i < cnt; i++)
{
nsCOMPtr<nsINetModRegEntry> curEntry =
dont_AddRef(NS_STATIC_CAST(nsINetModRegEntry*, mEntries->ElementAt(i)));
PRBool same = PR_FALSE;
rv = newEntryI->Equals(curEntry, &same);
if (NS_FAILED(rv)) return rv;
// if we've already got this one registered, yank it, and replace it with the new one
if (same) {
mEntries->DeleteElementAt(i);
break;
}
}
rv = mEntries->AppendElement(NS_STATIC_CAST(nsISupports*, newEntryI)) ? NS_OK : NS_ERROR_FAILURE; // XXX this method incorrectly returns a bool
return rv;
}
NS_IMETHODIMP
nsNetModuleMgr::UnregisterModule(const char *aTopic, nsINetNotify *aNotify)
{
nsAutoMonitor mon(mMonitor);
nsresult rv;
nsCOMPtr<nsINetModRegEntry> tmpEntryI;
nsNetModRegEntry *tmpEntry = new nsNetModRegEntry(aTopic, aNotify, &rv);
if (!tmpEntry)
return NS_ERROR_OUT_OF_MEMORY;
if (NS_FAILED(rv)) return rv;
rv = tmpEntry->QueryInterface(NS_GET_IID(nsINetModRegEntry), getter_AddRefs(tmpEntryI));
if (NS_FAILED(rv)) return rv;
PRUint32 cnt;
mEntries->Count(&cnt);
for (PRUint32 i = 0; i < cnt; i++) {
nsCOMPtr<nsINetModRegEntry> curEntry =
dont_AddRef(NS_STATIC_CAST(nsINetModRegEntry*, mEntries->ElementAt(i)));
PRBool same = PR_FALSE;
rv = tmpEntryI->Equals(curEntry, &same);
if (NS_FAILED(rv)) return rv;
if (same) {
mEntries->DeleteElementAt(i);
break;
}
}
return NS_OK;
}
NS_IMETHODIMP
nsNetModuleMgr::EnumerateModules(const char *aTopic, nsISimpleEnumerator **aEnumerator) {
nsresult rv;
// get all the entries for this topic
nsAutoMonitor mon(mMonitor);
PRUint32 cnt;
rv = mEntries->Count(&cnt);
if (NS_FAILED(rv)) return rv;
// create the new array
nsCOMPtr<nsISupportsArray> topicEntries;
rv = NS_NewISupportsArray(getter_AddRefs(topicEntries));
if (NS_FAILED(rv)) return rv;
// run through the main entry array looking for topic matches.
for (PRUint32 i = 0; i < cnt; i++) {
nsCOMPtr<nsINetModRegEntry> entry =
dont_AddRef(NS_STATIC_CAST(nsINetModRegEntry*, mEntries->ElementAt(i)));
nsXPIDLCString topic;
rv = entry->GetTopic(getter_Copies(topic));
if (NS_FAILED(rv)) return rv;
if (0 == PL_strcmp(aTopic, topic)) {
// found a match, add it to the list
rv = topicEntries->AppendElement(NS_STATIC_CAST(nsISupports*, entry)) ? NS_OK : NS_ERROR_FAILURE; // XXX this method incorrectly returns a bool
if (NS_FAILED(rv)) return rv;
}
}
nsCOMPtr<nsISimpleEnumerator> enumerator;
rv = NS_NewArrayEnumerator(getter_AddRefs(enumerator), topicEntries);
if (NS_FAILED(rv)) return rv;
*aEnumerator = enumerator;
NS_ADDREF(*aEnumerator);
return NS_OK;
}
///////////////////////////////////
//// nsNetModuleMgr
///////////////////////////////////
nsNetModuleMgr::nsNetModuleMgr() {
NS_INIT_REFCNT();
NS_NewISupportsArray(&mEntries);
mMonitor = nsAutoMonitor::NewMonitor("nsNetModuleMgr");
}
nsNetModuleMgr::~nsNetModuleMgr() {
NS_IF_RELEASE(mEntries);
nsAutoMonitor::DestroyMonitor(mMonitor);
gManager = nsnull;
}
NS_METHOD
nsNetModuleMgr::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{
if (aOuter)
return NS_ERROR_NO_AGGREGATION;
if (! gManager) {
gManager = new nsNetModuleMgr();
if (! gManager)
return NS_ERROR_OUT_OF_MEMORY;
}
NS_ADDREF(gManager);
nsresult rv = gManager->QueryInterface(aIID, aResult);
NS_RELEASE(gManager);
return rv;
}

View File

@@ -0,0 +1,55 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef ___nsNetModuleMgr_h__
#define ___nsNetModuleMgr_h__
#include "nsINetModuleMgr.h"
#include "prlock.h"
#include "nspr.h"
#include "nsISupportsArray.h"
class nsNetModuleMgr : public nsINetModuleMgr {
protected:
static nsNetModuleMgr* gManager;
public:
// nsISupports
NS_DECL_ISUPPORTS
// nsINetModuleMgr
NS_DECL_NSINETMODULEMGR
// nsNetModuleMgr
nsNetModuleMgr();
virtual ~nsNetModuleMgr();
static NS_METHOD
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
nsISupportsArray *mEntries;
PRMonitor* mMonitor;
};
#endif // ___nsNetModuleMgr_h__

View File

@@ -0,0 +1,410 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Andreas Otte.
*
* Contributor(s):
*/
#include "nsNoAuthURLParser.h"
#include "nsURLHelper.h"
#include "nsCRT.h"
#include "nsString.h"
#include "prprf.h"
#include "prnetdb.h"
NS_IMPL_THREADSAFE_ISUPPORTS1(nsNoAuthURLParser, nsIURLParser)
nsNoAuthURLParser::~nsNoAuthURLParser()
{
}
NS_METHOD
nsNoAuthURLParser::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{
if (aOuter)
return NS_ERROR_NO_AGGREGATION;
nsNoAuthURLParser* p = new nsNoAuthURLParser();
if (p == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(p);
nsresult rv = p->QueryInterface(aIID, aResult);
NS_RELEASE(p);
return rv;
}
nsresult
nsNoAuthURLParser::ParseAtScheme(const char* i_Spec, char* *o_Scheme,
char* *o_Username, char* *o_Password,
char* *o_Host, PRInt32 *o_Port, char* *o_Path)
{
nsresult rv = NS_OK;
NS_PRECONDITION( (nsnull != i_Spec), "Parse called on empty url!");
if (!i_Spec)
return NS_ERROR_MALFORMED_URI;
int len = PL_strlen(i_Spec);
if (len >= 2 && *i_Spec == '/' && *(i_Spec+1) == '/') // No Scheme
{
rv = ParseAtPreHost(i_Spec, o_Username, o_Password, o_Host, o_Port,
o_Path);
return rv;
}
static const char delimiters[] = ":"; //this order is optimized.
char* brk = PL_strpbrk(i_Spec, delimiters);
if (!brk) // everything is a path
{
rv = ParseAtPath((char*)i_Spec, o_Path);
return rv;
}
switch (*brk)
{
case ':' :
rv = ExtractString((char*)i_Spec, o_Scheme, (brk - i_Spec));
if (NS_FAILED(rv))
return rv;
ToLowerCase(*o_Scheme);
rv = ParseAtPreHost(brk+1, o_Username, o_Password, o_Host,
o_Port, o_Path);
return rv;
break;
default:
NS_ASSERTION(0, "This just can't be!");
break;
}
return NS_OK;
}
nsresult
nsNoAuthURLParser::ParseAtPreHost(const char* i_Spec, char* *o_Username,
char* *o_Password, char* *o_Host,
PRInt32 *o_Port, char* *o_Path)
{
nsresult rv = NS_OK;
// Skip leading two slashes if possible
char* fwdPtr= (char*) i_Spec;
if (fwdPtr) {
if (*fwdPtr != '\0')
if (*fwdPtr != '/')
// No Host, go directly to path
return ParseAtPath(fwdPtr,o_Path);
else
// Move over the slash
fwdPtr++;
if (*fwdPtr != '\0')
if (*fwdPtr != '/')
// No Host, go directly to path
return ParseAtPath(fwdPtr,o_Path);
else
// Move over the slash
fwdPtr++;
}
// There maybe is a host
rv = ParseAtHost(fwdPtr, o_Host, o_Port, o_Path);
return rv;
}
nsresult
nsNoAuthURLParser::ParseAtHost(const char* i_Spec, char* *o_Host,
PRInt32 *o_Port, char* *o_Path)
{
// Usually there is no Host, but who knows ...
nsresult rv = NS_OK;
PRInt32 len = PL_strlen(i_Spec);
if ((*i_Spec == '/')
#ifdef XP_PC
// special case for XP_PC: look for a drive
|| (len > 1 && (*(i_Spec+1) == ':' || *(i_Spec+1) == '|'))
#endif
){
// No host, okay ...
rv = ParseAtPath(i_Spec, o_Path);
} else {
// There seems be a host ...
if (len > 1 && *i_Spec == '[') {
// Possible IPv6 address
PRNetAddr netaddr;
char* fwdPtr = PL_strchr(i_Spec+1, ']');
if (fwdPtr) {
rv = ExtractString((char*)i_Spec+1, o_Host,
(fwdPtr - i_Spec - 1));
if (NS_FAILED(rv)) return rv;
rv = PR_StringToNetAddr(*o_Host, &netaddr);
if (rv != PR_SUCCESS || netaddr.raw.family != PR_AF_INET6) {
// try something else
CRTFREEIF(*o_Host);
}
}
}
static const char delimiters[] = "/?#";
char* brk = PL_strpbrk(i_Spec, delimiters);
if (!brk) {
// do we already have a host?
if (!*o_Host) {
// everything is the host
rv = DupString(o_Host, i_Spec);
if (NS_FAILED(rv)) return rv;
ToLowerCase(*o_Host);
}
// parse after the host
rv = ParseAtPath(i_Spec+len, o_Path);
} else {
// do we already have a host?
if (!*o_Host) {
rv = ExtractString((char*)i_Spec, o_Host, (brk - i_Spec));
if (NS_FAILED(rv)) return rv;
ToLowerCase(*o_Host);
}
// parse after the host
rv = ParseAtPath(brk, o_Path);
}
}
return rv;
}
nsresult
nsNoAuthURLParser::ParseAtPort(const char* i_Spec, PRInt32 *o_Port, char* *o_Path)
{
nsresult rv = NS_OK;
// There is no Port
rv = ParseAtPath(i_Spec, o_Path);
return NS_OK;
}
nsresult
nsNoAuthURLParser::ParseAtPath(const char* i_Spec, char* *o_Path)
{
// Just write the path and check for a starting /
nsCAutoString dir;
if ('/' != *i_Spec)
dir += "/";
dir += i_Spec;
*o_Path = dir.ToNewCString();
return (*o_Path ? NS_OK : NS_ERROR_OUT_OF_MEMORY);
}
nsresult
nsNoAuthURLParser::ParseAtDirectory(const char* i_Path, char* *o_Directory,
char* *o_FileBaseName, char* *o_FileExtension,
char* *o_Param, char* *o_Query, char* *o_Ref)
{
// Cleanout
CRTFREEIF(*o_Directory);
CRTFREEIF(*o_FileBaseName);
CRTFREEIF(*o_FileExtension);
CRTFREEIF(*o_Param);
CRTFREEIF(*o_Query);
CRTFREEIF(*o_Ref);
nsresult rv = NS_OK;
// Parse the Path into its components
if (!i_Path)
{
DupString(o_Directory, "/");
return (o_Directory ? NS_OK : NS_ERROR_OUT_OF_MEMORY);
}
char* dirfile = nsnull;
char* options = nsnull;
int len = PL_strlen(i_Path);
/* Factor out the optionpart with ;?# */
static const char delimiters[] = ";?#"; // for param, query and ref
char* brk = PL_strpbrk(i_Path, delimiters);
if (!brk) // Everything is just path and filename
{
DupString(&dirfile, i_Path);
}
else
{
int dirfileLen = brk - i_Path;
ExtractString((char*)i_Path, &dirfile, dirfileLen);
len -= dirfileLen;
ExtractString((char*)i_Path + dirfileLen, &options, len);
brk = options;
}
/* now that we have broken up the path treat every part differently */
/* first dir+file */
char* file;
int dlen = PL_strlen(dirfile);
if (dlen == 0)
{
DupString(o_Directory, "/");
file = dirfile;
} else {
#ifdef XP_PC
// if it contains only a drive then add a /
if (PL_strlen(dirfile) == 3 && *dirfile == '/' &&
(*(dirfile+2) == ':' || *(dirfile+2) == '|')) {
nsCAutoString tempdir;
tempdir += dirfile;
tempdir += "/";
CRTFREEIF(dirfile);
dirfile = tempdir.ToNewCString();
if (!dirfile) return NS_ERROR_OUT_OF_MEMORY;
} else {
// if it is not beginning with a drive and
// there are no three slashes then add them and
// take it as an unc path
if (PL_strlen(dirfile) < 3 ||
!(*(dirfile+2) == ':' || *(dirfile+2) == '|')) {
nsCAutoString tempdir;
if (PL_strlen(dirfile) < 2 || (PL_strlen(dirfile) >= 2 &&
*(dirfile+1) != '/' && *(dirfile+1) != '\\')) {
tempdir += "/";
}
if (PL_strlen(dirfile) < 3 || (PL_strlen(dirfile) >= 3 &&
*(dirfile+2) != '/' && *(dirfile+2) != '\\')) {
tempdir += "/";
}
tempdir += dirfile;
CRTFREEIF(dirfile);
dirfile = tempdir.ToNewCString();
if (!dirfile) return NS_ERROR_OUT_OF_MEMORY;
}
}
#endif
CoaleseDirs(dirfile);
// Get length again
dlen = PL_strlen(dirfile);
// First find the last slash
file = PL_strrchr(dirfile, '/');
if (!file)
{
DupString(o_Directory, "/");
file = dirfile;
}
// If its not the same as the first slash then extract directory
if (file != dirfile)
{
ExtractString(dirfile, o_Directory, (file - dirfile)+1);
if (*dirfile != '/') {
nsCAutoString dir;
dir += "/" ;
dir += *o_Directory;
CRTFREEIF(*o_Directory);
*o_Directory = dir.ToNewCString();
}
} else {
DupString(o_Directory, "/");
}
}
/* Extract FileBaseName and FileExtension */
if (dlen > 0) {
// Look again if there was a slash
char* slash = PL_strrchr(dirfile, '/');
char* e_FileName = nsnull;
if (slash) {
if (dirfile+dlen-1>slash)
ExtractString(slash+1, &e_FileName, dlen-(slash-dirfile+1));
} else {
// Use the full String as Filename
ExtractString(dirfile, &e_FileName, dlen);
}
rv = ParseFileName(e_FileName,o_FileBaseName,o_FileExtension);
CRTFREEIF(e_FileName);
}
// Now take a look at the options. "#" has precedence over "?"
// which has precedence over ";"
if (options) {
// Look for "#" first. Everything following it is in the ref
brk = PL_strchr(options, '#');
if (brk) {
int pieceLen = len - (brk + 1 - options);
ExtractString(brk+1, o_Ref, pieceLen);
len -= pieceLen + 1;
*brk = '\0';
}
// Now look for "?"
brk = PL_strchr(options, '?');
if (brk) {
int pieceLen = len - (brk + 1 - options);
ExtractString(brk+1, o_Query, pieceLen);
len -= pieceLen + 1;
*brk = '\0';
}
// Now look for ';'
brk = PL_strchr(options, ';');
if (brk) {
int pieceLen = len - (brk + 1 - options);
ExtractString(brk+1, o_Param, pieceLen);
len -= pieceLen + 1;
*brk = '\0';
}
}
nsCRT::free(dirfile);
nsCRT::free(options);
return rv;
}
nsresult
nsNoAuthURLParser::ParsePreHost(const char* i_PreHost, char* *o_Username,
char* *o_Password)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
nsresult
nsNoAuthURLParser::ParseFileName(const char* i_FileName,
char* *o_FileBaseName,
char* *o_FileExtension)
{
nsresult rv = NS_OK;
if (!i_FileName) {
*o_FileBaseName = nsnull;
*o_FileExtension = nsnull;
return rv;
}
// Search for FileExtension
// Search for last .
// Ignore . at the beginning
char* brk = PL_strrchr(i_FileName+1, '.');
if (brk)
{
rv = ExtractString((char*)i_FileName, o_FileBaseName,
(brk - i_FileName));
if (NS_FAILED(rv))
return rv;
rv = ExtractString(brk + 1, o_FileExtension,
(i_FileName+PL_strlen(i_FileName) - brk - 1));
} else {
rv = DupString(o_FileBaseName, i_FileName);
}
return rv;
}

View File

@@ -0,0 +1,51 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsNoAuthURLParser_h__
#define nsNoAuthURLParser_h__
#include "nsIURLParser.h"
#include "nsIURI.h"
#include "nsAgg.h"
#include "nsCRT.h"
class nsNoAuthURLParser : public nsIURLParser
{
public:
NS_DECL_ISUPPORTS
///////////////////////////////////////////////////////////////////////////
// nsNoAuthURLParser methods:
nsNoAuthURLParser() {
NS_INIT_REFCNT();
}
virtual ~nsNoAuthURLParser();
static NS_METHOD
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
///////////////////////////////////////////////////////////////////////////
// nsIURLParser methods:
NS_DECL_NSIURLPARSER
};
#endif // nsNoAuthURLParser_h__

View File

@@ -0,0 +1,457 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsProtocolProxyService.h"
#include "nsIServiceManager.h"
#include "nsXPIDLString.h"
#include "nsIProxyAutoConfig.h"
#include "nsAutoLock.h"
static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID);
static const char PROXY_PREFS[] = "network.proxy";
static PRInt32 PR_CALLBACK ProxyPrefsCallback(const char* pref, void* instance)
{
nsProtocolProxyService* proxyServ = (nsProtocolProxyService*) instance;
NS_ASSERTION(proxyServ, "bad instance data");
if (proxyServ) proxyServ->PrefsChanged(pref);
return 0;
}
NS_IMPL_THREADSAFE_ISUPPORTS1(nsProtocolProxyService, nsIProtocolProxyService);
nsProtocolProxyService::nsProtocolProxyService():
mArrayLock(PR_NewLock()),
mUseProxy(0)
{
NS_INIT_REFCNT();
}
nsProtocolProxyService::~nsProtocolProxyService()
{
if(mArrayLock)
PR_DestroyLock(mArrayLock);
if (mFiltersArray.Count() > 0)
{
mFiltersArray.EnumerateForwards(
(nsVoidArrayEnumFunc)this->CleanupFilterArray, nsnull);
mFiltersArray.Clear();
}
}
// nsProtocolProxyService methods
NS_IMETHODIMP
nsProtocolProxyService::Init() {
nsresult rv = NS_OK;
mPrefs = do_GetService(kPrefServiceCID, &rv);
if (NS_FAILED(rv)) return rv;
// register for change callbacks
rv = mPrefs->RegisterCallback(PROXY_PREFS, ProxyPrefsCallback, (void*)this);
if (NS_FAILED(rv)) return rv;
PrefsChanged(nsnull);
return NS_OK;
}
NS_METHOD
nsProtocolProxyService::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult) {
nsresult rv;
if (aOuter) return NS_ERROR_NO_AGGREGATION;
nsProtocolProxyService* serv = new nsProtocolProxyService();
if (!serv) return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(serv);
rv = serv->Init();
if (NS_FAILED(rv)) {
delete serv;
return rv;
}
rv = serv->QueryInterface(aIID, aResult);
NS_RELEASE(serv);
return rv;
}
void
nsProtocolProxyService::PrefsChanged(const char* pref) {
NS_ASSERTION(mPrefs, "No preference service available!");
if (!mPrefs) return;
nsresult rv = NS_OK;
nsXPIDLCString tempString;
if (!pref || !PL_strcmp(pref, "network.proxy.type"))
{
PRInt32 type = -1;
rv = mPrefs->GetIntPref("network.proxy.type",&type);
if (NS_SUCCEEDED(rv))
mUseProxy = type; // type == 2 is autoconfig stuff
}
if (!pref || !PL_strcmp(pref, "network.proxy.http"))
{
mHTTPProxyHost = "";
rv = mPrefs->CopyCharPref("network.proxy.http",
getter_Copies(tempString));
if (NS_SUCCEEDED(rv) && tempString && *tempString)
mHTTPProxyHost = nsCRT::strdup(tempString);
}
if (!pref || !PL_strcmp(pref, "network.proxy.http_port"))
{
mHTTPProxyPort = -1;
PRInt32 proxyPort = -1;
rv = mPrefs->GetIntPref("network.proxy.http_port",&proxyPort);
if (NS_SUCCEEDED(rv) && proxyPort>0)
mHTTPProxyPort = proxyPort;
}
if (!pref || !PL_strcmp(pref, "network.proxy.ssl"))
{
mHTTPSProxyHost = "";
rv = mPrefs->CopyCharPref("network.proxy.ssl",
getter_Copies(tempString));
if (NS_SUCCEEDED(rv) && tempString && *tempString)
mHTTPSProxyHost = nsCRT::strdup(tempString);
}
if (!pref || !PL_strcmp(pref, "network.proxy.ssl_port"))
{
mHTTPSProxyPort = -1;
PRInt32 proxyPort = -1;
rv = mPrefs->GetIntPref("network.proxy.ssl_port",&proxyPort);
if (NS_SUCCEEDED(rv) && proxyPort>0)
mHTTPSProxyPort = proxyPort;
}
if (!pref || !PL_strcmp(pref, "network.proxy.ftp"))
{
mFTPProxyHost = "";
rv = mPrefs->CopyCharPref("network.proxy.ftp",
getter_Copies(tempString));
if (NS_SUCCEEDED(rv) && tempString && *tempString)
mFTPProxyHost = nsCRT::strdup(tempString);
}
if (!pref || !PL_strcmp(pref, "network.proxy.ftp_port"))
{
mFTPProxyPort = -1;
PRInt32 proxyPort = -1;
rv = mPrefs->GetIntPref("network.proxy.ftp_port",&proxyPort);
if (NS_SUCCEEDED(rv) && proxyPort>0)
mFTPProxyPort = proxyPort;
}
if (!pref || !PL_strcmp(pref, "network.proxy.gopher"))
{
mGopherProxyHost = "";
rv = mPrefs->CopyCharPref("network.proxy.gopher",
getter_Copies(tempString));
if (NS_SUCCEEDED(rv) && tempString && *tempString)
mGopherProxyHost = nsCRT::strdup(tempString);
}
if (!pref || !PL_strcmp(pref, "network.proxy.gopher_port"))
{
mGopherProxyPort = -1;
PRInt32 proxyPort = -1;
rv = mPrefs->GetIntPref("network.proxy.gopher_port",&proxyPort);
if (NS_SUCCEEDED(rv) && proxyPort>0)
mGopherProxyPort = proxyPort;
}
if (!pref || !PL_strcmp(pref, "network.proxy.socks"))
{
mSOCKSProxyHost = "";
rv = mPrefs->CopyCharPref("network.proxy.socks",
getter_Copies(tempString));
if (NS_SUCCEEDED(rv) && tempString && *tempString)
mSOCKSProxyHost = nsCRT::strdup(tempString);
}
if (!pref || !PL_strcmp(pref, "network.proxy.socks_port"))
{
mSOCKSProxyPort = -1;
PRInt32 proxyPort = -1;
rv = mPrefs->GetIntPref("network.proxy.socks_port",&proxyPort);
if (NS_SUCCEEDED(rv) && proxyPort>0)
mSOCKSProxyPort = proxyPort;
}
if (!pref || !PL_strcmp(pref, "network.proxy.no_proxies_on"))
{
rv = mPrefs->CopyCharPref("network.proxy.no_proxies_on",
getter_Copies(tempString));
if (NS_SUCCEEDED(rv) && tempString && *tempString)
(void)LoadFilters((const char*)tempString);
}
}
PRBool
nsProtocolProxyService::CanUseProxy(nsIURI* aURI)
{
if (mFiltersArray.Count() == 0)
return PR_TRUE;
PRInt32 port;
nsXPIDLCString host;
nsresult rv = aURI->GetHost(getter_Copies(host));
if (NS_FAILED(rv) || !host || !*host)
return PR_FALSE;
rv = aURI->GetPort(&port);
if (NS_FAILED(rv)) {
return PR_FALSE;
}
PRInt32 index = -1;
int host_len = PL_strlen(host);
int filter_host_len;
while (++index < mFiltersArray.Count())
{
host_port* hp = (host_port*) mFiltersArray[index];
// only if port doesn't exist or matches
if (((hp->port == -1) || (hp->port == port)) &&
hp->host)
{
filter_host_len = hp->host->Length();
if ((host_len >= filter_host_len) &&
(0 == PL_strncasecmp(host + host_len - filter_host_len,
hp->host->get(), filter_host_len)))
return PR_FALSE;
}
}
return PR_TRUE;
}
// nsIProtocolProxyService
NS_IMETHODIMP
nsProtocolProxyService::ExamineForProxy(nsIURI *aURI, nsIProxy *aProxy) {
nsresult rv = NS_OK;
NS_ASSERTION(aURI && aProxy, "need a uri and proxy iface folks.");
// if proxies are enabled and this host:port combo is
// supposed to use a proxy, check for a proxy.
if ((0 == mUseProxy) ||
((1 == mUseProxy) && !CanUseProxy(aURI))) {
rv = aProxy->SetProxyHost(nsnull);
if (NS_FAILED(rv)) return rv;
rv = aProxy->SetProxyPort(-1);
if (NS_FAILED(rv)) return rv;
return NS_OK;
}
// Proxy auto config magic...
if (2 == mUseProxy)
{
// later on put this in a member variable TODO
nsCOMPtr<nsIProxyAutoConfig> pac =
do_CreateInstance(NS_PROXY_AUTO_CONFIG_CONTRACTID, &rv);
if (NS_SUCCEEDED(rv))
{
nsXPIDLCString p_host;
nsXPIDLCString p_type;
PRInt32 p_port;
if (NS_SUCCEEDED(rv = pac->ProxyForURL(aURI, getter_Copies(p_host),
&p_port, getter_Copies(p_type))))
{
if (NS_FAILED(rv = aProxy->SetProxyHost(p_host)))
return rv;
if (NS_FAILED(rv = aProxy->SetProxyPort(p_port)))
return rv;
if (NS_FAILED(rv = aProxy->SetProxyType(p_type)))
return rv;
return NS_OK;
}
}
return rv;
}
nsXPIDLCString scheme;
rv = aURI->GetScheme(getter_Copies(scheme));
if (NS_FAILED(rv)) return rv;
if (mFTPProxyHost.get()[0] && mFTPProxyPort > 0 &&
!PL_strcasecmp(scheme, "ftp")) {
rv = aProxy->SetProxyHost(mFTPProxyHost);
if (NS_FAILED(rv)) return rv;
aProxy->SetProxyType("http");
return aProxy->SetProxyPort(mFTPProxyPort);
}
if (mGopherProxyHost.get()[0] && mGopherProxyPort > 0 &&
!PL_strcasecmp(scheme, "gopher")) {
rv = aProxy->SetProxyHost(mGopherProxyHost);
if (NS_FAILED(rv)) return rv;
aProxy->SetProxyType("http");
return aProxy->SetProxyPort(mGopherProxyPort);
}
if (mHTTPProxyHost.get()[0] && mHTTPProxyPort > 0 &&
!PL_strcasecmp(scheme, "http")) {
rv = aProxy->SetProxyHost(mHTTPProxyHost);
if (NS_FAILED(rv)) return rv;
aProxy->SetProxyType("http");
return aProxy->SetProxyPort(mHTTPProxyPort);
}
if (mHTTPSProxyHost.get()[0] && mHTTPSProxyPort > 0 &&
!PL_strcasecmp(scheme, "https")) {
rv = aProxy->SetProxyHost(mHTTPSProxyHost);
if (NS_FAILED(rv)) return rv;
aProxy->SetProxyType("http");
return aProxy->SetProxyPort(mHTTPSProxyPort);
}
if (mSOCKSProxyHost.get()[0] && mSOCKSProxyPort > 0) {
rv = aProxy->SetProxyHost(mSOCKSProxyHost);
if (NS_FAILED(rv)) return rv;
aProxy->SetProxyType("socks");
return aProxy->SetProxyPort(mSOCKSProxyPort);
}
return NS_OK;
}
NS_IMETHODIMP
nsProtocolProxyService::GetProxyEnabled(PRBool* o_Enabled)
{
if (!o_Enabled)
return NS_ERROR_NULL_POINTER;
*o_Enabled = mUseProxy;
return NS_OK;
}
NS_IMETHODIMP
nsProtocolProxyService::AddNoProxyFor(const char* iHost, PRInt32 iPort)
{
if (!iHost)
return NS_ERROR_NULL_POINTER;
host_port* hp = new host_port();
if (!hp)
return NS_ERROR_OUT_OF_MEMORY;
hp->host = new nsCString(iHost);
hp->port = iPort;
nsAutoLock lock(mArrayLock);
return (mFiltersArray.AppendElement(hp)) ? NS_OK : NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsProtocolProxyService::RemoveNoProxyFor(const char* iHost, PRInt32 iPort)
{
if (!iHost)
return NS_ERROR_NULL_POINTER;
nsAutoLock lock(mArrayLock);
if (mFiltersArray.Count()==0)
return NS_ERROR_FAILURE;
PRInt32 index = -1;
while (++index < mFiltersArray.Count())
{
host_port* hp = (host_port*) mFiltersArray[index];
if ((hp && hp->host) &&
(iPort == hp->port) &&
(0 == PL_strcasecmp((const char*)hp->host, iHost)))
{
delete hp->host;
delete hp;
mFiltersArray.RemoveElementAt(index);
return NS_OK;
}
}
return NS_ERROR_FAILURE; // not found
}
PRBool
nsProtocolProxyService::CleanupFilterArray(void* aElement, void* aData)
{
if (aElement)
{
host_port* hp = (host_port*)aElement;
delete hp->host;
delete hp;
}
return PR_TRUE;
}
void
nsProtocolProxyService::LoadFilters(const char* filters)
{
host_port* hp;
// check to see the owners flag? /!?/ TODO
if (mFiltersArray.Count() > 0)
{
mFiltersArray.EnumerateForwards(
(nsVoidArrayEnumFunc)this->CleanupFilterArray, nsnull);
mFiltersArray.Clear();
}
if (!filters)
return ;//fail silently...
char* np = (char*)filters;
while (*np)
{
// skip over spaces and ,
while (*np && (*np == ',' || nsCRT::IsAsciiSpace(*np)))
np++;
char* endproxy = np+1; // at least that...
char* portLocation = 0;
PRInt32 nport = 0; // no proxy port
while (*endproxy && (*endproxy != ',' &&
!nsCRT::IsAsciiSpace(*endproxy)))
{
if (*endproxy == ':')
portLocation = endproxy;
endproxy++;
}
if (portLocation)
nport = atoi(portLocation+1);
hp = new host_port();
if (!hp)
return; // fail silently
hp->host = new nsCString(np, endproxy-np);
if (!hp->host)
return;
hp->port = nport>0 ? nport : -1;
mFiltersArray.AppendElement(hp);
np = endproxy;
}
}

View File

@@ -0,0 +1,84 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef __nsprotocolproxyservice___h___
#define __nsprotocolproxyservice___h___
#include "nsString.h"
#include "nsCOMPtr.h"
#include "nsIPref.h"
#include "nsVoidArray.h"
#include "nsXPIDLString.h"
#include "nsIProtocolProxyService.h"
class nsProtocolProxyService : public nsIProtocolProxyService {
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIPROTOCOLPROXYSERVICE
nsProtocolProxyService();
virtual ~nsProtocolProxyService();
NS_IMETHOD Init();
static NS_METHOD
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
void PrefsChanged(const char* pref);
protected:
void LoadFilters(const char* filters);
static PRBool CleanupFilterArray(void* aElement, void* aData);
// simplified array of filters defined by this struct
struct host_port {
nsCString* host;
PRInt32 port;
};
PRLock *mArrayLock;
nsVoidArray mFiltersArray;
PRBool CanUseProxy(nsIURI* aURI);
nsCOMPtr<nsIPref> mPrefs;
PRUint16 mUseProxy;
nsXPIDLCString mHTTPProxyHost;
PRInt32 mHTTPProxyPort;
nsXPIDLCString mFTPProxyHost;
PRInt32 mFTPProxyPort;
nsXPIDLCString mGopherProxyHost;
PRInt32 mGopherProxyPort;
nsXPIDLCString mHTTPSProxyHost;
PRInt32 mHTTPSProxyPort;
nsXPIDLCString mSOCKSProxyHost;
PRInt32 mSOCKSProxyPort;
};
#endif // __nsprotocolproxyservice___h___

View File

@@ -0,0 +1,257 @@
/* -*- Mode: Java; tab-width: 4; c-basic-offset: 4; -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
/*
Script for Proxy Auto Config in the new world order.
- Gagan Saksena 04/24/00
*/
const kPAC_CONTRACTID = "@mozilla.org/network/proxy_autoconfig;1";
const kIOSERVICE_CONTRACTID = "@mozilla.org/network/io-service;1";
const kDNS_CONTRACTID = "@mozilla.org/network/dns-service;1";
const kPAC_CID = Components.ID("{63ac8c66-1dd2-11b2-b070-84d00d3eaece}");
const nsIProxyAutoConfig = Components.interfaces.nsIProxyAutoConfig;
const nsIIOService = Components.interfaces['nsIIOService'];
const nsIDNSService = Components.interfaces.nsIDNSService;
function debug(msg)
{
dump("\nPAC:" + msg + "\n\n");
}
// implementor of nsIProxyAutoConfig
function nsProxyAutoConfig() {};
nsProxyAutoConfig.prototype = {
ProxyForURL: function(url, host, port, type) {
var uri = url.QueryInterface(Components.interfaces.nsIURI);
// Call the original function-
var proxy = FindProxyForURL(uri.spec, uri.host);
debug("Proxy = " + proxy);
if (proxy == "DIRECT") {
host.value = null;
type.value = "direct";
}
else {
// TODO warn about SOCKS
// we ignore everything else past the first proxy.
// we could theoretically check isResolvable now and continue
// parsing. but for now...
var hostport = /^PROXY ([^:]+):(\d+)/(proxy);
host.value = hostport[1];
port.value = hostport[2];
type.value = "http"; //proxy (http, socks, direct, etc)
}
}
}
var pacModule = new Object();
pacModule.registerSelf =
function (compMgr, fileSpec, location, type) {
dump("*** Registering Proxy Auto Config (a Javascript module!) \n");
compMgr.registerComponentWithType(kPAC_CID,
"Proxy Auto Config",
kPAC_CONTRACTID,
fileSpec, location,
true, true, type);
}
pacModule.getClassObject =
function (compMgr, cid, iid) {
if (!cid.equals(kPAC_CID))
throw Components.results.NS_ERROR_NO_INTERFACE;
if (!iid.equals(Components.interfaces.nsIFactory))
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
return pacFactory;
}
pacModule.canUnload =
function (compMgr) {
dump("*** Unloading Proxy Auto Config...\n");
return true;
}
var pacFactory = new Object();
pacFactory.createInstance =
function (outer, iid) {
if (outer != null)
throw Components.results.NS_ERROR_NO_AGGREGATION;
if (!iid.equals(nsIProxyAutoConfig) &&
!iid.equals(Components.interfaces.nsISupports)) {
// shouldn't this be NO_INTERFACE?
throw Components.results.NS_ERROR_INVALID_ARG;
}
return PacMan;
}
function NSGetModule(compMgr, fileSpec) {
return pacModule;
}
var PacMan = new nsProxyAutoConfig() ;
// dumb hacks for "special" functions that should have long been
// deprecated.
var date = new Date();
function dateRange(dmy) {
var intval = parseInt(dmy, 10);
if (isNaN(intval)) { // it's a month
return (date.toString().toLowerCase().search(dmy.toLowerCase()) != -1);
}
if (intval <= 31) { // it's a day
return (date.getDate() == intval);
}
else { // it's an year
return (date.getFullYear() == intval);
}
}
function dateRange(dmy1, dmy2) {
dump("nsProxyAutoConfig.js: dateRange function deprecated or not implemented\n");
return false;
}
function dateRange(d1, m1, y1, d2, m2, y2) {
var date1 = new Date(y1,m1,d1);
var date2 = new Date(y2,m2,d2);
return (date >= date1) && (date <= date2);
}
function dnsDomainIs(host, domain) {
//TODO fix this later!
return (host.search(domain) != -1);
}
function dnsDomainLevels(host) {
return host.split('.').length-1;
}
var ios = Components.classes[kIOSERVICE_CONTRACTID].getService(nsIIOService);
var dns = Components.classes[kDNS_CONTRACTID].getService(nsIDNSService);
function dnsResolve(host) {
try {
var addr = dns.resolve(host);
//debug(addr);
return addr;
}
catch (ex) {
debug (ex);
// ugh... return error!
return null;
}
}
// This function could be done here instead of in nsDNSService...
function isInNet(ipaddr, pattern, mask) {
var result = dns.isInNet(ipaddr, pattern, mask);
//debug(result);
return result;
}
function isPlainHostName(host) {
return (host.search("\.") == -1);
}
function isResolvable(host) {
var ip = dnsResolve(host);
return (ip != null) ? true: false;
}
function localHostOrDomainIs(host, hostdom) {
if (isPlainHostName(host)) {
return (hostdom.search("/^" + host + "/") != -1);
}
else {
return (host == hostdom); //TODO check
}
}
function myIpAddress() {
try {
// for now...
var ip = dnsResolve("localhost");
return ip;
}
catch (ex) {
debug(ex);
}
return null;
}
function shExpMatch(str, shexp) {
dump("nsProxyAutoConfig.js: shExpMatch function deprecated or not implemented\n");
// this may be a tricky one to implement in JS.
return false;
}
function timeRange(hour) {
dump("nsProxyAutoConfig.js: timeRange function deprecated or not implemented\n");
return false;
}
function timeRange(h1, h2) {
dump("nsProxyAutoConfig.js: timeRange function deprecated or not implemented\n");
return false;
}
function timeRange(h1, m1, h2, m2) {
dump("nsProxyAutoConfig.js: timeRange function deprecated or not implemented\n");
return false;
}
function timeRange(h1, m1, s1, h2, m2, s2) {
dump("nsProxyAutoConfig.js: timeRange function deprecated or not implemented\n");
return false;
}
function timeRange(h1, m1, s1, h2, m2, s2, gmt) {
dump("nsProxyAutoConfig.js: timeRange function deprecated or not implemented\n");
return false;
}
function weekdayRange(wd1, wd2, gmt) {
dump("nsProxyAutoConfig.js: weekdayRange function deprecated or not implemented\n");
return false;
}
///--------- replace everything below with your existing pac file ...
// Sample implementation ...
function FindProxyForURL(url, host)
{
if (isPlainHostName(host) ||
dnsDomainIs(host, ".mozilla.org") ||
isResolvable(host))
return "DIRECT";
else
return "PROXY tegu.mozilla.org:3130; DIRECT";
}

View File

@@ -0,0 +1,59 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Andreas Otte.
*
* Contributor(s):
*/
#include "nsProxyAutoConfigUtils.h"
nsProxyAutoConfigUtils::nsProxyAutoConfigUtils()
{
NS_INIT_ISUPPORTS();
}
nsProxyAutoConfigUtils::~nsProxyAutoConfigUtils()
{
}
NS_IMPL_ISUPPORTS1(nsProxyAutoConfigUtils, nsIProxyAutoConfigUtils);
NS_IMETHODIMP
nsProxyAutoConfigUtils::IsResolvable(const char* aHost, PRBool *result)
{
return NS_OK;
}
NS_IMETHODIMP
nsProxyAutoConfigUtils::IsInNet(const char* aHost,
const char* aPattern,
const char* aMask,
PRBool *result)
{
return NS_OK;
}
NS_IMETHODIMP
nsProxyAutoConfigUtils::DNSResolve(const char* aHost, char** aIPAddress)
{
return NS_OK;
}
NS_IMETHODIMP
nsProxyAutoConfigUtils::MyIPAddress(char **aIPAddress)
{
return NS_OK;
}

View File

@@ -0,0 +1,39 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Andreas Otte.
*
* Contributor(s):
*/
#ifndef _nsPACUtils_h_
#define _nsPACUtils_h_
#include "nsCOMPtr.h"
#include "nsIProxyAutoConfigUtils.h"
class nsProxyAutoConfigUtils : public nsIProxyAutoConfigUtils
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIPROXYAUTOCONFIGUTILS
nsProxyAutoConfigUtils();
virtual ~nsProxyAutoConfigUtils();
};
#endif // _nsPACUtils_h_

View File

@@ -0,0 +1,96 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Darin Fisher <darin@netscape.com> (original author)
*/
#include "nsSimpleStreamListener.h"
//
//----------------------------------------------------------------------------
// nsISupports implementation...
//----------------------------------------------------------------------------
//
NS_IMPL_ISUPPORTS3(nsSimpleStreamListener,
nsISimpleStreamListener,
nsIStreamListener,
nsIStreamObserver)
//
//----------------------------------------------------------------------------
// nsIStreamObserver implementation...
//----------------------------------------------------------------------------
//
NS_IMETHODIMP
nsSimpleStreamListener::OnStartRequest(nsIRequest *aRequest,
nsISupports *aContext)
{
return mObserver ?
mObserver->OnStartRequest(aRequest, aContext) : NS_OK;
}
NS_IMETHODIMP
nsSimpleStreamListener::OnStopRequest(nsIRequest* request,
nsISupports *aContext,
nsresult aStatus,
const PRUnichar *aStatusText)
{
return mObserver ?
mObserver->OnStopRequest(request, aContext, aStatus, aStatusText) : NS_OK;
}
//
//----------------------------------------------------------------------------
// nsIStreamListener implementation...
//----------------------------------------------------------------------------
//
NS_IMETHODIMP
nsSimpleStreamListener::OnDataAvailable(nsIRequest* request,
nsISupports *aContext,
nsIInputStream *aSource,
PRUint32 aOffset,
PRUint32 aCount)
{
PRUint32 writeCount;
nsresult rv = mSink->WriteFrom(aSource, aCount, &writeCount);
//
// Equate zero bytes read and NS_SUCCEEDED to stopping the read.
//
if (NS_SUCCEEDED(rv) && (writeCount == 0))
return NS_BASE_STREAM_CLOSED;
return rv;
}
//
//----------------------------------------------------------------------------
// nsISimpleStreamListener implementation...
//----------------------------------------------------------------------------
//
NS_IMETHODIMP
nsSimpleStreamListener::Init(nsIOutputStream *aSink,
nsIStreamObserver *aObserver)
{
NS_PRECONDITION(aSink, "null output stream");
mSink = aSink;
mObserver = aObserver;
return NS_OK;
}

View File

@@ -0,0 +1,19 @@
#include "nsIStreamListener.h"
#include "nsIOutputStream.h"
#include "nsCOMPtr.h"
class nsSimpleStreamListener : public nsISimpleStreamListener
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSISTREAMOBSERVER
NS_DECL_NSISTREAMLISTENER
NS_DECL_NSISIMPLESTREAMLISTENER
nsSimpleStreamListener() { NS_INIT_ISUPPORTS(); }
virtual ~nsSimpleStreamListener() {}
protected:
nsCOMPtr<nsIOutputStream> mSink;
nsCOMPtr<nsIStreamObserver> mObserver;
};

View File

@@ -0,0 +1,97 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Darin Fisher <darin@netscape.com> (original author)
*/
#include "nsSimpleStreamProvider.h"
#include "nsIOutputStream.h"
//
//----------------------------------------------------------------------------
// nsISupports implementation...
//----------------------------------------------------------------------------
//
NS_IMPL_THREADSAFE_ISUPPORTS3(nsSimpleStreamProvider,
nsISimpleStreamProvider,
nsIStreamProvider,
nsIStreamObserver)
//
//----------------------------------------------------------------------------
// nsIStreamObserver implementation...
//----------------------------------------------------------------------------
//
NS_IMETHODIMP
nsSimpleStreamProvider::OnStartRequest(nsIRequest *request,
nsISupports *aContext)
{
return mObserver ?
mObserver->OnStartRequest(request, aContext) : NS_OK;
}
NS_IMETHODIMP
nsSimpleStreamProvider::OnStopRequest(nsIRequest* request,
nsISupports *aContext,
nsresult aStatus,
const PRUnichar *aStatusText)
{
return mObserver ?
mObserver->OnStopRequest(request, aContext, aStatus, aStatusText) : NS_OK;
}
//
//----------------------------------------------------------------------------
// nsIStreamProvider implementation...
//----------------------------------------------------------------------------
//
NS_IMETHODIMP
nsSimpleStreamProvider::OnDataWritable(nsIRequest *request,
nsISupports *aContext,
nsIOutputStream *aOutput,
PRUint32 aOffset,
PRUint32 aCount)
{
PRUint32 writeCount;
nsresult rv = aOutput->WriteFrom(mSource, aCount, &writeCount);
//
// Equate zero bytes written and NS_SUCCEEDED to EOF
//
if (NS_SUCCEEDED(rv) && (writeCount == 0))
return NS_BASE_STREAM_CLOSED;
return rv;
}
//
//----------------------------------------------------------------------------
// nsISimpleStreamProvider implementation...
//----------------------------------------------------------------------------
//
NS_IMETHODIMP
nsSimpleStreamProvider::Init(nsIInputStream *aSource,
nsIStreamObserver *aObserver)
{
NS_PRECONDITION(aSource, "null input stream");
mSource = aSource;
mObserver = aObserver;
return NS_OK;
}

View File

@@ -0,0 +1,19 @@
#include "nsIStreamProvider.h"
#include "nsIInputStream.h"
#include "nsCOMPtr.h"
class nsSimpleStreamProvider : public nsISimpleStreamProvider
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSISTREAMOBSERVER
NS_DECL_NSISTREAMPROVIDER
NS_DECL_NSISIMPLESTREAMPROVIDER
nsSimpleStreamProvider() { NS_INIT_ISUPPORTS(); }
virtual ~nsSimpleStreamProvider() {}
protected:
nsCOMPtr<nsIInputStream> mSource;
nsCOMPtr<nsIStreamObserver> mObserver;
};

View File

@@ -0,0 +1,310 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Pierre Phaneuf <pp@ludusdesign.com>
* Gagan Saksena <gagan@netscape.com>
*/
#include "nsSimpleURI.h"
#include "nscore.h"
#include "nsCRT.h"
#include "nsString.h"
#include "prmem.h"
#include "prprf.h"
#include "nsURLHelper.h"
static NS_DEFINE_CID(kSimpleURICID, NS_SIMPLEURI_CID);
static NS_DEFINE_CID(kThisSimpleURIImplementationCID,
NS_THIS_SIMPLEURI_IMPLEMENTATION_CID);
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
////////////////////////////////////////////////////////////////////////////////
// nsSimpleURI methods:
nsSimpleURI::nsSimpleURI(nsISupports* outer)
: mScheme(nsnull),
mPath(nsnull)
{
NS_INIT_AGGREGATED(outer);
}
nsSimpleURI::~nsSimpleURI()
{
if (mScheme) nsCRT::free(mScheme);
if (mPath) nsCRT::free(mPath);
}
NS_IMPL_AGGREGATED(nsSimpleURI);
NS_IMETHODIMP
nsSimpleURI::AggregatedQueryInterface(const nsIID& aIID, void** aInstancePtr)
{
NS_ENSURE_ARG_POINTER(aInstancePtr);
if (aIID.Equals(kISupportsIID))
*aInstancePtr = GetInner();
else if (aIID.Equals(kThisSimpleURIImplementationCID) || // used by Equals
aIID.Equals(NS_GET_IID(nsIURI)))
*aInstancePtr = NS_STATIC_CAST(nsIURI*, this);
else {
*aInstancePtr = nsnull;
return NS_NOINTERFACE;
}
NS_ADDREF((nsISupports*)*aInstancePtr);
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsIURI methods:
NS_IMETHODIMP
nsSimpleURI::GetSpec(char* *result)
{
nsAutoString string;
// NS_LOCK_INSTANCE();
// STRING USE WARNING: perhaps |string| should be |nsCAutoString|? -- scc
string.AssignWithConversion(mScheme);
string.AppendWithConversion(':');
string.AppendWithConversion(mPath);
// NS_UNLOCK_INSTANCE();
*result = string.ToNewCString();
return NS_OK;
}
NS_IMETHODIMP
nsSimpleURI::SetSpec(const char* aSpec)
{
nsAutoString spec;
spec.AssignWithConversion(aSpec);
PRInt32 pos = spec.Find(":");
if (pos == -1)
return NS_ERROR_FAILURE;
nsAutoString scheme;
PRInt32 n = spec.Left(scheme, pos);
NS_ASSERTION(n == pos, "Left failed");
nsAutoString path;
PRInt32 count = spec.Length() - pos - 1;
n = spec.Mid(path, pos + 1, count);
NS_ASSERTION(n == count, "Mid failed");
if (mScheme)
nsCRT::free(mScheme);
mScheme = scheme.ToNewCString();
if (mScheme == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
ToLowerCase(mScheme);
if (mPath)
nsCRT::free(mPath);
mPath = path.ToNewCString();
if (mPath == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
}
NS_IMETHODIMP
nsSimpleURI::GetScheme(char* *result)
{
*result = nsCRT::strdup(mScheme);
return NS_OK;
}
NS_IMETHODIMP
nsSimpleURI::SetScheme(const char* scheme)
{
if (mScheme) nsCRT::free(mScheme);
mScheme = nsCRT::strdup(scheme);
ToLowerCase(mScheme);
return NS_OK;
}
NS_IMETHODIMP
nsSimpleURI::GetPrePath(char* *result)
{
nsCAutoString prePath(mScheme);
prePath += ":";
*result = prePath.ToNewCString();
return *result ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
}
NS_IMETHODIMP
nsSimpleURI::SetPrePath(const char* scheme)
{
NS_NOTREACHED("nsSimpleURI::SetPrePath");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsSimpleURI::GetPreHost(char* *result)
{
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsSimpleURI::SetPreHost(const char* preHost)
{
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsSimpleURI::GetUsername(char* *result)
{
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsSimpleURI::SetUsername(const char* userName)
{
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsSimpleURI::GetPassword(char* *result)
{
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsSimpleURI::SetPassword(const char* password)
{
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsSimpleURI::GetHost(char* *result)
{
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsSimpleURI::SetHost(const char* host)
{
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsSimpleURI::GetPort(PRInt32 *result)
{
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsSimpleURI::SetPort(PRInt32 port)
{
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsSimpleURI::GetPath(char* *result)
{
*result = nsCRT::strdup(mPath);
return NS_OK;
}
NS_IMETHODIMP
nsSimpleURI::SetPath(const char* path)
{
if (mPath) nsCRT::free(mPath);
mPath = nsCRT::strdup(path);
return NS_OK;
}
NS_IMETHODIMP
nsSimpleURI::Equals(nsIURI* other, PRBool *result)
{
PRBool eq = PR_FALSE;
if (other) {
// NS_LOCK_INSTANCE();
nsSimpleURI* otherUrl;
nsresult rv =
other->QueryInterface(kThisSimpleURIImplementationCID,
(void**)&otherUrl);
if (NS_SUCCEEDED(rv)) {
eq = PRBool((0 == PL_strcmp(mScheme, otherUrl->mScheme)) &&
(0 == PL_strcmp(mPath, otherUrl->mPath)));
NS_RELEASE(otherUrl);
}
// NS_UNLOCK_INSTANCE();
}
*result = eq;
return NS_OK;
}
NS_IMETHODIMP
nsSimpleURI::SchemeIs(const char *i_Scheme, PRBool *o_Equals)
{
NS_ENSURE_ARG_POINTER(o_Equals);
if (!i_Scheme) return NS_ERROR_NULL_POINTER;
// mScheme is guaranteed to be lower case.
if (*i_Scheme == *mScheme || *i_Scheme == (*mScheme - ('a' - 'A')) ) {
*o_Equals = PL_strcasecmp(mScheme, i_Scheme) ? PR_FALSE : PR_TRUE;
} else {
*o_Equals = PR_FALSE;
}
return NS_OK;
}
NS_IMETHODIMP
nsSimpleURI::Clone(nsIURI* *result)
{
nsSimpleURI* url = new nsSimpleURI(nsnull); // XXX outer?
if (url == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
url->mScheme = nsCRT::strdup(mScheme);
if (url->mScheme == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
url->mPath = nsCRT::strdup(mPath);
if (url->mPath == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
*result = url;
NS_ADDREF(url);
return NS_OK;
}
NS_IMETHODIMP
nsSimpleURI::Resolve(const char *relativePath, char **result)
{
return DupString(result,(char*)relativePath);
}
////////////////////////////////////////////////////////////////////////////////
NS_METHOD
nsSimpleURI::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{
NS_ENSURE_ARG_POINTER(aResult);
NS_ENSURE_PROPER_AGGREGATION(aOuter, aIID);
nsSimpleURI* url = new nsSimpleURI(aOuter);
if (url == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
nsresult rv = url->AggregatedQueryInterface(aIID, aResult);
if (NS_FAILED(rv))
delete url;
return rv;
}
////////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,56 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsSimpleURI_h__
#define nsSimpleURI_h__
#include "nsIURL.h"
#include "nsAgg.h"
#define NS_THIS_SIMPLEURI_IMPLEMENTATION_CID \
{ /* 22b8f64a-2f7b-11d3-8cd0-0060b0fc14a3 */ \
0x22b8f64a, \
0x2f7b, \
0x11d3, \
{0x8c, 0xd0, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \
}
class nsSimpleURI : public nsIURI
{
public:
NS_DECL_AGGREGATED
NS_DECL_NSIURI
// nsSimpleURI methods:
nsSimpleURI(nsISupports* outer);
virtual ~nsSimpleURI();
static NS_METHOD
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
protected:
char* mScheme;
char* mPath;
};
#endif // nsSimpleURI_h__

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,441 @@
/*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Darin Fisher <darin@netscape.com>
*/
#ifndef nsSocketTransport_h___
#define nsSocketTransport_h___
#include "prclist.h"
#include "prio.h"
#include "prnetdb.h"
#include "prinrval.h"
#include "nsCOMPtr.h"
#include "nsISocketTransport.h"
#include "nsIInputStream.h"
#include "nsIOutputStream.h"
#include "nsIEventQueueService.h"
#include "nsIStreamListener.h"
#include "nsIStreamProvider.h"
#include "nsIDNSListener.h"
#include "nsIDNSService.h"
#include "nsIPipe.h"
#include "nsIProgressEventSink.h"
#include "nsIInterfaceRequestor.h"
#define NS_SOCKET_TRANSPORT_SEGMENT_SIZE (2*1024)
#define NS_SOCKET_TRANSPORT_BUFFER_SIZE (8*1024)
//
// This is the maximum amount of data that will be read into a stream before
// another transport is processed...
//
#define MAX_IO_TRANSFER_SIZE (8*1024)
enum nsSocketState {
eSocketState_Created = 0,
eSocketState_WaitDNS = 1,
eSocketState_Closed = 2,
eSocketState_WaitConnect = 3,
eSocketState_Connected = 4,
eSocketState_WaitReadWrite = 5,
eSocketState_Done = 6,
eSocketState_Timeout = 7,
eSocketState_Error = 8,
eSocketState_Max = 9
};
enum nsSocketOperation {
eSocketOperation_None = 0,
eSocketOperation_Connect = 1,
eSocketOperation_ReadWrite = 2,
eSocketOperation_Max = 3
};
//
// The following emun provides information about the currently
// active read and/or write requests...
//
// +-------------------------------+
// | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
// +-------------------------------+
// <-----flag bits----><-type bits->
//
// Bits:
// 0-3: Type (ie. None, Async, Sync)
// 4: Done flag.
// 5: Wait flag.
// 6-7: Unused flags...
//
//
//
enum nsSocketReadWriteInfo {
eSocketRead_None = 0x0000,
eSocketRead_Async = 0x0001,
eSocketRead_Sync = 0x0002,
eSocketRead_Done = 0x0010,
eSocketRead_Wait = 0x0020,
eSocketRead_Type_Mask = 0x000F,
eSocketRead_Flag_Mask = 0x00F0,
eSocketWrite_None = 0x0000,
eSocketWrite_Async = 0x0100,
eSocketWrite_Sync = 0x0200,
eSocketWrite_Done = 0x1000,
eSocketWrite_Wait = 0x2000,
eSocketWrite_Type_Mask = 0x0F00,
eSocketWrite_Flag_Mask = 0xF000,
eSocketDNS_Wait = 0x2020
};
//
// This is the default timeout value (in milliseconds) for sockets which have
// no activity...
//
#define DEFAULT_SOCKET_CONNECT_TIMEOUT_IN_MS 35*1000
// Forward declarations...
class nsSocketTransportService;
class nsSocketBS; // base class for blocking streams
class nsSocketBIS; // blocking input stream
class nsSocketBOS; // blocking output stream
class nsSocketIS; // input stream
class nsSocketOS; // output stream
class nsSocketRequest;
class nsSocketReadRequest;
class nsSocketWriteRequest;
class nsSocketTransport : public nsISocketTransport,
public nsIDNSListener
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSITRANSPORT
NS_DECL_NSISOCKETTRANSPORT
NS_DECL_NSIDNSLISTENER
// nsSocketTransport methods:
nsSocketTransport();
virtual ~nsSocketTransport();
nsresult Init(nsSocketTransportService* aService,
const char* aHost,
PRInt32 aPort,
PRUint32 aSocketTypeCount,
const char* *aSocketTypes,
const char* aProxyHost,
PRInt32 aProxyPort,
PRUint32 bufferSegmentSize,
PRUint32 bufferMaxSize);
nsresult Process(PRInt16 aSelectFlags);
nsresult Cancel(nsresult status);
nsresult CheckForTimeout (PRIntervalTime aCurrentTime);
// Close this socket either right away or once done with the transaction.
nsresult CloseConnection(PRBool bNow=PR_TRUE);
// Access methods used by the socket transport service...
PRFileDesc* GetSocket(void) { return mSocketFD; }
PRInt16 GetSelectFlags(void) { return mSelectFlags; }
PRCList* GetListNode(void) { return &mListLink; }
static nsSocketTransport* GetInstance(PRCList* qp) { return (nsSocketTransport*)((char*)qp - offsetof(nsSocketTransport, mListLink)); }
PRBool CanBeReused(void) { return
(mCurrentState != eSocketState_Error) && !mCloseConnectionOnceDone;}
//
// request helpers
//
nsresult GetName(PRUnichar **);
nsresult Dispatch(nsSocketRequest *);
nsresult OnProgress(nsSocketRequest *, nsISupports *ctxt, PRUint32 offset);
nsresult OnStatus(nsSocketRequest *, nsISupports *ctxt, nsresult message);
protected:
nsresult doConnection(PRInt16 aSelectFlags);
nsresult doBlockingConnection();
nsresult doReadWrite(PRInt16 aSelectFlags);
nsresult doResolveHost();
nsresult OnStatus(nsresult message); // with either request
void CompleteAsyncRead();
void CompleteAsyncWrite();
PRIntervalTime mSocketTimeout;
PRIntervalTime mSocketConnectTimeout;
// Access methods for manipulating the ReadWriteInfo...
inline void SetReadType(nsSocketReadWriteInfo aType) {
mReadWriteState = (mReadWriteState & ~eSocketRead_Type_Mask) | aType;
}
inline PRUint32 GetReadType(void) {
return mReadWriteState & eSocketRead_Type_Mask;
}
inline void SetWriteType(nsSocketReadWriteInfo aType) {
mReadWriteState = (mReadWriteState & ~eSocketWrite_Type_Mask) | aType;
}
inline PRUint32 GetWriteType(void) {
return mReadWriteState & eSocketWrite_Type_Mask;
}
inline void SetFlag(nsSocketReadWriteInfo aFlag) {
mReadWriteState |= aFlag;
}
inline PRUint32 GetFlag(nsSocketReadWriteInfo aFlag) {
return mReadWriteState & aFlag;
}
inline void ClearFlag(nsSocketReadWriteInfo aFlag) {
mReadWriteState &= ~aFlag;
}
protected:
nsSocketState mCurrentState;
nsCOMPtr<nsIRequest> mDNSRequest;
nsCOMPtr<nsIProgressEventSink> mEventSink;
nsCOMPtr<nsIInterfaceRequestor> mNotificationCallbacks;
char* mHostName;
PRInt32 mPort;
PRIntervalTime mLastActiveTime;
PRCList mListLink;
PRMonitor* mMonitor;
PRNetAddr mNetAddress;
nsSocketOperation mOperation;
nsCOMPtr<nsISupports> mSecurityInfo;
PRInt32 mProxyPort;
char* mProxyHost;
PRPackedBool mProxyTransparent;
PRPackedBool mSSLProxy;
/* put all the packed bools together so we save space */
PRPackedBool mCloseConnectionOnceDone;
PRPackedBool mWasConnected;
nsSocketTransportService* mService;
PRUint32 mReadWriteState;
PRInt16 mSelectFlags;
nsresult mStatus;
PRFileDesc* mSocketFD;
PRUint32 mSocketTypeCount;
char* *mSocketTypes;
PRInt32 mBytesExpected;
PRUint32 mReuseCount;
PRUint32 mLastReuseCount;
PRUint32 mBufferSegmentSize;
PRUint32 mBufferMaxSize;
PRUint32 mIdleTimeoutInSeconds;
nsSocketBIS *mBIS;
nsSocketBOS *mBOS;
nsSocketReadRequest *mReadRequest;
nsSocketWriteRequest *mWriteRequest;
};
/**
* base blocking stream ...
*/
class nsSocketBS
{
public:
nsSocketBS();
virtual ~nsSocketBS();
void SetTransport(nsSocketTransport *);
void SetSocket(PRFileDesc *aSock) { mSock = aSock; }
nsresult Poll(PRInt16 event);
protected:
nsSocketTransport *mTransport;
PRFileDesc *mSock;
};
/**
* blocking input stream, returned by nsITransport::OpenInputStream()
*/
class nsSocketBIS : public nsSocketBS
, public nsIInputStream
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIINPUTSTREAM
nsSocketBIS();
virtual ~nsSocketBIS();
};
/**
* blocking output stream, returned by nsITransport::OpenOutputStream()
*/
class nsSocketBOS : public nsSocketBS
, public nsIOutputStream
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIOUTPUTSTREAM
nsSocketBOS();
virtual ~nsSocketBOS();
};
/**
* input stream, passed to nsIStreamListener::OnDataAvailable()
*/
class nsSocketIS : public nsIInputStream
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIINPUTSTREAM
nsSocketIS();
virtual ~nsSocketIS() { }
void SetSocket(PRFileDesc *aSock) { mSock = aSock; }
PRUint32 GetOffset() { return mOffset; }
void SetOffset(PRUint32 o) { mOffset = o; }
PRBool GotWouldBlock() { return mError == PR_WOULD_BLOCK_ERROR; }
PRBool GotError() { return mError != 0; }
PRErrorCode GetError() { return mError; }
private:
PRUint32 mOffset;
PRFileDesc *mSock;
PRErrorCode mError;
};
/**
* output stream, passed to nsIStreamProvider::OnDataWritable()
*/
class nsSocketOS : public nsIOutputStream
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIOUTPUTSTREAM
nsSocketOS();
virtual ~nsSocketOS() { }
void SetSocket(PRFileDesc *aSock) { mSock = aSock; }
PRUint32 GetOffset() { return mOffset; }
void SetOffset(PRUint32 o) { mOffset = o; }
PRBool GotWouldBlock() { return mError == PR_WOULD_BLOCK_ERROR; }
PRBool GotError() { return mError != 0; }
PRErrorCode GetError() { return mError; }
private:
static NS_METHOD WriteFromSegments(nsIInputStream *, void *, const char *,
PRUint32, PRUint32, PRUint32 *);
PRUint32 mOffset;
PRFileDesc *mSock;
PRErrorCode mError;
};
/**
* base request
*/
class nsSocketRequest : public nsITransportRequest
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIREQUEST
NS_DECL_NSITRANSPORTREQUEST
nsSocketRequest();
virtual ~nsSocketRequest();
PRBool IsInitialized() { return mStartFired; }
PRBool IsSuspended() { return mSuspendCount > 0; }
PRBool IsCanceled() { return mCanceled; }
void SetTransport(nsSocketTransport *);
void SetObserver(nsIStreamObserver *obs) { mObserver = obs; }
void SetContext(nsISupports *ctx) { mContext = ctx; }
void SetStatus(nsresult status) { mStatus = status; }
nsISupports *Context() { return mContext; }
virtual nsresult OnStart();
virtual nsresult OnStop();
protected:
nsSocketTransport *mTransport;
nsCOMPtr<nsIStreamObserver> mObserver;
nsCOMPtr<nsISupports> mContext;
nsresult mStatus;
PRIntn mSuspendCount;
PRPackedBool mCanceled;
PRPackedBool mStartFired;
};
/**
* read request, returned by nsITransport::AsyncRead()
*/
class nsSocketReadRequest : public nsSocketRequest
{
public:
nsSocketReadRequest();
virtual ~nsSocketReadRequest();
void SetSocket(PRFileDesc *);
void SetListener(nsIStreamListener *l) { mListener = l; }
nsresult OnStop();
nsresult OnRead();
private:
nsSocketIS *mInputStream;
nsCOMPtr<nsIStreamListener> mListener;
};
/**
* write request, returned by nsITransport::AsyncWrite()
*/
class nsSocketWriteRequest : public nsSocketRequest
{
public:
nsSocketWriteRequest();
virtual ~nsSocketWriteRequest();
void SetSocket(PRFileDesc *);
void SetProvider(nsIStreamProvider *p) { mProvider = p; }
nsresult OnStop();
nsresult OnWrite();
private:
nsSocketOS *mOutputStream;
nsCOMPtr<nsIStreamProvider> mProvider;
};
#endif /* nsSocketTransport_h___ */

View File

@@ -0,0 +1,729 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsILoadGroup.h"
#include "netCore.h"
#include "nsSocketTransportService.h"
#include "nsSocketTransport.h"
#include "nsAutoLock.h"
#include "nsIIOService.h"
#include "nsIServiceManager.h"
#include "nsProxiedService.h"
#include "nsString.h"
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
static NS_DEFINE_CID(kStringBundleServiceCID, NS_STRINGBUNDLESERVICE_CID);
nsSocketTransportService::nsSocketTransportService () :
mConnectedTransports (0),
mTotalTransports (0)
{
NS_INIT_REFCNT();
PR_INIT_CLIST(&mWorkQ);
mThread = nsnull;
mThreadEvent = nsnull;
mThreadLock = nsnull;
mSelectFDSet = nsnull;
mSelectFDSetCount = 0;
mActiveTransportList = nsnull;
mThreadRunning = PR_FALSE;
}
nsSocketTransportService::~nsSocketTransportService()
{
//
// It is impossible for the nsSocketTransportService to be deleted while
// the transport thread is running because it holds a reference to the
// nsIRunnable (ie. the nsSocketTransportService instance)...
//
NS_ASSERTION(!mThread && !mThreadRunning,
"The socket transport thread is still running...");
if (mSelectFDSet) {
PR_Free(mSelectFDSet);
mSelectFDSet = nsnull;
}
if (mActiveTransportList) {
PR_Free(mActiveTransportList);
mActiveTransportList = nsnull;
}
if (mThreadEvent)
{
PR_DestroyPollableEvent(mThreadEvent);
mThreadEvent = nsnull;
}
if (mThreadLock) {
PR_DestroyLock(mThreadLock);
mThreadLock = nsnull;
}
}
NS_METHOD
nsSocketTransportService::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{
nsresult rv;
if (aOuter)
return NS_ERROR_NO_AGGREGATION;
nsSocketTransportService* trans = new nsSocketTransportService();
if (trans == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(trans);
rv = trans->Init();
if (NS_SUCCEEDED(rv)) {
rv = trans->QueryInterface(aIID, aResult);
}
NS_RELEASE(trans);
return rv;
}
NS_IMETHODIMP
nsSocketTransportService::Init(void)
{
nsresult rv = NS_OK;
NS_ASSERTION(!mThread, "Socket transport thread has already been created!.");
//
// Create FDSET list used by PR_Poll(...)
//
if (!mSelectFDSet) {
mSelectFDSet = (PRPollDesc*)PR_Malloc(sizeof(PRPollDesc)*MAX_OPEN_CONNECTIONS);
if (mSelectFDSet) {
memset(mSelectFDSet, 0, sizeof(PRPollDesc)*MAX_OPEN_CONNECTIONS);
} else {
rv = NS_ERROR_OUT_OF_MEMORY;
}
}
//
// Create the list of Active transport objects... This list contains the
// nsSocketTransport corresponding to each PRFileDesc* in the mSelectFDSet
//
if (NS_SUCCEEDED(rv) && !mActiveTransportList) {
mActiveTransportList = (nsSocketTransport**)PR_Malloc(sizeof(nsSocketTransport*)*MAX_OPEN_CONNECTIONS);
if (mActiveTransportList) {
memset(mActiveTransportList, 0, sizeof(nsSocketTransport*)*MAX_OPEN_CONNECTIONS);
} else {
rv = NS_ERROR_OUT_OF_MEMORY;
}
}
//
// Create the pollable event used to immediately wake up the transport
// thread when it is blocked in PR_Poll(...)
//
#ifdef USE_POLLABLE_EVENT
if (NS_SUCCEEDED(rv) && !mThreadEvent)
mThreadEvent = PR_NewPollableEvent();
#endif
//
// Create the synchronization lock for the transport thread...
//
if (NS_SUCCEEDED(rv) && !mThreadLock) {
mThreadLock = PR_NewLock();
if (!mThreadLock) {
rv = NS_ERROR_OUT_OF_MEMORY;
}
}
//
// Create the transport thread...
//
if (NS_SUCCEEDED(rv) && !mThread) {
mThreadRunning = PR_TRUE;
rv = NS_NewThread(&mThread, this, 0, PR_JOINABLE_THREAD);
}
return rv;
}
nsresult nsSocketTransportService::AddToWorkQ(nsSocketTransport* aTransport)
{
PRStatus status = PR_SUCCESS;
PRBool bFireEvent = PR_FALSE;
nsresult rv = NS_OK;
PRCList* qp;
{
nsAutoLock lock(mThreadLock);
//
// Only add the transport if it is *not* already on the list...
//
qp = aTransport->GetListNode();
if (PR_CLIST_IS_EMPTY(qp)) {
NS_ADDREF(aTransport);
bFireEvent = PR_CLIST_IS_EMPTY(&mWorkQ);
PR_APPEND_LINK(qp, &mWorkQ);
}
}
//
// Only fire an event if this is the first entry in the workQ. Otherwise,
// the event has already been fired and the transport thread will process
// all of the entries at once...
//
if (bFireEvent) {
if (mThreadEvent)
status = PR_SetPollableEvent(mThreadEvent);
if (PR_FAILURE == status) {
rv = NS_ERROR_FAILURE;
}
}
return rv;
}
nsresult nsSocketTransportService::ProcessWorkQ(void)
{
nsresult rv = NS_OK;
PRCList* qp;
//
// Only process pending operations while there is space available in the
// select list...
//
// XXX: Need a way to restart the ProcessWorkQ(...) when space becomes
// available in the select set...
//
PR_Lock(mThreadLock);
NS_ASSERTION(MAX_OPEN_CONNECTIONS > mSelectFDSetCount, "reached max open connections");
while (!PR_CLIST_IS_EMPTY(&mWorkQ) &&
(MAX_OPEN_CONNECTIONS > mSelectFDSetCount)) {
nsSocketTransport* transport;
// Get the next item off of the workQ...
qp = PR_LIST_HEAD(&mWorkQ);
transport = nsSocketTransport::GetInstance(qp);
PR_REMOVE_AND_INIT_LINK(qp);
//
// Make sure that the transport is not already on the select list.
// It will be added (if necessary) after Process() is called...
//
RemoveFromSelectList(transport);
// Try to perform the operation...
//
// Do not process the transport while holding the transport service
// lock... A deadlock could occur if another thread is holding the
// transport lock and tries to add the transport to the service's WorkQ...
//
// Do not pass any select flags...
PR_Unlock(mThreadLock);
rv = transport->Process(0);
PR_Lock(mThreadLock);
//
// If the operation would block, then add it to the select list for
// later processing when the data arrives...
//
if (NS_BASE_STREAM_WOULD_BLOCK == rv) {
rv = AddToSelectList(transport);
}
// Release the transport object (since it is no longer on the WorkQ).
NS_RELEASE(transport);
}
PR_Unlock(mThreadLock);
return rv;
}
nsresult nsSocketTransportService::AddToSelectList(nsSocketTransport* aTransport)
{
nsresult rv = NS_OK;
NS_ASSERTION(MAX_OPEN_CONNECTIONS > mSelectFDSetCount, "reached max open connections");
if (aTransport && (MAX_OPEN_CONNECTIONS > mSelectFDSetCount) ) {
PRPollDesc* pfd;
int i;
//
// Check to see if the transport is already in the list...
//
// If the first FD is the Pollable Event, it will be ignored since
// its corresponding entry in the ActiveTransportList is nsnull.
//
for (i=0; i<mSelectFDSetCount; i++) {
if (mActiveTransportList[i] == aTransport) {
break;
}
}
// Initialize/update the info in the entry...
pfd = &mSelectFDSet[i];
pfd->fd = aTransport->GetSocket();
pfd->in_flags = aTransport->GetSelectFlags();
pfd->out_flags = 0;
// Add the FileDesc to the PRPollDesc list...
if (i == mSelectFDSetCount) {
// Add the transport instance to the corresponding active transport list...
NS_ADDREF(aTransport);
mActiveTransportList[mSelectFDSetCount] = aTransport;
mSelectFDSetCount += 1;
}
}
return rv;
}
nsresult nsSocketTransportService::RemoveFromSelectList(nsSocketTransport* aTransport)
{
int i;
nsresult rv = NS_ERROR_FAILURE;
if (!aTransport) return rv;
//
// Remove the transport from SelectFDSet and ActiveTransportList...
//
// If the first FD is the Pollable Event, it will be ignored since
// its corresponding entry in the ActiveTransportList is nsnull.
//
for (i=0; i<mSelectFDSetCount; i++) {
if (mActiveTransportList[i] == aTransport) {
int last = mSelectFDSetCount-1;
NS_RELEASE(mActiveTransportList[i]);
// Move the last element in the array into the new empty slot...
if (i != last) {
memcpy(&mSelectFDSet[i], &mSelectFDSet[last], sizeof(mSelectFDSet[0]));
mSelectFDSet[last].fd = nsnull;
mActiveTransportList[i] = mActiveTransportList[last];
mActiveTransportList[last] = nsnull;
} else {
mSelectFDSet[i].fd = nsnull;
mActiveTransportList[i] = nsnull;
}
mSelectFDSetCount -= 1;
rv = NS_OK;
break;
}
}
return rv;
}
//
// --------------------------------------------------------------------------
// nsISupports implementation...
// --------------------------------------------------------------------------
//
NS_IMPL_THREADSAFE_ISUPPORTS2(nsSocketTransportService,
nsISocketTransportService,
nsIRunnable)
//
// --------------------------------------------------------------------------
// nsIRunnable implementation...
// --------------------------------------------------------------------------
//
NS_IMETHODIMP
nsSocketTransportService::Run(void)
{
PRIntervalTime pollTimeout;
if (mThreadEvent)
{
//
// Initialize the FDSET used by PR_Poll(...). The first item in the FDSet
// is *always* the pollable event (ie. mThreadEvent).
//
mSelectFDSet[0].fd = mThreadEvent;
mSelectFDSet[0].in_flags = PR_POLL_READ;
mSelectFDSetCount = 1;
pollTimeout = PR_MillisecondsToInterval (DEFAULT_POLL_TIMEOUT_IN_MS);
}
else
{
//
// For now, rather than breaking out of the call to PR_Poll(...) just set
// the time out small enough...
//
// This means that new transports will only be processed once a timeout
// occurs...
//
mSelectFDSetCount = 0;
pollTimeout = PR_MillisecondsToInterval(5);
}
while (mThreadRunning) {
nsresult rv;
PRInt32 count;
PRIntervalTime intervalNow;
nsSocketTransport* transport;
int i;
count = PR_Poll(mSelectFDSet, mSelectFDSetCount, pollTimeout);
if (-1 == count) {
// XXX: PR_Poll failed... What should happen?
}
intervalNow = PR_IntervalNow();
//
// See if any sockets have data...
//
// Walk the list of active transports backwards to avoid missing
// elements when a transport is removed...
//
for (i=mSelectFDSetCount-1; i>=0; i--) {
PRPollDesc* pfd;
PRInt16 out_flags;
transport = mActiveTransportList[i];
pfd = &mSelectFDSet[i];
/* Process any sockets with data first... */
//
// XXX: PR_Poll(...) has the unpleasent behavior of ONLY setting the
// out_flags if one or more FDs are ready. So, DO NOT look at
// the out_flags unless count > 0.
//
if ((count > 0) && pfd->out_flags) {
// Clear the out_flags for next time...
out_flags = pfd->out_flags;
pfd->out_flags = 0;
if (transport) {
rv = transport->Process(out_flags);
if (NS_BASE_STREAM_WOULD_BLOCK == rv) {
// Update the select flags...
pfd->in_flags = transport->GetSelectFlags();
}
//
// If the operation completed, then remove the entry from the
// select list...
//
else {
rv = RemoveFromSelectList(transport);
}
}
else {
if (mThreadEvent)
{
/* Process any pending operations on the mWorkQ... */
NS_ASSERTION(0 == i, "Null transport in active list...");
if (0 == i) {
//
// Clear the pollable event... This call should *never* block since
// PR_Poll(...) said that it had been fired...
//
NS_ASSERTION(!(mSelectFDSet[0].out_flags & PR_POLL_EXCEPT),
"Exception on Pollable event.");
PR_WaitForPollableEvent(mThreadEvent);
rv = ProcessWorkQ();
}
}
else
{
//
// The pollable event should be the *only* null transport
// in the active transport list.
//
NS_ASSERTION(transport, "Null transport in active list...");
}
}
//
// Check to see if the transport has timed out...
//
} else {
if (transport) {
rv = transport->CheckForTimeout(intervalNow);
if (NS_ERROR_NET_TIMEOUT == rv) {
// Process the timeout...
rv = transport->Process(0);
//
// The operation has completed. Remove the entry from the
// select list///
//
rv = RemoveFromSelectList(transport);
}
}
}
} // end-for
if (!mThreadEvent)
/* Process any pending operations on the mWorkQ... */
rv = ProcessWorkQ();
}
return NS_OK;
}
//
// --------------------------------------------------------------------------
// nsISocketTransportService implementation...
// --------------------------------------------------------------------------
//
NS_IMETHODIMP
nsSocketTransportService::CreateTransport(const char* aHost,
PRInt32 aPort,
const char* proxyHost,
PRInt32 proxyPort,
PRUint32 bufferSegmentSize,
PRUint32 bufferMaxSize,
nsITransport** aResult)
{
return CreateTransportOfTypes(0, nsnull, aHost, aPort, proxyHost, proxyPort,
bufferSegmentSize, bufferMaxSize, aResult);
}
NS_IMETHODIMP
nsSocketTransportService::CreateTransportOfType(const char* aSocketType,
const char* aHost,
PRInt32 aPort,
const char* proxyHost,
PRInt32 proxyPort,
PRUint32 bufferSegmentSize,
PRUint32 bufferMaxSize,
nsITransport** aResult)
{
const char * types[] = { aSocketType };
return CreateTransportOfTypes(1, types, aHost, aPort, proxyHost, proxyPort,
bufferSegmentSize, bufferMaxSize, aResult);
}
NS_IMETHODIMP
nsSocketTransportService::CreateTransportOfTypes(PRUint32 socketTypeCount,
const char* *aSocketTypes,
const char* aHost,
PRInt32 aPort,
const char* proxyHost,
PRInt32 proxyPort,
PRUint32 bufferSegmentSize,
PRUint32 bufferMaxSize,
nsITransport** aResult)
{
nsresult rv = NS_OK;
NS_WITH_SERVICE(nsIIOService, ios, kIOServiceCID, &rv);
if (NS_FAILED(rv)) return rv;
PRBool offline;
rv = ios->GetOffline(&offline);
if (NS_FAILED(rv)) return rv;
if (offline) return NS_ERROR_OFFLINE;
nsSocketTransport* transport = nsnull;
// Parameter validation...
NS_ASSERTION(aResult, "aResult == nsnull.");
if (!aResult) {
return NS_ERROR_NULL_POINTER;
}
// Create and initialize a new connection object...
NS_NEWXPCOM(transport, nsSocketTransport);
if (transport) {
rv = transport->Init(this, aHost, aPort, socketTypeCount, aSocketTypes,
proxyHost, proxyPort, bufferSegmentSize, bufferMaxSize);
if (NS_FAILED(rv)) {
delete transport;
transport = nsnull;
}
}
else {
rv = NS_ERROR_OUT_OF_MEMORY;
}
// Set the reference count to one...
if (NS_SUCCEEDED(rv)) {
NS_ADDREF(transport);
}
*aResult = transport;
return rv;
}
NS_IMETHODIMP
nsSocketTransportService::ReuseTransport(nsITransport* i_Transport,
PRBool * o_Reuse)
{
nsresult rv = NS_ERROR_FAILURE;
if (!i_Transport)
return NS_ERROR_NULL_POINTER;
nsSocketTransport* trans = NS_STATIC_CAST(nsSocketTransport*,
i_Transport);
if (!trans) return rv;
*o_Reuse = trans->CanBeReused();
return NS_OK;
}
/**
* wakeup the transport from PR_Poll ()
*/
NS_IMETHODIMP
nsSocketTransportService::Wakeup (nsITransport* i_Transport)
{
nsSocketTransport *transport = NS_STATIC_CAST (nsSocketTransport *, i_Transport);
if (transport == NULL)
return NS_ERROR_NULL_POINTER;
AddToWorkQ (transport);
if (mThreadEvent)
PR_SetPollableEvent (mThreadEvent);
// else
// XXX/ruslan: normally we would call PR_Interrupt (), but since it did work
// wait till NSPR fixes it one day
return NS_OK;
}
NS_IMETHODIMP
nsSocketTransportService::Shutdown(void)
{
PRStatus status;
nsresult rv = NS_OK;
int i;
if (mThread) {
// Cancel all remaining transports.
for (i=0; i<mSelectFDSetCount; i++) {
if (mActiveTransportList[i])
mActiveTransportList[i]->Cancel(NS_BINDING_ABORTED);
}
//
// Clear the running flag and wake up the transport thread...
//
mThreadRunning = PR_FALSE;
if (mThreadEvent)
{
status = PR_SetPollableEvent(mThreadEvent);
// XXX: what should happen if this fails?
NS_ASSERTION(PR_SUCCESS == status, "Unable to wake up the transport thread.");
}
else
status = PR_SUCCESS;
// Wait for the transport thread to exit nsIRunnable::Run()
if (PR_SUCCESS == status) {
mThread->Join();
}
NS_RELEASE(mThread);
for (i=0; i<mSelectFDSetCount; i++)
NS_IF_RELEASE(mActiveTransportList[i]);
} else {
rv = NS_ERROR_FAILURE;
}
return rv;
}
NS_IMETHODIMP
nsSocketTransportService::GetTotalTransportCount (PRUint32 * o_TransCount)
{
if (!o_TransCount)
return NS_ERROR_NULL_POINTER;
*o_TransCount = (PRUint32) mTotalTransports;
return NS_OK;
}
NS_IMETHODIMP
nsSocketTransportService::GetConnectedTransportCount (PRUint32 * o_TransCount)
{
if (!o_TransCount)
return NS_ERROR_NULL_POINTER;
*o_TransCount = (PRUint32) mConnectedTransports;
return NS_OK;
}
NS_IMETHODIMP
nsSocketTransportService::GetInUseTransportCount (PRUint32 * o_TransCount)
{
if (!o_TransCount)
return NS_ERROR_NULL_POINTER;
PRUint32 inUseTransports = (PRUint32)mSelectFDSetCount;
// The first item in the FDSet is *always* the pollable event, if we are using them
if (mThreadEvent && inUseTransports > 0)
--inUseTransports;
*o_TransCount = inUseTransports;
return NS_OK;
}
nsresult
nsSocketTransportService::GetNeckoStringByName (const char *aName, PRUnichar **aString)
{
nsresult res;
nsAutoString resultString; resultString.AssignWithConversion(aName);
if (!m_stringBundle) {
char* propertyURL = NECKO_MSGS_URL;
// make sure that we get this service on the UI thread.
NS_WITH_PROXIED_SERVICE(nsIStringBundleService, sBundleService, kStringBundleServiceCID,
NS_UI_THREAD_EVENTQ, &res);
if (NS_SUCCEEDED (res) && (nsnull != sBundleService)) {
nsILocale *locale = nsnull;
res = sBundleService->CreateBundle(propertyURL, locale, getter_AddRefs(m_stringBundle));
}
}
if (m_stringBundle)
{
nsAutoString unicodeName; unicodeName.AssignWithConversion(aName);
PRUnichar *ptrv = nsnull;
res = m_stringBundle->GetStringFromName(unicodeName.GetUnicode(), &ptrv);
if (NS_FAILED(res))
{
resultString.AssignWithConversion("[StringName");
resultString.AppendWithConversion(aName);
resultString.AppendWithConversion("?]");
*aString = resultString.ToNewUnicode();
}
else
{
*aString = ptrv;
}
}
else
{
res = NS_OK;
*aString = resultString.ToNewUnicode();
}
return res;
}

View File

@@ -0,0 +1,102 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsSocketTransportService_h___
#define nsSocketTransportService_h___
#include "nspr.h"
#include "nsIRunnable.h"
#include "nsIThread.h"
#include "nsISocketTransportService.h"
#include "nsIInputStream.h"
#include "nsCOMPtr.h"
#include "nsIStringBundle.h"
#if defined(XP_PC) || defined(XP_UNIX) || defined(XP_BEOS) || defined(XP_MAC)
//
// Both Windows and Unix support PR_PollableEvents which are used to break
// the socket transport thread out of calls to PR_Poll(...) when new
// file descriptors must be added to the poll list...
//
#define USE_POLLABLE_EVENT
#endif
//
// This is the Maximum number of Socket Transport instances that can be active
// at once...
//
#define MAX_OPEN_CONNECTIONS 50
#define DEFAULT_POLL_TIMEOUT_IN_MS 35*1000
// Forward declarations...
class nsSocketTransport;
class nsSocketTransportService : public nsISocketTransportService,
public nsIRunnable
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSISOCKETTRANSPORTSERVICE
NS_DECL_NSIRUNNABLE
// nsSocketTransportService methods:
nsSocketTransportService();
virtual ~nsSocketTransportService();
static NS_METHOD
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
nsresult AddToWorkQ(nsSocketTransport* aTransport);
// XXX: Should these use intervals or Milliseconds?
nsresult GetSocketTimeoutInterval(PRIntervalTime* aResult);
nsresult SetSocketTimeoutInterval(PRIntervalTime aTime);
// The following methods are called by the transport thread...
nsresult ProcessWorkQ(void);
nsresult AddToSelectList(nsSocketTransport* aTransport);
nsresult RemoveFromSelectList(nsSocketTransport* aTransport);
PRInt32 mConnectedTransports;
PRInt32 mTotalTransports;
nsresult GetNeckoStringByName (const char *aName, PRUnichar **aString);
protected:
nsIThread* mThread;
PRFileDesc* mThreadEvent;
PRLock* mThreadLock;
PRBool mThreadRunning;
PRCList mWorkQ;
PRInt32 mSelectFDSetCount;
PRPollDesc* mSelectFDSet;
nsSocketTransport** mActiveTransportList;
nsCOMPtr<nsIStringBundle> m_stringBundle;
};
#endif /* nsSocketTransportService_h___ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,241 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsStdURL_h__
#define nsStdURL_h__
#include "nsIURL.h"
#include "nsIURLParser.h"
#include "nsURLHelper.h"
#include "nsAgg.h"
#include "nsCRT.h"
#include "nsString.h" // REMOVE Later!!
#include "nsCOMPtr.h"
#include "nsIFile.h"
#include "nsIFileChannel.h"
#include "nsIFileChannel.h"
#define NS_THIS_STANDARDURL_IMPLEMENTATION_CID \
{ /* e3939dc8-29ab-11d3-8cce-0060b0fc14a3 */ \
0xe3939dc8, \
0x29ab, \
0x11d3, \
{0x8c, 0xce, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \
}
class nsStdURL : public nsIFileURL, nsIStandardURL
{
public:
///////////////////////////////////////////////////////////////////////////
// nsStdURL methods:
nsStdURL(nsISupports* outer = nsnull);
nsStdURL(const nsStdURL& i_URL);
virtual ~nsStdURL();
nsStdURL& operator =(const nsStdURL& otherURL);
PRBool operator ==(const nsStdURL& otherURL) const;
static NS_METHOD
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
// Global objects management.
static NS_METHOD InitGlobalObjects();
static NS_METHOD ShutdownGlobalObjects();
NS_DECL_AGGREGATED
NS_DECL_NSIURI
NS_DECL_NSIURL
NS_DECL_NSIFILEURL
NS_DECL_NSISTANDARDURL
protected:
enum Format { ESCAPED, // Normal URL escaping
UNESCAPED, // No escaping
HOSTESCAPED }; // Host name escaping
nsresult Parse(const char* i_Spec);
nsresult AppendString(nsCString& buffer, char* fromUnescapedStr,
Format toFormat, PRInt16 mask);
nsresult GetString(char** result, char* fromEscapedStr,
Format toFormat);
nsresult AppendPreHost(nsCString& buffer, char* i_Username,
char* i_Password, Format toFormat);
nsresult AppendFileName(nsCString& buffer, char* i_FileBaseName,
char* i_FileExtension, Format toFormat);
protected:
char* mScheme;
char* mUsername;
char* mPassword;
char* mHost;
PRInt32 mPort;
char* mDirectory;
char* mFileBaseName;
char* mFileExtension;
char* mParam;
char* mQuery;
char* mRef;
nsCOMPtr<nsIURLParser> mURLParser;
PRInt32 mDefaultPort; // port for protocol (used for canonicalizing,
// and printing)
// Global objects. Dont use comptr as its destructor will cause
// a coredump if we leak it.
static nsIURLParser *gStdURLParser;
static nsIURLParser *gAuthURLParser;
static nsIURLParser *gNoAuthURLParser;
// If a file was given to SetFile, then this instance variable holds it.
// If GetFile is called, we synthesize one and cache it here.
nsCOMPtr<nsIFile> mFile;
};
inline NS_METHOD
nsStdURL::GetScheme(char* *o_Scheme)
{
return GetString(o_Scheme, mScheme, UNESCAPED);
}
inline NS_METHOD
nsStdURL::GetUsername(char* *o_Username)
{
return GetString(o_Username, mUsername, UNESCAPED);
}
inline NS_METHOD
nsStdURL::GetPassword(char* *o_Password)
{
return GetString(o_Password, mPassword, UNESCAPED);
}
inline NS_METHOD
nsStdURL::GetHost(char* *o_Host)
{
return GetString(o_Host, mHost, UNESCAPED);
}
inline NS_METHOD
nsStdURL::GetPort(PRInt32 *aPort)
{
if (aPort)
{
*aPort = mPort;
return NS_OK;
}
return NS_ERROR_NULL_POINTER;
}
inline NS_METHOD
nsStdURL::GetFileBaseName(char* *o_FileBaseName)
{
return GetString(o_FileBaseName, mFileBaseName, UNESCAPED);
}
inline NS_METHOD
nsStdURL::GetFileExtension(char* *o_FileExtension)
{
return GetString(o_FileExtension, mFileExtension, UNESCAPED);
}
inline NS_METHOD
nsStdURL::GetParam(char **o_Param)
{
return GetString(o_Param, mParam, UNESCAPED);
}
inline NS_METHOD
nsStdURL::GetQuery(char* *o_Query)
{
return GetString(o_Query, mQuery, UNESCAPED);
}
inline NS_METHOD
nsStdURL::GetEscapedQuery(char* *o_Query)
{
return GetString(o_Query, mQuery, ESCAPED);
}
inline NS_METHOD
nsStdURL::GetRef(char* *o_Ref)
{
return GetString(o_Ref, mRef, UNESCAPED);
}
inline NS_METHOD
nsStdURL::SetScheme(const char* i_Scheme)
{
CRTFREEIF(mScheme);
nsresult rv = DupString(&mScheme, i_Scheme);
ToLowerCase(mScheme);
return rv;
}
inline NS_METHOD
nsStdURL::SetUsername(const char* i_Username)
{
CRTFREEIF(mUsername);
return DupString(&mUsername, i_Username);
}
inline NS_METHOD
nsStdURL::SetPassword(const char* i_Password)
{
CRTFREEIF(mPassword);
return DupString(&mPassword, i_Password);
}
inline NS_METHOD
nsStdURL::SetHost(const char* i_Host)
{
CRTFREEIF(mHost);
nsresult rv = DupString(&mHost, i_Host);
ToLowerCase(mHost);
return rv;
}
inline NS_METHOD
nsStdURL::SetPort(PRInt32 aPort)
{
mPort = aPort;
return NS_OK;
}
inline NS_METHOD
nsStdURL::SetFileBaseName(const char* i_FileBaseName)
{
CRTFREEIF(mFileBaseName);
return DupString(&mFileBaseName, i_FileBaseName);
}
inline NS_METHOD
nsStdURL::SetFileExtension(const char* i_FileExtension)
{
CRTFREEIF(mFileExtension);
return DupString(&mFileExtension, i_FileExtension);
}
#endif // nsStdURL_h__

View File

@@ -0,0 +1,595 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Andreas Otte.
*
* Contributor(s):
*/
#include "nsStdURLParser.h"
#include "nsURLHelper.h"
#include "nsCRT.h"
#include "nsString.h"
#include "prprf.h"
#include "prnetdb.h"
NS_IMPL_THREADSAFE_ISUPPORTS1(nsStdURLParser, nsIURLParser)
nsStdURLParser::~nsStdURLParser()
{
}
NS_METHOD
nsStdURLParser::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{
if (aOuter)
return NS_ERROR_NO_AGGREGATION;
nsStdURLParser* p = new nsStdURLParser();
if (p == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(p);
nsresult rv = p->QueryInterface(aIID, aResult);
NS_RELEASE(p);
return rv;
}
nsresult
nsStdURLParser::ParseAtScheme(const char* i_Spec, char* *o_Scheme,
char* *o_Username,
char* *o_Password,
char* *o_Host, PRInt32 *o_Port, char* *o_Path)
{
nsresult rv = NS_OK;
NS_PRECONDITION( (nsnull != i_Spec), "Parse called on empty url!");
if (!i_Spec)
return NS_ERROR_MALFORMED_URI;
int len = PL_strlen(i_Spec);
if (len >= 2 && *i_Spec == '/' && *(i_Spec+1) == '/') // No Scheme
{
rv = ParseAtPreHost(i_Spec, o_Username, o_Password, o_Host, o_Port,
o_Path);
return rv;
}
static const char delimiters[] = "/:@?#[";
char* brk = PL_strpbrk(i_Spec, delimiters);
if (!brk) // everything is a host
{
rv = ExtractString((char*)i_Spec, o_Host, len);
ToLowerCase(*o_Host);
return rv;
} else
len = PL_strlen(brk);
switch (*brk)
{
case '/' :
case '?' :
case '#' :
// If the URL starts with a slash then everything is a path
if (brk == i_Spec)
{
rv = ParseAtPath(brk, o_Path);
return rv;
}
else // The first part is host, so its host/path
{
rv = ExtractString((char*)i_Spec, o_Host, (brk - i_Spec));
if (NS_FAILED(rv))
return rv;
ToLowerCase(*o_Host);
rv = ParseAtPath(brk, o_Path);
return rv;
}
break;
case ':' :
if (len >= 2 && *(brk+1) == '/' && *(brk+2) == '/') {
// Standard http://...
rv = ExtractString((char*)i_Spec, o_Scheme, (brk - i_Spec));
if (NS_FAILED(rv))
return rv;
ToLowerCase(*o_Scheme);
rv = ParseAtPreHost(brk+1, o_Username, o_Password, o_Host,
o_Port, o_Path);
if (rv == NS_ERROR_MALFORMED_URI) {
// or not ? Try something else
CRTFREEIF(*o_Username);
CRTFREEIF(*o_Password);
CRTFREEIF(*o_Host);
*o_Port = -1;
rv = ParseAtPath(brk+3, o_Path);
}
return rv;
} else {
if ( len >= 2 && *(brk+1) == '/' && *(brk+2) != '/') {
// May be it is file:/....
rv = ExtractString((char*)i_Spec, o_Scheme, (brk - i_Spec));
if (NS_FAILED(rv))
return rv;
ToLowerCase(*o_Scheme);
rv = ParseAtPath(brk+1, o_Path);
return rv;
} else {
// Could be host:port, so try conversion to number
PRInt32 port = ExtractPortFrom(brk+1);
if (port <= 0)
{
// No, try normal procedure
rv = ExtractString((char*)i_Spec, o_Scheme,
(brk - i_Spec));
if (NS_FAILED(rv))
return rv;
ToLowerCase(*o_Scheme);
rv = ParseAtPreHost(brk+1, o_Username, o_Password, o_Host,
o_Port, o_Path);
if (rv == NS_ERROR_MALFORMED_URI) {
// Try something else
CRTFREEIF(*o_Username);
CRTFREEIF(*o_Password);
CRTFREEIF(*o_Host);
*o_Port = -1;
rv = ParseAtPath(brk+1, o_Path);
}
return rv;
} else {
rv = ExtractString((char*)i_Spec, o_Host, (brk - i_Spec));
if (NS_FAILED(rv))
return rv;
ToLowerCase(*o_Host);
rv = ParseAtPort(brk+1, o_Port, o_Path);
return rv;
}
}
}
break;
case '@' :
rv = ParseAtPreHost(i_Spec, o_Username, o_Password, o_Host,
o_Port, o_Path);
return rv;
break;
case '[':
if (brk == i_Spec) {
rv = ParseAtHost(i_Spec, o_Host, o_Port, o_Path);
if (rv != NS_ERROR_MALFORMED_URI) return rv;
// Try something else
CRTFREEIF(*o_Host);
*o_Port = -1;
}
rv = ParseAtPath(i_Spec, o_Path);
return rv;
default:
NS_ASSERTION(0, "This just can't be!");
break;
}
return NS_OK;
}
nsresult
nsStdURLParser::ParseAtPreHost(const char* i_Spec, char* *o_Username,
char* *o_Password, char* *o_Host,
PRInt32 *o_Port, char* *o_Path)
{
nsresult rv = NS_OK;
// Skip leading two slashes
char* fwdPtr= (char*) i_Spec;
if (fwdPtr && (*fwdPtr != '\0') && (*fwdPtr == '/'))
fwdPtr++;
if (fwdPtr && (*fwdPtr != '\0') && (*fwdPtr == '/'))
fwdPtr++;
static const char delimiters[] = "/:@?#[";
char* brk = PL_strpbrk(fwdPtr, delimiters);
char* brk2 = nsnull;
if (!brk)
{
rv = ParseAtHost(fwdPtr, o_Host, o_Port, o_Path);
return rv;
}
char* e_PreHost = nsnull;
switch (*brk)
{
case ':' :
// this maybe the : of host:port or username:password
// look if the next special char is @
brk2 = PL_strpbrk(brk+1, delimiters);
if (!brk2)
{
rv = ParseAtHost(fwdPtr, o_Host, o_Port, o_Path);
return rv;
}
switch (*brk2)
{
case '@' :
rv = ExtractString(fwdPtr, &e_PreHost, (brk2 - fwdPtr));
if (NS_FAILED(rv)) {
CRTFREEIF(e_PreHost);
return rv;
}
rv = ParsePreHost(e_PreHost,o_Username,o_Password);
CRTFREEIF(e_PreHost);
if (NS_FAILED(rv))
return rv;
rv = ParseAtHost(brk2+1, o_Host, o_Port, o_Path);
break;
default:
rv = ParseAtHost(fwdPtr, o_Host, o_Port, o_Path);
return rv;
}
break;
case '@' :
rv = ExtractString(fwdPtr, &e_PreHost, (brk - fwdPtr));
if (NS_FAILED(rv)) {
CRTFREEIF(e_PreHost);
return rv;
}
rv = ParsePreHost(e_PreHost,o_Username,o_Password);
CRTFREEIF(e_PreHost);
if (NS_FAILED(rv))
return rv;
rv = ParseAtHost(brk+1, o_Host, o_Port, o_Path);
break;
case '[':
if (brk == fwdPtr) {
rv = ParseAtHost(fwdPtr, o_Host, o_Port, o_Path);
if (rv != NS_ERROR_MALFORMED_URI) return rv;
// Try something else
CRTFREEIF(*o_Host);
*o_Port = -1;
}
rv = ParseAtPath(fwdPtr, o_Path);
break;
default:
rv = ParseAtHost(fwdPtr, o_Host, o_Port, o_Path);
}
return rv;
}
nsresult
nsStdURLParser::ParseAtHost(const char* i_Spec, char* *o_Host,
PRInt32 *o_Port, char* *o_Path)
{
nsresult rv = NS_OK;
int len = PL_strlen(i_Spec);
static const char delimiters[] = ":/?#"; //this order is optimized.
const char* fwdPtr= i_Spec;
PRNetAddr netaddr;
if (fwdPtr && *fwdPtr == '[') {
// Possible IPv6 address
fwdPtr = strchr(fwdPtr+1, ']');
if (fwdPtr && (fwdPtr[1] == '\0' || strchr(delimiters, fwdPtr[1]))) {
rv = ExtractString((char*)i_Spec+1, o_Host, (fwdPtr - i_Spec - 1));
if (NS_FAILED(rv))
return rv;
rv = PR_StringToNetAddr(*o_Host, &netaddr);
if (rv != PR_SUCCESS || netaddr.raw.family != PR_AF_INET6) {
// try something else
CRTFREEIF(*o_Host);
} else {
ToLowerCase(*o_Host);
fwdPtr++;
switch (*fwdPtr)
{
case '\0': // everything is a host
return NS_OK;
case '/' :
case '?' :
case '#' :
rv = ParseAtPath(fwdPtr, o_Path);
return rv;
case ':' :
rv = ParseAtPort(fwdPtr+1, o_Port, o_Path);
return rv;
default:
NS_ASSERTION(0, "This just can't be!");
break;
}
}
}
}
char* brk = PL_strpbrk(i_Spec, delimiters);
if (!brk) // everything is a host
{
rv = ExtractString((char*)i_Spec, o_Host, len);
ToLowerCase(*o_Host);
return rv;
}
switch (*brk)
{
case '/' :
case '?' :
case '#' :
// Get the Host, the rest is Path
rv = ExtractString((char*)i_Spec, o_Host, (brk - i_Spec));
if (NS_FAILED(rv))
return rv;
ToLowerCase(*o_Host);
rv = ParseAtPath(brk, o_Path);
return rv;
break;
case ':' :
// Get the Host
rv = ExtractString((char*)i_Spec, o_Host, (brk - i_Spec));
if (NS_FAILED(rv))
return rv;
ToLowerCase(*o_Host);
rv = ParseAtPort(brk+1, o_Port, o_Path);
return rv;
break;
default:
NS_ASSERTION(0, "This just can't be!");
break;
}
return NS_OK;
}
nsresult
nsStdURLParser::ParseAtPort(const char* i_Spec, PRInt32 *o_Port, char* *o_Path)
{
nsresult rv = NS_OK;
static const char delimiters[] = "/?#"; //this order is optimized.
char* brk = PL_strpbrk(i_Spec, delimiters);
if (!brk) // everything is a Port
{
*o_Port = ExtractPortFrom(i_Spec);
if (*o_Port <= 0)
return NS_ERROR_MALFORMED_URI;
else
return NS_OK;
}
switch (*brk)
{
case '/' :
case '?' :
case '#' :
// Get the Port, the rest is Path
*o_Port = ExtractPortFrom(i_Spec);
if (*o_Port <= 0)
return NS_ERROR_MALFORMED_URI;
rv = ParseAtPath(brk, o_Path);
return rv;
break;
default:
NS_ASSERTION(0, "This just can't be!");
break;
}
return NS_OK;
}
nsresult
nsStdURLParser::ParseAtPath(const char* i_Spec, char* *o_Path)
{
// Just write the path and check for a starting /
nsCAutoString dir;
if ('/' != *i_Spec)
dir += "/";
dir += i_Spec;
*o_Path = dir.ToNewCString();
return (*o_Path ? NS_OK : NS_ERROR_OUT_OF_MEMORY);
}
nsresult
nsStdURLParser::ParseAtDirectory(const char* i_Path, char* *o_Directory,
char* *o_FileBaseName, char* *o_FileExtension,
char* *o_Param, char* *o_Query, char* *o_Ref)
{
// Cleanout
CRTFREEIF(*o_Directory);
CRTFREEIF(*o_FileBaseName);
CRTFREEIF(*o_FileExtension);
CRTFREEIF(*o_Param);
CRTFREEIF(*o_Query);
CRTFREEIF(*o_Ref);
nsresult rv = NS_OK;
// Parse the Path into its components
if (!i_Path)
{
DupString(o_Directory, "/");
return (o_Directory ? NS_OK : NS_ERROR_OUT_OF_MEMORY);
}
char* dirfile = nsnull;
char* options = nsnull;
int len = PL_strlen(i_Path);
/* Factor out the optionpart with ;?# */
static const char delimiters[] = ";?#"; // for param, query and ref
char* brk = PL_strpbrk(i_Path, delimiters);
if (!brk) // Everything is just path and filename
{
DupString(&dirfile, i_Path);
}
else
{
int dirfileLen = brk - i_Path;
ExtractString((char*)i_Path, &dirfile, dirfileLen);
len -= dirfileLen;
ExtractString((char*)i_Path + dirfileLen, &options, len);
brk = options;
}
/* now that we have broken up the path treat every part differently */
/* first dir+file */
char* file= nsnull;
int dlen = PL_strlen(dirfile);
if (dlen == 0)
{
DupString(o_Directory, "/");
file = dirfile;
} else {
CoaleseDirs(dirfile);
// Get length again
dlen = PL_strlen(dirfile);
// First find the last slash
file = PL_strrchr(dirfile, '/');
if (!file)
{
DupString(o_Directory, "/");
file = dirfile;
}
// If its not the same as the first slash then extract directory
if (file != dirfile)
{
ExtractString(dirfile, o_Directory, (file - dirfile)+1);
if (*dirfile != '/') {
nsCAutoString dir;
dir += "/" ;
dir += *o_Directory;
CRTFREEIF(*o_Directory);
*o_Directory = dir.ToNewCString();
}
} else {
DupString(o_Directory, "/");
}
}
/* Extract FileBaseName and FileExtension */
if (dlen > 0) {
// Look again if there was a slash
char* slash = PL_strrchr(dirfile, '/');
char* e_FileName = nsnull;
if (slash) {
if (dirfile+dlen-1>slash)
ExtractString(slash+1, &e_FileName, dlen-(slash-dirfile+1));
} else {
// Use the full String as Filename
ExtractString(dirfile, &e_FileName, dlen);
}
rv = ParseFileName(e_FileName,o_FileBaseName,o_FileExtension);
CRTFREEIF(e_FileName);
}
// Now take a look at the options. "#" has precedence over "?"
// which has precedence over ";"
if (options) {
// Look for "#" first. Everything following it is in the ref
brk = PL_strchr(options, '#');
if (brk) {
int pieceLen = len - (brk + 1 - options);
ExtractString(brk+1, o_Ref, pieceLen);
len -= pieceLen + 1;
*brk = '\0';
}
// Now look for "?"
brk = PL_strchr(options, '?');
if (brk) {
int pieceLen = len - (brk + 1 - options);
ExtractString(brk+1, o_Query, pieceLen);
len -= pieceLen + 1;
*brk = '\0';
}
// Now look for ';'
brk = PL_strchr(options, ';');
if (brk) {
int pieceLen = len - (brk + 1 - options);
ExtractString(brk+1, o_Param, pieceLen);
len -= pieceLen + 1;
*brk = '\0';
}
}
CRTFREEIF(dirfile);
CRTFREEIF(options);
return rv;
}
nsresult
nsStdURLParser::ParsePreHost(const char* i_PreHost, char* *o_Username,
char* *o_Password)
{
nsresult rv = NS_OK;
if (!i_PreHost) {
*o_Username = nsnull;
*o_Password = nsnull;
return rv;
}
// Search for :
static const char delimiters[] = ":";
char* brk = PL_strpbrk(i_PreHost, delimiters);
if (brk)
{
rv = ExtractString((char*)i_PreHost, o_Username, (brk - i_PreHost));
if (NS_FAILED(rv))
return rv;
rv = ExtractString(brk+1, o_Password,
(i_PreHost+PL_strlen(i_PreHost) - brk - 1));
} else {
CRTFREEIF(*o_Password);
rv = DupString(o_Username, i_PreHost);
}
return rv;
}
nsresult
nsStdURLParser::ParseFileName(const char* i_FileName, char* *o_FileBaseName,
char* *o_FileExtension)
{
nsresult rv = NS_OK;
if (!i_FileName) {
*o_FileBaseName = nsnull;
*o_FileExtension = nsnull;
return rv;
}
// Search for FileExtension
// Search for last .
// Ignore . at the beginning
char* brk = PL_strrchr(i_FileName+1, '.');
if (brk)
{
rv = ExtractString((char*)i_FileName, o_FileBaseName,
(brk - i_FileName));
if (NS_FAILED(rv))
return rv;
rv = ExtractString(brk + 1, o_FileExtension,
(i_FileName+PL_strlen(i_FileName) - brk - 1));
} else {
rv = DupString(o_FileBaseName, i_FileName);
}
return rv;
}

Some files were not shown because too many files have changed in this diff Show More