1998-05-22 23:38:40 +00:00
|
|
|
/* -*- 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.0 (the "NPL"); you may not use this file except in
|
|
|
|
* compliance with the NPL. You may obtain a copy of the NPL at
|
|
|
|
* http://www.mozilla.org/NPL/
|
|
|
|
*
|
|
|
|
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
|
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
|
|
|
* for the specific language governing rights and limitations under the
|
|
|
|
* NPL.
|
|
|
|
*
|
|
|
|
* The Initial Developer of this code under the NPL is Netscape
|
|
|
|
* Communications Corporation. Portions created by Netscape are
|
|
|
|
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
|
|
|
* Reserved.
|
|
|
|
*/
|
|
|
|
|
1998-07-13 23:43:13 +00:00
|
|
|
#include "nsRepository.h"
|
1998-07-29 06:01:11 +00:00
|
|
|
#include "nsITimer.h"
|
1998-05-22 23:38:40 +00:00
|
|
|
#include "nsNetService.h"
|
|
|
|
#include "nsNetStream.h"
|
|
|
|
#include "net.h"
|
1998-07-13 23:43:13 +00:00
|
|
|
extern "C" {
|
|
|
|
#include "mkutils.h"
|
|
|
|
#include "mkgeturl.h"
|
1998-05-22 23:38:40 +00:00
|
|
|
#include "mktrace.h"
|
1998-07-13 23:43:13 +00:00
|
|
|
#include "mkstream.h"
|
|
|
|
#include "cvchunk.h"
|
|
|
|
};
|
|
|
|
#include "netcache.h"
|
1998-07-25 00:32:32 +00:00
|
|
|
#include "cookies.h"
|
1998-07-01 23:56:20 +00:00
|
|
|
#include "plstr.h"
|
1998-05-22 23:38:40 +00:00
|
|
|
|
1998-06-04 05:09:32 +00:00
|
|
|
#include "nsString.h"
|
1998-05-22 23:38:40 +00:00
|
|
|
#include "nsIProtocolConnection.h"
|
1998-07-01 23:56:20 +00:00
|
|
|
#include "nsINetContainerApplication.h"
|
1998-05-22 23:38:40 +00:00
|
|
|
|
|
|
|
/* XXX: Legacy definitions... */
|
1998-07-29 06:01:11 +00:00
|
|
|
// Global count of active urls from mkgeturl.c
|
|
|
|
extern "C" int NET_TotalNumberOfProcessingURLs;
|
|
|
|
|
1998-07-21 20:27:59 +00:00
|
|
|
MWContext *new_stub_context(URL_Struct *URL_s);
|
1998-05-22 23:38:40 +00:00
|
|
|
void free_stub_context(MWContext *window_id);
|
1998-06-24 01:17:51 +00:00
|
|
|
static void bam_exit_routine(URL_Struct *URL_s, int status, MWContext *window_id);
|
1998-05-22 23:38:40 +00:00
|
|
|
|
1998-08-25 05:51:40 +00:00
|
|
|
#if defined(XP_WIN)
|
|
|
|
nsresult PerformNastyWindowsAsyncDNSHack(URL_Struct* URL_s, nsIURL* aURL);
|
|
|
|
#endif /* XP_WIN */
|
|
|
|
|
1998-05-22 23:38:40 +00:00
|
|
|
extern "C" {
|
1998-05-29 23:04:49 +00:00
|
|
|
#include "fileurl.h"
|
|
|
|
#include "httpurl.h"
|
|
|
|
#include "ftpurl.h"
|
|
|
|
#include "abouturl.h"
|
|
|
|
#include "gophurl.h"
|
|
|
|
#include "fileurl.h"
|
|
|
|
#include "remoturl.h"
|
|
|
|
#include "netcache.h"
|
|
|
|
|
1998-06-02 00:23:17 +00:00
|
|
|
#if defined(XP_WIN) || defined(XP_OS2)
|
1998-05-22 23:38:40 +00:00
|
|
|
extern char *XP_AppCodeName;
|
|
|
|
extern char *XP_AppVersion;
|
1998-07-02 22:34:46 +00:00
|
|
|
extern char *XP_AppName;
|
|
|
|
extern char *XP_AppLanguage;
|
|
|
|
extern char *XP_AppPlatform;
|
1998-06-02 00:23:17 +00:00
|
|
|
#else
|
|
|
|
extern const char *XP_AppCodeName;
|
|
|
|
extern const char *XP_AppVersion;
|
1998-07-02 22:34:46 +00:00
|
|
|
extern const char *XP_AppName;
|
|
|
|
extern const char *XP_AppLanguage;
|
|
|
|
extern const char *XP_AppPlatform;
|
1998-06-02 00:23:17 +00:00
|
|
|
#endif
|
1998-07-13 23:43:13 +00:00
|
|
|
|
1998-07-15 18:44:26 +00:00
|
|
|
extern "C" void RL_Init();
|
|
|
|
|
1998-07-13 23:43:13 +00:00
|
|
|
PUBLIC NET_StreamClass *
|
|
|
|
NET_NGLayoutConverter(FO_Present_Types format_out,
|
|
|
|
void *converter_obj,
|
|
|
|
URL_Struct *URL_s,
|
|
|
|
MWContext *context);
|
1998-05-22 23:38:40 +00:00
|
|
|
};
|
|
|
|
|
1998-05-29 23:04:49 +00:00
|
|
|
/*
|
|
|
|
* Initialize our protocols
|
|
|
|
*/
|
|
|
|
|
|
|
|
extern "C" void NET_ClientProtocolInitialize()
|
|
|
|
{
|
|
|
|
NET_InitFileProtocol();
|
|
|
|
NET_InitHTTPProtocol();
|
|
|
|
NET_InitMemCacProtocol();
|
|
|
|
NET_InitFTPProtocol();
|
|
|
|
NET_InitAboutProtocol();
|
|
|
|
NET_InitGopherProtocol();
|
|
|
|
NET_InitRemoteProtocol();
|
|
|
|
}
|
|
|
|
|
1998-05-22 23:38:40 +00:00
|
|
|
static NS_DEFINE_IID(kIProtocolConnectionIID, NS_IPROTOCOLCONNECTION_IID);
|
1998-07-01 23:56:20 +00:00
|
|
|
static NS_DEFINE_IID(kINetContainerApplicationIID, NS_INETCONTAINERAPPLICATION_IID);
|
1998-05-22 23:38:40 +00:00
|
|
|
|
1998-07-01 23:56:20 +00:00
|
|
|
nsNetlibService::nsNetlibService(nsINetContainerApplication *aContainerApp)
|
1998-05-22 23:38:40 +00:00
|
|
|
{
|
|
|
|
NS_INIT_REFCNT();
|
|
|
|
|
1998-07-21 20:27:59 +00:00
|
|
|
/*
|
|
|
|
m_stubContext = new_stub_context();
|
|
|
|
*/
|
1998-05-22 23:38:40 +00:00
|
|
|
|
|
|
|
/* Initialize netlib with 32 sockets... */
|
|
|
|
NET_InitNetLib(0, 32);
|
|
|
|
|
1998-07-02 19:44:56 +00:00
|
|
|
/* Initialize the file extension -> content-type mappings */
|
|
|
|
NET_InitFileFormatTypes(nsnull, nsnull);
|
|
|
|
|
1998-07-13 23:43:13 +00:00
|
|
|
NET_FinishInitNetLib();
|
|
|
|
|
|
|
|
NET_RegisterContentTypeConverter("*", FO_CACHE_AND_NGLAYOUT, NULL,
|
|
|
|
NET_CacheConverter);
|
|
|
|
NET_RegisterContentTypeConverter("*", FO_NGLAYOUT, NULL,
|
|
|
|
NET_NGLayoutConverter);
|
1998-07-21 20:27:59 +00:00
|
|
|
NET_RegisterContentTypeConverter(APPLICATION_HTTP_INDEX, FO_NGLAYOUT,
|
|
|
|
NULL, NET_HTTPIndexFormatToHTMLConverter);
|
1998-07-13 23:43:13 +00:00
|
|
|
|
|
|
|
NET_RegisterUniversalEncodingConverter("chunked",
|
|
|
|
NULL,
|
|
|
|
NET_ChunkedDecoderStream);
|
|
|
|
|
1998-07-29 06:01:11 +00:00
|
|
|
mPollingTimer = nsnull;
|
1998-07-15 18:44:26 +00:00
|
|
|
RL_Init();
|
|
|
|
|
1998-07-01 23:56:20 +00:00
|
|
|
mContainer = aContainerApp;
|
|
|
|
NS_IF_ADDREF(mContainer);
|
|
|
|
if (NULL != mContainer) {
|
|
|
|
nsAutoString str;
|
|
|
|
|
|
|
|
mContainer->GetAppCodeName(str);
|
|
|
|
XP_AppCodeName = str.ToNewCString();
|
|
|
|
mContainer->GetAppVersion(str);
|
|
|
|
XP_AppVersion = str.ToNewCString();
|
|
|
|
mContainer->GetAppName(str);
|
|
|
|
XP_AppName = str.ToNewCString();
|
|
|
|
mContainer->GetPlatform(str);
|
|
|
|
XP_AppPlatform = str.ToNewCString();
|
|
|
|
mContainer->GetLanguage(str);
|
|
|
|
XP_AppLanguage = str.ToNewCString();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// XXX: Where should the defaults really come from
|
|
|
|
XP_AppCodeName = PL_strdup("Mozilla");
|
|
|
|
XP_AppVersion = PL_strdup("5.0 Netscape/5.0 (Windows;I;x86;en)");
|
|
|
|
XP_AppName = PL_strdup("Netscape");
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XXX: Some of these should come from resources and/or
|
|
|
|
* platform-specific code.
|
|
|
|
*/
|
|
|
|
XP_AppLanguage = PL_strdup("en");
|
|
|
|
#ifdef XP_WIN
|
|
|
|
XP_AppPlatform = PL_strdup("Win32");
|
|
|
|
#elif defined(XP_MAC)
|
|
|
|
XP_AppPlatform = PL_strdup("MacPPC");
|
|
|
|
#elif defined(XP_UNIX)
|
|
|
|
/* XXX: Need to differentiate between various Unisys */
|
|
|
|
XP_AppPlatform = PL_strdup("Unix");
|
|
|
|
#endif
|
|
|
|
}
|
1998-05-22 23:38:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NS_DEFINE_IID(kINetServiceIID, NS_INETSERVICE_IID);
|
|
|
|
NS_IMPL_ISUPPORTS(nsNetlibService,kINetServiceIID);
|
|
|
|
|
|
|
|
|
|
|
|
nsNetlibService::~nsNetlibService()
|
|
|
|
{
|
|
|
|
TRACEMSG(("nsNetlibService is being destroyed...\n"));
|
|
|
|
|
1998-07-21 20:27:59 +00:00
|
|
|
/*
|
|
|
|
if (NULL != m_stubContext) {
|
1998-05-22 23:38:40 +00:00
|
|
|
free_stub_context((MWContext *)m_stubContext);
|
|
|
|
m_stubContext = NULL;
|
1998-07-21 20:27:59 +00:00
|
|
|
}
|
|
|
|
*/
|
1998-08-18 23:24:28 +00:00
|
|
|
|
1998-07-29 06:01:11 +00:00
|
|
|
NS_IF_RELEASE(mPollingTimer);
|
1998-07-01 23:56:20 +00:00
|
|
|
NS_IF_RELEASE(mContainer);
|
1998-05-22 23:38:40 +00:00
|
|
|
NET_ShutdownNetLib();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nsresult nsNetlibService::OpenStream(nsIURL *aUrl,
|
1998-07-21 20:27:59 +00:00
|
|
|
nsIStreamListener *aConsumer)
|
1998-05-22 23:38:40 +00:00
|
|
|
{
|
|
|
|
URL_Struct *URL_s;
|
|
|
|
nsConnectionInfo *pConn;
|
|
|
|
nsIProtocolConnection *pProtocol;
|
|
|
|
nsresult result;
|
1998-08-19 23:00:15 +00:00
|
|
|
NET_ReloadMethod reloadType;
|
1998-05-22 23:38:40 +00:00
|
|
|
|
|
|
|
if ((NULL == aConsumer) || (NULL == aUrl)) {
|
|
|
|
return NS_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Create the nsConnectionInfo object... */
|
|
|
|
pConn = new nsConnectionInfo(aUrl, NULL, aConsumer);
|
|
|
|
if (NULL == pConn) {
|
|
|
|
return NS_FALSE;
|
|
|
|
}
|
|
|
|
pConn->AddRef();
|
|
|
|
|
1998-08-18 23:24:28 +00:00
|
|
|
/* We've got a nsConnectionInfo(), now hook it up
|
|
|
|
* to the nsISupports of the nsIContentViewerContainer
|
|
|
|
*/
|
|
|
|
pConn->pContainer = aUrl->GetContainer();
|
|
|
|
if(pConn->pContainer) {
|
|
|
|
NS_ADDREF(pConn->pContainer);
|
|
|
|
}
|
|
|
|
|
1998-05-22 23:38:40 +00:00
|
|
|
/* Create the URLStruct... */
|
1998-08-19 23:00:15 +00:00
|
|
|
|
|
|
|
/* Set the NET_ReloadMethod to correspond with what we've
|
|
|
|
* been asked to do.
|
|
|
|
*
|
|
|
|
* 0 = nsReload (normal)
|
|
|
|
* 1 = nsReloadBypassCache
|
|
|
|
* 2 = nsReloadBypassProxy
|
|
|
|
*/
|
|
|
|
if (aUrl->GetReloadType() == 1)
|
|
|
|
reloadType = NET_SUPER_RELOAD;
|
|
|
|
else
|
|
|
|
reloadType = NET_NORMAL_RELOAD;
|
|
|
|
URL_s = NET_CreateURLStruct(aUrl->GetSpec(), reloadType);
|
1998-05-22 23:38:40 +00:00
|
|
|
if (NULL == URL_s) {
|
|
|
|
pConn->Release();
|
|
|
|
return NS_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Mark the URL as background loading. This prevents many
|
|
|
|
* client upcall notifications...
|
|
|
|
*/
|
1998-06-02 20:17:17 +00:00
|
|
|
URL_s->load_background = FALSE;
|
1998-05-22 23:38:40 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Attach the Data Consumer to the URL_Struct.
|
|
|
|
*
|
|
|
|
* Both the Data Consumer and the URL_Struct are freed in the
|
|
|
|
* bam_exit_routine(...)
|
|
|
|
*
|
|
|
|
* The Reference count on pConn is already 1 so no AddRef() is necessary.
|
|
|
|
*/
|
|
|
|
URL_s->fe_data = pConn;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Give the protocol a chance to initialize any URL_Struct fields...
|
|
|
|
*
|
|
|
|
* XXX: Currently the return value form InitializeURLInfo(...) is
|
|
|
|
* ignored... Should the connection abort if it fails?
|
|
|
|
*/
|
1998-07-21 20:27:59 +00:00
|
|
|
result = aUrl->QueryInterface(kIProtocolConnectionIID, (void**)&pProtocol);
|
|
|
|
if (NS_OK == result) {
|
|
|
|
pProtocol->InitializeURLInfo(URL_s);
|
|
|
|
NS_RELEASE(pProtocol);
|
|
|
|
}
|
|
|
|
|
|
|
|
MWContext *stubContext = new_stub_context(URL_s);
|
1998-05-22 23:38:40 +00:00
|
|
|
/* Start the URL load... */
|
1998-07-21 20:27:59 +00:00
|
|
|
/*
|
|
|
|
NET_GetURL (URL_s, // URL_Struct
|
|
|
|
FO_CACHE_AND_NGLAYOUT, // FO_Present_type
|
|
|
|
(MWContext *)m_stubContext, // MWContext
|
|
|
|
bam_exit_routine); // Exit routine...
|
|
|
|
*/
|
1998-05-22 23:38:40 +00:00
|
|
|
NET_GetURL (URL_s, /* URL_Struct */
|
1998-07-13 23:43:13 +00:00
|
|
|
FO_CACHE_AND_NGLAYOUT, /* FO_Present_type */
|
1998-07-21 20:27:59 +00:00
|
|
|
(MWContext *)stubContext, /* MWContext */
|
1998-05-22 23:38:40 +00:00
|
|
|
bam_exit_routine); /* Exit routine... */
|
|
|
|
|
|
|
|
/* Remember, the URL_s may have been freed ! */
|
|
|
|
|
1998-07-29 06:01:11 +00:00
|
|
|
/*
|
|
|
|
* Start the network timer to call NET_PollSockets(...) until the
|
|
|
|
* URL has been completely loaded...
|
|
|
|
*/
|
|
|
|
SchedulePollingTimer();
|
1998-05-22 23:38:40 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nsresult nsNetlibService::OpenBlockingStream(nsIURL *aUrl,
|
|
|
|
nsIStreamListener *aConsumer,
|
|
|
|
nsIInputStream **aNewStream)
|
|
|
|
{
|
|
|
|
URL_Struct *URL_s;
|
|
|
|
nsConnectionInfo *pConn;
|
|
|
|
nsNetlibStream *pBlockingStream;
|
|
|
|
nsIProtocolConnection *pProtocol;
|
|
|
|
nsresult result;
|
|
|
|
|
|
|
|
|
|
|
|
if (NULL == aNewStream) {
|
|
|
|
return NS_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (NULL != aUrl) {
|
|
|
|
/* Create the blocking stream... */
|
|
|
|
pBlockingStream = new nsBlockingStream();
|
1998-08-19 23:00:15 +00:00
|
|
|
NET_ReloadMethod reloadType;
|
|
|
|
|
1998-05-22 23:38:40 +00:00
|
|
|
if (NULL == pBlockingStream) {
|
|
|
|
goto loser;
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
* AddRef the new stream in anticipation of returning it... This will
|
|
|
|
* keep it alive :-)
|
|
|
|
*/
|
|
|
|
pBlockingStream->AddRef();
|
|
|
|
|
|
|
|
/* Create the nsConnectionInfo object... */
|
|
|
|
pConn = new nsConnectionInfo(aUrl, pBlockingStream, aConsumer);
|
|
|
|
if (NULL == pConn) {
|
|
|
|
pBlockingStream->Release();
|
|
|
|
goto loser;
|
|
|
|
}
|
|
|
|
pConn->AddRef();
|
|
|
|
|
1998-08-18 23:24:28 +00:00
|
|
|
/* We've got a nsConnectionInfo(), now hook it up
|
|
|
|
* to the nsISupports of the nsIContentViewerContainer
|
|
|
|
*/
|
|
|
|
pConn->pContainer = aUrl->GetContainer();
|
|
|
|
if(pConn->pContainer) {
|
|
|
|
NS_ADDREF(pConn->pContainer);
|
|
|
|
}
|
|
|
|
|
1998-05-22 23:38:40 +00:00
|
|
|
/* Create the URLStruct... */
|
1998-08-19 23:00:15 +00:00
|
|
|
|
|
|
|
/* Set the NET_ReloadMethod to correspond with what we've
|
|
|
|
* been asked to do.
|
|
|
|
*
|
|
|
|
* 0 = nsReload (normal)
|
|
|
|
* 1 = nsReloadBypassCache
|
|
|
|
* 2 = nsReloadBypassProxy
|
|
|
|
*/
|
|
|
|
if (aUrl->GetReloadType() == 1)
|
|
|
|
reloadType = NET_SUPER_RELOAD;
|
|
|
|
else
|
|
|
|
reloadType = NET_NORMAL_RELOAD;
|
|
|
|
|
|
|
|
URL_s = NET_CreateURLStruct(aUrl->GetSpec(), reloadType);
|
1998-05-22 23:38:40 +00:00
|
|
|
if (NULL == URL_s) {
|
|
|
|
pBlockingStream->Release();
|
|
|
|
pConn->Release();
|
|
|
|
goto loser;
|
|
|
|
}
|
|
|
|
|
1998-08-25 05:51:40 +00:00
|
|
|
#if defined(XP_WIN)
|
|
|
|
/*
|
|
|
|
* When opening a blocking HTTP stream, perform a synchronous DNS
|
|
|
|
* lookup now, to avoid netlib from doing an async lookup later
|
|
|
|
* and causing a deadlock!
|
|
|
|
*/
|
|
|
|
result = PerformNastyWindowsAsyncDNSHack(URL_s, aUrl);
|
|
|
|
if (NS_OK != result) {
|
|
|
|
NET_FreeURLStruct(URL_s);
|
|
|
|
pBlockingStream->Release();
|
|
|
|
pConn->Release();
|
|
|
|
goto loser;
|
|
|
|
}
|
|
|
|
#endif /* XP_WIN */
|
|
|
|
|
1998-05-22 23:38:40 +00:00
|
|
|
/*
|
|
|
|
* Mark the URL as background loading. This prevents many
|
|
|
|
* client upcall notifications...
|
|
|
|
*/
|
1998-06-02 20:17:17 +00:00
|
|
|
URL_s->load_background = FALSE;
|
1998-05-22 23:38:40 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Attach the ConnectionInfo object to the URL_Struct.
|
|
|
|
*
|
|
|
|
* Both the ConnectionInfo and the URL_Struct are freed in the
|
|
|
|
* bam_exit_routine(...)
|
|
|
|
* The Reference count on pConn is already 1 so no AddRef() is
|
|
|
|
* necessary.
|
|
|
|
*/
|
|
|
|
URL_s->fe_data = pConn;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Give the protocol a chance to initialize any URL_Struct fields...
|
|
|
|
*
|
|
|
|
* XXX: Currently the return value form InitializeURLInfo(...) is
|
|
|
|
* ignored... Should the connection abort if it fails?
|
|
|
|
*/
|
|
|
|
result = aUrl->QueryInterface(kIProtocolConnectionIID, (void**)&pProtocol);
|
|
|
|
if (NS_OK == result) {
|
|
|
|
pProtocol->InitializeURLInfo(URL_s);
|
|
|
|
NS_RELEASE(pProtocol);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* printf("+++ Loading %s\n", aUrl); */
|
|
|
|
|
1998-07-21 20:27:59 +00:00
|
|
|
MWContext *stubContext = new_stub_context(URL_s);
|
|
|
|
|
1998-05-22 23:38:40 +00:00
|
|
|
/* Start the URL load... */
|
1998-07-21 20:27:59 +00:00
|
|
|
/*
|
|
|
|
NET_GetURL (URL_s, // URL_Struct
|
|
|
|
FO_CACHE_AND_NGLAYOUT, // FO_Present_type
|
|
|
|
(MWContext *)m_stubContext, // MWContext
|
|
|
|
bam_exit_routine); // Exit routine...
|
|
|
|
*/
|
1998-05-22 23:38:40 +00:00
|
|
|
NET_GetURL (URL_s, /* URL_Struct */
|
1998-07-13 23:43:13 +00:00
|
|
|
FO_CACHE_AND_NGLAYOUT, /* FO_Present_type */
|
1998-07-21 20:27:59 +00:00
|
|
|
(MWContext *) stubContext, /* MWContext */
|
1998-05-22 23:38:40 +00:00
|
|
|
bam_exit_routine); /* Exit routine... */
|
|
|
|
|
|
|
|
/* Remember, the URL_s may have been freed ! */
|
|
|
|
|
1998-07-29 06:01:11 +00:00
|
|
|
/*
|
|
|
|
* Start the network timer to call NET_PollSockets(...) until the
|
|
|
|
* URL has been completely loaded...
|
|
|
|
*/
|
|
|
|
SchedulePollingTimer();
|
|
|
|
|
1998-05-22 23:38:40 +00:00
|
|
|
*aNewStream = pBlockingStream;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
loser:
|
|
|
|
*aNewStream = NULL;
|
|
|
|
return NS_FALSE;
|
|
|
|
}
|
|
|
|
|
1998-07-01 23:56:20 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsNetlibService::GetContainerApplication(nsINetContainerApplication **aContainer)
|
|
|
|
{
|
|
|
|
*aContainer = mContainer;
|
|
|
|
|
|
|
|
NS_IF_ADDREF(mContainer);
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsNetlibService::SetContainerApplication(nsINetContainerApplication *aContainer)
|
|
|
|
{
|
|
|
|
NS_IF_RELEASE(mContainer);
|
|
|
|
|
|
|
|
mContainer = aContainer;
|
|
|
|
|
|
|
|
NS_IF_ADDREF(mContainer);
|
|
|
|
|
|
|
|
if (mContainer) {
|
|
|
|
nsAutoString str;
|
|
|
|
|
1998-07-02 01:10:21 +00:00
|
|
|
if (XP_AppCodeName) {
|
|
|
|
PR_Free((void *)XP_AppCodeName);
|
|
|
|
}
|
1998-07-01 23:56:20 +00:00
|
|
|
mContainer->GetAppCodeName(str);
|
|
|
|
XP_AppCodeName = str.ToNewCString();
|
1998-07-02 01:10:21 +00:00
|
|
|
if (XP_AppVersion) {
|
|
|
|
PR_Free((void *)XP_AppVersion);
|
|
|
|
}
|
1998-07-01 23:56:20 +00:00
|
|
|
mContainer->GetAppVersion(str);
|
|
|
|
XP_AppVersion = str.ToNewCString();
|
1998-07-02 01:10:21 +00:00
|
|
|
if (XP_AppName) {
|
|
|
|
PR_Free((void *)XP_AppName);
|
|
|
|
}
|
1998-07-01 23:56:20 +00:00
|
|
|
mContainer->GetAppName(str);
|
|
|
|
XP_AppName = str.ToNewCString();
|
1998-07-02 01:10:21 +00:00
|
|
|
if (XP_AppPlatform) {
|
1998-07-02 17:46:15 +00:00
|
|
|
PR_Free((void *)XP_AppPlatform);
|
1998-07-02 01:10:21 +00:00
|
|
|
}
|
1998-07-01 23:56:20 +00:00
|
|
|
mContainer->GetPlatform(str);
|
|
|
|
XP_AppPlatform = str.ToNewCString();
|
1998-07-02 01:10:21 +00:00
|
|
|
if (XP_AppLanguage) {
|
1998-07-02 17:46:15 +00:00
|
|
|
PR_Free((void *)XP_AppLanguage);
|
1998-07-02 01:10:21 +00:00
|
|
|
}
|
1998-07-01 23:56:20 +00:00
|
|
|
mContainer->GetLanguage(str);
|
|
|
|
XP_AppLanguage = str.ToNewCString();
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1998-07-25 00:32:32 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsNetlibService::GetCookieString(nsIURL *aURL, nsString& aCookie)
|
|
|
|
{
|
|
|
|
// XXX How safe is it to create a stub context without a URL_Struct?
|
|
|
|
MWContext *stubContext = new_stub_context(nsnull);
|
|
|
|
|
|
|
|
const char *spec = aURL->GetSpec();
|
|
|
|
char *cookie = NET_GetCookie(stubContext, (char *)spec);
|
|
|
|
|
|
|
|
if (nsnull != cookie) {
|
|
|
|
aCookie.SetString(cookie);
|
|
|
|
PR_FREEIF(cookie);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
aCookie.SetString("");
|
|
|
|
}
|
|
|
|
|
|
|
|
free_stub_context(stubContext);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsNetlibService::SetCookieString(nsIURL *aURL, const nsString& aCookie)
|
|
|
|
{
|
|
|
|
// XXX How safe is it to create a stub context without a URL_Struct?
|
|
|
|
MWContext *stubContext = new_stub_context(nsnull);
|
|
|
|
|
|
|
|
const char *spec = aURL->GetSpec();
|
|
|
|
char *cookie = aCookie.ToNewCString();
|
|
|
|
|
|
|
|
NET_SetCookieString(stubContext, (char *)spec, cookie);
|
|
|
|
|
1998-08-15 01:53:38 +00:00
|
|
|
delete []cookie;
|
1998-07-25 00:32:32 +00:00
|
|
|
free_stub_context(stubContext);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
1998-05-22 23:38:40 +00:00
|
|
|
|
1998-07-29 06:01:11 +00:00
|
|
|
void nsNetlibService::SchedulePollingTimer()
|
|
|
|
{
|
|
|
|
// If a timer is already active, then do not create another...
|
|
|
|
if (nsnull == mPollingTimer) {
|
|
|
|
if (NS_OK == NS_NewTimer(&mPollingTimer)) {
|
|
|
|
mPollingTimer->Init(nsNetlibService::NetPollSocketsCallback, this, 1000 / 50);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void nsNetlibService::CleanupPollingTimer(nsITimer* aTimer)
|
|
|
|
{
|
|
|
|
NS_PRECONDITION((aTimer == mPollingTimer), "Unknown Timer...");
|
|
|
|
|
|
|
|
NS_RELEASE(mPollingTimer);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void nsNetlibService::NetPollSocketsCallback(nsITimer* aTimer, void* aClosure)
|
|
|
|
{
|
|
|
|
nsNetlibService* inet = (nsNetlibService*)aClosure;
|
|
|
|
|
|
|
|
NS_PRECONDITION((nsnull != inet), "Null pointer");
|
|
|
|
if (nsnull != inet) {
|
|
|
|
(void) NET_PollSockets();
|
|
|
|
|
|
|
|
inet->CleanupPollingTimer(aTimer);
|
|
|
|
// Keep scheduling callbacks as long as there are URLs to process...
|
1998-08-01 09:13:20 +00:00
|
|
|
/// if (0 < NET_TotalNumberOfProcessingURLs) {
|
1998-07-29 06:01:11 +00:00
|
|
|
inet->SchedulePollingTimer();
|
1998-08-01 09:13:20 +00:00
|
|
|
/// }
|
1998-07-29 06:01:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1998-08-25 05:51:40 +00:00
|
|
|
#if defined(XP_WIN)
|
|
|
|
/*
|
|
|
|
* This routine is used to avoid a (hopefully temporary) problem which netlib
|
|
|
|
* has when processing blocking HTTP streams.
|
|
|
|
*
|
|
|
|
* When ASYNC_DNS is enabled, all DNS lookups go through the main message pump,
|
|
|
|
* unfortunately, this is not possible when processing a blocking stream, so
|
|
|
|
* we deadlock :-(
|
|
|
|
*
|
|
|
|
* To avoid this deadlock, we synchronously resolve the hostname and store it
|
|
|
|
* in the little known IPAddressString field of the URL_Struct. This prevents
|
|
|
|
* netlib from doing an Async DNS lookup later...
|
|
|
|
*/
|
|
|
|
nsresult PerformNastyWindowsAsyncDNSHack(URL_Struct *URL_s, nsIURL* aURL)
|
|
|
|
{
|
|
|
|
PRHostEnt hpbuf;
|
|
|
|
char dbbuf[PR_NETDB_BUF_SIZE];
|
|
|
|
PRStatus err;
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
|
|
|
|
/* Only attempt to resolve the hostname for HTTP URLs... */
|
|
|
|
if (0 == PL_strcasecmp("http", aURL->GetProtocol())) {
|
|
|
|
/* Perform a synchronous DNS lookup... */
|
|
|
|
err = PR_GetHostByName(aURL->GetHost(), dbbuf, sizeof(dbbuf), &hpbuf);
|
|
|
|
if (PR_SUCCESS == err) {
|
|
|
|
int a,b,c,d;
|
|
|
|
unsigned char *pc;
|
|
|
|
|
|
|
|
pc = (unsigned char *) hpbuf.h_addr_list[0];
|
|
|
|
|
|
|
|
a = (int) *pc;
|
|
|
|
b = (int) *(++pc);
|
|
|
|
c = (int) *(++pc);
|
|
|
|
d = (int) *(++pc);
|
|
|
|
URL_s->IPAddressString = PR_smprintf("%d.%d.%d.%d", a,b,c,d);
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
* If we fail to resolve a host on a HTTP connection, then abort the
|
|
|
|
* connection to prevent a deadlock...
|
|
|
|
*/
|
|
|
|
rv = NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
#endif /* XP_WIN */
|
|
|
|
|
1998-07-01 23:56:20 +00:00
|
|
|
|
1998-08-22 00:12:54 +00:00
|
|
|
static nsNetlibService *gNetlibService = nsnull;
|
1998-07-01 23:56:20 +00:00
|
|
|
|
1998-08-25 00:04:27 +00:00
|
|
|
//
|
|
|
|
// Class to manage static initialization of the Netlib DLL...
|
|
|
|
//
|
|
|
|
struct nsNetlibInit {
|
|
|
|
nsNetlibInit() {
|
|
|
|
gNetlibService = nsnull;
|
|
|
|
(void) NS_InitINetService(nsnull);
|
|
|
|
}
|
|
|
|
|
|
|
|
~nsNetlibInit() {
|
|
|
|
NS_ShutdownINetService();
|
|
|
|
gNetlibService = nsnull;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
#ifdef XP_MAC
|
|
|
|
static nsNetlibInit* netlibInit = nsnull;
|
|
|
|
#else
|
|
|
|
static nsNetlibInit netlibInit;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
extern "C" {
|
1998-05-22 23:38:40 +00:00
|
|
|
/*
|
|
|
|
* Factory for creating instance of the NetlibService...
|
|
|
|
*/
|
|
|
|
NS_NET nsresult NS_NewINetService(nsINetService** aInstancePtrResult,
|
|
|
|
nsISupports* aOuter)
|
|
|
|
{
|
1998-08-22 00:12:54 +00:00
|
|
|
if (nsnull != aOuter) {
|
1998-05-22 23:38:40 +00:00
|
|
|
return NS_ERROR_NO_AGGREGATION;
|
|
|
|
}
|
|
|
|
|
1998-08-22 00:12:54 +00:00
|
|
|
#ifdef XP_MAC
|
|
|
|
// Perform static initialization...
|
|
|
|
if (nsnull == netlibInit) {
|
|
|
|
netlibInit = new nsNetlibInit;
|
|
|
|
}
|
1998-08-25 00:04:27 +00:00
|
|
|
#endif /* XP_MAC */ // XXX on the mac this never gets shutdown
|
1998-08-22 00:12:54 +00:00
|
|
|
|
|
|
|
// The Netlib Service is created by the nsNetlibInit class...
|
|
|
|
if (nsnull == gNetlibService) {
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
1998-05-22 23:38:40 +00:00
|
|
|
}
|
|
|
|
|
1998-08-22 00:12:54 +00:00
|
|
|
return gNetlibService->QueryInterface(kINetServiceIID, (void**)aInstancePtrResult);
|
1998-07-01 23:56:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_NET nsresult NS_InitINetService(nsINetContainerApplication *aContainer)
|
|
|
|
{
|
|
|
|
/* XXX: For now only allow a single instance of the Netlib Service */
|
1998-08-22 00:12:54 +00:00
|
|
|
if (nsnull == gNetlibService) {
|
|
|
|
gNetlibService = new nsNetlibService(aContainer);
|
|
|
|
if (nsnull == gNetlibService) {
|
1998-07-01 23:56:20 +00:00
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
1998-08-22 00:12:54 +00:00
|
|
|
gNetlibService->SetContainerApplication(aContainer);
|
1998-05-22 23:38:40 +00:00
|
|
|
}
|
|
|
|
|
1998-08-22 00:12:54 +00:00
|
|
|
NS_ADDREF(gNetlibService);
|
1998-07-01 23:56:20 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_NET nsresult NS_ShutdownINetService()
|
|
|
|
{
|
1998-08-22 00:12:54 +00:00
|
|
|
nsNetlibService *service = gNetlibService;
|
1998-07-01 23:56:20 +00:00
|
|
|
|
1998-08-22 00:12:54 +00:00
|
|
|
// Release the container...
|
|
|
|
if (nsnull != service) {
|
|
|
|
gNetlibService->SetContainerApplication(nsnull);
|
|
|
|
NS_RELEASE(service);
|
|
|
|
}
|
1998-07-01 23:56:20 +00:00
|
|
|
return NS_OK;
|
1998-05-22 23:38:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}; /* extern "C" */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This is the generic exit routine for all URLs loaded via the new
|
|
|
|
* BAM APIs...
|
|
|
|
*/
|
|
|
|
static void bam_exit_routine(URL_Struct *URL_s, int status, MWContext *window_id)
|
|
|
|
{
|
|
|
|
TRACEMSG(("bam_exit_routine was called...\n"));
|
|
|
|
|
|
|
|
if (NULL != URL_s) {
|
|
|
|
nsConnectionInfo *pConn = (nsConnectionInfo *)URL_s->fe_data;
|
|
|
|
|
1998-06-01 20:53:01 +00:00
|
|
|
#ifdef NOISY
|
1998-05-22 23:38:40 +00:00
|
|
|
printf("+++ Finished loading %s\n", URL_s->address);
|
1998-06-01 20:53:01 +00:00
|
|
|
#endif
|
1998-05-22 23:38:40 +00:00
|
|
|
PR_ASSERT(pConn);
|
|
|
|
|
|
|
|
/* Release the ConnectionInfo object held in the URL_Struct. */
|
|
|
|
if (pConn) {
|
|
|
|
/*
|
|
|
|
* Normally, the stream is closed when the connection has been
|
|
|
|
* completed. However, if the URL exit proc was called directly
|
|
|
|
* by NET_GetURL(...), then the stream may still be around...
|
|
|
|
*/
|
|
|
|
if (pConn->pNetStream) {
|
|
|
|
pConn->pNetStream->Close();
|
|
|
|
pConn->pNetStream->Release();
|
|
|
|
pConn->pNetStream = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Notify the Data Consumer that the Binding has completed...
|
|
|
|
* Since the Consumer is still available, the stream was never
|
|
|
|
* closed (or possibly created). So, the binding has failed...
|
|
|
|
*/
|
|
|
|
if (pConn->pConsumer) {
|
1998-06-04 05:09:32 +00:00
|
|
|
nsAutoString status;
|
1998-08-18 23:24:28 +00:00
|
|
|
pConn->pConsumer->OnStopBinding(pConn->pURL, NS_BINDING_FAILED, status);
|
1998-05-22 23:38:40 +00:00
|
|
|
pConn->pConsumer->Release();
|
|
|
|
pConn->pConsumer = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Release the nsConnectionInfo object hanging off of the fe_data */
|
|
|
|
URL_s->fe_data = NULL;
|
|
|
|
pConn->Release();
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Delete the URL_Struct... */
|
|
|
|
NET_FreeURLStruct(URL_s);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1998-07-22 00:16:00 +00:00
|
|
|
/*
|
|
|
|
* Ugly hack to free contexts
|
|
|
|
*/
|
|
|
|
|
|
|
|
extern "C" void net_ReleaseContext(MWContext *context)
|
|
|
|
{
|
|
|
|
if (context) {
|
1998-07-29 18:44:23 +00:00
|
|
|
if (context->modular_data) {
|
|
|
|
free_stub_context(context);
|
|
|
|
} else {
|
|
|
|
TRACEMSG(("net_ReleaseContext: not releasing non-modular context"));
|
|
|
|
}
|
1998-07-22 00:16:00 +00:00
|
|
|
}
|
|
|
|
}
|