gecko-dev/network/module/nsStubContext.cpp
valeski%netscape.com f25f2cb5b2 network/module/nsIRefreshUrl.h
Extended the nsIRefreshUrl interface to include a cancel method.

network/module/nsNetService.cpp
1. Added code to hook the nsConnectionInfo object up to the nsISupports pointer in the url being loaded.
2. Removed the redirect logic in bam_exit_routine(). The backend dependency on the front end is gone.

network/module/nsNetStream.cpp
Added initialization/destruction of the nsISupports pointer in the nsConnectionInfo.

network/module/nsNetStream.h
Added the nsISupports member declaration to nsConnectionInfo, and remvoed the redirect member variable.

network/module/nsNetStubs.cpp
FE_SetRefreshURLTimer() routine has been modified so it no longer relies on the pConsumer (i.e. nsDocumentBindInfo) which was causing us to leak it. Now we use the nsISupports pointer in the nsConnectionInfo object to access the nsIRefreshURL interface so we can reload the url.

network/module/nsStubContext.cpp
Modified stub_complete() so we no longer pay attention to the redirect member of the nsConnectionInfo object.

network/module/nsIURL.h
1. Added GetContainer() method to nsIURL which returns the nsISupports pointer of the container for this url.
2. created a new NS_NewURL() routine which takes an nsISupports pointer as a parameter.

network/module/nsURL.cpp
1. Added a new nsURL constructor that takes a nsISupports pointer as a param.
2. Added GetContainer() method and nsISupports pointer initialization/destruction.
1998-08-18 23:24:28 +00:00

689 lines
23 KiB
C++

