Compare commits

..

2 Commits

Author SHA1 Message Date
sdv%sparc.spb.su
53866ece4f workaround for bug=30927
git-svn-id: svn://10.0.0.236/branches/M15-patch@72213 18797224-902f-48f8-a5cc-f745e15eee43
2000-06-14 11:34:36 +00:00
(no author)
350be55313 This commit was manufactured by cvs2svn to create branch 'M15-patch'.
git-svn-id: svn://10.0.0.236/branches/M15-patch@52901 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-06 02:47:16 +00:00
14 changed files with 105 additions and 2287 deletions

View File

@@ -0,0 +1,105 @@
/*
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 Sun Microsystems,
Inc. Portions created by Sun are
Copyright (C) 1999 Sun Microsystems, Inc. All
Rights Reserved.
Contributor(s):
*/
#ifndef __JavaDOMGlobals_h__
#define __JavaDOMGlobals_h__
#include "jni.h"
#include "prclist.h"
#include "nsError.h"
#ifdef ERROR
#undef ERROR
#endif
class nsISupports;
class nsIDOMNode;
struct PRLogModuleInfo;
struct PRLock;
class JavaDOMGlobals {
public:
static jclass attrClass;
static jclass cDataSectionClass;
static jclass commentClass;
static jclass documentClass;
static jclass documentFragmentClass;
static jclass documentTypeClass;
static jclass domImplementationClass;
static jclass elementClass;
static jclass entityClass;
static jclass entityReferenceClass;
static jclass namedNodeMapClass;
static jclass nodeClass;
static jclass nodeListClass;
static jclass notationClass;
static jclass processingInstructionClass;
static jclass textClass;
static jfieldID nodePtrFID;
static jfieldID nodeListPtrFID;
static jfieldID domImplementationPtrFID;
static jfieldID nodeTypeAttributeFID;
static jfieldID nodeTypeCDataSectionFID;
static jfieldID nodeTypeCommentFID;
static jfieldID nodeTypeDocumentFragmentFID;
static jfieldID nodeTypeDocumentFID;
static jfieldID nodeTypeDocumentTypeFID;
static jfieldID nodeTypeElementFID;
static jfieldID nodeTypeEntityFID;
static jfieldID nodeTypeEntityReferenceFID;
static jfieldID nodeTypeNotationFID;
static jfieldID nodeTypeProcessingInstructionFID;
static jfieldID nodeTypeTextFID;
static jclass domExceptionClass;
static jmethodID domExceptionInitMID;
static jclass runtimeExceptionClass;
static jmethodID runtimeExceptionInitMID;
static const char* const DOM_EXCEPTION_MESSAGE[];
typedef enum ExceptionType { EXCEPTION_RUNTIME,
EXCEPTION_DOM } ExceptionType;
static PRLogModuleInfo* log;
static PRCList garbage;
static PRLock* garbageLock;
static PRInt32 javaMaxInt;
static void Initialize(JNIEnv *env);
static void Destroy(JNIEnv *env);
static jobject CreateNodeSubtype(JNIEnv *env,
nsIDOMNode *node);
static void AddToGarbage(nsISupports* domObject);
static void TakeOutGarbage();
static void ThrowException(JNIEnv *env,
const char * message = NULL,
nsresult rv = NS_OK,
ExceptionType exceptionType = EXCEPTION_RUNTIME);
};
#endif /* __JavaDOMGlobals_h__ */

View File

@@ -1,34 +0,0 @@
#
# The contents of this file are subject to the Netscape Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/NPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is Mozilla Communicator client code,
# released March 31, 1998.
#
# The Initial Developer of the Original Code is Netscape Communications
# Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
# Samir Gehani <sgehani@netscape.com>
#
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
DIRS = src test
include $(topsrcdir)/config/rules.mk

View File

@@ -1,30 +0,0 @@
#!gmake
#
# The contents of this file are subject to the Netscape Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/NPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is Mozilla Communicator client code,
# released March 31, 1998.
#
# The Initial Developer of the Original Code is Netscape Communications
# Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
# Samir Gehani <sgehani@netscape.com>
#
DEPTH=..\..\..
DIRS=src test
include <$(DEPTH)\config\rules.mak>

View File

@@ -1,44 +0,0 @@
#
# The contents of this file are subject to the Netscape Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/NPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is Mozilla Communicator client code,
# released March 31, 1998.
#
# The Initial Developer of the Original Code is Netscape Communications
# Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
# Samir Gehani <sgehani@netscape.com>
#
DEPTH = ../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VAPTH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = xpnet
LIBRARY_NAME = xpnet_s
CPPSRCS = \
nsSocket.cpp \
nsFTPConn.cpp \
nsHTTPConn.cpp \
$(NULL)
override NO_SHARED_LIB=1
override NO_STATIC_LIB=
include $(topsrcdir)/config/rules.mk

View File

@@ -1,48 +0,0 @@
#!gmake
#
# The contents of this file are subject to the Netscape Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/NPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is Mozilla Communicator client code,
# released March 31, 1998.
#
# The Initial Developer of the Original Code is Netscape Communications
# Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
# Samir Gehani <sgehani@netscape.com>
#
MODULE=xpnet
LIBNAME=$(MODULE)
DEPTH=..\..\..\..
MAKE_OBJ_TYPE=DLL
LIBRARY=$(OBJDIR)\$(LIBNAME)_s.lib
OBJS= \
.\$(OBJDIR)\nsSocket.obj \
.\$(OBJDIR)\nsFTPConn.obj \
.\$(OBJDIR)\nsHTTPConn.obj \
$(NULL)
include <$(DEPTH)/config/rules.mak>
install::
$(MAKE_INSTALL) $(LIBRARY) $(DIST)\lib
clobber::
$(RM) $(DIST)\lib\$(LIBNAME)_s.lib
clobber_all:: clobber

View File

