Fix 49934: gopher support, minor restructuring of directory viewer. necko: r=darin,dougt sr=rpotts other: r=waterson,mstoltz,jag sr=alecf

Fix 70404: assertionsf or datetime and finger. r=dougt, sr=rpotts

Both patches by Bradley Baetz (bbaetz@cs.mcgill.ca)
This commit is contained in:
blakeross%telocity.com 2001-03-14 02:41:18 +00:00
parent 92e3bfdeb7
commit 650b9d4dd1
17 changed files with 1366 additions and 251 deletions

View File

@ -165,6 +165,24 @@ nsProtocolProxyService::PrefsChanged(const char* pref) {
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 = "";
@ -287,6 +305,14 @@ nsProtocolProxyService::ExamineForProxy(nsIURI *aURI, nsIProxy *aProxy) {
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")) {

View File

@ -70,6 +70,9 @@ protected:
nsXPIDLCString mFTPProxyHost;
PRInt32 mFTPProxyPort;
nsXPIDLCString mGopherProxyHost;
PRInt32 mGopherProxyPort;
nsXPIDLCString mHTTPSProxyHost;
PRInt32 mHTTPSProxyPort;

View File

@ -22,6 +22,7 @@
#include "nsIGenericFactory.h"
#include "nsGopherHandler.h"
#include "nsFtpProtocolHandler.h"
#include "nsFingerHandler.h"
#include "nsDateTimeHandler.h"
@ -32,6 +33,13 @@ NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsFtpProtocolHandler, Init);
// Module implementation for the net library
static nsModuleComponentInfo gNetModuleInfo[] = {
//gopher:
{ "The Gopher Protocol Handler",
NS_GOPHERHANDLER_CID,
NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "gopher",
nsGopherHandler::Create
},
// from netwerk/protocol/ftp:
{ "The FTP Protocol Handler",
NS_FTPPROTOCOLHANDLER_CID,

View File

@ -0,0 +1,39 @@
# 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 Bradley Baetz
# Portions created by Brian Ryner are Copyright (C) 2000 Bradley Baetz.
# All Rights Reserved.
#
# Contributor(s):
# Bradley Baetz <bbaetz@student.usyd.edu.au>
MODULE = necko
DEPTH = ..\..\..\..
LIBRARY_NAME=nkgopher_s
LCFLAGS = -DWIN32_LEAN_AND_MEAN -D_IMPL_NS_NET
CPP_OBJS = \
.\$(OBJDIR)\nsGopherHandler.obj \
.\$(OBJDIR)\nsGopherChannel.obj \
$(NULL)
include <$(DEPTH)\config\rules.mak>
install:: $(LIBRARY)
$(MAKE_INSTALL) $(LIBRARY) $(DIST)\lib
clobber::
rm -f $(DIST)\lib\$(LIBRARY_NAME).lib

View File

@ -0,0 +1,522 @@
/* -*- Mode: C++; tab-width: 4; 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 the Gopher protocol code.
*
* The Initial Developer of the Original Code is Bradley Baetz.
* Portions created by Bradley Baetz are Copyright (C) 2000 Bradley Baetz.
* All Rights Reserved.
*
* Contributor(s):
* Bradley Baetz <bbaetz@student.usyd.edu.au>
*/
// gopher implementation - based on datetime and finger implimentations
// and documentation
#include "nsGopherChannel.h"
#include "nsIServiceManager.h"
#include "nsILoadGroup.h"
#include "nsIInterfaceRequestor.h"
#include "nsXPIDLString.h"
#include "nsISocketTransportService.h"
#include "nsIStringStream.h"
#include "nsMimeTypes.h"
#include "nsIStreamConverterService.h"
#include "nsEscape.h"
#include "nsITXTToHTMLConv.h"
#include "nsIProgressEventSink.h"
#include "nsNetUtil.h"
static NS_DEFINE_CID(kSocketTransportServiceCID, NS_SOCKETTRANSPORTSERVICE_CID);
static NS_DEFINE_CID(kStreamConverterServiceCID, NS_STREAMCONVERTERSERVICE_CID);
#define BUFFER_SEG_SIZE (4*1024)
#define BUFFER_MAX_SIZE (64*1024)
// nsGopherChannel methods
nsGopherChannel::nsGopherChannel()
: mContentLength(-1),
mActAsObserver(PR_TRUE),
mType(-1),
mStatus(NS_OK)
{
NS_INIT_REFCNT();
}
nsGopherChannel::~nsGopherChannel() {
}
NS_IMPL_THREADSAFE_ISUPPORTS4(nsGopherChannel,
nsIChannel,
nsIRequest,
nsIStreamListener,
nsIStreamObserver);
nsresult
nsGopherChannel::Init(nsIURI* uri)
{
nsresult rv;
nsCOMPtr<nsIURL> url = do_QueryInterface(uri, &rv);
if (NS_FAILED(rv))
return NS_ERROR_MALFORMED_URI;
mUrl = uri;
nsXPIDLCString buffer;
rv = url->GetPath(getter_Copies(buffer));
if (NS_FAILED(rv))
return rv;
rv = url->GetHost(getter_Copies(mHost));
if (NS_FAILED(rv))
return rv;
rv = url->GetPort(&mPort);
if (NS_FAILED(rv))
return rv;
if (mPort==-1)
mPort=GOPHER_PORT;
// No path given
if (buffer[0]=='\0' || (buffer[0]=='/' && buffer[1]=='\0')) {
mType = '1';
mSelector = "";
} else {
mType = buffer[1]; // Ignore leading '/'
mSelector = nsUnescape(NS_CONST_CAST(char*,&buffer[2]));
}
//printf("Host: mHost = %s, mPort = %d\n", mHost.get(), mPort);
//printf("Status: mType = %c, mSelector = %s\n", mType, mSelector.get());
return NS_OK;
}
NS_METHOD
nsGopherChannel::Create(nsISupports* aOuter, const nsIID& aIID, void* *aResult)
{
nsGopherChannel* fc = new nsGopherChannel();
if (!fc)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(fc);
nsresult rv = fc->QueryInterface(aIID, aResult);
NS_RELEASE(fc);
return rv;
}
////////////////////////////////////////////////////////////////////////////////
// nsIRequest methods:
NS_IMETHODIMP
nsGopherChannel::GetName(PRUnichar* *result)
{
nsString name;
name.AppendWithConversion(mHost);
name.AppendWithConversion(":");
name.AppendInt(mPort);
*result = name.ToNewUnicode();
return *result ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
}
NS_IMETHODIMP
nsGopherChannel::IsPending(PRBool *result)
{
NS_NOTREACHED("nsGopherChannel::IsPending");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsGopherChannel::GetStatus(nsresult *status)
{
*status = mStatus;
return NS_OK;
}
NS_IMETHODIMP
nsGopherChannel::Cancel(nsresult status)
{
NS_ASSERTION(NS_FAILED(status), "shouldn't cancel with a success code");
nsresult rv = NS_ERROR_FAILURE;
mStatus = status;
if (mTransportRequest) {
rv = mTransportRequest->Cancel(status);
}
return rv;
}
NS_IMETHODIMP
nsGopherChannel::Suspend(void)
{
NS_NOTREACHED("nsGopherChannel::Suspend");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsGopherChannel::Resume(void)
{
NS_NOTREACHED("nsGopherChannel::Resume");
return NS_ERROR_NOT_IMPLEMENTED;
}
////////////////////////////////////////////////////////////////////////////////
// nsIChannel methods:
NS_IMETHODIMP
nsGopherChannel::GetOriginalURI(nsIURI* *aURI)
{
*aURI = mOriginalURI ? mOriginalURI : mUrl;
NS_ADDREF(*aURI);
return NS_OK;
}
NS_IMETHODIMP
nsGopherChannel::SetOriginalURI(nsIURI* aURI)
{
mOriginalURI = aURI;
return NS_OK;
}
NS_IMETHODIMP
nsGopherChannel::GetURI(nsIURI* *aURI)
{
*aURI = mUrl;
NS_IF_ADDREF(*aURI);
return NS_OK;
}
NS_IMETHODIMP
nsGopherChannel::SetURI(nsIURI* aURI)
{
mUrl = aURI;
return NS_OK;
}
NS_IMETHODIMP
nsGopherChannel::Open(nsIInputStream **_retval)
{
nsresult rv = NS_OK;
NS_WITH_SERVICE(nsISocketTransportService,
socketService,
kSocketTransportServiceCID,
&rv);
if (NS_FAILED(rv)) return rv;
rv = socketService->CreateTransport(mHost,
mPort,
nsnull,
-1,
BUFFER_SEG_SIZE,
BUFFER_MAX_SIZE,
getter_AddRefs(mTransport));
if (NS_FAILED(rv)) return rv;
mTransport->SetNotificationCallbacks(mCallbacks,
(mLoadAttributes & LOAD_BACKGROUND));
return mTransport->OpenInputStream(0, (PRUint32)-1, 0, _retval);
}
NS_IMETHODIMP
nsGopherChannel::AsyncOpen(nsIStreamListener *aListener, nsISupports *ctxt)
{
nsresult rv = NS_OK;
NS_WITH_SERVICE(nsISocketTransportService,
socketService,
kSocketTransportServiceCID,
&rv);
if (NS_FAILED(rv)) return rv;
rv = socketService->CreateTransport(mHost,
mPort,
nsnull,
-1,
BUFFER_SEG_SIZE,
BUFFER_MAX_SIZE,
getter_AddRefs(mTransport));
if (NS_FAILED(rv)) return rv;
mTransport->SetNotificationCallbacks(mCallbacks,
(mLoadAttributes & LOAD_BACKGROUND));
mListener = aListener;
mResponseContext = ctxt;
return SendRequest(mTransport);
}
NS_IMETHODIMP
nsGopherChannel::GetLoadAttributes(PRUint32 *aLoadAttributes)
{
*aLoadAttributes = mLoadAttributes;
return NS_OK;
}
NS_IMETHODIMP
nsGopherChannel::SetLoadAttributes(PRUint32 aLoadAttributes)
{
mLoadAttributes = aLoadAttributes;
return NS_OK;
}
NS_IMETHODIMP
nsGopherChannel::GetContentType(char* *aContentType) {
if (!aContentType) return NS_ERROR_NULL_POINTER;
switch(mType) {
case '0':
*aContentType = nsCRT::strdup(TEXT_HTML);
break;
case '1':
*aContentType = nsCRT::strdup("application/http-index-format");
break;
case '2': // CSO search - unhandled, should not be selectable
*aContentType = nsCRT::strdup(TEXT_HTML);
break;
case '3': // "Error" - should not be selectable
*aContentType = nsCRT::strdup(TEXT_HTML);
break;
case '4': // "BinHexed Macintosh file"
*aContentType = nsCRT::strdup(APPLICATION_BINHEX);
break;
case '5':
// "DOS binary archive of some sort" - is the mime-type correct?
*aContentType = nsCRT::strdup(APPLICATION_OCTET_STREAM);
break;
case '6':
*aContentType = nsCRT::strdup(APPLICATION_UUENCODE);
break;
case '7': // search - unhandled yet
*aContentType = nsCRT::strdup(TEXT_HTML);
break;
case '8': // telnet - type doesn't make sense
*aContentType = nsCRT::strdup(TEXT_PLAIN);
break;
case '9': // "Binary file!"
*aContentType = nsCRT::strdup(APPLICATION_OCTET_STREAM);
break;
case 'g':
*aContentType = nsCRT::strdup(IMAGE_GIF);
break;
case 'i': // info line- should not be selectable
*aContentType = nsCRT::strdup(TEXT_HTML);
break;
case 'I':
*aContentType = nsCRT::strdup(IMAGE_GIF);
break;
case 'T': // tn3270 - type doesn't make sense
*aContentType = nsCRT::strdup(TEXT_PLAIN);
break;
default:
NS_WARNING("Unknown gopher type");
*aContentType = nsCRT::strdup(UNKNOWN_CONTENT_TYPE);
}
if (!*aContentType)
return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
}
NS_IMETHODIMP
nsGopherChannel::SetContentType(const char *aContentType)
{
//It doesn't make sense to set the content-type on this type
// of channel...
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsGopherChannel::GetContentLength(PRInt32 *aContentLength)
{
*aContentLength = mContentLength;
return NS_OK;
}
NS_IMETHODIMP
nsGopherChannel::SetContentLength(PRInt32 aContentLength)
{
NS_NOTREACHED("nsGopherChannel::SetContentLength");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsGopherChannel::GetLoadGroup(nsILoadGroup* *aLoadGroup)
{
*aLoadGroup = mLoadGroup;
NS_IF_ADDREF(*aLoadGroup);
return NS_OK;
}
NS_IMETHODIMP
nsGopherChannel::SetLoadGroup(nsILoadGroup* aLoadGroup)
{
mLoadGroup = aLoadGroup;
return NS_OK;
}
NS_IMETHODIMP
nsGopherChannel::GetOwner(nsISupports* *aOwner)
{
*aOwner = mOwner.get();
NS_IF_ADDREF(*aOwner);
return NS_OK;
}
NS_IMETHODIMP
nsGopherChannel::SetOwner(nsISupports* aOwner)
{
mOwner = aOwner;
return NS_OK;
}
NS_IMETHODIMP
nsGopherChannel::GetNotificationCallbacks(nsIInterfaceRequestor* *aNotificationCallbacks)
{
*aNotificationCallbacks = mCallbacks.get();
NS_IF_ADDREF(*aNotificationCallbacks);
return NS_OK;
}
NS_IMETHODIMP
nsGopherChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aNotificationCallbacks)
{
mCallbacks = aNotificationCallbacks;
return NS_OK;
}
NS_IMETHODIMP
nsGopherChannel::GetSecurityInfo(nsISupports * *aSecurityInfo)
{
*aSecurityInfo = nsnull;
return NS_OK;
}
// nsIStreamObserver methods
NS_IMETHODIMP
nsGopherChannel::OnStartRequest(nsIRequest *aRequest, nsISupports *aContext) {
if (!mActAsObserver) {
// acting as a listener
return mListener->OnStartRequest(this, aContext);
} else {
// we don't want to pass our AsyncWrite's OnStart through
// we just ignore this
return NS_OK;
}
}
NS_IMETHODIMP
nsGopherChannel::OnStopRequest(nsIRequest* aRequest, nsISupports* aContext,
nsresult aStatus, const PRUnichar* aStatusArg)
{
nsresult rv = NS_OK;
if (NS_FAILED(aStatus) || !mActAsObserver) {
if (NS_SUCCEEDED(rv) && mLoadGroup) {
rv = mLoadGroup->RemoveRequest(this, nsnull, aStatus, aStatusArg);
}
if (NS_FAILED(aStatus)) // let the original caller know
aContext=mResponseContext;
rv = mListener->OnStopRequest(this, aContext, aStatus, aStatusArg);
mListener = 0;
mTransport = 0;
return rv;
} else {
// at this point we know the request has been sent.
// we're no longer acting as an observer.
mActAsObserver = PR_FALSE;
nsCOMPtr<nsIStreamListener> converterListener;
NS_WITH_SERVICE(nsIStreamConverterService, StreamConvService,
kStreamConverterServiceCID, &rv);
if (NS_FAILED(rv)) return rv;
// What we now do depends on what type of file we have
if (mType=='1') {
// Send the directory format back for a directory
rv = StreamConvService->AsyncConvertData(NS_LITERAL_STRING("text/gopher-dir").get(),
NS_LITERAL_STRING("application/http-index-format").get(),
this,
mUrl,
getter_AddRefs(converterListener));
if (NS_FAILED(rv)) return rv;
} else if (mType=='0') {
// Convert general file
rv = StreamConvService->AsyncConvertData(NS_LITERAL_STRING("text/plain").get(),
NS_LITERAL_STRING("text/html").get(),
this,
mResponseContext,
getter_AddRefs(converterListener));
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsITXTToHTMLConv> converter(do_QueryInterface(converterListener));
if (converter) {
nsXPIDLCString spec;
rv = mUrl->GetSpec(getter_Copies(spec));
nsUnescape(NS_CONST_CAST(char*, spec.get()));
converter->SetTitle(NS_ConvertASCIItoUCS2(spec).get());
converter->PreFormatHTML(PR_TRUE);
}
} else
// other file type - no conversions
converterListener = this;
return mTransport->AsyncRead(converterListener, mResponseContext, 0,
(PRUint32)-1, 0, getter_AddRefs(mTransportRequest));
}
}
// nsIStreamListener method
NS_IMETHODIMP
nsGopherChannel::OnDataAvailable(nsIRequest* aRequest, nsISupports* aContext,
nsIInputStream *aInputStream,
PRUint32 aSourceOffset, PRUint32 aLength) {
mContentLength = aLength;
return mListener->OnDataAvailable(this, aContext, aInputStream,
aSourceOffset, aLength);
}
nsresult
nsGopherChannel::SendRequest(nsITransport* aTransport) {
nsresult rv = NS_OK;
nsCOMPtr<nsISupports> result;
nsCOMPtr<nsIInputStream> charstream;
nsCString requestBuffer(mSelector);
if (mLoadGroup) {
mLoadGroup->AddRequest(this, nsnull);
}
requestBuffer.Append(CRLF);
mRequest = requestBuffer.ToNewCString();
rv = NS_NewCharInputStream(getter_AddRefs(result), mRequest);
if (NS_FAILED(rv)) return rv;
charstream = do_QueryInterface(result, &rv);
if (NS_FAILED(rv)) return rv;
//printf("Sending: %s\n", requestBuffer.GetBuffer());
rv = NS_AsyncWriteFromStream(getter_AddRefs(mTransportRequest),
aTransport, charstream,
0, requestBuffer.Length(), 0,
this, nsnull);
return rv;
}

View File

@ -0,0 +1,88 @@
/* -*- Mode: C++; tab-width: 4; 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 the Gopher protocol code.
*
* The Initial Developer of the Original Code is Bradley Baetz.
* Portions created by Bradley Baetz are Copyright (C) 2000 Bradley Baetz.
* All Rights Reserved.
*
* Contributor(s):
* Bradley Baetz <bbaetz@student.usyd.edu.au>
*/
#ifndef nsGopherChannel_h___
#define nsGopherChannel_h___
#include "nsString.h"
#include "nsILoadGroup.h"
#include "nsIInputStream.h"
#include "nsIInterfaceRequestor.h"
#include "nsCOMPtr.h"
#include "nsXPIDLString.h"
#include "nsIChannel.h"
#include "nsIURI.h"
#include "nsIURL.h"
#include "nsGopherHandler.h"
#include "nsIStreamListener.h"
#include "nsITransport.h"
class nsGopherChannel : public nsIChannel,
public nsIStreamListener {
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIREQUEST
NS_DECL_NSICHANNEL
NS_DECL_NSISTREAMLISTENER
NS_DECL_NSISTREAMOBSERVER
// nsGopherChannel methods:
nsGopherChannel();
virtual ~nsGopherChannel();
// Define a Create method to be used with a factory:
static NS_METHOD
Create(nsISupports* aOuter, const nsIID& aIID, void* *aResult);
nsresult Init(nsIURI* uri);
protected:
nsCOMPtr<nsIURI> mOriginalURI;
nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
nsCOMPtr<nsIURI> mUrl;
nsCOMPtr<nsIStreamListener> mListener;
PRUint32 mLoadAttributes;
nsCOMPtr<nsILoadGroup> mLoadGroup;
nsCString mContentType;
PRInt32 mContentLength;
nsCOMPtr<nsISupports> mOwner;
PRUint32 mBufferSegmentSize;
PRUint32 mBufferMaxSize;
PRBool mActAsObserver;
nsXPIDLCString mHost;
PRInt32 mPort;
char mType;
nsXPIDLCString mSelector;
nsXPIDLCString mRequest;
nsCOMPtr<nsISupports> mResponseContext;
nsCOMPtr<nsITransport> mTransport;
nsCOMPtr<nsIRequest> mTransportRequest;
nsresult mStatus;
protected:
nsresult SendRequest(nsITransport* aTransport);
};
#endif /* nsGopherChannel_h___ */

View File

@ -0,0 +1,222 @@
/* -*- Mode: C++; tab-width: 4; 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 the Gopher protocol code.
*
* The Initial Developer of the Original Code is Bradley Baetz.
* Portions created by Bradley Baetz are Copyright (C) 2000 Bradley Baetz.
* All Rights Reserved.
*
* Contributor(s):
* Bradley Baetz <bbaetz@student.usyd.edu.au>
*/
// This is based rather heavily on the datetime and finger implementations
// and documentation
#include "nspr.h"
#include "nsGopherChannel.h"
#include "nsGopherHandler.h"
#include "nsIURL.h"
#include "nsCRT.h"
#include "nsIComponentManager.h"
#include "nsIServiceManager.h"
#include "nsIInterfaceRequestor.h"
#include "nsIProgressEventSink.h"
#include "nsIHTTPProtocolHandler.h"
#include "nsIHTTPChannel.h"
#include "nsIErrorService.h"
#include "nsNetUtil.h"
static NS_DEFINE_CID(kStandardURLCID, NS_STANDARDURL_CID);
static NS_DEFINE_CID(kProtocolProxyServiceCID, NS_PROTOCOLPROXYSERVICE_CID);
static NS_DEFINE_CID(kHTTPHandlerCID, NS_IHTTPHANDLER_CID);
////////////////////////////////////////////////////////////////////////////////
nsGopherHandler::nsGopherHandler() : mProxyPort(-1) {
NS_INIT_REFCNT();
nsresult rv;
mProxySvc = do_GetService(kProtocolProxyServiceCID, &rv);
if (!mProxySvc)
NS_WARNING("Failed to get proxy service!\n");
}
nsGopherHandler::~nsGopherHandler() {
}
NS_IMPL_ISUPPORTS2(nsGopherHandler, nsIProtocolHandler, nsIProxy);
NS_METHOD
nsGopherHandler::Create(nsISupports* aOuter, const nsIID& aIID, void* *aResult) {
nsGopherHandler* ph = new nsGopherHandler();
if (!ph)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(ph);
nsresult rv = ph->QueryInterface(aIID, aResult);
NS_RELEASE(ph);
return rv;
}
////////////////////////////////////////////////////////////////////////////////
// nsIProxy methods:
NS_IMETHODIMP
nsGopherHandler::GetProxyHost(char **aProxyHost) {
*aProxyHost = mProxyHost.ToNewCString();
if (!*aProxyHost) return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
}
NS_IMETHODIMP
nsGopherHandler::SetProxyHost(const char * aProxyHost) {
mProxyHost = aProxyHost;
return NS_OK;
}
NS_IMETHODIMP
nsGopherHandler::GetProxyPort(PRInt32 *aProxyPort) {
*aProxyPort = mProxyPort;
return NS_OK;
}
NS_IMETHODIMP
nsGopherHandler::SetProxyPort(PRInt32 aProxyPort) {
mProxyPort = aProxyPort;
return NS_OK;
}
NS_IMETHODIMP
nsGopherHandler::GetProxyType(char **aProxyType) {
*aProxyType = mProxyType.ToNewCString();
if (!*aProxyType) return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
}
NS_IMETHODIMP
nsGopherHandler::SetProxyType(const char * aProxyType) {
mProxyType = aProxyType;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsIProtocolHandler methods:
NS_IMETHODIMP
nsGopherHandler::GetScheme(char* *result) {
*result = nsCRT::strdup("gopher");
if (!*result) return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
}
NS_IMETHODIMP
nsGopherHandler::GetDefaultPort(PRInt32 *result) {
*result = GOPHER_PORT;
return NS_OK;
}
NS_IMETHODIMP
nsGopherHandler::NewURI(const char *aSpec, nsIURI *aBaseURI,
nsIURI **result) {
nsresult rv;
// All gopher URLs are absolute by definition
NS_ASSERTION(!aBaseURI, "base url passed into gopher protocol handler");
// I probably need an nsIGopherURL
nsCOMPtr<nsIStandardURL> url;
rv = nsComponentManager::CreateInstance(kStandardURLCID, nsnull,
NS_GET_IID(nsIStandardURL),
getter_AddRefs(url));
if (NS_FAILED(rv)) return rv;
rv = url->Init(nsIStandardURL::URLTYPE_STANDARD, GOPHER_PORT,
aSpec, aBaseURI);
if (NS_FAILED(rv)) return rv;
return url->QueryInterface(NS_GET_IID(nsIURI), (void**)result);
}
NS_IMETHODIMP
nsGopherHandler::NewChannel(nsIURI* url, nsIChannel* *result)
{
nsresult rv;
nsGopherChannel* channel;
rv = nsGopherChannel::Create(nsnull, NS_GET_IID(nsIChannel),
(void**)&channel);
if (NS_FAILED(rv)) return rv;
rv = channel->Init(url);
if (NS_FAILED(rv)) {
NS_RELEASE(channel);
return rv;
}
// Proxy code is largly taken from the ftp and http protocol handlers
PRBool useProxy = PR_FALSE;
if (mProxySvc &&
NS_SUCCEEDED(mProxySvc->GetProxyEnabled(&useProxy)) && useProxy) {
rv = mProxySvc->ExamineForProxy(url, this);
if (NS_FAILED(rv)) return rv;
if (mProxyHost.IsEmpty() || !mProxyType.Compare("socks")) {
*result = channel;
return NS_OK;
}
nsCOMPtr<nsIChannel> proxyChannel;
// if an gopher proxy is enabled, push things off to HTTP.
nsCOMPtr<nsIHTTPProtocolHandler> httpHandler =
do_GetService(kHTTPHandlerCID, &rv);
if (NS_FAILED(rv)) return rv;
// rjc says: the dummy URI (for the HTTP layer) needs to be a syntactically valid URI
nsCOMPtr<nsIURI> uri;
rv = NS_NewURI(getter_AddRefs(uri), "http://example.com");
if (NS_FAILED(rv)) return rv;
rv = httpHandler->NewChannel(uri, getter_AddRefs(proxyChannel));
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIHTTPChannel> httpChannel = do_QueryInterface(proxyChannel, &rv);
if (NS_FAILED(rv)) return rv;
nsXPIDLCString spec;
rv = url->GetSpec(getter_Copies(spec));
if (NS_FAILED(rv)) return rv;
rv = httpChannel->SetProxyRequestURI((const char*)spec);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIProxy> proxyHTTP = do_QueryInterface(httpChannel, &rv);
if (NS_FAILED(rv)) return rv;
rv = proxyHTTP->SetProxyHost(mProxyHost);
if (NS_FAILED(rv)) return rv;
rv = proxyHTTP->SetProxyPort(mProxyPort);
if (NS_FAILED(rv)) return rv;
rv = proxyHTTP->SetProxyType(mProxyType);
if (NS_FAILED(rv)) return rv;
*result = proxyChannel;
NS_ADDREF(*result);
} else {
*result = channel;
}
return NS_OK;
}

View File

@ -0,0 +1,63 @@
/* -*- Mode: C++; tab-width: 4; 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 the Gopher protocol code.
*
* The Initial Developer of the Original Code is Bradley Baetz.
* Portions created by Bradley Baetz are Copyright (C) 2000 Bradley Baetz.
* All Rights Reserved.
*
* Contributor(s):
* Bradley Baetz <bbaetz@student.usyd.edu.au>
*/
#ifndef nsGopherHandler_h___
#define nsGopherHandler_h___
#include "nsIProtocolHandler.h"
#include "nsIProtocolProxyService.h"
#include "nsIProxy.h"
#include "nsString.h"
#include "nsCOMPtr.h"
#define GOPHER_PORT 70
// {0x44588c1f-2ce8-4ad8-9b16-dfb9d9d513a7}
#define NS_GOPHERHANDLER_CID \
{ 0x44588c1f, 0x2ce8, 0x4ad8, \
{0x9b, 0x16, 0xdf, 0xb9, 0xd9, 0xd5, 0x13, 0xa7} }
class nsGopherHandler : public nsIProtocolHandler, public nsIProxy
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIPROTOCOLHANDLER
NS_DECL_NSIPROXY
// nsGopherHandler methods:
nsGopherHandler();
virtual ~nsGopherHandler();
// Define a Create method to be used with a factory:
static NS_METHOD Create(nsISupports* aOuter, const nsIID& aIID,
void* *aResult);
protected:
nsCOMPtr<nsIProtocolProxyService> mProxySvc;
nsCAutoString mProxyHost;
PRInt32 mProxyPort;
nsCAutoString mProxyType;
};
#endif /* nsGopherHandler_h___ */

View File

@ -1,4 +1,4 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* -*- 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
@ -184,7 +184,7 @@ nsContextMenu.prototype = {
this.onLink = false;
this.inFrame = false;
this.hasBGImage = false;
// Remember the node that was clicked.
this.target = node;
@ -258,14 +258,12 @@ nsContextMenu.prototype = {
this.target.getAttribute( "background" ) );
} else if ( "HTTPIndex" in _content &&
_content.HTTPIndex instanceof Components.interfaces.nsIHTTPIndex ) {
// The above test is a roundabout way of determining whether
// the content area contains chrome://global/content/directory/directory.xul.
this.inDirList = true;
// Bubble outward till we get to an element with id= attribute
// Bubble outward till we get to an element with URL attribute
// (which should be the href).
var root = this.target;
while ( root && !this.link ) {
if ( root.getAttribute( "id" ) ) {
if ( root.getAttribute( "URL" ) ) {
if ( root.tagName == "tree" ) {
// Hit root of tree; must have clicked in empty space;
// thus, no link.
@ -273,7 +271,7 @@ nsContextMenu.prototype = {
}
// Build pseudo link object so link-related functions work.
this.onLink = true;
this.link = { href : root.getAttribute( "id" ) };
this.link = { href : root.getAttribute("URL") };
// If element is a directory, then you can't save it.
if ( root.getAttribute( "container" ) == "true" ) {
this.onSaveableLink = false;

View File

@ -1,4 +1,4 @@
/* -*- Mode: Java; tab-width: 4; c-basic-offset: 4; -*-
/* -*- Mode: Java; 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
@ -18,6 +18,7 @@
* Rights Reserved.
*
* Contributor(s):
* Bradley Baetz <bbaetz@student.usyd.edu.au>
*/
/*
@ -56,7 +57,7 @@ const nsISupportsWString = Components.interfaces.nsISupportsWString;
function debug(msg)
{
// Uncomment to print out debug info.
// dump(msg);
//dump(msg);
}
@ -167,9 +168,10 @@ function Init()
debug("append traiing slash to FTP directory URL\n");
baseURI += "/";
}
}
if (baseURI && (baseURI.indexOf("file://") != 0)) {
// Note: DON'T add the HTTPIndex datasource into the tree
// for file URLs, only do it for FTP URLs; the "rdf:files"
// for file URLs, only do it for FTP/Gopher/etc URLs; the "rdf:files"
// datasources handles file URLs
tree.database.AddDataSource(HTTPIndex.DataSource);
}
@ -209,8 +211,6 @@ function Init()
tree.setAttribute("ref", baseURI);
}
function DoUnload()
{
var tree = document.getElementById("tree");
@ -232,21 +232,33 @@ function OnClick(event, node)
return(false);
var tree = document.getElementById("tree");
if( tree.selectedItems.length == 1 )
{
if( tree.selectedItems.length == 1 ) {
var selectedItem = tree.selectedItems[0];
var theID = selectedItem.getAttribute("id");
window._content.location.href = theID;
var url = selectedItem.getAttribute("URL");
window._content.location.href = url;
// set window title
var theWindow = window._content.parentWindow;
if (theWindow)
theWindow.title = theID;
}
theWindow.title = url;
}
}
function OnMouseOver(event, node)
{
if (node.nodeName != "treeitem")
return false;
var url = node.getAttribute("URL");
window._content.status = url;
return true;
}
function OnMouseOut(event, node)
{
window._content.status = "";
return true;
}
function doSort(sortColName)
{

View File

@ -43,6 +43,7 @@
<template>
<treechildren flex="1">
<treeitem uri="..." persist="open"
URL="rdf:http://home.netscape.com/NC-rdf#URL"
type="rdf:http://home.netscape.com/NC-rdf#File-Type"
loading="rdf:http://home.netscape.com/NC-rdf#loading" >
<treerow>
@ -83,7 +84,10 @@
<!-- Create the treechildren here so we can attach event handlers
at this level (rather than at the tree level -->
<treechildren flex="1" onclick="OnClick(event, event.target.parentNode.parentNode);" onkeypress="OnClick(event, event.target.parentNode.parentNode);"/>
<treechildren flex="1" onclick="OnClick(event, event.target.parentNode.parentNode);"
onkeypress="OnClick(event, event.target.parentNode.parentNode);"
onmouseover="OnMouseOver(event, event.target.parentNode.parentNode);"
onmouseout="OnMouseOut(event, event.target.parentNode.parentNode);" />
</tree>
</window>

View File

@ -23,6 +23,7 @@
*
* Contributor(s):
* Pierre Phaneuf <pp@ludusdesign.com>
* Bradley Baetz <bbaetz@student.usyd.edu.au>
*/
/*
@ -32,6 +33,9 @@
http://www.area.com/~roeber/file_format.html
One added change is for a description entry, for when the
target does not match the filename (ie gopher)
*/
#include "nsDirectoryViewer.h"
@ -69,6 +73,10 @@ static NS_DEFINE_CID(kRDFInMemoryDataSourceCID, NS_RDFINMEMORYDATASOURCE_CID);
// what's used in the rest of the application
#define HTTPINDEX_NAMESPACE_URI NC_NAMESPACE_URI
// Various protocols we have to special case
static const char kFTPProtocol[] = "ftp://";
static const char kGopherProtocol[] = "gopher://";
//----------------------------------------------------------------------
//
// nsHTTPIndex
@ -87,20 +95,26 @@ protected:
static nsITextToSubURI* gTextToSubURI;
static nsIRDFResource* kHTTPIndex_Comment;
static nsIRDFResource* kHTTPIndex_Filename;
static nsIRDFResource* kHTTPIndex_Description;
static nsIRDFResource* kHTTPIndex_Filetype;
static nsIRDFResource* kHTTPIndex_Loading;
static nsIRDFResource* kHTTPIndex_URL;
static nsIRDFResource* kNC_Child;
static nsIRDFLiteral* kTrueLiteral;
static nsIRDFLiteral* kFalseLiteral;
static nsresult ParseLiteral(nsIRDFResource *arc, const nsString& aValue, nsIRDFNode** aResult);
static nsresult ParseDate(nsIRDFResource *arc, const nsString& aValue, nsIRDFNode** aResult);
static nsresult ParseInt(nsIRDFResource *arc, const nsString& aValue, nsIRDFNode** aResult);
static nsresult ParseLiteral(nsIRDFResource *arc, const nsString& aValue,
nsIRDFNode** aResult);
static nsresult ParseDate(nsIRDFResource *arc, const nsString& aValue,
nsIRDFNode** aResult);
static nsresult ParseInt(nsIRDFResource *arc, const nsString& aValue,
nsIRDFNode** aResult);
struct Field {
const char *mName;
const char *mResName;
nsresult (*mParse)(nsIRDFResource *arc, const nsString& aValue, nsIRDFNode** aResult);
nsresult (*mParse)(nsIRDFResource *arc, const nsString& aValue,
nsIRDFNode** aResult);
nsIRDFResource* mProperty;
};
@ -110,14 +124,15 @@ protected:
nsCOMPtr<nsIRDFDataSource> mDataSource;
nsCOMPtr<nsIRDFResource> mDirectory;
nsCString mURI;
nsCString mBuf;
PRInt32 mLineStart;
PRBool mHasDescription; // Is there a description entry?
nsresult ProcessData(nsISupports *context);
nsresult ParseFormat(const char* aFormatStr);
nsresult ParseData(nsString* values, const char *baseStr, const char *encodingStr, char* aDataStr, nsIRDFResource *parentRes);
nsresult ParseData(nsString* values, const char *encodingStr, char* aDataStr,
nsIRDFResource *parentRes);
nsAutoString mComment;
@ -151,30 +166,42 @@ nsIRDFService* nsHTTPIndexParser::gRDF;
nsITextToSubURI *nsHTTPIndexParser::gTextToSubURI;
nsIRDFResource* nsHTTPIndexParser::kHTTPIndex_Comment;
nsIRDFResource* nsHTTPIndexParser::kHTTPIndex_Filename;
nsIRDFResource* nsHTTPIndexParser::kHTTPIndex_Description;
nsIRDFResource* nsHTTPIndexParser::kHTTPIndex_Filetype;
nsIRDFResource* nsHTTPIndexParser::kHTTPIndex_Loading;
nsIRDFResource* nsHTTPIndexParser::kHTTPIndex_URL;
nsIRDFResource* nsHTTPIndexParser::kNC_Child;
nsIRDFLiteral* nsHTTPIndexParser::kTrueLiteral;
nsIRDFLiteral* nsHTTPIndexParser::kFalseLiteral;
// This table tells us how to parse the fields in the HTTP-index
// stream into an RDF graph.
nsHTTPIndexParser::Field
nsHTTPIndexParser::gFieldTable[] = {
{ "Filename", "http://home.netscape.com/NC-rdf#Name", nsHTTPIndexParser::ParseLiteral, nsnull },
{ "Content-Length", "http://home.netscape.com/NC-rdf#Content-Length", nsHTTPIndexParser::ParseInt, nsnull },
{ "Last-Modified", "http://home.netscape.com/WEB-rdf#LastModifiedDate", nsHTTPIndexParser::ParseDate, nsnull },
{ "Content-Type", "http://home.netscape.com/NC-rdf#Content-Type", nsHTTPIndexParser::ParseLiteral, nsnull },
{ "File-Type", "http://home.netscape.com/NC-rdf#File-Type", nsHTTPIndexParser::ParseLiteral, nsnull },
{ "Permissions", "http://home.netscape.com/NC-rdf#Permissions", nsHTTPIndexParser::ParseLiteral, nsnull },
{ nsnull, "", nsHTTPIndexParser::ParseLiteral, nsnull },
{ "Filename", "http://home.netscape.com/NC-rdf#Name",
nsHTTPIndexParser::ParseLiteral, nsnull },
{ "Description", "http://home.netscape.com/NC-rdf#Description",
nsHTTPIndexParser::ParseLiteral, nsnull },
{ "Content-Length", "http://home.netscape.com/NC-rdf#Content-Length",
nsHTTPIndexParser::ParseInt, nsnull },
{ "Last-Modified", "http://home.netscape.com/WEB-rdf#LastModifiedDate",
nsHTTPIndexParser::ParseDate, nsnull },
{ "Content-Type", "http://home.netscape.com/NC-rdf#Content-Type",
nsHTTPIndexParser::ParseLiteral, nsnull },
{ "File-Type", "http://home.netscape.com/NC-rdf#File-Type",
nsHTTPIndexParser::ParseLiteral, nsnull },
{ "Permissions", "http://home.netscape.com/NC-rdf#Permissions",
nsHTTPIndexParser::ParseLiteral, nsnull },
{ nsnull, "",
nsHTTPIndexParser::ParseLiteral, nsnull },
};
nsHTTPIndexParser::nsHTTPIndexParser(nsHTTPIndex* aHTTPIndex, nsISupports* aContainer)
nsHTTPIndexParser::nsHTTPIndexParser(nsHTTPIndex* aHTTPIndex,
nsISupports* aContainer)
: mHTTPIndex(aHTTPIndex),
mLineStart(0),
mHasDescription(PR_FALSE),
mContainer(aContainer)
{
NS_INIT_REFCNT();
@ -185,7 +212,7 @@ nsHTTPIndexParser::nsHTTPIndexParser(nsHTTPIndex* aHTTPIndex, nsISupports* aCont
nsresult
nsHTTPIndexParser::Init()
{
NS_PRECONDITION(mHTTPIndex != nsnull, "not initialized");
NS_PRECONDITION(mHTTPIndex, "not initialized");
if (! mHTTPIndex)
return NS_ERROR_NOT_INITIALIZED;
@ -208,24 +235,39 @@ nsHTTPIndexParser::Init()
NS_REINTERPRET_CAST(nsISupports**, &gTextToSubURI));
if (NS_FAILED(rv)) return rv;
rv = gRDF->GetResource(HTTPINDEX_NAMESPACE_URI "Comment", &kHTTPIndex_Comment);
rv = gRDF->GetResource(HTTPINDEX_NAMESPACE_URI "Comment",
&kHTTPIndex_Comment);
if (NS_FAILED(rv)) return rv;
rv = gRDF->GetResource(HTTPINDEX_NAMESPACE_URI "Name", &kHTTPIndex_Filename);
rv = gRDF->GetResource(HTTPINDEX_NAMESPACE_URI "Name",
&kHTTPIndex_Filename);
if (NS_FAILED(rv)) return rv;
rv = gRDF->GetResource(HTTPINDEX_NAMESPACE_URI "Description",
&kHTTPIndex_Description);
if (NS_FAILED(rv)) return rv;
rv = gRDF->GetResource(HTTPINDEX_NAMESPACE_URI "File-Type",
&kHTTPIndex_Filetype);
if (NS_FAILED(rv)) return rv;
rv = gRDF->GetResource(HTTPINDEX_NAMESPACE_URI "File-Type", &kHTTPIndex_Filetype);
rv = gRDF->GetResource(HTTPINDEX_NAMESPACE_URI "loading",
&kHTTPIndex_Loading);
if (NS_FAILED(rv)) return rv;
rv = gRDF->GetResource(HTTPINDEX_NAMESPACE_URI "URL",
&kHTTPIndex_URL);
if (NS_FAILED(rv)) return rv;
rv = gRDF->GetResource(HTTPINDEX_NAMESPACE_URI "loading", &kHTTPIndex_Loading);
rv = gRDF->GetResource(NC_NAMESPACE_URI "child",
&kNC_Child);
if (NS_FAILED(rv)) return rv;
rv = gRDF->GetResource(NC_NAMESPACE_URI "child", &kNC_Child);
rv = gRDF->GetLiteral(NS_LITERAL_STRING("true").get(),
&kTrueLiteral);
if (NS_FAILED(rv)) return rv;
rv = gRDF->GetLiteral(NS_ConvertASCIItoUCS2("true").GetUnicode(), &kTrueLiteral);
if (NS_FAILED(rv)) return rv;
rv = gRDF->GetLiteral(NS_ConvertASCIItoUCS2("false").GetUnicode(), &kFalseLiteral);
rv = gRDF->GetLiteral(NS_LITERAL_STRING("false").get(),
&kFalseLiteral);
if (NS_FAILED(rv)) return rv;
for (Field* field = gFieldTable; field->mName; ++field) {
@ -239,14 +281,15 @@ nsHTTPIndexParser::Init()
}
nsHTTPIndexParser::~nsHTTPIndexParser()
{
if (--gRefCntParser == 0) {
NS_IF_RELEASE(kHTTPIndex_Comment);
NS_IF_RELEASE(kHTTPIndex_Filename);
NS_IF_RELEASE(kHTTPIndex_Description);
NS_IF_RELEASE(kHTTPIndex_Filetype);
NS_IF_RELEASE(kHTTPIndex_Loading);
NS_IF_RELEASE(kHTTPIndex_URL);
NS_IF_RELEASE(kNC_Child);
NS_IF_RELEASE(kTrueLiteral);
NS_IF_RELEASE(kFalseLiteral);
@ -275,7 +318,7 @@ nsHTTPIndexParser::Create(nsHTTPIndex* aHTTPIndex,
nsISupports* aContainer,
nsIStreamListener** aResult)
{
NS_PRECONDITION(aHTTPIndex != nsnull, "null ptr");
NS_PRECONDITION(aHTTPIndex, "null ptr");
if (! aHTTPIndex)
return NS_ERROR_NULL_POINTER;
@ -295,7 +338,9 @@ nsHTTPIndexParser::Create(nsHTTPIndex* aHTTPIndex,
}
NS_IMPL_THREADSAFE_ISUPPORTS2(nsHTTPIndexParser, nsIStreamListener, nsIStreamObserver);
NS_IMPL_THREADSAFE_ISUPPORTS2(nsHTTPIndexParser,
nsIStreamListener,
nsIStreamObserver);
NS_IMETHODIMP
@ -322,7 +367,8 @@ nsHTTPIndexParser::OnStartRequest(nsIRequest *request, nsISupports* aContext)
rv = scriptGlobal->GetContext(getter_AddRefs(context));
NS_ENSURE_TRUE(context, NS_ERROR_FAILURE);
JSContext* jscontext = NS_REINTERPRET_CAST(JSContext*, context->GetNativeContext());
JSContext* jscontext = NS_REINTERPRET_CAST(JSContext*,
context->GetNativeContext());
JSObject* global = JS_GetGlobalObject(jscontext);
// Using XPConnect, wrap the HTTP index object...
@ -331,7 +377,7 @@ nsHTTPIndexParser::OnStartRequest(nsIRequest *request, nsISupports* aContext)
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIXPConnectJSObjectHolder> wrapper;
rv = xpc->WrapNative(jscontext,
rv = xpc->WrapNative(jscontext,
global,
httpindex,
NS_GET_IID(nsIHTTPIndex),
@ -342,7 +388,8 @@ nsHTTPIndexParser::OnStartRequest(nsIRequest *request, nsISupports* aContext)
JSObject* jsobj;
rv = wrapper->GetJSObject(&jsobj);
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get jsobj from xpconnect wrapper");
NS_ASSERTION(NS_SUCCEEDED(rv),
"unable to get jsobj from xpconnect wrapper");
if (NS_FAILED(rv)) return rv;
jsval jslistener = OBJECT_TO_JSVAL(jsobj);
@ -354,32 +401,17 @@ nsHTTPIndexParser::OnStartRequest(nsIRequest *request, nsISupports* aContext)
NS_ASSERTION(ok, "unable to set Listener property");
if (! ok)
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIChannel> aChannel = do_QueryInterface(request);
// Save off some information about the stream we're about to parse.
nsCOMPtr<nsIURI> mDirectoryURI;
rv = aChannel->GetURI(getter_AddRefs(mDirectoryURI));
if (NS_FAILED(rv)) return rv;
nsXPIDLCString uristr;
rv = mDirectoryURI->GetSpec(getter_Copies(uristr));
if (NS_FAILED(rv)) return rv;
// we know that this is a directory (due to being a HTTP-INDEX response)
// so ensure it ends with a slash if its a FTP URL
mURI.Assign(uristr);
if ((mURI.Find("ftp://", PR_TRUE) == 0) && (mURI.Last() != (PRUnichar('/'))))
{
mURI.Append('/');
}
rv = gRDF->GetResource(mURI, getter_AddRefs(mDirectory));
if (NS_FAILED(rv)) return rv;
// Get the directory from the context
mDirectory = do_QueryInterface(aContext);
if (!mDirectory) {
return(NS_ERROR_UNEXPECTED);
}
// Mark the directory as "loading"
rv = mDataSource->Assert(mDirectory, kHTTPIndex_Loading, kTrueLiteral, PR_TRUE);
rv = mDataSource->Assert(mDirectory, kHTTPIndex_Loading,
kTrueLiteral, PR_TRUE);
if (NS_FAILED(rv)) return rv;
return NS_OK;
@ -499,92 +531,70 @@ nsHTTPIndexParser::ProcessData(nsISupports *context)
}
}
PRInt32 numItems = 0;
while(PR_TRUE)
{
++numItems;
PRInt32 eol = mBuf.FindCharInSet("\n\r", mLineStart);
if (eol < 0) break;
mBuf.SetCharAt(PRUnichar('\0'), eol);
const char *line = &mBuf.mStr[mLineStart];
PRInt32 lineLen = eol - mLineStart;
mLineStart = eol + 1;
if (lineLen >= 4)
{
nsresult rv;
const char *buf = line;
if (buf[0] == '1')
{
if (buf[1] == '0')
{
if (buf[2] == '0' && buf[3] == ':')
{
// 100. Human-readable comment line. Ignore
}
else if (buf[2] == '1' && buf[3] == ':')
{
// 101. Human-readable information line.
mComment.AppendWithConversion(buf + 4);
}
else if (buf[2] == '2' && buf[3] == ':')
{
// 102. Human-readable information line, HTML.
mComment.AppendWithConversion(buf + 4);
}
}
}
else if (buf[0] == '2')
{
if (buf[1] == '0')
{
if (buf[2] == '0' && buf[3] == ':')
{
// 200. Define field names
rv = ParseFormat(buf + 4);
if (NS_FAILED(rv))
{
return rv;
}
}
else if (buf[2] == '1' && buf[3] == ':')
{
// 201. Field data
rv = ParseData(values, mURI, encodingStr, ((char *)buf) + 4, parentRes);
if (NS_FAILED(rv))
{
return rv;
}
}
}
}
else if (buf[0] == '3')
{
if (buf[1] == '0')
{
if (buf[2] == '0' && buf[3] == ':')
{
// 300. Self-referring URL
}
}
}
}
}
PRInt32 numItems = 0;
while(PR_TRUE) {
++numItems;
PRInt32 eol = mBuf.FindCharInSet("\n\r", mLineStart);
if (eol < 0) break;
mBuf.SetCharAt(PRUnichar('\0'), eol);
const char *line = &mBuf.mStr[mLineStart];
PRInt32 lineLen = eol - mLineStart;
mLineStart = eol + 1;
if (lineLen >= 4) {
nsresult rv;
const char *buf = line;
if (buf[0] == '1') {
if (buf[1] == '0') {
if (buf[2] == '0' && buf[3] == ':') {
// 100. Human-readable comment line. Ignore
} else if (buf[2] == '1' && buf[3] == ':') {
// 101. Human-readable information line.
mComment.AppendWithConversion(buf + 4);
} else if (buf[2] == '2' && buf[3] == ':') {
// 102. Human-readable information line, HTML.
mComment.AppendWithConversion(buf + 4);
}
}
} else if (buf[0] == '2') {
if (buf[1] == '0') {
if (buf[2] == '0' && buf[3] == ':') {
// 200. Define field names
rv = ParseFormat(buf + 4);
if (NS_FAILED(rv)) {
return rv;
}
} else if (buf[2] == '1' && buf[3] == ':') {
// 201. Field data
rv = ParseData(values, encodingStr, ((char *)buf) + 4, parentRes);
if (NS_FAILED(rv)) {
return rv;
}
}
}
} else if (buf[0] == '3') {
if (buf[1] == '0') {
if (buf[2] == '0' && buf[3] == ':') {
// 300. Self-referring URL
}
}
}
}
}
// If we needed to spill values onto the heap, make sure we clean up
// here.
if (values != autovalues)
delete[] values;
return(NS_OK);
return(NS_OK);
}
nsresult
nsHTTPIndexParser::ParseFormat(const char* aFormatStr)
{
@ -610,6 +620,10 @@ nsHTTPIndexParser::ParseFormat(const char* aFormatStr)
// Okay, we're gonna monkey with the nsStr. Bold!
name.mLength = nsUnescapeCount(name.mStr);
// All tokens are case-insensitive - http://www.area.com/~roeber/file_format.html
if (name.EqualsIgnoreCase("description"))
mHasDescription = PR_TRUE;
Field* field = nsnull;
for (Field* i = gFieldTable; i->mName; ++i) {
if (name.EqualsIgnoreCase(i->mName)) {
@ -624,8 +638,6 @@ nsHTTPIndexParser::ParseFormat(const char* aFormatStr)
return NS_OK;
}
NS_IMETHODIMP
nsHTTPIndex::SetEncoding(const char *encoding)
{
@ -633,29 +645,23 @@ nsHTTPIndex::SetEncoding(const char *encoding)
return(NS_OK);
}
NS_IMETHODIMP
nsHTTPIndex::GetEncoding(char **encoding)
{
NS_PRECONDITION(encoding != nsnull, "null ptr");
if (! encoding)
return(NS_ERROR_NULL_POINTER);
if ((*encoding = nsXPIDLCString::Copy(mEncoding)) == nsnull)
return(NS_ERROR_OUT_OF_MEMORY);
return(NS_OK);
NS_PRECONDITION(encoding, "null ptr");
if (! encoding)
return(NS_ERROR_NULL_POINTER);
*encoding = nsXPIDLCString::Copy(mEncoding);
if (!*encoding)
return(NS_ERROR_OUT_OF_MEMORY);
return(NS_OK);
}
nsresult
nsHTTPIndexParser::ParseData(nsString* values, const char *baseStr, const char *encodingStr,
register char* aDataStr, nsIRDFResource *parentRes)
nsHTTPIndexParser::ParseData(nsString* values, const char *encodingStr,
char* aDataStr, nsIRDFResource *parentRes)
{
// Parse a "201" data line, using the field ordering specified in
// mFormat.
@ -672,6 +678,13 @@ nsHTTPIndexParser::ParseData(nsString* values, const char *baseStr, const char *
nsCAutoString filename;
PRBool isDirType = PR_FALSE;
const char* baseStr = nsnull;
parentRes->GetValueConst(&baseStr);
if (! baseStr) {
NS_ERROR("Could not reconstruct base uri\n");
return NS_ERROR_UNEXPECTED;
}
for (PRInt32 i = 0; i < numFormats; ++i) {
// If we've exhausted the data before we run out of fields, just
// bail.
@ -717,7 +730,7 @@ nsHTTPIndexParser::ParseData(nsString* values, const char *baseStr, const char *
{
PRUnichar *result = nsnull;
if (NS_SUCCEEDED(rv = gTextToSubURI->UnEscapeAndConvert(encodingStr, filename,
&result)) && (result))
&result)) && (result))
{
if (nsCRT::strlen(result) > 0)
{
@ -757,39 +770,73 @@ nsHTTPIndexParser::ParseData(nsString* values, const char *baseStr, const char *
}
}
// we found the filename; construct a resource for its entry
nsCAutoString entryuriC(baseStr);
entryuriC.Append(filename);
// if its a directory, make sure it ends with a trailing slash
if (isDirType == PR_TRUE)
{
entryuriC.Append('/');
}
nsCOMPtr<nsIRDFResource> entry;
rv = gRDF->GetResource(entryuriC, getter_AddRefs(entry));
// we found the filename; construct a resource for its entry
nsCAutoString entryuriC(baseStr);
// gopher resource don't point to an entry in the same directory
// like ftp uris. So the entryuriC is just a unique string, while
// the URL attribute is the destination of this element
// The naming scheme for the attributes is taken from the bookmarks
entryuriC.Append(filename);
// if its a directory, make sure it ends with a trailing slash.
// This doesn't matter for gopher, (where directories don't have
// to end in a trailing /), because the filename is used for the URL
// attribute.
if (isDirType == PR_TRUE)
{
entryuriC.Append('/');
}
nsCOMPtr<nsIRDFResource> entry;
rv = gRDF->GetResource(entryuriC, getter_AddRefs(entry));
// At this point, we'll (hopefully) have found the filename and
// constructed a resource for it, stored in entry. So now take a
// second pass through the values and add as statements to the RDF
// datasource.
if (entry && NS_SUCCEEDED(rv)) {
for (PRInt32 indx = 0; indx < numFormats; ++indx) {
Field* field = NS_STATIC_CAST(Field*, mFormat.ElementAt(indx));
// Field* field = NS_REINTERPRET_CAST(Field*, mFormat.ElementAt(indx));
if (! field)
continue;
nsCOMPtr<nsIRDFNode> nodeValue;
rv = (*field->mParse)(field->mProperty, values[indx], getter_AddRefs(nodeValue));
if (NS_FAILED(rv)) break;
if (nodeValue)
{
rv = mDataSource->Assert(entry, field->mProperty, nodeValue, PR_TRUE);
if (entry && NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIRDFLiteral> URLVal;
nsString url;
// For gopher, the target is the filename. We still have to do all
// the above string manipulation though, because we need the entryuric
// as the key for the RDF data source
if (!strncmp(entryuriC, kGopherProtocol, sizeof(kGopherProtocol)-1))
url.AssignWithConversion(filename);
else
url.AssignWithConversion(entryuriC);
rv = gRDF->GetLiteral(url.GetUnicode(), getter_AddRefs(URLVal));
if (NS_SUCCEEDED(rv)) {
mDataSource->Assert(entry, kHTTPIndex_URL, URLVal, PR_TRUE);
for (PRInt32 indx = 0; indx < numFormats; ++indx) {
Field* field = NS_STATIC_CAST(Field*, mFormat.ElementAt(indx));
if (! field)
continue;
if (mHasDescription && field->mProperty == kHTTPIndex_Filename)
continue;
nsCOMPtr<nsIRDFNode> nodeValue;
rv = (*field->mParse)(field->mProperty, values[indx], getter_AddRefs(nodeValue));
if (NS_FAILED(rv)) break;
if (nodeValue) {
// If there is a description entry, prefer that over the filename
if (mHasDescription && field->mProperty == kHTTPIndex_Description) {
rv = mDataSource->Assert(entry, kHTTPIndex_Filename, nodeValue, PR_TRUE);
if (NS_FAILED(rv)) break;
}
rv = mDataSource->Assert(entry, field->mProperty, nodeValue, PR_TRUE);
if (NS_FAILED(rv)) break;
}
}
}
// instead of
// rv = mDataSource->Assert(parentRes, kNC_Child, entry, PR_TRUE);
// if (NS_FAILED(rv)) return rv;
@ -810,11 +857,12 @@ nsHTTPIndexParser::ParseLiteral(nsIRDFResource *arc, const nsString& aValue, nsI
if (arc == kHTTPIndex_Filename)
{
// strip off trailing slash(s) from directory names
// strip off trailing slash(s) from directory names - but not gopher
PRInt32 len = aValue.Length();
if (len > 0)
{
if (aValue[len - 1] == '/')
if (aValue[len - 1] == '/' && aValue.EqualsIgnoreCase(kGopherProtocol,
sizeof(kGopherProtocol)))
{
nsAutoString temp(aValue);
temp.SetLength(len - 1);
@ -886,7 +934,7 @@ nsHTTPIndexParser::ParseInt(nsIRDFResource *arc, const nsString& aValue, nsIRDFN
//
nsHTTPIndex::nsHTTPIndex()
: mContainer(nsnull)
: mContainer(nsnull)
{
NS_INIT_REFCNT();
}
@ -894,7 +942,7 @@ nsHTTPIndex::nsHTTPIndex()
nsHTTPIndex::nsHTTPIndex(nsISupports* aContainer)
: mContainer(aContainer)
: mContainer(aContainer)
{
NS_INIT_REFCNT();
}
@ -908,6 +956,7 @@ nsHTTPIndex::~nsHTTPIndex()
NS_IF_RELEASE(kNC_Child);
NS_IF_RELEASE(kNC_loading);
NS_IF_RELEASE(kNC_URL);
NS_IF_RELEASE(kTrueLiteral);
NS_IF_RELEASE(kFalseLiteral);
@ -954,10 +1003,11 @@ nsHTTPIndex::CommonInit()
mDirRDF->GetResource(NC_NAMESPACE_URI "child", &kNC_Child);
mDirRDF->GetResource(NC_NAMESPACE_URI "loading", &kNC_loading);
mDirRDF->GetResource(NC_NAMESPACE_URI "URL", &kNC_URL);
rv = mDirRDF->GetLiteral(NS_ConvertASCIItoUCS2("true").GetUnicode(), &kTrueLiteral);
rv = mDirRDF->GetLiteral(NS_LITERAL_STRING("true").get(), &kTrueLiteral);
if (NS_FAILED(rv)) return(rv);
rv = mDirRDF->GetLiteral(NS_ConvertASCIItoUCS2("false").GetUnicode(), &kFalseLiteral);
rv = mDirRDF->GetLiteral(NS_LITERAL_STRING("false").get(), &kFalseLiteral);
if (NS_FAILED(rv)) return(rv);
rv = NS_NewISupportsArray(getter_AddRefs(mConnectionList));
@ -1009,7 +1059,6 @@ nsHTTPIndex::Init(nsIURI* aBaseURL)
if (NS_FAILED(rv)) return rv;
mBaseURL.Assign(url);
return NS_OK;
}
@ -1078,7 +1127,41 @@ nsHTTPIndex::CreateListener(nsIStreamListener** _result)
return NS_OK;
}
// This function finds the destination when following a given nsIRDFResource
// If the resource has a URL attribute, we use that. If not, just use
// the uri.
// We'd really like to not have to copy all the time. But because sometimes
// we get a char*, and sometimes a PRUnichar*, we have to copy at some point,
// and this would leak unless we deleted one of them. scc is working on string
// changes which would hide the explicit ASCII vs unicode stuff, and I could just
// return one of them. (see bug 53065). In the meantime, the performance loss in
// copying should be small, especially compared with bug 69185.
//
// Do NOT try to get the destination of a uri in any other way
char* nsHTTPIndex::GetDestination(nsIRDFResource* r) {
// First try the URL attribute
nsCOMPtr<nsIRDFNode> node;
GetTarget(r, kNC_URL, PR_TRUE, getter_AddRefs(node));
nsCOMPtr<nsIRDFLiteral> url;
if (node)
url = do_QueryInterface(node);
char* cUri;
if (!url) {
// copy always - see comments above
r->GetValue(&cUri);
} else {
const PRUnichar* uri;
url->GetValueConst(&uri);
nsCAutoString tmp;
tmp.AssignWithConversion(uri);
cUri = ToNewCString(tmp);
}
return cUri;
}
// rjc: isWellknownContainerURI() decides whether a URI is a container for which,
// when asked (say, by the template builder), we'll make a network connection
@ -1092,25 +1175,45 @@ nsHTTPIndex::CreateListener(nsIStreamListener** _result)
// get double the # of answers we really want... also, "rdf:file" is
// less expensive in terms of both memory usage as well as speed
static const char kFTPProtocol[] = "ftp://";
// We also handle gopher now
// This could be replaced by an RDF attribute (so we don't have to do string
// parsing), set by the parser (using the isDirType flag - we have this
// information already)
// But doing that gave me lots of xpcwrappednative assersions sometimes (not
// always repeatable), plus it doesn't work properly with the personal toolbar
// uris that end up here at startup (from the bookmarks code).
// Maybe just use this as a fallback, and use the attribute for everything
// else? - bbaetz
PRBool
nsHTTPIndex::isWellknownContainerURI(nsIRDFResource *r)
{
PRBool isContainerFlag = PR_FALSE;
const char *uri = nsnull;
r->GetValueConst(&uri);
if ((uri) && (!strncmp(uri, kFTPProtocol, sizeof(kFTPProtocol) - 1)))
{
if (uri[strlen(uri)-1] == '/')
{
isContainerFlag = PR_TRUE;
}
}
return(isContainerFlag);
}
PRBool isContainerFlag = PR_FALSE;
char *uri = nsnull;
// For gopher, we need to follow the URL attribute to get the
// real destination
uri = GetDestination(r);
if ((uri) && (!strncmp(uri, kFTPProtocol, sizeof(kFTPProtocol) - 1)))
{
if (uri[strlen(uri)-1] == '/')
{
isContainerFlag = PR_TRUE;
}
}
if ((uri) && (!strncmp(uri,kGopherProtocol, sizeof(kGopherProtocol)-1))) {
char* pos = PL_strchr(uri+sizeof(kGopherProtocol)-1, '/');
if (pos) {
if (pos == nsnull || *(pos+1) == '\0' || *(pos+1) == '1')
isContainerFlag = PR_TRUE;
}
}
nsMemory::Free(uri);
return(isContainerFlag);
}
NS_IMETHODIMP
@ -1168,7 +1271,7 @@ nsHTTPIndex::GetTarget(nsIRDFResource *aSource, nsIRDFResource *aProperty, PRBoo
*_retval = nsnull;
if (isWellknownContainerURI(aSource) && (aProperty == kNC_Child) && (aTruthValue))
if ((aTruthValue) && (aProperty == kNC_Child) && isWellknownContainerURI(aSource))
{
// fake out the generic builder (i.e. return anything in this case)
// so that search containers never appear to be empty
@ -1199,7 +1302,7 @@ nsHTTPIndex::GetTargets(nsIRDFResource *aSource, nsIRDFResource *aProperty, PRBo
rv = NS_NewEmptyEnumerator(_retval);
}
if (isWellknownContainerURI(aSource) && (aProperty == kNC_Child))
if ((aProperty == kNC_Child) && isWellknownContainerURI(aSource))
{
PRBool doNetworkRequest = PR_TRUE;
if (NS_SUCCEEDED(rv) && (_retval))
@ -1219,7 +1322,7 @@ nsHTTPIndex::GetTargets(nsIRDFResource *aSource, nsIRDFResource *aProperty, PRBo
// by using a global connection list and an immediately-firing timer
if ((doNetworkRequest == PR_TRUE) && (mConnectionList))
{
{
PRInt32 connectionIndex = mConnectionList->IndexOf(aSource);
if (connectionIndex < 0)
{
@ -1271,7 +1374,7 @@ nsHTTPIndex::AddElement(nsIRDFResource *parent, nsIRDFResource *prop, nsIRDFNode
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to create a timer");
if (NS_FAILED(rv)) return(rv);
mTimer->Init(nsHTTPIndex::FireTimer, this, 10,
mTimer->Init(nsHTTPIndex::FireTimer, this, 1,
NS_PRIORITY_LOWEST, NS_TYPE_ONE_SHOT);
// Note: don't addref "this" as we'll cancel the
// timer in the httpIndex destructor
@ -1307,28 +1410,27 @@ nsHTTPIndex::FireTimer(nsITimer* aTimer, void* aClosure)
nsCOMPtr<nsIRDFResource> aSource;
if (isupports) aSource = do_QueryInterface(isupports);
const char *uri = nsnull;
if (aSource) aSource->GetValueConst(&uri);
char* uri = nsnull;
if (aSource) uri = httpIndex->GetDestination(aSource);
nsresult rv = NS_OK;
nsCOMPtr<nsIURI> url;
if (uri)
{
rv = NS_NewURI(getter_AddRefs(url), uri);
}
nsCOMPtr<nsIChannel> channel;
if (NS_SUCCEEDED(rv) && (url))
{
rv = NS_OpenURI(getter_AddRefs(channel), url, nsnull, nsnull);
}
nsCOMPtr<nsIStreamListener> listener;
if (NS_SUCCEEDED(rv) && (channel))
{
rv = httpIndex->CreateListener(getter_AddRefs(listener));
}
if (NS_SUCCEEDED(rv) && (listener))
{
rv = channel->AsyncOpen(listener, aSource);
}
nsCOMPtr<nsIURI> url;
if (uri) {
rv = NS_NewURI(getter_AddRefs(url), uri);
nsMemory::Free(uri);
}
nsCOMPtr<nsIChannel> channel;
if (NS_SUCCEEDED(rv) && (url)) {
rv = NS_OpenURI(getter_AddRefs(channel), url, nsnull, nsnull);
}
nsCOMPtr<nsIStreamListener> listener;
if (NS_SUCCEEDED(rv) && (channel)) {
rv = httpIndex->CreateListener(getter_AddRefs(listener));
}
if (NS_SUCCEEDED(rv) && (listener)) {
rv = channel->AsyncOpen(listener, aSource);
}
}
}
httpIndex->mConnectionList->Clear();

View File

@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
/* -*- 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
@ -76,6 +76,7 @@ private:
nsIRDFResource *kNC_Child;
nsIRDFResource *kNC_loading;
nsIRDFResource *kNC_URL;
nsIRDFLiteral *kTrueLiteral;
nsIRDFLiteral *kFalseLiteral;
@ -100,7 +101,10 @@ protected:
nsresult CommonInit(void);
nsresult Init(nsIURI* aBaseURL);
PRBool isWellknownContainerURI(nsIRDFResource *r);
static void FireTimer(nsITimer* aTimer, void* aClosure);
// Get the destination of the nsIRDFResource
char* GetDestination(nsIRDFResource *r);
static void FireTimer(nsITimer* aTimer, void* aClosure);
public:
nsHTTPIndex();

View File

@ -23,6 +23,8 @@ function DoEnabling()
var i;
var ftp = document.getElementById("networkProxyFTP");
var ftpPort = document.getElementById("networkProxyFTP_Port");
var gopher = document.getElementById("networkProxyGopher");
var gopherPort = document.getElementById("networkProxyGopher_Port");
var http = document.getElementById("networkProxyHTTP");
var httpPort = document.getElementById("networkProxyHTTP_Port");
var ssl = document.getElementById("networkProxySSL");
@ -34,7 +36,7 @@ function DoEnabling()
var autoReload = document.getElementById("autoReload");
// convenience arrays
var manual = [ftp, ftpPort, http, httpPort, ssl, sslPort, socks, socksPort, noProxy];
var manual = [ftp, ftpPort, gopher, gopherPort, http, httpPort, ssl, sslPort, socks, socksPort, noProxy];
var auto = [autoURL, autoReload];
// radio buttons

View File

@ -35,7 +35,13 @@
<script type="application/x-javascript">
<![CDATA[
var _elementIDs = ["networkProxyType", "networkProxyFTP", "networkProxyFTP_Port", "networkProxyHTTP", "networkProxyHTTP_Port", "networkProxySSL", "networkProxySSL_Port", "networkProxySOCKS", "networkProxySOCKS_Port", "networkProxyNone", "networkProxyAutoconfigURL"];
var _elementIDs = ["networkProxyType",
"networkProxyFTP", "networkProxyFTP_Port",
"networkProxyGopher", "networkProxyGopher_Port",
"networkProxyHTTP", "networkProxyHTTP_Port",
"networkProxySSL", "networkProxySSL_Port",
"networkProxySOCKS", "networkProxySOCKS_Port",
"networkProxyNone", "networkProxyAutoconfigURL"];
]]>
</script>
@ -73,6 +79,17 @@
prefattribute="value" size="5"/>
</box>
</row>
<row>
<text class="label" value="&gopher.label;" accesskey="&gopher.accesskey;" for="networkProxyGopher"/>
<box autostretch="never">
<textfield id="networkProxyGopher" pref="true" preftype="string" prefstring="network.proxy.gopher"
prefattribute="value" flex="1"/>
<!-- gopher port doesn't have an accesskey because the window needs a redesign - bbaetz -->
<text class="label" value="&port.label;" accesskey="&gopherPort.accesskey;" for="networkProxyGopher_Port"/>
<textfield id="networkProxyGopher_Port" pref="true" preftype="int" prefstring="network.proxy.gopher_port"
prefattribute="value" size="5"/>
</box>
</row>
<row>
<text class="label" value="&http.label;" accesskey="&http.accesskey;" for="networkProxyHTTP"/>
<box autostretch="never">

View File

@ -17,6 +17,8 @@
<!ENTITY reload.accesskey "l">
<!ENTITY ftp.label "FTP Proxy:">
<!ENTITY ftp.accesskey "f">
<!ENTITY gopher.label "Gopher Proxy:">
<!ENTITY gopher.accesskey "g">
<!ENTITY http.label "HTTP Proxy:">
<!ENTITY http.accesskey "h">
<!ENTITY ssl.label "SSL Proxy:">
@ -25,6 +27,8 @@
<!ENTITY socks.accesskey "c">
<!ENTITY port.label "Port:">
<!ENTITY FTPport.accesskey "p">
<!-- No accesskey for gopher (':' doesn't go well) - mpt's going to redesign the window -->
<!ENTITY gopherPort.accesskey "">
<!ENTITY HTTPport.accesskey "o">
<!ENTITY SSLport.accesskey "r">
<!ENTITY SOCKSport.accesskey "t">

View File

@ -47,6 +47,7 @@ static NS_DEFINE_CID(kStandardURLCID, NS_STANDARDURL_CID);
static char * ignoreArray[] = {
"http://",
"ftp://",
"gopher://",
"www.",
"http://www.",
"https://",