URLStorage.cxx revision 7c478bd95313f5f23a4c958a745db2134aa03244
// Copyright (c) 1995 James Clark
// See the file COPYING for copying permission.
#pragma ident "%Z%%M% %I% %E% SMI"
#ifdef __GNUG__
#pragma implementation
#endif
// FIXME This implementation won't work on an EBCDIC machine.
#include "splib.h"
#ifdef WINSOCK
#include <winsock.h>
#define readsocket(s, p, n) ::recv(s, p, n, 0)
#define writesocket(s, p, n) ::send(s, p, n, 0)
#define errnosocket (WSAGetLastError())
#define SocketMessageArg(n) WinsockMessageArg(n)
#define SOCKET_EINTR (WSAEINTR)
#define SP_HAVE_SOCKET
#else
#ifdef SP_HAVE_SOCKET
#include <netdb.h>
#ifdef SP_INCLUDE_UNISTD_H
#include <unistd.h>
#endif
#ifdef SP_INCLUDE_OSFCN_H
#include <osfcn.h>
#endif
#ifdef SP_DECLARE_H_ERRNO
extern int h_errno;
#endif
typedef int SOCKET;
#define SOCKET_ERROR (-1)
#define INVALID_SOCKET (-1)
#define SOCKET_EINTR (EINTR)
#define closesocket(s) close(s)
#define readsocket(s, p, n) ::read(s, p, n)
#define errnosocket (errno)
#define SocketMessageArg(n) ErrnoMessageArg(n)
#include "ErrnoMessageArg.h"
#endif /* SP_HAVE_SOCKET */
#endif /* not WINSOCK */
#include "URLStorage.h"
#include "URLStorageMessages.h"
#include "RewindStorageObject.h"
#include "UnivCharsetDesc.h"
#include "MessageArg.h"
#include "MessageBuilder.h"
#include "macros.h"
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <stddef.h>
#include <ctype.h>
#include <stdio.h>
#ifdef SP_NAMESPACE
namespace SP_NAMESPACE {
#endif
#ifdef SP_HAVE_SOCKET
class HttpSocketStorageObject : public RewindStorageObject {
public:
unsigned short port,
private:
void operator=(const HttpSocketStorageObject &); // undefined
};
#ifdef WINSOCK
class WinsockMessageArg : public MessageArg {
public:
WinsockMessageArg(int n) : n_(n) { }
void append(MessageBuilder &) const;
private:
int n_;
};
{
// I can't figure out how to get a string associated
// with this error number. FormatMessage() doesn't seem
// to work.
}
class WinsockIniter {
public:
~WinsockIniter();
private:
};
static WinsockIniter winsockIniter;
: inited_(0)
{
}
{
if (inited_ && initSuccess_)
(void)WSACleanup();
}
{
if (!inited_) {
inited_ = 1;
initSuccess_ = 0;
if (err)
WSACleanup();
}
else
initSuccess_ = 1;
}
return initSuccess_;
}
#endif /* WINSOCK */
#endif /* SP_HAVE_SOCKET */
{
}
const char *URLStorageManager::type() const
{
return type_;
}
const CharsetInfo &charset) const
{
return 0;
size_t i = 0;
for (const char *s = "http://"; *s; s++, i++)
return 0;
return 1;
}
{
#ifdef SP_HAVE_SOCKET
return 0;
}
return 0;
}
size_t i = 7;
if (id[i] == '/')
break;
if (id[i] == ':')
break;
i++;
}
return 0;
}
unsigned short port;
i++;
i++;
}
return 0;
}
digits += '\0';
char *endptr;
|| n < 0
|| n > 65535L) {
return 0;
}
port = (unsigned short)n;
}
else
port = 80;
i++;
}
}
path += '/';
host += '\0';
if (fd == INVALID_SOCKET)
return 0;
delete p;
return 0;
}
return p;
#else /* not SP_HAVE_SOCKET */
return 0;
#endif /* not SP_HAVE_SOCKET */
}
Boolean) const
{
static const char schemeChars[] =
"abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"01234567879"
"+-.";
size_t i;
// If it has a scheme, it is absolute.
if (id[i] == ':') {
if (i == 0)
break;
else
return 1;
}
break;
}
if (id[i] != '/')
break;
}
size_t slashCount = i;
if (slashCount > 0) {
Boolean foundSameSlash = 0;
size_t thisSlashCount = 0;
foundSameSlash = 1;
sameSlashPos = j;
}
else if (thisSlashCount > slashCount)
foundSameSlash = 0;
}
if (foundSameSlash) {
}
}
else {
size_t j;
break;
if (j > 0) {
}
}
// FIXME remove xxx/../, and /.
return 1;
}
Messenger &) const
{
if (fold)
if (c <= (unsigned char)-1)
}
return 1;
}
#ifdef SP_HAVE_SOCKET
unsigned short port,
{
#ifdef WINSOCK
return INVALID_SOCKET;
#endif
struct sockaddr_in sock;
if (n == (unsigned long)-1) {
return INVALID_SOCKET;
}
}
else {
if (!hp) {
const MessageType1 *message;
switch (h_errno) {
case HOST_NOT_FOUND:
break;
case TRY_AGAIN:
break;
case NO_RECOVERY:
break;
case NO_DATA:
#ifdef NO_ADDRESS
#if NO_ADDRESS != NO_DATA
case NO_ADDRESS:
#endif
#endif
break;
default:
#ifdef WINSOCK
return INVALID_SOCKET;
#else
break;
#endif
}
return INVALID_SOCKET;
}
}
if (fd == INVALID_SOCKET) {
return INVALID_SOCKET;
}
(void)closesocket(fd);
return INVALID_SOCKET;
}
return fd;
}
{
}
{
if (fd_ != INVALID_SOCKET)
(void)closesocket(fd_);
}
{
request += ' ';
// FIXME check length of write
(void)closesocket(fd_);
return 0;
}
if (!readHeader(mgr)) {
(void)closesocket(fd_);
return 0;
}
return 1;
}
{
return 0;
buf += '\0';
int val;
return 1;
}
ptr++;
}
return 0;
}
for (;;) {
return 0;
break;
}
return 1;
}
// Status line must start with: "HTTP/" 1*DIGIT "." 1*DIGIT SP 3DIGIT SP
{
static const char ver[] = "HTTP/";
if (*v != *ptr)
return 0;
return 0;
do {
++ptr;
if (*ptr != '.')
return 0;
ptr++;
return 0;
do {
++ptr;
if (*ptr != ' ')
return 0;
ptr++;
val = 0;
for (int i = 0; i < 3; i++, ptr++) {
return 0;
}
if (*ptr != ' ')
return 0;
ptr++;
return 1;
}
// True will be returned for an empty line.
{
if (hadCr) {
gotLine = 1;
break;
}
line += '\r';
hadCr = 1;
}
line += '\n';
li++;
gotLine = 1;
break;
}
else if (hadCr) {
gotLine = 1;
break;
}
else
}
if (gotLine) {
return 1;
}
if (eof_)
return 1;
for (;;) {
char c;
long n;
do {
} while (n < 0 && errnosocket == SOCKET_EINTR);
if (n == 0) {
(void)closesocket(fd_);
eof_ = 1;
return 1;
}
if (n < 0) {
(void)closesocket(fd_);
return 0;
}
switch (c) {
case '\r':
if (hadCr) {
leftOver += c;
return 1;
}
hadCr = 1;
line += c;
break;
case '\n':
line += c;
return 1;
default:
if (hadCr) {
leftOver += c;
return 1;
}
line += c;
break;
}
}
return 0; // not reached
}
{
return 1;
return 0;
long n;
do {
} while (n < 0 && errnosocket == SOCKET_EINTR);
if (n > 0) {
return 1;
}
if (n < 0) {
}
else {
eof_ = 1;
}
return 0;
}
{
return 0;
}
#endif /* SP_HAVE_SOCKET */
#ifdef SP_NAMESPACE
}
#endif