@@ -1,496 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code,
* released March 31, 1998.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Samir Gehani <sgehani@netscape.com>
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <sys/stat.h>
#ifdef __unix
#include <sys/param.h>
#elif defined(_WINDOWS)
#include <windows.h>
#define MAXPATHLEN MAX_PATH
#endif
#include "nsSocket.h"
#include "nsFTPConn.h"
const int kCntlPort = 21;
const int kDataPort = 20;
const int kCmdBufSize = 64 + MAXPATHLEN;
const int kRespBufSize = 1024;
const int kKilobyte = 1024;
const int kUsecsPerSec = 1000000;
const int kDlBufSize = 1024;
nsFTPConn::nsFTPConn(char *aHost) :
mHost(aHost),
mState(CLOSED),
mPassive(FALSE),
mCntlSock(NULL),
mDataSock(NULL)
{
}
nsFTPConn::~nsFTPConn()
{
// don't release mHost cause we don't own it
}
int
nsFTPConn::Open()
{
int err = OK;
char cmd[kCmdBufSize], resp[kRespBufSize];
int respBufSize = kRespBufSize;
if (!mHost)
return E_PARAM;
if (mState != CLOSED)
return E_ALREADY_OPEN;
/* open control connection on port 21 */
mCntlSock = new nsSocket(mHost, kCntlPort);
if (!mCntlSock)
return E_MEM;
ERR_CHECK(mCntlSock->Open());
ERR_CHECK(mCntlSock->Recv((unsigned char *)resp, &respBufSize));
DUMP(resp);
/* issue USER command on control connection */
sprintf(cmd, "USER anonymous\r\n");
err = IssueCmd(cmd, resp, kRespBufSize, mCntlSock);
/* issue PASS command on control connection */
sprintf(cmd, "PASS -linux@installer.sbg\r\n");
ERR_CHECK(IssueCmd(cmd, resp, kRespBufSize, mCntlSock));
mState = OPEN;
return err;
BAIL:
if (mCntlSock)
{
mCntlSock->Close();
delete mCntlSock;
mCntlSock = NULL;
}
if (mDataSock)
{
mDataSock->Close();
delete mDataSock;
mDataSock = NULL;
}
return err;
}
int
nsFTPConn::Open(char *aHost)
{
if (!aHost)
return E_PARAM;
mHost = aHost;
return Open();
}
int
nsFTPConn::Get(char *aSrvPath, char *aLoclPath, int aType, int aOvWrite,
FTPGetCB aCBFunc)
{
struct stat dummy;
int err = OK, wrote = 0, totBytesRd = 0;
char cmd[kCmdBufSize], resp[kRespBufSize];
int fileSize = 0, respBufSize = kRespBufSize;
FILE *loclfd = NULL;
if (!aSrvPath || !aLoclPath)
return E_PARAM;
if (mState != OPEN || !mCntlSock)
return E_NOT_OPEN;
/* stat local path and verify aOvWrite is set if file already exists */
err = stat(aLoclPath, &dummy);
if (err != -1 && aOvWrite == FALSE)
return E_CANT_OVWRITE;
mState = GETTING;
/* initialize data connection */
ERR_CHECK(DataInit(mHost, kDataPort, &mDataSock));
/* issue SIZE command on control connection */
sprintf(cmd, "SIZE %s\r\n", aSrvPath);
err = IssueCmd(cmd, resp, kRespBufSize, mCntlSock); /* non-fatal */
if (err == OK && (resp[0] == '2'))
fileSize = atoi(&resp[4]);
/* issue TYPE command on control connection */
sprintf(cmd, "TYPE %s\r\n", aType==BINARY ? "I" : "A");
ERR_CHECK(IssueCmd(cmd, resp, kRespBufSize, mCntlSock));
/* issue RETR command on control connection */
sprintf(cmd, "RETR %s\r\n", aSrvPath);
ERR_CHECK(IssueCmd(cmd, resp, kRespBufSize, mCntlSock));
/* get file contents on data connection */
if (!mPassive)
ERR_CHECK(mDataSock->SrvAccept());
/* initialize locl file */
if (!(loclfd = fopen(aLoclPath, aType==BINARY ? "wb" : "w")) ||
(fseek(loclfd, 0, SEEK_SET) != 0))
{
err = E_LOCL_INIT;
goto BAIL;
}
totBytesRd = 0;
do
{
respBufSize = kDlBufSize;
err = mDataSock->Recv((unsigned char *)resp, &respBufSize);
if (err != nsSocket::E_READ_MORE &&
err != nsSocket::E_EOF_FOUND &&
err != nsSocket::OK)
goto BAIL;
totBytesRd += respBufSize;
if (err == nsSocket::E_READ_MORE && aCBFunc)
aCBFunc(totBytesRd, fileSize);
/* append to local file */
wrote = fwrite((void *)resp, 1, respBufSize, loclfd);
if (wrote != respBufSize)
{
err = E_WRITE;
goto BAIL;
}
}
while (err == nsSocket::E_READ_MORE || err == nsSocket::OK);
if (err == nsSocket::E_EOF_FOUND)
err = OK;
BAIL:
/* close locl file if open */
if (loclfd)
fclose(loclfd);
/* kill data connection if it exists */
if (mDataSock)
{
mDataSock->Close();
delete mDataSock;
mDataSock = NULL;
}
mState = OPEN;
mPassive = FALSE;
return err;
}
int
nsFTPConn::Close()
{
int err = OK;
if (mState != OPEN)
return E_NOT_OPEN;
/* close sockets */
if (mCntlSock)
{
ERR_CHECK(mCntlSock->Close());
delete mCntlSock;
mCntlSock = NULL;
}
if (mDataSock)
{
ERR_CHECK(mDataSock->Close());
delete mDataSock;
mDataSock = NULL;
}
BAIL:
return err;
}
int
nsFTPConn::IssueCmd(char *aCmd, char *aResp, int aRespSize, nsSocket *aSock)
{
int err = OK;
int len;
/* param check */
if (!aSock || !aCmd || !aResp || aRespSize <= 0)
return E_PARAM;
/* send command */
len = strlen(aCmd);
ERR_CHECK(aSock->Send((unsigned char *)aCmd, &len));
DUMP(aCmd);
/* receive response */
do
{
err = aSock->Recv((unsigned char *)aResp, &aRespSize);
if (err != nsSocket::OK &&
err != nsSocket::E_READ_MORE &&
err != nsSocket::E_EOF_FOUND)
goto BAIL;
DUMP(aResp);
}
while (err == nsSocket::E_READ_MORE);
/* alternate interpretation of err codes */
if ( (strncmp(aCmd, "APPE", 4) == 0) ||
(strncmp(aCmd, "LIST", 4) == 0) ||
(strncmp(aCmd, "NLST", 4) == 0) ||
(strncmp(aCmd, "REIN", 4) == 0) ||
(strncmp(aCmd, "RETR", 4) == 0) ||
(strncmp(aCmd, "STOR", 4) == 0) ||
(strncmp(aCmd, "STOU", 4) == 0) )
{
switch (*aResp)
{
case '1': /* exception: 100 series is OK */
case '2':
break;
case '3':
err = E_CMD_ERR;
break;
case '4':
case '5':
err = E_CMD_FAIL;
break;
default:
err = E_CMD_UNEXPECTED;
break;
}
}
/* regular interpretation of err codes */
else
{
switch (*aResp)
{
case '2':
break;
case '1':
case '3':
err = E_CMD_ERR;
break;
case '4':
case '5':
err = E_CMD_FAIL;
break;
default:
err = E_CMD_UNEXPECTED;
break;
}
}
BAIL:
return err;
}
int
nsFTPConn::ParseAddr(char *aBuf, char **aHost, int *aPort)
{
int err = OK;
char *c;
int addr[6];
/* param check */
if (!aBuf || !aHost || !aPort)
return E_PARAM;
c = aBuf + strlen("227 "); /* pass by return code */
while (!isdigit((int)(*c)))
{
if (*c == '\0')
return E_INVALID_ADDR;
c++;
}
if (sscanf(c, "%d,%d,%d,%d,%d,%d",
&addr[0], &addr[1], &addr[2], &addr[3], &addr[4], &addr[5]) != 6)
return E_INVALID_ADDR;
*aHost = (char *)malloc(strlen("XXX.XXX.XXX.XXX"));
sprintf(*aHost, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);
*aPort = ((addr[4] & 0xFF) << 8) | (addr[5] & 0xFF);
#ifdef DEBUG
printf("%s %d: PASV response: %d,%d,%d,%d,%d,%d\n", __FILE__, __LINE__,
addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
printf("%s %d: Host = %s\tPort = %d\n", __FILE__, __LINE__, *aHost, *aPort);
#endif
return err;
}
int
nsFTPConn::DataInit(char *aHost, int aPort, nsSocket **aSock)
{
int err = OK;
char cmd[kCmdBufSize], resp[kRespBufSize];
char *srvHost = NULL;
int srvPort = 0;
char *hostPort = NULL;
/* param check */
if (!aHost || !aSock)
return E_PARAM;
/* issue PASV command */
sprintf(cmd, "PASV\r\n");
err = IssueCmd(cmd, resp, kRespBufSize, mCntlSock);
if (err != OK)
{
err = OK;
goto ACTIVE; /* failover to active mode */
}
mPassive = TRUE;
ERR_CHECK(ParseAddr(resp, &srvHost, &srvPort));
*aSock = new nsSocket(srvHost, srvPort);
if (!*aSock)
{
err = E_MEM;
goto BAIL;
}
ERR_CHECK((*aSock)->Open());
if (srvHost)
{
free(srvHost);
srvHost = NULL;
}
return err;
ACTIVE:
*aSock = new nsSocket(aHost, aPort);
if (!*aSock)
{
err = E_MEM;
goto BAIL;
}
/* init data socket making it listen */
ERR_CHECK((*aSock)->SrvOpen());
ERR_CHECK((*aSock)->GetHostPortString(&hostPort)); // allocates
if (!hostPort)
{
err = E_MEM;
goto BAIL;
}
sprintf(cmd, "PORT %s\r\n", hostPort);
ERR_CHECK(IssueCmd(cmd, resp, kRespBufSize, mCntlSock));
BAIL:
if (mPassive && err != OK)
mPassive = FALSE;
if (err != OK && (*aSock))
{
delete *aSock;
*aSock = NULL;
}
if (srvHost)
{
free(srvHost);
srvHost = NULL;
}
if (hostPort)
{
free(hostPort);
hostPort = NULL;
}
return err;
}
#ifdef TEST_NSFTPCONN
static struct timeval init;
int
TestFTPGetCB(int aBytesRd, int aTotal)
{
struct timeval now;
float rate;
gettimeofday(&now, NULL);
rate = nsSocket::CalcRate(&init, &now, aBytesRd);
printf("br=%d\ttot=%d\trt=%f\tirt=%d\n",aBytesRd, aTotal, rate, (int)rate);
return 0;
}
int
main(int argc, char **argv)
{
int err = nsFTPConn::OK;
nsFTPConn *conn = 0;
char *leaf = NULL;
if (argc < 2)
{
printf("usage: %s <host> <path/on/server>\n", argv[0]);
exit(0);
}
if ((leaf = strrchr(argv[2], '/'))) leaf++;
else leaf = argv[2];
conn = new nsFTPConn(argv[1]);
printf("Opening connection to %s...\n", argv[1]);
err = conn->Open();
if (err != nsFTPConn::OK) { printf("error: %d\n", err); exit(err); }
printf("Getting binary file %s...\n", argv[2]);
gettimeofday(&init, NULL);
err = conn->Get(argv[2], leaf, nsFTPConn::BINARY, TRUE, TestFTPGetCB);
if (err != nsFTPConn::OK) { printf("error: %d\n", err); exit(err); }
printf("Closing connection to %s...\n", argv[1]);
err = conn->Close();
if (err != nsFTPConn::OK) { printf("error: %d\n", err); exit(err); }
printf("Test successful!\n");
exit(err);
}
#endif /* TEST_NSFTPCONN */

View File

@@ -1,126 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code,
* released March 31, 1998.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Samir Gehani <sgehani@netscape.com>
*/
#ifndef _NS_FTPCONN_H_
#define _NS_FTPCONN_H_
class nsSocket;
typedef int (*FTPGetCB)(int aBytesRd, int aTotal);
class nsFTPConn
{
public:
nsFTPConn(char *aHost);
~nsFTPConn();
/* ftp type */
enum
{
ASCII = 0,
BINARY
};
/* connection state */
enum
{
OPEN = 0,
GETTING,
CLOSED
};
int Open();
int Open(char *aHost);
int Get(char *aSrvPath, char *aLoclPath, int aType, int aOvWrite,
FTPGetCB aCBFunc);
int Close();
/*--------------------------------------------------------------------*
* Errors
*--------------------------------------------------------------------*/
enum
{
OK = 0,
E_MEM = -801, /* out of memory */
E_PARAM = -802, /* parameter null or incorrect */
E_ALREADY_OPEN = -803, /* connection already established */
E_NOT_OPEN = -804, /* connection not established, can't use */
E_CMD_ERR = -805, /* ftp command error */
E_CMD_FAIL = -806, /* ftp command failed */
E_CMD_UNEXPECTED = -807, /* ftp command unexpected response */
E_WRITE = -808, /* write to socket/fd failed */
E_READ = -809, /* read on socket/fd failed */
E_SMALL_BUF = -810, /* buffer too small, provide bigger one */
E_CANT_OVWRITE = -811, /* cannot overwrite existing file */
E_LOCL_INIT = -812, /* local file open/init failed */
E_INVALID_ADDR = -814 /* couldn't parse address/port */
};
private:
int IssueCmd(char *aCmd, char *aResp, int aRespSize,
nsSocket *aSock);
int ParseAddr(char *aBuf, char **aHost, int *aPort);
int DataInit(char *aHost, int aPort, nsSocket **aSock);
char *mHost;
int mState;
int mPassive;
nsSocket *mCntlSock;
nsSocket *mDataSock;
};
#ifndef NULL
#define NULL (void*)0L
#endif
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#ifdef DUMP
#undef DUMP
#endif
#if defined(DEBUG) || defined(DEBUG_sgehani)
#define DUMP(_msg) printf("%s %d: %s\n", __FILE__, __LINE__, _msg);
#else
#define DUMP(_msg)
#endif /* DEBUG */
#ifndef ERR_CHECK
#define ERR_CHECK(_func) \
do { \
err = _func; \
if (err != OK) \
goto BAIL; \
} while(0);
#endif
#endif /* _NS_FTPCONN_H_ */

View File

@@ -1,598 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code,
* released March 31, 1998.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Samir Gehani <sgehani@netscape.com>
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <sys/stat.h>
#include "nsHTTPConn.h"
#include "nsSocket.h"
const char kHTTPProto[8] = "http://";
const char kFTPProto[8] = "ftp://";
const int kHTTPPort = 80;
const int kFTPPort = 21;
const int kRespBufSize = 1024;
const int kReqBufSize = 1024;
const int kHdrBufSize = 256;
const char kCRLF[3] = "\r\n";
const char kHdrBodyDelim[5] = "\r\n\r\n";
const char kDefaultDestFile[11] = "index.html";
nsHTTPConn::nsHTTPConn(char *aHost, int aPort, char *aPath) :
mHost(aHost),
mPath(aPath),
mProxiedURL(NULL),
mProxyUser(NULL),
mProxyPswd(NULL),
mDestFile(NULL),
mHostPathAllocd(FALSE),
mSocket(NULL)
{
if (aPort <= 0)
mPort = kHTTPPort;
else
mPort = aPort;
DUMP(("mHost = %s\n", mHost));
DUMP(("mPort = %d\n", mPort));
DUMP(("mPath = %s\n", mPath));
}
nsHTTPConn::nsHTTPConn(char *aURL) :
mPort(kHTTPPort),
mProxiedURL(NULL),
mProxyUser(NULL),
mProxyPswd(NULL),
mDestFile(NULL),
mHostPathAllocd(FALSE),
mSocket(NULL)
{
// parse URL
if (ParseURL(kHTTPProto, aURL, &mHost, &mPort, &mPath) == OK)
mHostPathAllocd = TRUE;
else
{
mHost = NULL;
mPath = NULL;
}
DUMP(("mHost = %s\n", mHost));
DUMP(("mPort = %d\n", mPort));
DUMP(("mPath = %s\n", mPath));
}
nsHTTPConn::~nsHTTPConn()
{
if (mHostPathAllocd)
{
if (mHost)
free(mHost);
if (mPath)
free(mPath);
}
}
int
nsHTTPConn::Open()
{
// verify host && path
if (!mHost || !mPath)
return E_MALFORMED_URL;
// create socket
mSocket = new nsSocket(mHost, mPort);
if (!mSocket)
return E_MEM;
// open socket
return mSocket->Open();
}
int
nsHTTPConn::Get(HTTPGetCB aCallback, char *aDestFile)
{
int rv;
char *pathToUse;
// verify host && path
if (!mHost || !mPath)
return E_MALFORMED_URL;
if (!aDestFile)
{
if (mProxiedURL)
pathToUse = mProxiedURL;
else
pathToUse = mPath;
// no leaf: assume default file 'index.html'
if (*(pathToUse + strlen(pathToUse) - 1) == '/')
aDestFile = (char *) kDefaultDestFile;
else
aDestFile = strrchr(pathToUse, '/') + 1;
}
// issue request
rv = Request();
// recv response
if (rv == OK)
rv = Response(aCallback, aDestFile);
return rv;
}
int
nsHTTPConn::Close()
{
int rv;
// close socket
rv = mSocket->Close();
// destroy socket
delete mSocket;
return rv;
}
void
nsHTTPConn::SetProxyInfo(char *aProxiedURL, char *aProxyUser,
char *aProxyPswd)
{
mProxiedURL = aProxiedURL;
mProxyUser = aProxyUser;
mProxyPswd = aProxyPswd;
}
int
nsHTTPConn::Request()
{
char req[kReqBufSize];
char hdr[kHdrBufSize];
int rv;
memset(req, 0, kReqBufSize);
// format header buf:
// request line
memset(hdr, 0, kHdrBufSize);
if (mProxiedURL)
{
sprintf(hdr, "GET %s HTTP/1.1%s", mProxiedURL, kCRLF);
strcpy(req, hdr);
memset(hdr, 0, kHdrBufSize);
if (strncmp(mProxiedURL, kFTPProto, strlen(kFTPProto)) == 0)
{
char *ftpHost, *ftpPath;
int ftpPort = kFTPPort;
rv = ParseURL(kFTPProto, mProxiedURL,
&ftpHost, &ftpPort, &ftpPath);
if (rv == OK)
sprintf(hdr, "Host: %s:%d%s", ftpHost, ftpPort, kCRLF);
if (ftpHost)
free(ftpHost);
if (ftpPath)
free(ftpPath);
}
else
sprintf(hdr, "Host: %s%s", mHost, kCRLF);
strcat(req, hdr);
}
else
{
sprintf(hdr, "GET %s HTTP/1.1%s", mPath, kCRLF);
strcpy(req, hdr);
memset(hdr, 0, kHdrBufSize);
sprintf(hdr, "Host: %s%s", mHost, kCRLF);
strcat(req, hdr);
}
// if proxy set and proxy user/pswd set
if (mProxyUser && mProxyPswd)
{
char *usrPsd = (char *) malloc(strlen(mProxyUser) +
strlen(":") +
strlen(mProxyPswd));
if (!usrPsd)
return E_MEM;
sprintf(usrPsd, "%s:%s", mProxyUser, mProxyPswd);
// base 64 encode proxy header
char usrPsdEncoded[128]; // pray that 128 is long enough
memset(usrPsdEncoded, 0, 128);
DUMP(("Unencoded string: %s\n", usrPsd));
rv = Base64Encode((const unsigned char *)usrPsd, strlen(usrPsd),
usrPsdEncoded, 128);
DUMP(("Encoded string: %s\n", usrPsdEncoded));
DUMP(("Base64Encode returned: %d\n", rv));
if (rv <= 0)
{
return E_B64_ENCODE;
}
// append proxy header to header buf
memset(hdr, 0, kHdrBufSize);
sprintf(hdr, "Proxy-authorization: Basic %s%s", usrPsdEncoded, kCRLF);
strcat(req, hdr);
// XXX append host with port 21 if ftp
}
// headers all done so indicate
strcat(req, kCRLF);
// send header buf over socket
int bufSize = strlen(req);
rv = mSocket->Send((unsigned char *) req, &bufSize);
DUMP(("\n\n%s", req));
if (bufSize != (int) strlen(req))
rv = E_REQ_INCOMPLETE;
return rv;
}
int
nsHTTPConn::Response(HTTPGetCB aCallback, char *aDestFile)
{
// NOTE: overwrites dest file if it already exists
int rv = OK;
char resp[kRespBufSize];
int bufSize, fwriteLen, fwrote, bytesWritten = 0, expectedSize = 0;
FILE *destFd;
char *fwritePos;
int bFirstIter = TRUE;
if (!aDestFile)
return E_PARAM;
// open dest file
destFd = fopen(aDestFile, "w+");
if (!destFd)
return E_OPEN_FILE;
// iteratively recv response
do
{
memset(resp, 0, kRespBufSize);
bufSize = kRespBufSize;
rv = mSocket->Recv((unsigned char *) resp, &bufSize);
DUMP((resp));
DUMP(("nsSocket::Recv returned: %d\t and recd: %d\n", rv, bufSize));
if (bFirstIter)
{
fwritePos = strstr(resp, kHdrBodyDelim);
if (fwritePos == NULL)
{
// XXX no header! should we handle?
fwritePos = resp;
fwriteLen = bufSize;
}
else
{
ParseContentLength((const char *)resp, &expectedSize);
// move past hdr-body delimiter
fwritePos += strlen(kHdrBodyDelim);
fwriteLen = bufSize - (fwritePos - resp);
}
bFirstIter = FALSE;
}
else
{
fwritePos = resp;
fwriteLen = bufSize;
}
fwrote = fwrite(fwritePos, sizeof(char), fwriteLen, destFd);
assert(fwrote == fwriteLen);
if (fwriteLen > 0)
bytesWritten += fwriteLen;
if (aCallback)
aCallback(bytesWritten, expectedSize);
} while (rv == nsSocket::E_READ_MORE || rv == nsSocket::OK);
if (rv == nsSocket::E_EOF_FOUND)
{
DUMP(("EOF detected\n"));
rv = OK;
}
fclose(destFd);
return rv;
}
int
nsHTTPConn::ParseURL(const char *aProto, char *aURL, char **aHost,
int *aPort, char **aPath)
{
char *pos, *nextSlash, *nextColon, *end, *hostEnd;
int protoLen = strlen(aProto);
if (!aURL || !aHost || !aPort || !aPath || !aProto)
return E_PARAM;
if ((strncmp(aURL, aProto, protoLen) != 0) ||
(strlen(aURL) < 9))
return E_MALFORMED_URL;
pos = aURL + protoLen;
nextColon = strchr(pos, ':');
nextSlash = strchr(pos, '/');
// optional port specification
if (nextColon && ((nextSlash && nextColon < nextSlash) ||
!nextSlash))
{
int portStrLen;
if (nextSlash)
portStrLen = nextSlash - nextColon;
else
portStrLen = strlen(nextColon);
char *portStr = (char *) malloc(portStrLen);
if (!portStr)
return E_MEM;
memset(portStr, 0, portStrLen);
strncpy(portStr, nextColon+1, portStrLen);
*aPort = atoi(portStr);
free(portStr);
}
if ( (!nextColon || (nextSlash && (nextColon > nextSlash)))
&& *aPort <= 0) // don't override port if already set
*aPort = -1;
// only host in URL, assume '/' for path
if (!nextSlash)
{
int copyLen;
if (nextColon)
copyLen = nextColon - pos;
else
copyLen = strlen(pos);
*aHost = (char *) malloc(copyLen + 1); // to NULL terminate
strncpy(*aHost, pos, copyLen);
*aPath = (char *) malloc(2);
*aPath = "/\0";
return OK;
}
// normal parsing: both host and path exist
if (nextColon)
hostEnd = nextColon;
else
hostEnd = nextSlash;
*aHost = (char *) malloc(hostEnd - pos + 1); // to NULL terminate
if (!*aHost)
return E_MEM;
memset(*aHost, 0, hostEnd - pos + 1);
strncpy(*aHost, pos, hostEnd - pos);
*(*aHost + (hostEnd - pos)) = 0; // NULL terminate
pos = nextSlash;
end = aURL + strlen(aURL);
*aPath = (char *) malloc(end - pos + 1);
if (!*aPath)
{
if (*aHost)
free(*aHost);
return E_MEM;
}
memset(*aPath, 0, end - pos + 1);
strncpy(*aPath, pos, end - pos);
return OK;
}
void
nsHTTPConn::ParseContentLength(const char *aBuf, int *aLength)
{
char *clHdr; // Content-length header line start
char *eol, *pos;
char clNameStr1[16] = "Content-length:";
char clNameStr2[16] = "Content-Length:";
char *clNameStr = clNameStr1;
if (!aBuf || !aLength)
return; // non fatal so no error codes returned
*aLength = 0;
// XXX strcasestr() needs to be ported for Solaris (and Win32 and Mac?)
clHdr = strstr(aBuf, (char *)clNameStr1);
if (!clHdr)
{
clHdr = strstr(aBuf, (char *)clNameStr2);
clNameStr = clNameStr2;
}
if (clHdr)
{
eol = strstr(clHdr, kCRLF); // end of line
pos = clHdr + strlen(clNameStr);
while ((pos < eol) && (*pos == ' ' || *pos == '\t'))
pos++;
if (pos < eol)
{
int clValStrLen = eol - pos + 1; // extra byte to NULL terminate
char *clValStr = (char *) malloc(clValStrLen);
if (!clValStr)
return; // imminent doom!
memset(clValStr, 0, clValStrLen);
strncpy(clValStr, pos, eol - pos);
*aLength = atoi(clValStr);
}
}
}
int
nsHTTPConn::Base64Encode(const unsigned char *in_str, int in_len,
char *out_str, int out_len)
{
// NOTE: shamelessly copied from nsAbSyncPostEngine.cpp
static unsigned char base64[] =
{
/* 0 1 2 3 4 5 6 7 */
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', /* 0 */
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', /* 1 */
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', /* 2 */
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', /* 3 */
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', /* 4 */
'o', 'p', 'q', 'r', 's', 't', 'u', 'v', /* 5 */
'w', 'x', 'y', 'z', '0', '1', '2', '3', /* 6 */
'4', '5', '6', '7', '8', '9', '+', '/' /* 7 */
};
int curr_out_len = 0;
int i = 0;
unsigned char a, b, c;
out_str[0] = '\0';
if (in_len > 0)
{
while (i < in_len)
{
a = in_str[i];
b = (i + 1 >= in_len) ? 0 : in_str[i + 1];
c = (i + 2 >= in_len) ? 0 : in_str[i + 2];
if (i + 2 < in_len)
{
out_str[curr_out_len++] = (base64[(a >> 2) & 0x3F]);
out_str[curr_out_len++] = (base64[((a << 4) & 0x30)
+ ((b >> 4) & 0xf)]);
out_str[curr_out_len++] = (base64[((b << 2) & 0x3c)
+ ((c >> 6) & 0x3)]);
out_str[curr_out_len++] = (base64[c & 0x3F]);
}
else if (i + 1 < in_len)
{
out_str[curr_out_len++] = (base64[(a >> 2) & 0x3F]);
out_str[curr_out_len++] = (base64[((a << 4) & 0x30)
+ ((b >> 4) & 0xf)]);
out_str[curr_out_len++] = (base64[((b << 2) & 0x3c)
+ ((c >> 6) & 0x3)]);
out_str[curr_out_len++] = '=';
}
else
{
out_str[curr_out_len++] = (base64[(a >> 2) & 0x3F]);
out_str[curr_out_len++] = (base64[((a << 4) & 0x30)
+ ((b >> 4) & 0xf)]);
out_str[curr_out_len++] = '=';
out_str[curr_out_len++] = '=';
}
i += 3;
if((curr_out_len + 4) > out_len)
{
return(-1);
}
}
out_str[curr_out_len] = '\0';
}
return curr_out_len;
}
#ifdef TEST_NSHTTPCONN
int
TestHTTPCB(int aBytesRd, int aTotal)
{
DUMP(("Bytes rd: %d\tTotal: %d\n", aBytesRd, aTotal));
return 0;
}
int
main(int argc, char **argv)
{
nsHTTPConn *conn;
int rv = nsHTTPConn::OK;
char *proxiedURL = NULL;
char *proxyUser = NULL;
char *proxyPswd = NULL;
DUMP(("*** %s: A self-test for the nsHTTPConn class.\n", argv[0]));
if (argc < 2)
{
printf("usage: %s <http_url> [<proxied_url> [<proxy_user> ", argv[0]);
printf("<proxy_pswd>]]\n");
exit(1);
}
conn = new nsHTTPConn(argv[1]);
if (argc >= 3)
{
proxiedURL = argv[2];
}
if (argc >= 5)
{
proxyUser = argv[3];
proxyPswd = argv[4];
}
conn->SetProxyInfo(proxiedURL, proxyUser, proxyPswd);
rv = conn->Open();
DUMP(("nsHTTPConn::Open returned: %d\n", rv));
rv = conn->Get(TestHTTPCB, NULL); // NULL: local file name = URL leaf
DUMP(("nsHTTPConn::Get returned: %d\n", rv));
rv = conn->Close();
DUMP(("nsHTTPConn::Close returned: %d\n", rv));
return 0;
}
#endif /* TEST_NSHTTPCONN */

View File

@@ -1,102 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code,
* released March 31, 1998.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Samir Gehani <sgehani@netscape.com>
*/
#ifndef _NS_HTTPCONN_H_
#define _NS_HTTPCONN_H_
class nsSocket;
typedef int (*HTTPGetCB)(int aBytesRd, int aTotal);
class nsHTTPConn
{
public:
nsHTTPConn(char *aHost, int aPort, char *aPath);
nsHTTPConn(char *aURL);
~nsHTTPConn();
int Open();
int Get(HTTPGetCB aCallback, char *aDestFile);
int Close();
void SetProxyInfo(char *aProxiedURL, char *aProxyUser,
char *aProxyPswd);
static int ParseURL(const char *aProto, char *aURL, char **aHost,
int *aPort, char **aPath);
enum
{
OK = 0,
E_MEM = -801,
E_PARAM = -802,
E_MALFORMED_URL = -803,
E_REQ_INCOMPLETE = -804,
E_B64_ENCODE = -805,
E_OPEN_FILE = -806
};
private:
int Request();
int Response(HTTPGetCB aCallback, char *aDestFile);
void ParseContentLength(const char *aBuf, int *aLength);
int Base64Encode(const unsigned char *in_str, int in_len,
char *out_str, int out_len);
char *mHost;
char *mPath;
int mPort;
char *mProxiedURL;
char *mProxyUser;
char *mProxyPswd;
char *mDestFile;
int mHostPathAllocd;
nsSocket *mSocket;
};
#ifndef NULL
#define NULL ((void*) 0L);
#endif
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#ifdef DUMP
#undef DUMP
#endif
#if defined(DEBUG_sgehani) || defined(DEBUG)
#define DUMP(_vargs) \
do { \
printf("%s %d: ", __FILE__, __LINE__); \
printf _vargs; \
} while(0);
#else
#define DUMP(_vargs)
#endif
#endif /* _NS_HTTPCONN_H_ */

View File

@@ -1,450 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code,
* released March 31, 1998.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Samir Gehani <sgehani@netscape.com>
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
/* Platform-specific headers for socket functionality */
#ifdef __unix
#include <unistd.h>
#include <netdb.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#elif defined(_WINDOWS)
#define read(_socket, _buf, _len) \
recv(_socket, (char *) _buf, _len, 0);
#define write(_socket, _buf, _len) \
send(_socket, (char *) _buf, _len, 0);
#include <winsock2.h>
#endif
#include "nsSocket.h"
#define MAXSOCKADDR 128
#include "platform.h" // for SOLARIS define
#if defined(SOLARIS) || defined(_WINDOWS)
#define socklen_t int
#endif
#ifndef SHUT_RDWR
#define SHUT_RDWR 2
#endif
const int kUsecsPerSec = 1000000;
const int kTimeoutThresholdUsecs = 120 * kUsecsPerSec;
const int kTimeoutSelectUsecs = 100000;
const int kKilobyte = 1024;
const int kReadBufSize = 1024;
nsSocket::nsSocket(char *aHost, int aPort) :
mHost(aHost),
mPort(aPort),
mFd(-1),
mListenFd(-1)
{
}
nsSocket::~nsSocket()
{
// don't release mHost cause we don't own it
}
int
nsSocket::Open()
{
#ifdef _WINDOWS
/* funky windows initialization of winsock */
int err;
WSADATA wsaData;
WORD wVersionRequested = MAKEWORD(4, 0);
err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0)
{
return E_WINSOCK;
}
#endif
int rv = OK;
struct sockaddr_in servaddr;
struct hostent *hptr = NULL;
mFd = socket(AF_INET, SOCK_STREAM, 0);
#ifdef _WINDOWS
if (mFd == INVALID_SOCKET)
{
printf("Last error: %d\n", WSAGetLastError());
}
#endif
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(mPort);
if ( (hptr = gethostbyname(mHost)) == NULL )
return E_INVALID_HOST;
memcpy(&servaddr.sin_addr, (struct in_addr **) hptr->h_addr_list[0],
sizeof(struct in_addr));
rv = connect(mFd, (struct sockaddr *) &servaddr, sizeof(servaddr));
if (rv < 0)
{
#if defined(DEBUG) && defined(__unix)
printf("ETIMEDOUT: %d\n", ETIMEDOUT);
printf("ECONNREFUSED: %d\n", ECONNREFUSED);
printf("EHOSTUNREACH: %d\n", EHOSTUNREACH);
printf("ENETUNREACH: %d\n", ENETUNREACH);
printf("connect error: %d\n", errno);
#endif /* DEBUG && __unix */
mFd = -1;
rv = E_SOCK_OPEN;
}
else
rv = OK;
return rv;
}
int
nsSocket::SrvOpen()
{
int rv = OK;
struct sockaddr_in servaddr;
/* init data socket making it listen */
mListenFd = socket(AF_INET, SOCK_STREAM, 0);
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_addr.s_addr = htonl(INADDR_ANY); /* wildcard */
servaddr.sin_port = 0; /* let kernel bind an ephemeral port */
if ((bind(mListenFd, (struct sockaddr *) &servaddr, sizeof(servaddr))) != 0)
return E_BIND;
if ((listen(mListenFd, SOMAXCONN)) != 0)
return E_LISTEN;
return rv;
}
int
nsSocket::SrvAccept()
{
int rv = OK;
struct sockaddr cliaddr;
socklen_t clilen;
if (mListenFd < 0)
return E_PARAM;
clilen = sizeof(cliaddr);
mFd = accept(mListenFd, (struct sockaddr *) &cliaddr, &clilen);
if (mFd < 0)
rv = E_ACCEPT;
return rv;
}
int
nsSocket::Send(unsigned char *aBuf, int *aBufSize)
{
int rv = OK;
struct timeval seltime;
int timeout = 0;
fd_set selset;
if (!aBuf || aBufSize <= 0 || mFd < 0)
return E_PARAM;
while (timeout < kTimeoutThresholdUsecs)
{
FD_ZERO(&selset);
FD_SET(mFd, &selset);
seltime.tv_sec = 0;
seltime.tv_usec = kTimeoutSelectUsecs;
rv = select(mFd+1, NULL, &selset, NULL, &seltime);
switch (rv)
{
case -1: /* error occured! */
return errno;
case 0: /* timeout; retry */
timeout += kTimeoutSelectUsecs;
continue;
default: /* ready to write */
break;
}
if (!FD_ISSET(mFd, &selset))
{
timeout += kTimeoutSelectUsecs;
continue; /* not ready to write; retry */
}
else
break;
}
if (rv == 0)
return E_TIMEOUT;
rv = write(mFd, aBuf, *aBufSize);
if (rv <= 0)
rv = E_WRITE;
else
{
*aBufSize = rv;
rv = OK;
}
return rv;
}
int
nsSocket::Recv(unsigned char *aBuf, int *aBufSize)
{
int rv = OK;
unsigned char lbuf[kReadBufSize]; /* function local buffer */
int bytesrd = 0;
struct timeval seltime;
fd_set selset;
int bufsize;
if (!aBuf || *aBufSize <= 0 || mFd < 0)
return E_PARAM;
memset(aBuf, 0, *aBufSize);
for ( ; ; )
{
/* return if we anticipate overflowing caller's buffer */
if (bytesrd >= *aBufSize)
return E_READ_MORE;
memset(&lbuf, 0, kReadBufSize);
FD_ZERO(&selset);
FD_SET(mFd, &selset);
seltime.tv_sec = 0;
seltime.tv_usec = kTimeoutSelectUsecs;
rv = select(mFd+1, &selset, NULL, NULL, &seltime);
switch (rv)
{
case -1: /* error occured! */
return errno;
case 0: /* timeout; retry */
continue;
default: /* ready to read */
break;
}
// XXX TODO: prevent inf loop returning at kTimeoutThresholdUsecs
if (!FD_ISSET(mFd, &selset))
continue; /* not ready to read; retry */
bufsize = *aBufSize - bytesrd;
rv = read(mFd, lbuf, bufsize);
if (rv == 0) /* EOF encountered */
{
rv = E_EOF_FOUND;
break;
}
if (rv < 0)
{
rv = E_READ;
break;
}
if (*aBufSize >= bytesrd + rv)
{
memcpy(aBuf + bytesrd, lbuf, rv);
bytesrd += rv;
if (rv <= bufsize)
{
FD_ZERO(&selset);
FD_SET(mFd, &selset);
seltime.tv_sec = 0;
seltime.tv_usec = kTimeoutSelectUsecs;
/* check if we still need to read from this socket */
rv = select(mFd+1, &selset, NULL, NULL, &seltime);
if (rv == 1)
rv = E_READ_MORE;
else
rv = OK;
break;
}
}
else
{
rv = E_SMALL_BUF;
break;
}
}
*aBufSize = bytesrd;
return rv;
}
int
nsSocket::Close()
{
int rv = OK, rv1 = OK, rv2 = OK;
rv1 = shutdown(mFd, SHUT_RDWR);
if (mListenFd > 0)
rv2 = shutdown(mListenFd, SHUT_RDWR);
if (rv1 != 0 || rv2 != 0)
rv = E_SOCK_CLOSE;
/* funky windows shutdown of winsock */
#ifdef _WINDOWS
int wsaErr = WSACleanup();
if (wsaErr != 0)
rv = wsaErr;
#endif
return rv;
}
int
nsSocket::GetHostPortString(char **aHostPort)
{
int rv = OK;
socklen_t salen;
struct sockaddr_in servaddr;
int hpsLen; // host-port string length
if (!aHostPort)
return E_PARAM;
salen = MAXSOCKADDR;
if ((getsockname(mListenFd, (struct sockaddr *) &servaddr, &salen)) < 0)
{
*aHostPort = NULL;
return E_GETSOCKNAME;
}
hpsLen = strlen("AA1,AA2,AA3,AA4,PP1,PP2");
*aHostPort = (char *) malloc(hpsLen);
if (!*aHostPort)
return E_MEM;
memset(*aHostPort, 0, hpsLen);
sprintf(*aHostPort, "%d,%d,%d,%d,%d,%d",
(int)((char*)&servaddr.sin_addr)[0] & 0xFF,
(int)((char*)&servaddr.sin_addr)[1] & 0xFF,
(int)((char*)&servaddr.sin_addr)[2] & 0xFF,
(int)((char*)&servaddr.sin_addr)[3] & 0xFF,
(int)((char*)&servaddr.sin_port)[0] & 0xFF,
(int)((char*)&servaddr.sin_port)[1] & 0xFF);
return rv;
}
float
nsSocket::CalcRate(struct timeval *aPre, struct timeval *aPost, int aBytes)
{
float diffUsecs, rate;
/* param check */
if (!aPre || !aPost || aBytes <= 0)
return 0;
diffUsecs = (float)(aPost->tv_sec - aPre->tv_sec) * kUsecsPerSec;
diffUsecs += (float)aPost->tv_usec - (float)aPre->tv_usec;
rate = ((float)(aBytes/kKilobyte))/
((float)(diffUsecs/kUsecsPerSec));
return rate;
}
#ifdef TEST_NSSOCKET
void
my_nprintf(char *buf, int len)
{
printf("buf size = %d\n", len);
for (int i = 0; i < len; ++i)
{
printf("%c", *(buf+i));
}
printf("\n");
}
const int kTestBufSize = 1024;
int
main(int argc, char **argv)
{
DUMP(("*** %s: A self-test for nsSocket.\n", argv[0]));
if (argc < 4)
{
fprintf(stderr, "usage: %s <host> <port> <http_url>\n",
argv[0]);
exit(1);
}
int rv = nsSocket::OK;
nsSocket *sock = new nsSocket(argv[1], atoi(argv[2]));
char buf[kTestBufSize];
int bufSize;
memset(buf, 0, kTestBufSize);
// open socket
rv = sock->Open();
DUMP(("nsSocket::Open returned: %d\n", rv));
// prepare http request str
sprintf(buf, "GET %s HTTP/1.1\r\n\r\n", argv[3]);
bufSize = strlen(buf) + 1; // add 1 for NULL termination
// make request
rv = sock->Send((unsigned char *)buf, &bufSize);
DUMP(("nsSocket::Send returned: %d\t and sent: %d bytes\n", rv, bufSize));
// get response
do {
// prepare response buf
memset(buf, 0, kTestBufSize);
bufSize = kTestBufSize;
rv = sock->Recv((unsigned char *)buf, &bufSize);
DUMP(("nsSocket::Recv returned: %d\t and recd: %d bytes\n",
rv, bufSize));
// DUMP(("%s\n", buf));
my_nprintf(buf, bufSize);
} while (rv == nsSocket::E_READ_MORE);
// close socket
rv = sock->Close();
DUMP(("nsSocket::Close returned: %d\n", rv));
return 0;
}
#endif /* TEST_NSSOCKET */