/* -*- 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.
*/
#include "net.h"
#include "mktrace.h"
#include "structs.h"
#include "ctxtfunc.h"
#include "xp_list.h"
#include "plstr.h"
#include "nsString.h"
#include "nsIStreamListener.h"
#include "nsINetSupport.h"
#include "nsNetStream.h"
/****************************************************************************/
/* Beginning of MWContext Evil!!! */
/* ------------------------------- */
/* */
/* Define a dummy MWContext where all of the upcalls are stubbed out. */
/* */
/****************************************************************************/
PRIVATE int
stub_noop(int x, ...)
{
#ifdef XP_MAC
#pragma unused (x)
#endif
/* DebugBreak(); */
return 0;
}
static nsIStreamListener *getStreamListener(URL_Struct *URL_s)
{
nsIStreamListener *res = NULL;
if (URL_s && URL_s->fe_data) {
/*
* Retrieve the nsConnectionInfo object from the fe_data field
* of the URL_Struct...
*/
nsConnectionInfo *pConn = (nsConnectionInfo *)URL_s->fe_data;
if (pConn) {
res = pConn->pConsumer;
}
}
NS_IF_ADDREF(res);
return res;
}
static nsINetSupport *getNetSupport(URL_Struct *URL_s)
{
nsIStreamListener *isl = getStreamListener(URL_s);
if (isl) {
nsINetSupport *ins;
isl->QueryInterface(kINetSupportIID, (void **) &ins);
isl->Release();
return ins;
}
return NULL;
}
void stub_Alert(MWContext *context,
const char *msg)
{
nsINetSupport *ins;
if (nsnull != (ins = getNetSupport(context->modular_data))) {
nsString str(msg);
ins->Alert(str);
ins->Release();
} else {
printf("Alert: %s", msg);
}
}
extern "C" void FE_Alert(MWContext *context, const char *msg)
{
stub_Alert(context, msg);
}
XP_Bool stub_Confirm(MWContext *context,
const char *msg)
{
nsINetSupport *ins;
if (nsnull != (ins = getNetSupport(context->modular_data))) {
XP_Bool res;
nsString str(msg);
res = ins->Confirm(str);
ins->Release();
return res;
} else {
printf("Confirm: %s", msg);
}
return FALSE;
}
char *stub_Prompt(MWContext *context,
const char *msg,
const char *def)
{
nsINetSupport *ins;
if (nsnull != (ins = getNetSupport(context->modular_data))) {
nsString str(msg);
nsString defStr(def);
nsString res;
if (ins->Prompt(msg, defStr, res)) {
ins->Release();
return res.ToNewCString();
}
ins->Release();
} else {
char buf[256];
printf("%s\n", msg);
printf("Prompt: ");
scanf("%s", buf);
if (PL_strlen(buf)) {
return PL_strdup(buf);
}
}
return NULL;
}
PRIVATE XP_Bool
stub_PromptUsernameAndPassword(MWContext *context,
const char *msg,
char **username,
char **password)
{
nsINetSupport *ins;
if (nsnull != (ins = getNetSupport(context->modular_data))) {
nsString str(msg);
nsString userStr;
nsString pwdStr;
if (ins->PromptUserAndPassword(msg, userStr, pwdStr)) {
ins->Release();
*username = userStr.ToNewCString();
*password = pwdStr.ToNewCString();
return TRUE;
}
ins->Release();
} else {
char buf[256];
printf("%s\n", msg);
printf("Username: ");
scanf("%s", buf);
*username = PL_strdup(buf);
printf("Password: ");
scanf("%s", buf);
*password = PL_strdup(buf);
if (**username) {
return TRUE;
}
PR_FREEIF(*username);
PR_FREEIF(*password);
}
return FALSE;
}
char *stub_PromptPassword(MWContext *context,
const char *msg)
{
nsINetSupport *ins;
if (nsnull != (ins = getNetSupport(context->modular_data))) {
nsString str(msg);
nsString res;
if (ins->PromptPassword(msg, res)) {
ins->Release();
return res.ToNewCString();
}
ins->Release();
} else {
char buf[256];
printf("%s\n", msg);
printf("Password: ");
scanf("%s", buf);
if (PL_strlen(buf)) {
return PL_strdup(buf);
}
}
return NULL;
}
PRIVATE void stub_GraphProgressInit(MWContext *context,
URL_Struct *URL_s,
int32 content_length)
{
nsIStreamListener *pListener;
if (URL_s->load_background)
return;
if (nsnull != (pListener = getStreamListener(URL_s))) {
nsConnectionInfo *pConn = (nsConnectionInfo *) URL_s->fe_data;
pListener->OnProgress(pConn->pURL, 0, content_length);
pListener->Release();
}
}
PRIVATE void stub_GraphProgress(MWContext *context,
URL_Struct *URL_s,
int32 bytes_received,
int32 bytes_since_last_time,
int32 content_length)
{
nsIStreamListener *pListener;
if (URL_s->load_background)
return;
if (nsnull != (pListener = getStreamListener(URL_s))) {
nsConnectionInfo *pConn = (nsConnectionInfo *) URL_s->fe_data;
pListener->OnProgress(pConn->pURL, bytes_received,
content_length);
pListener->Release();
}
}
PRIVATE void stub_GraphProgressDestroy(MWContext *context,
URL_Struct *URL_s,
int32 content_length,
int32 total_bytes_read)
{
/*
* XXX: Currently this function never calls OnProgress(...) because
* netlib calls FE_GraphProgressDestroy(...) after closing the
* stream... So, OnStopBinding(...) has already been called and
* the nsConnectionInfo->pConsumer has been released and NULLed...
*/
nsIStreamListener *pListener;
if (URL_s->load_background)
return;
if (nsnull != (pListener = getStreamListener(URL_s))) {
nsConnectionInfo *pConn = (nsConnectionInfo *) URL_s->fe_data;
pListener->OnProgress(pConn->pURL, total_bytes_read,
content_length);
}
}
PRIVATE void stub_Progress(MWContext *context, const char *msg)
{
nsIStreamListener *pListener;
if (nsnull != (pListener = getStreamListener(context->modular_data))) {
nsConnectionInfo *pConn =
(nsConnectionInfo *) context->modular_data->fe_data;
nsAutoString status(msg);
pListener->OnStatus(pConn->pURL, status);
pListener->Release();
} else {
printf("%s\n", msg);
}
}
PRIVATE void stub_AllConnectionsComplete(MWContext *context)
{
}
#define MAKE_FE_TYPES_PREFIX(func) func##_t
#define MAKE_FE_FUNCS_TYPES
#include "mk_cx_fn.h"
#undef MAKE_FE_FUNCS_TYPES
#define stub_CreateNewDocWindow (CreateNewDocWindow_t)stub_noop
#define stub_LayoutNewDocument (LayoutNewDocument_t)stub_noop
#define stub_SetDocTitle (SetDocTitle_t)stub_noop
#define stub_FinishedLayout (FinishedLayout_t)stub_noop
#define stub_TranslateISOText (TranslateISOText_t)stub_noop
#define stub_GetTextInfo (GetTextInfo_t)stub_noop
#define stub_MeasureText (MeasureText_t)stub_noop
#define stub_GetEmbedSize (GetEmbedSize_t)stub_noop
#define stub_GetJavaAppSize (GetJavaAppSize_t)stub_noop
#define stub_GetFormElementInfo (GetFormElementInfo_t)stub_noop
#define stub_GetFormElementValue (GetFormElementValue_t)stub_noop
#define stub_ResetFormElement (ResetFormElement_t)stub_noop
#define stub_SetFormElementToggle (SetFormElementToggle_t)stub_noop
#define stub_FreeFormElement (FreeFormElement_t)stub_noop
#define stub_FreeImageElement (FreeImageElement_t)stub_noop
#define stub_FreeEmbedElement (FreeEmbedElement_t)stub_noop
#define stub_FreeBuiltinElement (FreeBuiltinElement_t)stub_noop
#define stub_FreeJavaAppElement (FreeJavaAppElement_t)stub_noop
#define stub_CreateEmbedWindow (CreateEmbedWindow_t)stub_noop
#define stub_SaveEmbedWindow (SaveEmbedWindow_t)stub_noop
#define stub_RestoreEmbedWindow (RestoreEmbedWindow_t)stub_noop
#define stub_DestroyEmbedWindow (DestroyEmbedWindow_t)stub_noop
#define stub_HideJavaAppElement (HideJavaAppElement_t)stub_noop
#define stub_FreeEdgeElement (FreeEdgeElement_t)stub_noop
#define stub_FormTextIsSubmit (FormTextIsSubmit_t)stub_noop
#define stub_DisplaySubtext (DisplaySubtext_t)stub_noop
#define stub_DisplayText (DisplayText_t)stub_noop
#define stub_DisplayImage (DisplayImage_t)stub_noop
#define stub_DisplayEmbed (DisplayEmbed_t)stub_noop
#define stub_DisplayBuiltin (DisplayBuiltin_t)stub_noop
#define stub_DisplayJavaApp (DisplayJavaApp_t)stub_noop
#define stub_DisplaySubImage (DisplaySubImage_t)stub_noop
#define stub_DisplayEdge (DisplayEdge_t)stub_noop
#define stub_DisplayTable (DisplayTable_t)stub_noop
#define stub_DisplayCell (DisplayCell_t)stub_noop
#define stub_InvalidateEntireTableOrCell (InvalidateEntireTableOrCell_t)stub_noop
#define stub_DisplayAddRowOrColBorder (DisplayAddRowOrColBorder_t)stub_noop
#define stub_DisplaySubDoc (DisplaySubDoc_t)stub_noop
#define stub_DisplayLineFeed (DisplayLineFeed_t)stub_noop
#define stub_DisplayHR (DisplayHR_t)stub_noop
#define stub_DisplayBullet (DisplayBullet_t)stub_noop
#define stub_DisplayFormElement (DisplayFormElement_t)stub_noop
#define stub_DisplayBorder (DisplayBorder_t)stub_noop
#define stub_UpdateEnableStates (UpdateEnableStates_t)stub_noop
#define stub_DisplayFeedback (DisplayFeedback_t)stub_noop
#define stub_ClearView (ClearView_t)stub_noop
#define stub_SetDocDimension (SetDocDimension_t)stub_noop
#define stub_SetDocPosition (SetDocPosition_t)stub_noop
#define stub_GetDocPosition (GetDocPosition_t)stub_noop
#define stub_BeginPreSection (BeginPreSection_t)stub_noop
#define stub_EndPreSection (EndPreSection_t)stub_noop
#define stub_SetProgressBarPercent (SetProgressBarPercent_t)stub_noop
#define stub_SetBackgroundColor (SetBackgroundColor_t)stub_noop
#define stub_Progress (Progress_t)stub_Progress
#define stub_Alert (Alert_t)stub_Alert
#define stub_SetCallNetlibAllTheTime (SetCallNetlibAllTheTime_t)stub_noop
#define stub_ClearCallNetlibAllTheTime (ClearCallNetlibAllTheTime_t)stub_noop
#define stub_GraphProgressInit (GraphProgressInit_t)stub_GraphProgressInit
#define stub_GraphProgressDestroy (GraphProgressDestroy_t)stub_GraphProgressDestroy
#define stub_GraphProgress (GraphProgress_t)stub_GraphProgress
#define stub_UseFancyFTP (UseFancyFTP_t)stub_noop
#define stub_UseFancyNewsgroupListing (UseFancyNewsgroupListing_t)stub_noop
#define stub_FileSortMethod (FileSortMethod_t)stub_noop
#define stub_ShowAllNewsArticles (ShowAllNewsArticles_t)stub_noop
#define stub_Confirm (Confirm_t)stub_Confirm
#define stub_CheckConfirm (CheckConfirm_t)stub_noop
#define stub_SelectDialog (SelectDialog_t)stub_noop
#define stub_Prompt (Prompt_t)stub_Prompt
#define stub_PromptWithCaption (PromptWithCaption_t)stub_noop
#define stub_PromptUsernameAndPassword (PromptUsernameAndPassword_t)stub_PromptUsernameAndPassword
#define stub_PromptPassword (PromptPassword_t)stub_PromptPassword
#define stub_EnableClicking (EnableClicking_t)stub_noop
#define stub_AllConnectionsComplete (AllConnectionsComplete_t)stub_AllConnectionsComplete
#define stub_ImageSize (ImageSize_t)stub_noop
#define stub_ImageData (ImageData_t)stub_noop
#define stub_ImageIcon (ImageIcon_t)stub_noop
#define stub_ImageOnScreen (ImageOnScreen_t)stub_noop
#define stub_SetColormap (SetColormap_t)stub_noop
#ifdef LAYERS
#define stub_EraseBackground (EraseBackground_t)stub_noop
#define stub_SetDrawable (SetDrawable_t)stub_noop
#define stub_GetTextFrame (GetTextFrame_t)stub_noop
#define stub_SetClipRegion (SetClipRegion_t)stub_noop
#define stub_SetOrigin (SetOrigin_t)stub_noop
#define stub_GetOrigin (GetOrigin_t)stub_noop
#define stub_GetTextFrame (GetTextFrame_t)stub_noop
#endif
#define stub_GetDefaultBackgroundColor (GetDefaultBackgroundColor_t)stub_noop
#define stub_LoadFontResource (LoadFontResource_t)stub_noop
#define stub_DrawJavaApp (DrawJavaApp_t)stub_noop
#define stub_HandleClippingView (HandleClippingView_t)stub_noop
/* Just reuse the same set of context functions: */
ContextFuncs stub_context_funcs;
XP_List *stub_context_list = NULL;
MWContext *new_stub_context(URL_Struct *URL_s)
{
static int funcsInitialized = 0;
MWContext *context;
if (!funcsInitialized) {
#define MAKE_FE_FUNCS_PREFIX(f) stub_##f
#define MAKE_FE_FUNCS_ASSIGN stub_context_funcs.
#include "mk_cx_fn.h"
funcsInitialized = 1;
stub_context_list = XP_ListNew();
}
context = (MWContext *)calloc(sizeof(struct MWContext_), 1);
if (nsnull != context) {
context->funcs = &stub_context_funcs;
context->type = MWContextBrowser;
context->modular_data = URL_s;
if (nsnull != stub_context_list) {
XP_ListAddObjectToEnd(stub_context_list, context);
}
}
return context;
}
void free_stub_context(MWContext *window_id)
{
TRACEMSG(("Freeing stub context...\n"));
if (window_id) {
if (stub_context_list) {
PRBool result;
result = XP_ListRemoveObject(stub_context_list, window_id);
PR_ASSERT(PR_TRUE == result);
}
free(window_id);
}
}
extern "C" MWContext * XP_FindContextOfType (MWContext * context,
MWContextType type)
{
MWContext *window_id;
/*
* Return the context that was passed in if it is the correct type
*/
if (nsnull != context) {
if (context->type == type) {
window_id = context;
}
}
/*
* Otherwise, the type MUST be a MWBrowserContext, since that is the
* only type of context that is created...
*
* Return the first stub context, since it is as good as any... :-)
*/
else if (MWContextBrowser == type) {
window_id = (MWContext *)XP_ListTopObject(stub_context_list);
}
return window_id;
}
/****************************************************************************/
/* End of MWContext Evil!!! */
/****************************************************************************/
nsConnectionInfo *GetConnectionInfoFromStream(NET_StreamClass *stream)
{
URL_Struct *URL_s = (URL_Struct *)stream->data_object;
return (URL_s) ? (nsConnectionInfo *)URL_s->fe_data : NULL;
}
/*
* Define a NET_StreamClass which pushes its data into an nsIStream
* and fires off notifications through the nsIStreamListener interface
*/
void stub_complete(NET_StreamClass *stream)
{
URL_Struct *URL_s = (URL_Struct *)stream->data_object;
nsConnectionInfo *pConn = GetConnectionInfoFromStream(stream);
TRACEMSG(("+++ stream complete.\n"));
/* Close the stream and remove it from the ConnectionInfo... */
pConn->pNetStream->Close();
pConn->pNetStream->Release();
pConn->pNetStream = NULL;
/* Notify the Data Consumer that the Binding has completed... */
if (pConn->pConsumer) {
nsAutoString status;
pConn->pConsumer->OnStopBinding(pConn->pURL, NS_BINDING_SUCCEEDED, status);
pConn->pConsumer->Release();
pConn->pConsumer = NULL;
}
/* Release the URL_Struct hanging off of the data_object */
stream->data_object = NULL;
NET_DropURLStruct(URL_s);
}
void stub_abort(NET_StreamClass *stream, int status)
{
URL_Struct *URL_s = (URL_Struct *)stream->data_object;
nsConnectionInfo *pConn = GetConnectionInfoFromStream(stream);
TRACEMSG(("+++ stream abort. Status = %d\n", status));
/* Close the stream and remove it from the ConnectionInfo... */
pConn->pNetStream->Close();
pConn->pNetStream->Release();
pConn->pNetStream = NULL;
/* Notify the Data Consumer that the Binding has completed... */
/*
* XXX: Currently, there is no difference between complete and
* abort...
*/
if (pConn->pConsumer) {
nsAutoString status;
pConn->pConsumer->OnStopBinding(pConn->pURL, NS_BINDING_ABORTED, status);
pConn->pConsumer->Release();
pConn->pConsumer = NULL;
}
/* Release the URL_Struct hanging off of the data_object */
stream->data_object = NULL;
NET_DropURLStruct(URL_s);
}
int stub_put_block(NET_StreamClass *stream, const char *buffer, int32 length)
{
PRInt32 bytesWritten;
nsresult errorCode;
nsConnectionInfo *pConn = GetConnectionInfoFromStream(stream);
TRACEMSG(("+++ stream put_block. Length = %d\n", length));
/*
* XXX: Sometimes put_block(...) will be called without having
* called is_write_ready(...) first. One case is when a stream
* is interrupted... In this case, Netlib will call put_block(...)
* with the string "Transfer Interrupted!"
*/
errorCode = pConn->pNetStream->Write(buffer, 0, length, &bytesWritten);
/* Abort the connection... */
if (NS_BASE_STREAM_EOF == errorCode) {
return -1;
}
if (pConn->pConsumer && (0 < bytesWritten)) {
errorCode = pConn->pConsumer->OnDataAvailable(pConn->pURL, pConn->pNetStream, bytesWritten);
}
/* Abort the connection if an error occurred... */
if (NS_FAILED(errorCode) || (bytesWritten != length)) {
return -1;
}
return 1;
}
unsigned int stub_is_write_ready(NET_StreamClass *stream)
{
PRInt32 errorCode;
unsigned int free_space = 0;
URL_Struct *URL_s = (URL_Struct *)stream->data_object;
nsConnectionInfo *pConn = GetConnectionInfoFromStream(stream);
free_space = (unsigned int)pConn->pNetStream->GetAvailableSpace(&errorCode);
/*
* If the InputStream has been closed... Return 1 byte available so
* Netlib will call put_block(...) one more time...
*/
if (NS_BASE_STREAM_EOF == errorCode) {
free_space = 1;
}
TRACEMSG(("+++ stream is_write_ready. Returning %d\n", free_space));
return free_space;
}
extern "C" {
/*
*Find a converter routine to create a stream and return the stream struct
*/
PUBLIC NET_StreamClass *
NET_NGLayoutConverter(FO_Present_Types format_out,
void *converter_obj,
URL_Struct *URL_s,
MWContext *context)
{
NET_StreamClass *stream = NULL;
PRBool bSuccess = PR_TRUE;
/*
* Only create a stream if an nsConnectionInfo object is
* available from the fe_data...
*/
if (NULL != URL_s->fe_data) {
stream = (NET_StreamClass *)calloc(sizeof(NET_StreamClass), 1);
if (NULL != stream) {
nsConnectionInfo *pConn;
/*
* Initialize the NET_StreamClass instance...
*/
stream->name = "Stub Stream";
stream->window_id = context;
stream->complete = stub_complete;
stream->abort = stub_abort;
stream->put_block = stub_put_block;
stream->is_write_ready = stub_is_write_ready;
/*
* Retrieve the nsConnectionInfo object from the fe_data field
* of the URL_Struct...
*/
pConn = (nsConnectionInfo *)URL_s->fe_data;
/*
* If the URL address has been rewritten by netlib then update
* the cached info in the URL object...
*/
if ((URL_s->address_modified) && (NULL != pConn->pURL)) {
pConn->pURL->Set(NET_URLStruct_Address(URL_s));
}
/*
* Create an Async stream unless a blocking stream is already
* available in the ConnectionInfo...
*/
if (NULL == pConn->pNetStream) {
pConn->pNetStream = new nsAsyncStream(8192);
if (NULL == pConn->pNetStream) {
free(stream);
return NULL;
}
pConn->pNetStream->AddRef();
}
/* Hang the URL_Struct off of the NET_StreamClass */
NET_HoldURLStruct(URL_s);
stream->data_object = URL_s;
/* Notify the data consumer that Binding is beginning...*/
/* XXX: check result to terminate connection if necessary */
#ifdef NOISY
printf("+++ Created a stream for %s\n", URL_s->address);
#endif
if (pConn->pConsumer) {
nsresult rv;
rv = pConn->pConsumer->OnStartBinding(pConn->pURL, URL_s->content_type);
/*
* If OnStartBinding fails, then tear down the NET_StreamClass
* and release all references...
*/
if (NS_OK != rv) {
NET_DropURLStruct(URL_s);
free(stream);
stream = NULL;
/*
* The NET_GetURL(...) exit_routine will clean up the
* nsConnectionInfo and associated objects.
*/
}
}
}
}
return stream;
}
}; /* extern "C" */