зеркало из https://github.com/mozilla/pjs.git
socket implementation of the transport interface. (not currently being built by checked in makefiles)
This commit is contained in:
Родитель
ec483a05f4
Коммит
26bbd4972f
|
@ -0,0 +1,288 @@
|
||||||
|
/* -*- 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 "nsRepository.h"
|
||||||
|
#include "nsNetStream.h"
|
||||||
|
#include "nsSocketTransport.h"
|
||||||
|
#include "nsINetService.h"
|
||||||
|
#include "nsINetlibURL.h"
|
||||||
|
|
||||||
|
#include "nsIServiceManager.h"
|
||||||
|
#include "nsXPComCIID.h"
|
||||||
|
|
||||||
|
#include "mktcp.h"
|
||||||
|
#include "sockstub.h"
|
||||||
|
|
||||||
|
#include "plstr.h"
|
||||||
|
|
||||||
|
extern nsIStreamListener* ns_NewStreamListenerProxy(nsIStreamListener* aListener, PLEventQueue* aEventQ);
|
||||||
|
static NS_DEFINE_IID(kIOutputStreamIID, NS_IOUTPUTSTREAM_IID);
|
||||||
|
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
||||||
|
static NS_DEFINE_IID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
|
||||||
|
static NS_DEFINE_IID(kIEventQueueServiceIID, NS_IEVENTQUEUESERVICE_IID);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
// from nsISupports
|
||||||
|
|
||||||
|
static NS_DEFINE_IID(kITransportIID, NS_ITRANSPORT_IID);
|
||||||
|
NS_IMPL_ADDREF(nsSocketTransport)
|
||||||
|
NS_IMPL_RELEASE(nsSocketTransport)
|
||||||
|
NS_IMPL_QUERY_INTERFACE(nsSocketTransport, kITransportIID);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
// from nsITransport:
|
||||||
|
|
||||||
|
NS_METHOD
|
||||||
|
nsSocketTransport::GetURL(nsIURL* *result)
|
||||||
|
{
|
||||||
|
*result = m_url;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static NS_DEFINE_IID(kINetlibURLIID, NS_INETLIBURL_IID);
|
||||||
|
|
||||||
|
|
||||||
|
NS_METHOD
|
||||||
|
nsSocketTransport::LoadURL(nsIURL *pURL)
|
||||||
|
{
|
||||||
|
nsresult rv = NS_OK;
|
||||||
|
if (nsnull == pURL) {
|
||||||
|
return NS_ERROR_NULL_POINTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nsnull == m_inputStreamConsumer) {
|
||||||
|
return NS_ERROR_NULL_POINTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_url = pURL;
|
||||||
|
NS_IF_ADDREF(m_url);
|
||||||
|
pURL->SetHostPort(m_port);
|
||||||
|
|
||||||
|
nsresult ns_result = NS_OpenURL(pURL, m_inputStreamConsumer);
|
||||||
|
if (NS_OK != ns_result) {
|
||||||
|
return ns_result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_METHOD
|
||||||
|
nsSocketTransport::SetInputStreamConsumer(nsIStreamListener* aListener)
|
||||||
|
{
|
||||||
|
// generates the thread safe proxy
|
||||||
|
m_inputStreamConsumer = ns_NewStreamListenerProxy(aListener, m_evQueue);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NS_METHOD
|
||||||
|
nsSocketTransport::GetOutputStreamConsumer(nsIStreamListener ** aConsumer)
|
||||||
|
{
|
||||||
|
// assuming the transport layer is a nsIStreamListener
|
||||||
|
*aConsumer = ns_NewStreamListenerProxy(this, m_evQueue);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NS_METHOD
|
||||||
|
nsSocketTransport::GetOutputStream(nsIOutputStream ** aOutputStream)
|
||||||
|
{
|
||||||
|
if (aOutputStream) {
|
||||||
|
// a buffered stream supports the nsIOutputStream interface
|
||||||
|
nsBufferedStream * stream = new nsBufferedStream();
|
||||||
|
if (stream) // return the buffer in the format they want
|
||||||
|
stream->QueryInterface(kIOutputStreamIID, (void **) aOutputStream);
|
||||||
|
else
|
||||||
|
*aOutputStream = NULL;
|
||||||
|
}
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsSocketTransport::OnStartBinding(nsIURL* pURL, const char *aContentType)
|
||||||
|
{
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsSocketTransport::OnProgress(nsIURL* pURL,
|
||||||
|
PRUint32 aProgress,
|
||||||
|
PRUint32 aProgressMax)
|
||||||
|
{
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsSocketTransport::OnStatus(nsIURL* pURL, const PRUnichar* aMsg)
|
||||||
|
{
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsSocketTransport::OnStopBinding(nsIURL* pURL,
|
||||||
|
nsresult aStatus,
|
||||||
|
const PRUnichar* aMsg)
|
||||||
|
{
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsSocketTransport::GetBindInfo(nsIURL* pURL,
|
||||||
|
nsStreamBindingInfo* aInfo)
|
||||||
|
{
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsSocketTransport::OnDataAvailable(nsIURL* pURL,
|
||||||
|
nsIInputStream *aIStream,
|
||||||
|
PRUint32 aLength)
|
||||||
|
{
|
||||||
|
nsresult rv = NS_OK;
|
||||||
|
PRUint32 len, lenRead;
|
||||||
|
URL_Struct* URL_s;
|
||||||
|
m_ready_fd = NULL;
|
||||||
|
|
||||||
|
/* XXX: HACK The following is a hack.
|
||||||
|
* Get the URL_s structure and pass it to sockstub protocol code to get the
|
||||||
|
* socket FD so that we could write the data back.
|
||||||
|
*/
|
||||||
|
rv = GetURLInfo(pURL, &URL_s);
|
||||||
|
|
||||||
|
if (NS_SUCCEEDED(rv)) {
|
||||||
|
if (nsnull != URL_s) {
|
||||||
|
/* Find the socket given URL_s pointer */
|
||||||
|
m_ready_fd = NET_GetSocketToHashTable(URL_s);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_ready_fd == NULL) {
|
||||||
|
return NS_ERROR_NULL_POINTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
aIStream->GetLength(&len);
|
||||||
|
|
||||||
|
memset(m_buffer, '\0', NET_SOCKSTUB_BUF_SIZE);
|
||||||
|
while (len > 0) {
|
||||||
|
if (len < NET_SOCKSTUB_BUF_SIZE) {
|
||||||
|
lenRead = len;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lenRead = NET_SOCKSTUB_BUF_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = aIStream->Read(m_buffer, 0, lenRead, &lenRead);
|
||||||
|
if (NS_OK != rv) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* XXX: We should check if the write has succeeded or not */
|
||||||
|
(int) NET_BlockingWrite(m_ready_fd, m_buffer, lenRead);
|
||||||
|
len -= lenRead;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
// from nsSocketTransport:
|
||||||
|
|
||||||
|
nsSocketTransport::nsSocketTransport(PRUint32 aPortToUse, const char * aHostName)
|
||||||
|
{
|
||||||
|
NS_INIT_REFCNT();
|
||||||
|
|
||||||
|
// remember the port and host name
|
||||||
|
NS_PRECONDITION(aPortToUse > 0 && aHostName, "Creating a socket transport with an invalid port or host name.");
|
||||||
|
m_port = aPortToUse;
|
||||||
|
if (aHostName)
|
||||||
|
m_hostName = PL_strdup(aHostName);
|
||||||
|
else
|
||||||
|
m_hostName = PL_strdup("");
|
||||||
|
|
||||||
|
m_inputStream = NULL;
|
||||||
|
m_inputStreamConsumer = NULL;
|
||||||
|
m_url = NULL;
|
||||||
|
|
||||||
|
m_outStream = NULL;
|
||||||
|
m_outStreamSize = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Cache the EventQueueService...
|
||||||
|
*/
|
||||||
|
// XXX: What if this fails?
|
||||||
|
mEventQService = nsnull;
|
||||||
|
m_evQueue = nsnull;
|
||||||
|
nsresult rv = nsServiceManager::GetService(kEventQueueServiceCID,
|
||||||
|
kIEventQueueServiceIID,
|
||||||
|
(nsISupports **)&mEventQService);
|
||||||
|
|
||||||
|
if (nsnull != mEventQService) {
|
||||||
|
mEventQService->GetThreadEventQueue(PR_GetCurrentThread(), &m_evQueue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nsSocketTransport::~nsSocketTransport()
|
||||||
|
{
|
||||||
|
nsresult rv = NS_OK;
|
||||||
|
URL_Struct* URL_s;
|
||||||
|
|
||||||
|
/* XXX: HACK The following is a hack.
|
||||||
|
* Get the URL_s structure and pass it to sockstub protocol code to delete it
|
||||||
|
*/
|
||||||
|
rv = GetURLInfo(m_url, &URL_s);
|
||||||
|
|
||||||
|
if (NS_SUCCEEDED(rv)) {
|
||||||
|
if (nsnull != URL_s) {
|
||||||
|
/* Release the socket given URL_s pointer */
|
||||||
|
int32 res = NET_FreeSocket(URL_s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_hostName)
|
||||||
|
PR_Free(m_hostName);
|
||||||
|
|
||||||
|
NS_IF_RELEASE(m_outStream);
|
||||||
|
NS_IF_RELEASE(m_url);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsSocketTransport::GetURLInfo(nsIURL* pURL, URL_Struct_ **aResult)
|
||||||
|
{
|
||||||
|
nsresult rv = NS_OK;
|
||||||
|
nsINetlibURL *pNetlibURL = NULL;
|
||||||
|
|
||||||
|
NS_PRECONDITION(aResult != nsnull, "invalid input argument");
|
||||||
|
if (aResult)
|
||||||
|
{
|
||||||
|
*aResult = nsnull;
|
||||||
|
|
||||||
|
rv = pURL->QueryInterface(kINetlibURLIID, (void**)&pNetlibURL);
|
||||||
|
if (NS_SUCCEEDED(rv) && pNetlibURL) {
|
||||||
|
|
||||||
|
pNetlibURL->GetURLInfo(aResult);
|
||||||
|
NS_RELEASE(pNetlibURL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
|
@ -0,0 +1,110 @@
|
||||||
|
/* -*- 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef nsSocketTransport_h__
|
||||||
|
#define nsSocketTransport_h__
|
||||||
|
|
||||||
|
#include "nsRepository.h"
|
||||||
|
#include "nsITransport.h"
|
||||||
|
#include "nsIStreamListener.h"
|
||||||
|
#include "nsIInputStream.h"
|
||||||
|
#include "nsIOutputStream.h"
|
||||||
|
#include "nsIEventQueueService.h"
|
||||||
|
#include "nsAgg.h"
|
||||||
|
#include "nsString.h"
|
||||||
|
|
||||||
|
#define NET_SOCKSTUB_BUF_SIZE 1024
|
||||||
|
|
||||||
|
/* forward declaration */
|
||||||
|
struct URL_Struct_;
|
||||||
|
|
||||||
|
class nsSocketTransport : public nsITransport
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
// from nsISupports:
|
||||||
|
|
||||||
|
NS_DECL_ISUPPORTS
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
// from nsITransport:
|
||||||
|
|
||||||
|
NS_IMETHOD GetURL(nsIURL* *result);
|
||||||
|
|
||||||
|
NS_IMETHOD LoadURL(nsIURL *url);
|
||||||
|
|
||||||
|
NS_IMETHOD SetInputStreamConsumer(nsIStreamListener* aListener);
|
||||||
|
|
||||||
|
NS_IMETHOD GetOutputStreamConsumer(nsIStreamListener ** aConsumer);
|
||||||
|
|
||||||
|
NS_IMETHOD GetOutputStream(nsIOutputStream ** aOutputStream);
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
// from nsIStreamListener:
|
||||||
|
|
||||||
|
NS_IMETHOD OnStartBinding(nsIURL* aURL, const char *aContentType);
|
||||||
|
NS_IMETHOD OnProgress(nsIURL* aURL, PRUint32 aProgress, PRUint32 aProgressMax);
|
||||||
|
NS_IMETHOD OnStatus(nsIURL* aURL, const PRUnichar* aMsg);
|
||||||
|
NS_IMETHOD OnStopBinding(nsIURL* aURL, nsresult aStatus, const PRUnichar* aMsg);
|
||||||
|
NS_IMETHOD GetBindInfo(nsIURL* aURL, nsStreamBindingInfo* aInfo);
|
||||||
|
NS_IMETHOD OnDataAvailable(nsIURL* aURL, nsIInputStream *aIStream,
|
||||||
|
PRUint32 aLength);
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
// nsSocketTransport:
|
||||||
|
|
||||||
|
nsSocketTransport(PRUint32 aPortToUse, const char * aHostName);
|
||||||
|
virtual ~nsSocketTransport(void);
|
||||||
|
NS_IMETHOD GetURLInfo(nsIURL* pURL, URL_Struct_ **aResult);
|
||||||
|
|
||||||
|
// the following routines are called by the sock stub protocol hack....
|
||||||
|
// we should be able to remove this dependency once we move things to the new
|
||||||
|
// net lib world...
|
||||||
|
PRUint32 GetPort() {return m_port;}
|
||||||
|
const char * GetHostName() { return m_hostName;}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// socket specific information...
|
||||||
|
PRUint32 m_port;
|
||||||
|
char *m_hostName;
|
||||||
|
|
||||||
|
// the stream we write data from the socket into
|
||||||
|
nsIInputStream * m_inputStream;
|
||||||
|
|
||||||
|
// XXX sock stub hack..need to remember stream with data to be written to the socket
|
||||||
|
nsIInputStream * m_outStream;
|
||||||
|
PRUint32 m_outStreamSize;
|
||||||
|
|
||||||
|
// the proxied stream listener. Whenever the transport layer
|
||||||
|
// writes socket date to input stream, it calls OnDataAvailable
|
||||||
|
// through the inputStreamConsumer any socket specific data
|
||||||
|
nsIStreamListener *m_inputStreamConsumer;
|
||||||
|
|
||||||
|
nsIURL *m_url;
|
||||||
|
nsString* mData;
|
||||||
|
PRFileDesc *m_ready_fd;
|
||||||
|
nsIEventQueueService* mEventQService;
|
||||||
|
PLEventQueue* m_evQueue;
|
||||||
|
char m_buffer[NET_SOCKSTUB_BUF_SIZE];
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // nsSocketTransport_h__
|
Загрузка…
Ссылка в новой задаче