View File

@@ -1,112 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code,
* released March 31, 1998.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Samir Gehani <sgehani@netscape.com>
*/
#ifndef _NS_SOCKET_H_
#define _NS_SOCKET_H_
#ifndef _WINDOWS
#include <sys/time.h>
#endif
class nsSocket
{
public:
nsSocket(char *aHost, int aPort);
~nsSocket();
//----------------------------------------------------------------------
// Errors
//----------------------------------------------------------------------
enum
{
OK = 0,
E_PARAM = -1001,
E_MEM = -1002,
E_INVALID_HOST = -1003,
E_SOCK_OPEN = -1004,
E_SOCK_CLOSE = -1005,
E_TIMEOUT = -1006,
E_WRITE = -1007,
E_READ_MORE = -1008,
E_READ = -1009,
E_SMALL_BUF = -1010,
E_EOF_FOUND = -1011,
E_BIND = -1012,
E_LISTEN = -1014,
E_ACCEPT = -1015,
E_GETSOCKNAME = -1016,
E_WINSOCK = -1017
};
//----------------------------------------------------------------------
// Public interface
//----------------------------------------------------------------------
int Open();
int SrvOpen(); // server alternate to client Open()
int SrvAccept(); // must be called after SrvOpen()
int Send(unsigned char *aBuf, int *aBufSize);
int Recv(unsigned char *aBuf, int *aBufSize);
int Close();
int GetHostPortString(char **aHostPort);
static
float CalcRate(struct timeval *aPre, struct timeval *aPost, int aBytes);
private:
char *mHost;
int mPort;
int mFd; // connected socket
int mListenFd; // listening socket (only if SrvOpen() was called)
};
//----------------------------------------------------------------------
// Macro definitions
//----------------------------------------------------------------------
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#ifndef NULL
#define NULL ((void *) 0L)
#endif
#ifdef DUMP
#undef DUMP
#endif
#if defined(DEBUG) || defined(DEBUG_sgehani)
#define DUMP(_vargs) \
do { \
printf("%s %d: ", __FILE__, __LINE__); \
printf _vargs; \
} while (0);
#else
#define DUMP(_vargs)
#endif
#endif /* _NS_SOCKET_H_ */

View File

@@ -1,40 +0,0 @@
#
# The contents of this file are subject to the Netscape Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/NPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is Mozilla Communicator client code,
# released March 31, 1998.
#
# The Initial Developer of the Original Code is Netscape Communications
# Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
# Samir Gehani <sgehani@netscape.com>
#
DEPTH = ../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VAPTH = @srcdir@
include $(DEPTH)/config/autoconf.mk
CPPSRCS = TestLibxpnet.cpp
SIMPLE_PROGRAMS = $(CPPSRCS:.cpp=$(BIN_SUFFIX))
LIBS = -lxpnet_s
include $(topsrcdir)/config/rules.mk
INCLUDES += -I$(srcdir)/../src

View File

@@ -1,158 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code,
* released March 31, 1998.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Samir Gehani <sgehani@netscape.com>
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "nsFTPConn.h"
#include "nsHTTPConn.h"
const int kProxySrvrLen = 1024;
const char kHTTP[8] = "http://";
const char kFTP[7] = "ftp://";
const char kLoclFile[7] = "zzzFTP";
int
ProgressCB(int aBytesSoFar, int aTotalFinalSize)
{
printf(".");
return 0;
}
void
spew(char *funcName, int rv)
{
printf("%s returned %d\n", funcName, rv);
}
void
usage(char *prog)
{
fprintf(stderr, "usage: %s <URL> [ProxyServer ", prog);
fprintf(stderr, "ProxyPort [ProxyUserName ProxyPassword]\n");
}
int
main(int argc, char **argv)
{
char *proxyUser = 0, *proxyPswd = 0;
char proxyURL[kProxySrvrLen];
int rv = 0;
if (argc < 2)
{
usage(argv[0]);
exit(1);
}
/* has a proxy server been specified? */
if (argc >= 4)
{
memset(proxyURL, 0, kProxySrvrLen);
sprintf(proxyURL, "http://%s:%s", argv[2], argv[3]);
if (argc >=6)
{
proxyUser = argv[4];
proxyPswd = argv[5];
}
nsHTTPConn *conn = new nsHTTPConn(proxyURL);
conn->SetProxyInfo(argv[1], proxyUser, proxyPswd);
printf("Proxy URL: %s\n", argv[1]);
if (proxyUser && proxyPswd)
{
printf("Proxy User: %s\n", proxyUser);
printf("Proxy Pswd: %s\n", proxyPswd);
}
rv = conn->Open();
spew("nsHTTPConn::Open", rv);
rv = conn->Get(ProgressCB, NULL); // use leaf from URL
printf("\n"); // newline after progress completes
spew("nsHTTPConn::Get", rv);
rv = conn->Close();
spew("nsHTTPConn::Close", rv);
}
else
{
/* is this an HTTP URL? */
if (strncmp(argv[1], kHTTP, strlen(kHTTP)) == 0)
{
nsHTTPConn *conn = new nsHTTPConn(argv[1]);
rv = conn->Open();
spew("nsHTTPConn::Open", rv);
rv = conn->Get(ProgressCB, NULL);
printf("\n"); // newline after progress completes
spew("nsHTTPConn::Get", rv);
rv = conn->Close();
spew("nsHTTPConn::Close", rv);
}
/* or is this an FTP URL? */
else if (strncmp(argv[1], kFTP, strlen(kFTP)) == 0)
{
char *host = 0, *path = 0, *file = (char*) kLoclFile;
int port = 21;
rv = nsHTTPConn::ParseURL(kFTP, argv[1], &host, &port, &path);
spew("nsHTTPConn::ParseURL", rv);
nsFTPConn *conn = new nsFTPConn(host);
rv = conn->Open();
spew("nsFTPConn::Open", rv);
if (strrchr(path, '/') != (path + strlen(path)))
file = strrchr(path, '/') + 1; // set to leaf name
rv = conn->Get(path, file, nsFTPConn::BINARY, 1, ProgressCB);
printf("\n"); // newline after progress completes
spew("nsFTPConn::Get", rv);
rv = conn->Close();
spew("nsFTPConn::Close", rv);
if (host)
free(host);
if (path)
free(path);
}
/* or we don't understand the args */
else
{
fprintf(stderr, "Like, uhm, dude! I don't get you. ");
fprintf(stderr, "See usage...\n");
usage(argv[0]);
}
}
return 0;
}

View File

@@ -1,49 +0,0 @@
#!gmake
#
# The contents of this file are subject to the Netscape Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/NPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is Mozilla Communicator client code,
# released March 31, 1998.
#
# The Initial Developer of the Original Code is Netscape Communications
# Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
# Samir Gehani <sgehani@netscape.com>
#
MODULE=xpnet
DEPTH=..\..\..\..
MAKE_OBJ_TYPE=EXE
EXENAME=TestLibxpnet
PDBFILE=TestLibxpnet
MAPFILE=TestLibxpnet.map
PROGRAM=.\$(OBJDIR)\$(EXENAME).exe
OBJS=.\$(OBJDIR)\TestLibxpnet.obj
LINCS=-I..\src
LLIBS=$(DIST)\lib\$(MODULE)_s.lib
include <$(DEPTH)/config/rules.mak>
install:: $(PROGRAM)
$(MAKE_INSTALL) $(PROGRAM) $(DIST)\bin
clobber::
$(RM) $(DIST)\bin\$(EXENAME).exe