delete files with GPL License + modify build scripts
This commit is contained in:
@@ -880,6 +880,7 @@ set(UTIL_SRC
|
||||
${OPENAIR2_DIR}/UTIL/OMG/omg_hashtable.c
|
||||
${OPENAIR2_DIR}/UTIL/OMG/rwalk.c
|
||||
${OPENAIR2_DIR}/UTIL/OMG/rwp.c
|
||||
${OPENAIR2_DIR}/UTIL/OMG/sumo.c
|
||||
${OPENAIR2_DIR}/UTIL/OMG/socket_traci_OMG.c
|
||||
${OPENAIR2_DIR}/UTIL/OMG/static.c
|
||||
${OPENAIR2_DIR}/UTIL/OMG/steadystaterwp.c
|
||||
@@ -1797,7 +1798,6 @@ add_executable(oaisim_nos1
|
||||
${OPENAIR_TARGETS}/SIMU/USER/oaisim.c
|
||||
${OPENAIR2_DIR}/RRC/NAS/nas_config.c
|
||||
${OPENAIR2_DIR}/RRC/NAS/rb_config.c
|
||||
${OPENAIR2_DIR}/UTIL/OMG/sumo.c
|
||||
${OPENAIR_TARGETS}/COMMON/create_tasks.c
|
||||
${HW_SOURCE}
|
||||
${TRANSPORT_SOURCE}
|
||||
@@ -1882,7 +1882,6 @@ foreach(myExe s1ap
|
||||
aes128_cmac_encrypt
|
||||
secu_knas_encrypt_eia2)
|
||||
add_executable(test_${myExe}
|
||||
${OPENAIR3_DIR}/TEST/test_util.c
|
||||
${OPENAIR3_DIR}/TEST/test_${myExe}.c
|
||||
)
|
||||
target_link_libraries (test_${myExe}
|
||||
|
||||
@@ -6,20 +6,6 @@
|
||||
* By Gerald Combs <gerald@wireshark.org>
|
||||
* Copyright 1998 Gerald Combs
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* This header file may also be distributed under
|
||||
* the terms of the BSD Licence as follows:
|
||||
*
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
* \date 2009
|
||||
* \version 0.1
|
||||
* \company Eurecom
|
||||
* \note This conde is under GNU GENERAL PUBLIC LICENSE, version 2, June 1991
|
||||
* \email: navid.nikaein@eurecom.fr
|
||||
* \warning
|
||||
*/
|
||||
|
||||
@@ -1,414 +0,0 @@
|
||||
/**
|
||||
** \file Ajp13Socket.cpp
|
||||
** \date 2007-10-05
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2007-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4786)
|
||||
#endif
|
||||
#include "Ajp13Socket.h"
|
||||
#include "ajp13.h"
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define DEB(x) x
|
||||
#else
|
||||
#define DEB(x)
|
||||
#endif
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
Ajp13Socket::Ajp13Socket(ISocketHandler& h) : AjpBaseSocket(h)
|
||||
, m_body_size_left(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
void Ajp13Socket::OnHeader( short id, short len )
|
||||
{
|
||||
if (id != 0x1234)
|
||||
{
|
||||
DEB( fprintf(stderr, "ABORT: bad packet id: %x\n", id);)
|
||||
SetCloseAndDelete();
|
||||
}
|
||||
else
|
||||
{
|
||||
DEB(fprintf(stderr, "Packet size: %d bytes\n", len);)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
void Ajp13Socket::ReceiveBody(const char *buf, size_t sz)
|
||||
{
|
||||
if (sz - 2 > m_body_size_left)
|
||||
{
|
||||
DEB( fprintf(stderr, "More body data received than expected\n");)
|
||||
SetCloseAndDelete();
|
||||
return;
|
||||
}
|
||||
|
||||
m_req.Write( buf + 2, sz - 2 );
|
||||
m_body_size_left -= sz - 2;
|
||||
|
||||
// request more body data
|
||||
if (m_body_size_left)
|
||||
{
|
||||
int ptr = 4;
|
||||
char msg[100];
|
||||
msg[0] = 'A';
|
||||
msg[1] = 'B';
|
||||
|
||||
// reply codes
|
||||
// 0x3 Send Body Chunk
|
||||
// 0x4 Send Headers
|
||||
// 0x5 End Response
|
||||
// 0x6 Get Body Chunk <------
|
||||
// 0x9 CPong Reply
|
||||
|
||||
put_byte(msg, ptr, 0x06); // GET_BODY_CHUNK;
|
||||
put_integer(msg, ptr, 1000); // request 1000 bytes
|
||||
|
||||
short len = htons( ptr - 4 );
|
||||
memcpy( msg + 2, &len, 2 );
|
||||
|
||||
SendBuf( msg, ptr );
|
||||
return;
|
||||
}
|
||||
|
||||
// Close
|
||||
m_req.CloseBody();
|
||||
|
||||
// no more body data left to read - execute
|
||||
Execute();
|
||||
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
void Ajp13Socket::ReceiveForwardRequest( const char *buf, size_t sz )
|
||||
{
|
||||
//
|
||||
int ptr = 0;
|
||||
|
||||
get_byte(buf, ptr); // skip first byte: prefix_code
|
||||
unsigned char method = get_byte(buf, ptr);
|
||||
std::string protocol = get_string(buf, ptr);
|
||||
std::string req_uri = get_string(buf, ptr);
|
||||
std::string remote_addr = get_string(buf, ptr);
|
||||
std::string remote_host = get_string(buf, ptr);
|
||||
std::string server_name = get_string(buf, ptr);
|
||||
short server_port = get_integer(buf, ptr);
|
||||
bool is_ssl = get_boolean(buf, ptr);
|
||||
|
||||
std::string method_str = Utility::l2string( method );
|
||||
std::map<int, std::string>::const_iterator it = Init.Method.find( method );
|
||||
if (it != Init.Method.end())
|
||||
{
|
||||
method_str = it -> second;
|
||||
}
|
||||
m_req.SetHttpMethod( method_str );
|
||||
m_req.SetHttpVersion( protocol );
|
||||
m_req.SetUri( req_uri );
|
||||
m_req.SetRemoteAddr( remote_addr );
|
||||
m_req.SetRemoteHost( remote_host );
|
||||
m_req.SetServerName( server_name );
|
||||
m_req.SetServerPort( server_port );
|
||||
m_req.SetIsSsl( is_ssl );
|
||||
|
||||
// Get Headers
|
||||
short num_headers = get_integer(buf, ptr);
|
||||
for (int i = 0; i < num_headers; i++)
|
||||
{
|
||||
std::string key;
|
||||
switch ( (unsigned char)buf[ptr]) // 0xa0
|
||||
{
|
||||
case 0xa0:
|
||||
{
|
||||
unsigned short x = (unsigned short)get_integer(buf, ptr);
|
||||
std::map<int, std::string>::const_iterator it;
|
||||
if ( (it = Init.Header.find(x)) != Init.Header.end())
|
||||
{
|
||||
key = it -> second;
|
||||
}
|
||||
else
|
||||
{
|
||||
DEB( fprintf(stderr, "Unknown header key value: %x\n", x);)
|
||||
SetCloseAndDelete();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default: // string
|
||||
key = get_string(buf, ptr);
|
||||
}
|
||||
if (Utility::ToLower(key) == "cookie" || Utility::ToLower(key) == "cookie2")
|
||||
m_req.AddCookie(get_string(buf, ptr));
|
||||
else
|
||||
m_req.SetHeader(key, get_string(buf, ptr));
|
||||
} // for
|
||||
|
||||
// size left to read from web server
|
||||
m_body_size_left = m_req.ContentLength();
|
||||
|
||||
// Get Attributes
|
||||
while ( (unsigned char)buf[ptr] != 0xff)
|
||||
{
|
||||
std::string key;
|
||||
unsigned char code = buf[ptr++];
|
||||
switch ( code)
|
||||
{
|
||||
case 10: // req_attribute, attribute name follow
|
||||
key = get_string(buf, ptr);
|
||||
break;
|
||||
default:
|
||||
{
|
||||
std::map<int, std::string>::const_iterator it = Init.Attribute.find( code );
|
||||
if (it != Init.Attribute.end())
|
||||
{
|
||||
key = it -> second;
|
||||
}
|
||||
else
|
||||
{
|
||||
DEB( fprintf(stderr, "Unknown attribute key: 0x%02x\n", buf[ptr]);)
|
||||
SetCloseAndDelete();
|
||||
}
|
||||
}
|
||||
}
|
||||
m_req.SetAttribute(key, get_string(buf, ptr));
|
||||
} // while
|
||||
|
||||
// execute at once if no body data
|
||||
if (!m_body_size_left)
|
||||
{
|
||||
Execute();
|
||||
}
|
||||
else
|
||||
{
|
||||
// open temporary file for body data
|
||||
m_req.InitBody( m_body_size_left );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
void Ajp13Socket::ReceiveShutdown( const char *buf, size_t sz )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
void Ajp13Socket::ReceivePing( const char *buf, size_t sz )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
void Ajp13Socket::ReceiveCPing( const char *buf, size_t sz )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
void Ajp13Socket::Execute()
|
||||
{
|
||||
// parse form data / query_string and cookie header if available
|
||||
m_req.ParseBody();
|
||||
|
||||
// prepare page
|
||||
OnExec( m_req );
|
||||
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
void Ajp13Socket::Respond(const HttpResponse& res)
|
||||
{
|
||||
char msg[8192];
|
||||
msg[0] = 'A';
|
||||
msg[1] = 'B';
|
||||
|
||||
m_res = res;
|
||||
|
||||
// reply codes
|
||||
// 0x3 Send Body Chunk
|
||||
// 0x4 Send Headers
|
||||
// 0x5 End Response
|
||||
// 0x6 Get Body Chunk
|
||||
// 0x9 CPong Reply
|
||||
|
||||
// check content length
|
||||
if (!m_res.ContentLength() && m_res.GetFile().size())
|
||||
{
|
||||
// m_res.SetContentLength( m_res.GetFile().size() );
|
||||
}
|
||||
|
||||
// Send Headers
|
||||
{
|
||||
int ptr = 4;
|
||||
put_byte(msg, ptr, 0x04); // send headers
|
||||
put_integer(msg, ptr, m_res.HttpStatusCode() );
|
||||
put_string(msg, ptr, m_res.HttpStatusMsg() );
|
||||
put_integer(msg, ptr, (short)m_res.Headers().size() );
|
||||
for (Utility::ncmap<std::string>::const_iterator it = m_res.Headers().begin(); it != m_res.Headers().end(); ++it)
|
||||
{
|
||||
Utility::ncmap<int>::const_iterator it2 = Init.ResponseHeader.find( it -> first );
|
||||
if (it2 != Init.ResponseHeader.end())
|
||||
{
|
||||
put_integer(msg, ptr, it2 -> second);
|
||||
}
|
||||
else
|
||||
{
|
||||
put_string(msg, ptr, it -> first);
|
||||
}
|
||||
put_string(msg, ptr, it -> second);
|
||||
}
|
||||
std::list<std::string> vec = m_res.CookieNames();
|
||||
{
|
||||
for (std::list<std::string>::iterator it = vec.begin(); it != vec.end(); ++it)
|
||||
{
|
||||
Utility::ncmap<int>::const_iterator it2 = Init.ResponseHeader.find( "set-cookie" );
|
||||
if (it2 != Init.ResponseHeader.end())
|
||||
{
|
||||
put_integer(msg, ptr, it2 -> second);
|
||||
}
|
||||
else
|
||||
{
|
||||
put_string(msg, ptr, "set-cookie");
|
||||
}
|
||||
put_string(msg, ptr, m_res.Cookie(*it) );
|
||||
}
|
||||
}
|
||||
|
||||
short len = htons( ptr - 4 );
|
||||
memcpy( msg + 2, &len, 2 );
|
||||
|
||||
SendBuf( msg, ptr );
|
||||
}
|
||||
// Send Body Chunk
|
||||
OnTransferLimit();
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
void Ajp13Socket::OnTransferLimit()
|
||||
{
|
||||
char msg[8192];
|
||||
msg[0] = 'A';
|
||||
msg[1] = 'B';
|
||||
|
||||
// Send Body Chunk
|
||||
size_t n = m_res.GetFile().fread(msg + 7, 1, 8100);
|
||||
while (n > 0)
|
||||
{
|
||||
int ptr = 4;
|
||||
put_byte(msg, ptr, 0x03); // send body chunk
|
||||
put_integer(msg, ptr, (short)n);
|
||||
ptr += (int)n;
|
||||
|
||||
short len = htons( ptr - 4 );
|
||||
memcpy( msg + 2, &len, 2 );
|
||||
|
||||
SendBuf( msg, ptr );
|
||||
if (GetOutputLength() > 1)
|
||||
{
|
||||
SetTransferLimit( 1 );
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
n = m_res.GetFile().fread(msg + 7, 1, 8100);
|
||||
}
|
||||
if (!GetOutputLength()) // all body data sent and no data in output buffer - send end response
|
||||
{
|
||||
// End Response
|
||||
int ptr = 4;
|
||||
put_byte(msg, ptr, 0x05); // end response
|
||||
put_boolean(msg, ptr, false); // reuse
|
||||
/*
|
||||
don't reuse
|
||||
- but with m_req.Reset() and m_res.Reset() it should be possible
|
||||
- also reset any AjpBaseSocket/Ajp13Socket specific states
|
||||
*/
|
||||
|
||||
short len = htons( ptr - 4 );
|
||||
memcpy( msg + 2, &len, 2 );
|
||||
|
||||
SendBuf( msg, ptr );
|
||||
|
||||
SetTransferLimit(0);
|
||||
m_res.GetFile().fclose();
|
||||
OnResponseComplete();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
void Ajp13Socket::OnPacket( const char *buf, size_t sz )
|
||||
{
|
||||
DEB(fprintf(stderr, "OnPacket: %d bytes, code 0x%02x %02x %02x %02x\n", sz, *buf, buf[1], buf[2], buf[3]);)
|
||||
|
||||
// check body size left to read, if non-zero packet is body data
|
||||
if (m_body_size_left) // must be a body packet
|
||||
{
|
||||
ReceiveBody(buf, sz);
|
||||
return;
|
||||
}
|
||||
switch (*buf)
|
||||
{
|
||||
case 0x2: // Forward Request
|
||||
ReceiveForwardRequest(buf, sz);
|
||||
break;
|
||||
case 0x7: // Shutdown
|
||||
ReceiveShutdown(buf, sz);
|
||||
break;
|
||||
case 0x8: // Ping
|
||||
ReceivePing(buf, sz);
|
||||
break;
|
||||
case 0xa: // CPing
|
||||
ReceiveCPing(buf, sz);
|
||||
break;
|
||||
default:
|
||||
DEB( fprintf(stderr, "Unknown packet type: 0x%02x\n", *buf);)
|
||||
SetCloseAndDelete();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
} // namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
/**
|
||||
** \file Ajp13Socket.h
|
||||
** \date 2007-10-05
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2007-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef _SOCKETS_Ajp13Socket_H
|
||||
#define _SOCKETS_Ajp13Socket_H
|
||||
|
||||
#include "AjpBaseSocket.h"
|
||||
#include "HttpRequest.h"
|
||||
#include "IHttpServer.h"
|
||||
#include "HttpResponse.h"
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
|
||||
class HttpResponse;
|
||||
|
||||
class Ajp13Socket : public AjpBaseSocket, public IHttpServer
|
||||
{
|
||||
public:
|
||||
Ajp13Socket(ISocketHandler& h);
|
||||
|
||||
void OnHeader( short id, short len );
|
||||
void OnPacket( const char *buf, size_t sz );
|
||||
|
||||
// implements IHttpServer::Respond
|
||||
void Respond(const HttpResponse& res);
|
||||
|
||||
void OnTransferLimit();
|
||||
|
||||
private:
|
||||
void ReceiveBody( const char *buf, size_t sz );
|
||||
void ReceiveForwardRequest( const char *buf, size_t sz );
|
||||
void ReceiveShutdown( const char *buf, size_t sz );
|
||||
void ReceivePing( const char *buf, size_t sz );
|
||||
void ReceiveCPing( const char *buf, size_t sz );
|
||||
void Execute();
|
||||
//
|
||||
size_t m_body_size_left;
|
||||
HttpRequest m_req;
|
||||
HttpResponse m_res;
|
||||
};
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
} // namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
#endif // _SOCKETS_Ajp13Socket_H
|
||||
|
||||
@@ -1,268 +0,0 @@
|
||||
/**
|
||||
** \file AjpBaseSocket.cpp
|
||||
** \date 2007-10-05
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2007-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4786)
|
||||
#endif
|
||||
#include "AjpBaseSocket.h"
|
||||
#include "ajp13.h"
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define DEB(x) x
|
||||
#else
|
||||
#define DEB(x)
|
||||
#endif
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
AjpBaseSocket::Initializer AjpBaseSocket::Init;
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
AjpBaseSocket::Initializer::Initializer()
|
||||
{
|
||||
|
||||
Header[HTTP_REQUEST_ACCEPT] = "accept";
|
||||
Header[HTTP_REQUEST_ACCEPT_CHARSET] = "accept-charset";
|
||||
Header[HTTP_REQUEST_ACCEPT_ENCODING] = "accept-encoding";
|
||||
Header[HTTP_REQUEST_ACCEPT_LANGUAGE] = "accept-language";
|
||||
Header[HTTP_REQUEST_AUTHORIZATION] = "authorization";
|
||||
Header[HTTP_REQUEST_CONNECTION] = "connection";
|
||||
Header[HTTP_REQUEST_CONTENT_TYPE] = "content-type";
|
||||
Header[HTTP_REQUEST_CONTENT_LENGTH] = "content-length";
|
||||
Header[HTTP_REQUEST_COOKIE] = "cookie";
|
||||
Header[HTTP_REQUEST_COOKIE2] = "cookie2";
|
||||
Header[HTTP_REQUEST_HOST] = "host";
|
||||
Header[HTTP_REQUEST_PRAGMA] = "pragma";
|
||||
Header[HTTP_REQUEST_REFERER] = "referer";
|
||||
Header[HTTP_REQUEST_USER_AGENT] = "user-agent";
|
||||
|
||||
Method[HTTP_METHOD_OPTIONS] = "OPTIONS";
|
||||
Method[HTTP_METHOD_GET] = "GET";
|
||||
Method[HTTP_METHOD_HEAD] = "HEAD";
|
||||
Method[HTTP_METHOD_POST] = "POST";
|
||||
Method[HTTP_METHOD_PUT] = "PUT";
|
||||
Method[HTTP_METHOD_DELETE] = "DELETE";
|
||||
Method[HTTP_METHOD_TRACE] = "TRACE";
|
||||
Method[HTTP_METHOD_PROPFIND] = "PROPFIND";
|
||||
Method[HTTP_METHOD_PROPPATCH] = "PROPPATCH";
|
||||
Method[HTTP_METHOD_MKCOL] = "MKCOL";
|
||||
Method[HTTP_METHOD_COPY] = "COPY";
|
||||
Method[HTTP_METHOD_MOVE] = "MOVE";
|
||||
Method[HTTP_METHOD_LOCK] = "LOCK";
|
||||
Method[HTTP_METHOD_UNLOCK] = "UNLOCK";
|
||||
Method[HTTP_METHOD_ACL] = "ACL";
|
||||
Method[HTTP_METHOD_REPORT] = "REPORT";
|
||||
Method[HTTP_METHOD_VERSION_CONTROL] = "VERSION_CONTROL"; // with a dash "VERSION-CONTROL"
|
||||
Method[HTTP_METHOD_CHECKIN] = "CHECKIN";
|
||||
Method[HTTP_METHOD_CHECKOUT] = "CHECKOUT";
|
||||
Method[HTTP_METHOD_UNCHECKOUT] = "UNCHECKOUT";
|
||||
Method[HTTP_METHOD_SEARCH] = "SEARCH";
|
||||
Method[HTTP_METHOD_MKWORKSPACE] = "MKWORKSPACE";
|
||||
Method[HTTP_METHOD_UPDATE] = "UPDATE";
|
||||
Method[HTTP_METHOD_LABEL] = "LABEL";
|
||||
Method[HTTP_METHOD_MERGE] = "MERGE";
|
||||
Method[HTTP_METHOD_BASELINE_CONTROL] = "BASELINE_CONTROL";
|
||||
Method[HTTP_METHOD_MKACTIVITY] = "MKACTIVITY";
|
||||
|
||||
Attribute[ATTR_CONTEXT] = "context";
|
||||
Attribute[ATTR_SERVLET_PATH] = "servlet_path";
|
||||
Attribute[ATTR_REMOTE_USER] = "remote_user";
|
||||
Attribute[ATTR_AUTH_TYPE] = "auth_type";
|
||||
Attribute[ATTR_QUERY_STRING] = "query_string";
|
||||
Attribute[ATTR_ROUTE] = "route";
|
||||
Attribute[ATTR_SSL_CERT] = "ssl_cert";
|
||||
Attribute[ATTR_SSL_CIPHER] = "ssl_cipher";
|
||||
Attribute[ATTR_SSL_SESSION] = "ssl_session";
|
||||
Attribute[ATTR_SSL_KEY_SIZE] = "ssl_key_size";
|
||||
Attribute[ATTR_SECRET] = "secret";
|
||||
Attribute[ATTR_STORED_METHOD] = "stored_method";
|
||||
|
||||
ResponseHeader["content-type"] = 0xa001;
|
||||
ResponseHeader["content-language"] = 0xa002;
|
||||
ResponseHeader["content-length"] = 0xa003;
|
||||
ResponseHeader["date"] = 0xa004;
|
||||
ResponseHeader["last-modified"] = 0xa005;
|
||||
ResponseHeader["location"] = 0xa006;
|
||||
ResponseHeader["set-cookie"] = 0xa007;
|
||||
ResponseHeader["set-cookie2"] = 0xa008;
|
||||
ResponseHeader["servlet-engine"] = 0xa009;
|
||||
ResponseHeader["status"] = 0xa00a;
|
||||
ResponseHeader["www-authenticate"] = 0xa00b;
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
AjpBaseSocket::AjpBaseSocket(ISocketHandler& h) : TcpSocket(h)
|
||||
, m_state(0)
|
||||
, m_length(4)
|
||||
, m_ptr(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
void AjpBaseSocket::OnRawData(const char *buf, size_t sz)
|
||||
{
|
||||
DEB(fprintf(stderr, "OnRawData: %d bytes\n", sz);)
|
||||
size_t ptr = 0;
|
||||
while (true)
|
||||
{
|
||||
size_t left = sz - ptr;
|
||||
DEB(fprintf(stderr, " left: %d bytes\n", left);
|
||||
fprintf(stderr, " state: %d\n", m_state);)
|
||||
switch (m_state)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
size_t missing = m_length - m_ptr;
|
||||
short len = (short)(missing < left ? missing : left);
|
||||
memcpy(m_message + m_ptr, buf + ptr, len);
|
||||
m_ptr += len;
|
||||
ptr += len;
|
||||
if (m_ptr < m_length)
|
||||
{
|
||||
return; // read more
|
||||
}
|
||||
int p = 0;
|
||||
short id = get_integer(m_message, p);
|
||||
short length = get_integer(m_message, p);
|
||||
OnHeader(id, length);
|
||||
m_state = 1;
|
||||
m_length = length;
|
||||
m_ptr = 0; // bytes in m_message
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
{
|
||||
size_t missing = m_length - m_ptr;
|
||||
short len = (short)(missing < left ? missing : left);
|
||||
memcpy(m_message + m_ptr, buf + ptr, len);
|
||||
m_ptr += len;
|
||||
ptr += len;
|
||||
if (m_ptr < m_length)
|
||||
{
|
||||
return; // read more
|
||||
}
|
||||
OnPacket(m_message, m_ptr);
|
||||
m_state = 0;
|
||||
m_length = 4;
|
||||
m_ptr = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
unsigned char AjpBaseSocket::get_byte(const char *buf, int& ptr)
|
||||
{
|
||||
return (unsigned char)buf[ptr++];
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
bool AjpBaseSocket::get_boolean(const char *buf, int& ptr)
|
||||
{
|
||||
return ( (unsigned char)buf[ptr++] & 1) == 1 ? true : false;
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
short AjpBaseSocket::get_integer(const char *buf, int& ptr)
|
||||
{
|
||||
short n;
|
||||
memcpy(&n, buf + ptr, 2);
|
||||
ptr += 2;
|
||||
return ntohs(n);
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
std::string AjpBaseSocket::get_string(const char *buf, int& ptr)
|
||||
{
|
||||
short len = get_integer(buf, ptr);
|
||||
if (len != -1)
|
||||
{
|
||||
std::string tmp = buf + ptr;
|
||||
ptr += len;
|
||||
ptr++; // skip trailing 0x0
|
||||
tmp.resize(len);
|
||||
return tmp;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
void AjpBaseSocket::put_byte(char *buf, int& ptr, unsigned char zz)
|
||||
{
|
||||
buf[ptr++] = zz;
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
void AjpBaseSocket::put_boolean(char *buf, int& ptr, bool zz)
|
||||
{
|
||||
buf[ptr++] = zz ? 1 : 0;
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
void AjpBaseSocket::put_integer(char *buf, int& ptr, short zz)
|
||||
{
|
||||
short tmp = htons(zz);
|
||||
memcpy(buf + ptr, &tmp, 2);
|
||||
ptr += 2;
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
void AjpBaseSocket::put_string(char *buf, int& ptr, const std::string& zz)
|
||||
{
|
||||
put_integer(buf, ptr, (short)zz.size() );
|
||||
memcpy(buf + ptr, zz.c_str(), zz.size());
|
||||
ptr += (int)zz.size();
|
||||
put_byte(buf, ptr, 0);
|
||||
}
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
} // namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,96 +0,0 @@
|
||||
/**
|
||||
** \file AjpBaseSocket.h
|
||||
** \date 2007-10-05
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2007-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef _SOCKETS_AjpBaseSocket_H
|
||||
#define _SOCKETS_AjpBaseSocket_H
|
||||
|
||||
#include "TcpSocket.h"
|
||||
#include <map>
|
||||
#include "Utility.h"
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
class AjpBaseSocket : public TcpSocket
|
||||
{
|
||||
class Initializer
|
||||
{
|
||||
public:
|
||||
Initializer();
|
||||
virtual ~Initializer() {}
|
||||
|
||||
std::map<int, std::string> Method;
|
||||
std::map<int, std::string> Header;
|
||||
std::map<int, std::string> Attribute;
|
||||
|
||||
Utility::ncmap<int> ResponseHeader;
|
||||
|
||||
};
|
||||
|
||||
public:
|
||||
AjpBaseSocket(ISocketHandler& h);
|
||||
|
||||
void OnRawData(const char *buf, size_t sz);
|
||||
|
||||
virtual void OnHeader( short id, short len ) = 0;
|
||||
virtual void OnPacket( const char *buf, size_t sz ) = 0;
|
||||
|
||||
protected:
|
||||
unsigned char get_byte(const char *buf, int& ptr);
|
||||
bool get_boolean(const char *buf, int& ptr);
|
||||
short get_integer(const char *buf, int& ptr);
|
||||
std::string get_string(const char *buf, int& ptr);
|
||||
|
||||
void put_byte(char *buf, int& ptr, unsigned char zz);
|
||||
void put_boolean(char *buf, int& ptr, bool zz);
|
||||
void put_integer(char *buf, int& ptr, short zz);
|
||||
void put_string(char *buf, int& ptr, const std::string& zz);
|
||||
|
||||
static Initializer Init;
|
||||
|
||||
private:
|
||||
int m_state;
|
||||
int m_length;
|
||||
int m_ptr;
|
||||
char m_message[8192];
|
||||
};
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
} // namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
#endif // _SOCKETS_AjpBaseSocket_H
|
||||
|
||||
@@ -1,314 +0,0 @@
|
||||
/** \file Base64.cpp
|
||||
** \date 2004-02-13
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2004-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#include "Base64.h"
|
||||
#include "IFile.h"
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
|
||||
const char *Base64::bstr =
|
||||
"ABCDEFGHIJKLMNOPQ"
|
||||
"RSTUVWXYZabcdefgh"
|
||||
"ijklmnopqrstuvwxy"
|
||||
"z0123456789+/";
|
||||
|
||||
const char Base64::rstr[] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 63,
|
||||
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
||||
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0,
|
||||
0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
|
||||
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 0, 0, 0, 0, 0};
|
||||
|
||||
|
||||
Base64::Base64()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void Base64::encode(IFile *fil, std::string& output, bool add_crlf)
|
||||
{
|
||||
size_t remain;
|
||||
size_t i = 0;
|
||||
size_t o = 0;
|
||||
char input[4];
|
||||
|
||||
output = "";
|
||||
remain = fil -> fread(input,1,3);
|
||||
while (remain > 0)
|
||||
{
|
||||
if (add_crlf && o && o % 76 == 0)
|
||||
output += "\n";
|
||||
switch (remain)
|
||||
{
|
||||
case 1:
|
||||
output += bstr[ ((input[i] >> 2) & 0x3f) ];
|
||||
output += bstr[ ((input[i] << 4) & 0x30) ];
|
||||
output += "==";
|
||||
break;
|
||||
case 2:
|
||||
output += bstr[ ((input[i] >> 2) & 0x3f) ];
|
||||
output += bstr[ ((input[i] << 4) & 0x30) + ((input[i + 1] >> 4) & 0x0f) ];
|
||||
output += bstr[ ((input[i + 1] << 2) & 0x3c) ];
|
||||
output += "=";
|
||||
break;
|
||||
default:
|
||||
output += bstr[ ((input[i] >> 2) & 0x3f) ];
|
||||
output += bstr[ ((input[i] << 4) & 0x30) + ((input[i + 1] >> 4) & 0x0f) ];
|
||||
output += bstr[ ((input[i + 1] << 2) & 0x3c) + ((input[i + 2] >> 6) & 0x03) ];
|
||||
output += bstr[ (input[i + 2] & 0x3f) ];
|
||||
}
|
||||
o += 4;
|
||||
//
|
||||
remain = fil -> fread(input,1,3);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Base64::encode(FILE *fil, std::string& output, bool add_crlf)
|
||||
{
|
||||
size_t remain;
|
||||
size_t i = 0;
|
||||
size_t o = 0;
|
||||
char input[4];
|
||||
|
||||
output = "";
|
||||
remain = fread(input,1,3,fil);
|
||||
while (remain > 0)
|
||||
{
|
||||
if (add_crlf && o && o % 76 == 0)
|
||||
output += "\n";
|
||||
switch (remain)
|
||||
{
|
||||
case 1:
|
||||
output += bstr[ ((input[i] >> 2) & 0x3f) ];
|
||||
output += bstr[ ((input[i] << 4) & 0x30) ];
|
||||
output += "==";
|
||||
break;
|
||||
case 2:
|
||||
output += bstr[ ((input[i] >> 2) & 0x3f) ];
|
||||
output += bstr[ ((input[i] << 4) & 0x30) + ((input[i + 1] >> 4) & 0x0f) ];
|
||||
output += bstr[ ((input[i + 1] << 2) & 0x3c) ];
|
||||
output += "=";
|
||||
break;
|
||||
default:
|
||||
output += bstr[ ((input[i] >> 2) & 0x3f) ];
|
||||
output += bstr[ ((input[i] << 4) & 0x30) + ((input[i + 1] >> 4) & 0x0f) ];
|
||||
output += bstr[ ((input[i + 1] << 2) & 0x3c) + ((input[i + 2] >> 6) & 0x03) ];
|
||||
output += bstr[ (input[i + 2] & 0x3f) ];
|
||||
}
|
||||
o += 4;
|
||||
//
|
||||
remain = fread(input,1,3,fil);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Base64::encode(const std::string& str_in, std::string& str_out, bool add_crlf)
|
||||
{
|
||||
encode(str_in.c_str(), str_in.size(), str_out, add_crlf);
|
||||
}
|
||||
|
||||
|
||||
void Base64::encode(const char* input,size_t l,std::string& output, bool add_crlf)
|
||||
{
|
||||
size_t i = 0;
|
||||
size_t o = 0;
|
||||
|
||||
output = "";
|
||||
while (i < l)
|
||||
{
|
||||
size_t remain = l - i;
|
||||
if (add_crlf && o && o % 76 == 0)
|
||||
output += "\n";
|
||||
switch (remain)
|
||||
{
|
||||
case 1:
|
||||
output += bstr[ ((input[i] >> 2) & 0x3f) ];
|
||||
output += bstr[ ((input[i] << 4) & 0x30) ];
|
||||
output += "==";
|
||||
break;
|
||||
case 2:
|
||||
output += bstr[ ((input[i] >> 2) & 0x3f) ];
|
||||
output += bstr[ ((input[i] << 4) & 0x30) + ((input[i + 1] >> 4) & 0x0f) ];
|
||||
output += bstr[ ((input[i + 1] << 2) & 0x3c) ];
|
||||
output += "=";
|
||||
break;
|
||||
default:
|
||||
output += bstr[ ((input[i] >> 2) & 0x3f) ];
|
||||
output += bstr[ ((input[i] << 4) & 0x30) + ((input[i + 1] >> 4) & 0x0f) ];
|
||||
output += bstr[ ((input[i + 1] << 2) & 0x3c) + ((input[i + 2] >> 6) & 0x03) ];
|
||||
output += bstr[ (input[i + 2] & 0x3f) ];
|
||||
}
|
||||
o += 4;
|
||||
i += 3;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Base64::encode(const unsigned char* input,size_t l,std::string& output,bool add_crlf)
|
||||
{
|
||||
size_t i = 0;
|
||||
size_t o = 0;
|
||||
|
||||
output = "";
|
||||
while (i < l)
|
||||
{
|
||||
size_t remain = l - i;
|
||||
if (add_crlf && o && o % 76 == 0)
|
||||
output += "\n";
|
||||
switch (remain)
|
||||
{
|
||||
case 1:
|
||||
output += bstr[ ((input[i] >> 2) & 0x3f) ];
|
||||
output += bstr[ ((input[i] << 4) & 0x30) ];
|
||||
output += "==";
|
||||
break;
|
||||
case 2:
|
||||
output += bstr[ ((input[i] >> 2) & 0x3f) ];
|
||||
output += bstr[ ((input[i] << 4) & 0x30) + ((input[i + 1] >> 4) & 0x0f) ];
|
||||
output += bstr[ ((input[i + 1] << 2) & 0x3c) ];
|
||||
output += "=";
|
||||
break;
|
||||
default:
|
||||
output += bstr[ ((input[i] >> 2) & 0x3f) ];
|
||||
output += bstr[ ((input[i] << 4) & 0x30) + ((input[i + 1] >> 4) & 0x0f) ];
|
||||
output += bstr[ ((input[i + 1] << 2) & 0x3c) + ((input[i + 2] >> 6) & 0x03) ];
|
||||
output += bstr[ (input[i + 2] & 0x3f) ];
|
||||
}
|
||||
o += 4;
|
||||
i += 3;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Base64::decode(const std::string& input,std::string& output)
|
||||
{
|
||||
size_t i = 0;
|
||||
size_t l = input.size();
|
||||
|
||||
output = "";
|
||||
while (i < l)
|
||||
{
|
||||
while (i < l && (input[i] == 13 || input[i] == 10))
|
||||
i++;
|
||||
if (i < l)
|
||||
{
|
||||
char b1 = (char)((rstr[(int)input[i]] << 2 & 0xfc) +
|
||||
(rstr[(int)input[i + 1]] >> 4 & 0x03));
|
||||
output += b1;
|
||||
if (input[i + 2] != '=')
|
||||
{
|
||||
char b2 = (char)((rstr[(int)input[i + 1]] << 4 & 0xf0) +
|
||||
(rstr[(int)input[i + 2]] >> 2 & 0x0f));
|
||||
output += b2;
|
||||
}
|
||||
if (input[i + 3] != '=')
|
||||
{
|
||||
char b3 = (char)((rstr[(int)input[i + 2]] << 6 & 0xc0) +
|
||||
rstr[(int)input[i + 3]]);
|
||||
output += b3;
|
||||
}
|
||||
i += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Base64::decode(const std::string& input, unsigned char *output, size_t& sz)
|
||||
{
|
||||
size_t i = 0;
|
||||
size_t l = input.size();
|
||||
size_t j = 0;
|
||||
|
||||
while (i < l)
|
||||
{
|
||||
while (i < l && (input[i] == 13 || input[i] == 10))
|
||||
i++;
|
||||
if (i < l)
|
||||
{
|
||||
unsigned char b1 = (unsigned char)((rstr[(int)input[i]] << 2 & 0xfc) +
|
||||
(rstr[(int)input[i + 1]] >> 4 & 0x03));
|
||||
if (output)
|
||||
{
|
||||
output[j] = b1;
|
||||
}
|
||||
j++;
|
||||
if (input[i + 2] != '=')
|
||||
{
|
||||
unsigned char b2 = (unsigned char)((rstr[(int)input[i + 1]] << 4 & 0xf0) +
|
||||
(rstr[(int)input[i + 2]] >> 2 & 0x0f));
|
||||
if (output)
|
||||
{
|
||||
output[j] = b2;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
if (input[i + 3] != '=')
|
||||
{
|
||||
unsigned char b3 = (unsigned char)((rstr[(int)input[i + 2]] << 6 & 0xc0) +
|
||||
rstr[(int)input[i + 3]]);
|
||||
if (output)
|
||||
{
|
||||
output[j] = b3;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
i += 4;
|
||||
}
|
||||
}
|
||||
sz = j;
|
||||
}
|
||||
|
||||
|
||||
size_t Base64::decode_length(const std::string& str64)
|
||||
{
|
||||
if (!str64.size() || str64.size() % 4)
|
||||
return 0;
|
||||
size_t l = 3 * (str64.size() / 4 - 1) + 1;
|
||||
if (str64[str64.size() - 2] != '=')
|
||||
l++;
|
||||
if (str64[str64.size() - 1] != '=')
|
||||
l++;
|
||||
return l;
|
||||
}
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
/** \file Base64.h
|
||||
** \date 2004-02-13
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2004-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef _SOCKETS_Base64_H
|
||||
#define _SOCKETS_Base64_H
|
||||
|
||||
#include "sockets-config.h"
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4514)
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
class IFile;
|
||||
|
||||
/** \defgroup util Utilities */
|
||||
|
||||
/** Base64 encode/decode.
|
||||
\ingroup util */
|
||||
class Base64
|
||||
{
|
||||
public:
|
||||
Base64();
|
||||
|
||||
void encode(FILE *, std::string& , bool add_crlf = true);
|
||||
void encode(IFile *, std::string& , bool add_crlf = true);
|
||||
void encode(const std::string&, std::string& , bool add_crlf = true);
|
||||
void encode(const char *, size_t, std::string& , bool add_crlf = true);
|
||||
void encode(const unsigned char *, size_t, std::string& , bool add_crlf = true);
|
||||
|
||||
void decode(const std::string&, std::string& );
|
||||
void decode(const std::string&, unsigned char *, size_t&);
|
||||
|
||||
size_t decode_length(const std::string& );
|
||||
|
||||
private:
|
||||
Base64(const Base64& ) {}
|
||||
Base64& operator=(const Base64& ) {
|
||||
return *this;
|
||||
}
|
||||
static const char *bstr;
|
||||
static const char rstr[128];
|
||||
};
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _SOCKETS_Base64_H
|
||||
|
||||
@@ -1,855 +0,0 @@
|
||||
diff for next release always available @ http://www.alhem.net/Sockets/latest_diff.html
|
||||
|
||||
next
|
||||
--------
|
||||
|
||||
|
||||
2.3.9.4
|
||||
--------
|
||||
File can be created using an existing FILE *. Fix bug in File using wrong
|
||||
file ptr when writing.
|
||||
Added HttpdForm constructor (FILE *) that detects cgi input using
|
||||
environment variables.
|
||||
Added HttpRequest constructor (FILE *) that can parse a cgi request.
|
||||
Added missing sockets namespace in SocketThread class files.
|
||||
Added new operator <<(int64_t) in StreamWriter. Might be ambigouos on some
|
||||
architectures.
|
||||
Fix expression evaluation in TcpSocket, causing access to null pointer.
|
||||
Fix disable of both reconnect and detach functions.
|
||||
Added Utility::bigint2string(int64_t).
|
||||
Added Json support.
|
||||
|
||||
2.3.9.3
|
||||
--------
|
||||
Added multithread support in sockethandler. New method SetNumberOfThreads()
|
||||
enables this.
|
||||
New method in sockethandler: Release(). Make select() release before
|
||||
specified timeout. Enable function with method EnableRelease().
|
||||
EventHandler using new release functionality.
|
||||
Thread startup controlled with semaphore instead of flag/sleep combo.
|
||||
Default thread startup behaviour is run at once, optional is wait until
|
||||
released by posting to semaphore (via method SetRelease(true)).
|
||||
Adding a socket with closeanddelete flag set now works as expected.
|
||||
Added platform independent method Utility::Sleep( milliseconds ).
|
||||
Added missing win32 implementation in new sockethandler.
|
||||
Added win32 implementation of Semaphore.
|
||||
Repaired build for cygwin/mingw/devcpp.
|
||||
|
||||
2.3.9.2
|
||||
--------
|
||||
More internal restructuring of SocketHandler.
|
||||
The Get() method has been removed. Set() has been split into three:
|
||||
ISocketHandler_Add(), ISocketHandler_Mod(), and ISocketHandler_Del().
|
||||
New methods defined in ISocketHandler interface to support different
|
||||
models of socket io: ISocketHandler_Select(), MaxCount().
|
||||
Removed Set() method from Socket class.
|
||||
Implemented SocketHandlerEp using epoll for linux only.
|
||||
reinterpret_cast<> added in ListenSocket for ipv6 address struct.
|
||||
HttpPostSocket member variable holding http headers (m_fields) is now
|
||||
protected (changed from private).
|
||||
Repaired Reconnect function in sockethandler.
|
||||
|
||||
2.3.9.1
|
||||
--------
|
||||
Using thread- and memory safe clib/c runtime function when possible.
|
||||
Restructured sockethandler internals.
|
||||
Quicker tcp shutdown sequence when sockets lib initiates close.
|
||||
Renamed Utility::GetCurrentDirectory to Utility::CurrentDirectory, and
|
||||
added Utility::GetEnv().
|
||||
Removed unused triggers code.
|
||||
|
||||
2.3.9
|
||||
------
|
||||
TcpSocket using std::vector<char> to receive incoming line (OnLine
|
||||
callback). Configurable max limit for library available in sockets-config.h,
|
||||
default 8192 bytes (TCP_LINE_SIZE). Override ISocketHandler::MaxTcpLineSize
|
||||
to change this value without recompiling the library.
|
||||
Added more operators in Debug class. Removed some leftover debug printouts.
|
||||
HttpResponse returns non-const output file.
|
||||
HTTPSocket aborts after receiving more than 200 (MAX_HTTP_HEADER_COUNT) http
|
||||
headers. Use method HTTPSocket::SetMaxHeaderCount() to modify this value.
|
||||
Reordered log level enum, added minlevel to StdoutLog.
|
||||
|
||||
2.3.8
|
||||
------
|
||||
SSL sockets now operate in nonblocking mode. A much better solution to the
|
||||
"hang" problem mentioned in 2.3.7.
|
||||
Added Path() method to IFile interface. Returns File path name or MemFile
|
||||
virtual path name.
|
||||
Added constructor in MemFile that takes a File as input. Will read the
|
||||
entire File to memory. Added constructor in MemFile that copies another
|
||||
memfile. Will use the source memfile when reading.
|
||||
Added reference count when a MemFile object is source for another memfile.
|
||||
|
||||
Set OnTransferLimit back to 0 after a successful transfer of requested file
|
||||
(in Ajp13Socket and HttpBaseSocket). Reset IFile auto_ptr to
|
||||
decrease the reference count asap (by using fclose).
|
||||
|
||||
2.3.7
|
||||
------
|
||||
Moved some #include's outside the sockets namespace definition.
|
||||
Fix code to avoid an increment on an stl iterator that has reached end.
|
||||
Helping compilers deal with it++ when result is not used, changed all it++
|
||||
to ++it where appropriate.
|
||||
Doing an extra select on write readiness on file descriptor before calling
|
||||
SSL_write. Prevents a hang situation when the remote end drops the
|
||||
connection.
|
||||
|
||||
2.3.6
|
||||
------
|
||||
Added improved Valid() method using unique socket instance identifier. Using
|
||||
this identifier internally for events and resolver. Added optional data
|
||||
parameter in Event class, used by library to store socket instance
|
||||
identifier.
|
||||
No longer using SSL_MODE_AUTO_RETRY for ssl connections. If remote end
|
||||
disconnects this would cause hangups.
|
||||
Using SSL_MODE_ENABLE_PARTIAL_WRITE because the library supports this.
|
||||
Renamed EventHandler() method in IEventOwner to GetEventHandler().
|
||||
Added file system path abstraction methods to Utility.
|
||||
Reset file descriptor after successful close of a ListenSocket.
|
||||
|
||||
2.3.5
|
||||
------
|
||||
Added method(s) in UdpSocket to set default interface to be used for multicast.
|
||||
Added flag for position independent code for linux-x86-32 architecture (see
|
||||
Makefile.Defines.linux-x86-32).
|
||||
Added missing includes (on some distributions/gcc versions).
|
||||
SetUri in HttpRequest no longer URLDecodes the entire url.
|
||||
Fix for static variables in SSLInitializer.
|
||||
Fix for new version of openssl (const SSLxx_method()).
|
||||
Fix for getnameinfo.
|
||||
Modified Utility::Uri parser class so it also splits the url in path /
|
||||
querystring parts.
|
||||
|
||||
2.3.4
|
||||
------
|
||||
Some .cpp were missing namespace declarations - fixed. Some includes for
|
||||
ipv6 was missing - fixed. Operators in StreamWriter class modified to work
|
||||
on 64-bit as well as 32-bit systems.
|
||||
|
||||
2.3.3
|
||||
------
|
||||
Fix deadlock in SSLInitializer introduced in 2.3.2.
|
||||
Added check when select() returns -1 indicating one of the file descriptors
|
||||
have gone bad. The check rebuilds the fd_set used by select().
|
||||
Bugfix in HttpGetSocket, one of the constructors had no support in
|
||||
HttpClientSocket - added.
|
||||
Corrected bad #include's in Utility.
|
||||
Added IStream interface to read/write from socket and IFile (memfile, normal
|
||||
file). New classes SocketStream, FileStream, StreamWriter.
|
||||
Added ReadInput method in TcpSocket - read from input buffer.
|
||||
Added GetLine method in TcpSocket - chars input on current line when using
|
||||
SetLineProtocol mode.
|
||||
|
||||
2.3.2
|
||||
------
|
||||
Threadsafe list of ssl initializer, ssl contexts and openssl error text
|
||||
retrieval.
|
||||
Added interface for Mutex class, adding the possibility for others to
|
||||
implement the mutex functionality using other approaches.
|
||||
Moved FromUtf8 method from XmlNode to Utility.
|
||||
|
||||
2.3.1
|
||||
------
|
||||
Request: Remove() method in SocketHandler changed from private to protected.
|
||||
Added Utility::Stack that returns a stack walk (currently linux only).
|
||||
Request: Added $(DESTDIR) variable in Makefile for more flexible installation.
|
||||
The timeout value is now reset before OnTimeout() is called, making it
|
||||
possible to set a new timeout value in the OnTimeout() method.
|
||||
|
||||
2.3
|
||||
------
|
||||
Small change in ListenSocket<> to improve accepting of incoming
|
||||
connections.
|
||||
Added xml parsing classes: XmlDocument, XmlNode, and XmlException.
|
||||
Added new OnDisconnect(flags, code) callback that provides reason
|
||||
for the disconnect.
|
||||
Fix crash bug if an event object gets deleted in its own OnEvent
|
||||
method.
|
||||
gcc 4.3 compability fixes.
|
||||
|
||||
2.2.9a
|
||||
------
|
||||
Added assignment operator on HttpRequest class.
|
||||
HttpdForm sometimes got stuck in an infinite loop - fixed.
|
||||
Lock using const Mutex, and Mutex modified to work when const.
|
||||
Added Utility::Uri that can be used for parsing of an url.
|
||||
|
||||
2.2.9
|
||||
-----
|
||||
Fixed memory leak in TcpSocket.
|
||||
Fixed potentially unsafe code in http form data parser (HttpdForm).
|
||||
Fix memory and resource leak in HttpRequest.
|
||||
Ajp13Socket/HttpBaseSocket now creates a copy of the HttpResponse
|
||||
instance when sending a response, to avoid synchronization problems.
|
||||
Added "lost" flag which is set when a tcpsocket has lost connection
|
||||
unexpectedly (on read/write error). Earlier this function was only
|
||||
present when the connection pool was enabled (ENABLE_POOL).
|
||||
Removed unnecessary call to shutdown() when destroying a closed
|
||||
tcp socket.
|
||||
Added brief 'INSTALL' document.
|
||||
|
||||
2.2.8
|
||||
-----
|
||||
Added http client ability to receive a chunked response.
|
||||
HTTP headers are now treated in a case insensitive manner.
|
||||
MacOS leopard fixes.
|
||||
Added callback "OnDataComplete" to HTTPSocket, which is called
|
||||
when the full body of the request/response has been received.
|
||||
New random generator (mersienne twister).
|
||||
|
||||
2.2.7
|
||||
-----
|
||||
Http header names no longer converted to lowercase.
|
||||
"setsockopt()" wrapper methods returning int values has been fixed.
|
||||
No longer sets query_string attribute of HttpRequest when there is no
|
||||
query string present.
|
||||
|
||||
2.2.6
|
||||
-----
|
||||
Modified HttpRequest class to easier add support for pipelining.
|
||||
Made the following classes work with the copy constructor: HttpRequest,
|
||||
HttpTransaction, HttpdCookies.
|
||||
Always adding http header names as lowercase in internal storage
|
||||
(HTTPSocket). Added method to check if http header is set.
|
||||
Changed IHttpServer interface to better separate request and response.
|
||||
Added -mno-cygwin flag in Makefile defines for cygwin.
|
||||
Added calls to OnDisconnect when socket operation caused socket to close.
|
||||
|
||||
2.2.5
|
||||
-----
|
||||
A basic_string exception thrown while trying to access the first
|
||||
(non-existing) element in a zero-sized string was fixed in HTTPSocket.
|
||||
Added separate http_version for HttpResponse. Improved reset of state
|
||||
information in HTTPSocket and derivates (for keep-alive connections).
|
||||
MemFile support reads and writes larger than internal blocksize.
|
||||
|
||||
2.2.4
|
||||
-----
|
||||
IFile (File/MemFile) added reset_read and reset_write.
|
||||
Bugfix MemFile read.
|
||||
UdpSocket timestamp small fix for win32.
|
||||
Cookies reworked in Http framework (Transaction/Request/Response
|
||||
and HttpBaseSocket/Ajp13Socket).
|
||||
Compile issue when compiling without openssl solved.
|
||||
|
||||
2.2.3
|
||||
-----
|
||||
SSL Handshake was never initiated when using both client and server from the
|
||||
library - fixed.
|
||||
UdpSocket read timestamp added (SetTimestamp) as new OnRawData method. Use
|
||||
when timestamps enabled with call to SetSoTimestamp. Not win32.
|
||||
MacOSX project added. Big Thanks to Bruce for both of these.
|
||||
|
||||
2.2.2
|
||||
-----
|
||||
Close file descriptor in File destructor.
|
||||
HttpClientSocket new access method Filename.
|
||||
Added a few access methods to HttpdSocket.
|
||||
Check if gethostbyname_r failed.
|
||||
Async resolver fix.
|
||||
Fix win32 build problem (uint64_t).
|
||||
|
||||
2.2.1
|
||||
-----
|
||||
Adding (optional) exceptions when Bind() or CreateSocket() fails.
|
||||
Enable with ENABLE_EXCEPTIONS.
|
||||
Added GetSock* methods in Socket, to retreive information about local
|
||||
port and address in a connection.
|
||||
Added InitializeContext in TcpSocket with separate certificate / key files.
|
||||
Moved some #include's from .h to .cpp files.
|
||||
Removed multiple calls to recvfrom() in UdpSocket OnRead.
|
||||
HTTPSocket corrected.
|
||||
|
||||
2.2
|
||||
-----
|
||||
TcpSocket output buffer error fixed.
|
||||
HTTPSocket HTTP/1.0 request (or HTTP/1.1 with connection: close) fixed.
|
||||
IEventHandler now won't crash if the IEventOwner is deleted in OnEvent.
|
||||
Added Ajp13Socket that understands the ajp/1.3 protocol. Each request received
|
||||
by the class results in an "OnExec(HttpRequest, HttpResponse)" call.
|
||||
Added "HttpBaseSocket" that also use the "OnExec" method to process a
|
||||
http/https request.
|
||||
|
||||
2.1.9
|
||||
-----
|
||||
Added exception class.
|
||||
Changed platform selection in Unix Makefile.
|
||||
Cleaner compile on mingw.
|
||||
HTTPSocket supports keepalive.
|
||||
OnDisconnect moved out of ENABLE_RECONNECT scope.
|
||||
|
||||
2.1.8
|
||||
-----
|
||||
Added missing (optional) namespace in SmtpdSocket.
|
||||
TcpSocket: Calling OnDisconnect when reading 0 bytes.
|
||||
TcpSocket: Added OnTransferLimit() callback, called when output buffer
|
||||
size drops below limit set by SetTransferLimit().
|
||||
Boundary bug (writes over two blocks failed) in MemFile fixed.
|
||||
Member variables in SSLInitializer no longer static since SSLInitializer
|
||||
in itself is static in TcpSocket (avoid potential problem with
|
||||
initialization order of static's).
|
||||
|
||||
2.1.7
|
||||
-----
|
||||
Fatal bug in LineProtocol/Online found, when a crlf happens over a read
|
||||
buffer boundary. FIXED.
|
||||
New output buffer logic. OnWriteComplete callback added, which fires after
|
||||
the output buffer has been transferred.
|
||||
|
||||
2.1.6
|
||||
-----
|
||||
No more random number generator in Socket. Random number generator used in
|
||||
Utility changed to static.
|
||||
ISocketHandler is now a pure virtual definition of the SocketHandler.
|
||||
Added general purpose timeout to Socket class (SetTimeout, OnTimeout), and
|
||||
used it to implement the connection timeout logic in TcpSocket/SctpSocket.
|
||||
Also added OnConnectTimeout which is called instead of OnTimeout, if the
|
||||
socket is in Connecting mode.
|
||||
New StreamSocket class defines variables used for sock_stream stuff (such
|
||||
as connecting, the line protocol).
|
||||
|
||||
2.1.5
|
||||
-----
|
||||
Changed socket and ip option calls to directly manipulate the socket. They
|
||||
should be used in the OnOptions callback, to set up the connection before
|
||||
it is used. OnOptions is only called on client sockets. It is not called on
|
||||
incoming connections accepted with accept()).
|
||||
Removed Set methods from ResolvSocket and replaced them with one
|
||||
constructor for each of the different resolves it can do.
|
||||
Added DNS cache in ResolvSocket.
|
||||
Made CircularBuffer an internal class of TcpSocket.
|
||||
Moved these classes to a separate download:
|
||||
ICrypt NullCrypt CTcpSocket MinionSocket MinderSocket MinderHandler Uid
|
||||
ListenSocket now sets SO_REUSEADDR in its OnOptions method.
|
||||
Small fixes to SmtpSocket to support the new configuration stuff.
|
||||
Added socket to socket trigger framework (sockets-config.h: ENABLE_TRIGGERS).
|
||||
Small bugfix in TcpSocket::Open when trying to connect to an ipv6 host
|
||||
with numeric ip address.
|
||||
|
||||
2.1.4
|
||||
-----
|
||||
Added traffic monitor function.
|
||||
EventHandler/IEventOwner bugfix (pure virtual method called on takedown).
|
||||
Added outstanding events counter to IEventOwner, to avoid calling
|
||||
ClearEvents in destructor of an IEventOwner with no events to clear.
|
||||
Modified GetTimeUntilNextEvent to not return a negative time.
|
||||
Added SmtpdSocket serverside implementation.
|
||||
Crash bug fix if trying to add a socket that already exists in
|
||||
sockethandler queue.
|
||||
Made a few classes internal (PoolSocket, EventSocket, SocketThread).
|
||||
|
||||
2.1.3
|
||||
-----
|
||||
Added optional Ipv6 and Detach functionality to sockets-config.h.
|
||||
(ENABLE_IPV6, ENABLE_DETACH)
|
||||
Crash bug fix: if socket that asked a resolve question is destroyed
|
||||
before answer arrives.
|
||||
HTTPS (openssl) session support on server side.
|
||||
Safer ssl read/write - tnx Peters!
|
||||
All debug output now to stderr.
|
||||
GetClientRemoteAddress and XXX now returns a copy of the address in
|
||||
question, to avoid NULLing the source address when using std::auto_ptr.
|
||||
SSL initialization code separated from TcpSocket and put in a new
|
||||
SSLInitializer class.
|
||||
|
||||
2.1.2
|
||||
-----
|
||||
Fix for broken http framework.
|
||||
Http and httpd tests added.
|
||||
Configurable options moved to new 'sockets-config.h' file.
|
||||
Restored code for dns resolve when getaddrinfo/getnameinfo isn't available.
|
||||
(See sockets-config.h symbol NO_GETADDRINFO)
|
||||
|
||||
2.1.1
|
||||
-----
|
||||
Semaphore added.
|
||||
Utility::GetTime() fixed on win32.
|
||||
|
||||
2.1
|
||||
---
|
||||
* Added Utility::GetTime.
|
||||
* Created socket handler base class ISocketHandler. It will now be possible
|
||||
to write really customized sockethandlers. One effect of this is that
|
||||
the first parameter of the Socket class constructor changes from
|
||||
SocketHandler& to ISocketHandler& - this will affect all current
|
||||
software using the library.
|
||||
* StdLog constructor first parameter changed from SocketHandler*
|
||||
to ISocketHandler*
|
||||
* Modified list handling in Socket/SocketHandler.
|
||||
* Added possibility to clear tcp socket byte counters by passing
|
||||
'true' as input parameter to GetBytesReceived() and GetBytesSent().
|
||||
* Improved CircularBuffer performance when used as output buffer by
|
||||
TcpSocket.
|
||||
* Removed unused and confusing method ISocketHandler::GetSocket.
|
||||
* SocketAddress will replace direct use of ipv4/ipv6 addresses in the code.
|
||||
* Removed virtual supporting method Socket::ReadLine. If anyone was using
|
||||
that method, it used to be called directly after the OnRead callback,
|
||||
if SetLineProtocol was enabled. Repairing the functionality means
|
||||
adding a call of your own in the OnRead callback.
|
||||
* Optimized code for OnLine and HTTP header parsing.
|
||||
* Found and fixed a timing bug in thread code that could cause
|
||||
a segmentation fault.
|
||||
* 'echoserver.cpp' and 'stressclient.cpp' added, for test. Supports
|
||||
normal echo operation, http "echo" server and ssl server/client.
|
||||
|
||||
2.0.9
|
||||
-----
|
||||
Added a way to disable input buffering on tcp sockets.
|
||||
The method TcpSocket::DisableInputBuffer() will prevent all writing
|
||||
to the input buffer. After that, the only way to receive data is to
|
||||
implement an OnRawData method. TcpSocket derived classes that
|
||||
already only use OnRawData as a means of receiving data should
|
||||
call DisableInputBuffer() to improve performance (and turn off those
|
||||
annoying warning messages).
|
||||
OnOptions will now be called by UdpSocket. OnOptions is now a pure
|
||||
virtual method in the Socket class. Moved default implementation of
|
||||
OnOptions from Socket to TcpSocket. Added empty implementations of
|
||||
OnOptions in ListenSocket<>, UdpSocket and PoolSocket.
|
||||
Made Sockets-config compile on mingw systems.
|
||||
|
||||
2.0.8
|
||||
-----
|
||||
gethostbyname_r only used if the symbol LINUX is defined.
|
||||
Sctp protocol by default disabled. Enable by defining USE_SCTP.
|
||||
Fixed warnings about GetSocket/handler in connect and disconnect
|
||||
situations.
|
||||
|
||||
2.0.7
|
||||
-----
|
||||
Added Resolve(ipaddr_t) and Resolve(const std::string&) in Socket class
|
||||
for reverse lookup. Added OnResolveFailed() callback to Socket when a
|
||||
Resolve call failed.
|
||||
Moved definition of SOCKETS_DYNAMIC_TEMP to socket_include.h to avoid
|
||||
breaking windows application not using Sockets-config to retrieve
|
||||
compile time flags.
|
||||
Added "fd XX" to StdoutLog debug printout whenever a socket instance
|
||||
generates an event, where XX is the file descriptor of the socket or
|
||||
-1 if the file descriptor isn't valid.
|
||||
Reset connected flag when read returns 0 - avoids using shutdown on
|
||||
Close() and the following warning.
|
||||
SCTP support added - see SctpSocket class.
|
||||
|
||||
2.0.6
|
||||
-----
|
||||
"gethostbyname()" calls are replaced with "gethostbyname_r()", to ensure
|
||||
threadsafe operation.
|
||||
If the flag SOCKETS_DYNAMIC_TEMP is defined at compile time of the library,
|
||||
all application using the library must also define the same flag. In unix/
|
||||
linux Makefiles this is easiest done by adding `Sockets-config` to the
|
||||
CPPFLAGS variable.
|
||||
Optimized SocketHandler by removing the SocketHandler::GetSocket method
|
||||
and adding better code in each place where it was used - Thanks Samuel.
|
||||
CircularBuffer now has a ReadString method.
|
||||
Added method to remove a specific event to the EventHandler class.
|
||||
Added methods to the IEventOwner interface to remove all events or
|
||||
one specific events. - Thanks Thomas
|
||||
|
||||
2.0.5
|
||||
-----
|
||||
Added missing call to OnRawData when using ssl.
|
||||
Bugfix in HttpPostSocket, where the boundary variable was never set.
|
||||
Reset connecting flag in TcpSocket when a connection attempt fails.
|
||||
Define SOCKETS_DYNAMIC_TEMP to use dynamically allocated temporary
|
||||
buffers in read operations - helps on ECOS.
|
||||
Compile with -O0 if you are using gcc 2.9.x.
|
||||
|
||||
2.0.4
|
||||
-----
|
||||
Improved Http client classes, now they're all able to receive a response.
|
||||
Use methods SetFilename() / SetDataPtr() to write response to a file
|
||||
or to memory respectively.
|
||||
Small fix for uuid.h include for mac os x.
|
||||
Removed debug printout in SSLInitializer.
|
||||
|
||||
2.0.3
|
||||
-----
|
||||
Url parsing modified for Http Get/Put/Post classes to enable ssl if the
|
||||
url protocol is https.
|
||||
TcpSocket/SSL random file modified, see tutorial page at
|
||||
http://www.alhem.net/Sockets/tutorial/using6d.html
|
||||
Removed a lot of old debug printouts.
|
||||
|
||||
2.0.2b
|
||||
------
|
||||
Replaced direct read access to sockets map with a method looping through
|
||||
the map, to avoid adding null pointers to non-existing file descriptors.
|
||||
|
||||
2.0.2a
|
||||
------
|
||||
The new add control logic broke tcp reconnect, so this is a fix for that.
|
||||
|
||||
2.0.2
|
||||
-----
|
||||
Fixed infinite loop that could lock the main process when a socket attempts
|
||||
to connect, gets data to send, and then the connection fails.
|
||||
Added control so the same file descriptor can't be added to the socket
|
||||
handler twice.
|
||||
Utility::rfc1738_encode buffer overflow (read only) fixed.
|
||||
Moved local hostname resolution stuff from SocketHandler to Utility
|
||||
- see http://www.alhem.net/Sockets/tutorial/using6c.html
|
||||
Project files for visual studio 6 slightly modified (missing dependency,
|
||||
FD_SETSIZE define removed).
|
||||
|
||||
2.0.1
|
||||
-----
|
||||
Moved Errno declaration outside sockets namespace when compiling for unix.
|
||||
This was already done for the win32 implementation.
|
||||
Made typedef for socket_m in SocketHandler protected, since its use are
|
||||
already protected.
|
||||
Fixed problem with reconnect.
|
||||
|
||||
2.0
|
||||
---
|
||||
Optimizing SocketHandler.
|
||||
Fixed SSL socket reconnect.
|
||||
HttpGetSocket url parsing fixed. Really.
|
||||
Increased char buffer size in HttpdSocket for large query_string's.
|
||||
Added timer events, implemented in EventHandler.
|
||||
Using _beginthreadex()/_endthreadex() to create/end thread in _win32.
|
||||
Using GetTempPathA() explicitly when getting _win32 temporary path.
|
||||
* Removed (almost) all sprintf's.
|
||||
Visual studio .net project now build multithreaded library.
|
||||
Removed redundant classes SSLSocket, HttpsGetSocket, and HttpsSocket
|
||||
(all SSL functionality now in TcpSocket).
|
||||
Using dummy ssl types in TcpSocket if HAVE_OPENSSL is not defined.
|
||||
Moved a few typedef's outside the optional sockets namespace in the file
|
||||
socket_include.h.
|
||||
Fixed Thread/SocketThread to avoid using method on deleted pointer.
|
||||
Added CXX in Makefile.
|
||||
Bugfix in SocketThread so the correct sockethandler will be used by the
|
||||
detached socket object.
|
||||
Added full mutex threadsafe operations. The old _THREADSAFE_SOCKETS
|
||||
Makefile option is no longer in use.
|
||||
Improved graceful shutdown of tcp connections when possible.
|
||||
Moved address resolution methods from class Socket to Utility. The methods
|
||||
are isip, u2ip, l2ip.
|
||||
Added fix for unassigned names in httpdform parser.
|
||||
|
||||
1.9.9
|
||||
-----
|
||||
Trying to remove all dynamic_cast's. They are used in ListenSocket to
|
||||
check that the Create method returns correct type, and in the socket
|
||||
handler to give extra functionality to tcp sockets.
|
||||
New callback OnDisconnect is called only when a connected tcp socket
|
||||
is set for reconnect, and has lost connection.
|
||||
Memory leak in TcpSocket output buffering fixed.
|
||||
HttpGetSocket.url_this fixed.
|
||||
Replaced HttpGetSocket.m_content string with an allocated byte buffer.
|
||||
Fix bug in Utility::rfc1738_decode.
|
||||
SocketHandler.Select can be called without parameters, which means it
|
||||
will not return until an event has been received by a socket.
|
||||
Automatic purging of tcp sockets that hang around too long with data
|
||||
still left to send.
|
||||
Added virtual destructor for ICrypt pure virtual.
|
||||
|
||||
1.9.8
|
||||
-----
|
||||
Nasty bug fixed on macosx that caused OnConnect to be called even if
|
||||
the connection failed.
|
||||
SSL client functionality restored. Cached data was not sent on connect
|
||||
because the connected flag was not set.
|
||||
Two new callbacks added for TcpSocket, to indicate that ssl negotiation
|
||||
failed: OnSSLConnectFailed and OnSSLAcceptFailed.
|
||||
HttpGetSocket: getting a https: address enables ssl....
|
||||
Added fatal error if trying to use a ssl server without implementing
|
||||
the initialization method (InitSSLServer).
|
||||
|
||||
1.9.7
|
||||
-----
|
||||
SocketHandler.OkToAccept now takes a socket class pointer as input
|
||||
parameter, which can be used to identify which ListenSocket is
|
||||
calling OkToAccept.
|
||||
Treating socket exception as connection failed on win32
|
||||
(if trying to connect).
|
||||
Reset "flush before close" flag on write/read error.
|
||||
Moved sockethandler Add logic once again, this time outside loop
|
||||
checking for fd_set events..
|
||||
Check if fd_set is getting full (trying to add more than FD_SETSIZE
|
||||
sockets to the socket handler). Incoming connections are immediately
|
||||
disconnected if the fd_set is full. TcpSocket::Open calls will
|
||||
fail instantly if there is no more space in the fd_set.
|
||||
Remember that FD_SETSIZE can be defined in socket_handler.h if there
|
||||
is a need for larger fd_set's. The default on win32 is 64 slots which
|
||||
is a bit thin. Linux and probably most unixes has 1024 slots...
|
||||
On MacOsX the macro FD_COPY is used to copy the fd_set's before select().
|
||||
More debug logging on exactly how a connection was established.
|
||||
|
||||
1.9.6
|
||||
-----
|
||||
Bugfix protecting the sockethandler from using deleted sockets.
|
||||
(Socket class destructor calls SocketHandler.Remove in case the socket
|
||||
is deleted before it is removed from the sockethandler).
|
||||
Removed a lot of warnings for visual studio .net / 2005 beta.
|
||||
Fix for bsd sockets sigpipe disable, using SO_NOSIGPIPE.
|
||||
Solaris use putenv in HttpdSocket.
|
||||
Added flag flush before close, telling a (tcp) socket to send all data
|
||||
before closing even while the SetCloseAndDelete flag is set.
|
||||
Default value: flush before close = true.
|
||||
|
||||
1.9.5
|
||||
-----
|
||||
Visual studio 6 and .net project files updated.
|
||||
DevCpp project files updated.
|
||||
Using openssl win32 installer from www.slproweb.com,
|
||||
with installation location c:\OpenSSL.
|
||||
Merged Sockets and SocketsEx projects in all windows projects.
|
||||
Added winsock error texts.
|
||||
|
||||
ListenSocket.Bind slightly modified - if port 0 random assigned is
|
||||
needed, 0 has to be specified in the Bind call (before this release
|
||||
a Bind call with no parameters had the same effect).
|
||||
Ipv6 support has been improved, with many of the ipv4/ipv6 methods
|
||||
overall merged into one. Ipv6 support for reconnect and connection retry.
|
||||
The connection pool now also support ipv6 connections.
|
||||
Added SocketHandler.ResolverReady that indicates the resolverthread
|
||||
is ready for queries.
|
||||
UdpSocket constructor modified to also include an ipv6 boolean
|
||||
parameter, because the socket file descriptor is created in the
|
||||
constructor.
|
||||
Change: UdpSocket.Bind returns 0 on success, -1 on failure, just like
|
||||
ListenSocket<>.Bind.
|
||||
Connection pool disabled by default. Use SocketHandler.EnablePool to
|
||||
turn it back on.
|
||||
HttpDebugSocket: Added first line of request (method url httpversion) to
|
||||
page echoing the request.
|
||||
TcpSocket ssl private key callback function no longer uses a static
|
||||
member variable to store the password. This enables the use of any number
|
||||
of private key files, each with a different password.
|
||||
|
||||
1.9.4
|
||||
-----
|
||||
Changed udp sockets to nonblocking.
|
||||
|
||||
1.9.3
|
||||
-----
|
||||
New define while compiling: _THREADSAFE_SOCKETS
|
||||
This "thread safe" compile mode only protects OnWrite / SendBuf in
|
||||
TcpSocket, but will probably include more sections of the code later on.
|
||||
Mutex and Lock classes added.
|
||||
HttpdCookies now excludes domain from the Set-Cookie http header
|
||||
(if COOKIE_DOMAIN is defined as a blank string "").
|
||||
Incoming connections should now respond quicker even when using a long
|
||||
Select() timeout.
|
||||
Documentation: All classes and Socket class members at least briefly described.
|
||||
Tcp and Udp socket now shares a common virtual description of the Send
|
||||
and SendBuf methods.
|
||||
Fixed bug that caused too long connection timeouts.
|
||||
UDP sockets reads up to 10 messages in one read event.
|
||||
|
||||
1.9.2
|
||||
-----
|
||||
Support for HttpdSocket http/1.1 keep-alive operation added.
|
||||
Fiddling with the connection / reconnect code. Not perfect by a long shot.
|
||||
If a connection timeout is set, and the socket is supposed to reconnect,
|
||||
the socket will wait the defined connection timeout until a connection
|
||||
retry is made even if the connection fails immediately.
|
||||
OnConnectFailed() will only be called after all connection retries has
|
||||
been attempted.
|
||||
OnConnectRetry() will be called before each connection retry. Return
|
||||
false from this callback method to abort connection retries and kill the
|
||||
socket permanently.
|
||||
Data sent before / between connection is preserved, whatever that's worth.
|
||||
Added optional namespace for the entire library.
|
||||
|
||||
1.9.1
|
||||
-----
|
||||
Added SetConnected() in ListenSocket.h for TcpSocket's on accept.
|
||||
If not, all incoming tcp connections refused to send their data.
|
||||
|
||||
1.9
|
||||
---
|
||||
Added reconnect and connection retry for TcpSocket's.
|
||||
New callbacks:
|
||||
OnConnectRetry() can return false to abort connection retries.
|
||||
OnReconnect() when a connection has resumed.
|
||||
|
||||
1.8.7
|
||||
-----
|
||||
Added methods GetSsl() and GetSslContext() to access openssl structures
|
||||
SSL resp. SSL_CTX in TcpSocket and SSLSocket.
|
||||
HttpGetSocket no longer reports an error when initialized with an empty
|
||||
filename.
|
||||
SocketHandler::GetCount now returns actual number of active socket plus
|
||||
number of sockets to be added to active sockets list.
|
||||
|
||||
1.8.6
|
||||
-----
|
||||
Socket::DisableRead - use this when creating a socket only for output
|
||||
(the file descriptor will not be added to the read fd_set on select).
|
||||
Added check to make sure no more than FD_SETSIZE sockets are added to
|
||||
the socket handler.
|
||||
|
||||
1.8.5
|
||||
-----
|
||||
ReadLine fixed.
|
||||
|
||||
1.8.4
|
||||
-----
|
||||
Fixed a buffer problem that lost a byte for each read when doing large
|
||||
http transfers (HTTPSocket, HttpsSocket, TcpSocket).
|
||||
Added classes mentioned in v1.8.3...
|
||||
Thread class implemented for win32 (not tested)
|
||||
|
||||
1.8.3
|
||||
-----
|
||||
(OnWriteComplete - pending)
|
||||
(IFile - File - MemFile)
|
||||
(HttpdSocket - HttpdForm - HttpdCookies)
|
||||
Incoming sockets are no longer blocking
|
||||
OnWrite no longer disconnect on EAGAIN error code
|
||||
SSLSocket has been integrated with TcpSocket (still experimental)
|
||||
|
||||
1.8.2
|
||||
-----
|
||||
Removed warning about read after shutdown.
|
||||
Socket does not try to do shutdown/close if the file descriptor is invalid.
|
||||
|
||||
1.8
|
||||
---
|
||||
ListenSocketBase functionality moved to ListenSocket template class.
|
||||
The important addition is the Create() method in Socket - use that to
|
||||
create a socket instance with an alternative constructor if needed.
|
||||
TcpSocket::Open bugfix - sometimes returned false (connection failed)
|
||||
although the connection was perfectly fine.
|
||||
Socks4 client functionality added for outgoing connections. See new
|
||||
SetSocks4Host, SetSocks4Port, SetSocks4Userid and SetSocks4TryDirect
|
||||
methods in SocketHandler.
|
||||
HttpGetSocket stores retrieved document in a private string member
|
||||
variable, reducing the need for disk access.
|
||||
Asynchronous DNS functionality added. Use the new SocketHandler method
|
||||
EnableResolver() to enable this for resolving of all outgoing connections.
|
||||
|
||||
1.7.6
|
||||
-----
|
||||
Small changes in UdpSocket
|
||||
New class ListenSocketBase as an alternative to ListenSocket<> template
|
||||
class
|
||||
New callback in Socket: Create - used by ListenSocketBase
|
||||
|
||||
1.7.5
|
||||
-----
|
||||
New callback on socket class: OnOptions, called when a new socket has
|
||||
been created, to set options like SetReuse and SetKeepalive.
|
||||
New get methods on MinionSocket.
|
||||
Socket::Close now does a recv() after shutdown().
|
||||
New logging level: Info
|
||||
|
||||
1.7.2
|
||||
-----
|
||||
HttpsGetSocket::url_this default port changed to 443 (was 80).
|
||||
TcpSocket buffer sizes adjusted.
|
||||
Switch off LineProtocol when reading the http body in HTTPSocket and
|
||||
HttpsSocket.
|
||||
|
||||
|
||||
1.7
|
||||
---
|
||||
HttpPostSocket added functionality, able to switch between url-encoded
|
||||
form-data or multipart/form-data.
|
||||
Connection pooling on TcpSocket's; When SetRetain() is called on a client
|
||||
socket (that use Open / OnConnect), that sockets connection will be left
|
||||
open and reused by the next TcpSocket the tries to open a new connection to
|
||||
the same host / port.
|
||||
This construction gives HTTPSocket HTTP/1.1 support for keep-alive
|
||||
connections.
|
||||
Pooled connections are stored as PoolSocket objects in the SocketHandler
|
||||
socket list, and supervised like any other socket - if a pooled connection
|
||||
is closed by the remote end, it's removed by the SocketHandler.
|
||||
|
||||
|
||||
1.6.4
|
||||
-----
|
||||
Socket::SetParent / ::GetParent added, as a way to find out which
|
||||
ListenSocket created the Socket. GetParent returns the pointer to the
|
||||
ListenSocket object, or NULL if the Socket was created by the
|
||||
programmer.
|
||||
Win32: WSA startup code is wrapped in a class, which is created as a
|
||||
static instance in Socket. This should automatically initialize
|
||||
winsock when the first Socket is created.
|
||||
|
||||
|
||||
1.6.3
|
||||
-----
|
||||
"errno" and "strerror" has been replaced by Errno and StrError,
|
||||
and is defined for each operating system environment.
|
||||
New classes for HTTP: HttpPutSocket, HttpPostSocket, HttpDebugSocket.
|
||||
|
||||
1.6.2
|
||||
-----
|
||||
Bugfix in ListenSocket, when opening a random port GetPort() returned
|
||||
wrong port number - this is now fixed.
|
||||
Defining methods depending on ipv4 or ipv6 was removed, and all ipv4 methods
|
||||
renamed to their original names - without the '4'.
|
||||
|
||||
|
||||
1.6.1
|
||||
-----
|
||||
Dummy copy constructor / assignment operator added to classes that can't be
|
||||
copied by default.
|
||||
Minor improvements to HTTPSocket.
|
||||
Removed typedef string_v - collision with other projects that use same name
|
||||
for std::vector<std::string> instead of internal use std::list<std::vector>
|
||||
|
||||
|
||||
1.6
|
||||
---
|
||||
Improvements on win32 compile and linking. Remember to turn on rtti
|
||||
information (/GR in visual studio), because I tend to use dynamic_cast a lot.
|
||||
|
||||
It is now possible to exclude openssl specific code, by not having
|
||||
HAVE_OPENSSL defined at compile time.
|
||||
Define HAVE_OPENSSL in Makefile or project file if openssl is installed
|
||||
on your machine.
|
||||
|
||||
Bugfix in CircularBuffer. It finally works.
|
||||
|
||||
Renamed CircularBuffer method GetCount to "ByteCounter" - the method returns
|
||||
the total number of bytes to have ever gone through the buffer.
|
||||
|
||||
Improved logging, and cleaned up old debug printouts.
|
||||
|
||||
Fixed a number of memory leaks that would occur in an application that
|
||||
creates and recreates a lot of SocketHandler's, and also in the threading
|
||||
part of the library.
|
||||
|
||||
Some optimizations for speed.
|
||||
|
||||
|
||||
1.5.4
|
||||
-----
|
||||
UdpSocket: Broadcast flag, Multicast stuff
|
||||
|
||||
|
||||
1.5.3
|
||||
-----
|
||||
SocketHandler no longer resolves local hostname on startup.
|
||||
On hosts with unresolvable hostname this would cause a delay on startup.
|
||||
|
||||
Changed unix socket i/o from read/write to recv/send with MSG_NOSIGNAL
|
||||
flag, to avoid sigpipe
|
||||
- see readsocket/writesocket macros in socket_include.h.
|
||||
|
||||
|
||||
1.5
|
||||
---
|
||||
|
||||
New callback: OnConnectFailed
|
||||
|
||||
new / modified methods to support ipv6:
|
||||
Socket::CreateSocket6
|
||||
Socket::u2ip
|
||||
Socket::l2ip
|
||||
Socket::GetRemoteIP6
|
||||
Socket::IsIpv6
|
||||
|
||||
|
||||
|
||||
04-04-12
|
||||
--------
|
||||
void TcpSocket::OnRawData(const char *,size_t)
|
||||
called when new data is read
|
||||
|
||||
bool SocketHandler::OkToAccept()
|
||||
called by ListenSocket - default implementation returns true
|
||||
|
||||
@@ -1,103 +0,0 @@
|
||||
#include "Debug.h"
|
||||
#include <stdarg.h>
|
||||
#include <cstring>
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
|
||||
std::map<unsigned long, int> Debug::m_level;
|
||||
const char *Debug::colors[] = {
|
||||
"\x1B[0;0m", // &n */
|
||||
"\x1B[0;0m\x1B[31m", // &r */
|
||||
"\x1B[0;0m\x1B[32m", // &g */
|
||||
"\x1B[0;0m\x1B[33m", // &y */
|
||||
"\x1B[0;0m\x1B[34m", // &b */
|
||||
"\x1B[0;0m\x1B[35m", // &m */
|
||||
"\x1B[0;0m\x1B[36m", // &c */
|
||||
"\x1B[0;0m\x1B[37m", // &w */
|
||||
"\x1B[1;31m", // &R */
|
||||
"\x1B[1;32m", // &G */
|
||||
"\x1B[1;33m", // &Y */
|
||||
"\x1B[1;34m", // &B */
|
||||
"\x1B[1;35m", // &M */
|
||||
"\x1B[1;36m", // &C */
|
||||
"\x1B[1;37m" }; // &W */
|
||||
|
||||
|
||||
void Debug::Print(const char *format, ...)
|
||||
{
|
||||
char slask[5000]; // temporary for vsprintf / vsnprintf
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, format);
|
||||
vsnprintf(slask, sizeof(slask), format, ap);
|
||||
va_end(ap);
|
||||
|
||||
fprintf(stderr, "%s", colors[Utility::ThreadID() % 14 + 1]);
|
||||
for (int i = 0; i < m_level[Utility::ThreadID()]; i++)
|
||||
fprintf(stderr, " ");
|
||||
if (slask[strlen(slask) - 1] == '\n')
|
||||
slask[strlen(slask) - 1] = 0;
|
||||
fprintf(stderr, "%s%s\n", slask, colors[0]);
|
||||
}
|
||||
|
||||
|
||||
Debug& Debug::operator<<(const char * str)
|
||||
{
|
||||
m_line += str;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
Debug& Debug::operator<<(const std::string& str)
|
||||
{
|
||||
m_line += str;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
Debug& Debug::operator<<(short l)
|
||||
{
|
||||
m_line += Utility::l2string(l);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
Debug& Debug::operator<<(int l)
|
||||
{
|
||||
m_line += Utility::l2string(l);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
Debug& Debug::operator<<(long l)
|
||||
{
|
||||
m_line += Utility::l2string(l);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
Debug& Debug::operator<<(double d)
|
||||
{
|
||||
char slask[100];
|
||||
snprintf(slask, sizeof(slask), "%f", d);
|
||||
m_line += slask;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
Debug& Debug::operator<<(endl)
|
||||
{
|
||||
Print("%s", m_line.c_str());
|
||||
m_line = "";
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
} // namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
#ifndef _SOCKETS_Debug_H
|
||||
#define _SOCKETS_Debug_H
|
||||
|
||||
#include "sockets-config.h"
|
||||
#include "Utility.h"
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
|
||||
class Debug
|
||||
{
|
||||
static const char *colors[];
|
||||
public:
|
||||
class endl
|
||||
{
|
||||
public:
|
||||
endl() {}
|
||||
virtual ~endl() {}
|
||||
};
|
||||
|
||||
public:
|
||||
Debug() {}
|
||||
Debug(const std::string& x) : m_id(0), m_text(x) {
|
||||
fprintf(stderr, "%s", colors[Utility::ThreadID() % 14 + 1]);
|
||||
|
||||
for (int i = 0; i < m_level[Utility::ThreadID()]; i++)
|
||||
fprintf(stderr, " ");
|
||||
|
||||
fprintf(stderr, "%s%s\n", x.c_str(), colors[0]);
|
||||
m_level[Utility::ThreadID()]++;
|
||||
}
|
||||
Debug(int id, const std::string& x) : m_id(id), m_text(x) {
|
||||
fprintf(stderr, "%s", colors[Utility::ThreadID() % 14 + 1]);
|
||||
|
||||
for (int i = 0; i < m_level[Utility::ThreadID()]; i++)
|
||||
fprintf(stderr, " ");
|
||||
|
||||
fprintf(stderr, "%d> %s%s\n", m_id, x.c_str(), colors[0]);
|
||||
m_level[Utility::ThreadID()]++;
|
||||
}
|
||||
~Debug() {
|
||||
if (!m_text.empty()) {
|
||||
if (m_level[Utility::ThreadID()])
|
||||
m_level[Utility::ThreadID()]--;
|
||||
|
||||
fprintf(stderr, "%s", colors[Utility::ThreadID() % 14 + 1]);
|
||||
|
||||
for (int i = 0; i < m_level[Utility::ThreadID()]; i++)
|
||||
fprintf(stderr, " ");
|
||||
|
||||
if (m_id)
|
||||
fprintf(stderr, "%d> /%s%s\n", m_id, m_text.c_str(), colors[0]);
|
||||
else
|
||||
fprintf(stderr, "/%s%s\n", m_text.c_str(), colors[0]);
|
||||
|
||||
fflush(stderr);
|
||||
}
|
||||
}
|
||||
static void Print(const char *format, ...);
|
||||
|
||||
Debug& operator<<(const char *);
|
||||
Debug& operator<<(const std::string& );
|
||||
Debug& operator<<(short);
|
||||
Debug& operator<<(int);
|
||||
Debug& operator<<(long);
|
||||
Debug& operator<<(double);
|
||||
Debug& operator<<(endl);
|
||||
|
||||
private:
|
||||
int m_id;
|
||||
std::string m_text;
|
||||
static std::map<unsigned long, int> m_level;
|
||||
std::string m_line;
|
||||
};
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
} // namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
#endif // _SOCKETS_Debug_H
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
/** \file Event.cpp
|
||||
** \date 2005-12-07
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2005-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#include "Event.h"
|
||||
#ifdef _WIN32
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
//#include "IEventOwner.h"
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
|
||||
// statics
|
||||
long Event::m_unique_id = 0;
|
||||
|
||||
|
||||
Event::Event(IEventOwner *from,long sec,long usec,unsigned long data) : m_from(from), m_data(data), m_time(sec, usec), m_id(++m_unique_id)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Event::~Event()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool Event::operator<(Event& e)
|
||||
{
|
||||
return m_time < e.m_time;
|
||||
}
|
||||
|
||||
|
||||
long Event::GetID() const
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
|
||||
|
||||
const EventTime& Event::GetTime() const
|
||||
{
|
||||
return m_time;
|
||||
}
|
||||
|
||||
|
||||
IEventOwner *Event::GetFrom() const
|
||||
{
|
||||
return m_from;
|
||||
}
|
||||
|
||||
|
||||
unsigned long Event::Data() const
|
||||
{
|
||||
return m_data;
|
||||
}
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,83 +0,0 @@
|
||||
/** \file Event.h
|
||||
** \date 2005-12-07
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2005-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef _SOCKETS_Event_H
|
||||
#define _SOCKETS_Event_H
|
||||
|
||||
#include "sockets-config.h"
|
||||
#ifdef _WIN32
|
||||
#else
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
#include "EventTime.h"
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
|
||||
class IEventOwner;
|
||||
|
||||
/** Store information about a timer event.
|
||||
\ingroup timer */
|
||||
class Event
|
||||
{
|
||||
public:
|
||||
Event(IEventOwner *,long sec,long usec,unsigned long data = 0);
|
||||
~Event();
|
||||
|
||||
bool operator<(Event&);
|
||||
long GetID() const;
|
||||
const EventTime& GetTime() const;
|
||||
IEventOwner *GetFrom() const;
|
||||
unsigned long Data() const;
|
||||
|
||||
private:
|
||||
Event(const Event& ) {} // copy constructor
|
||||
Event& operator=(const Event& ) {
|
||||
return *this; // assignment operator
|
||||
}
|
||||
IEventOwner *m_from;
|
||||
unsigned long m_data;
|
||||
EventTime m_time;
|
||||
static long m_unique_id;
|
||||
long m_id;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _SOCKETS_Event_H
|
||||
|
||||
@@ -1,209 +0,0 @@
|
||||
/** \file EventHandler.cpp
|
||||
** \date 2005-12-07
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2005-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4786)
|
||||
#endif
|
||||
#include "EventHandler.h"
|
||||
#include "IEventOwner.h"
|
||||
#include "Event.h"
|
||||
#include "TcpSocket.h"
|
||||
#include "ListenSocket.h"
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
|
||||
EventHandler::EventHandler(StdLog *p) : SocketHandler(p), m_quit(false)
|
||||
{
|
||||
EnableRelease();
|
||||
}
|
||||
|
||||
|
||||
EventHandler::EventHandler(IMutex& m,StdLog *p) : SocketHandler(m, p), m_quit(false)
|
||||
{
|
||||
EnableRelease();
|
||||
}
|
||||
|
||||
|
||||
EventHandler::~EventHandler()
|
||||
{
|
||||
while (m_events.size())
|
||||
{
|
||||
std::list<Event *>::iterator it = m_events.begin();
|
||||
Event *e = *it;
|
||||
e -> GetFrom() -> SetHandlerInvalid();
|
||||
delete e;
|
||||
m_events.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool EventHandler::GetTimeUntilNextEvent(struct timeval *tv)
|
||||
{
|
||||
if (!m_events.size())
|
||||
return false;
|
||||
std::list<Event *>::iterator it = m_events.begin();
|
||||
if (it != m_events.end())
|
||||
{
|
||||
EventTime now;
|
||||
mytime_t diff = (*it) -> GetTime() - now;
|
||||
if (diff < 1)
|
||||
{
|
||||
diff = 1;
|
||||
}
|
||||
tv -> tv_sec = static_cast<long>(diff / 1000000);
|
||||
tv -> tv_usec = static_cast<long>(diff % 1000000);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void EventHandler::CheckEvents()
|
||||
{
|
||||
EventTime now;
|
||||
std::list<Event *>::iterator it = m_events.begin();
|
||||
while (it != m_events.end() && (*it) -> GetTime() < now)
|
||||
{
|
||||
Event *e = *it;
|
||||
Socket *s = dynamic_cast<Socket *>(e -> GetFrom());
|
||||
/*
|
||||
s == NULL This is another object implementing 'IEventOwner' and not a socket.
|
||||
s != NULL This is a Socket implementing IEventOwner, and we can check that the
|
||||
object instance still is valid using SocketHandler::Valid.
|
||||
*/
|
||||
if (!s || (s && Valid( e -> Data() )))
|
||||
{
|
||||
e -> GetFrom() -> OnEvent(e -> GetID());
|
||||
}
|
||||
for (it = m_events.begin(); it != m_events.end(); ++it)
|
||||
if (*it == e)
|
||||
{
|
||||
delete e;
|
||||
break;
|
||||
}
|
||||
if (it != m_events.end())
|
||||
m_events.erase(it);
|
||||
it = m_events.begin();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
long EventHandler::AddEvent(IEventOwner *from,long sec,long usec)
|
||||
{
|
||||
Socket *s = dynamic_cast<Socket *>(from);
|
||||
Event *e = new Event(from, sec, usec, s ? s -> UniqueIdentifier() : 0);
|
||||
std::list<Event *>::iterator it = m_events.begin();
|
||||
while (it != m_events.end() && *(*it) < *e)
|
||||
{
|
||||
++it;
|
||||
}
|
||||
m_events.insert(it, e);
|
||||
Release();
|
||||
return e -> GetID();
|
||||
}
|
||||
|
||||
|
||||
void EventHandler::ClearEvents(IEventOwner *from)
|
||||
{
|
||||
bool repeat;
|
||||
do
|
||||
{
|
||||
repeat = false;
|
||||
for (std::list<Event *>::iterator it = m_events.begin(); it != m_events.end(); ++it)
|
||||
{
|
||||
Event *e = *it;
|
||||
if (e -> GetFrom() == from)
|
||||
{
|
||||
delete e;
|
||||
m_events.erase(it);
|
||||
repeat = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (repeat);
|
||||
}
|
||||
|
||||
|
||||
void EventHandler::EventLoop()
|
||||
{
|
||||
while (!m_quit)
|
||||
{
|
||||
struct timeval tv;
|
||||
if (GetTimeUntilNextEvent(&tv))
|
||||
{
|
||||
Select(&tv);
|
||||
CheckEvents();
|
||||
}
|
||||
else
|
||||
{
|
||||
Select();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void EventHandler::SetQuit(bool x)
|
||||
{
|
||||
m_quit = x;
|
||||
}
|
||||
|
||||
|
||||
void EventHandler::RemoveEvent(IEventOwner *from, long eid)
|
||||
{
|
||||
for (std::list<Event *>::iterator it = m_events.begin(); it != m_events.end(); ++it)
|
||||
{
|
||||
Event *e = *it;
|
||||
if (from == e -> GetFrom() && eid == e -> GetID())
|
||||
{
|
||||
delete e;
|
||||
m_events.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void EventHandler::Add(Socket *p)
|
||||
{
|
||||
SocketHandler::Add( p );
|
||||
}
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -1,88 +0,0 @@
|
||||
/** \file EventHandler.h
|
||||
** \date 2005-12-07
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2005-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef _SOCKETS_EventHandler_H
|
||||
#define _SOCKETS_EventHandler_H
|
||||
|
||||
#include "sockets-config.h"
|
||||
#include "SocketHandler.h"
|
||||
#include "IEventHandler.h"
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
|
||||
class StdLog;
|
||||
class IEventOwner;
|
||||
class Event;
|
||||
class TcpSocket;
|
||||
|
||||
/** SocketHandler implementing the IEventHandler interface.
|
||||
\ingroup timer */
|
||||
class EventHandler : public SocketHandler,public IEventHandler
|
||||
{
|
||||
public:
|
||||
EventHandler(StdLog * = NULL);
|
||||
EventHandler(IMutex&,StdLog * = NULL);
|
||||
~EventHandler();
|
||||
|
||||
bool GetTimeUntilNextEvent(struct timeval *tv);
|
||||
void CheckEvents();
|
||||
long AddEvent(IEventOwner *from,long sec,long usec);
|
||||
void ClearEvents(IEventOwner *from);
|
||||
void RemoveEvent(IEventOwner *from,long eid);
|
||||
|
||||
/** SocketHandler while() loop implemented with event functionality. */
|
||||
void EventLoop();
|
||||
/** Stop event loop. */
|
||||
void SetQuit(bool = true);
|
||||
|
||||
void Add(Socket *);
|
||||
|
||||
private:
|
||||
EventHandler(const EventHandler& ) {} // copy constructor
|
||||
EventHandler& operator=(const EventHandler& ) {
|
||||
return *this; // assignment operator
|
||||
}
|
||||
std::list<Event *> m_events;
|
||||
bool m_quit;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _SOCKETS_EventHandler_H
|
||||
|
||||
@@ -1,107 +0,0 @@
|
||||
/** \file EventTime.cpp
|
||||
** \date 2005-12-07
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2005-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifdef MACOSX
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <signal.h>
|
||||
#endif
|
||||
#include "EventTime.h"
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <sys/select.h>
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
|
||||
EventTime::EventTime() : m_time(Tick())
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
EventTime::EventTime(mytime_t sec,long usec) : m_time(Tick())
|
||||
{
|
||||
m_time += sec * 1000000 + usec;
|
||||
}
|
||||
|
||||
|
||||
EventTime::~EventTime()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
mytime_t EventTime::Tick()
|
||||
{
|
||||
mytime_t t;
|
||||
#ifdef _WIN32
|
||||
FILETIME ft;
|
||||
GetSystemTimeAsFileTime(&ft);
|
||||
t = ft.dwHighDateTime;
|
||||
t = t << 32;
|
||||
t += ft.dwLowDateTime;
|
||||
t /= 10; // us
|
||||
#else
|
||||
struct timeval tv;
|
||||
struct timezone tz;
|
||||
gettimeofday(&tv, &tz);
|
||||
t = tv.tv_sec;
|
||||
t *= 1000000;
|
||||
t += tv.tv_usec;
|
||||
#endif
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
EventTime EventTime::operator - (const EventTime& x) const
|
||||
{
|
||||
EventTime t;
|
||||
t.m_time = m_time - x.m_time;
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
bool EventTime::operator < (const EventTime& x) const
|
||||
{
|
||||
return m_time < x.m_time;
|
||||
}
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,84 +0,0 @@
|
||||
/** \file EventTime.h
|
||||
** \date 2005-12-07
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2005-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef _SOCKETS_EventTime_H
|
||||
#define _SOCKETS_EventTime_H
|
||||
|
||||
#include "sockets-config.h"
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
|
||||
#if defined( _WIN32) && !defined(__CYGWIN__)
|
||||
typedef __int64 mytime_t;
|
||||
#else
|
||||
#include <inttypes.h> // int64_t
|
||||
typedef int64_t mytime_t;
|
||||
#endif
|
||||
|
||||
|
||||
/** \defgroup timer EventTimer event handling */
|
||||
|
||||
/** EventTime primitive, returns current time as a 64-bit number.
|
||||
\ingroup timer */
|
||||
class EventTime
|
||||
{
|
||||
public:
|
||||
EventTime();
|
||||
EventTime(mytime_t sec,long usec);
|
||||
~EventTime();
|
||||
|
||||
static mytime_t Tick();
|
||||
|
||||
operator mytime_t () {
|
||||
return m_time;
|
||||
}
|
||||
EventTime operator - (const EventTime& x) const;
|
||||
bool operator < (const EventTime& x) const;
|
||||
|
||||
private:
|
||||
EventTime(const EventTime& ) {} // copy constructor
|
||||
EventTime& operator=(const EventTime& ) {
|
||||
return *this; // assignment operator
|
||||
}
|
||||
mytime_t m_time;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _SOCKETS_EventTime_H
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
/**
|
||||
** \file Exception.cpp
|
||||
** \date 2007-09-28
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2007-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4786)
|
||||
#endif
|
||||
#include "Exception.h"
|
||||
#include "Utility.h"
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
Exception::Exception(const std::string& description) : m_description(description)
|
||||
, m_stack(Utility::Stack())
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
const std::string Exception::ToString() const
|
||||
{
|
||||
return m_description;
|
||||
}
|
||||
|
||||
|
||||
const std::string Exception::Stack() const
|
||||
{
|
||||
return m_stack;
|
||||
}
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
} // namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
/**
|
||||
** \file Exception.h
|
||||
** \date 2007-09-28
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2007-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef _Sockets_Exception_H
|
||||
#define _Sockets_Exception_H
|
||||
|
||||
#include "sockets-config.h"
|
||||
#include <string>
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
class Exception
|
||||
{
|
||||
public:
|
||||
Exception(const std::string& description);
|
||||
virtual ~Exception() {}
|
||||
|
||||
virtual const std::string ToString() const;
|
||||
virtual const std::string Stack() const;
|
||||
|
||||
Exception(const Exception& ) {} // copy constructor
|
||||
|
||||
Exception& operator=(const Exception& ) {
|
||||
return *this; // assignment operator
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_description;
|
||||
std::string m_stack;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
} // namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
#endif // _Sockets_Exception_H
|
||||
|
||||
@@ -1,203 +0,0 @@
|
||||
/** \file File.cpp
|
||||
** \date 2005-04-25
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2004-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "File.h"
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
|
||||
File::File()
|
||||
:m_fil(NULL)
|
||||
,m_b_close(true)
|
||||
,m_rptr(0)
|
||||
,m_wptr(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
File::File(FILE *fil)
|
||||
:m_fil(fil)
|
||||
,m_b_close(false)
|
||||
,m_rptr(0)
|
||||
,m_wptr(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
File::File(const std::string& path, const std::string& mode)
|
||||
:m_fil(NULL)
|
||||
,m_b_close(true)
|
||||
,m_rptr(0)
|
||||
,m_wptr(0)
|
||||
{
|
||||
fopen(path, mode);
|
||||
}
|
||||
|
||||
|
||||
File::~File()
|
||||
{
|
||||
if (m_b_close)
|
||||
{
|
||||
fclose();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool File::fopen(const std::string& path, const std::string& mode)
|
||||
{
|
||||
m_path = path;
|
||||
m_mode = mode;
|
||||
#if defined( _WIN32) && !defined(__CYGWIN__)
|
||||
if (fopen_s(&m_fil, path.c_str(), mode.c_str()))
|
||||
m_fil = NULL;
|
||||
#else
|
||||
m_fil = ::fopen(path.c_str(), mode.c_str());
|
||||
#endif
|
||||
|
||||
return m_fil ? true : false;
|
||||
}
|
||||
|
||||
|
||||
void File::fclose() const
|
||||
{
|
||||
if (m_fil)
|
||||
{
|
||||
::fclose(m_fil);
|
||||
m_fil = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
size_t File::fread(char *ptr, size_t size, size_t nmemb) const
|
||||
{
|
||||
size_t r = 0;
|
||||
if (m_fil)
|
||||
{
|
||||
fseek(m_fil, m_rptr, SEEK_SET);
|
||||
r = ::fread(ptr, size, nmemb, m_fil);
|
||||
m_rptr = ftell(m_fil);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
size_t File::fwrite(const char *ptr, size_t size, size_t nmemb)
|
||||
{
|
||||
size_t r = 0;
|
||||
if (m_fil)
|
||||
{
|
||||
fseek(m_fil, m_wptr, SEEK_SET);
|
||||
r = ::fwrite(ptr, size, nmemb, m_fil);
|
||||
m_wptr = ftell(m_fil);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
|
||||
char *File::fgets(char *s, int size) const
|
||||
{
|
||||
char *r = NULL;
|
||||
if (m_fil)
|
||||
{
|
||||
fseek(m_fil, m_rptr, SEEK_SET);
|
||||
r = ::fgets(s, size, m_fil);
|
||||
m_rptr = ftell(m_fil);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
void File::fprintf(const char *format, ...)
|
||||
{
|
||||
if (!m_fil)
|
||||
return;
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
fseek(m_fil, m_wptr, SEEK_SET);
|
||||
vfprintf(m_fil, format, ap);
|
||||
m_wptr = ftell(m_fil);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
|
||||
off_t File::size() const
|
||||
{
|
||||
struct stat st;
|
||||
if (stat(m_path.c_str(), &st) == -1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return st.st_size;
|
||||
}
|
||||
|
||||
|
||||
bool File::eof() const
|
||||
{
|
||||
if (m_fil)
|
||||
{
|
||||
if (feof(m_fil))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void File::reset_read() const
|
||||
{
|
||||
m_rptr = 0;
|
||||
}
|
||||
|
||||
|
||||
void File::reset_write()
|
||||
{
|
||||
m_wptr = 0;
|
||||
}
|
||||
|
||||
|
||||
const std::string& File::Path() const
|
||||
{
|
||||
return m_path;
|
||||
}
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,95 +0,0 @@
|
||||
/** \file File.h
|
||||
** \date 2005-04-25
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2004-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef _SOCKETS_File_H
|
||||
#define _SOCKETS_File_H
|
||||
|
||||
#include "sockets-config.h"
|
||||
#include "IFile.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
|
||||
/** IFile implementation of a disk file.
|
||||
\ingroup file */
|
||||
class File : public IFile
|
||||
{
|
||||
public:
|
||||
File();
|
||||
File(FILE *);
|
||||
/** convenience: calls fopen() */
|
||||
File(const std::string& path, const std::string& mode);
|
||||
~File();
|
||||
|
||||
bool fopen(const std::string& path, const std::string& mode);
|
||||
void fclose() const;
|
||||
|
||||
size_t fread(char *, size_t, size_t) const;
|
||||
size_t fwrite(const char *, size_t, size_t);
|
||||
|
||||
char *fgets(char *, int) const;
|
||||
void fprintf(const char *format, ...);
|
||||
|
||||
off_t size() const;
|
||||
bool eof() const;
|
||||
|
||||
void reset_read() const;
|
||||
void reset_write();
|
||||
|
||||
const std::string& Path() const;
|
||||
|
||||
private:
|
||||
File(const File& ) {} // copy constructor
|
||||
File& operator=(const File& ) {
|
||||
return *this; // assignment operator
|
||||
}
|
||||
|
||||
std::string m_path;
|
||||
std::string m_mode;
|
||||
mutable FILE *m_fil;
|
||||
bool m_b_close;
|
||||
mutable long m_rptr;
|
||||
long m_wptr;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _SOCKETS_File_H
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
/**
|
||||
** \file FileStream.cpp
|
||||
** \date 2008-12-20
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2008-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#include "FileStream.h"
|
||||
#include "IFile.h"
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
FileStream::FileStream(IFile& file) : m_file(file)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
size_t FileStream::IStreamRead(char *buf, size_t max_sz)
|
||||
{
|
||||
return m_file.fread(buf, 1, max_sz);
|
||||
}
|
||||
|
||||
|
||||
void FileStream::IStreamWrite(const char *buf, size_t sz)
|
||||
{
|
||||
m_file.fwrite(buf, 1, sz);
|
||||
}
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
} // namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
@@ -1,62 +0,0 @@
|
||||
/**
|
||||
** \file FileStream.h
|
||||
** \date 2008-12-20
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2008-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef _SOCKETS_FileStream_H
|
||||
#define _SOCKETS_FileStream_H
|
||||
|
||||
#include "IStream.h"
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
class IFile;
|
||||
|
||||
class FileStream : public IStream
|
||||
{
|
||||
public:
|
||||
FileStream(IFile& file);
|
||||
|
||||
size_t IStreamRead(char *buf, size_t max_sz);
|
||||
|
||||
void IStreamWrite(const char *buf, size_t sz);
|
||||
|
||||
private:
|
||||
IFile& m_file;
|
||||
};
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _SOCKETS_FileStream_H
|
||||
@@ -1,519 +0,0 @@
|
||||
/** \file HTTPSocket.cpp
|
||||
** \date 2004-04-06
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2004-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4786)
|
||||
#endif
|
||||
#include "HTTPSocket.h"
|
||||
#include "Parse.h"
|
||||
#include "ISocketHandler.h"
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
|
||||
HTTPSocket::HTTPSocket(ISocketHandler& h)
|
||||
:TcpSocket(h)
|
||||
,m_first(true)
|
||||
,m_header(true)
|
||||
,m_http_version("HTTP/1.0")
|
||||
,m_request(false)
|
||||
,m_response(false)
|
||||
,m_body_size_left(0)
|
||||
,m_b_http_1_1(false)
|
||||
,m_b_keepalive(false)
|
||||
,m_b_chunked(false)
|
||||
,m_chunk_size(0)
|
||||
,m_chunk_state(0)
|
||||
,m_header_count(0)
|
||||
,m_max_header_count(MAX_HTTP_HEADER_COUNT)
|
||||
{
|
||||
SetLineProtocol();
|
||||
DisableInputBuffer();
|
||||
}
|
||||
|
||||
|
||||
HTTPSocket::~HTTPSocket()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void HTTPSocket::OnRawData(const char *buf,size_t len)
|
||||
{
|
||||
if (!m_header)
|
||||
{
|
||||
if (m_b_chunked)
|
||||
{
|
||||
size_t ptr = 0;
|
||||
while (ptr < len)
|
||||
{
|
||||
switch (m_chunk_state)
|
||||
{
|
||||
case 4:
|
||||
while (ptr < len && (m_chunk_line.size() < 2 || m_chunk_line.substr(m_chunk_line.size() - 2) != "\r\n"))
|
||||
m_chunk_line += buf[ptr++];
|
||||
if (m_chunk_line.size() > 1 && m_chunk_line.substr(m_chunk_line.size() - 2) == "\r\n")
|
||||
{
|
||||
OnDataComplete();
|
||||
// prepare for next request(or response)
|
||||
m_b_chunked = false;
|
||||
SetLineProtocol( true );
|
||||
m_first = true;
|
||||
m_header = true;
|
||||
m_body_size_left = 0;
|
||||
if (len - ptr > 0)
|
||||
{
|
||||
char tmp[TCP_BUFSIZE_READ];
|
||||
memcpy(tmp, buf + ptr, len - ptr);
|
||||
tmp[len - ptr] = 0;
|
||||
OnRead( tmp, len - ptr );
|
||||
ptr = len;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0:
|
||||
while (ptr < len && (m_chunk_line.size() < 2 || m_chunk_line.substr(m_chunk_line.size() - 2) != "\r\n"))
|
||||
m_chunk_line += buf[ptr++];
|
||||
if (m_chunk_line.size() > 1 && m_chunk_line.substr(m_chunk_line.size() - 2) == "\r\n")
|
||||
{
|
||||
m_chunk_line.resize(m_chunk_line.size() - 2);
|
||||
Parse pa(m_chunk_line, ";");
|
||||
std::string size_str = pa.getword();
|
||||
m_chunk_size = Utility::hex2unsigned(size_str);
|
||||
if (!m_chunk_size)
|
||||
{
|
||||
m_chunk_state = 4;
|
||||
m_chunk_line = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
m_chunk_state = 1;
|
||||
m_chunk_line = "";
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
{
|
||||
size_t left = len - ptr;
|
||||
size_t sz = m_chunk_size < left ? m_chunk_size : left;
|
||||
OnData(buf + ptr, sz);
|
||||
m_chunk_size -= sz;
|
||||
ptr += sz;
|
||||
if (!m_chunk_size)
|
||||
{
|
||||
m_chunk_state = 2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2: // skip CR
|
||||
ptr++;
|
||||
m_chunk_state = 3;
|
||||
break;
|
||||
case 3: // skip LF
|
||||
ptr++;
|
||||
m_chunk_state = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
if (!m_b_http_1_1 || !m_b_keepalive)
|
||||
{
|
||||
OnData(buf, len);
|
||||
/*
|
||||
request is HTTP/1.0 _or_ HTTP/1.1 and not keep-alive
|
||||
|
||||
This means we destroy the connection after the response has been delivered,
|
||||
hence no need to reset all internal state variables for a new incoming
|
||||
request.
|
||||
*/
|
||||
m_body_size_left -= len;
|
||||
if (!m_body_size_left)
|
||||
{
|
||||
OnDataComplete();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t sz = m_body_size_left < len ? m_body_size_left : len;
|
||||
OnData(buf, sz);
|
||||
m_body_size_left -= sz;
|
||||
if (!m_body_size_left)
|
||||
{
|
||||
OnDataComplete();
|
||||
// prepare for next request(or response)
|
||||
SetLineProtocol( true );
|
||||
m_first = true;
|
||||
m_header = true;
|
||||
m_body_size_left = 0;
|
||||
if (len - sz > 0)
|
||||
{
|
||||
char tmp[TCP_BUFSIZE_READ];
|
||||
memcpy(tmp, buf + sz, len - sz);
|
||||
tmp[len - sz] = 0;
|
||||
OnRead( tmp, len - sz );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void HTTPSocket::OnLine(const std::string& line)
|
||||
{
|
||||
if (m_first)
|
||||
{
|
||||
Parse pa(line);
|
||||
std::string str = pa.getword();
|
||||
if (str.size() > 4 && Utility::ToLower(str.substr(0,5)) == "http/") // response
|
||||
{
|
||||
m_http_version = str;
|
||||
m_status = pa.getword();
|
||||
m_status_text = pa.getrest();
|
||||
m_response = true;
|
||||
}
|
||||
else // request
|
||||
{
|
||||
m_method = str;
|
||||
m_url = pa.getword();
|
||||
size_t spl = m_url.find("?");
|
||||
if (spl != std::string::npos)
|
||||
{
|
||||
m_uri = m_url.substr(0,spl);
|
||||
m_query_string = m_url.substr(spl + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_uri = m_url;
|
||||
m_query_string = "";
|
||||
}
|
||||
m_http_version = pa.getword();
|
||||
m_b_http_1_1 = m_http_version.size() > 4 && m_http_version.substr(4) == "/1.1";
|
||||
m_b_keepalive = m_b_http_1_1;
|
||||
m_request = true;
|
||||
}
|
||||
m_first = false;
|
||||
OnFirst();
|
||||
return;
|
||||
}
|
||||
if (!line.size())
|
||||
{
|
||||
if (m_body_size_left || !m_b_http_1_1 || !m_b_keepalive || m_b_chunked)
|
||||
{
|
||||
SetLineProtocol(false);
|
||||
m_header = false;
|
||||
}
|
||||
OnHeaderComplete();
|
||||
if (!m_body_size_left && !m_b_chunked)
|
||||
{
|
||||
OnDataComplete();
|
||||
}
|
||||
return;
|
||||
}
|
||||
Parse pa(line,":");
|
||||
std::string key = pa.getword();
|
||||
std::string value = pa.getrest();
|
||||
OnHeader(key,value);
|
||||
if (Utility::ToLower(key) == "content-length")
|
||||
{
|
||||
m_body_size_left = atol(value.c_str());
|
||||
}
|
||||
if (m_b_http_1_1 && Utility::ToLower(key) == "connection")
|
||||
{
|
||||
m_b_keepalive = Utility::ToLower(value) != "close";
|
||||
}
|
||||
if (Utility::ToLower(key) == "transfer-encoding" && Utility::ToLower(value) == "chunked")
|
||||
{
|
||||
m_b_chunked = true;
|
||||
}
|
||||
/* If remote end tells us to keep connection alive, and we're operating
|
||||
in http/1.1 mode (not http/1.0 mode), then we mark the socket to be
|
||||
retained. */
|
||||
#ifdef ENABLE_POOL
|
||||
if (m_b_http_1_1 && m_b_keepalive)
|
||||
{
|
||||
SetRetain();
|
||||
}
|
||||
#endif
|
||||
if (m_header_count++ > m_max_header_count)
|
||||
{
|
||||
SetCloseAndDelete();
|
||||
Handler().LogError(this, "OnLine", m_header_count, "http header count exceeds builtin limit of (" + Utility::l2string(m_max_header_count) + ")", LOG_LEVEL_FATAL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void HTTPSocket::SendResponse()
|
||||
{
|
||||
std::string msg;
|
||||
msg = m_http_version + " " + m_status + " " + m_status_text + "\r\n";
|
||||
for (string_m::iterator it = m_response_header.begin(); it != m_response_header.end(); ++it)
|
||||
{
|
||||
std::string key = (*it).first;
|
||||
std::string val = (*it).second;
|
||||
msg += key + ": " + val + "\r\n";
|
||||
}
|
||||
for (std::list<std::pair<std::string, std::string> >::iterator it2 = m_response_header_append.begin(); it2 != m_response_header_append.end(); ++it2)
|
||||
{
|
||||
msg += it2 -> first + ": " + it2 -> second + "\r\n";
|
||||
}
|
||||
msg += "\r\n";
|
||||
Send( msg );
|
||||
}
|
||||
|
||||
|
||||
void HTTPSocket::AddResponseHeader(const std::string& header, const char *format, ...)
|
||||
{
|
||||
char slask[8192]; // temporary for vsprintf / vsnprintf
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, format);
|
||||
vsnprintf(slask, sizeof(slask), format, ap);
|
||||
va_end(ap);
|
||||
|
||||
m_response_header[header] = slask;
|
||||
}
|
||||
|
||||
|
||||
void HTTPSocket::SendRequest()
|
||||
{
|
||||
std::string msg;
|
||||
msg = m_method + " " + m_url + " " + m_http_version + "\r\n";
|
||||
for (string_m::iterator it = m_response_header.begin(); it != m_response_header.end(); ++it)
|
||||
{
|
||||
std::string key = (*it).first;
|
||||
std::string val = (*it).second;
|
||||
msg += key + ": " + val + "\r\n";
|
||||
}
|
||||
msg += "\r\n";
|
||||
Send( msg );
|
||||
}
|
||||
|
||||
|
||||
std::string HTTPSocket::MyUseragent()
|
||||
{
|
||||
std::string version = "C++Sockets/";
|
||||
#ifdef _VERSION
|
||||
version += _VERSION;
|
||||
#endif
|
||||
return version;
|
||||
}
|
||||
|
||||
|
||||
void HTTPSocket::Reset()
|
||||
{
|
||||
m_first = true;
|
||||
m_header = true;
|
||||
m_request = false;
|
||||
m_response = false;
|
||||
SetLineProtocol(true);
|
||||
while (m_response_header.size())
|
||||
{
|
||||
string_m::iterator it = m_response_header.begin();
|
||||
m_response_header.erase(it);
|
||||
}
|
||||
while (m_response_header_append.size())
|
||||
{
|
||||
std::list<std::pair<std::string, std::string> >::iterator it = m_response_header_append.begin();
|
||||
m_response_header_append.erase(it);
|
||||
}
|
||||
m_header_count = 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
const std::string& HTTPSocket::GetMethod()
|
||||
{
|
||||
return m_method;
|
||||
}
|
||||
|
||||
|
||||
void HTTPSocket::SetMethod(const std::string& x)
|
||||
{
|
||||
m_method = x;
|
||||
}
|
||||
|
||||
|
||||
const std::string& HTTPSocket::GetUrl()
|
||||
{
|
||||
return m_url;
|
||||
}
|
||||
|
||||
|
||||
void HTTPSocket::SetUrl(const std::string& x)
|
||||
{
|
||||
m_url = x;
|
||||
}
|
||||
|
||||
|
||||
const std::string& HTTPSocket::GetUri()
|
||||
{
|
||||
return m_uri;
|
||||
}
|
||||
|
||||
|
||||
const std::string& HTTPSocket::GetQueryString()
|
||||
{
|
||||
return m_query_string;
|
||||
}
|
||||
|
||||
|
||||
const std::string& HTTPSocket::GetHttpVersion()
|
||||
{
|
||||
return m_http_version;
|
||||
}
|
||||
|
||||
|
||||
const std::string& HTTPSocket::GetStatus()
|
||||
{
|
||||
return m_status;
|
||||
}
|
||||
|
||||
|
||||
const std::string& HTTPSocket::GetStatusText()
|
||||
{
|
||||
return m_status_text;
|
||||
}
|
||||
|
||||
|
||||
bool HTTPSocket::IsRequest()
|
||||
{
|
||||
return m_request;
|
||||
}
|
||||
|
||||
|
||||
bool HTTPSocket::IsResponse()
|
||||
{
|
||||
return m_response;
|
||||
}
|
||||
|
||||
|
||||
void HTTPSocket::SetHttpVersion(const std::string& x)
|
||||
{
|
||||
m_http_version = x;
|
||||
}
|
||||
|
||||
|
||||
void HTTPSocket::SetStatus(const std::string& x)
|
||||
{
|
||||
m_status = x;
|
||||
}
|
||||
|
||||
|
||||
void HTTPSocket::SetStatusText(const std::string& x)
|
||||
{
|
||||
m_status_text = x;
|
||||
}
|
||||
|
||||
|
||||
void HTTPSocket::AddResponseHeader(const std::string& x,const std::string& y)
|
||||
{
|
||||
m_response_header[x] = y;
|
||||
}
|
||||
|
||||
|
||||
void HTTPSocket::AppendResponseHeader(const std::string& x,const std::string& y)
|
||||
{
|
||||
m_response_header_append.push_back(std::pair<std::string, std::string>(x,y));
|
||||
}
|
||||
|
||||
|
||||
void HTTPSocket::SetUri(const std::string& x)
|
||||
{
|
||||
m_uri = x;
|
||||
}
|
||||
|
||||
|
||||
void HTTPSocket::url_this(const std::string& url_in,std::string& protocol,std::string& host,port_t& port,std::string& url,std::string& file)
|
||||
{
|
||||
Parse pa(url_in,"/");
|
||||
protocol = pa.getword(); // http
|
||||
if (!strcasecmp(protocol.c_str(), "https:"))
|
||||
{
|
||||
#ifdef HAVE_OPENSSL
|
||||
EnableSSL();
|
||||
#else
|
||||
Handler().LogError(this, "url_this", -1, "SSL not available", LOG_LEVEL_WARNING);
|
||||
#endif
|
||||
port = 443;
|
||||
}
|
||||
else
|
||||
{
|
||||
port = 80;
|
||||
}
|
||||
host = pa.getword();
|
||||
if (strstr(host.c_str(),":"))
|
||||
{
|
||||
Parse pa(host,":");
|
||||
pa.getword(host);
|
||||
port = static_cast<port_t>(pa.getvalue());
|
||||
}
|
||||
url = "/" + pa.getrest();
|
||||
{
|
||||
Parse pa(url,"/");
|
||||
std::string tmp = pa.getword();
|
||||
while (tmp.size())
|
||||
{
|
||||
file = tmp;
|
||||
tmp = pa.getword();
|
||||
}
|
||||
}
|
||||
} // url_this
|
||||
|
||||
|
||||
bool HTTPSocket::ResponseHeaderIsSet(const std::string& name)
|
||||
{
|
||||
string_m::iterator it = m_response_header.find( name );
|
||||
if (it != m_response_header.end())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
std::list<std::pair<std::string, std::string> >::iterator it2;
|
||||
for (it2 = m_response_header_append.begin(); it2 != m_response_header_append.end(); ++it2)
|
||||
{
|
||||
std::pair<std::string, std::string>& ref = *it2;
|
||||
if (!strcasecmp(ref.first.c_str(), name.c_str()) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,175 +0,0 @@
|
||||
/** \file HTTPSocket.h Class HTTPSocket definition.
|
||||
** \date 2004-04-06
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2004-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef _SOCKETS_HTTPSocket_H
|
||||
#define _SOCKETS_HTTPSocket_H
|
||||
|
||||
#include "sockets-config.h"
|
||||
#include "TcpSocket.h"
|
||||
#include "Utility.h"
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
/** \defgroup http HTTP Sockets */
|
||||
/** HTTP request/response base class.
|
||||
\ingroup http */
|
||||
class HTTPSocket : public TcpSocket
|
||||
{
|
||||
/** map to hold http header values. */
|
||||
typedef Utility::ncmap<std::string> string_m;
|
||||
public:
|
||||
HTTPSocket(ISocketHandler& );
|
||||
~HTTPSocket();
|
||||
|
||||
void OnRawData(const char *buf,size_t len);
|
||||
void OnLine(const std::string& line);
|
||||
|
||||
/** Callback executes when first line has been received.
|
||||
GetMethod, GetUrl/GetUri, and GetHttpVersion are valid when this callback is executed. */
|
||||
virtual void OnFirst() = 0;
|
||||
/** For each header line this callback is executed.
|
||||
\param key Http header name
|
||||
\param value Http header value */
|
||||
virtual void OnHeader(const std::string& key,const std::string& value) = 0;
|
||||
/** Callback fires when all http headers have been received. */
|
||||
virtual void OnHeaderComplete() = 0;
|
||||
/** Chunk of http body data recevied. */
|
||||
virtual void OnData(const char *,size_t) = 0;
|
||||
/** The full request/response body has been received. */
|
||||
virtual void OnDataComplete() {}
|
||||
|
||||
/** Get http method from incoming request, ie GET/POST/PUT etc */
|
||||
const std::string& GetMethod();
|
||||
/** Set http method to be used in request. */
|
||||
void SetMethod(const std::string& x);
|
||||
/** Get url from request. */
|
||||
const std::string& GetUrl();
|
||||
/** Set url to be used in outgoing request. */
|
||||
void SetUrl(const std::string& x);
|
||||
/** Get part of url before '?' character. */
|
||||
const std::string& GetUri();
|
||||
/** Now why would I need this when there is a SetUrl method? */
|
||||
void SetUri(const std::string& x);
|
||||
/** Get part of url after '?' character. */
|
||||
const std::string& GetQueryString();
|
||||
/** Get http version from incoming request/response. */
|
||||
const std::string& GetHttpVersion();
|
||||
/** Get http status from incoming response. */
|
||||
const std::string& GetStatus();
|
||||
/** Get http statustext from incoming response. */
|
||||
const std::string& GetStatusText();
|
||||
/** Incoming header has been identified as a request (method url http_version\r\n). */
|
||||
bool IsRequest();
|
||||
/** Incoming header has been identified as a response (http_version status status_text\r\n). */
|
||||
bool IsResponse();
|
||||
/** Set http version to be used in outgoing request/response. */
|
||||
void SetHttpVersion(const std::string& x);
|
||||
/** Set http status for outgoing response. */
|
||||
void SetStatus(const std::string& x);
|
||||
/** Set http statustext for outgoing response. */
|
||||
void SetStatusText(const std::string& x);
|
||||
/** Add (and replace if exists) http header. */
|
||||
void AddResponseHeader(const std::string& x,const std::string& y);
|
||||
/** Add (and replace if exists) http header. */
|
||||
void AddResponseHeader(const std::string& x,const char *format, ...);
|
||||
/** Add http header. */
|
||||
void AppendResponseHeader(const std::string& x,const std::string& y);
|
||||
/** See if http header 'name' has been set. */
|
||||
bool ResponseHeaderIsSet(const std::string& name);
|
||||
/** Send response prepared with calls to methods SetHttpVersion, SetStatus, SetStatusText,
|
||||
and AddResponseHeader. */
|
||||
void SendResponse();
|
||||
/** Send request prepared with calls to methods SetMethod, SetUrl, SetHttpVersion,
|
||||
and AddResponseHeader. */
|
||||
void SendRequest();
|
||||
|
||||
/** Implement this to return your own User-agent string. */
|
||||
virtual std::string MyUseragent();
|
||||
|
||||
/** Parse url. If protocol is https, EnableSSL() will be called. */
|
||||
void url_this(const std::string& url_in,std::string& protocol,std::string& host,port_t& port,std::string& url,std::string& file);
|
||||
|
||||
/** Transfer coding 'chunked' */
|
||||
bool IsChunked() {
|
||||
return m_b_chunked;
|
||||
}
|
||||
|
||||
protected:
|
||||
HTTPSocket(const HTTPSocket& s) : TcpSocket(s) {}
|
||||
/** Reset state of socket to sucessfully implement keep-alive. */
|
||||
virtual void Reset();
|
||||
|
||||
void SetMaxHeaderCount(int x) {
|
||||
m_max_header_count = x;
|
||||
}
|
||||
|
||||
private:
|
||||
HTTPSocket& operator=(const HTTPSocket& ) {
|
||||
return *this;
|
||||
}
|
||||
bool m_first;
|
||||
bool m_header;
|
||||
std::string m_line;
|
||||
std::string m_method;
|
||||
std::string m_url;
|
||||
std::string m_uri;
|
||||
std::string m_query_string;
|
||||
std::string m_http_version;
|
||||
std::string m_status;
|
||||
std::string m_status_text;
|
||||
bool m_request;
|
||||
bool m_response;
|
||||
string_m m_response_header;
|
||||
size_t m_body_size_left;
|
||||
bool m_b_http_1_1;
|
||||
bool m_b_keepalive;
|
||||
std::list<std::pair<std::string, std::string> > m_response_header_append;
|
||||
bool m_b_chunked;
|
||||
size_t m_chunk_size;
|
||||
int m_chunk_state;
|
||||
std::string m_chunk_line;
|
||||
int m_header_count;
|
||||
int m_max_header_count;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _SOCKETS_HTTPSocket_H
|
||||
|
||||
@@ -1,215 +0,0 @@
|
||||
/**
|
||||
** \file AjpBaseSocket.cpp
|
||||
** \date 2007-10-05
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2007-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4786)
|
||||
#endif
|
||||
#include "HttpBaseSocket.h"
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define DEB(x) x
|
||||
#else
|
||||
#define DEB(x)
|
||||
#endif
|
||||
|
||||
|
||||
HttpBaseSocket::HttpBaseSocket(ISocketHandler& h)
|
||||
:HTTPSocket(h)
|
||||
,m_b_keepalive(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HttpBaseSocket::~HttpBaseSocket()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void HttpBaseSocket::OnFirst()
|
||||
{
|
||||
DEB(fprintf(stderr, " %s %s %s\n", GetMethod().c_str(), GetUri().c_str(), GetHttpVersion().c_str());)
|
||||
m_req.SetHttpMethod( GetMethod() );
|
||||
m_req.SetUri( GetUri() );
|
||||
m_req.SetHttpVersion( GetHttpVersion() );
|
||||
|
||||
if (Utility::ToLower(GetMethod()) == "get" && !GetQueryString().empty())
|
||||
{
|
||||
m_req.SetAttribute("query_string", GetQueryString() );
|
||||
}
|
||||
|
||||
m_req.SetRemoteAddr( GetRemoteAddress() );
|
||||
m_req.SetRemoteHost( "" ); // %!
|
||||
m_req.SetServerName( GetSockAddress() );
|
||||
m_req.SetServerPort( GetSockPort() );
|
||||
}
|
||||
|
||||
|
||||
void HttpBaseSocket::OnHeader(const std::string& key,const std::string& value)
|
||||
{
|
||||
DEB(fprintf(stderr, " (request)OnHeader %s: %s\n", key.c_str(), value.c_str());)
|
||||
if (Utility::ToLower(key) == "cookie")
|
||||
m_req.AddCookie(value);
|
||||
else
|
||||
m_req.SetHeader(key, value);
|
||||
}
|
||||
|
||||
|
||||
void HttpBaseSocket::OnHeaderComplete()
|
||||
{
|
||||
m_body_size_left = atol( m_req.Header("content-length").c_str() );
|
||||
if (m_body_size_left > 0)
|
||||
{
|
||||
m_req.InitBody( m_body_size_left );
|
||||
}
|
||||
else
|
||||
{
|
||||
// execute
|
||||
Execute();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void HttpBaseSocket::OnData(const char *buf,size_t sz)
|
||||
{
|
||||
m_req.Write( buf, sz );
|
||||
m_body_size_left -= sz;
|
||||
if (!m_body_size_left)
|
||||
{
|
||||
m_req.CloseBody();
|
||||
|
||||
// execute
|
||||
Execute();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
void HttpBaseSocket::Execute()
|
||||
{
|
||||
// parse form data / query_string and cookie header if available
|
||||
m_req.ParseBody();
|
||||
|
||||
DEB(printf(" *** http version: %s\n", m_req.HttpVersion().c_str());
|
||||
printf(" *** connection: %s\n", m_req.Header("connection").c_str());)
|
||||
if ( !(m_req.HttpVersion().size() > 4 && m_req.HttpVersion().substr(m_req.HttpVersion().size() - 4) == "/1.1") ||
|
||||
m_req.Header("connection") == "close")
|
||||
{
|
||||
m_b_keepalive = false;
|
||||
DEB(printf(" *** keepalive: false\n");)
|
||||
}
|
||||
else
|
||||
{
|
||||
m_b_keepalive = true;
|
||||
DEB(printf(" *** keepalive: true\n");)
|
||||
}
|
||||
|
||||
// prepare page
|
||||
OnExec( m_req );
|
||||
|
||||
m_req.Reset();
|
||||
Reset();
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
void HttpBaseSocket::Respond(const HttpResponse& res)
|
||||
{
|
||||
m_res = res;
|
||||
|
||||
SetHttpVersion( m_res.HttpVersion() );
|
||||
SetStatus( Utility::l2string(m_res.HttpStatusCode()) );
|
||||
SetStatusText( m_res.HttpStatusMsg() );
|
||||
|
||||
if (!ResponseHeaderIsSet("content-length"))
|
||||
{
|
||||
AddResponseHeader( "content-length", Utility::l2string( m_res.GetFile().size() ) );
|
||||
}
|
||||
for (Utility::ncmap<std::string>::const_iterator it = m_res.Headers().begin(); it != m_res.Headers().end(); ++it)
|
||||
{
|
||||
AddResponseHeader( it -> first, it -> second );
|
||||
}
|
||||
std::list<std::string> vec = m_res.CookieNames();
|
||||
for (std::list<std::string>::iterator it2 = vec.begin(); it2 != vec.end(); ++it2)
|
||||
{
|
||||
AppendResponseHeader( "set-cookie", m_res.Cookie(*it2) );
|
||||
}
|
||||
SendResponse();
|
||||
|
||||
OnTransferLimit();
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
void HttpBaseSocket::OnTransferLimit()
|
||||
{
|
||||
char msg[32768];
|
||||
size_t n = m_res.GetFile().fread(msg, 1, 32768);
|
||||
while (n > 0)
|
||||
{
|
||||
SendBuf( msg, n );
|
||||
if (GetOutputLength() > 1)
|
||||
{
|
||||
SetTransferLimit( 1 );
|
||||
break;
|
||||
}
|
||||
n = m_res.GetFile().fread(msg, 1, 32768);
|
||||
}
|
||||
if (!GetOutputLength())
|
||||
{
|
||||
SetTransferLimit(0);
|
||||
m_res.GetFile().fclose();
|
||||
OnResponseComplete();
|
||||
if (!m_b_keepalive)
|
||||
{
|
||||
SetCloseAndDelete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
void HttpBaseSocket::Reset()
|
||||
{
|
||||
HTTPSocket::Reset();
|
||||
m_body_size_left = 0;
|
||||
}
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
} // namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
/**
|
||||
** \file HttpBaseSocket.h
|
||||
** \date 2007-10-05
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2007-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef _HttpBaseSocket_H
|
||||
#define _HttpBaseSocket_H
|
||||
|
||||
#include "HTTPSocket.h"
|
||||
#include "HttpRequest.h"
|
||||
#include "IHttpServer.h"
|
||||
#include "HttpResponse.h"
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
|
||||
class HttpResponse;
|
||||
|
||||
class HttpBaseSocket : public HTTPSocket, public IHttpServer
|
||||
{
|
||||
public:
|
||||
HttpBaseSocket(ISocketHandler& h);
|
||||
~HttpBaseSocket();
|
||||
|
||||
void OnFirst();
|
||||
void OnHeader(const std::string& key,const std::string& value);
|
||||
void OnHeaderComplete();
|
||||
void OnData(const char *,size_t);
|
||||
|
||||
// implements IHttpServer::Respond
|
||||
void Respond(const HttpResponse& res);
|
||||
|
||||
void OnTransferLimit();
|
||||
|
||||
protected:
|
||||
HttpBaseSocket(const HttpBaseSocket& s) : HTTPSocket(s) {} // copy constructor
|
||||
//
|
||||
HttpRequest m_req;
|
||||
HttpResponse m_res;
|
||||
void Reset();
|
||||
|
||||
private:
|
||||
HttpBaseSocket& operator=(const HttpBaseSocket& ) {
|
||||
return *this; // assignment operator
|
||||
}
|
||||
void Execute();
|
||||
//
|
||||
size_t m_body_size_left;
|
||||
bool m_b_keepalive;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
} // namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
#endif // _HttpBaseSocket_H
|
||||
|
||||
@@ -1,312 +0,0 @@
|
||||
/**
|
||||
** \file HttpClientSocket.cpp
|
||||
** \date 2006-04-20
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2007-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4786)
|
||||
#endif
|
||||
#include "HttpClientSocket.h"
|
||||
#include "StdLog.h"
|
||||
#include "ISocketHandler.h"
|
||||
#include "File.h"
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
|
||||
HttpClientSocket::HttpClientSocket(ISocketHandler& h)
|
||||
:HTTPSocket(h)
|
||||
,m_data_ptr(NULL)
|
||||
,m_data_size(0)
|
||||
,m_content_length(0)
|
||||
,m_data_ptr_set(false)
|
||||
,m_fil(NULL)
|
||||
,m_content_ptr(0)
|
||||
,m_b_complete(false)
|
||||
,m_b_close_when_complete(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HttpClientSocket::HttpClientSocket(ISocketHandler& h,const std::string& url_in)
|
||||
:HTTPSocket(h)
|
||||
,m_data_ptr(NULL)
|
||||
,m_data_size(0)
|
||||
,m_content_length(0)
|
||||
,m_data_ptr_set(false)
|
||||
,m_fil(NULL)
|
||||
,m_content_ptr(0)
|
||||
,m_b_complete(false)
|
||||
,m_b_close_when_complete(false)
|
||||
{
|
||||
std::string url;
|
||||
url_this(url_in, m_protocol, m_host, m_port, url, m_url_filename);
|
||||
SetUrl( url );
|
||||
}
|
||||
|
||||
|
||||
HttpClientSocket::HttpClientSocket(ISocketHandler& h,const std::string& host, port_t port, const std::string& url_in)
|
||||
:HTTPSocket(h)
|
||||
,m_data_ptr(NULL)
|
||||
,m_data_size(0)
|
||||
,m_content_length(0)
|
||||
,m_data_ptr_set(false)
|
||||
,m_fil(NULL)
|
||||
,m_content_ptr(0)
|
||||
,m_b_complete(false)
|
||||
,m_b_close_when_complete(false)
|
||||
{
|
||||
std::string url;
|
||||
std::string tmp = "http://" + host + ":" + Utility::l2string(port) + url_in;
|
||||
url_this(tmp, m_protocol, m_host, m_port, url, m_url_filename);
|
||||
SetUrl( url );
|
||||
}
|
||||
|
||||
|
||||
HttpClientSocket::~HttpClientSocket()
|
||||
{
|
||||
if (m_data_ptr && !m_data_ptr_set)
|
||||
{
|
||||
delete[] m_data_ptr;
|
||||
}
|
||||
if (m_fil)
|
||||
{
|
||||
m_fil -> fclose();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void HttpClientSocket::OnFirst()
|
||||
{
|
||||
if (!IsResponse())
|
||||
{
|
||||
Handler().LogError(this, "OnFirst", 0, "Response expected but not received - aborting", LOG_LEVEL_FATAL);
|
||||
SetCloseAndDelete();
|
||||
}
|
||||
m_content = GetHttpVersion() + " " + GetStatus() + " " + GetStatusText() + "\r\n";
|
||||
}
|
||||
|
||||
|
||||
void HttpClientSocket::OnHeader(const std::string& key,const std::string& value)
|
||||
{
|
||||
m_content += key + ": " + value + "\r\n";
|
||||
if (!strcasecmp(key.c_str(), "content-length"))
|
||||
{
|
||||
m_content_length = atoi(value.c_str());
|
||||
}
|
||||
else
|
||||
if (!strcasecmp(key.c_str(), "content-type"))
|
||||
{
|
||||
m_content_type = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void HttpClientSocket::OnHeaderComplete()
|
||||
{
|
||||
if (m_filename.size())
|
||||
{
|
||||
m_fil = new File;
|
||||
if (!m_fil -> fopen(m_filename, "wb"))
|
||||
{
|
||||
delete m_fil;
|
||||
m_fil = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (!m_data_ptr && m_content_length)
|
||||
{
|
||||
m_data_ptr = new unsigned char[m_content_length];
|
||||
m_data_size = m_content_length;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void HttpClientSocket::OnData(const char *buf,size_t len)
|
||||
{
|
||||
if (m_fil)
|
||||
{
|
||||
m_fil -> fwrite(buf, 1, len);
|
||||
}
|
||||
else
|
||||
if (m_data_ptr)
|
||||
{
|
||||
if (m_content_ptr + len > m_data_size)
|
||||
{
|
||||
Handler().LogError(this, "OnData", -1, "content buffer overflow", LOG_LEVEL_ERROR);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(m_data_ptr + m_content_ptr, buf, len);
|
||||
}
|
||||
}
|
||||
m_content_ptr += len;
|
||||
if (m_content_ptr == m_content_length && m_content_length)
|
||||
{
|
||||
if (m_fil)
|
||||
{
|
||||
m_fil -> fclose();
|
||||
delete m_fil;
|
||||
m_fil = NULL;
|
||||
}
|
||||
m_b_complete = true;
|
||||
OnContent();
|
||||
if (m_b_close_when_complete)
|
||||
{
|
||||
SetCloseAndDelete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void HttpClientSocket::OnDelete()
|
||||
{
|
||||
if (!m_b_complete)
|
||||
{
|
||||
if (m_fil)
|
||||
{
|
||||
m_fil -> fclose();
|
||||
delete m_fil;
|
||||
m_fil = NULL;
|
||||
}
|
||||
m_b_complete = true;
|
||||
OnContent();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void HttpClientSocket::SetFilename(const std::string& x)
|
||||
{
|
||||
m_filename = x;
|
||||
}
|
||||
|
||||
|
||||
void HttpClientSocket::SetDataPtr(unsigned char *buf,size_t len)
|
||||
{
|
||||
m_data_ptr = buf;
|
||||
m_data_size = len;
|
||||
m_data_ptr_set = true;
|
||||
}
|
||||
|
||||
|
||||
const std::string& HttpClientSocket::GetContent()
|
||||
{
|
||||
return m_content;
|
||||
}
|
||||
|
||||
|
||||
size_t HttpClientSocket::GetContentLength()
|
||||
{
|
||||
return m_content_length;
|
||||
}
|
||||
|
||||
|
||||
size_t HttpClientSocket::GetContentPtr()
|
||||
{
|
||||
return m_content_ptr;
|
||||
}
|
||||
|
||||
|
||||
size_t HttpClientSocket::GetPos()
|
||||
{
|
||||
return m_content_ptr;
|
||||
}
|
||||
|
||||
|
||||
bool HttpClientSocket::Complete()
|
||||
{
|
||||
return m_b_complete;
|
||||
}
|
||||
|
||||
|
||||
const unsigned char *HttpClientSocket::GetDataPtr() const
|
||||
{
|
||||
return m_data_ptr;
|
||||
}
|
||||
|
||||
|
||||
void HttpClientSocket::OnContent()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void HttpClientSocket::SetCloseOnComplete(bool x)
|
||||
{
|
||||
m_b_close_when_complete = x;
|
||||
}
|
||||
|
||||
|
||||
const std::string& HttpClientSocket::GetUrlProtocol()
|
||||
{
|
||||
return m_protocol;
|
||||
}
|
||||
|
||||
|
||||
const std::string& HttpClientSocket::GetUrlHost()
|
||||
{
|
||||
return m_host;
|
||||
}
|
||||
|
||||
|
||||
port_t HttpClientSocket::GetUrlPort()
|
||||
{
|
||||
return m_port;
|
||||
}
|
||||
|
||||
|
||||
const std::string& HttpClientSocket::GetUrlFilename()
|
||||
{
|
||||
return m_url_filename;
|
||||
}
|
||||
|
||||
|
||||
const std::string& HttpClientSocket::GetContentType()
|
||||
{
|
||||
return m_content_type;
|
||||
}
|
||||
|
||||
|
||||
void HttpClientSocket::Url(const std::string& url_in,std::string& host,port_t& port)
|
||||
{
|
||||
std::string url;
|
||||
url_this(url_in, m_protocol, m_host, m_port, url, m_url_filename);
|
||||
SetUrl(url);
|
||||
host = GetUrlHost();
|
||||
port = GetUrlPort();
|
||||
}
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
} // namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
@@ -1,139 +0,0 @@
|
||||
/**
|
||||
** \file HttpClientSocket.h
|
||||
** \date 2006-04-20
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2007-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef _SOCKETS_HttpClientSocket_H
|
||||
#define _SOCKETS_HttpClientSocket_H
|
||||
|
||||
#include "sockets-config.h"
|
||||
#include "HTTPSocket.h"
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
class IFile;
|
||||
|
||||
/** Get http response to file or memory.
|
||||
\ingroup http */
|
||||
class HttpClientSocket : public HTTPSocket
|
||||
{
|
||||
public:
|
||||
HttpClientSocket(ISocketHandler&);
|
||||
HttpClientSocket(ISocketHandler&,const std::string& url_in);
|
||||
HttpClientSocket(ISocketHandler&,const std::string& host, port_t port, const std::string& url_in);
|
||||
~HttpClientSocket();
|
||||
|
||||
/** Parse url to protocol,host,port,url and file. */
|
||||
void Url(const std::string& url_in,std::string& host,port_t& port);
|
||||
|
||||
void OnFirst();
|
||||
void OnHeader(const std::string&,const std::string&);
|
||||
void OnHeaderComplete();
|
||||
void OnData(const char *,size_t);
|
||||
void OnDelete();
|
||||
|
||||
/** New callback method fires when all data is received. */
|
||||
virtual void OnContent();
|
||||
|
||||
/** Write response to this file */
|
||||
void SetFilename(const std::string& );
|
||||
const std::string& Filename() const {
|
||||
return m_filename;
|
||||
}
|
||||
|
||||
/** Store response in this buffer. */
|
||||
void SetDataPtr(unsigned char *,size_t);
|
||||
|
||||
/** Get response headers. */
|
||||
const std::string& GetContent();
|
||||
|
||||
/** Get size of response body. */
|
||||
size_t GetContentLength();
|
||||
|
||||
/** Get content type from response header. */
|
||||
const std::string& GetContentType();
|
||||
|
||||
/** Get size of received response body. */
|
||||
size_t GetContentPtr();
|
||||
/** Get size of received response body. */
|
||||
size_t GetPos();
|
||||
|
||||
/** Complete response has been received. */
|
||||
bool Complete();
|
||||
|
||||
/** Get ptr to response data buffer. */
|
||||
const unsigned char *GetDataPtr() const;
|
||||
|
||||
/** Close socket when response received. */
|
||||
void SetCloseOnComplete(bool = true);
|
||||
|
||||
/** Get protocol used from url. */
|
||||
const std::string& GetUrlProtocol();
|
||||
/** Get hostname from url. */
|
||||
const std::string& GetUrlHost();
|
||||
/** Get port from url. */
|
||||
port_t GetUrlPort();
|
||||
/** Get filename part of url. */
|
||||
const std::string& GetUrlFilename();
|
||||
|
||||
protected:
|
||||
HttpClientSocket(const HttpClientSocket& s) : HTTPSocket(s) {} // copy constructor
|
||||
HttpClientSocket& operator=(const HttpClientSocket& ) {
|
||||
return *this; // assignment operator
|
||||
}
|
||||
private:
|
||||
std::string m_filename; ///< Filename to write response to
|
||||
unsigned char *m_data_ptr; ///< Ptr to buffer where to store response
|
||||
size_t m_data_size; ///< Max size of data buffer
|
||||
size_t m_content_length; ///< Content-length header received from remote
|
||||
std::string m_content; ///< Received http headers
|
||||
bool m_data_ptr_set; ///< Buffer set from outside, do not delete
|
||||
IFile *m_fil; ///< Output file
|
||||
size_t m_content_ptr; ///< Number of bytes received from body
|
||||
bool m_b_complete; ///< The entire content-length number of bytes has been received
|
||||
bool m_b_close_when_complete; ///< Close when the full response has been received
|
||||
std::string m_protocol; ///< Protocol part of url_in
|
||||
std::string m_host; ///< Hostname from url_in
|
||||
port_t m_port; ///< Port from url_in
|
||||
std::string m_url_filename; ///< Filename from url_in
|
||||
std::string m_content_type; ///< Content-type: header from response
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
} // namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
#endif // _SOCKETS_HttpClientSocket_H
|
||||
|
||||
@@ -1,144 +0,0 @@
|
||||
/** \file HttpDebugSocket.cpp
|
||||
** \date 2004-10-08
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2004-2010 Anders Hedstrom (grymse@alhem.net)
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4786)
|
||||
#endif
|
||||
#include "HttpDebugSocket.h"
|
||||
#include "ISocketHandler.h"
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
|
||||
HttpDebugSocket::HttpDebugSocket(ISocketHandler& h) : HTTPSocket(h)
|
||||
,m_content_length(0)
|
||||
,m_read_ptr(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HttpDebugSocket::~HttpDebugSocket()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void HttpDebugSocket::Init()
|
||||
{
|
||||
if (GetParent() -> GetPort() == 443)
|
||||
{
|
||||
#ifdef HAVE_OPENSSL
|
||||
EnableSSL();
|
||||
#else
|
||||
Handler().LogError(this, "url_this", -1, "SSL not available", LOG_LEVEL_WARNING);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void HttpDebugSocket::OnFirst()
|
||||
{
|
||||
Send(
|
||||
"HTTP/1.1 200 OK\n"
|
||||
"Content-type: text/html\n"
|
||||
"Connection: close\n"
|
||||
"Server: HttpDebugSocket/1.0\n"
|
||||
"\n");
|
||||
Send(
|
||||
"<html><head><title>Echo Request</title></head>"
|
||||
"<body><h3>Request Header</h3>");
|
||||
Send( "<form method='post' action='/test_post'>"
|
||||
"<input type='text' name='text' value='test text'><br>"
|
||||
"<input type='submit' name='submit' value=' OK '></form>");
|
||||
|
||||
// enctype 'multipart/form-data'
|
||||
Sendf("<form action='/test_post' method='post' enctype='multipart/form-data'>");
|
||||
Sendf("<input type=file name=the_file><br>");
|
||||
Sendf("<input type=text name=the_name><br>");
|
||||
Sendf("<input type=submit name=submit value=' test form-data '>");
|
||||
Sendf("</form>");
|
||||
|
||||
Send( "<pre style='background: #e0e0e0'>");
|
||||
Send(GetMethod() + " " + GetUrl() + " " + GetHttpVersion() + "\n");
|
||||
}
|
||||
|
||||
|
||||
void HttpDebugSocket::OnHeader(const std::string& key,const std::string& value)
|
||||
{
|
||||
if (!strcasecmp(key.c_str(),"content-length"))
|
||||
m_content_length = atoi(value.c_str());
|
||||
|
||||
Send(key + ": " + value + "\n");
|
||||
}
|
||||
|
||||
|
||||
void HttpDebugSocket::OnHeaderComplete()
|
||||
{
|
||||
if (m_content_length || IsChunked())
|
||||
{
|
||||
Send("</pre><h3>Request Body</h3><pre style='background: #e0e0e0'>");
|
||||
}
|
||||
else
|
||||
{
|
||||
Send("</pre><hr></body></html>");
|
||||
SetCloseAndDelete();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void HttpDebugSocket::OnData(const char *p,size_t l)
|
||||
{
|
||||
SendBuf(p,l);
|
||||
m_read_ptr += (int)l;
|
||||
if (m_read_ptr >= m_content_length && m_content_length)
|
||||
{
|
||||
Send("</pre><hr></body></html>");
|
||||
SetCloseAndDelete();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void HttpDebugSocket::OnDataComplete()
|
||||
{
|
||||
if (!CloseAndDelete())
|
||||
{
|
||||
Send("</pre><hr></body></html>");
|
||||
SetCloseAndDelete();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
/** \file HttpDebugSocket.h
|
||||
** \date 2004-09-27
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2004-2010 Anders Hedstrom (grymse@alhem.net)
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef _SOCKETS_HttpDebugSocket_H
|
||||
#define _SOCKETS_HttpDebugSocket_H
|
||||
|
||||
#include "sockets-config.h"
|
||||
#include "HTTPSocket.h"
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
class ISocketHandler;
|
||||
|
||||
/** HTTP request "echo" class. This class echoes a http request/body
|
||||
with a html formatted page.
|
||||
\ingroup http */
|
||||
class HttpDebugSocket : public HTTPSocket
|
||||
{
|
||||
public:
|
||||
HttpDebugSocket(ISocketHandler&);
|
||||
~HttpDebugSocket();
|
||||
|
||||
void Init();
|
||||
|
||||
void OnFirst();
|
||||
void OnHeader(const std::string& key,const std::string& value);
|
||||
void OnHeaderComplete();
|
||||
void OnData(const char *,size_t);
|
||||
void OnDataComplete();
|
||||
|
||||
private:
|
||||
HttpDebugSocket(const HttpDebugSocket& s) : HTTPSocket(s) {} // copy constructor
|
||||
HttpDebugSocket& operator=(const HttpDebugSocket& ) {
|
||||
return *this; // assignment operator
|
||||
}
|
||||
int m_content_length;
|
||||
int m_read_ptr;
|
||||
};
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _SOCKETS_HttpDebugSocket_H
|
||||
|
||||
@@ -1,114 +0,0 @@
|
||||
/** \file HttpGetSocket.cpp
|
||||
** \date 2004-02-13
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2004-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifdef _WIN32
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4786)
|
||||
#endif
|
||||
#else
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#include "ISocketHandler.h"
|
||||
#include "HttpGetSocket.h"
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
|
||||
HttpGetSocket::HttpGetSocket(ISocketHandler& h) : HttpClientSocket(h)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HttpGetSocket::HttpGetSocket(ISocketHandler& h,const std::string& url_in,const std::string& to_file) : HttpClientSocket(h, url_in)
|
||||
{
|
||||
if (to_file.size())
|
||||
{
|
||||
SetFilename(to_file);
|
||||
}
|
||||
if (!Open(GetUrlHost(),GetUrlPort()))
|
||||
{
|
||||
if (!Connecting())
|
||||
{
|
||||
Handler().LogError(this, "HttpGetSocket", -1, "connect() failed miserably", LOG_LEVEL_FATAL);
|
||||
SetCloseAndDelete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
HttpGetSocket::HttpGetSocket(ISocketHandler& h,const std::string& host,port_t port,const std::string& url,const std::string& to_file) : HttpClientSocket(h, host, port, url)
|
||||
{
|
||||
SetUrl(url);
|
||||
if (to_file.size())
|
||||
{
|
||||
SetFilename(to_file);
|
||||
}
|
||||
if (!Open(host, port))
|
||||
{
|
||||
if (!Connecting())
|
||||
{
|
||||
Handler().LogError(this, "HttpGetSocket", -1, "connect() failed miserably", LOG_LEVEL_FATAL);
|
||||
SetCloseAndDelete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
HttpGetSocket::~HttpGetSocket()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void HttpGetSocket::OnConnect()
|
||||
{
|
||||
SetMethod( "GET" );
|
||||
AddResponseHeader( "Accept", "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,video/x-mng,image/png,image/jpeg,image/gif;q=0.2,*/*;q=0.1");
|
||||
AddResponseHeader( "Accept-Language", "en-us,en;q=0.5");
|
||||
AddResponseHeader( "Accept-Encoding", "gzip,deflate");
|
||||
AddResponseHeader( "Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7");
|
||||
AddResponseHeader( "User-agent", MyUseragent() );
|
||||
|
||||
if (GetUrlPort() != 80 && GetUrlPort() != 443)
|
||||
AddResponseHeader( "Host", GetUrlHost() + ":" + Utility::l2string(GetUrlPort()) );
|
||||
else
|
||||
AddResponseHeader( "Host", GetUrlHost() );
|
||||
SendRequest();
|
||||
}
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
/** \file HttpGetSocket.h
|
||||
** \date 2004-02-13
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2004-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef _SOCKETS_HttpGetSocket_H
|
||||
#define _SOCKETS_HttpGetSocket_H
|
||||
|
||||
#include "sockets-config.h"
|
||||
#include "HttpClientSocket.h"
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
|
||||
/** Get http page.
|
||||
\ingroup http */
|
||||
class HttpGetSocket : public HttpClientSocket
|
||||
{
|
||||
public:
|
||||
HttpGetSocket(ISocketHandler&);
|
||||
HttpGetSocket(ISocketHandler&,const std::string& url,const std::string& to_file = "");
|
||||
HttpGetSocket(ISocketHandler&,const std::string& host,port_t port,const std::string& url,const std::string& to_file = "");
|
||||
~HttpGetSocket();
|
||||
|
||||
void OnConnect();
|
||||
|
||||
protected:
|
||||
HttpGetSocket& operator=(const HttpGetSocket& ) {
|
||||
return *this;
|
||||
}
|
||||
HttpGetSocket(const HttpGetSocket& s) : HttpClientSocket(s) {}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _SOCKETS_HttpGetSocket_H
|
||||
|
||||
@@ -1,295 +0,0 @@
|
||||
/** \file HttpPostSocket.cpp
|
||||
** \date 2004-10-30
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2004-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifdef _WIN32
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4786)
|
||||
#pragma warning(disable:4503)
|
||||
#endif
|
||||
#else
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#endif
|
||||
#include "ISocketHandler.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include "Lock.h"
|
||||
#include "File.h"
|
||||
|
||||
#include "HttpPostSocket.h"
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
|
||||
int HttpPostSocket::m_boundary_count = 0;
|
||||
Mutex HttpPostSocket::m_boundary_mutex;
|
||||
|
||||
|
||||
HttpPostSocket::HttpPostSocket(ISocketHandler& h) : HttpClientSocket(h)
|
||||
,m_bMultipart(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HttpPostSocket::HttpPostSocket(ISocketHandler& h,const std::string& url_in) : HttpClientSocket(h, url_in)
|
||||
,m_bMultipart(false)
|
||||
{
|
||||
Lock lock(m_boundary_mutex);
|
||||
|
||||
m_boundary = "----";
|
||||
for (int i = 0; i < 12; i++)
|
||||
{
|
||||
char c = m_boundary_count++ % 128;
|
||||
while (!isalnum(c))
|
||||
c = m_boundary_count++ % 128;
|
||||
m_boundary += c;
|
||||
}
|
||||
m_boundary += "__" + Utility::l2string(m_boundary_count++);
|
||||
}
|
||||
|
||||
|
||||
HttpPostSocket::~HttpPostSocket()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void HttpPostSocket::AddField(const std::string& name,const std::string& value)
|
||||
{
|
||||
std::list<std::string> vec;
|
||||
vec.push_back(value);
|
||||
AddMultilineField(name, vec);
|
||||
}
|
||||
|
||||
|
||||
void HttpPostSocket::AddMultilineField(const std::string& name,std::list<std::string>& values)
|
||||
{
|
||||
m_fields[name] = values;
|
||||
}
|
||||
|
||||
|
||||
void HttpPostSocket::AddFile(const std::string& name,const std::string& filename,const std::string& type)
|
||||
{
|
||||
struct stat st;
|
||||
if (!stat(filename.c_str(), &st))
|
||||
{
|
||||
m_files[name] = filename;
|
||||
m_content_length[filename] = st.st_size;
|
||||
m_content_type[filename] = type;
|
||||
m_bMultipart = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Handler().LogError(this, "AddFile", Errno, StrError(Errno), LOG_LEVEL_FATAL);
|
||||
SetCloseAndDelete();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void HttpPostSocket::Open()
|
||||
{
|
||||
// why do I have to specify TcpSocket:: to get to the Open() method??
|
||||
TcpSocket::Open(GetUrlHost(), GetUrlPort());
|
||||
}
|
||||
|
||||
|
||||
void HttpPostSocket::OnConnect()
|
||||
{
|
||||
if (m_bMultipart)
|
||||
{
|
||||
DoMultipartPost();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string body;
|
||||
|
||||
// only fields, no files, add urlencoding
|
||||
for (std::map<std::string,std::list<std::string> >::iterator it = m_fields.begin(); it != m_fields.end(); ++it)
|
||||
{
|
||||
std::string name = (*it).first;
|
||||
std::list<std::string>& ref = (*it).second;
|
||||
if (body.size())
|
||||
{
|
||||
body += '&';
|
||||
}
|
||||
body += name + "=";
|
||||
bool first = true;
|
||||
for (std::list<std::string>::iterator it = ref.begin(); it != ref.end(); ++it)
|
||||
{
|
||||
std::string value = *it;
|
||||
if (!first)
|
||||
{
|
||||
body += "%0d%0a"; // CRLF
|
||||
}
|
||||
body += Utility::rfc1738_encode(value);
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
|
||||
// build header, send body
|
||||
SetMethod("POST");
|
||||
SetHttpVersion( "HTTP/1.1" );
|
||||
AddResponseHeader( "Host", GetUrlHost() ); // oops - this is actually a request header that we're adding..
|
||||
AddResponseHeader( "User-agent", MyUseragent());
|
||||
AddResponseHeader( "Accept", "text/html, text/plain, */*;q=0.01" );
|
||||
AddResponseHeader( "Connection", "close" );
|
||||
AddResponseHeader( "Content-type", "application/x-www-form-urlencoded" );
|
||||
AddResponseHeader( "Content-length", Utility::l2string((long)body.size()) );
|
||||
SendRequest();
|
||||
|
||||
// send body
|
||||
Send( body );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void HttpPostSocket::DoMultipartPost()
|
||||
{
|
||||
long length = 0; // calculate content_length of our post body
|
||||
std::string tmp;
|
||||
|
||||
// fields
|
||||
{
|
||||
for (std::map<std::string,std::list<std::string> >::iterator it = m_fields.begin(); it != m_fields.end(); ++it)
|
||||
{
|
||||
std::string name = (*it).first;
|
||||
std::list<std::string>& ref = (*it).second;
|
||||
tmp = "--" + m_boundary + "\r\n"
|
||||
"content-disposition: form-data; name=\"" + name + "\"\r\n"
|
||||
"\r\n";
|
||||
for (std::list<std::string>::iterator it = ref.begin(); it != ref.end(); ++it)
|
||||
{
|
||||
std::string value = *it;
|
||||
tmp += value + "\r\n";
|
||||
}
|
||||
length += (long)tmp.size();
|
||||
}
|
||||
}
|
||||
|
||||
// files
|
||||
{
|
||||
for (std::map<std::string,std::string>::iterator it = m_files.begin(); it != m_files.end(); ++it)
|
||||
{
|
||||
std::string name = (*it).first;
|
||||
std::string filename = (*it).second;
|
||||
long content_length = m_content_length[filename];
|
||||
std::string content_type = m_content_type[filename];
|
||||
tmp = "--" + m_boundary + "\r\n"
|
||||
"content-disposition: form-data; name=\"" + name + "\"; filename=\"" + filename + "\"\r\n"
|
||||
"content-type: " + content_type + "\r\n"
|
||||
"\r\n";
|
||||
length += (long)tmp.size();
|
||||
length += content_length;
|
||||
length += 2; // crlf after file
|
||||
}
|
||||
}
|
||||
|
||||
// end
|
||||
tmp = "--" + m_boundary + "--\r\n";
|
||||
length += (long)tmp.size();
|
||||
|
||||
// build header, send body
|
||||
SetMethod("POST");
|
||||
SetHttpVersion( "HTTP/1.1" );
|
||||
AddResponseHeader( "Host", GetUrlHost() ); // oops - this is actually a request header that we're adding..
|
||||
AddResponseHeader( "User-agent", MyUseragent());
|
||||
AddResponseHeader( "Accept", "text/html, text/plain, */*;q=0.01" );
|
||||
AddResponseHeader( "Connection", "close" );
|
||||
AddResponseHeader( "Content-type", "multipart/form-data; boundary=" + m_boundary );
|
||||
AddResponseHeader( "Content-length", Utility::l2string(length) );
|
||||
|
||||
SendRequest();
|
||||
|
||||
// send fields
|
||||
{
|
||||
for (std::map<std::string,std::list<std::string> >::iterator it = m_fields.begin(); it != m_fields.end(); ++it)
|
||||
{
|
||||
std::string name = (*it).first;
|
||||
std::list<std::string>& ref = (*it).second;
|
||||
tmp = "--" + m_boundary + "\r\n"
|
||||
"content-disposition: form-data; name=\"" + name + "\"\r\n"
|
||||
"\r\n";
|
||||
for (std::list<std::string>::iterator it = ref.begin(); it != ref.end(); ++it)
|
||||
{
|
||||
std::string value = *it;
|
||||
tmp += value + "\r\n";
|
||||
}
|
||||
Send( tmp );
|
||||
}
|
||||
}
|
||||
|
||||
// send files
|
||||
{
|
||||
for (std::map<std::string,std::string>::iterator it = m_files.begin(); it != m_files.end(); ++it)
|
||||
{
|
||||
std::string name = (*it).first;
|
||||
std::string filename = (*it).second;
|
||||
std::string content_type = m_content_type[filename];
|
||||
tmp = "--" + m_boundary + "\r\n"
|
||||
"content-disposition: form-data; name=\"" + name + "\"; filename=\"" + filename + "\"\r\n"
|
||||
"content-type: " + content_type + "\r\n"
|
||||
"\r\n";
|
||||
Send( tmp );
|
||||
{
|
||||
std::auto_ptr<IFile> fil = std::auto_ptr<IFile>(new File);
|
||||
if (fil -> fopen(filename, "rb"))
|
||||
{
|
||||
char slask[2000]; // for fread
|
||||
size_t n;
|
||||
while ((n = fil -> fread(slask, 1, 2000)) > 0)
|
||||
{
|
||||
SendBuf(slask, n);
|
||||
}
|
||||
fil -> fclose();
|
||||
}
|
||||
}
|
||||
Send("\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
// end of send
|
||||
Send("--" + m_boundary + "--\r\n");
|
||||
}
|
||||
|
||||
|
||||
void HttpPostSocket::SetMultipart()
|
||||
{
|
||||
m_bMultipart = true;
|
||||
}
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,101 +0,0 @@
|
||||
/** \file HttpPostSocket.h
|
||||
** \date 2004-10-30
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2004-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef _SOCKETS_HttpPostSocket_H
|
||||
#define _SOCKETS_HttpPostSocket_H
|
||||
|
||||
#include "sockets-config.h"
|
||||
#include "HttpClientSocket.h"
|
||||
#include "Mutex.h"
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
|
||||
class ISocketHandler;
|
||||
|
||||
/** Generate a http post request, get response.
|
||||
\ingroup http */
|
||||
class HttpPostSocket : public HttpClientSocket
|
||||
{
|
||||
public:
|
||||
HttpPostSocket(ISocketHandler&);
|
||||
/* client constructor,
|
||||
\param url_in = 'http://host:port/resource' */
|
||||
HttpPostSocket(ISocketHandler&,const std::string& url_in);
|
||||
~HttpPostSocket();
|
||||
|
||||
// these must be specified before connecting / adding to handler
|
||||
/** Add field to post. */
|
||||
void AddField(const std::string& name,const std::string& value);
|
||||
/** Add multiline field to post. */
|
||||
void AddMultilineField(const std::string& name,std::list<std::string>& values);
|
||||
/** Add file to post. */
|
||||
void AddFile(const std::string& name,const std::string& filename,const std::string& type);
|
||||
|
||||
/** use this to post with content-type multipart/form-data.
|
||||
// when adding a file to the post, this is the default and only content-type */
|
||||
void SetMultipart();
|
||||
|
||||
/** connect to host:port derived from url in constructor */
|
||||
void Open();
|
||||
|
||||
/** http put client implemented in OnConnect */
|
||||
void OnConnect();
|
||||
|
||||
protected:
|
||||
std::map<std::string,std::list<std::string> > m_fields;
|
||||
|
||||
private:
|
||||
HttpPostSocket(const HttpPostSocket& s) : HttpClientSocket(s) {} // copy constructor
|
||||
HttpPostSocket& operator=(const HttpPostSocket& ) {
|
||||
return *this; // assignment operator
|
||||
}
|
||||
void DoMultipartPost();
|
||||
//
|
||||
std::map<std::string,std::string> m_files;
|
||||
std::string m_boundary;
|
||||
std::map<std::string,long> m_content_length;
|
||||
std::map<std::string,std::string> m_content_type;
|
||||
bool m_bMultipart;
|
||||
static int m_boundary_count;
|
||||
static Mutex m_boundary_mutex;
|
||||
};
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _SOCKETS_HttpPostSocket_H
|
||||
|
||||
@@ -1,125 +0,0 @@
|
||||
/** \file HttpPutSocket.cpp
|
||||
** \date 2004-10-30
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2004-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifdef _WIN32
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4786)
|
||||
#endif
|
||||
#else
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#include "ISocketHandler.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include "File.h"
|
||||
|
||||
#include "HttpPutSocket.h"
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
|
||||
HttpPutSocket::HttpPutSocket(ISocketHandler& h) : HttpClientSocket(h)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HttpPutSocket::HttpPutSocket(ISocketHandler& h,const std::string& url_in) : HttpClientSocket(h, url_in)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HttpPutSocket::~HttpPutSocket()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void HttpPutSocket::SetFile(const std::string& file)
|
||||
{
|
||||
struct stat st;
|
||||
if (!stat(file.c_str(), &st))
|
||||
{
|
||||
m_filename = file;
|
||||
m_content_length = st.st_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
Handler().LogError(this, "SetFile", Errno, StrError(Errno), LOG_LEVEL_FATAL);
|
||||
SetCloseAndDelete();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void HttpPutSocket::SetContentType(const std::string& type)
|
||||
{
|
||||
m_content_type = type;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void HttpPutSocket::Open()
|
||||
{
|
||||
// why do I have to specify TcpSocket:: to get to the Open() method??
|
||||
TcpSocket::Open(GetUrlHost(), GetUrlPort());
|
||||
}
|
||||
|
||||
|
||||
void HttpPutSocket::OnConnect()
|
||||
{
|
||||
SetMethod( "PUT" );
|
||||
SetHttpVersion( "HTTP/1.1" );
|
||||
AddResponseHeader( "Host", GetUrlHost() );
|
||||
AddResponseHeader( "Content-type", m_content_type );
|
||||
AddResponseHeader( "Content-length", Utility::l2string(m_content_length) );
|
||||
AddResponseHeader( "User-agent", MyUseragent() );
|
||||
SendRequest();
|
||||
|
||||
std::auto_ptr<IFile> fil = std::auto_ptr<IFile>(new File);
|
||||
if (fil -> fopen(m_filename, "rb"))
|
||||
{
|
||||
size_t n;
|
||||
char buf[32768];
|
||||
while ((n = fil -> fread(buf, 1, 32768)) > 0)
|
||||
{
|
||||
SendBuf(buf, n);
|
||||
}
|
||||
fil -> fclose();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,88 +0,0 @@
|
||||
/** \file HttpPutSocket.h
|
||||
** \date 2004-10-30
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2004-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef _SOCKETS_HttpPutSocket_H
|
||||
#define _SOCKETS_HttpPutSocket_H
|
||||
|
||||
#include "sockets-config.h"
|
||||
#include "HttpClientSocket.h"
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
|
||||
class ISocketHandler;
|
||||
|
||||
/** Put http page.
|
||||
\ingroup http */
|
||||
class HttpPutSocket : public HttpClientSocket
|
||||
{
|
||||
public:
|
||||
HttpPutSocket(ISocketHandler&);
|
||||
/** client constructor,
|
||||
\param url_in = 'http://host:port/resource' */
|
||||
HttpPutSocket(ISocketHandler&,const std::string& url_in);
|
||||
~HttpPutSocket();
|
||||
|
||||
// these must be specified before connecting / adding to handler
|
||||
/** Set filename to send. */
|
||||
void SetFile(const std::string& );
|
||||
/** Set mimetype of file to send. */
|
||||
void SetContentType(const std::string& );
|
||||
|
||||
/** connect to host:port derived from url in constructor */
|
||||
void Open();
|
||||
|
||||
/** http put client implemented in OnConnect */
|
||||
void OnConnect();
|
||||
|
||||
private:
|
||||
HttpPutSocket(const HttpPutSocket& s) : HttpClientSocket(s) {} // copy constructor
|
||||
HttpPutSocket& operator=(const HttpPutSocket& ) {
|
||||
return *this; // assignment operator
|
||||
}
|
||||
//
|
||||
std::string m_filename;
|
||||
std::string m_content_type;
|
||||
long m_content_length;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _SOCKETS_HttpPutSocket_H
|
||||
|
||||
@@ -1,428 +0,0 @@
|
||||
/**
|
||||
** \file HttpRequest.cpp
|
||||
** \date 2007-10-05
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2007-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4786)
|
||||
#endif
|
||||
#include "HttpRequest.h"
|
||||
#include "MemFile.h"
|
||||
#include "HttpdForm.h"
|
||||
#include "HttpdCookies.h"
|
||||
#include "Parse.h"
|
||||
#include "Exception.h"
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define DEB(x) x; fflush(stderr);
|
||||
#else
|
||||
#define DEB(x)
|
||||
#endif
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
HttpRequest::HttpRequest() : HttpTransaction()
|
||||
, m_server_port(0)
|
||||
, m_is_ssl(false)
|
||||
, m_body_file(NULL)
|
||||
, m_form(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
#ifndef _WIN32
|
||||
HttpRequest::HttpRequest(FILE *fil) : HttpTransaction()
|
||||
, m_server_port(0)
|
||||
, m_is_ssl(false)
|
||||
, m_body_file(NULL)
|
||||
, m_form(NULL)
|
||||
{
|
||||
int i = 0;
|
||||
DEB( std::cout << "Initialize HttpRequest from cgi...\n";)
|
||||
while (environ[i] && *environ[i])
|
||||
{
|
||||
Parse pa(environ[i], "=");
|
||||
std::string key = pa.getword();
|
||||
std::string value = pa.getrest();
|
||||
if (key == "REQUEST_METHOD")
|
||||
m_method = value;
|
||||
else
|
||||
if (key == "SERVER_PROTOCOL")
|
||||
m_protocol = value;
|
||||
else
|
||||
if (key == "PATH_INFO")
|
||||
m_req_uri = value;
|
||||
else
|
||||
if (key == "REMOTE_ADDR")
|
||||
m_remote_addr = value;
|
||||
else
|
||||
if (key == "REMOTE_HOST")
|
||||
m_remote_host = value;
|
||||
else
|
||||
if (key == "SERVER_NAME")
|
||||
m_server_name = value;
|
||||
else
|
||||
if (key == "SERVER_PORT")
|
||||
m_server_port = atoi(value.c_str());
|
||||
else
|
||||
if (key.size() > 5 && key.substr(0, 5) == "HTTP_")
|
||||
{
|
||||
key = key.substr(5);
|
||||
for (size_t pos = 0; pos < key.size(); pos++)
|
||||
{
|
||||
if (key[pos] == '_')
|
||||
key[pos] = '-';
|
||||
else
|
||||
if (key[pos] >= 'A' && key[pos] <= 'Z')
|
||||
key[pos] |= 32;
|
||||
}
|
||||
DEB( std::cout << " http header '" << key << "' == '" << value << "\n";)
|
||||
SetHeader(key, value);
|
||||
}
|
||||
++i;
|
||||
}
|
||||
DEB( std::cout << " setup http form\n";)
|
||||
m_form = std::auto_ptr<HttpdForm>(new HttpdForm(fil));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
HttpRequest::HttpRequest(const HttpRequest& src) : HttpTransaction(src)
|
||||
, m_method(src.m_method)
|
||||
, m_protocol(src.m_protocol)
|
||||
, m_req_uri(src.m_req_uri)
|
||||
, m_remote_addr(src.m_remote_addr)
|
||||
, m_remote_host(src.m_remote_host)
|
||||
, m_server_name(src.m_server_name)
|
||||
, m_server_port(src.m_server_port)
|
||||
, m_is_ssl(src.m_is_ssl)
|
||||
, m_attribute(src.m_attribute)
|
||||
, m_null(src.m_null)
|
||||
, m_body_file(src.m_body_file)
|
||||
, m_form(src.m_form)
|
||||
, m_cookies(src.m_cookies)
|
||||
, m_cookie(src.m_cookie)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
HttpRequest::~HttpRequest()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
HttpRequest& HttpRequest::operator=(const HttpRequest& src)
|
||||
{
|
||||
m_method = src.m_method;
|
||||
m_protocol = src.m_protocol;
|
||||
m_req_uri = src.m_req_uri;
|
||||
m_remote_addr = src.m_remote_addr;
|
||||
m_remote_host = src.m_remote_host;
|
||||
m_server_name = src.m_server_name;
|
||||
m_server_port = src.m_server_port;
|
||||
m_is_ssl = src.m_is_ssl;
|
||||
m_attribute = src.m_attribute;
|
||||
m_null = src.m_null;
|
||||
m_body_file = src.m_body_file;
|
||||
m_form = src.m_form;
|
||||
m_cookies = src.m_cookies;
|
||||
m_cookie = src.m_cookie;
|
||||
|
||||
HttpTransaction::operator=(src);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
void HttpRequest::SetHttpMethod(const std::string& value)
|
||||
{
|
||||
m_method = value;
|
||||
}
|
||||
|
||||
|
||||
const std::string& HttpRequest::HttpMethod() const
|
||||
{
|
||||
return m_method;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
void HttpRequest::SetHttpVersion(const std::string& value)
|
||||
{
|
||||
m_protocol = value;
|
||||
}
|
||||
|
||||
|
||||
const std::string& HttpRequest::HttpVersion() const
|
||||
{
|
||||
return m_protocol;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
void HttpRequest::SetUri(const std::string& value)
|
||||
{
|
||||
m_req_uri = value;
|
||||
}
|
||||
|
||||
|
||||
const std::string& HttpRequest::Uri() const
|
||||
{
|
||||
return m_req_uri;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
void HttpRequest::SetRemoteAddr(const std::string& value)
|
||||
{
|
||||
m_remote_addr = value;
|
||||
}
|
||||
|
||||
|
||||
const std::string& HttpRequest::RemoteAddr() const
|
||||
{
|
||||
return m_remote_addr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
void HttpRequest::SetRemoteHost(const std::string& value)
|
||||
{
|
||||
m_remote_host = value;
|
||||
}
|
||||
|
||||
|
||||
const std::string& HttpRequest::RemoteHost() const
|
||||
{
|
||||
return m_remote_host;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
void HttpRequest::SetServerName(const std::string& value)
|
||||
{
|
||||
m_server_name = value;
|
||||
}
|
||||
|
||||
|
||||
const std::string& HttpRequest::ServerName() const
|
||||
{
|
||||
return m_server_name;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
void HttpRequest::SetServerPort(int value)
|
||||
{
|
||||
m_server_port = value;
|
||||
}
|
||||
|
||||
|
||||
int HttpRequest::ServerPort() const
|
||||
{
|
||||
return m_server_port;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
void HttpRequest::SetIsSsl(bool value)
|
||||
{
|
||||
m_is_ssl = value;
|
||||
}
|
||||
|
||||
|
||||
bool HttpRequest::IsSsl() const
|
||||
{
|
||||
return m_is_ssl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
void HttpRequest::SetAttribute(const std::string& key, const std::string& value)
|
||||
{
|
||||
m_attribute[key] = value;
|
||||
}
|
||||
|
||||
|
||||
void HttpRequest::SetAttribute(const std::string& key, long value)
|
||||
{
|
||||
m_attribute[key] = Utility::l2string(value);
|
||||
}
|
||||
|
||||
|
||||
const std::string& HttpRequest::Attribute(const std::string& key) const
|
||||
{
|
||||
Utility::ncmap<std::string>::const_iterator it;
|
||||
if ( (it = m_attribute.find(key)) != m_attribute.end())
|
||||
return it -> second;
|
||||
return m_null;
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
const Utility::ncmap<std::string>& HttpRequest::Attributes() const
|
||||
{
|
||||
return m_attribute;
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
void HttpRequest::AddCookie(const std::string& str)
|
||||
{
|
||||
m_cookies.add( str );
|
||||
Parse pa(str, ";");
|
||||
std::string lstr = pa.getword();
|
||||
while (!lstr.empty())
|
||||
{
|
||||
Parse pa2(lstr, "=");
|
||||
std::string name = pa2.getword();
|
||||
m_cookie[name] = lstr;
|
||||
DEB(fprintf(stderr, " *** AddCookie '%s' = '%s'\n", name.c_str(), lstr.c_str());)
|
||||
lstr = pa.getword();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
void HttpRequest::InitBody( size_t sz )
|
||||
{
|
||||
if (!m_body_file.get())
|
||||
m_body_file = std::auto_ptr<IFile>(new MemFile);
|
||||
DEB( else
|
||||
fprintf(stderr, "Body data file already opened\n");)
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
void HttpRequest::Write( const char *buf, size_t sz )
|
||||
{
|
||||
if (m_body_file.get())
|
||||
m_body_file -> fwrite(buf, 1, sz);
|
||||
DEB( else
|
||||
fprintf(stderr, "Write: Body data file not open\n");)
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
void HttpRequest::CloseBody()
|
||||
{
|
||||
if (m_body_file.get())
|
||||
m_body_file -> fclose();
|
||||
DEB( else
|
||||
fprintf(stderr, "CloseBody: File not open\n");)
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
void HttpRequest::ParseBody()
|
||||
{
|
||||
Utility::ncmap<std::string>::const_iterator it;
|
||||
if ( (it = m_attribute.find("query_string")) != m_attribute.end())
|
||||
{
|
||||
std::string qs = it -> second;
|
||||
m_form = std::auto_ptr<HttpdForm>(new HttpdForm( qs, qs.size() ));
|
||||
}
|
||||
else
|
||||
if (m_body_file.get())
|
||||
{
|
||||
m_form = std::auto_ptr<HttpdForm>(new HttpdForm( m_body_file.get(), ContentType(), ContentLength() ));
|
||||
}
|
||||
else
|
||||
{
|
||||
// dummy
|
||||
m_form = std::auto_ptr<HttpdForm>(new HttpdForm( "", 0 ));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
const HttpdForm& HttpRequest::Form() const
|
||||
{
|
||||
if (!m_form.get())
|
||||
throw Exception("Form not available");
|
||||
return *m_form;
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
const HttpdCookies& HttpRequest::Cookies() const
|
||||
{
|
||||
return m_cookies;
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
void HttpRequest::Reset()
|
||||
{
|
||||
HttpTransaction::Reset();
|
||||
m_method = "";
|
||||
m_protocol = "";
|
||||
m_req_uri = "";
|
||||
m_remote_addr = "";
|
||||
m_remote_host = "";
|
||||
m_server_name = "";
|
||||
m_server_port = 0;
|
||||
m_is_ssl = false;
|
||||
while (!m_attribute.empty())
|
||||
{
|
||||
m_attribute.erase(m_attribute.begin());
|
||||
}
|
||||
m_body_file = std::auto_ptr<IFile>(NULL);
|
||||
m_form = std::auto_ptr<HttpdForm>(NULL);
|
||||
m_cookies.Reset();
|
||||
while (!m_cookie.empty())
|
||||
{
|
||||
m_cookie.erase(m_cookie.begin());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
} // namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,145 +0,0 @@
|
||||
/**
|
||||
** \file HttpRequest.h
|
||||
** \date 2007-10-05
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2007-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef _SOCKETS_HttpRequest_H
|
||||
#define _SOCKETS_HttpRequest_H
|
||||
|
||||
#include "HttpTransaction.h"
|
||||
#include "HttpdCookies.h"
|
||||
#include "IFile.h"
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
|
||||
class HttpdForm;
|
||||
class IFile;
|
||||
|
||||
class HttpRequest : public HttpTransaction
|
||||
{
|
||||
public:
|
||||
HttpRequest();
|
||||
/** Create from plain old cgi request */
|
||||
#ifndef _WIN32
|
||||
HttpRequest(FILE *);
|
||||
#endif
|
||||
HttpRequest(const HttpRequest& src);
|
||||
~HttpRequest();
|
||||
|
||||
HttpRequest& operator=(const HttpRequest& src);
|
||||
|
||||
/** Get, Post */
|
||||
void SetHttpMethod(const std::string& value);
|
||||
const std::string& HttpMethod() const;
|
||||
|
||||
/** HTTP/1.x */
|
||||
void SetHttpVersion(const std::string& value);
|
||||
const std::string& HttpVersion() const;
|
||||
|
||||
void SetUri(const std::string& value);
|
||||
const std::string& Uri() const;
|
||||
|
||||
void SetRemoteAddr(const std::string& value);
|
||||
const std::string& RemoteAddr() const;
|
||||
|
||||
void SetRemoteHost(const std::string& value);
|
||||
const std::string& RemoteHost() const;
|
||||
|
||||
void SetServerName(const std::string& value);
|
||||
const std::string& ServerName() const;
|
||||
|
||||
void SetServerPort(int value);
|
||||
int ServerPort() const;
|
||||
|
||||
void SetIsSsl(bool value);
|
||||
bool IsSsl() const;
|
||||
|
||||
/** Set / Read attribute value */
|
||||
void SetAttribute(const std::string& key, const std::string& value);
|
||||
void SetAttribute(const std::string& key, long value);
|
||||
const std::string& Attribute(const std::string& key) const;
|
||||
|
||||
const Utility::ncmap<std::string>& Attributes() const;
|
||||
|
||||
/** Cookies */
|
||||
void AddCookie(const std::string& );
|
||||
const Utility::ncmap<std::string>& CookieMap() const {
|
||||
return m_cookie;
|
||||
}
|
||||
|
||||
/** Open file for body data */
|
||||
void InitBody( size_t sz );
|
||||
|
||||
/** Write body data */
|
||||
void Write( const char *buf, size_t sz );
|
||||
|
||||
/** No more writing */
|
||||
void CloseBody();
|
||||
|
||||
void ParseBody();
|
||||
|
||||
const HttpdForm& Form() const;
|
||||
const HttpdCookies& Cookies() const;
|
||||
|
||||
const IFile *BodyFile() const {
|
||||
return m_body_file.get();
|
||||
}
|
||||
|
||||
void Reset();
|
||||
|
||||
private:
|
||||
std::string m_method;
|
||||
std::string m_protocol;
|
||||
std::string m_req_uri;
|
||||
std::string m_remote_addr;
|
||||
std::string m_remote_host;
|
||||
std::string m_server_name;
|
||||
int m_server_port;
|
||||
bool m_is_ssl;
|
||||
Utility::ncmap<std::string> m_attribute;
|
||||
std::string m_null;
|
||||
mutable std::auto_ptr<IFile> m_body_file;
|
||||
mutable std::auto_ptr<HttpdForm> m_form;
|
||||
HttpdCookies m_cookies;
|
||||
Utility::ncmap<std::string> m_cookie;
|
||||
|
||||
}; // end of class
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
} // namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
#endif // _SOCKETS_HttpRequest_H
|
||||
|
||||
@@ -1,251 +0,0 @@
|
||||
/**
|
||||
** \file HttpResponse.cpp
|
||||
** \date 2007-10-05
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2007-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4786)
|
||||
#endif
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "HttpResponse.h"
|
||||
#include "HttpRequest.h"
|
||||
#include "MemFile.h"
|
||||
#include "File.h"
|
||||
#include "Parse.h"
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define DEB(x) x; fflush(stderr);
|
||||
#else
|
||||
#define DEB(x)
|
||||
#endif
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
HttpResponse::HttpResponse(const std::string& version) : HttpTransaction()
|
||||
, m_http_version( version )
|
||||
, m_http_status_code(0)
|
||||
, m_file( new MemFile )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
HttpResponse::HttpResponse(const HttpResponse& src) : HttpTransaction(src)
|
||||
, m_http_version( src.m_http_version )
|
||||
, m_http_status_code( src.m_http_status_code )
|
||||
, m_http_status_msg( src.m_http_status_msg )
|
||||
, m_cookie( src.m_cookie )
|
||||
, m_file( src.m_file )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
HttpResponse::~HttpResponse()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
HttpResponse& HttpResponse::operator=(const HttpResponse& src)
|
||||
{
|
||||
m_http_version = src.m_http_version;
|
||||
m_http_status_code = src.m_http_status_code;
|
||||
m_http_status_msg = src.m_http_status_msg;
|
||||
m_cookie = src.m_cookie;
|
||||
m_file = src.m_file;
|
||||
|
||||
HttpTransaction::operator=(src);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
void HttpResponse::SetHttpVersion(const std::string& value)
|
||||
{
|
||||
m_http_version = value;
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
const std::string& HttpResponse::HttpVersion() const
|
||||
{
|
||||
return m_http_version;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
void HttpResponse::SetHttpStatusCode(int value)
|
||||
{
|
||||
m_http_status_code = value;
|
||||
}
|
||||
|
||||
|
||||
int HttpResponse::HttpStatusCode() const
|
||||
{
|
||||
return m_http_status_code;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
void HttpResponse::SetHttpStatusMsg(const std::string& value)
|
||||
{
|
||||
m_http_status_msg = value;
|
||||
}
|
||||
|
||||
|
||||
const std::string& HttpResponse::HttpStatusMsg() const
|
||||
{
|
||||
return m_http_status_msg;
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
void HttpResponse::SetCookie(const std::string& value)
|
||||
{
|
||||
Parse pa(value, "=");
|
||||
std::string name = pa.getword();
|
||||
m_cookie[name] = value;
|
||||
DEB(fprintf(stderr, "HttpResponse::Set-Cookie<%s>: %s\n", name.c_str(), value.c_str());)
|
||||
}
|
||||
|
||||
|
||||
const std::string HttpResponse::Cookie(const std::string& name) const
|
||||
{
|
||||
Utility::ncmap<std::string>::const_iterator it = m_cookie.find(name);
|
||||
DEB(fprintf(stderr, "HttpResponse; get value of Cookie<%s>: ", name.c_str());)
|
||||
if (it != m_cookie.end())
|
||||
{
|
||||
DEB(fprintf(stderr, "%s\n", it -> second.c_str());)
|
||||
return it -> second;
|
||||
}
|
||||
DEB(fprintf(stderr, "\n");)
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
std::list<std::string> HttpResponse::CookieNames() const
|
||||
{
|
||||
std::list<std::string> vec;
|
||||
DEB(fprintf(stderr, "HttpResponse::CookieNames; ");)
|
||||
for (Utility::ncmap<std::string>::const_iterator it = m_cookie.begin(); it != m_cookie.end(); ++it)
|
||||
{
|
||||
DEB(fprintf(stderr, " %s", it -> first.c_str());)
|
||||
vec.push_back(it -> first);
|
||||
}
|
||||
DEB(fprintf(stderr, "\n");)
|
||||
return vec;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
void HttpResponse::Write( const std::string& str )
|
||||
{
|
||||
Write( str.c_str(), str.size() );
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
void HttpResponse::Write( const char *buf, size_t sz )
|
||||
{
|
||||
m_file -> fwrite( buf, 1, sz );
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
void HttpResponse::Writef( const char *format, ... )
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
char tmp[10000];
|
||||
vsnprintf(tmp, sizeof(tmp), format, ap);
|
||||
va_end(ap);
|
||||
m_file -> fwrite( tmp, 1, strlen(tmp) );
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
const IFile& HttpResponse::GetFile() const
|
||||
{
|
||||
return *m_file;
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
IFile& HttpResponse::GetFile()
|
||||
{
|
||||
return *m_file;
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
void HttpResponse::SetFile( const std::string& path )
|
||||
{
|
||||
m_file = std::auto_ptr<IFile>(new File);
|
||||
m_file -> fopen( path, "rb" );
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
void HttpResponse::SetFile( IFile *f )
|
||||
{
|
||||
m_file = std::auto_ptr<IFile>(f);
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
void HttpResponse::Reset()
|
||||
{
|
||||
HttpTransaction::Reset();
|
||||
m_http_version = "";
|
||||
m_http_status_code = 0;
|
||||
m_http_status_msg = "";
|
||||
while (!m_cookie.empty())
|
||||
{
|
||||
m_cookie.erase(m_cookie.begin());
|
||||
}
|
||||
m_file = std::auto_ptr<IFile>(new MemFile);
|
||||
}
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
} // namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
@@ -1,99 +0,0 @@
|
||||
/**
|
||||
** \file HttpResponse.h
|
||||
** \date 2007-10-05
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2007-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef _SOCKETS_HttpResponse_H
|
||||
#define _SOCKETS_HttpResponse_H
|
||||
|
||||
#include "HttpTransaction.h"
|
||||
#include <list>
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
|
||||
class IFile;
|
||||
|
||||
class HttpResponse : public HttpTransaction
|
||||
{
|
||||
public:
|
||||
HttpResponse(const std::string& version = "HTTP/1.0");
|
||||
HttpResponse(const HttpResponse& src);
|
||||
~HttpResponse();
|
||||
|
||||
HttpResponse& operator=(const HttpResponse& src);
|
||||
|
||||
/** HTTP/1.x */
|
||||
void SetHttpVersion(const std::string& value);
|
||||
const std::string& HttpVersion() const;
|
||||
|
||||
void SetHttpStatusCode(int value);
|
||||
int HttpStatusCode() const;
|
||||
|
||||
void SetHttpStatusMsg(const std::string& value);
|
||||
const std::string& HttpStatusMsg() const;
|
||||
|
||||
void SetCookie(const std::string& value);
|
||||
const std::string Cookie(const std::string& name) const;
|
||||
std::list<std::string> CookieNames() const;
|
||||
|
||||
void Write( const std::string& str );
|
||||
void Write( const char *buf, size_t sz );
|
||||
void Writef( const char *format, ... );
|
||||
|
||||
const IFile& GetFile() const;
|
||||
IFile& GetFile();
|
||||
|
||||
/** Replace memfile with file on disk, opened for read. */
|
||||
void SetFile( const std::string& path );
|
||||
/** Replace memfile with another IFile */
|
||||
void SetFile( IFile *f );
|
||||
|
||||
void Reset();
|
||||
|
||||
private:
|
||||
std::string m_http_version;
|
||||
int m_http_status_code;
|
||||
std::string m_http_status_msg;
|
||||
Utility::ncmap<std::string> m_cookie;
|
||||
mutable std::auto_ptr<IFile> m_file;
|
||||
|
||||
}; // end of class
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
} // namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
#endif // _SOCKETS_HttpResponse_H
|
||||
|
||||
@@ -1,262 +0,0 @@
|
||||
/**
|
||||
** \file HttpTransaction.cpp
|
||||
** \date 2007-10-05
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2007-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4786)
|
||||
#endif
|
||||
#include "HttpTransaction.h"
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
HttpTransaction::HttpTransaction()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
HttpTransaction::~HttpTransaction()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
void HttpTransaction::SetHeader(const std::string& key, const std::string& value)
|
||||
{
|
||||
m_header[key] = value;
|
||||
}
|
||||
|
||||
|
||||
void HttpTransaction::SetHeader(const std::string& key, long value)
|
||||
{
|
||||
m_header[key] = Utility::l2string(value);
|
||||
}
|
||||
|
||||
|
||||
const std::string& HttpTransaction::Header(const std::string& key) const
|
||||
{
|
||||
Utility::ncmap<std::string>::const_iterator it;
|
||||
if ((it = m_header.find(key)) != m_header.end())
|
||||
return it -> second;
|
||||
return m_null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
void HttpTransaction::SetAccept(const std::string& value)
|
||||
{
|
||||
SetHeader("accept", value);
|
||||
}
|
||||
|
||||
|
||||
const std::string& HttpTransaction::Accept() const
|
||||
{
|
||||
return Header("accept");
|
||||
}
|
||||
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
void HttpTransaction::SetAcceptCharset(const std::string& value)
|
||||
{
|
||||
SetHeader("accept-charset", value);
|
||||
}
|
||||
|
||||
|
||||
const std::string& HttpTransaction::AcceptCharset() const
|
||||
{
|
||||
return Header("accept-charset");
|
||||
}
|
||||
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
void HttpTransaction::SetAcceptEncoding(const std::string& value)
|
||||
{
|
||||
SetHeader("accept-encoding", value);
|
||||
}
|
||||
|
||||
|
||||
const std::string& HttpTransaction::AcceptEncoding() const
|
||||
{
|
||||
return Header("accept-encoding");
|
||||
}
|
||||
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
void HttpTransaction::SetAcceptLanguage(const std::string& value)
|
||||
{
|
||||
SetHeader("accept-language", value);
|
||||
}
|
||||
|
||||
|
||||
const std::string& HttpTransaction::AcceptLanguage() const
|
||||
{
|
||||
return Header("accept-language");
|
||||
}
|
||||
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
void HttpTransaction::SetConnection(const std::string& value)
|
||||
{
|
||||
SetHeader("connection", value);
|
||||
}
|
||||
|
||||
|
||||
const std::string& HttpTransaction::Connection() const
|
||||
{
|
||||
return Header("connection");
|
||||
}
|
||||
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
void HttpTransaction::SetContentType(const std::string& value)
|
||||
{
|
||||
SetHeader("content-type", value);
|
||||
}
|
||||
|
||||
|
||||
const std::string& HttpTransaction::ContentType() const
|
||||
{
|
||||
return Header("content-type");
|
||||
}
|
||||
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
void HttpTransaction::SetContentLength(long value)
|
||||
{
|
||||
SetHeader("content-length", value );
|
||||
}
|
||||
|
||||
|
||||
long HttpTransaction::ContentLength() const
|
||||
{
|
||||
return atol(Header("content-length").c_str());
|
||||
}
|
||||
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
void HttpTransaction::SetHost(const std::string& value)
|
||||
{
|
||||
SetHeader("host", value);
|
||||
}
|
||||
|
||||
|
||||
const std::string& HttpTransaction::Host() const
|
||||
{
|
||||
return Header("host");
|
||||
}
|
||||
|
||||
|
||||
const std::string HttpTransaction::HostOnly() const
|
||||
{
|
||||
std::string host = Header("host");
|
||||
size_t pos = host.find(":");
|
||||
if (pos != std::string::npos)
|
||||
return host.substr(0, pos);
|
||||
return host;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
void HttpTransaction::SetPragma(const std::string& value)
|
||||
{
|
||||
SetHeader("pragma", value);
|
||||
}
|
||||
|
||||
|
||||
const std::string& HttpTransaction::Pragma() const
|
||||
{
|
||||
return Header("pragma");
|
||||
}
|
||||
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
void HttpTransaction::SetReferer(const std::string& value)
|
||||
{
|
||||
SetHeader("referer", value);
|
||||
}
|
||||
|
||||
|
||||
const std::string& HttpTransaction::Referer() const
|
||||
{
|
||||
return Header("referer");
|
||||
}
|
||||
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
void HttpTransaction::SetUserAgent(const std::string& value)
|
||||
{
|
||||
SetHeader("user-agent", value);
|
||||
}
|
||||
|
||||
|
||||
const std::string& HttpTransaction::UserAgent() const
|
||||
{
|
||||
return Header("user-agent");
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
const Utility::ncmap<std::string>& HttpTransaction::Headers() const
|
||||
{
|
||||
return m_header;
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
void HttpTransaction::Reset()
|
||||
{
|
||||
while (!m_header.empty())
|
||||
{
|
||||
m_header.erase(m_header.begin());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
} // namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,106 +0,0 @@
|
||||
/**
|
||||
** \file HttpTransaction.h
|
||||
** \date 2007-10-05
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2007-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef _SOCKETS_HttpTransaction_H
|
||||
#define _SOCKETS_HttpTransaction_H
|
||||
|
||||
#include "Utility.h"
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
|
||||
class HttpTransaction
|
||||
{
|
||||
public:
|
||||
HttpTransaction();
|
||||
virtual ~HttpTransaction();
|
||||
|
||||
/** Set / Read http header value */
|
||||
void SetHeader(const std::string& key, const std::string& value);
|
||||
void SetHeader(const std::string& key, long value);
|
||||
const std::string& Header(const std::string& key) const;
|
||||
|
||||
void SetAccept(const std::string& value);
|
||||
const std::string& Accept() const;
|
||||
|
||||
void SetAcceptCharset(const std::string& value);
|
||||
const std::string& AcceptCharset() const;
|
||||
|
||||
void SetAcceptEncoding(const std::string& value);
|
||||
const std::string& AcceptEncoding() const;
|
||||
|
||||
void SetAcceptLanguage(const std::string& value);
|
||||
const std::string& AcceptLanguage() const;
|
||||
|
||||
void SetConnection(const std::string& value);
|
||||
const std::string& Connection() const;
|
||||
|
||||
void SetContentType(const std::string& value);
|
||||
const std::string& ContentType() const;
|
||||
|
||||
void SetContentLength(long value);
|
||||
long ContentLength() const;
|
||||
|
||||
void SetHost(const std::string& value);
|
||||
const std::string& Host() const;
|
||||
const std::string HostOnly() const;
|
||||
|
||||
void SetPragma(const std::string& value);
|
||||
const std::string& Pragma() const;
|
||||
|
||||
void SetReferer(const std::string& value);
|
||||
const std::string& Referer() const;
|
||||
|
||||
void SetUserAgent(const std::string& value);
|
||||
const std::string& UserAgent() const;
|
||||
|
||||
const Utility::ncmap<std::string>& Headers() const;
|
||||
|
||||
virtual void Reset();
|
||||
|
||||
private:
|
||||
Utility::ncmap<std::string> m_header;
|
||||
std::string m_null;
|
||||
|
||||
}; // end of class
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
} // namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
#endif // _SOCKETS_HttpTransaction_H
|
||||
|
||||
@@ -1,287 +0,0 @@
|
||||
/** \file HttpdCookies.cpp
|
||||
*/
|
||||
/*
|
||||
Copyright (C) 2003-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4786)
|
||||
#endif
|
||||
#include "Parse.h"
|
||||
#include "HTTPSocket.h"
|
||||
#include "HttpdCookies.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define DEB(x) x; fflush(stderr);
|
||||
#else
|
||||
#define DEB(x)
|
||||
#endif
|
||||
|
||||
|
||||
HttpdCookies::HttpdCookies()
|
||||
{
|
||||
}
|
||||
|
||||
HttpdCookies::HttpdCookies(const std::string& s)
|
||||
{
|
||||
Parse *pa = new Parse(s,";");
|
||||
|
||||
std::string slask = pa -> getword();
|
||||
while (slask.size())
|
||||
{
|
||||
Parse *pa2 = new Parse(slask,"=");
|
||||
std::string name = pa2 -> getword();
|
||||
std::string value = pa2 -> getword();
|
||||
delete pa2;
|
||||
m_cookies.push_back(std::pair<std::string, std::string>(name, value));
|
||||
//
|
||||
slask = pa -> getword();
|
||||
}
|
||||
delete pa;
|
||||
}
|
||||
|
||||
void HttpdCookies::add(const std::string& s)
|
||||
{
|
||||
Parse *pa = new Parse(s,";");
|
||||
DEB(fprintf(stderr, "Parse cookie: %s\n", s.c_str());)
|
||||
std::string slask = pa -> getword();
|
||||
while (slask.size())
|
||||
{
|
||||
Parse *pa2 = new Parse(slask,"=");
|
||||
std::string name = pa2 -> getword();
|
||||
std::string value = pa2 -> getword();
|
||||
delete pa2;
|
||||
m_cookies.push_back(std::pair<std::string, std::string>(name, value));
|
||||
//
|
||||
slask = pa -> getword();
|
||||
}
|
||||
delete pa;
|
||||
}
|
||||
|
||||
HttpdCookies::~HttpdCookies()
|
||||
{
|
||||
}
|
||||
|
||||
bool HttpdCookies::getvalue(const std::string& name,std::string& buffer) const
|
||||
{
|
||||
for (cookie_v::const_iterator it = m_cookies.begin(); it != m_cookies.end(); ++it)
|
||||
{
|
||||
const std::pair<std::string, std::string>& ref = *it;
|
||||
if (!strcasecmp(ref.first.c_str(),name.c_str()))
|
||||
{
|
||||
buffer = ref.second;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
buffer = "";
|
||||
return false;
|
||||
}
|
||||
|
||||
void HttpdCookies::replacevalue(const std::string& name,const std::string& value)
|
||||
{
|
||||
for (cookie_v::iterator it = m_cookies.begin(); it != m_cookies.end(); ++it)
|
||||
{
|
||||
std::pair<std::string, std::string>& ref = *it;
|
||||
if (!strcasecmp(ref.first.c_str(),name.c_str()))
|
||||
{
|
||||
ref.second = value;
|
||||
return;
|
||||
}
|
||||
}
|
||||
m_cookies.push_back(std::pair<std::string, std::string>(name, value));
|
||||
|
||||
}
|
||||
|
||||
void HttpdCookies::replacevalue(const std::string& name,long l)
|
||||
{
|
||||
replacevalue(name, Utility::l2string(l));
|
||||
}
|
||||
|
||||
void HttpdCookies::replacevalue(const std::string& name,int i)
|
||||
{
|
||||
replacevalue(name, Utility::l2string(i));
|
||||
}
|
||||
|
||||
size_t HttpdCookies::getlength(const std::string& name) const
|
||||
{
|
||||
for (cookie_v::const_iterator it = m_cookies.begin(); it != m_cookies.end(); ++it)
|
||||
{
|
||||
const std::pair<std::string, std::string>& ref = *it;
|
||||
if (!strcasecmp(ref.first.c_str(),name.c_str()))
|
||||
{
|
||||
return ref.second.size();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void HttpdCookies::setcookie(HTTPSocket *sock, const std::string& domain, const std::string& path, const std::string& name, const std::string& value)
|
||||
{
|
||||
size_t sz = name.size() + value.size() + domain.size() + path.size() + 100;
|
||||
char *str = new char[sz];
|
||||
|
||||
// set-cookie response
|
||||
if (domain.size())
|
||||
{
|
||||
snprintf(str, sz, "%s=%s; domain=%s; path=%s; expires=%s",
|
||||
name.c_str(), value.c_str(),
|
||||
domain.c_str(),
|
||||
path.c_str(),
|
||||
expiredatetime().c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(str, sz, "%s=%s; path=%s; expires=%s",
|
||||
name.c_str(), value.c_str(),
|
||||
path.c_str(),
|
||||
expiredatetime().c_str());
|
||||
}
|
||||
sock -> AddResponseHeader("Set-cookie", str);
|
||||
delete[] str;
|
||||
|
||||
replacevalue(name, value);
|
||||
}
|
||||
|
||||
void HttpdCookies::setcookie(HTTPSocket *sock, const std::string& domain, const std::string& path, const std::string& name, long value)
|
||||
{
|
||||
size_t sz = name.size() + domain.size() + path.size() + 100;
|
||||
char *str = new char[sz];
|
||||
char dt[80];
|
||||
|
||||
// set-cookie response
|
||||
if (domain.size())
|
||||
{
|
||||
snprintf(str, sz, "%s=%ld; domain=%s; path=%s; expires=%s",
|
||||
name.c_str(), value,
|
||||
domain.c_str(),
|
||||
path.c_str(),
|
||||
expiredatetime().c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(str, sz, "%s=%ld; path=%s; expires=%s",
|
||||
name.c_str(), value,
|
||||
path.c_str(),
|
||||
expiredatetime().c_str());
|
||||
}
|
||||
sock -> AddResponseHeader("Set-cookie", str);
|
||||
delete[] str;
|
||||
|
||||
snprintf(dt, sizeof(dt), "%ld", value);
|
||||
replacevalue(name, dt);
|
||||
}
|
||||
|
||||
void HttpdCookies::setcookie(HTTPSocket *sock, const std::string& domain, const std::string& path, const std::string& name, int value)
|
||||
{
|
||||
size_t sz = name.size() + domain.size() + path.size() + 100;
|
||||
char *str = new char[sz];
|
||||
char dt[80];
|
||||
|
||||
// set-cookie response
|
||||
if (domain.size())
|
||||
{
|
||||
snprintf(str, sz, "%s=%d; domain=%s; path=%s; expires=%s",
|
||||
name.c_str(), value,
|
||||
domain.c_str(),
|
||||
path.c_str(),
|
||||
expiredatetime().c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(str, sz, "%s=%d; path=%s; expires=%s",
|
||||
name.c_str(), value,
|
||||
path.c_str(),
|
||||
expiredatetime().c_str());
|
||||
}
|
||||
sock -> AddResponseHeader("Set-cookie", str);
|
||||
delete[] str;
|
||||
|
||||
snprintf(dt, sizeof(dt), "%d", value);
|
||||
replacevalue(name, dt);
|
||||
}
|
||||
|
||||
|
||||
const std::string& HttpdCookies::expiredatetime() const
|
||||
{
|
||||
const char *days[7] = {"Sunday", "Monday",
|
||||
"Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
|
||||
const char *months[12] = {"Jan", "Feb", "Mar", "Apr", "May",
|
||||
"Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
|
||||
char dt[100];
|
||||
|
||||
time_t t = time(NULL);
|
||||
#ifdef __CYGWIN__
|
||||
struct tm *tp = gmtime(&t);
|
||||
snprintf(dt, sizeof(dt), "%s, %02d-%s-%04d %02d:%02d:%02d GMT",
|
||||
days[tp -> tm_wday],
|
||||
tp -> tm_mday,
|
||||
months[tp -> tm_mon],
|
||||
tp -> tm_year + 1910,
|
||||
tp -> tm_hour,
|
||||
tp -> tm_min,
|
||||
tp -> tm_sec);
|
||||
#else
|
||||
struct tm tp;
|
||||
#if defined( _WIN32) && !defined(__CYGWIN__)
|
||||
gmtime_s(&tp, &t);
|
||||
#else
|
||||
gmtime_r(&t, &tp);
|
||||
#endif
|
||||
snprintf(dt, sizeof(dt), "%s, %02d-%s-%04d %02d:%02d:%02d GMT",
|
||||
days[tp.tm_wday],
|
||||
tp.tm_mday,
|
||||
months[tp.tm_mon],
|
||||
tp.tm_year + 1910,
|
||||
tp.tm_hour,
|
||||
tp.tm_min,
|
||||
tp.tm_sec);
|
||||
#endif
|
||||
m_date = dt;
|
||||
return m_date;
|
||||
}
|
||||
|
||||
|
||||
void HttpdCookies::Reset()
|
||||
{
|
||||
while (!m_cookies.empty())
|
||||
{
|
||||
m_cookies.erase(m_cookies.begin());
|
||||
}
|
||||
m_date = "";
|
||||
}
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,94 +0,0 @@
|
||||
/** \file HttpdCookies.h
|
||||
*/
|
||||
/*
|
||||
Copyright (C) 2003-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef _SOCKETS_HttpdCookies_H
|
||||
#define _SOCKETS_HttpdCookies_H
|
||||
|
||||
#include "sockets-config.h"
|
||||
#include <list>
|
||||
#include <string>
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
|
||||
//! Store the cookies name/value pairs.
|
||||
|
||||
|
||||
|
||||
//! Retrieve and manage cookies during a cgi call.
|
||||
class HTTPSocket;
|
||||
|
||||
/** HTTP Cookie parse/container class.
|
||||
\sa HttpdSocket
|
||||
\sa HttpdForm
|
||||
\ingroup webserver */
|
||||
class HttpdCookies
|
||||
{
|
||||
/** list of key/value structs. */
|
||||
typedef std::list<std::pair<std::string, std::string> > cookie_v;
|
||||
|
||||
public:
|
||||
HttpdCookies();
|
||||
HttpdCookies(const std::string& query_string);
|
||||
~HttpdCookies();
|
||||
|
||||
void add(const std::string& s);
|
||||
|
||||
bool getvalue(const std::string&,std::string&) const;
|
||||
void replacevalue(const std::string& ,const std::string& );
|
||||
void replacevalue(const std::string& ,long);
|
||||
void replacevalue(const std::string& ,int);
|
||||
size_t getlength(const std::string& ) const;
|
||||
void setcookie(HTTPSocket *,const std::string& d,const std::string& p,const std::string& c,const std::string& v);
|
||||
void setcookie(HTTPSocket *,const std::string& d,const std::string& p,const std::string& c,long v);
|
||||
void setcookie(HTTPSocket *,const std::string& d,const std::string& p,const std::string& c,int v);
|
||||
const std::string& expiredatetime() const;
|
||||
|
||||
cookie_v& GetHttpdCookies() {
|
||||
return m_cookies;
|
||||
}
|
||||
|
||||
void Reset();
|
||||
|
||||
private:
|
||||
cookie_v m_cookies;
|
||||
mutable std::string m_date;
|
||||
};
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _SOCKETS_HttpdCookies_H
|
||||
|
||||
@@ -1,717 +0,0 @@
|
||||
/** \file HttpdForm.cpp - read stdin, parse cgi input
|
||||
**
|
||||
** Written: 1999-Feb-10 grymse@alhem.net
|
||||
**/
|
||||
|
||||
/*
|
||||
Copyright (C) 1999-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4786)
|
||||
#endif
|
||||
#include "socket_include.h"
|
||||
#include "Parse.h"
|
||||
#include "IFile.h"
|
||||
#include "HttpdForm.h"
|
||||
#include "IFileUpload.h"
|
||||
#include "IStream.h"
|
||||
#include "File.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
#define TMPSIZE 32000
|
||||
#ifdef _DEBUG
|
||||
#define DEB(x) x
|
||||
#else
|
||||
#define DEB(x)
|
||||
#endif
|
||||
|
||||
|
||||
HttpdForm::HttpdForm(FILE *fil)
|
||||
{
|
||||
const char *r_m = getenv("REQUEST_METHOD");
|
||||
const char *q_s = getenv("QUERY_STRING");
|
||||
if (r_m && !strcasecmp(r_m, "post"))
|
||||
{
|
||||
const char *c_t = getenv("CONTENT_TYPE");
|
||||
const char *c_l = getenv("CONTENT_LENGTH");
|
||||
if (c_t && c_l)
|
||||
{
|
||||
std::auto_ptr<IFile> p = std::auto_ptr<IFile>(new File(fil));
|
||||
ParseFormData( p.get(), c_t, atoi(c_l) );
|
||||
}
|
||||
}
|
||||
if (q_s && strlen(q_s))
|
||||
{
|
||||
ParseQueryString(q_s, strlen(q_s));
|
||||
}
|
||||
}
|
||||
|
||||
HttpdForm::HttpdForm(IFile *infil, const std::string& content_type, size_t content_length) : raw(false)
|
||||
, m_file_upload(NULL)
|
||||
, m_upload_stream(NULL)
|
||||
{
|
||||
ParseFormData(infil, content_type, content_length);
|
||||
}
|
||||
|
||||
// HttpdForm(buffer,l) -- request_method GET
|
||||
|
||||
HttpdForm::HttpdForm(const std::string& buffer,size_t l) : raw(false)
|
||||
, m_file_upload(NULL)
|
||||
, m_upload_stream(NULL)
|
||||
{
|
||||
ParseQueryString(buffer, l);
|
||||
}
|
||||
|
||||
void HttpdForm::ParseFormData(IFile *infil, const std::string& content_type, size_t content_length)
|
||||
{
|
||||
CGI *cgi = NULL;
|
||||
size_t extra = 2;
|
||||
int cl = (int)content_length;
|
||||
|
||||
m_current = m_cgi.end();
|
||||
|
||||
if (content_type.size() >= 19 && content_type.substr(0, 19) == "multipart/form-data")
|
||||
{
|
||||
Parse pa(content_type,";=");
|
||||
char *tempcmp = NULL;
|
||||
size_t tc = 0;
|
||||
size_t l = 0;
|
||||
std::string str = pa.getword();
|
||||
m_strBoundary = "";
|
||||
while (!str.empty())
|
||||
{
|
||||
if (!strcmp(str.c_str(),"boundary"))
|
||||
{
|
||||
m_strBoundary = pa.getword();
|
||||
l = m_strBoundary.size();
|
||||
tempcmp = new char[l + extra];
|
||||
}
|
||||
//
|
||||
str = pa.getword();
|
||||
}
|
||||
if (!m_strBoundary.empty())
|
||||
{
|
||||
std::string content_type;
|
||||
std::string current_name;
|
||||
std::string current_filename;
|
||||
char *slask = new char[TMPSIZE];
|
||||
infil -> fgets(slask, TMPSIZE);
|
||||
cl -= (int)strlen(slask);
|
||||
while (cl >= 0 && !infil -> eof())
|
||||
{
|
||||
while (strlen(slask) && (slask[strlen(slask) - 1] == 13 || slask[strlen(slask) - 1] == 10))
|
||||
{
|
||||
slask[strlen(slask) - 1] = 0;
|
||||
}
|
||||
content_type = "";
|
||||
current_name = "";
|
||||
current_filename = "";
|
||||
if ((strstr(slask,m_strBoundary.c_str()) || strstr(m_strBoundary.c_str(),slask)) && strcmp(slask, m_strBoundary.c_str()))
|
||||
{
|
||||
m_strBoundary = slask;
|
||||
l = m_strBoundary.size();
|
||||
delete[] tempcmp;
|
||||
tempcmp = new char[l + extra];
|
||||
}
|
||||
if (!strcmp(slask, m_strBoundary.c_str()))
|
||||
{
|
||||
// Get headers until empty line
|
||||
infil -> fgets(slask, TMPSIZE);
|
||||
cl -= (int)strlen(slask);
|
||||
while (strlen(slask) && (slask[strlen(slask) - 1] == 13 || slask[strlen(slask) - 1] == 10))
|
||||
{
|
||||
slask[strlen(slask) - 1] = 0;
|
||||
}
|
||||
while (cl >= 0 && !infil -> eof() && *slask)
|
||||
{
|
||||
Parse pa(slask,":");
|
||||
std::string h = pa.getword();
|
||||
std::string h2 = pa.getrest();
|
||||
if (!strcasecmp(h.c_str(),"Content-type"))
|
||||
{
|
||||
Parse pa(h2, ";");
|
||||
content_type = pa.getword();
|
||||
}
|
||||
else
|
||||
if (!strcasecmp(h.c_str(),"Content-Disposition"))
|
||||
{
|
||||
Parse pa(h2, ";");
|
||||
h = pa.getword();
|
||||
if (!strcmp(h.c_str(),"form-data"))
|
||||
{
|
||||
pa.EnableQuote(true);
|
||||
h = pa.getword();
|
||||
while (!h.empty())
|
||||
{
|
||||
Parse pa2(h,"=");
|
||||
std::string name = pa2.getword();
|
||||
h = pa2.getrest();
|
||||
if (!strcmp(name.c_str(),"name"))
|
||||
{
|
||||
if (!h.empty() && h[0] == '"')
|
||||
{
|
||||
current_name = h.substr(1, h.size() - 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
current_name = h;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (!strcmp(name.c_str(),"filename"))
|
||||
{
|
||||
if (!h.empty() && h[0] == '"')
|
||||
{
|
||||
current_filename = h.substr(1, h.size() - 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
current_filename = h;
|
||||
}
|
||||
size_t x = 0;
|
||||
for (size_t i = 0; i < current_filename.size(); i++)
|
||||
{
|
||||
if (current_filename[i] == '/' || current_filename[i] == '\\')
|
||||
x = i + 1;
|
||||
}
|
||||
if (x)
|
||||
{
|
||||
current_filename = current_filename.substr(x);
|
||||
}
|
||||
}
|
||||
h = pa.getword();
|
||||
}
|
||||
}
|
||||
}
|
||||
// get next header value
|
||||
infil -> fgets(slask, TMPSIZE);
|
||||
cl -= (int)strlen(slask);
|
||||
while (strlen(slask) && (slask[strlen(slask) - 1] == 13 || slask[strlen(slask) - 1] == 10))
|
||||
{
|
||||
slask[strlen(slask) - 1] = 0;
|
||||
}
|
||||
}
|
||||
// Read content, save...?
|
||||
if (current_filename.empty()) // not a file
|
||||
{
|
||||
std::string val;
|
||||
infil -> fgets(slask, TMPSIZE);
|
||||
cl -= (int)strlen(slask);
|
||||
while (cl >= 0 && !infil -> eof() && strncmp(slask,m_strBoundary.c_str(),m_strBoundary.size() ))
|
||||
{
|
||||
val += slask;
|
||||
infil -> fgets(slask, TMPSIZE);
|
||||
cl -= (int)strlen(slask);
|
||||
}
|
||||
// remove trailing cr/linefeed
|
||||
while (!val.empty() && (val[val.size() - 1] == 13 || val[val.size() - 1] == 10))
|
||||
{
|
||||
val = val.substr(0,val.size() - 1);
|
||||
}
|
||||
cgi = new CGI(current_name, val);
|
||||
m_cgi.push_back(cgi);
|
||||
if (!cl)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
else // current_filename.size() > 0
|
||||
{
|
||||
// read until m_strBoundary...
|
||||
IFile *fil = NULL;
|
||||
int out = 0;
|
||||
char c;
|
||||
char fn[2000]; // where post'd file will be saved
|
||||
#ifdef _WIN32
|
||||
{
|
||||
char tmp_path[2000];
|
||||
::GetTempPathA(2000, tmp_path);
|
||||
if (tmp_path[strlen(tmp_path) - 1] != '\\')
|
||||
{
|
||||
#ifdef __CYGWIN__
|
||||
strcat(tmp_path, "\\");
|
||||
#else
|
||||
strcat_s(tmp_path, sizeof(tmp_path), "\\");
|
||||
#endif
|
||||
}
|
||||
snprintf(fn,sizeof(fn),"%s%s",tmp_path,current_filename.c_str());
|
||||
}
|
||||
#else
|
||||
snprintf(fn,sizeof(fn),"/tmp/%s",current_filename.c_str());
|
||||
#endif
|
||||
if (m_file_upload && !m_upload_stream)
|
||||
m_upload_stream = &m_file_upload -> IFileUploadBegin(current_name, current_filename, content_type);
|
||||
else
|
||||
{
|
||||
fil = new File;
|
||||
if (!fil -> fopen(fn, "wb"))
|
||||
{
|
||||
delete fil;
|
||||
fil = NULL;
|
||||
}
|
||||
}
|
||||
if (fil || m_upload_stream)
|
||||
{
|
||||
infil -> fread(&c,1,1);
|
||||
cl -= 1;
|
||||
while (cl >= 0 && !infil -> eof())
|
||||
{
|
||||
if (out)
|
||||
{
|
||||
if (m_upload_stream)
|
||||
m_upload_stream -> IStreamWrite(&tempcmp[tc], 1);
|
||||
else
|
||||
fil -> fwrite(&tempcmp[tc],1,1);
|
||||
}
|
||||
tempcmp[tc] = c;
|
||||
tc++;
|
||||
if (tc >= l + extra)
|
||||
{
|
||||
tc = 0;
|
||||
out = 1;
|
||||
}
|
||||
if (tc)
|
||||
{
|
||||
if (!strncmp(tempcmp + tc + extra, m_strBoundary.c_str(), l - tc) &&
|
||||
!strncmp(tempcmp, m_strBoundary.c_str() + l - tc, tc))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!strncmp(tempcmp + extra, m_strBoundary.c_str(), l))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
infil -> fread(&c,1,1);
|
||||
cl -= 1;
|
||||
}
|
||||
if (m_file_upload && m_upload_stream)
|
||||
{
|
||||
m_file_upload -> IFileUploadEnd();
|
||||
m_upload_stream = NULL;
|
||||
}
|
||||
else
|
||||
if (fil)
|
||||
{
|
||||
fil -> fclose();
|
||||
delete fil;
|
||||
}
|
||||
|
||||
cgi = new CGI(current_name,fn,fn);
|
||||
m_cgi.push_back(cgi);
|
||||
|
||||
#if defined( _WIN32) && !defined(__CYGWIN__)
|
||||
strcpy_s(slask, TMPSIZE, m_strBoundary.c_str());
|
||||
#else
|
||||
strcpy(slask, m_strBoundary.c_str());
|
||||
#endif
|
||||
size_t l = strlen(slask);
|
||||
infil -> fgets(slask + l, TMPSIZE - (int)l); // next line
|
||||
cl -= (int)strlen(slask + l);
|
||||
}
|
||||
else
|
||||
{
|
||||
// couldn't open file
|
||||
break;
|
||||
}
|
||||
if (!cl)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Probably '<m_strBoundary>--'
|
||||
break;
|
||||
}
|
||||
} // while (!infil -> eof())
|
||||
delete[] slask;
|
||||
} // if (m_strBoundary)
|
||||
if (tempcmp)
|
||||
{
|
||||
delete[] tempcmp;
|
||||
}
|
||||
} // end of multipart
|
||||
else
|
||||
if (strstr(content_type.c_str(), "x-www-form-urlencoded"))
|
||||
{
|
||||
bool got_name = false; // tnx to FatherNitwit
|
||||
int cl = (int)content_length;
|
||||
char c,chigh,clow;
|
||||
std::string slask;
|
||||
m_current = m_cgi.end();
|
||||
std::string name;
|
||||
|
||||
infil -> fread(&c,1,1);
|
||||
cl--;
|
||||
while (cl >= 0 && !infil -> eof())
|
||||
{
|
||||
switch (c) // built-in url decoder
|
||||
{
|
||||
case '=': /* end of name */
|
||||
name = slask;
|
||||
slask.resize(0);
|
||||
got_name = true;
|
||||
break;
|
||||
case '&': /* end of value */
|
||||
if (got_name)
|
||||
{
|
||||
cgi = new CGI(name,slask);
|
||||
got_name = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
cgi = new CGI(slask, "");
|
||||
}
|
||||
slask.resize(0);
|
||||
m_cgi.push_back(cgi);
|
||||
break;
|
||||
case '+': /* space */
|
||||
slask += " ";
|
||||
break;
|
||||
case '%': /* hex value */
|
||||
infil -> fread(&chigh,1,1);
|
||||
cl--;
|
||||
chigh -= 48 + (chigh > '9' ? 7 : 0) + (chigh >= 'a' ? 32 : 0);
|
||||
infil -> fread(&clow,1,1);
|
||||
cl--;
|
||||
clow -= 48 + (clow > '9' ? 7 : 0) + (clow >= 'a' ? 32 : 0);
|
||||
slask += (char)(chigh * 16 + clow);
|
||||
break;
|
||||
default: /* just another char */
|
||||
slask += c;
|
||||
break;
|
||||
}
|
||||
//
|
||||
if (cl > 0)
|
||||
{
|
||||
infil -> fread(&c,1,1);
|
||||
}
|
||||
cl--;
|
||||
}
|
||||
if (got_name)
|
||||
{
|
||||
cgi = new CGI(name,slask);
|
||||
}
|
||||
else
|
||||
{
|
||||
cgi = new CGI(slask, "");
|
||||
}
|
||||
m_cgi.push_back(cgi);
|
||||
}
|
||||
else // read other content up to a limit
|
||||
if (content_length > 0 && content_length < 500000)
|
||||
{
|
||||
int ptr = 0;
|
||||
int cl = (int)content_length;
|
||||
m_content.resize(cl);
|
||||
while (ptr < cl)
|
||||
{
|
||||
int remaining = cl - ptr;
|
||||
int n = fread(&m_content[ptr], 1, remaining, stdin);
|
||||
if (n > 0)
|
||||
ptr += n;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void HttpdForm::ParseQueryString(const std::string& buffer,size_t l)
|
||||
{
|
||||
CGI *cgi = NULL;
|
||||
std::string slask;
|
||||
std::string name;
|
||||
char c,chigh,clow;
|
||||
size_t ptr = 0;
|
||||
bool got_name = false;
|
||||
|
||||
m_current = m_cgi.end();
|
||||
|
||||
ptr = 0;
|
||||
while (ptr < l)
|
||||
{
|
||||
c = buffer[ptr++];
|
||||
switch (c)
|
||||
{
|
||||
case '=': /* end of name */
|
||||
name = slask;
|
||||
slask.resize(0);
|
||||
got_name = true;
|
||||
break;
|
||||
case '&': /* end of value */
|
||||
if (got_name)
|
||||
{
|
||||
cgi = new CGI(name,slask);
|
||||
got_name = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
cgi = new CGI(slask, "");
|
||||
}
|
||||
slask.resize(0);
|
||||
m_cgi.push_back(cgi);
|
||||
break;
|
||||
case '+': /* space */
|
||||
slask += " ";
|
||||
break;
|
||||
case '%': /* hex value */
|
||||
chigh = buffer[ptr++];
|
||||
chigh -= 48 + (chigh > '9' ? 7 : 0) + (chigh >= 'a' ? 32 : 0);
|
||||
clow = buffer[ptr++];
|
||||
clow -= 48 + (clow > '9' ? 7 : 0) + (clow >= 'a' ? 32 : 0);
|
||||
slask += (char)(chigh * 16 + clow);
|
||||
break;
|
||||
default: /* just another char */
|
||||
slask += c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (got_name)
|
||||
{
|
||||
cgi = new CGI(name,slask);
|
||||
}
|
||||
else
|
||||
{
|
||||
cgi = new CGI(slask, "");
|
||||
}
|
||||
m_cgi.push_back(cgi);
|
||||
}
|
||||
|
||||
|
||||
HttpdForm::~HttpdForm()
|
||||
{
|
||||
CGI *cgi = NULL; //,*tmp;
|
||||
|
||||
for (cgi_v::iterator it = m_cgi.begin(); it != m_cgi.end(); ++it)
|
||||
{
|
||||
cgi = *it;
|
||||
delete cgi;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void HttpdForm::EnableRaw(bool b)
|
||||
{
|
||||
raw = b;
|
||||
}
|
||||
|
||||
|
||||
void HttpdForm::strcpyval(std::string& v,const char *value) const
|
||||
{
|
||||
v = "";
|
||||
for (size_t i = 0; i < strlen(value); i++)
|
||||
{
|
||||
if (value[i] == '<')
|
||||
{
|
||||
v += "<";
|
||||
}
|
||||
else
|
||||
if (value[i] == '>')
|
||||
{
|
||||
v += ">";
|
||||
}
|
||||
else
|
||||
if (value[i] == '&')
|
||||
{
|
||||
v += "&";
|
||||
}
|
||||
else
|
||||
{
|
||||
v += value[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool HttpdForm::getfirst(std::string& n) const
|
||||
{
|
||||
m_current = m_cgi.begin();
|
||||
return getnext(n);
|
||||
}
|
||||
|
||||
|
||||
bool HttpdForm::getnext(std::string& n) const
|
||||
{
|
||||
if (m_current != m_cgi.end() )
|
||||
{
|
||||
CGI *current = *m_current;
|
||||
n = current -> name;
|
||||
m_current++;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
n = "";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool HttpdForm::getfirst(std::string& n,std::string& v) const
|
||||
{
|
||||
m_current = m_cgi.begin();
|
||||
return getnext(n,v);
|
||||
}
|
||||
|
||||
|
||||
bool HttpdForm::getnext(std::string& n,std::string& v) const
|
||||
{
|
||||
if (m_current != m_cgi.end() )
|
||||
{
|
||||
CGI *current = *m_current;
|
||||
n = current -> name;
|
||||
if (raw)
|
||||
{
|
||||
v = current -> value;
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpyval(v,current -> value.c_str());
|
||||
}
|
||||
m_current++;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
n = "";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
int HttpdForm::getvalue(const std::string& n,std::string& v) const
|
||||
{
|
||||
CGI *cgi = NULL;
|
||||
int r = 0;
|
||||
|
||||
for (cgi_v::const_iterator it = m_cgi.begin(); it != m_cgi.end(); ++it)
|
||||
{
|
||||
cgi = *it;
|
||||
if (cgi -> name == n)
|
||||
break;
|
||||
cgi = NULL;
|
||||
}
|
||||
if (cgi)
|
||||
{
|
||||
if (raw)
|
||||
{
|
||||
v = cgi -> value;
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpyval(v,cgi -> value.c_str());
|
||||
}
|
||||
r++;
|
||||
}
|
||||
else
|
||||
{
|
||||
v = "";
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
std::string HttpdForm::getvalue(const std::string& n) const
|
||||
{
|
||||
for (cgi_v::const_iterator it = m_cgi.begin(); it != m_cgi.end(); ++it)
|
||||
{
|
||||
CGI *cgi = *it;
|
||||
if (cgi -> name == n)
|
||||
{
|
||||
return cgi -> value;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
size_t HttpdForm::getlength(const std::string& n) const
|
||||
{
|
||||
CGI *cgi = NULL;
|
||||
size_t l;
|
||||
|
||||
for (cgi_v::const_iterator it = m_cgi.begin(); it != m_cgi.end(); ++it)
|
||||
{
|
||||
cgi = *it;
|
||||
if (cgi -> name == n)
|
||||
break;
|
||||
cgi = NULL;
|
||||
}
|
||||
l = cgi ? cgi -> value.size() : 0;
|
||||
if (cgi && !raw)
|
||||
{
|
||||
for (size_t i = 0; i < cgi -> value.size(); i++)
|
||||
{
|
||||
switch (cgi -> value[i])
|
||||
{
|
||||
case '<': // <
|
||||
case '>': // >
|
||||
l += 4;
|
||||
break;
|
||||
case '&': // &
|
||||
l += 5;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
|
||||
HttpdForm::cgi_v& HttpdForm::getbase()
|
||||
{
|
||||
return m_cgi;
|
||||
}
|
||||
|
||||
|
||||
const std::string& HttpdForm::GetBoundary() const
|
||||
{
|
||||
return m_strBoundary;
|
||||
}
|
||||
|
||||
|
||||
void HttpdForm::SetFileUpload(IFileUpload& cb)
|
||||
{
|
||||
m_file_upload = &cb;
|
||||
}
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,147 +0,0 @@
|
||||
/** \file HttpdForm.h - read stdin, parse cgi input
|
||||
**
|
||||
** Written: 1999-Feb-10 grymse@alhem.net
|
||||
**/
|
||||
|
||||
/*
|
||||
Copyright (C) 1999-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef _SOCKETS_HttpdForm_H
|
||||
#define _SOCKETS_HttpdForm_H
|
||||
|
||||
#include "sockets-config.h"
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
|
||||
class IFile;
|
||||
class IFileUpload;
|
||||
class IStream;
|
||||
|
||||
/** Parse/store a http query_string/form-data body.
|
||||
\ingroup webserver */
|
||||
class HttpdForm
|
||||
{
|
||||
/**
|
||||
* Store the name/value pairs from a GET/POST operation.
|
||||
* "name" does not have to be unique.
|
||||
\ingroup webserver
|
||||
*/
|
||||
struct CGI {
|
||||
CGI(const std::string& n,const std::string& v) : name(n),value(v) {}
|
||||
CGI(const std::string& n,const std::string& v,const std::string& p) : name(n),value(v),path(p) {}
|
||||
std::string name;
|
||||
std::string value;
|
||||
std::string path;
|
||||
};
|
||||
/** list of key/value pairs. */
|
||||
typedef std::list<CGI *> cgi_v;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Default constructor
|
||||
*/
|
||||
HttpdForm(FILE *);
|
||||
/**
|
||||
* Constructor (used in POST operations).
|
||||
* Input is read from stdin. Number of characters to read
|
||||
* can be found in the environment variable CONTENT_LENGTH.
|
||||
*/
|
||||
HttpdForm(IFile *, const std::string& content_type, size_t content_length);
|
||||
/**
|
||||
* Another constructor (used in GET operations).
|
||||
* Input is read from the environment variable QUERY_STRING.
|
||||
* @param query_string The httpd server provided QUERY_STRING
|
||||
* @param length Query string length.
|
||||
*/
|
||||
HttpdForm(const std::string& query_string,size_t length);
|
||||
~HttpdForm();
|
||||
|
||||
void ParseFormData(IFile *, const std::string&, size_t);
|
||||
void ParseQueryString(const std::string& query_string, size_t length);
|
||||
|
||||
void EnableRaw(bool);
|
||||
|
||||
/** Encode characters '<' '>' '&' as < > & */
|
||||
void strcpyval(std::string&,const char *) const;
|
||||
|
||||
/* get names */
|
||||
bool getfirst(std::string& n) const;
|
||||
bool getnext(std::string& n) const;
|
||||
|
||||
/* get names and values */
|
||||
bool getfirst(std::string& n,std::string& v) const;
|
||||
bool getnext(std::string& n,std::string& v) const;
|
||||
|
||||
/* get value */
|
||||
int getvalue(const std::string& ,std::string& ) const;
|
||||
std::string getvalue(const std::string& ) const;
|
||||
size_t getlength(const std::string& ) const;
|
||||
cgi_v& getbase();
|
||||
|
||||
const std::string& GetBoundary() const;
|
||||
|
||||
/** Enable IFileUpload callback */
|
||||
void SetFileUpload(IFileUpload& cb);
|
||||
|
||||
bool ContentAvailable() const {
|
||||
return !m_content.empty();
|
||||
}
|
||||
const std::vector<char>& GetContent() const {
|
||||
return m_content;
|
||||
}
|
||||
|
||||
private:
|
||||
HttpdForm(const HttpdForm& ) {}
|
||||
HttpdForm& operator=(const HttpdForm& ) {
|
||||
return *this;
|
||||
}
|
||||
cgi_v m_cgi;
|
||||
mutable cgi_v::const_iterator m_current;
|
||||
std::string m_strBoundary;
|
||||
bool raw;
|
||||
IFileUpload *m_file_upload;
|
||||
IStream *m_upload_stream;
|
||||
std::vector<char> m_content;
|
||||
};
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _SOCKETS_HttpdForm_H
|
||||
|
||||
@@ -1,326 +0,0 @@
|
||||
/** \file HttpdSocket.cpp
|
||||
*/
|
||||
/*
|
||||
Copyright (C) 2001-2010 Anders Hedstrom (grymse@alhem.net)
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4786)
|
||||
#endif
|
||||
#include "HttpdCookies.h"
|
||||
#include "HttpdForm.h"
|
||||
#include "MemFile.h"
|
||||
#include "HttpdSocket.h"
|
||||
#include "Base64.h"
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
#define TMPSIZE 10000
|
||||
|
||||
|
||||
// statics
|
||||
int HttpdSocket::m_request_count = 0;
|
||||
std::string HttpdSocket::m_start = "";
|
||||
|
||||
|
||||
HttpdSocket::HttpdSocket(ISocketHandler& h)
|
||||
:HTTPSocket(h)
|
||||
,m_content_length(0)
|
||||
,m_file(NULL)
|
||||
,m_received(0)
|
||||
,m_request_id(++m_request_count)
|
||||
,m_cookies(NULL)
|
||||
,m_form(NULL)
|
||||
{
|
||||
m_http_date = datetime2httpdate(GetDate());
|
||||
if (!m_start.size())
|
||||
m_start = m_http_date;
|
||||
}
|
||||
|
||||
|
||||
HttpdSocket::~HttpdSocket()
|
||||
{
|
||||
if (m_file)
|
||||
{
|
||||
delete m_file;
|
||||
}
|
||||
if (m_cookies)
|
||||
delete m_cookies;
|
||||
if (m_form)
|
||||
delete m_form;
|
||||
}
|
||||
|
||||
|
||||
void HttpdSocket::OnFirst()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void HttpdSocket::OnHeader(const std::string& key,const std::string& value)
|
||||
{
|
||||
if (!strcasecmp(key.c_str(),"content-length"))
|
||||
{
|
||||
m_content_length = atoi(value.c_str());
|
||||
m_content_length_str = value;
|
||||
}
|
||||
else
|
||||
if (!strcasecmp(key.c_str(),"cookie"))
|
||||
{
|
||||
m_http_cookie = value;
|
||||
}
|
||||
else
|
||||
if (!strcasecmp(key.c_str(),"content-type"))
|
||||
{
|
||||
m_content_type = value;
|
||||
}
|
||||
else
|
||||
if (!strcasecmp(key.c_str(),"if-modified-since"))
|
||||
{
|
||||
m_if_modified_since = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void HttpdSocket::OnHeaderComplete()
|
||||
{
|
||||
m_cookies = new HttpdCookies(m_http_cookie);
|
||||
|
||||
if (GetMethod() == "GET")
|
||||
{
|
||||
Utility::SetEnv("QUERY_STRING", GetQueryString());
|
||||
}
|
||||
Utility::SetEnv("REQUEST_METHOD", GetMethod());
|
||||
Utility::SetEnv("HTTP_COOKIE", m_http_cookie);
|
||||
Utility::SetEnv("CONTENT_TYPE", m_content_type);
|
||||
Utility::SetEnv("CONTENT_LENGTH", m_content_length_str);
|
||||
if (GetMethod() == "POST")
|
||||
{
|
||||
m_file = new MemFile;
|
||||
}
|
||||
else
|
||||
if (GetMethod() == "GET")
|
||||
{
|
||||
m_form = new HttpdForm(GetQueryString(), GetQueryString().size() );
|
||||
AddResponseHeader("Date", datetime2httpdate(GetDate()) );
|
||||
if (GetUri() == "/image")
|
||||
{
|
||||
Send64(Utility::Logo, "image/png");
|
||||
}
|
||||
else
|
||||
{
|
||||
Exec();
|
||||
}
|
||||
Reset(); // prepare for next request
|
||||
}
|
||||
else
|
||||
{
|
||||
AddResponseHeader("Date", GetHttpDate());
|
||||
AddResponseHeader("Connection", "close");
|
||||
SetStatus("405");
|
||||
SetStatusText("Method not allowed");
|
||||
SendResponse();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void HttpdSocket::OnData(const char *p,size_t l)
|
||||
{
|
||||
if (m_file)
|
||||
{
|
||||
m_file -> fwrite(p,1,l);
|
||||
}
|
||||
m_received += l;
|
||||
if (m_received >= m_content_length && m_content_length)
|
||||
{
|
||||
// all done
|
||||
if (m_file && !m_form)
|
||||
{
|
||||
m_form = new HttpdForm(m_file, m_content_type, m_content_length);
|
||||
AddResponseHeader("Date", datetime2httpdate(GetDate()) );
|
||||
if (GetUri() == "/image")
|
||||
{
|
||||
Send64(Utility::Logo, "image/png");
|
||||
}
|
||||
else
|
||||
{
|
||||
Exec();
|
||||
}
|
||||
Reset(); // prepare for next request
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void HttpdSocket::Send64(const std::string& str64, const std::string& type)
|
||||
{
|
||||
Base64 bb;
|
||||
|
||||
if (!strcasecmp(m_start.c_str(), m_if_modified_since.c_str()))
|
||||
{
|
||||
SetStatus("304");
|
||||
SetStatusText("Not Modified");
|
||||
SendResponse();
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t len = bb.decode_length(str64);
|
||||
unsigned char *buf = new unsigned char[len];
|
||||
|
||||
SetStatus("200");
|
||||
SetStatusText("OK");
|
||||
|
||||
AddResponseHeader("Content-length", Utility::l2string( (long)len) );
|
||||
AddResponseHeader("Content-type", type );
|
||||
AddResponseHeader("Last-modified", m_start);
|
||||
SendResponse();
|
||||
|
||||
bb.decode(str64, buf, len);
|
||||
SendBuf( (char *)buf, len);
|
||||
delete[] buf;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::string HttpdSocket::datetime2httpdate(const std::string& dt)
|
||||
{
|
||||
struct tm tp;
|
||||
time_t t;
|
||||
const char *days[] = { "Sun","Mon","Tue","Wed","Thu","Fri","Sat" };
|
||||
const char *months[] = { "Jan","Feb","Mar","Apr","May","Jun",
|
||||
"Jul","Aug","Sep","Oct","Nov","Dec" };
|
||||
int i;
|
||||
char s[40];
|
||||
|
||||
/* 1997-12-16 09:50:40 */
|
||||
|
||||
if (dt.size() == 19)
|
||||
{
|
||||
tp.tm_year = atoi(dt.substr(0,4).c_str()) - 1900;
|
||||
i = atoi(dt.substr(5,2).c_str()) - 1;
|
||||
tp.tm_mon = i >= 0 ? i : 0;
|
||||
tp.tm_mday = atoi(dt.substr(8,2).c_str());
|
||||
tp.tm_hour = atoi(dt.substr(11,2).c_str());
|
||||
tp.tm_min = atoi(dt.substr(14,2).c_str());
|
||||
tp.tm_sec = atoi(dt.substr(17,2).c_str());
|
||||
tp.tm_wday = 0;
|
||||
tp.tm_yday = 0;
|
||||
tp.tm_isdst = 0;
|
||||
t = mktime(&tp);
|
||||
if (t == -1)
|
||||
{
|
||||
Handler().LogError(this, "datetime2httpdate", 0, "mktime() failed");
|
||||
}
|
||||
|
||||
snprintf(s,sizeof(s),"%s, %02d %s %d %02d:%02d:%02d GMT",
|
||||
days[tp.tm_wday],
|
||||
tp.tm_mday,
|
||||
months[tp.tm_mon],
|
||||
tp.tm_year + 1900,
|
||||
tp.tm_hour,tp.tm_min,tp.tm_sec);
|
||||
}
|
||||
else
|
||||
{
|
||||
*s = 0;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
std::string HttpdSocket::GetDate()
|
||||
{
|
||||
time_t t = time(NULL);
|
||||
char slask[40]; // yyyy-mm-dd hh:mm:ss
|
||||
#ifdef __CYGWIN__
|
||||
struct tm *tp = localtime(&t);
|
||||
snprintf(slask,sizeof(slask),"%d-%02d-%02d %02d:%02d:%02d",
|
||||
tp -> tm_year + 1900,
|
||||
tp -> tm_mon + 1,
|
||||
tp -> tm_mday,
|
||||
tp -> tm_hour,tp -> tm_min,tp -> tm_sec);
|
||||
#else
|
||||
struct tm tp;
|
||||
#if defined( _WIN32) && !defined(__CYGWIN__)
|
||||
localtime_s(&tp, &t);
|
||||
#else
|
||||
localtime_r(&t, &tp);
|
||||
#endif
|
||||
snprintf(slask,sizeof(slask),"%d-%02d-%02d %02d:%02d:%02d",
|
||||
tp.tm_year + 1900,
|
||||
tp.tm_mon + 1,
|
||||
tp.tm_mday,
|
||||
tp.tm_hour,tp.tm_min,tp.tm_sec);
|
||||
#endif
|
||||
return slask;
|
||||
}
|
||||
|
||||
|
||||
void HttpdSocket::Reset()
|
||||
{
|
||||
HTTPSocket::Reset();
|
||||
m_content_length = 0;
|
||||
if (m_file)
|
||||
{
|
||||
delete m_file;
|
||||
m_file = NULL;
|
||||
}
|
||||
m_received = 0;
|
||||
m_request_id = ++m_request_count;
|
||||
if (m_cookies)
|
||||
delete m_cookies;
|
||||
m_cookies = NULL;
|
||||
if (m_form)
|
||||
delete m_form;
|
||||
m_form = NULL;
|
||||
}
|
||||
|
||||
|
||||
const std::string& HttpdSocket::GetHttpDate() const
|
||||
{
|
||||
return m_http_date;
|
||||
}
|
||||
|
||||
|
||||
HttpdCookies *HttpdSocket::GetCookies()
|
||||
{
|
||||
return m_cookies;
|
||||
}
|
||||
|
||||
|
||||
const HttpdForm *HttpdSocket::GetForm() const
|
||||
{
|
||||
return m_form;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,117 +0,0 @@
|
||||
/** \file HttpdSocket.h
|
||||
*/
|
||||
/*
|
||||
Copyright (C) 2001-2010 Anders Hedstrom (grymse@alhem.net)
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef _SOCKETS_HttpdSocket_H
|
||||
#define _SOCKETS_HttpdSocket_H
|
||||
|
||||
#include "sockets-config.h"
|
||||
#include "HTTPSocket.h"
|
||||
#include "ISocketHandler.h"
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
|
||||
class HttpdCookies;
|
||||
class HttpdForm;
|
||||
class IFile;
|
||||
|
||||
/** \defgroup webserver Webserver framework */
|
||||
/** Web server socket framework.
|
||||
\ingroup webserver */
|
||||
class HttpdSocket : public HTTPSocket
|
||||
{
|
||||
public:
|
||||
HttpdSocket(ISocketHandler& );
|
||||
~HttpdSocket();
|
||||
|
||||
void OnFirst();
|
||||
void OnHeader(const std::string& key,const std::string& value);
|
||||
void OnHeaderComplete();
|
||||
void OnData(const char *,size_t);
|
||||
|
||||
/** This method needs to be implemented with logic to produce
|
||||
a response to an incoming request. */
|
||||
virtual void Exec() = 0;
|
||||
/** Get current date in http rfc format. */
|
||||
const std::string& GetHttpDate() const;
|
||||
/** Get pointer to cookie class. */
|
||||
HttpdCookies *GetCookies();
|
||||
/** Get pointer to query string/form data class. */
|
||||
const HttpdForm *GetForm() const;
|
||||
|
||||
size_t ContentLength() const {
|
||||
return m_content_length;
|
||||
}
|
||||
const IFile *Body() const {
|
||||
return m_file;
|
||||
}
|
||||
int RequestId() const {
|
||||
return m_request_id;
|
||||
}
|
||||
|
||||
protected:
|
||||
HttpdSocket(const HttpdSocket& s) : HTTPSocket(s) {}
|
||||
/** Decode and send a base64-encoded string.
|
||||
\param str64 Base64-encoded string
|
||||
\param type Mime type of content (content-type header) */
|
||||
void Send64(const std::string& str64, const std::string& type);
|
||||
std::string datetime2httpdate(const std::string& dt);
|
||||
std::string GetDate();
|
||||
void Reset();
|
||||
// headers
|
||||
std::string m_http_cookie;
|
||||
std::string m_content_type;
|
||||
std::string m_content_length_str;
|
||||
std::string m_if_modified_since;
|
||||
|
||||
private:
|
||||
HttpdSocket& operator=(const HttpdSocket& s) {
|
||||
return *this;
|
||||
}
|
||||
static int m_request_count;
|
||||
static std::string m_start;
|
||||
size_t m_content_length;
|
||||
IFile *m_file;
|
||||
size_t m_received;
|
||||
int m_request_id;
|
||||
std::string m_http_date;
|
||||
HttpdCookies *m_cookies;
|
||||
HttpdForm *m_form;
|
||||
};
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _SOCKETS_HttpdSocket_H
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
/**
|
||||
** \file
|
||||
** \date 2007-06-05
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2007-2010 Anders Hedstrom
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef _SOCKETS_IBase_H
|
||||
#define _SOCKETS_IBase_H
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
|
||||
class IBase
|
||||
{
|
||||
public:
|
||||
virtual ~IBase() {}
|
||||
|
||||
};
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
} // namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
#endif // _SOCKETS_IBase_H
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
/** \file IEventHandler.h
|
||||
** \date 2005-12-07
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2005-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef _SOCKETS_IEventHandler_H
|
||||
#define _SOCKETS_IEventHandler_H
|
||||
|
||||
#include "sockets-config.h"
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
|
||||
class IEventOwner;
|
||||
|
||||
/** Timer event handler pure virtual base class.
|
||||
\ingroup timer */
|
||||
class IEventHandler
|
||||
{
|
||||
public:
|
||||
virtual ~IEventHandler() {}
|
||||
|
||||
/** Return time left until next event.
|
||||
\param tv Time struct that will be filled by method
|
||||
\return true if time is set for next event */
|
||||
virtual bool GetTimeUntilNextEvent(struct timeval *) = 0;
|
||||
/** Will fire events whose time has come. */
|
||||
virtual void CheckEvents() = 0;
|
||||
/** Schedule event for an owner.
|
||||
\param from Event owner
|
||||
\param sec Seconds until event
|
||||
\param usec Microseconds until event */
|
||||
virtual long AddEvent(IEventOwner *,long sec,long usec) = 0;
|
||||
/** Clear all events for a specific owner. */
|
||||
virtual void ClearEvents(IEventOwner *) = 0;
|
||||
/** Remove one specific event for an event owner. */
|
||||
virtual void RemoveEvent(IEventOwner *,long) = 0;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _SOCKETS_IEventHandler_H
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
/** \file IEventOwner.cpp
|
||||
** \date 2005-12-07
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2005-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#include "IEventOwner.h"
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
|
||||
IEventOwner::IEventOwner(IEventHandler& h) : m_event_handler(h), m_handler_invalid(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
IEventOwner::~IEventOwner()
|
||||
{
|
||||
if (!m_handler_invalid)
|
||||
{
|
||||
m_event_handler.ClearEvents(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
IEventHandler& IEventOwner::GetEventHandler()
|
||||
{
|
||||
return m_event_handler;
|
||||
}
|
||||
|
||||
|
||||
long IEventOwner::AddEvent(long sec,long usec)
|
||||
{
|
||||
return m_event_handler.AddEvent(this, sec, usec);
|
||||
}
|
||||
|
||||
|
||||
void IEventOwner::ClearEvents()
|
||||
{
|
||||
m_event_handler.ClearEvents(this);
|
||||
}
|
||||
|
||||
|
||||
void IEventOwner::RemoveEvent(long eid)
|
||||
{
|
||||
m_event_handler.RemoveEvent(this, eid);
|
||||
}
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
/** \file IEventOwner.h
|
||||
** \date 2005-12-07
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2005-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef _SOCKETS_IEventOwner_H
|
||||
#define _SOCKETS_IEventOwner_H
|
||||
|
||||
#include "sockets-config.h"
|
||||
#include "IEventHandler.h"
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
|
||||
/** Any class that wants to use timer events inherits this.
|
||||
\ingroup timer */
|
||||
class IEventOwner
|
||||
{
|
||||
public:
|
||||
IEventOwner(IEventHandler& h);
|
||||
virtual ~IEventOwner();
|
||||
|
||||
/** Schedule event.
|
||||
\param sec Seconds until event
|
||||
\param usec Microseconds until event
|
||||
\return Event ID */
|
||||
long AddEvent(long sec,long usec);
|
||||
/** Clear all events scheduled by this owner. */
|
||||
void ClearEvents();
|
||||
/** Remove one event scheduled by this owner.
|
||||
\param eid Event ID to remove */
|
||||
void RemoveEvent(long eid);
|
||||
/** Event callback will fire when time is up. */
|
||||
virtual void OnEvent(int) = 0;
|
||||
|
||||
IEventHandler& GetEventHandler();
|
||||
void SetHandlerInvalid(bool x = true) {
|
||||
m_handler_invalid = x;
|
||||
}
|
||||
|
||||
private:
|
||||
IEventHandler& m_event_handler;
|
||||
bool m_handler_invalid;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _SOCKETS_IEventOwner_H
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
/** \file IFile.h
|
||||
** \date 2005-04-25
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2004-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef _SOCKETS_IFile_H
|
||||
#define _SOCKETS_IFile_H
|
||||
|
||||
#include "sockets-config.h"
|
||||
#include <string>
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
/** \defgroup file File handling */
|
||||
/** Pure virtual file I/O interface.
|
||||
\ingroup file */
|
||||
class IFile
|
||||
{
|
||||
public:
|
||||
virtual ~IFile() {}
|
||||
|
||||
virtual bool fopen(const std::string&, const std::string&) = 0;
|
||||
virtual void fclose() const = 0;
|
||||
|
||||
virtual size_t fread(char *, size_t, size_t) const = 0;
|
||||
virtual size_t fwrite(const char *, size_t, size_t) = 0;
|
||||
|
||||
virtual char *fgets(char *, int) const = 0;
|
||||
virtual void fprintf(const char *format, ...) = 0;
|
||||
|
||||
virtual off_t size() const = 0;
|
||||
virtual bool eof() const = 0;
|
||||
|
||||
virtual void reset_read() const = 0;
|
||||
virtual void reset_write() = 0;
|
||||
|
||||
virtual const std::string& Path() const = 0;
|
||||
};
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _SOCKETS_IFile_H
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
/** \file IFileUpload.h
|
||||
** \date 2009-04-22
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2004-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef _SOCKETS_IFileUpload_H
|
||||
#define _SOCKETS_IFileUpload_H
|
||||
|
||||
#include "sockets-config.h"
|
||||
#include <string>
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
class IStream;
|
||||
|
||||
/** Multipart form file upload callback.
|
||||
\ingroup webserver */
|
||||
class IFileUpload
|
||||
{
|
||||
public:
|
||||
virtual ~IFileUpload() {}
|
||||
|
||||
virtual IStream& IFileUploadBegin(const std::string& input_name, const std::string& filename, const std::string& content_type) = 0;
|
||||
|
||||
virtual void IFileUploadEnd() = 0;
|
||||
};
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _SOCKETS_IFileUpload_H
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
/**
|
||||
** \file IHttpServer.h
|
||||
** \date 2007-10-05
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2007-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef _SOCKETS_IHttpServer_H
|
||||
#define _SOCKETS_IHttpServer_H
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
|
||||
class HttpRequest;
|
||||
class HttpResponse;
|
||||
|
||||
class IHttpServer
|
||||
{
|
||||
public:
|
||||
virtual ~IHttpServer() {}
|
||||
|
||||
/** Complete request has been received and parsed. Send response
|
||||
using the Respond() method. */
|
||||
virtual void OnExec(const HttpRequest& req) = 0;
|
||||
|
||||
/** Send response. */
|
||||
virtual void Respond(const HttpResponse& res) = 0;
|
||||
|
||||
/** Called when the body part of the response has been sent. */
|
||||
virtual void OnResponseComplete() = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
} // namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
#endif // _SOCKETS_IHttpServer_H
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
/** \file IMutex.h
|
||||
** \date 2008-10-25
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2004-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef _SOCKETS_IMutex_H
|
||||
#define _SOCKETS_IMutex_H
|
||||
|
||||
#include "sockets-config.h"
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
/** IMutex interface.
|
||||
\ingroup threading */
|
||||
class IMutex
|
||||
{
|
||||
public:
|
||||
virtual ~IMutex() {}
|
||||
|
||||
virtual void Lock() const = 0;
|
||||
virtual void Unlock() const = 0;
|
||||
};
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
#endif // _SOCKETS_IMutex_H
|
||||
|
||||
@@ -1,262 +0,0 @@
|
||||
/** \file ISocketHandler.h
|
||||
** \date 2004-02-13
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2004-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef _SOCKETS_ISocketHandler_H
|
||||
#define _SOCKETS_ISocketHandler_H
|
||||
#include "sockets-config.h"
|
||||
|
||||
#include <list>
|
||||
#include <map>
|
||||
|
||||
#include "socket_include.h"
|
||||
#include "Socket.h"
|
||||
#include "StdLog.h"
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
class SocketAddress;
|
||||
class IMutex;
|
||||
|
||||
|
||||
/** Socket container class, event generator.
|
||||
\ingroup basic */
|
||||
class ISocketHandler
|
||||
{
|
||||
friend class Socket;
|
||||
|
||||
public:
|
||||
/** Connection pool class for internal use by the ISocketHandler.
|
||||
\ingroup internal */
|
||||
#ifdef ENABLE_POOL
|
||||
class PoolSocket : public Socket
|
||||
{
|
||||
public:
|
||||
PoolSocket(ISocketHandler& h,Socket *src) : Socket(h) {
|
||||
CopyConnection( src );
|
||||
SetIsClient();
|
||||
}
|
||||
|
||||
void OnRead() {
|
||||
Handler().LogError(this, "OnRead", 0, "data on hibernating socket", LOG_LEVEL_FATAL);
|
||||
SetCloseAndDelete();
|
||||
}
|
||||
void OnOptions(int,int,int,SOCKET) {}
|
||||
|
||||
};
|
||||
#endif
|
||||
|
||||
public:
|
||||
virtual ~ISocketHandler() {}
|
||||
|
||||
/** Return another instance */
|
||||
virtual ISocketHandler *Create(StdLog * = NULL) = 0;
|
||||
|
||||
/** Return another instance */
|
||||
virtual ISocketHandler *Create(IMutex&, ISocketHandler&, StdLog * = NULL) = 0;
|
||||
|
||||
/** Handler created with parent */
|
||||
virtual bool ParentHandlerIsValid() = 0;
|
||||
|
||||
/** Get parent sockethandler */
|
||||
virtual ISocketHandler& ParentHandler() = 0;
|
||||
|
||||
/** Get thread handler with least connections */
|
||||
virtual ISocketHandler& GetRandomHandler() = 0;
|
||||
|
||||
/** Return parent handler if valid, otherwise return normal handler */
|
||||
virtual ISocketHandler& GetEffectiveHandler() = 0;
|
||||
|
||||
/** Enable threading */
|
||||
virtual void SetNumberOfThreads(size_t n) = 0;
|
||||
|
||||
/** Threading is enabled */
|
||||
virtual bool IsThreaded() = 0;
|
||||
|
||||
/** Enable select release */
|
||||
virtual void EnableRelease() = 0;
|
||||
|
||||
/** Make select release */
|
||||
virtual void Release() = 0;
|
||||
|
||||
/** Get mutex reference for threadsafe operations. */
|
||||
virtual IMutex& GetMutex() const = 0;
|
||||
|
||||
/** Register StdLog object for error callback.
|
||||
\param log Pointer to log class */
|
||||
virtual void RegStdLog(StdLog *log) = 0;
|
||||
|
||||
/** Log error to log class for print out / storage. */
|
||||
virtual void LogError(Socket *p,const std::string& user_text,int err,const std::string& sys_err,loglevel_t t = LOG_LEVEL_WARNING) = 0;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Socket stuff
|
||||
// -------------------------------------------------------------------------
|
||||
/** Add socket instance to socket map. Removal is always automatic. */
|
||||
virtual void Add(Socket *) = 0;
|
||||
|
||||
protected:
|
||||
/** Remove socket from socket map, used by Socket class. */
|
||||
virtual void Remove(Socket *) = 0;
|
||||
|
||||
/** Actual call to select() */
|
||||
virtual int ISocketHandler_Select(struct timeval *) = 0;
|
||||
|
||||
public:
|
||||
/** Set read/write/exception file descriptor sets (fd_set). */
|
||||
virtual void ISocketHandler_Add(Socket *,bool bRead,bool bWrite) = 0;
|
||||
virtual void ISocketHandler_Mod(Socket *,bool bRead,bool bWrite) = 0;
|
||||
virtual void ISocketHandler_Del(Socket *) = 0;
|
||||
|
||||
/** Wait for events, generate callbacks. */
|
||||
virtual int Select(long sec,long usec) = 0;
|
||||
/** This method will not return until an event has been detected. */
|
||||
virtual int Select() = 0;
|
||||
/** Wait for events, generate callbacks. */
|
||||
virtual int Select(struct timeval *tsel) = 0;
|
||||
|
||||
/** Check that a socket really is handled by this socket handler. */
|
||||
virtual bool Valid(Socket *) = 0;
|
||||
/** Preferred method - Check that a socket still is handled by this socket handler. */
|
||||
virtual bool Valid(socketuid_t) = 0;
|
||||
|
||||
/** Return number of sockets handled by this handler. */
|
||||
virtual size_t GetCount() = 0;
|
||||
|
||||
/** Return maximum number of sockets allowed. */
|
||||
virtual size_t MaxCount() = 0;
|
||||
|
||||
/** Override and return false to deny all incoming connections.
|
||||
\param p ListenSocket class pointer (use GetPort to identify which one) */
|
||||
virtual bool OkToAccept(Socket *p) = 0;
|
||||
|
||||
/** Use with care, always lock with h.GetMutex() if multithreaded */
|
||||
virtual const std::map<SOCKET, Socket *>& AllSockets() = 0;
|
||||
|
||||
/** Override to accept longer lines than TCP_LINE_SIZE */
|
||||
virtual size_t MaxTcpLineSize() = 0;
|
||||
|
||||
virtual void SetCallOnConnect(bool = true) = 0;
|
||||
virtual void SetDetach(bool = true) = 0;
|
||||
virtual void SetTimeout(bool = true) = 0;
|
||||
virtual void SetRetry(bool = true) = 0;
|
||||
virtual void SetClose(bool = true) = 0;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Connection pool
|
||||
// -------------------------------------------------------------------------
|
||||
#ifdef ENABLE_POOL
|
||||
/** Find available open connection (used by connection pool). */
|
||||
virtual ISocketHandler::PoolSocket *FindConnection(int type,const std::string& protocol,SocketAddress&) = 0;
|
||||
/** Enable connection pool (by default disabled). */
|
||||
virtual void EnablePool(bool = true) = 0;
|
||||
/** Check pool status.
|
||||
\return true if connection pool is enabled */
|
||||
virtual bool PoolEnabled() = 0;
|
||||
#endif // ENABLE_POOL
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Socks4
|
||||
// -------------------------------------------------------------------------
|
||||
#ifdef ENABLE_SOCKS4
|
||||
/** Set socks4 server ip that all new tcp sockets should use. */
|
||||
virtual void SetSocks4Host(ipaddr_t) = 0;
|
||||
/** Set socks4 server hostname that all new tcp sockets should use. */
|
||||
virtual void SetSocks4Host(const std::string& ) = 0;
|
||||
/** Set socks4 server port number that all new tcp sockets should use. */
|
||||
virtual void SetSocks4Port(port_t) = 0;
|
||||
/** Set optional socks4 userid. */
|
||||
virtual void SetSocks4Userid(const std::string& ) = 0;
|
||||
/** If connection to socks4 server fails, immediately try direct connection to final host. */
|
||||
virtual void SetSocks4TryDirect(bool = true) = 0;
|
||||
/** Get socks4 server ip.
|
||||
\return socks4 server ip */
|
||||
virtual ipaddr_t GetSocks4Host() = 0;
|
||||
/** Get socks4 port number.
|
||||
\return socks4 port number */
|
||||
virtual port_t GetSocks4Port() = 0;
|
||||
/** Get socks4 userid (optional).
|
||||
\return socks4 userid */
|
||||
virtual const std::string& GetSocks4Userid() = 0;
|
||||
/** Check status of socks4 try direct flag.
|
||||
\return true if direct connection should be tried if connection to socks4 server fails */
|
||||
virtual bool Socks4TryDirect() = 0;
|
||||
#endif // ENABLE_SOCKS4
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// DNS resolve server
|
||||
// -------------------------------------------------------------------------
|
||||
#ifdef ENABLE_RESOLVER
|
||||
/** Enable asynchronous DNS.
|
||||
\param port Listen port of asynchronous dns server */
|
||||
virtual void EnableResolver(port_t = 16667) = 0;
|
||||
/** Check resolver status.
|
||||
\return true if resolver is enabled */
|
||||
virtual bool ResolverEnabled() = 0;
|
||||
/** Queue a dns request.
|
||||
\param host Hostname to be resolved
|
||||
\param port Port number will be echoed in Socket::OnResolved callback */
|
||||
virtual int Resolve(Socket *,const std::string& host,port_t port) = 0;
|
||||
#ifdef ENABLE_IPV6
|
||||
virtual int Resolve6(Socket *,const std::string& host,port_t port) = 0;
|
||||
#endif
|
||||
/** Do a reverse dns lookup. */
|
||||
virtual int Resolve(Socket *,ipaddr_t a) = 0;
|
||||
#ifdef ENABLE_IPV6
|
||||
virtual int Resolve(Socket *,in6_addr& a) = 0;
|
||||
#endif
|
||||
/** Get listen port of asynchronous dns server. */
|
||||
virtual port_t GetResolverPort() = 0;
|
||||
/** Resolver thread ready for queries. */
|
||||
virtual bool ResolverReady() = 0;
|
||||
/** Returns true if socket waiting for a resolve event. */
|
||||
virtual bool Resolving(Socket *) = 0;
|
||||
#endif // ENABLE_RESOLVER
|
||||
|
||||
#ifdef ENABLE_DETACH
|
||||
/** Indicates that the handler runs under SocketThread. */
|
||||
virtual void SetSlave(bool x = true) = 0;
|
||||
/** Indicates that the handler runs under SocketThread. */
|
||||
virtual bool IsSlave() = 0;
|
||||
#endif // ENABLE_DETACH
|
||||
|
||||
};
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _SOCKETS_ISocketHandler_H
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
/** \file IStream.h
|
||||
** \date 2008-11-15
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2008-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef _SOCKETS_IStream_H
|
||||
#define _SOCKETS_IStream_H
|
||||
|
||||
#include "sockets-config.h"
|
||||
#include <string>
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
class IStream
|
||||
{
|
||||
public:
|
||||
virtual ~IStream() {}
|
||||
|
||||
/** Try to read 'buf_sz' number of bytes from source.
|
||||
\return Number of bytes actually read. */
|
||||
virtual size_t IStreamRead(char *buf, size_t buf_sz) = 0;
|
||||
|
||||
/** Write 'sz' bytes to destination. */
|
||||
virtual void IStreamWrite(const char *buf, size_t sz) = 0;
|
||||
|
||||
};
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _SOCKETS_IStream_H
|
||||
@@ -1,223 +0,0 @@
|
||||
/**
|
||||
** \file Ipv4Address.cpp
|
||||
** \date 2006-09-21
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2007-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#include "Ipv4Address.h"
|
||||
#include "Utility.h"
|
||||
#ifndef _WIN32
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
Ipv4Address::Ipv4Address(port_t port) : m_valid(true)
|
||||
{
|
||||
memset(&m_addr, 0, sizeof(m_addr));
|
||||
m_addr.sin_family = AF_INET;
|
||||
m_addr.sin_port = htons( port );
|
||||
}
|
||||
|
||||
|
||||
Ipv4Address::Ipv4Address(ipaddr_t a,port_t port) : m_valid(true)
|
||||
{
|
||||
memset(&m_addr, 0, sizeof(m_addr));
|
||||
m_addr.sin_family = AF_INET;
|
||||
m_addr.sin_port = htons( port );
|
||||
memcpy(&m_addr.sin_addr, &a, sizeof(struct in_addr));
|
||||
}
|
||||
|
||||
|
||||
Ipv4Address::Ipv4Address(struct in_addr& a,port_t port) : m_valid(true)
|
||||
{
|
||||
memset(&m_addr, 0, sizeof(m_addr));
|
||||
m_addr.sin_family = AF_INET;
|
||||
m_addr.sin_port = htons( port );
|
||||
m_addr.sin_addr = a;
|
||||
}
|
||||
|
||||
|
||||
Ipv4Address::Ipv4Address(const std::string& host,port_t port) : m_valid(false)
|
||||
{
|
||||
memset(&m_addr, 0, sizeof(m_addr));
|
||||
m_addr.sin_family = AF_INET;
|
||||
m_addr.sin_port = htons( port );
|
||||
{
|
||||
ipaddr_t a;
|
||||
if (Utility::u2ip(host, a))
|
||||
{
|
||||
memcpy(&m_addr.sin_addr, &a, sizeof(struct in_addr));
|
||||
m_valid = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Ipv4Address::Ipv4Address(struct sockaddr_in& sa)
|
||||
{
|
||||
m_addr = sa;
|
||||
m_valid = sa.sin_family == AF_INET;
|
||||
}
|
||||
|
||||
|
||||
Ipv4Address::~Ipv4Address()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Ipv4Address::operator struct sockaddr *()
|
||||
{
|
||||
return (struct sockaddr *)&m_addr;
|
||||
}
|
||||
|
||||
|
||||
Ipv4Address::operator socklen_t()
|
||||
{
|
||||
return sizeof(struct sockaddr_in);
|
||||
}
|
||||
|
||||
|
||||
void Ipv4Address::SetPort(port_t port)
|
||||
{
|
||||
m_addr.sin_port = htons( port );
|
||||
}
|
||||
|
||||
|
||||
port_t Ipv4Address::GetPort()
|
||||
{
|
||||
return ntohs( m_addr.sin_port );
|
||||
}
|
||||
|
||||
|
||||
bool Ipv4Address::Resolve(const std::string& hostname,struct in_addr& a)
|
||||
{
|
||||
struct sockaddr_in sa;
|
||||
memset(&a, 0, sizeof(a));
|
||||
if (Utility::isipv4(hostname))
|
||||
{
|
||||
if (!Utility::u2ip(hostname, sa, AI_NUMERICHOST))
|
||||
return false;
|
||||
a = sa.sin_addr;
|
||||
return true;
|
||||
}
|
||||
if (!Utility::u2ip(hostname, sa))
|
||||
return false;
|
||||
a = sa.sin_addr;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Ipv4Address::Reverse(struct in_addr& a,std::string& name)
|
||||
{
|
||||
struct sockaddr_in sa;
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sa.sin_family = AF_INET;
|
||||
sa.sin_addr = a;
|
||||
return Utility::reverse((struct sockaddr *)&sa, sizeof(sa), name);
|
||||
}
|
||||
|
||||
|
||||
std::string Ipv4Address::Convert(bool include_port)
|
||||
{
|
||||
if (include_port)
|
||||
return Convert(m_addr.sin_addr) + ":" + Utility::l2string(GetPort());
|
||||
return Convert(m_addr.sin_addr);
|
||||
}
|
||||
|
||||
|
||||
std::string Ipv4Address::Convert(struct in_addr& a)
|
||||
{
|
||||
struct sockaddr_in sa;
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sa.sin_family = AF_INET;
|
||||
sa.sin_addr = a;
|
||||
std::string name;
|
||||
Utility::reverse((struct sockaddr *)&sa, sizeof(sa), name, NI_NUMERICHOST);
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
void Ipv4Address::SetAddress(struct sockaddr *sa)
|
||||
{
|
||||
memcpy(&m_addr, sa, sizeof(struct sockaddr_in));
|
||||
}
|
||||
|
||||
|
||||
int Ipv4Address::GetFamily()
|
||||
{
|
||||
return m_addr.sin_family;
|
||||
}
|
||||
|
||||
|
||||
bool Ipv4Address::IsValid()
|
||||
{
|
||||
return m_valid;
|
||||
}
|
||||
|
||||
|
||||
bool Ipv4Address::operator==(SocketAddress& a)
|
||||
{
|
||||
if (a.GetFamily() != GetFamily())
|
||||
return false;
|
||||
if ((socklen_t)a != sizeof(m_addr))
|
||||
return false;
|
||||
struct sockaddr *sa = a;
|
||||
struct sockaddr_in *p = (struct sockaddr_in *)sa;
|
||||
if (p -> sin_port != m_addr.sin_port)
|
||||
return false;
|
||||
if (memcmp(&p -> sin_addr, &m_addr.sin_addr, 4))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
std::auto_ptr<SocketAddress> Ipv4Address::GetCopy()
|
||||
{
|
||||
return std::auto_ptr<SocketAddress>(new Ipv4Address(m_addr));
|
||||
}
|
||||
|
||||
|
||||
std::string Ipv4Address::Reverse()
|
||||
{
|
||||
std::string tmp;
|
||||
Reverse(m_addr.sin_addr, tmp);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
} // namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
@@ -1,111 +0,0 @@
|
||||
/**
|
||||
** \file Ipv4Address.h
|
||||
** \date 2006-09-21
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2007-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef _SOCKETS_Ipv4Address_H
|
||||
#define _SOCKETS_Ipv4Address_H
|
||||
|
||||
#include "sockets-config.h"
|
||||
#include "SocketAddress.h"
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
|
||||
/* Ipv4 address implementation.
|
||||
\ingroup basic */
|
||||
class Ipv4Address : public SocketAddress
|
||||
{
|
||||
public:
|
||||
/** Create empty Ipv4 address structure.
|
||||
\param port Port number */
|
||||
Ipv4Address(port_t port = 0);
|
||||
/** Create Ipv4 address structure.
|
||||
\param a Socket address in network byte order (as returned by Utility::u2ip)
|
||||
\param port Port number in host byte order */
|
||||
Ipv4Address(ipaddr_t a,port_t port);
|
||||
/** Create Ipv4 address structure.
|
||||
\param a Socket address in network byte order
|
||||
\param port Port number in host byte order */
|
||||
Ipv4Address(struct in_addr& a,port_t port);
|
||||
/** Create Ipv4 address structure.
|
||||
\param host Hostname to be resolved
|
||||
\param port Port number in host byte order */
|
||||
Ipv4Address(const std::string& host,port_t port);
|
||||
Ipv4Address(struct sockaddr_in&);
|
||||
~Ipv4Address();
|
||||
|
||||
// SocketAddress implementation
|
||||
|
||||
operator struct sockaddr *();
|
||||
operator socklen_t();
|
||||
bool operator==(SocketAddress&);
|
||||
|
||||
void SetPort(port_t port);
|
||||
port_t GetPort();
|
||||
|
||||
void SetAddress(struct sockaddr *sa);
|
||||
int GetFamily();
|
||||
|
||||
bool IsValid();
|
||||
std::auto_ptr<SocketAddress> GetCopy();
|
||||
|
||||
/** Convert address struct to text. */
|
||||
std::string Convert(bool include_port = false);
|
||||
std::string Reverse();
|
||||
|
||||
/** Resolve hostname. */
|
||||
static bool Resolve(const std::string& hostname,struct in_addr& a);
|
||||
/** Reverse resolve (IP to hostname). */
|
||||
static bool Reverse(struct in_addr& a,std::string& name);
|
||||
/** Convert address struct to text. */
|
||||
static std::string Convert(struct in_addr& a);
|
||||
|
||||
private:
|
||||
Ipv4Address(const Ipv4Address& ) {} // copy constructor
|
||||
Ipv4Address& operator=(const Ipv4Address& ) {
|
||||
return *this; // assignment operator
|
||||
}
|
||||
struct sockaddr_in m_addr;
|
||||
bool m_valid;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
} // namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
#endif // _SOCKETS_Ipv4Address_H
|
||||
|
||||
@@ -1,286 +0,0 @@
|
||||
/**
|
||||
** \file Ipv6Address.cpp
|
||||
** \date 2006-09-21
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2007-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include "Ipv6Address.h"
|
||||
#ifdef ENABLE_IPV6
|
||||
|
||||
#include "Utility.h"
|
||||
#ifndef _WIN32
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
#ifdef IPPROTO_IPV6
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
|
||||
Ipv6Address::Ipv6Address(port_t port) : m_valid(true)
|
||||
{
|
||||
memset(&m_addr, 0, sizeof(m_addr));
|
||||
m_addr.sin6_family = AF_INET6;
|
||||
m_addr.sin6_port = htons( port );
|
||||
}
|
||||
|
||||
|
||||
Ipv6Address::Ipv6Address(struct in6_addr& a,port_t port) : m_valid(true)
|
||||
{
|
||||
memset(&m_addr, 0, sizeof(m_addr));
|
||||
m_addr.sin6_family = AF_INET6;
|
||||
m_addr.sin6_port = htons( port );
|
||||
m_addr.sin6_addr = a;
|
||||
}
|
||||
|
||||
|
||||
Ipv6Address::Ipv6Address(const std::string& host,port_t port) : m_valid(false)
|
||||
{
|
||||
memset(&m_addr, 0, sizeof(m_addr));
|
||||
m_addr.sin6_family = AF_INET6;
|
||||
m_addr.sin6_port = htons( port );
|
||||
{
|
||||
struct in6_addr a;
|
||||
if (Utility::u2ip(host, a))
|
||||
{
|
||||
m_addr.sin6_addr = a;
|
||||
m_valid = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Ipv6Address::Ipv6Address(struct sockaddr_in6& sa)
|
||||
{
|
||||
m_addr = sa;
|
||||
m_valid = sa.sin6_family == AF_INET6;
|
||||
}
|
||||
|
||||
|
||||
Ipv6Address::~Ipv6Address()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Ipv6Address::operator struct sockaddr *()
|
||||
{
|
||||
return (struct sockaddr *)&m_addr;
|
||||
}
|
||||
|
||||
|
||||
Ipv6Address::operator socklen_t()
|
||||
{
|
||||
return sizeof(struct sockaddr_in6);
|
||||
}
|
||||
|
||||
|
||||
void Ipv6Address::SetPort(port_t port)
|
||||
{
|
||||
m_addr.sin6_port = htons( port );
|
||||
}
|
||||
|
||||
|
||||
port_t Ipv6Address::GetPort()
|
||||
{
|
||||
return ntohs( m_addr.sin6_port );
|
||||
}
|
||||
|
||||
|
||||
bool Ipv6Address::Resolve(const std::string& hostname,struct in6_addr& a)
|
||||
{
|
||||
struct sockaddr_in6 sa;
|
||||
memset(&a, 0, sizeof(a));
|
||||
if (Utility::isipv6(hostname))
|
||||
{
|
||||
if (!Utility::u2ip(hostname, sa, AI_NUMERICHOST))
|
||||
return false;
|
||||
a = sa.sin6_addr;
|
||||
return true;
|
||||
}
|
||||
if (!Utility::u2ip(hostname, sa))
|
||||
return false;
|
||||
a = sa.sin6_addr;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Ipv6Address::Reverse(struct in6_addr& a,std::string& name)
|
||||
{
|
||||
struct sockaddr_in6 sa;
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sa.sin6_family = AF_INET6;
|
||||
sa.sin6_addr = a;
|
||||
return Utility::reverse((struct sockaddr *)&sa, sizeof(sa), name);
|
||||
}
|
||||
|
||||
|
||||
std::string Ipv6Address::Convert(bool include_port)
|
||||
{
|
||||
if (include_port)
|
||||
return Convert(m_addr.sin6_addr) + ":" + Utility::l2string(GetPort());
|
||||
return Convert(m_addr.sin6_addr);
|
||||
}
|
||||
|
||||
|
||||
std::string Ipv6Address::Convert(struct in6_addr& a,bool mixed)
|
||||
{
|
||||
char slask[100]; // l2ip temporary
|
||||
*slask = 0;
|
||||
unsigned int prev = 0;
|
||||
bool skipped = false;
|
||||
bool ok_to_skip = true;
|
||||
if (mixed)
|
||||
{
|
||||
unsigned short x;
|
||||
unsigned short addr16[8];
|
||||
memcpy(addr16, &a, sizeof(addr16));
|
||||
for (size_t i = 0; i < 6; i++)
|
||||
{
|
||||
x = ntohs(addr16[i]);
|
||||
if (*slask && (x || !ok_to_skip || prev))
|
||||
{
|
||||
#if defined( _WIN32) && !defined(__CYGWIN__)
|
||||
strcat_s(slask,sizeof(slask),":");
|
||||
#else
|
||||
strcat(slask,":");
|
||||
#endif
|
||||
}
|
||||
if (x || !ok_to_skip)
|
||||
{
|
||||
snprintf(slask + strlen(slask), sizeof(slask) - strlen(slask),"%x", x);
|
||||
if (x && skipped)
|
||||
ok_to_skip = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
skipped = true;
|
||||
}
|
||||
prev = x;
|
||||
}
|
||||
x = ntohs(addr16[6]);
|
||||
snprintf(slask + strlen(slask), sizeof(slask) - strlen(slask),":%u.%u",x / 256,x & 255);
|
||||
x = ntohs(addr16[7]);
|
||||
snprintf(slask + strlen(slask), sizeof(slask) - strlen(slask),".%u.%u",x / 256,x & 255);
|
||||
}
|
||||
else
|
||||
{
|
||||
struct sockaddr_in6 sa;
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sa.sin6_family = AF_INET6;
|
||||
sa.sin6_addr = a;
|
||||
std::string name;
|
||||
Utility::reverse((struct sockaddr *)&sa, sizeof(sa), name, NI_NUMERICHOST);
|
||||
return name;
|
||||
}
|
||||
return slask;
|
||||
}
|
||||
|
||||
|
||||
void Ipv6Address::SetAddress(struct sockaddr *sa)
|
||||
{
|
||||
memcpy(&m_addr, sa, sizeof(struct sockaddr_in6));
|
||||
}
|
||||
|
||||
|
||||
int Ipv6Address::GetFamily()
|
||||
{
|
||||
return m_addr.sin6_family;
|
||||
}
|
||||
|
||||
|
||||
void Ipv6Address::SetFlowinfo(uint32_t x)
|
||||
{
|
||||
m_addr.sin6_flowinfo = x;
|
||||
}
|
||||
|
||||
|
||||
uint32_t Ipv6Address::GetFlowinfo()
|
||||
{
|
||||
return m_addr.sin6_flowinfo;
|
||||
}
|
||||
|
||||
|
||||
#ifndef _WIN32
|
||||
void Ipv6Address::SetScopeId(uint32_t x)
|
||||
{
|
||||
m_addr.sin6_scope_id = x;
|
||||
}
|
||||
|
||||
|
||||
uint32_t Ipv6Address::GetScopeId()
|
||||
{
|
||||
return m_addr.sin6_scope_id;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
bool Ipv6Address::IsValid()
|
||||
{
|
||||
return m_valid;
|
||||
}
|
||||
|
||||
|
||||
bool Ipv6Address::operator==(SocketAddress& a)
|
||||
{
|
||||
if (a.GetFamily() != GetFamily())
|
||||
return false;
|
||||
if ((socklen_t)a != sizeof(m_addr))
|
||||
return false;
|
||||
struct sockaddr *sa = a;
|
||||
struct sockaddr_in6 *p = (struct sockaddr_in6 *)sa;
|
||||
if (p -> sin6_port != m_addr.sin6_port)
|
||||
return false;
|
||||
if (memcmp(&p -> sin6_addr, &m_addr.sin6_addr, sizeof(struct in6_addr)))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
std::auto_ptr<SocketAddress> Ipv6Address::GetCopy()
|
||||
{
|
||||
return std::auto_ptr<SocketAddress>(new Ipv6Address(m_addr));
|
||||
}
|
||||
|
||||
|
||||
std::string Ipv6Address::Reverse()
|
||||
{
|
||||
std::string tmp;
|
||||
Reverse(m_addr.sin6_addr, tmp);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
} // namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
#endif // IPPROTO_IPV6
|
||||
#endif // ENABLE_IPV6
|
||||
|
||||
@@ -1,120 +0,0 @@
|
||||
/**
|
||||
** \file Ipv6Address.h
|
||||
** \date 2006-09-21
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2007-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef _SOCKETS_Ipv6Address_H
|
||||
#define _SOCKETS_Ipv6Address_H
|
||||
#include "sockets-config.h"
|
||||
#ifdef ENABLE_IPV6
|
||||
|
||||
#include "SocketAddress.h"
|
||||
#ifdef IPPROTO_IPV6
|
||||
#if defined( _WIN32) && !defined(__CYGWIN__)
|
||||
typedef unsigned __int32 uint32_t;
|
||||
#endif
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
|
||||
/** Ipv6 address implementation.
|
||||
\ingroup basic */
|
||||
class Ipv6Address : public SocketAddress
|
||||
{
|
||||
public:
|
||||
/** Create empty Ipv6 address structure.
|
||||
\param port Port number */
|
||||
Ipv6Address(port_t port = 0);
|
||||
/** Create Ipv6 address structure.
|
||||
\param a Socket address in network byte order
|
||||
\param port Port number in host byte order */
|
||||
Ipv6Address(struct in6_addr& a,port_t port);
|
||||
/** Create Ipv6 address structure.
|
||||
\param host Hostname to be resolved
|
||||
\param port Port number in host byte order */
|
||||
Ipv6Address(const std::string& host,port_t port);
|
||||
Ipv6Address(struct sockaddr_in6&);
|
||||
~Ipv6Address();
|
||||
|
||||
// SocketAddress implementation
|
||||
|
||||
operator struct sockaddr *();
|
||||
operator socklen_t();
|
||||
bool operator==(SocketAddress&);
|
||||
|
||||
void SetPort(port_t port);
|
||||
port_t GetPort();
|
||||
|
||||
void SetAddress(struct sockaddr *sa);
|
||||
int GetFamily();
|
||||
|
||||
bool IsValid();
|
||||
std::auto_ptr<SocketAddress> GetCopy();
|
||||
|
||||
/** Convert address struct to text. */
|
||||
std::string Convert(bool include_port = false);
|
||||
std::string Reverse();
|
||||
|
||||
/** Resolve hostname. */
|
||||
static bool Resolve(const std::string& hostname,struct in6_addr& a);
|
||||
/** Reverse resolve (IP to hostname). */
|
||||
static bool Reverse(struct in6_addr& a,std::string& name);
|
||||
/** Convert address struct to text. */
|
||||
static std::string Convert(struct in6_addr& a,bool mixed = false);
|
||||
|
||||
void SetFlowinfo(uint32_t);
|
||||
uint32_t GetFlowinfo();
|
||||
#ifndef _WIN32
|
||||
void SetScopeId(uint32_t);
|
||||
uint32_t GetScopeId();
|
||||
#endif
|
||||
|
||||
private:
|
||||
Ipv6Address(const Ipv6Address& ) {} // copy constructor
|
||||
Ipv6Address& operator=(const Ipv6Address& ) {
|
||||
return *this; // assignment operator
|
||||
}
|
||||
struct sockaddr_in6 m_addr;
|
||||
bool m_valid;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
} // namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
#endif // IPPROTO_IPV6
|
||||
#endif // ENABLE_IPV6
|
||||
#endif // _SOCKETS_Ipv6Address_H
|
||||
|
||||
@@ -1,572 +0,0 @@
|
||||
#include "Json.h"
|
||||
#include <stdio.h>
|
||||
#include <sstream>
|
||||
#include "Utility.h"
|
||||
|
||||
#define C buffer[index]
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
Json::Json() : m_type(TYPE_UNKNOWN)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
Json::Json(char value) : m_type(TYPE_INTEGER), m_i_value(value)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
Json::Json(short value) : m_type(TYPE_INTEGER), m_i_value(value)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
Json::Json(long value) : m_type(TYPE_INTEGER), m_i_value(value)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
//Json::Json(int64_t value) : m_type(TYPE_INTEGER), m_i_value(value)
|
||||
Json::Json(long long value) : m_type(TYPE_INTEGER), m_i_value(value)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
Json::Json(double value) : m_type(TYPE_REAL), m_d_value(value)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
Json::Json(const char *value) : m_type(TYPE_STRING), m_str_value(value)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
Json::Json(const std::string& value) : m_type(TYPE_STRING), m_str_value(value)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
Json::Json(bool value) : m_type(TYPE_BOOLEAN), m_b_value(value)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
Json::Json(json_type_t t) : m_type(t)
|
||||
{
|
||||
if (t != TYPE_ARRAY && t != TYPE_OBJECT)
|
||||
throw Exception("Must be type: Array or type: Object");
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
Json::~Json()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
Json::json_type_t Json::Type() const { return m_type; }
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
bool Json::HasValue(const std::string& name) const
|
||||
{
|
||||
if (m_type != TYPE_OBJECT)
|
||||
return false;
|
||||
return m_object.find(name) != m_object.end();
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
Json::operator char() const
|
||||
{
|
||||
return (char)m_i_value;
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
Json::operator short() const
|
||||
{
|
||||
return (short)m_i_value;
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
Json::operator long() const
|
||||
{
|
||||
return m_i_value;
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
Json::operator int64_t() const
|
||||
{
|
||||
return m_i_value;
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
Json::operator double() const
|
||||
{
|
||||
return m_d_value;
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
Json::operator std::string() const
|
||||
{
|
||||
return m_str_value;
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
Json::operator bool() const
|
||||
{
|
||||
return m_b_value;
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
const Json& Json::operator[](const char *name) const
|
||||
{
|
||||
if (m_type != TYPE_OBJECT)
|
||||
throw Exception("Must be type: Object");
|
||||
json_map_t::const_iterator it = m_object.find(name);
|
||||
if (it != m_object.end())
|
||||
return it -> second;
|
||||
throw Exception("Key not found: " + std::string(name));
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
Json& Json::operator[](const char *name)
|
||||
{
|
||||
if (m_type == TYPE_UNKNOWN)
|
||||
m_type = TYPE_OBJECT;
|
||||
if (m_type != TYPE_OBJECT)
|
||||
throw Exception("Must be type: Object");
|
||||
return m_object[name];
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
const Json& Json::operator[](const std::string& name) const
|
||||
{
|
||||
if (m_type != TYPE_OBJECT)
|
||||
throw Exception("Must be type: Object");
|
||||
json_map_t::const_iterator it = m_object.find(name);
|
||||
if (it != m_object.end())
|
||||
return it -> second;
|
||||
throw Exception("Key not found: " + name);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
Json& Json::operator[](const std::string& name)
|
||||
{
|
||||
if (m_type == TYPE_UNKNOWN)
|
||||
m_type = TYPE_OBJECT;
|
||||
if (m_type != TYPE_OBJECT)
|
||||
throw Exception("Must be type: Object");
|
||||
return m_object[name];
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
void Json::Add(Json data)
|
||||
{
|
||||
if (m_type == TYPE_UNKNOWN)
|
||||
m_type = TYPE_ARRAY;
|
||||
if (m_type != TYPE_ARRAY)
|
||||
throw Exception("trying to add array data in non-array");
|
||||
m_array.push_back(data);
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
const std::string& Json::GetString() const
|
||||
{
|
||||
return m_str_value;
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
Json::json_list_t& Json::GetArray()
|
||||
{
|
||||
if (m_type == TYPE_UNKNOWN)
|
||||
m_type = TYPE_ARRAY;
|
||||
if (m_type != TYPE_ARRAY)
|
||||
throw Exception("Json instance not of type: Array");
|
||||
return m_array;
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
Json::json_map_t& Json::GetObject()
|
||||
{
|
||||
if (m_type == TYPE_UNKNOWN)
|
||||
m_type = TYPE_OBJECT;
|
||||
if (m_type != TYPE_OBJECT)
|
||||
throw Exception("Json instance not of type: Array");
|
||||
return m_object;
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
const Json::json_list_t& Json::GetArray() const
|
||||
{
|
||||
if (m_type != TYPE_ARRAY)
|
||||
throw Exception("Json instance not of type: Array");
|
||||
return m_array;
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
const Json::json_map_t& Json::GetObject() const
|
||||
{
|
||||
if (m_type != TYPE_OBJECT)
|
||||
throw Exception("Json instance not of type: Array");
|
||||
return m_object;
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
Json Json::Parse(const std::string& data)
|
||||
{
|
||||
size_t i = 0;
|
||||
Json obj;
|
||||
obj.Parse(data.c_str(), i);
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
char Json::Parse(const char *buffer, size_t& index)
|
||||
{
|
||||
while (C == ' ' || C == 9 || C == 13 || C == 10)
|
||||
++index;
|
||||
size_t x = index; // origin
|
||||
std::string ord;
|
||||
if (C == '-' || isdigit(C)) // Number
|
||||
{
|
||||
bool dot = false;
|
||||
if (C == '-')
|
||||
{
|
||||
++index;
|
||||
}
|
||||
while (isdigit(C) || C == '.')
|
||||
{
|
||||
if (C == '.')
|
||||
dot = true;
|
||||
++index;
|
||||
}
|
||||
size_t sz = index - x;
|
||||
ord.resize(sz);
|
||||
memcpy(&ord[0], &buffer[x], sz);
|
||||
if (dot)
|
||||
{
|
||||
m_type = TYPE_REAL;
|
||||
m_d_value = atof(ord.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_type = TYPE_INTEGER;
|
||||
m_i_value = atoi(ord.c_str());
|
||||
}
|
||||
}
|
||||
else
|
||||
if (C == 34) // " - String
|
||||
{
|
||||
bool ign = false;
|
||||
x = ++index;
|
||||
while (C && (ign || C != 34))
|
||||
{
|
||||
if (ign)
|
||||
{
|
||||
ign = false;
|
||||
}
|
||||
else
|
||||
if (C == '\\')
|
||||
{
|
||||
ign = true;
|
||||
}
|
||||
++index;
|
||||
}
|
||||
size_t sz = index - x;
|
||||
ord.resize(sz);
|
||||
memcpy(&ord[0], &buffer[x], sz);
|
||||
decode(ord);
|
||||
++index;
|
||||
m_type = TYPE_STRING;
|
||||
m_str_value = ord;
|
||||
}
|
||||
else
|
||||
if (!strncmp(&buffer[index], "null", 4)) // null value
|
||||
{
|
||||
m_type = TYPE_UNKNOWN;
|
||||
index += 4;
|
||||
}
|
||||
else
|
||||
if (!strncmp(&buffer[index], "true", 4)) // Boolean: true
|
||||
{
|
||||
m_type = TYPE_BOOLEAN;
|
||||
m_b_value = true;
|
||||
index += 4;
|
||||
}
|
||||
else
|
||||
if (!strncmp(&buffer[index], "false", 5)) // Boolean: false
|
||||
{
|
||||
m_type = TYPE_BOOLEAN;
|
||||
m_b_value = false;
|
||||
index += 5;
|
||||
}
|
||||
else
|
||||
if (C == '[') // Array
|
||||
{
|
||||
++index;
|
||||
m_type = TYPE_ARRAY;
|
||||
while (true)
|
||||
{
|
||||
char res;
|
||||
Json o;
|
||||
if ((res = o.Parse(buffer, index)) == 0)
|
||||
{
|
||||
m_array.push_back(o);
|
||||
}
|
||||
else
|
||||
if (res == ']')
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
if (res == ',') // another element follows
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
throw Exception(std::string("Unexpected end of Array: ") + res);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
if (C == ']') // end of Array
|
||||
{
|
||||
++index;
|
||||
return ']';
|
||||
}
|
||||
else
|
||||
if (C == '{') // Object
|
||||
{
|
||||
++index;
|
||||
m_type = TYPE_OBJECT;
|
||||
int state = 0;
|
||||
std::string element_name;
|
||||
bool quit = false;
|
||||
while (!quit)
|
||||
{
|
||||
Json o;
|
||||
char res = o.Parse(buffer, index);
|
||||
switch (state)
|
||||
{
|
||||
case 0:
|
||||
if (res == ',') // another object follow
|
||||
break;
|
||||
if (res == '}') // end of Object
|
||||
{
|
||||
quit = true;
|
||||
break;
|
||||
}
|
||||
if (res || o.Type() != TYPE_STRING)
|
||||
throw Exception("Object element name missing");
|
||||
element_name = o.GetString();
|
||||
state = 1;
|
||||
break;
|
||||
case 1:
|
||||
if (res != ':')
|
||||
throw Exception("Object element separator missing");
|
||||
state = 2;
|
||||
break;
|
||||
case 2:
|
||||
if (res)
|
||||
throw Exception(std::string("Unexpected character when parsing anytype: ") + res);
|
||||
m_object[element_name] = o;
|
||||
state = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
if (C == '}') // end of Object
|
||||
{
|
||||
++index;
|
||||
return '}';
|
||||
}
|
||||
else
|
||||
if (C == ',')
|
||||
{
|
||||
++index;
|
||||
return ',';
|
||||
}
|
||||
else
|
||||
if (C == ':')
|
||||
{
|
||||
++index;
|
||||
return ':';
|
||||
}
|
||||
else
|
||||
{
|
||||
throw Exception("Can't parse Json representation: " + std::string(&buffer[index]));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
std::string Json::ToString(bool quote) const
|
||||
{
|
||||
switch (m_type)
|
||||
{
|
||||
case TYPE_UNKNOWN:
|
||||
break;
|
||||
case TYPE_INTEGER:
|
||||
return Utility::l2string(m_i_value);
|
||||
case TYPE_REAL:
|
||||
{
|
||||
char slask[100];
|
||||
sprintf(slask, "%f", m_d_value);
|
||||
return slask;
|
||||
}
|
||||
case TYPE_STRING:
|
||||
{
|
||||
std::ostringstream tmp;
|
||||
tmp << "\"" << encode(m_str_value) << "\"";
|
||||
return tmp.str();
|
||||
}
|
||||
case TYPE_BOOLEAN:
|
||||
return m_b_value ? "true" : "false";
|
||||
case TYPE_ARRAY:
|
||||
{
|
||||
std::ostringstream tmp;
|
||||
bool first = true;
|
||||
tmp << "[";
|
||||
for (json_list_t::const_iterator it = m_array.begin(); it != m_array.end(); it++)
|
||||
{
|
||||
const Json& ref = *it;
|
||||
if (!first)
|
||||
tmp << ",";
|
||||
tmp << ref.ToString(quote);
|
||||
first = false;
|
||||
}
|
||||
tmp << "]";
|
||||
return tmp.str();
|
||||
}
|
||||
case TYPE_OBJECT:
|
||||
{
|
||||
std::ostringstream tmp;
|
||||
bool first = true;
|
||||
tmp << "{";
|
||||
for (json_map_t::const_iterator it = m_object.begin(); it != m_object.end(); it++)
|
||||
{
|
||||
const std::pair<std::string, Json>& ref = *it;
|
||||
if (!first)
|
||||
tmp << ",";
|
||||
if (quote)
|
||||
tmp << "\"" << encode(ref.first) << "\":" << ref.second.ToString(quote);
|
||||
else
|
||||
tmp << ref.first << ":" << ref.second.ToString(quote);
|
||||
first = false;
|
||||
}
|
||||
tmp << "}";
|
||||
return tmp.str();
|
||||
}
|
||||
}
|
||||
return "null";
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
void Json::encode(std::string& src) const
|
||||
{
|
||||
size_t pos = src.find("\\");
|
||||
while (pos != std::string::npos)
|
||||
{
|
||||
src.replace(pos, 1, "\\\\");
|
||||
pos = src.find("\\", pos + 2);
|
||||
}
|
||||
pos = src.find("\r");
|
||||
while (pos != std::string::npos)
|
||||
{
|
||||
src.replace(pos, 1, "\\r");
|
||||
pos = src.find("\r", pos + 2);
|
||||
}
|
||||
pos = src.find("\n");
|
||||
while (pos != std::string::npos)
|
||||
{
|
||||
src.replace(pos, 1, "\\n");
|
||||
pos = src.find("\n", pos + 2);
|
||||
}
|
||||
pos = src.find("\"");
|
||||
while (pos != std::string::npos)
|
||||
{
|
||||
src.replace(pos, 1, "\\\"");
|
||||
pos = src.find("\"", pos + 2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
void Json::decode(std::string& src) const
|
||||
{
|
||||
size_t pos = src.find("\\\"");
|
||||
while (pos != std::string::npos)
|
||||
{
|
||||
src.replace(pos, 2, "\"");
|
||||
pos = src.find("\\\"", pos + 1);
|
||||
}
|
||||
pos = src.find("\\r");
|
||||
while (pos != std::string::npos)
|
||||
{
|
||||
src.replace(pos, 2, "\r");
|
||||
pos = src.find("\\r", pos + 1);
|
||||
}
|
||||
pos = src.find("\\n");
|
||||
while (pos != std::string::npos)
|
||||
{
|
||||
src.replace(pos, 2, "\n");
|
||||
pos = src.find("\\n", pos + 1);
|
||||
}
|
||||
pos = src.find("\\\\");
|
||||
while (pos != std::string::npos)
|
||||
{
|
||||
src.replace(pos, 2, "\\");
|
||||
pos = src.find("\\\\", pos + 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
std::string Json::encode(const std::string& src) const
|
||||
{
|
||||
std::string tmp(src);
|
||||
encode(tmp);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
} // namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
@@ -1,102 +0,0 @@
|
||||
#ifndef _SOCKETS_Json_H
|
||||
#define _SOCKETS_Json_H
|
||||
|
||||
#include "Exception.h"
|
||||
#include <list>
|
||||
#include <map>
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
class Json
|
||||
{
|
||||
public:
|
||||
typedef std::list<Json> json_list_t;
|
||||
typedef std::map<std::string, Json> json_map_t;
|
||||
|
||||
typedef enum {
|
||||
TYPE_UNKNOWN = 0,
|
||||
TYPE_INTEGER,
|
||||
TYPE_REAL,
|
||||
TYPE_STRING,
|
||||
TYPE_BOOLEAN,
|
||||
TYPE_ARRAY,
|
||||
TYPE_OBJECT
|
||||
} json_type_t;
|
||||
|
||||
public:
|
||||
/** Default constructor */
|
||||
Json(); //m_type(TYPE_UNKNOWN);
|
||||
|
||||
/** Basic type constructors */
|
||||
Json(char value);
|
||||
Json(short value);
|
||||
Json(long value); //m_type(TYPE_INTEGER), m_i_value(value);
|
||||
Json(long long value);
|
||||
// LG Json(int64_t value);
|
||||
Json(double value); //m_type(TYPE_REAL), m_d_value(value);
|
||||
Json(const char *value); //m_type(TYPE_STRING), m_str_value(value);
|
||||
Json(const std::string& value); //m_type(TYPE_STRING), m_str_value(value);
|
||||
Json(bool value); //m_type(TYPE_BOOLEAN), m_b_value(value);
|
||||
|
||||
/** Complex type constructor (array, object) */
|
||||
Json(json_type_t t); //m_type(t);
|
||||
|
||||
virtual ~Json();
|
||||
|
||||
char Parse(const char *buffer, size_t& index);
|
||||
|
||||
json_type_t Type() const;
|
||||
|
||||
bool HasValue(const std::string& name) const;
|
||||
|
||||
operator char() const;
|
||||
operator short() const;
|
||||
operator long() const;
|
||||
//operator int64_t() const;
|
||||
operator long long() const;
|
||||
operator double() const;
|
||||
operator std::string() const;
|
||||
operator bool() const;
|
||||
|
||||
const Json& operator[](const char *name) const;
|
||||
Json& operator[](const char *name);
|
||||
|
||||
const Json& operator[](const std::string& name) const;
|
||||
Json& operator[](const std::string& name);
|
||||
|
||||
void Add(Json data);
|
||||
|
||||
const std::string& GetString() const;
|
||||
|
||||
const json_list_t& GetArray() const;
|
||||
json_list_t& GetArray();
|
||||
|
||||
const json_map_t& GetObject() const;
|
||||
json_map_t& GetObject();
|
||||
|
||||
std::string ToString(bool quote = true) const;
|
||||
|
||||
static Json Parse(const std::string& data);
|
||||
|
||||
void encode(std::string& src) const;
|
||||
void decode(std::string& src) const;
|
||||
std::string encode(const std::string&) const;
|
||||
|
||||
private:
|
||||
json_type_t m_type;
|
||||
long m_i_value;
|
||||
double m_d_value;
|
||||
std::string m_str_value;
|
||||
bool m_b_value;
|
||||
json_list_t m_array;
|
||||
json_map_t m_object;
|
||||
};
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
} // namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
#endif // _SOCKETS_Json_H
|
||||
@@ -1,511 +0,0 @@
|
||||
/** \file ListenSocket.h
|
||||
** \date 2004-02-13
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2004-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef _SOCKETS_ListenSocket_H
|
||||
#define _SOCKETS_ListenSocket_H
|
||||
#include "sockets-config.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <stdlib.h>
|
||||
#else
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
#include "ISocketHandler.h"
|
||||
#include "Socket.h"
|
||||
#include "Utility.h"
|
||||
#include "SctpSocket.h"
|
||||
#include "Ipv4Address.h"
|
||||
#include "Ipv6Address.h"
|
||||
#ifdef ENABLE_EXCEPTIONS
|
||||
#include "Exception.h"
|
||||
#endif
|
||||
#include "Lock.h"
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
|
||||
/** Binds incoming port number to new Socket class X.
|
||||
\ingroup basic */
|
||||
template <class X>
|
||||
class ListenSocket : public Socket
|
||||
{
|
||||
public:
|
||||
/** Constructor.
|
||||
\param h ISocketHandler reference
|
||||
\param use_creator Optional use of creator (default true) */
|
||||
ListenSocket(ISocketHandler& h,bool use_creator = true) : Socket(h), m_depth(0), m_creator(NULL)
|
||||
,m_bHasCreate(false) {
|
||||
if (use_creator) {
|
||||
m_creator = new X(h);
|
||||
Socket *tmp = m_creator -> Create();
|
||||
|
||||
if (tmp && dynamic_cast<X *>(tmp)) {
|
||||
m_bHasCreate = true;
|
||||
}
|
||||
|
||||
if (tmp) {
|
||||
delete tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
~ListenSocket() {
|
||||
if (m_creator) {
|
||||
delete m_creator;
|
||||
}
|
||||
}
|
||||
|
||||
/** Close file descriptor. */
|
||||
int Close() {
|
||||
if (GetSocket() != INVALID_SOCKET) {
|
||||
if (closesocket(GetSocket()) == -1) {
|
||||
} else {
|
||||
Attach(INVALID_SOCKET);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Bind and listen to any interface.
|
||||
\param port Port (0 is random)
|
||||
\param depth Listen queue depth */
|
||||
int Bind(port_t port,int depth = 20) {
|
||||
#ifdef ENABLE_IPV6
|
||||
#ifdef IPPROTO_IPV6
|
||||
|
||||
if (IsIpv6()) {
|
||||
Ipv6Address ad(port);
|
||||
return Bind(ad, depth);
|
||||
} else
|
||||
#endif
|
||||
#endif
|
||||
{
|
||||
Ipv4Address ad(port);
|
||||
return Bind(ad, depth);
|
||||
}
|
||||
}
|
||||
|
||||
int Bind(SocketAddress& ad,int depth) {
|
||||
#ifdef USE_SCTP
|
||||
|
||||
if (dynamic_cast<SctpSocket *>(m_creator)) {
|
||||
return Bind(ad, "sctp", depth);
|
||||
}
|
||||
|
||||
#endif
|
||||
return Bind(ad, "tcp", depth);
|
||||
}
|
||||
|
||||
/** Bind and listen to any interface, with optional protocol.
|
||||
\param port Port (0 is random)
|
||||
\param protocol Network protocol
|
||||
\param depth Listen queue depth */
|
||||
int Bind(port_t port,const std::string& protocol,int depth = 20) {
|
||||
#ifdef ENABLE_IPV6
|
||||
#ifdef IPPROTO_IPV6
|
||||
|
||||
if (IsIpv6()) {
|
||||
Ipv6Address ad(port);
|
||||
return Bind(ad, protocol, depth);
|
||||
} else
|
||||
#endif
|
||||
#endif
|
||||
{
|
||||
Ipv4Address ad(port);
|
||||
return Bind(ad, protocol, depth);
|
||||
}
|
||||
}
|
||||
|
||||
/** Bind and listen to specific interface.
|
||||
\param intf Interface hostname
|
||||
\param port Port (0 is random)
|
||||
\param depth Listen queue depth */
|
||||
int Bind(const std::string& intf,port_t port,int depth = 20) {
|
||||
#ifdef ENABLE_IPV6
|
||||
#ifdef IPPROTO_IPV6
|
||||
|
||||
if (IsIpv6()) {
|
||||
Ipv6Address ad(intf, port);
|
||||
|
||||
if (ad.IsValid()) {
|
||||
return Bind(ad, depth);
|
||||
}
|
||||
|
||||
Handler().LogError(this, "Bind", 0, "name resolution of interface name failed", LOG_LEVEL_FATAL);
|
||||
return -1;
|
||||
} else
|
||||
#endif
|
||||
#endif
|
||||
{
|
||||
Ipv4Address ad(intf, port);
|
||||
|
||||
if (ad.IsValid()) {
|
||||
return Bind(ad, depth);
|
||||
}
|
||||
|
||||
Handler().LogError(this, "Bind", 0, "name resolution of interface name failed", LOG_LEVEL_FATAL);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/** Bind and listen to specific interface.
|
||||
\param intf Interface hostname
|
||||
\param port Port (0 is random)
|
||||
\param protocol Network protocol
|
||||
\param depth Listen queue depth */
|
||||
int Bind(const std::string& intf,port_t port,const std::string& protocol,int depth = 20) {
|
||||
#ifdef ENABLE_IPV6
|
||||
#ifdef IPPROTO_IPV6
|
||||
|
||||
if (IsIpv6()) {
|
||||
Ipv6Address ad(intf, port);
|
||||
|
||||
if (ad.IsValid()) {
|
||||
return Bind(ad, protocol, depth);
|
||||
}
|
||||
|
||||
Handler().LogError(this, "Bind", 0, "name resolution of interface name failed", LOG_LEVEL_FATAL);
|
||||
return -1;
|
||||
} else
|
||||
#endif
|
||||
#endif
|
||||
{
|
||||
Ipv4Address ad(intf, port);
|
||||
|
||||
if (ad.IsValid()) {
|
||||
return Bind(ad, protocol, depth);
|
||||
}
|
||||
|
||||
Handler().LogError(this, "Bind", 0, "name resolution of interface name failed", LOG_LEVEL_FATAL);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/** Bind and listen to ipv4 interface.
|
||||
\param a Ipv4 interface address
|
||||
\param port Port (0 is random)
|
||||
\param depth Listen queue depth */
|
||||
int Bind(ipaddr_t a,port_t port,int depth = 20) {
|
||||
Ipv4Address ad(a, port);
|
||||
#ifdef USE_SCTP
|
||||
|
||||
if (dynamic_cast<SctpSocket *>(m_creator)) {
|
||||
return Bind(ad, "sctp", depth);
|
||||
}
|
||||
|
||||
#endif
|
||||
return Bind(ad, "tcp", depth);
|
||||
}
|
||||
/** Bind and listen to ipv4 interface.
|
||||
\param a Ipv4 interface address
|
||||
\param port Port (0 is random)
|
||||
\param protocol Network protocol
|
||||
\param depth Listen queue depth */
|
||||
int Bind(ipaddr_t a,port_t port,const std::string& protocol,int depth) {
|
||||
Ipv4Address ad(a, port);
|
||||
return Bind(ad, protocol, depth);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_IPV6
|
||||
#ifdef IPPROTO_IPV6
|
||||
/** Bind and listen to ipv6 interface.
|
||||
\param a Ipv6 interface address
|
||||
\param port Port (0 is random)
|
||||
\param depth Listen queue depth */
|
||||
int Bind(in6_addr a,port_t port,int depth = 20) {
|
||||
Ipv6Address ad(a, port);
|
||||
#ifdef USE_SCTP
|
||||
|
||||
if (dynamic_cast<SctpSocket *>(m_creator)) {
|
||||
return Bind(ad, "sctp", depth);
|
||||
}
|
||||
|
||||
#endif
|
||||
return Bind(ad, "tcp", depth);
|
||||
}
|
||||
/** Bind and listen to ipv6 interface.
|
||||
\param a Ipv6 interface address
|
||||
\param port Port (0 is random)
|
||||
\param protocol Network protocol
|
||||
\param depth Listen queue depth */
|
||||
int Bind(in6_addr a,port_t port,const std::string& protocol,int depth) {
|
||||
Ipv6Address ad(a, port);
|
||||
return Bind(ad, protocol, depth);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/** Bind and listen to network interface.
|
||||
\param ad Interface address
|
||||
\param protocol Network protocol
|
||||
\param depth Listen queue depth */
|
||||
int Bind(SocketAddress& ad,const std::string& protocol,int depth) {
|
||||
SOCKET s;
|
||||
|
||||
if ( (s = CreateSocket(ad.GetFamily(), SOCK_STREAM, protocol)) == INVALID_SOCKET) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// socket must be nonblocking for async connect
|
||||
if (!SetNonblocking(true, s)) {
|
||||
closesocket(s);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (bind(s, ad, ad) == -1) {
|
||||
Handler().LogError(this, "bind", Errno, StrError(Errno), LOG_LEVEL_FATAL);
|
||||
closesocket(s);
|
||||
#ifdef ENABLE_EXCEPTIONS
|
||||
throw Exception("bind() failed for port " + Utility::l2string(ad.GetPort()) + ": " + StrError(Errno));
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (listen(s, depth) == -1) {
|
||||
Handler().LogError(this, "listen", Errno, StrError(Errno), LOG_LEVEL_FATAL);
|
||||
closesocket(s);
|
||||
#ifdef ENABLE_EXCEPTIONS
|
||||
throw Exception("listen() failed for port " + Utility::l2string(ad.GetPort()) + ": " + StrError(Errno));
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
m_depth = depth;
|
||||
Attach(s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Return assigned port number. */
|
||||
port_t GetPort() {
|
||||
return GetSockPort();
|
||||
}
|
||||
|
||||
/** Return listen queue depth. */
|
||||
int GetDepth() {
|
||||
return m_depth;
|
||||
}
|
||||
|
||||
/** OnRead on a ListenSocket receives an incoming connection. */
|
||||
void OnRead() {
|
||||
struct sockaddr sa;
|
||||
int max = 10; // process max 10 incoming connection in one call
|
||||
|
||||
while (max--) {
|
||||
socklen_t sa_len = sizeof(struct sockaddr);
|
||||
SOCKET a_s = accept(GetSocket(), &sa, &sa_len);
|
||||
|
||||
if (a_s == INVALID_SOCKET) {
|
||||
// EAGAIN or EWOULDBLOCK
|
||||
#ifdef _WIN32
|
||||
if (Errno != WSAEWOULDBLOCK)
|
||||
#else
|
||||
if (Errno != EWOULDBLOCK)
|
||||
#endif
|
||||
{
|
||||
Handler().LogError(this, "accept", Errno, StrError(Errno), LOG_LEVEL_ERROR);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Handler().OkToAccept(this)) {
|
||||
Handler().LogError(this, "accept", -1, "Not OK to accept", LOG_LEVEL_WARNING);
|
||||
closesocket(a_s);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Handler().GetCount() >= Handler().MaxCount()) {
|
||||
Handler().LogError(this, "accept", (int)Handler().GetCount(), "ISocketHandler socket limit reached", LOG_LEVEL_FATAL);
|
||||
closesocket(a_s);
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
Socket *tmp = NULL;
|
||||
|
||||
if (Handler().IsThreaded()) {
|
||||
ISocketHandler& h = Handler().GetRandomHandler();
|
||||
tmp = new X(h); // %! no support for Create
|
||||
#ifdef ENABLE_IPV6
|
||||
tmp -> SetIpv6( IsIpv6() );
|
||||
#endif
|
||||
tmp -> SetParent(this);
|
||||
tmp -> Attach(a_s);
|
||||
tmp -> SetNonblocking(true);
|
||||
#ifdef ENABLE_IPV6
|
||||
#ifdef IPPROTO_IPV6
|
||||
|
||||
if (sa_len == sizeof(struct sockaddr_in6)) {
|
||||
if (reinterpret_cast<struct sockaddr_in6&>(sa).sin6_family == AF_INET6) {
|
||||
Ipv6Address ad(reinterpret_cast<struct sockaddr_in6&>(sa).sin6_addr,
|
||||
ntohs(reinterpret_cast<struct sockaddr_in6&>(sa).sin6_port));
|
||||
ad.SetFlowinfo(reinterpret_cast<struct sockaddr_in6&>(sa).sin6_flowinfo);
|
||||
#ifndef _WIN32
|
||||
ad.SetScopeId(reinterpret_cast<struct sockaddr_in6&>(sa).sin6_scope_id);
|
||||
#endif
|
||||
tmp -> SetRemoteAddress(ad);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (sa_len == sizeof(struct sockaddr_in)) {
|
||||
struct sockaddr_in *p = (struct sockaddr_in *)&sa;
|
||||
|
||||
if (p -> sin_family == AF_INET) {
|
||||
Ipv4Address ad(p -> sin_addr,ntohs(p -> sin_port));
|
||||
tmp -> SetRemoteAddress(ad);
|
||||
}
|
||||
}
|
||||
|
||||
tmp -> SetConnected(true);
|
||||
tmp -> Init();
|
||||
tmp -> SetDeleteByHandler(true);
|
||||
{
|
||||
Lock lock(h.GetMutex());
|
||||
h.Add(tmp);
|
||||
#ifdef HAVE_OPENSSL
|
||||
|
||||
if (tmp -> IsSSL()) { // SSL Enabled socket
|
||||
// %! OnSSLAccept calls SSLNegotiate that can finish in this one call.
|
||||
// %! If that happens and negotiation fails, the 'tmp' instance is
|
||||
// %! still added to the list of active sockets in the sockethandler.
|
||||
// %! See bugfix for this in SocketHandler::Select - don't Set rwx
|
||||
// %! flags if CloseAndDelete() flag is true.
|
||||
// %! An even better fugbix (see TcpSocket::OnSSLAccept) now avoids
|
||||
// %! the Add problem altogether, so ignore the above.
|
||||
// %! (OnSSLAccept does no longer call SSLNegotiate().)
|
||||
tmp -> OnSSLAccept();
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
tmp -> OnAccept();
|
||||
}
|
||||
}
|
||||
h.Release();
|
||||
} else {
|
||||
tmp = m_bHasCreate ? m_creator -> Create() : new X(Handler());
|
||||
#ifdef ENABLE_IPV6
|
||||
tmp -> SetIpv6( IsIpv6() );
|
||||
#endif
|
||||
tmp -> SetParent(this);
|
||||
tmp -> Attach(a_s);
|
||||
tmp -> SetNonblocking(true);
|
||||
#ifdef ENABLE_IPV6
|
||||
#ifdef IPPROTO_IPV6
|
||||
|
||||
if (sa_len == sizeof(struct sockaddr_in6)) {
|
||||
if (reinterpret_cast<struct sockaddr_in6&>(sa).sin6_family == AF_INET6) {
|
||||
Ipv6Address ad(reinterpret_cast<struct sockaddr_in6&>(sa).sin6_addr,
|
||||
ntohs(reinterpret_cast<struct sockaddr_in6&>(sa).sin6_port));
|
||||
ad.SetFlowinfo(reinterpret_cast<struct sockaddr_in6&>(sa).sin6_flowinfo);
|
||||
#ifndef _WIN32
|
||||
ad.SetScopeId(reinterpret_cast<struct sockaddr_in6&>(sa).sin6_scope_id);
|
||||
#endif
|
||||
tmp -> SetRemoteAddress(ad);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (sa_len == sizeof(struct sockaddr_in)) {
|
||||
struct sockaddr_in *p = (struct sockaddr_in *)&sa;
|
||||
|
||||
if (p -> sin_family == AF_INET) {
|
||||
Ipv4Address ad(p -> sin_addr,ntohs(p -> sin_port));
|
||||
tmp -> SetRemoteAddress(ad);
|
||||
}
|
||||
}
|
||||
|
||||
tmp -> SetConnected(true);
|
||||
tmp -> Init();
|
||||
tmp -> SetDeleteByHandler(true);
|
||||
Handler().Add(tmp);
|
||||
#ifdef HAVE_OPENSSL
|
||||
|
||||
if (tmp -> IsSSL()) { // SSL Enabled socket
|
||||
// %! OnSSLAccept calls SSLNegotiate that can finish in this one call.
|
||||
// %! If that happens and negotiation fails, the 'tmp' instance is
|
||||
// %! still added to the list of active sockets in the sockethandler.
|
||||
// %! See bugfix for this in SocketHandler::Select - don't Set rwx
|
||||
// %! flags if CloseAndDelete() flag is true.
|
||||
// %! An even better fugbix (see TcpSocket::OnSSLAccept) now avoids
|
||||
// %! the Add problem altogether, so ignore the above.
|
||||
// %! (OnSSLAccept does no longer call SSLNegotiate().)
|
||||
tmp -> OnSSLAccept();
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
tmp -> OnAccept();
|
||||
}
|
||||
}
|
||||
} // while (true)
|
||||
}
|
||||
|
||||
/** Please don't use this method.
|
||||
"accept()" is handled automatically in the OnRead() method. */
|
||||
virtual SOCKET Accept(SOCKET socket, struct sockaddr *saptr, socklen_t *lenptr) {
|
||||
return accept(socket, saptr, lenptr);
|
||||
}
|
||||
|
||||
bool HasCreator() {
|
||||
return m_bHasCreate;
|
||||
}
|
||||
|
||||
void OnOptions(int,int,int,SOCKET) {
|
||||
SetSoReuseaddr(true);
|
||||
}
|
||||
|
||||
protected:
|
||||
ListenSocket(const ListenSocket& s) : Socket(s) {}
|
||||
private:
|
||||
ListenSocket& operator=(const ListenSocket& ) {
|
||||
return *this;
|
||||
}
|
||||
int m_depth;
|
||||
X *m_creator;
|
||||
bool m_bHasCreate;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _SOCKETS_ListenSocket_H
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
/** \file Lock.cpp
|
||||
** \date 2005-08-22
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2005-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#include "IMutex.h"
|
||||
#include "Lock.h"
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
|
||||
Lock::Lock(const IMutex& m) : m_mutex(m)
|
||||
{
|
||||
m_mutex.Lock();
|
||||
}
|
||||
|
||||
|
||||
Lock::~Lock()
|
||||
{
|
||||
m_mutex.Unlock();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
/** \file Lock.h
|
||||
** \date 2005-08-22
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2005-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef _SOCKETS_Lock_H
|
||||
#define _SOCKETS_Lock_H
|
||||
|
||||
#include "sockets-config.h"
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
class IMutex;
|
||||
|
||||
/** IMutex encapsulation class.
|
||||
\ingroup threading */
|
||||
class Lock
|
||||
{
|
||||
public:
|
||||
Lock(const IMutex&);
|
||||
~Lock();
|
||||
|
||||
private:
|
||||
const IMutex& m_mutex;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
#endif // _SOCKETS_Lock_H
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
noinst_LIBRARIES = libsockets.a
|
||||
|
||||
libsockets_a_SOURCES = Ajp13Socket.cpp HttpRequest.cpp SocketHandlerEp.cpp \
|
||||
AjpBaseSocket.cpp HttpResponse.cpp SocketHandlerThread.cpp \
|
||||
Base64.cpp HTTPSocket.cpp socket_include.cpp \
|
||||
Debug.cpp HttpTransaction.cpp \
|
||||
Event.cpp IEventOwner.cpp SocketStream.cpp \
|
||||
EventHandler.cpp Ipv4Address.cpp SocketThread.cpp \
|
||||
EventTime.cpp Ipv6Address.cpp SSLInitializer.cpp \
|
||||
Exception.cpp Json.cpp StdoutLog.cpp \
|
||||
File.cpp Lock.cpp StreamSocket.cpp \
|
||||
FileStream.cpp MemFile.cpp StreamWriter.cpp \
|
||||
HttpBaseSocket.cpp Mutex.cpp TcpSocket.cpp \
|
||||
HttpClientSocket.cpp Parse.cpp Thread.cpp \
|
||||
HttpdCookies.cpp ResolvServer.cpp UdpSocket.cpp \
|
||||
HttpDebugSocket.cpp ResolvSocket.cpp Utility.cpp \
|
||||
HttpdForm.cpp SctpSocket.cpp XmlDocument.cpp \
|
||||
HttpdSocket.cpp Semaphore.cpp XmlException.cpp \
|
||||
HttpGetSocket.cpp SmtpdSocket.cpp XmlNode.cpp \
|
||||
HttpPostSocket.cpp Socket.cpp \
|
||||
HttpPutSocket.cpp SocketHandler.cpp \
|
||||
ajp13.h HttpTransaction.h SocketAddress.h \
|
||||
Ajp13Socket.h IBase.h Socket.h \
|
||||
AjpBaseSocket.h IEventHandler.h SocketHandlerEp.h \
|
||||
Base64.h IEventOwner.h SocketHandler.h \
|
||||
Debug.h IFile.h SocketHandlerThread.h \
|
||||
Event.h IFileUpload.h socket_include.h \
|
||||
EventHandler.h IHttpServer.h sockets-config.h \
|
||||
EventTime.h IMutex.h SocketStream.h \
|
||||
Exception.h Ipv4Address.h SocketThread.h \
|
||||
File.h Ipv6Address.h SSLInitializer.h \
|
||||
FileStream.h ISocketHandler.h StdLog.h \
|
||||
HttpBaseSocket.h IStream.h StdoutLog.h \
|
||||
HttpClientSocket.h Json.h StreamSocket.h \
|
||||
HttpdCookies.h ListenSocket.h StreamWriter.h \
|
||||
HttpDebugSocket.h Lock.h TcpSocket.h \
|
||||
HttpdForm.h MemFile.h Thread.h \
|
||||
HttpdSocket.h Mutex.h UdpSocket.h \
|
||||
HttpGetSocket.h Parse.h Utility.h \
|
||||
HttpPostSocket.h ResolvServer.h XmlDocument.h \
|
||||
HttpPutSocket.h ResolvSocket.h XmlException.h \
|
||||
HttpRequest.h SctpSocket.h XmlNode.h \
|
||||
HttpResponse.h Semaphore.h \
|
||||
HTTPSocket.h SmtpdSocket.h
|
||||
@@ -1,349 +0,0 @@
|
||||
/** \file MemFile.cpp
|
||||
** \date 2005-04-25
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2004-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4786)
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
|
||||
#include "MemFile.h"
|
||||
#include "Exception.h"
|
||||
#include "Lock.h"
|
||||
#include "Utility.h"
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
|
||||
MemFile::MemFile()
|
||||
:m_src(m_src)
|
||||
,m_src_valid(false)
|
||||
,m_base(new block_t)
|
||||
,m_current_read(m_base)
|
||||
,m_current_write(m_base)
|
||||
,m_current_write_nr(0)
|
||||
,m_read_ptr(0)
|
||||
,m_write_ptr(0)
|
||||
,m_b_read_caused_eof(false)
|
||||
,m_ref_count(0)
|
||||
,m_ref_decreased(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
MemFile::MemFile(MemFile& s)
|
||||
:m_src(s)
|
||||
,m_src_valid(true)
|
||||
,m_base(s.m_base)
|
||||
,m_current_read(m_base)
|
||||
,m_current_write(s.m_current_write)
|
||||
,m_current_write_nr(s.m_current_write_nr)
|
||||
,m_read_ptr(0)
|
||||
,m_write_ptr(s.m_write_ptr)
|
||||
,m_b_read_caused_eof(false)
|
||||
,m_ref_count(0)
|
||||
,m_ref_decreased(false)
|
||||
,m_path(s.m_path)
|
||||
{
|
||||
m_src.Increase();
|
||||
}
|
||||
|
||||
|
||||
MemFile::MemFile(File& f)
|
||||
:m_src(m_src)
|
||||
,m_src_valid(false)
|
||||
,m_base(new block_t)
|
||||
,m_current_read(NULL)
|
||||
,m_current_write(NULL)
|
||||
,m_current_write_nr(0)
|
||||
,m_read_ptr(0)
|
||||
,m_write_ptr(0)
|
||||
,m_b_read_caused_eof(false)
|
||||
,m_ref_count(0)
|
||||
,m_ref_decreased(false)
|
||||
,m_path(f.Path())
|
||||
{
|
||||
m_current_read = m_base;
|
||||
m_current_write = m_base;
|
||||
char slask[32768];
|
||||
size_t n;
|
||||
while ((n = f.fread(slask, 1, 32768)) > 0)
|
||||
{
|
||||
fwrite(slask, 1, n);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
MemFile::~MemFile()
|
||||
{
|
||||
if (m_ref_count)
|
||||
std::cerr << "MemFile destructor with a ref count of " + Utility::l2string(m_ref_count) << std::endl;
|
||||
while (m_base && !m_src_valid)
|
||||
{
|
||||
block_t *p = m_base;
|
||||
m_base = p -> next;
|
||||
delete p;
|
||||
}
|
||||
if (m_src_valid && !m_ref_decreased)
|
||||
{
|
||||
m_src.Decrease();
|
||||
m_ref_decreased = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool MemFile::fopen(const std::string& path, const std::string& mode)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void MemFile::fclose() const
|
||||
{
|
||||
if (m_src_valid && !m_ref_decreased)
|
||||
{
|
||||
m_src.Decrease();
|
||||
m_ref_decreased = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
size_t MemFile::fread(char *ptr, size_t size, size_t nmemb) const
|
||||
{
|
||||
size_t p = m_read_ptr % BLOCKSIZE;
|
||||
size_t sz = size * nmemb;
|
||||
size_t available = m_write_ptr - m_read_ptr;
|
||||
if (sz > available) // read beyond eof
|
||||
{
|
||||
sz = available;
|
||||
m_b_read_caused_eof = true;
|
||||
}
|
||||
if (!sz)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (p + sz < BLOCKSIZE)
|
||||
{
|
||||
memcpy(ptr, m_current_read -> data + p, sz);
|
||||
m_read_ptr += sz;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t sz1 = BLOCKSIZE - p;
|
||||
size_t sz2 = sz - sz1;
|
||||
memcpy(ptr, m_current_read -> data + p, sz1);
|
||||
m_read_ptr += sz1;
|
||||
while (sz2 > BLOCKSIZE)
|
||||
{
|
||||
if (m_current_read -> next)
|
||||
{
|
||||
m_current_read = m_current_read -> next;
|
||||
memcpy(ptr + sz1, m_current_read -> data, BLOCKSIZE);
|
||||
m_read_ptr += BLOCKSIZE;
|
||||
sz1 += BLOCKSIZE;
|
||||
sz2 -= BLOCKSIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return sz1;
|
||||
}
|
||||
}
|
||||
if (m_current_read -> next)
|
||||
{
|
||||
m_current_read = m_current_read -> next;
|
||||
memcpy(ptr + sz1, m_current_read -> data, sz2);
|
||||
m_read_ptr += sz2;
|
||||
}
|
||||
else
|
||||
{
|
||||
return sz1;
|
||||
}
|
||||
}
|
||||
return sz;
|
||||
}
|
||||
|
||||
|
||||
size_t MemFile::fwrite(const char *ptr, size_t size, size_t nmemb)
|
||||
{
|
||||
size_t p = m_write_ptr % BLOCKSIZE;
|
||||
int nr = (int)m_write_ptr / BLOCKSIZE;
|
||||
size_t sz = size * nmemb;
|
||||
if (m_current_write_nr < nr)
|
||||
{
|
||||
block_t *next = new block_t;
|
||||
m_current_write -> next = next;
|
||||
m_current_write = next;
|
||||
m_current_write_nr++;
|
||||
}
|
||||
if (p + sz <= BLOCKSIZE)
|
||||
{
|
||||
memcpy(m_current_write -> data + p, ptr, sz);
|
||||
m_write_ptr += sz;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t sz1 = BLOCKSIZE - p; // size left
|
||||
size_t sz2 = sz - sz1;
|
||||
memcpy(m_current_write -> data + p, ptr, sz1);
|
||||
m_write_ptr += sz1;
|
||||
while (sz2 > BLOCKSIZE)
|
||||
{
|
||||
if (m_current_write -> next)
|
||||
{
|
||||
m_current_write = m_current_write -> next;
|
||||
m_current_write_nr++;
|
||||
}
|
||||
else
|
||||
{
|
||||
block_t *next = new block_t;
|
||||
m_current_write -> next = next;
|
||||
m_current_write = next;
|
||||
m_current_write_nr++;
|
||||
}
|
||||
memcpy(m_current_write -> data, ptr + sz1, BLOCKSIZE);
|
||||
m_write_ptr += BLOCKSIZE;
|
||||
sz1 += BLOCKSIZE;
|
||||
sz2 -= BLOCKSIZE;
|
||||
}
|
||||
if (m_current_write -> next)
|
||||
{
|
||||
m_current_write = m_current_write -> next;
|
||||
m_current_write_nr++;
|
||||
}
|
||||
else
|
||||
{
|
||||
block_t *next = new block_t;
|
||||
m_current_write -> next = next;
|
||||
m_current_write = next;
|
||||
m_current_write_nr++;
|
||||
}
|
||||
memcpy(m_current_write -> data, ptr + sz1, sz2);
|
||||
m_write_ptr += sz2;
|
||||
}
|
||||
return sz;
|
||||
}
|
||||
|
||||
|
||||
|
||||
char *MemFile::fgets(char *s, int size) const
|
||||
{
|
||||
int n = 0;
|
||||
while (n < size - 1 && !eof())
|
||||
{
|
||||
char c;
|
||||
size_t sz = fread(&c, 1, 1);
|
||||
if (sz)
|
||||
{
|
||||
if (c == 10)
|
||||
{
|
||||
s[n] = 0;
|
||||
return s;
|
||||
}
|
||||
s[n++] = c;
|
||||
}
|
||||
}
|
||||
s[n] = 0;
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
void MemFile::fprintf(const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char tmp[BLOCKSIZE];
|
||||
va_start(ap, format);
|
||||
vsnprintf(tmp, sizeof(tmp), format, ap);
|
||||
va_end(ap);
|
||||
fwrite(tmp, 1, strlen(tmp));
|
||||
}
|
||||
|
||||
|
||||
off_t MemFile::size() const
|
||||
{
|
||||
return (off_t)m_write_ptr;
|
||||
}
|
||||
|
||||
|
||||
bool MemFile::eof() const
|
||||
{
|
||||
return m_b_read_caused_eof; //(m_read_ptr < m_write_ptr) ? false : true;
|
||||
}
|
||||
|
||||
|
||||
void MemFile::reset_read() const
|
||||
{
|
||||
m_read_ptr = 0;
|
||||
m_current_read = m_base;
|
||||
}
|
||||
|
||||
|
||||
void MemFile::reset_write()
|
||||
{
|
||||
m_write_ptr = 0;
|
||||
m_current_write = m_base;
|
||||
m_current_write_nr = 0;
|
||||
}
|
||||
|
||||
|
||||
int MemFile::RefCount() const
|
||||
{
|
||||
return m_ref_count;
|
||||
}
|
||||
|
||||
|
||||
void MemFile::Increase()
|
||||
{
|
||||
++m_ref_count;
|
||||
}
|
||||
|
||||
|
||||
void MemFile::Decrease()
|
||||
{
|
||||
--m_ref_count;
|
||||
}
|
||||
|
||||
|
||||
const std::string& MemFile::Path() const
|
||||
{
|
||||
return m_path;
|
||||
}
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,118 +0,0 @@
|
||||
/** \file MemFile.h
|
||||
** \date 2005-04-25
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2004-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef _SOCKETS_MemFile_H
|
||||
#define _SOCKETS_MemFile_H
|
||||
|
||||
#include "sockets-config.h"
|
||||
#include <map>
|
||||
#include "File.h"
|
||||
#include "Mutex.h"
|
||||
|
||||
#define BLOCKSIZE 32768
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
|
||||
/** Implements a memory file.
|
||||
\ingroup file */
|
||||
class MemFile : public IFile
|
||||
{
|
||||
public:
|
||||
/** File block structure.
|
||||
\ingroup file */
|
||||
struct block_t {
|
||||
block_t() : next(NULL) {}
|
||||
struct block_t *next;
|
||||
char data[BLOCKSIZE];
|
||||
};
|
||||
public:
|
||||
/** Create temporary memory buffer, will be freed when object destructs */
|
||||
MemFile();
|
||||
/** Copy buffer from source, reset read ptr */
|
||||
MemFile(MemFile& );
|
||||
/** Read file and write to this, create non-temporary memory buffer from f.Path() */
|
||||
MemFile(File& f);
|
||||
~MemFile();
|
||||
|
||||
bool fopen(const std::string& path, const std::string& mode);
|
||||
void fclose() const;
|
||||
|
||||
size_t fread(char *ptr, size_t size, size_t nmemb) const;
|
||||
size_t fwrite(const char *ptr, size_t size, size_t nmemb);
|
||||
|
||||
char *fgets(char *s, int size) const;
|
||||
void fprintf(const char *format, ...);
|
||||
|
||||
off_t size() const;
|
||||
bool eof() const;
|
||||
|
||||
void reset_read() const;
|
||||
void reset_write();
|
||||
|
||||
/** Reference count when copy constructor is used */
|
||||
int RefCount() const;
|
||||
void Increase();
|
||||
void Decrease();
|
||||
|
||||
const std::string& Path() const;
|
||||
|
||||
private:
|
||||
MemFile& operator=(const MemFile& ) {
|
||||
return *this; // assignment operator
|
||||
}
|
||||
|
||||
MemFile& m_src;
|
||||
bool m_src_valid;
|
||||
block_t *m_base;
|
||||
mutable block_t *m_current_read;
|
||||
block_t *m_current_write;
|
||||
int m_current_write_nr;
|
||||
mutable size_t m_read_ptr;
|
||||
size_t m_write_ptr;
|
||||
mutable bool m_b_read_caused_eof;
|
||||
int m_ref_count;
|
||||
mutable bool m_ref_decreased;
|
||||
std::string m_path;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _SOCKETS_MemFile_H
|
||||
|
||||
@@ -1,83 +0,0 @@
|
||||
/** \file Mutex.cpp
|
||||
** \date 2004-10-30
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2004-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#include "Mutex.h"
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
|
||||
Mutex::Mutex()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
m_mutex = ::CreateMutex(NULL, FALSE, NULL);
|
||||
#else
|
||||
pthread_mutex_init(&m_mutex, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
Mutex::~Mutex()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
::CloseHandle(m_mutex);
|
||||
#else
|
||||
pthread_mutex_destroy(&m_mutex);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void Mutex::Lock() const
|
||||
{
|
||||
#ifdef _WIN32
|
||||
DWORD d = WaitForSingleObject(m_mutex, INFINITE);
|
||||
/// \todo check 'd' for result
|
||||
#else
|
||||
pthread_mutex_lock(&m_mutex);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void Mutex::Unlock() const
|
||||
{
|
||||
#ifdef _WIN32
|
||||
::ReleaseMutex(m_mutex);
|
||||
#else
|
||||
pthread_mutex_unlock(&m_mutex);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
/** \file Mutex.h
|
||||
** \date 2004-10-30
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2004-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef _SOCKETS_Mutex_H
|
||||
#define _SOCKETS_Mutex_H
|
||||
|
||||
#include "sockets-config.h"
|
||||
#ifndef _WIN32
|
||||
#include <pthread.h>
|
||||
#else
|
||||
#include "socket_include.h"
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#include "IMutex.h"
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
/** Mutex container class, used by Lock.
|
||||
\ingroup threading */
|
||||
class Mutex : public IMutex
|
||||
{
|
||||
public:
|
||||
Mutex();
|
||||
~Mutex();
|
||||
|
||||
virtual void Lock() const;
|
||||
virtual void Unlock() const;
|
||||
|
||||
private:
|
||||
#ifdef _WIN32
|
||||
HANDLE m_mutex;
|
||||
#else
|
||||
mutable pthread_mutex_t m_mutex;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
#endif // _SOCKETS_Mutex_H
|
||||
|
||||
Binary file not shown.
@@ -1,323 +0,0 @@
|
||||
/** \file Parse.cpp - parse a string
|
||||
**
|
||||
** Written: 1999-Feb-10 grymse@alhem.net
|
||||
**/
|
||||
|
||||
/*
|
||||
Copyright (C) 1999-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <cstring>
|
||||
|
||||
#include "Parse.h"
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
|
||||
/* implementation of class Parse */
|
||||
|
||||
Parse::Parse()
|
||||
:pa_the_str("")
|
||||
,pa_splits("")
|
||||
,pa_ord("")
|
||||
,pa_the_ptr(0)
|
||||
,pa_breakchar(0)
|
||||
,pa_enable(0)
|
||||
,pa_disable(0)
|
||||
,pa_nospace(0)
|
||||
,pa_quote(false)
|
||||
{
|
||||
}
|
||||
|
||||
Parse::Parse(const std::string&s)
|
||||
:pa_the_str(s)
|
||||
,pa_splits("")
|
||||
,pa_ord("")
|
||||
,pa_the_ptr(0)
|
||||
,pa_breakchar(0)
|
||||
,pa_enable(0)
|
||||
,pa_disable(0)
|
||||
,pa_nospace(0)
|
||||
,pa_quote(false)
|
||||
{
|
||||
}
|
||||
|
||||
Parse::Parse(const std::string&s,const std::string&sp)
|
||||
:pa_the_str(s)
|
||||
,pa_splits(sp)
|
||||
,pa_ord("")
|
||||
,pa_the_ptr(0)
|
||||
,pa_breakchar(0)
|
||||
,pa_enable(0)
|
||||
,pa_disable(0)
|
||||
,pa_nospace(0)
|
||||
,pa_quote(false)
|
||||
{
|
||||
}
|
||||
|
||||
Parse::Parse(const std::string&s,const std::string&sp,short nospace)
|
||||
:pa_the_str(s)
|
||||
,pa_splits(sp)
|
||||
,pa_ord("")
|
||||
,pa_the_ptr(0)
|
||||
,pa_breakchar(0)
|
||||
,pa_enable(0)
|
||||
,pa_disable(0)
|
||||
,pa_nospace(1)
|
||||
,pa_quote(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Parse::~Parse()
|
||||
{
|
||||
}
|
||||
|
||||
#define C ((pa_the_ptr<pa_the_str.size()) ? pa_the_str[pa_the_ptr] : 0)
|
||||
|
||||
short Parse::issplit(const char c)
|
||||
{
|
||||
for (size_t i = 0; i < pa_splits.size(); i++)
|
||||
if (pa_splits[i] == c)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Parse::getsplit()
|
||||
{
|
||||
size_t x;
|
||||
|
||||
if (C == '=')
|
||||
{
|
||||
x = pa_the_ptr++;
|
||||
} else
|
||||
{
|
||||
while (C && (issplit(C)))
|
||||
pa_the_ptr++;
|
||||
x = pa_the_ptr;
|
||||
while (C && !issplit(C) && C != '=')
|
||||
pa_the_ptr++;
|
||||
}
|
||||
if (x == pa_the_ptr && C == '=')
|
||||
pa_the_ptr++;
|
||||
pa_ord = (x < pa_the_str.size()) ? pa_the_str.substr(x,pa_the_ptr - x) : "";
|
||||
}
|
||||
|
||||
std::string Parse::getword()
|
||||
{
|
||||
size_t x;
|
||||
int disabled = 0;
|
||||
int quote = 0;
|
||||
int rem = 0;
|
||||
|
||||
if (pa_nospace)
|
||||
{
|
||||
while (C && issplit(C))
|
||||
pa_the_ptr++;
|
||||
x = pa_the_ptr;
|
||||
while (C && !issplit(C) && (C != pa_breakchar || !pa_breakchar || disabled))
|
||||
{
|
||||
if (pa_breakchar && C == pa_disable)
|
||||
disabled = 1;
|
||||
if (pa_breakchar && C == pa_enable)
|
||||
disabled = 0;
|
||||
if (pa_quote && C == '"')
|
||||
quote = 1;
|
||||
pa_the_ptr++;
|
||||
while (quote && C && C != '"')
|
||||
{
|
||||
pa_the_ptr++;
|
||||
}
|
||||
if (pa_quote && C == '"')
|
||||
{
|
||||
pa_the_ptr++;
|
||||
}
|
||||
quote = 0;
|
||||
}
|
||||
} else
|
||||
{
|
||||
if (C == pa_breakchar && pa_breakchar)
|
||||
{
|
||||
x = pa_the_ptr++;
|
||||
rem = 1;
|
||||
} else
|
||||
{
|
||||
while (C && (C == ' ' || C == 9 || C == 13 || C == 10 || issplit(C)))
|
||||
pa_the_ptr++;
|
||||
x = pa_the_ptr;
|
||||
while (C && C != ' ' && C != 9 && C != 13 && C != 10 && !issplit(C) &&
|
||||
(C != pa_breakchar || !pa_breakchar || disabled))
|
||||
{
|
||||
if (pa_breakchar && C == pa_disable)
|
||||
disabled = 1;
|
||||
if (pa_breakchar && C == pa_enable)
|
||||
disabled = 0;
|
||||
if (pa_quote && C == '"')
|
||||
{
|
||||
quote = 1;
|
||||
pa_the_ptr++;
|
||||
while (quote && C && C != '"')
|
||||
{
|
||||
pa_the_ptr++;
|
||||
}
|
||||
if (pa_quote && C == '"')
|
||||
{
|
||||
pa_the_ptr++;
|
||||
}
|
||||
}
|
||||
else
|
||||
pa_the_ptr++;
|
||||
quote = 0;
|
||||
}
|
||||
pa_the_ptr++;
|
||||
rem = 1;
|
||||
}
|
||||
if (x == pa_the_ptr && C == pa_breakchar && pa_breakchar)
|
||||
pa_the_ptr++;
|
||||
}
|
||||
if (x < pa_the_str.size())
|
||||
{
|
||||
pa_ord = pa_the_str.substr(x,pa_the_ptr - x - rem);
|
||||
}
|
||||
else
|
||||
{
|
||||
pa_ord = "";
|
||||
}
|
||||
return pa_ord;
|
||||
}
|
||||
|
||||
void Parse::getword(std::string&s)
|
||||
{
|
||||
s = Parse::getword();
|
||||
}
|
||||
|
||||
void Parse::getsplit(std::string&s)
|
||||
{
|
||||
Parse::getsplit();
|
||||
s = pa_ord;
|
||||
}
|
||||
|
||||
void Parse::getword(std::string&s,std::string&fill,int l)
|
||||
{
|
||||
Parse::getword();
|
||||
s = "";
|
||||
while (s.size() + pa_ord.size() < (size_t)l)
|
||||
s += fill;
|
||||
s += pa_ord;
|
||||
}
|
||||
|
||||
std::string Parse::getrest()
|
||||
{
|
||||
std::string s;
|
||||
while (C && (C == ' ' || C == 9 || issplit(C)))
|
||||
pa_the_ptr++;
|
||||
s = (pa_the_ptr < pa_the_str.size()) ? pa_the_str.substr(pa_the_ptr) : "";
|
||||
return s;
|
||||
}
|
||||
|
||||
void Parse::getrest(std::string&s)
|
||||
{
|
||||
while (C && (C == ' ' || C == 9 || issplit(C)))
|
||||
pa_the_ptr++;
|
||||
s = (pa_the_ptr < pa_the_str.size()) ? pa_the_str.substr(pa_the_ptr) : "";
|
||||
}
|
||||
|
||||
long Parse::getvalue()
|
||||
{
|
||||
Parse::getword();
|
||||
return atol(pa_ord.c_str());
|
||||
}
|
||||
|
||||
void Parse::setbreak(const char c)
|
||||
{
|
||||
pa_breakchar = c;
|
||||
}
|
||||
|
||||
int Parse::getwordlen()
|
||||
{
|
||||
size_t x,y = pa_the_ptr,len;
|
||||
|
||||
if (C == pa_breakchar && pa_breakchar)
|
||||
{
|
||||
x = pa_the_ptr++;
|
||||
} else
|
||||
{
|
||||
while (C && (C == ' ' || C == 9 || C == 13 || C == 10 || issplit(C)))
|
||||
pa_the_ptr++;
|
||||
x = pa_the_ptr;
|
||||
while (C && C != ' ' && C != 9 && C != 13 && C != 10 && !issplit(C) && (C != pa_breakchar || !pa_breakchar))
|
||||
pa_the_ptr++;
|
||||
}
|
||||
if (x == pa_the_ptr && C == pa_breakchar && pa_breakchar)
|
||||
pa_the_ptr++;
|
||||
len = pa_the_ptr - x;
|
||||
pa_the_ptr = y;
|
||||
return (int)len;
|
||||
}
|
||||
|
||||
int Parse::getrestlen()
|
||||
{
|
||||
size_t y = pa_the_ptr;
|
||||
size_t len;
|
||||
|
||||
while (C && (C == ' ' || C == 9 || issplit(C)))
|
||||
pa_the_ptr++;
|
||||
len = strlen(pa_the_str.c_str() + pa_the_ptr);
|
||||
pa_the_ptr = y;
|
||||
return (int)len;
|
||||
}
|
||||
|
||||
void Parse::getline()
|
||||
{
|
||||
size_t x;
|
||||
|
||||
x = pa_the_ptr;
|
||||
while (C && C != 13 && C != 10)
|
||||
pa_the_ptr++;
|
||||
pa_ord = (x < pa_the_str.size()) ? pa_the_str.substr(x,pa_the_ptr - x) : "";
|
||||
if (C == 13)
|
||||
pa_the_ptr++;
|
||||
if (C == 10)
|
||||
pa_the_ptr++;
|
||||
}
|
||||
|
||||
void Parse::getline(std::string&s)
|
||||
{
|
||||
getline();
|
||||
s = pa_ord;
|
||||
}
|
||||
|
||||
/* end of implementation of class Parse */
|
||||
/***************************************************/
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,108 +0,0 @@
|
||||
/** \file Parse.h - parse a string
|
||||
**
|
||||
** Written: 1999-Feb-10 grymse@alhem.net
|
||||
**/
|
||||
|
||||
/*
|
||||
Copyright (C) 1999-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef _SOCKETS_Parse_H
|
||||
#define _SOCKETS_Parse_H
|
||||
|
||||
#include "sockets-config.h"
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4514)
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
|
||||
/***************************************************/
|
||||
/* interface of class Parse */
|
||||
|
||||
/** Splits a string whatever way you want.
|
||||
\ingroup util */
|
||||
class Parse
|
||||
{
|
||||
public:
|
||||
Parse();
|
||||
Parse(const std::string&);
|
||||
Parse(const std::string&,const std::string&);
|
||||
Parse(const std::string&,const std::string&,short);
|
||||
~Parse();
|
||||
short issplit(const char);
|
||||
void getsplit();
|
||||
void getsplit(std::string&);
|
||||
std::string getword();
|
||||
void getword(std::string&);
|
||||
void getword(std::string&,std::string&,int);
|
||||
std::string getrest();
|
||||
void getrest(std::string&);
|
||||
long getvalue();
|
||||
void setbreak(const char);
|
||||
int getwordlen();
|
||||
int getrestlen();
|
||||
void enablebreak(const char c) {
|
||||
pa_enable = c;
|
||||
}
|
||||
void disablebreak(const char c) {
|
||||
pa_disable = c;
|
||||
}
|
||||
void getline();
|
||||
void getline(std::string&);
|
||||
size_t getptr() {
|
||||
return pa_the_ptr;
|
||||
}
|
||||
void EnableQuote(bool b) {
|
||||
pa_quote = b;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string pa_the_str;
|
||||
std::string pa_splits;
|
||||
std::string pa_ord;
|
||||
size_t pa_the_ptr;
|
||||
char pa_breakchar;
|
||||
char pa_enable;
|
||||
char pa_disable;
|
||||
short pa_nospace;
|
||||
bool pa_quote;
|
||||
};
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _SOCKETS_Parse_H
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
http://www.alhem.net/Sockets/
|
||||
|
||||
C++ Sockets Library :: installation instructions
|
||||
|
||||
|
||||
Unix (and Cygwin/Mingw on windows)
|
||||
==================================
|
||||
|
||||
1. Change the 'PLATFORM =' line in Makefile
|
||||
|
||||
Possible values are
|
||||
linux-x86-32
|
||||
win32-cygwin
|
||||
solaris9-sparc-64
|
||||
macosx
|
||||
solaris8
|
||||
|
||||
2. If you want to use ssl encrypted socket communication, the library
|
||||
has support for the third-party library openssl. If necessary, add
|
||||
the following include directory to Makefile:
|
||||
|
||||
INCLUDE = -I<path to openssl>/include
|
||||
|
||||
The openssl include directory contains only one directory named
|
||||
'openssl', in which all header files can be found.
|
||||
|
||||
OpenSSL support is enabled by default.
|
||||
|
||||
If you don't need encrypted communications, make sure to comment
|
||||
out this line in the file 'sockets-config.h':
|
||||
|
||||
#define HAVE_OPENSSL
|
||||
|
||||
3. If you really need thread-safe dns lookups, and your operating has
|
||||
support for *addrinfo and *nameinfo function calls, make sure this
|
||||
line in 'sockets-config.h' is commented:
|
||||
|
||||
#define NO_GETADDRINFO
|
||||
|
||||
By default, dns lookups using getaddrinfo/getnameinfo is disabled.
|
||||
|
||||
4. If your operating system supports SCTP, there might be a slight
|
||||
chance the sctp code in the library works. Uncomment this line in
|
||||
'sockets-config.h' to try:
|
||||
|
||||
//#define USE_SCTP
|
||||
|
||||
5. If you need IPv6 support, uncomment this line in
|
||||
'sockets-config.h':
|
||||
|
||||
//#define ENABLE_IPV6
|
||||
|
||||
6. Type 'make'
|
||||
|
||||
7. If all builds ok, you'll find the static library file 'libSockets.a'
|
||||
in the build directory.
|
||||
|
||||
|
||||
When compiling the application, any flags used when compiling the library
|
||||
also needs to be present when including the library .h files. All flags
|
||||
can be retrieved using the 'Sockets-config' executable. Add something like
|
||||
this in your Makefile:
|
||||
|
||||
CFLAGS += `Sockets-config`
|
||||
CPPFLAGS += `Sockets-config`
|
||||
|
||||
When linking an application using the library, make sure the object and
|
||||
library files are in correct order on your link command line:
|
||||
|
||||
First: Application object files
|
||||
2nd: -lSockets
|
||||
3rd: openssl libraries
|
||||
Finally: Everything else, ending with -lpthread
|
||||
|
||||
|
||||
windows
|
||||
=======
|
||||
|
||||
Project files for various IDE's can be found here:
|
||||
|
||||
Project/ Visual studio 6.0
|
||||
Project.net/ Visual studio .NET
|
||||
DevCpp/ Dev C++
|
||||
|
||||
Please see steps 2-5 above for some details on configuring the library.
|
||||
|
||||
When linking on cygwin/mingw, add the following libraries:
|
||||
-lwsock32
|
||||
-lws2_32
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
MAC notes
|
||||
---------
|
||||
|
||||
The file OSX.zip contains xcode project files for an older version of the library.
|
||||
|
||||
Find uuid.h (if missing) here:
|
||||
http://www.die.net/doc/linux/include/uuid/uuid.h
|
||||
This used to be a problem, but isn't any more afaik.
|
||||
|
||||
@@ -1,99 +0,0 @@
|
||||
/** \file ResolvServer.cpp
|
||||
** \date 2005-03-24
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2004-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4786)
|
||||
#endif
|
||||
#include "ResolvServer.h"
|
||||
#ifdef ENABLE_RESOLVER
|
||||
#include "StdoutLog.h"
|
||||
#include "ListenSocket.h"
|
||||
#include "ResolvSocket.h"
|
||||
#include "SocketHandler.h"
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
|
||||
ResolvServer::ResolvServer(port_t port)
|
||||
:Thread()
|
||||
,m_quit(false)
|
||||
,m_port(port)
|
||||
,m_ready(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ResolvServer::~ResolvServer()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void ResolvServer::Run()
|
||||
{
|
||||
// StdoutLog log;
|
||||
SocketHandler h;
|
||||
ListenSocket<ResolvSocket> l(h);
|
||||
|
||||
if (l.Bind("127.0.0.1", m_port))
|
||||
{
|
||||
return;
|
||||
}
|
||||
h.Add(&l);
|
||||
|
||||
m_ready = true;
|
||||
while (!m_quit && IsRunning() )
|
||||
{
|
||||
h.Select(0, 500000);
|
||||
}
|
||||
SetRunning(false);
|
||||
}
|
||||
|
||||
|
||||
void ResolvServer::Quit()
|
||||
{
|
||||
m_quit = true;
|
||||
}
|
||||
|
||||
|
||||
bool ResolvServer::Ready()
|
||||
{
|
||||
return m_ready;
|
||||
}
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // ENABLE_RESOLVER
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
/** \file ResolvServer.h
|
||||
** \date 2005-03-24
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2004-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef _SOCKETS_ResolvServer_H
|
||||
#define _SOCKETS_ResolvServer_H
|
||||
#include "sockets-config.h"
|
||||
#ifdef ENABLE_RESOLVER
|
||||
#include "socket_include.h"
|
||||
#include "Thread.h"
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
/** \defgroup async Asynchronous DNS */
|
||||
/** Async DNS resolver thread.
|
||||
\ingroup async */
|
||||
class ResolvServer : public Thread
|
||||
{
|
||||
public:
|
||||
ResolvServer(port_t);
|
||||
~ResolvServer();
|
||||
|
||||
void Run();
|
||||
void Quit();
|
||||
|
||||
bool Ready();
|
||||
|
||||
private:
|
||||
ResolvServer(const ResolvServer& ) {} // copy constructor
|
||||
ResolvServer& operator=(const ResolvServer& ) {
|
||||
return *this; // assignment operator
|
||||
}
|
||||
|
||||
bool m_quit;
|
||||
port_t m_port;
|
||||
bool m_ready;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // ENABLE_RESOLVER
|
||||
#endif // _SOCKETS_ResolvServer_H
|
||||
|
||||
@@ -1,442 +0,0 @@
|
||||
/** \file ResolvSocket.cpp
|
||||
** \date 2005-03-24
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2004-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifdef _WIN32
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4786)
|
||||
#pragma warning(disable:4503)
|
||||
#endif
|
||||
#else
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
#include "ResolvSocket.h"
|
||||
#ifdef ENABLE_RESOLVER
|
||||
#include "Utility.h"
|
||||
#include "Parse.h"
|
||||
#include "ISocketHandler.h"
|
||||
#include "Lock.h"
|
||||
#include "Mutex.h"
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define DEB(x) x
|
||||
#else
|
||||
#define DEB(x)
|
||||
#endif
|
||||
|
||||
|
||||
// static
|
||||
ResolvSocket::cache_t ResolvSocket::m_cache;
|
||||
ResolvSocket::timeout_t ResolvSocket::m_cache_to;
|
||||
Mutex ResolvSocket::m_cache_mutex;
|
||||
|
||||
|
||||
ResolvSocket::ResolvSocket(ISocketHandler& h)
|
||||
:TcpSocket(h)
|
||||
,m_bServer(false)
|
||||
,m_parent(NULL)
|
||||
,m_parent_uid(0)
|
||||
#ifdef ENABLE_IPV6
|
||||
,m_resolve_ipv6(false)
|
||||
#endif
|
||||
,m_cached(false)
|
||||
{
|
||||
SetLineProtocol();
|
||||
}
|
||||
|
||||
|
||||
ResolvSocket::ResolvSocket(ISocketHandler& h, Socket *parent, const std::string& host, port_t port, bool ipv6)
|
||||
:TcpSocket(h)
|
||||
,m_bServer(false)
|
||||
,m_parent(parent)
|
||||
,m_parent_uid(parent -> UniqueIdentifier())
|
||||
,m_resolv_host(host)
|
||||
,m_resolv_port(port)
|
||||
#ifdef ENABLE_IPV6
|
||||
,m_resolve_ipv6(ipv6)
|
||||
#endif
|
||||
,m_cached(false)
|
||||
{
|
||||
SetLineProtocol();
|
||||
}
|
||||
|
||||
|
||||
ResolvSocket::ResolvSocket(ISocketHandler& h, Socket *parent, ipaddr_t a)
|
||||
:TcpSocket(h)
|
||||
,m_bServer(false)
|
||||
,m_parent(parent)
|
||||
,m_parent_uid(parent -> UniqueIdentifier())
|
||||
,m_resolv_port(0)
|
||||
,m_resolv_address(a)
|
||||
#ifdef ENABLE_IPV6
|
||||
,m_resolve_ipv6(false)
|
||||
#endif
|
||||
,m_cached(false)
|
||||
{
|
||||
SetLineProtocol();
|
||||
}
|
||||
|
||||
|
||||
#ifdef ENABLE_IPV6
|
||||
ResolvSocket::ResolvSocket(ISocketHandler& h, Socket *parent, in6_addr& a)
|
||||
:TcpSocket(h)
|
||||
,m_bServer(false)
|
||||
,m_parent(parent)
|
||||
,m_parent_uid(parent -> UniqueIdentifier())
|
||||
,m_resolv_port(0)
|
||||
,m_resolve_ipv6(true)
|
||||
,m_resolv_address6(a)
|
||||
,m_cached(false)
|
||||
{
|
||||
SetLineProtocol();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
ResolvSocket::~ResolvSocket()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void ResolvSocket::OnLine(const std::string& line)
|
||||
{
|
||||
Parse pa(line, ":");
|
||||
if (m_bServer)
|
||||
{
|
||||
m_query = pa.getword();
|
||||
m_data = pa.getrest();
|
||||
DEB( fprintf(stderr, " *** ResolvSocket server; query=%s, data=%s\n", m_query.c_str(), m_data.c_str());)
|
||||
// %! check cache
|
||||
{
|
||||
Lock lock(m_cache_mutex);
|
||||
if (m_cache[m_query].find(m_data) != m_cache[m_query].end())
|
||||
{
|
||||
if (time(NULL) - m_cache_to[m_query][m_data] < 3600) // ttl
|
||||
{
|
||||
std::string result = m_cache[m_query][m_data];
|
||||
DEB(fprintf(stderr, " *** Returning cache for [%s][%s] = '%s'\n", m_query.c_str(), m_data.c_str(), result.c_str());)
|
||||
Send("Cached\n");
|
||||
if (!result.size()) /* failed */
|
||||
{
|
||||
Send("Failed\n\n");
|
||||
SetCloseAndDelete();
|
||||
return;
|
||||
}
|
||||
else
|
||||
if (m_query == "gethostbyname")
|
||||
{
|
||||
Send("A: " + result + "\n\n");
|
||||
SetCloseAndDelete();
|
||||
return;
|
||||
}
|
||||
else
|
||||
#ifdef ENABLE_IPV6
|
||||
#ifdef IPPROTO_IPV6
|
||||
if (m_query == "gethostbyname2")
|
||||
{
|
||||
Send("AAAA: " + result + "\n\n");
|
||||
SetCloseAndDelete();
|
||||
return;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#endif
|
||||
if (m_query == "gethostbyaddr")
|
||||
{
|
||||
Send("Name: " + result + "\n\n");
|
||||
SetCloseAndDelete();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!Detach()) // detach failed?
|
||||
{
|
||||
SetCloseAndDelete();
|
||||
}
|
||||
return;
|
||||
}
|
||||
std::string key = pa.getword();
|
||||
std::string value = pa.getrest();
|
||||
DEB( fprintf(stderr, " *** ResolvSocket response; %s: %s\n", key.c_str(), value.c_str());)
|
||||
|
||||
if (key == "Cached")
|
||||
{
|
||||
m_cached = true;
|
||||
}
|
||||
else
|
||||
if (key == "Failed" && m_parent)
|
||||
{
|
||||
DEB( fprintf(stderr, " ************ Resolve failed\n");)
|
||||
if (Handler().Resolving(m_parent) || Handler().Valid(m_parent_uid))
|
||||
{
|
||||
m_parent -> OnResolveFailed(m_resolv_id);
|
||||
}
|
||||
// update cache
|
||||
if (!m_cached)
|
||||
{
|
||||
Lock lock(m_cache_mutex);
|
||||
DEB(fprintf(stderr, " *** Update cache for [%s][%s] = '%s'\n", m_query.c_str(), m_data.c_str(), value.c_str());)
|
||||
m_cache[m_query][m_data] = value;
|
||||
m_cache_to[m_query][m_data] = time(NULL);
|
||||
}
|
||||
m_parent = NULL;
|
||||
}
|
||||
else
|
||||
if (key == "Name" && !m_resolv_host.size() && m_parent)
|
||||
{
|
||||
if (Handler().Resolving(m_parent) || Handler().Valid(m_parent_uid))
|
||||
{
|
||||
m_parent -> OnReverseResolved(m_resolv_id, value);
|
||||
}
|
||||
// update cache
|
||||
if (!m_cached)
|
||||
{
|
||||
Lock lock(m_cache_mutex);
|
||||
DEB(fprintf(stderr, " *** Update cache for [%s][%s] = '%s'\n", m_query.c_str(), m_data.c_str(), value.c_str());)
|
||||
m_cache[m_query][m_data] = value;
|
||||
m_cache_to[m_query][m_data] = time(NULL);
|
||||
}
|
||||
m_parent = NULL;
|
||||
}
|
||||
else
|
||||
if (key == "A" && m_parent)
|
||||
{
|
||||
if (Handler().Resolving(m_parent) || Handler().Valid(m_parent_uid))
|
||||
{
|
||||
ipaddr_t l;
|
||||
Utility::u2ip(value, l); // ip2ipaddr_t
|
||||
m_parent -> OnResolved(m_resolv_id, l, m_resolv_port);
|
||||
}
|
||||
// update cache
|
||||
if (!m_cached)
|
||||
{
|
||||
Lock lock(m_cache_mutex);
|
||||
DEB(fprintf(stderr, " *** Update cache for [%s][%s] = '%s'\n", m_query.c_str(), m_data.c_str(), value.c_str());)
|
||||
m_cache[m_query][m_data] = value;
|
||||
m_cache_to[m_query][m_data] = time(NULL);
|
||||
}
|
||||
m_parent = NULL; // always use first ip in case there are several
|
||||
}
|
||||
#ifdef ENABLE_IPV6
|
||||
#ifdef IPPROTO_IPV6
|
||||
else
|
||||
if (key == "AAAA" && m_parent)
|
||||
{
|
||||
if (Handler().Resolving(m_parent) || Handler().Valid(m_parent_uid))
|
||||
{
|
||||
in6_addr a;
|
||||
Utility::u2ip(value, a);
|
||||
m_parent -> OnResolved(m_resolv_id, a, m_resolv_port);
|
||||
}
|
||||
// update cache
|
||||
if (!m_cached)
|
||||
{
|
||||
Lock lock(m_cache_mutex);
|
||||
DEB(fprintf(stderr, " *** Update cache for [%s][%s] = '%s'\n", m_query.c_str(), m_data.c_str(), value.c_str());)
|
||||
m_cache[m_query][m_data] = value;
|
||||
m_cache_to[m_query][m_data] = time(NULL);
|
||||
}
|
||||
m_parent = NULL;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void ResolvSocket::OnDetached()
|
||||
{
|
||||
DEB( fprintf(stderr, " *** ResolvSocket::OnDetached(); query=%s, data=%s\n", m_query.c_str(), m_data.c_str());)
|
||||
if (m_query == "gethostbyname")
|
||||
{
|
||||
struct sockaddr_in sa;
|
||||
if (Utility::u2ip(m_data, sa))
|
||||
{
|
||||
std::string ip;
|
||||
Utility::l2ip(sa.sin_addr, ip);
|
||||
Send("A: " + ip + "\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
Send("Failed\n");
|
||||
}
|
||||
Send("\n");
|
||||
}
|
||||
else
|
||||
#ifdef ENABLE_IPV6
|
||||
#ifdef IPPROTO_IPV6
|
||||
if (m_query == "gethostbyname2")
|
||||
{
|
||||
struct sockaddr_in6 sa;
|
||||
if (Utility::u2ip(m_data, sa))
|
||||
{
|
||||
std::string ip;
|
||||
Utility::l2ip(sa.sin6_addr, ip);
|
||||
Send("AAAA: " + ip + "\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
Send("Failed\n");
|
||||
}
|
||||
Send("\n");
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#endif
|
||||
if (m_query == "gethostbyaddr")
|
||||
{
|
||||
if (Utility::isipv4( m_data ))
|
||||
{
|
||||
struct sockaddr_in sa;
|
||||
if (!Utility::u2ip(m_data, sa, AI_NUMERICHOST))
|
||||
{
|
||||
Send("Failed: convert to sockaddr_in failed\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string name;
|
||||
if (!Utility::reverse( (struct sockaddr *)&sa, sizeof(sa), name))
|
||||
{
|
||||
Send("Failed: ipv4 reverse lookup of " + m_data + "\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
Send("Name: " + name + "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
#ifdef ENABLE_IPV6
|
||||
#ifdef IPPROTO_IPV6
|
||||
if (Utility::isipv6( m_data ))
|
||||
{
|
||||
struct sockaddr_in6 sa;
|
||||
if (!Utility::u2ip(m_data, sa, AI_NUMERICHOST))
|
||||
{
|
||||
Send("Failed: convert to sockaddr_in6 failed\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string name;
|
||||
if (!Utility::reverse( (struct sockaddr *)&sa, sizeof(sa), name))
|
||||
{
|
||||
Send("Failed: ipv6 reverse lookup of " + m_data + "\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
Send("Name: " + name + "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#endif
|
||||
{
|
||||
Send("Failed: malformed address\n");
|
||||
}
|
||||
Send("\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string msg = "Unknown query type: " + m_query;
|
||||
Handler().LogError(this, "OnDetached", 0, msg);
|
||||
Send("Unknown\n\n");
|
||||
}
|
||||
SetCloseAndDelete();
|
||||
}
|
||||
|
||||
|
||||
void ResolvSocket::OnConnect()
|
||||
{
|
||||
if (m_resolv_host.size())
|
||||
{
|
||||
#ifdef ENABLE_IPV6
|
||||
std::string msg = (m_resolve_ipv6 ? "gethostbyname2 " : "gethostbyname ") + m_resolv_host + "\n";
|
||||
m_query = m_resolve_ipv6 ? "gethostbyname2" : "gethostbyname";
|
||||
#else
|
||||
std::string msg = "gethostbyname " + m_resolv_host + "\n";
|
||||
m_query = "gethostbyname";
|
||||
#endif
|
||||
m_data = m_resolv_host;
|
||||
Send( msg );
|
||||
return;
|
||||
}
|
||||
#ifdef ENABLE_IPV6
|
||||
if (m_resolve_ipv6)
|
||||
{
|
||||
std::string tmp;
|
||||
Utility::l2ip(m_resolv_address6, tmp);
|
||||
m_query = "gethostbyaddr";
|
||||
m_data = tmp;
|
||||
std::string msg = "gethostbyaddr " + tmp + "\n";
|
||||
Send( msg );
|
||||
}
|
||||
#endif
|
||||
std::string tmp;
|
||||
Utility::l2ip(m_resolv_address, tmp);
|
||||
m_query = "gethostbyaddr";
|
||||
m_data = tmp;
|
||||
std::string msg = "gethostbyaddr " + tmp + "\n";
|
||||
Send( msg );
|
||||
}
|
||||
|
||||
|
||||
void ResolvSocket::OnDelete()
|
||||
{
|
||||
if (m_parent)
|
||||
{
|
||||
if (Handler().Resolving(m_parent) || Handler().Valid(m_parent_uid))
|
||||
{
|
||||
m_parent -> OnResolveFailed(m_resolv_id);
|
||||
}
|
||||
// update cache
|
||||
if (!m_cached)
|
||||
{
|
||||
Lock lock(m_cache_mutex);
|
||||
std::string value;
|
||||
DEB(fprintf(stderr, " *** Update cache for [%s][%s] = '%s'\n", m_query.c_str(), m_data.c_str(), value.c_str());)
|
||||
m_cache[m_query][m_data] = value;
|
||||
m_cache_to[m_query][m_data] = time(NULL);
|
||||
}
|
||||
m_parent = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // ENABLE_RESOLVER
|
||||
|
||||
@@ -1,120 +0,0 @@
|
||||
/** \file ResolvSocket.h
|
||||
** \date 2005-03-24
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2004-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef _SOCKETS_ResolvSocket_H
|
||||
#define _SOCKETS_ResolvSocket_H
|
||||
#include "sockets-config.h"
|
||||
#ifdef ENABLE_RESOLVER
|
||||
#include "TcpSocket.h"
|
||||
#include <map>
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
class Mutex;
|
||||
|
||||
/** Async DNS resolver socket.
|
||||
\ingroup async */
|
||||
class ResolvSocket : public TcpSocket
|
||||
{
|
||||
typedef std::map<std::string, /* type */
|
||||
std::map<std::string, std::string> > cache_t; /* host, result */
|
||||
typedef std::map<std::string, /* type */
|
||||
std::map<std::string, time_t> > timeout_t; /* host, time */
|
||||
|
||||
public:
|
||||
ResolvSocket(ISocketHandler&);
|
||||
ResolvSocket(ISocketHandler&, Socket *parent, const std::string& host, port_t port, bool ipv6 = false);
|
||||
ResolvSocket(ISocketHandler&, Socket *parent, ipaddr_t);
|
||||
#ifdef ENABLE_IPV6
|
||||
ResolvSocket(ISocketHandler&, Socket *parent, in6_addr&);
|
||||
#endif
|
||||
~ResolvSocket();
|
||||
|
||||
void OnAccept() {
|
||||
m_bServer = true;
|
||||
}
|
||||
void OnLine(const std::string& line);
|
||||
void OnDetached();
|
||||
void OnDelete();
|
||||
|
||||
void SetId(int x) {
|
||||
m_resolv_id = x;
|
||||
}
|
||||
int GetId() {
|
||||
return m_resolv_id;
|
||||
}
|
||||
|
||||
void OnConnect();
|
||||
|
||||
#ifdef ENABLE_IPV6
|
||||
void SetResolveIpv6(bool x = true) {
|
||||
m_resolve_ipv6 = x;
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
ResolvSocket(const ResolvSocket& s) : TcpSocket(s) {} // copy constructor
|
||||
ResolvSocket& operator=(const ResolvSocket& ) {
|
||||
return *this; // assignment operator
|
||||
}
|
||||
|
||||
std::string m_query;
|
||||
std::string m_data;
|
||||
bool m_bServer;
|
||||
Socket *m_parent;
|
||||
socketuid_t m_parent_uid;
|
||||
int m_resolv_id;
|
||||
std::string m_resolv_host;
|
||||
port_t m_resolv_port;
|
||||
ipaddr_t m_resolv_address;
|
||||
#ifdef ENABLE_IPV6
|
||||
bool m_resolve_ipv6;
|
||||
in6_addr m_resolv_address6;
|
||||
#endif
|
||||
static cache_t m_cache;
|
||||
static timeout_t m_cache_to;
|
||||
static Mutex m_cache_mutex;
|
||||
bool m_cached;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // ENABLE_RESOLVER
|
||||
#endif // _SOCKETS_ResolvSocket_H
|
||||
|
||||
@@ -1,181 +0,0 @@
|
||||
/**
|
||||
** \file SSLInitializer.cpp
|
||||
** \date 2007-04-30
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2007-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifdef _WIN32
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4786)
|
||||
#endif
|
||||
#include <io.h>
|
||||
#endif
|
||||
#include "SSLInitializer.h"
|
||||
#ifdef HAVE_OPENSSL
|
||||
#include <map>
|
||||
#include "Utility.h"
|
||||
#include <openssl/rand.h>
|
||||
#include "Lock.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define DEB(x) x
|
||||
#else
|
||||
#define DEB(x)
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
|
||||
std::map<int, IMutex *> *SSLInitializer::m_mmap = NULL;
|
||||
Mutex *SSLInitializer::m_mmap_mutex = NULL;
|
||||
|
||||
|
||||
SSLInitializer::SSLInitializer()
|
||||
{
|
||||
DEB( fprintf(stderr, "SSLInitializer()\n");)
|
||||
|
||||
bio_err = NULL;
|
||||
m_rand_size = 1024;
|
||||
|
||||
/* An error write context */
|
||||
bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
|
||||
|
||||
/* Global system initialization*/
|
||||
SSL_library_init();
|
||||
SSL_load_error_strings();
|
||||
OpenSSL_add_all_algorithms();
|
||||
CRYPTO_set_locking_callback( SSL_locking_function );
|
||||
CRYPTO_set_id_callback( SSL_id_function );
|
||||
|
||||
std::string randfile = Utility::GetEnv("RANDFILE");
|
||||
std::string home = Utility::GetEnv("HOME");
|
||||
if (randfile.empty() && home.empty())
|
||||
{
|
||||
std::string homepath = Utility::GetEnv("HOMEPATH");
|
||||
if (!homepath.empty())
|
||||
{
|
||||
Utility::SetEnv("HOME", homepath);
|
||||
}
|
||||
}
|
||||
char path[512];
|
||||
*path = 0;
|
||||
RAND_file_name(path, 512);
|
||||
if (*path)
|
||||
{
|
||||
m_rand_file = path;
|
||||
m_rand_size = 1024;
|
||||
RAND_write_file(path);
|
||||
}
|
||||
else
|
||||
{
|
||||
DEB( fprintf(stderr, "SSLInitializer: no random file generated\n");)
|
||||
}
|
||||
|
||||
/* Load randomness */
|
||||
if (!m_rand_file.size() || !RAND_load_file(m_rand_file.c_str(), m_rand_size))
|
||||
{
|
||||
DEB( fprintf(stderr, "SSLInitializer: PRNG not initialized\n");)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
SSLInitializer::~SSLInitializer()
|
||||
{
|
||||
DEB( fprintf(stderr, "~SSLInitializer()\n");)
|
||||
DeleteRandFile();
|
||||
// %! delete mutexes
|
||||
}
|
||||
|
||||
|
||||
void SSLInitializer::DeleteRandFile()
|
||||
{
|
||||
if (m_rand_file.size())
|
||||
{
|
||||
#ifdef _WIN32
|
||||
_unlink(m_rand_file.c_str());
|
||||
#else
|
||||
unlink(m_rand_file.c_str());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SSLInitializer::SSL_locking_function(int mode, int n, const char *file, int line)
|
||||
{
|
||||
IMutex *mutex = NULL;
|
||||
{
|
||||
Lock lock(MMapMutex());
|
||||
if (MMap().find(n) == MMap().end())
|
||||
{
|
||||
MMap()[n] = new Mutex;
|
||||
}
|
||||
mutex = MMap()[n];
|
||||
}
|
||||
if (mode & CRYPTO_LOCK)
|
||||
{
|
||||
mutex -> Lock();
|
||||
}
|
||||
else
|
||||
{
|
||||
mutex -> Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
unsigned long SSLInitializer::SSL_id_function()
|
||||
{
|
||||
return Utility::ThreadID();
|
||||
}
|
||||
|
||||
|
||||
std::map<int, IMutex *>& SSLInitializer::MMap()
|
||||
{
|
||||
if (m_mmap == NULL)
|
||||
m_mmap = new std::map<int, IMutex *>();
|
||||
return *m_mmap;
|
||||
}
|
||||
|
||||
|
||||
Mutex& SSLInitializer::MMapMutex()
|
||||
{
|
||||
if (m_mmap_mutex == NULL)
|
||||
m_mmap_mutex = new Mutex();
|
||||
return *m_mmap_mutex;
|
||||
}
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
} // namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
#endif // HAVE_OPENSSL
|
||||
|
||||
@@ -1,97 +0,0 @@
|
||||
/**
|
||||
** \file SSLInitializer.h
|
||||
** \date 2007-04-30
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2007-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef __SOCKETS_SSLInitializer_H
|
||||
#define __SOCKETS_SSLInitializer_H
|
||||
#include "sockets-config.h"
|
||||
#ifdef HAVE_OPENSSL
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#endif
|
||||
#include <openssl/ssl.h>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include "Mutex.h"
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
|
||||
class SSLInitializer
|
||||
{
|
||||
public:
|
||||
/**
|
||||
init openssl
|
||||
bio_err
|
||||
create random file
|
||||
*/
|
||||
SSLInitializer();
|
||||
|
||||
/**
|
||||
remove random file
|
||||
*/
|
||||
~SSLInitializer();
|
||||
|
||||
void DeleteRandFile();
|
||||
|
||||
/** SSL; mutex locking function callback. */
|
||||
static void SSL_locking_function(int mode, int n, const char *file, int line);
|
||||
|
||||
/** Return thread id. */
|
||||
static unsigned long SSL_id_function();
|
||||
|
||||
BIO *bio_err;
|
||||
|
||||
private:
|
||||
std::string m_rand_file;
|
||||
long m_rand_size;
|
||||
static std::map<int, IMutex *> *m_mmap;
|
||||
static Mutex *m_mmap_mutex;
|
||||
|
||||
static std::map<int, IMutex *>& MMap();
|
||||
static Mutex& MMapMutex();
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
} // namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
#endif // HAVE_OPENSSL
|
||||
#endif // __SOCKETS_SSLInitializer_H
|
||||
|
||||
@@ -1,506 +0,0 @@
|
||||
/**
|
||||
** \file SctpSocket.cpp
|
||||
** \date 2006-09-04
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2007-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#include "SctpSocket.h"
|
||||
#ifdef USE_SCTP
|
||||
#include "Utility.h"
|
||||
#include "ISocketHandler.h"
|
||||
#include <errno.h>
|
||||
#include "Ipv4Address.h"
|
||||
#include "Ipv6Address.h"
|
||||
#ifdef ENABLE_EXCEPTIONS
|
||||
#include "Exception.h"
|
||||
#endif
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
|
||||
SctpSocket::SctpSocket(ISocketHandler& h,int type) : StreamSocket(h)
|
||||
,m_type(type)
|
||||
,m_buf(new char[SCTP_BUFSIZE_READ])
|
||||
{
|
||||
if (type != SOCK_STREAM && type != SOCK_SEQPACKET)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SctpSocket::~SctpSocket()
|
||||
{
|
||||
delete[] m_buf;
|
||||
}
|
||||
|
||||
|
||||
int SctpSocket::Bind(const std::string& a,port_t p)
|
||||
{
|
||||
#ifdef ENABLE_IPV6
|
||||
#ifdef IPPROTO_IPV6
|
||||
if (IsIpv6())
|
||||
{
|
||||
Ipv6Address ad(a, p);
|
||||
return Bind(ad);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
Ipv4Address ad(a, p);
|
||||
return Bind(ad);
|
||||
}
|
||||
|
||||
|
||||
int SctpSocket::Bind(SocketAddress& ad)
|
||||
{
|
||||
if (!ad.IsValid())
|
||||
{
|
||||
Handler().LogError(this, "SctpSocket", -1, "invalid address", LOG_LEVEL_ERROR);
|
||||
return -1;
|
||||
}
|
||||
if (GetSocket() == INVALID_SOCKET)
|
||||
{
|
||||
Attach(CreateSocket(ad.GetFamily(), m_type, "sctp"));
|
||||
}
|
||||
if (GetSocket() != INVALID_SOCKET)
|
||||
{
|
||||
int n = bind(GetSocket(), ad, ad);
|
||||
if (n == -1)
|
||||
{
|
||||
Handler().LogError(this, "SctpSocket", -1, "bind() failed", LOG_LEVEL_ERROR);
|
||||
#ifdef ENABLE_EXCEPTIONS
|
||||
throw Exception("bind() failed for SctpSocket, port: " + Utility::l2string(ad.GetPort()));
|
||||
#endif
|
||||
}
|
||||
return n;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int SctpSocket::AddAddress(const std::string& a,port_t p)
|
||||
{
|
||||
#ifdef ENABLE_IPV6
|
||||
#ifdef IPPROTO_IPV6
|
||||
if (IsIpv6())
|
||||
{
|
||||
Ipv6Address ad(a, p);
|
||||
return AddAddress(ad);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
Ipv4Address ad(a, p);
|
||||
return AddAddress(ad);
|
||||
}
|
||||
|
||||
|
||||
int SctpSocket::AddAddress(SocketAddress& ad)
|
||||
{
|
||||
if (!ad.IsValid())
|
||||
{
|
||||
Handler().LogError(this, "SctpSocket", -1, "invalid address", LOG_LEVEL_ERROR);
|
||||
return -1;
|
||||
}
|
||||
if (GetSocket() == INVALID_SOCKET)
|
||||
{
|
||||
Handler().LogError(this, "SctpSocket", -1, "AddAddress called with invalid file descriptor", LOG_LEVEL_ERROR);
|
||||
return -1;
|
||||
}
|
||||
int n = sctp_bindx(GetSocket(), ad, ad, SCTP_BINDX_ADD_ADDR);
|
||||
if (n == -1)
|
||||
{
|
||||
Handler().LogError(this, "SctpSocket", -1, "sctp_bindx() failed", LOG_LEVEL_ERROR);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
int SctpSocket::RemoveAddress(const std::string& a,port_t p)
|
||||
{
|
||||
#ifdef ENABLE_IPV6
|
||||
#ifdef IPPROTO_IPV6
|
||||
if (IsIpv6())
|
||||
{
|
||||
Ipv6Address ad(a, p);
|
||||
return RemoveAddress(ad);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
Ipv4Address ad(a, p);
|
||||
return RemoveAddress(ad);
|
||||
}
|
||||
|
||||
|
||||
int SctpSocket::RemoveAddress(SocketAddress& ad)
|
||||
{
|
||||
if (!ad.IsValid())
|
||||
{
|
||||
Handler().LogError(this, "SctpSocket", -1, "invalid address", LOG_LEVEL_ERROR);
|
||||
return -1;
|
||||
}
|
||||
if (GetSocket() == INVALID_SOCKET)
|
||||
{
|
||||
Handler().LogError(this, "SctpSocket", -1, "RemoveAddress called with invalid file descriptor", LOG_LEVEL_ERROR);
|
||||
return -1;
|
||||
}
|
||||
int n = sctp_bindx(GetSocket(), ad, ad, SCTP_BINDX_REM_ADDR);
|
||||
if (n == -1)
|
||||
{
|
||||
Handler().LogError(this, "SctpSocket", -1, "sctp_bindx() failed", LOG_LEVEL_ERROR);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
int SctpSocket::Open(const std::string& a,port_t p)
|
||||
{
|
||||
#ifdef ENABLE_IPV6
|
||||
#ifdef IPPROTO_IPV6
|
||||
if (IsIpv6())
|
||||
{
|
||||
Ipv6Address ad(a, p);
|
||||
return Open(ad);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
Ipv4Address ad(a, p);
|
||||
return Open(ad);
|
||||
}
|
||||
|
||||
|
||||
int SctpSocket::Open(SocketAddress& ad)
|
||||
{
|
||||
if (!ad.IsValid())
|
||||
{
|
||||
Handler().LogError(this, "SctpSocket", -1, "invalid address", LOG_LEVEL_ERROR);
|
||||
return -1;
|
||||
}
|
||||
if (GetSocket() == INVALID_SOCKET)
|
||||
{
|
||||
Attach(CreateSocket(ad.GetFamily(), m_type, "sctp"));
|
||||
}
|
||||
if (GetSocket() != INVALID_SOCKET)
|
||||
{
|
||||
if (!SetNonblocking(true))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
int n = connect(GetSocket(), ad, ad);
|
||||
if (n == -1)
|
||||
{
|
||||
// check error code that means a connect is in progress
|
||||
#ifdef _WIN32
|
||||
if (Errno == WSAEWOULDBLOCK)
|
||||
#else
|
||||
if (Errno == EINPROGRESS)
|
||||
#endif
|
||||
{
|
||||
Handler().LogError(this, "connect: connection pending", Errno, StrError(Errno), LOG_LEVEL_INFO);
|
||||
SetConnecting( true ); // this flag will control fd_set's
|
||||
}
|
||||
else
|
||||
{
|
||||
Handler().LogError(this, "SctpSocket", -1, "connect() failed", LOG_LEVEL_ERROR);
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
#ifndef SOLARIS
|
||||
int SctpSocket::AddConnection(const std::string& a,port_t p)
|
||||
{
|
||||
#ifdef ENABLE_IPV6
|
||||
#ifdef IPPROTO_IPV6
|
||||
if (IsIpv6())
|
||||
{
|
||||
Ipv6Address ad(a, p);
|
||||
return AddConnection(ad);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
Ipv4Address ad(a, p);
|
||||
return AddConnection(ad);
|
||||
}
|
||||
|
||||
|
||||
int SctpSocket::AddConnection(SocketAddress& ad)
|
||||
{
|
||||
if (!ad.IsValid())
|
||||
{
|
||||
Handler().LogError(this, "SctpSocket", -1, "invalid address", LOG_LEVEL_ERROR);
|
||||
return -1;
|
||||
}
|
||||
if (GetSocket() == INVALID_SOCKET)
|
||||
{
|
||||
Handler().LogError(this, "SctpSocket", -1, "AddConnection called with invalid file descriptor", LOG_LEVEL_ERROR);
|
||||
return -1;
|
||||
}
|
||||
int n = sctp_connectx(GetSocket(), ad, ad);
|
||||
if (n == -1)
|
||||
{
|
||||
Handler().LogError(this, "SctpSocket", -1, "sctp_connectx() failed", LOG_LEVEL_ERROR);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetConnecting();
|
||||
}
|
||||
return n;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int SctpSocket::getpaddrs(sctp_assoc_t id,std::list<std::string>& vec)
|
||||
{
|
||||
struct sockaddr *p = NULL;
|
||||
int n = sctp_getpaddrs(GetSocket(), id, &p);
|
||||
if (!n || n == -1)
|
||||
{
|
||||
Handler().LogError(this, "SctpSocket", -1, "sctp_getpaddrs failed", LOG_LEVEL_WARNING);
|
||||
return n;
|
||||
}
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
vec.push_back(Utility::Sa2String(&p[i]));
|
||||
}
|
||||
sctp_freepaddrs(p);
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
int SctpSocket::getladdrs(sctp_assoc_t id,std::list<std::string>& vec)
|
||||
{
|
||||
struct sockaddr *p = NULL;
|
||||
int n = sctp_getladdrs(GetSocket(), id, &p);
|
||||
if (!n || n == -1)
|
||||
{
|
||||
Handler().LogError(this, "SctpSocket", -1, "sctp_getladdrs failed", LOG_LEVEL_WARNING);
|
||||
return n;
|
||||
}
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
vec.push_back(Utility::Sa2String(&p[i]));
|
||||
}
|
||||
sctp_freeladdrs(p);
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
int SctpSocket::PeelOff(sctp_assoc_t id)
|
||||
{
|
||||
int n = sctp_peeloff(GetSocket(), id);
|
||||
if (n == -1)
|
||||
{
|
||||
Handler().LogError(this, "SctpSocket", -1, "PeelOff failed", LOG_LEVEL_WARNING);
|
||||
return -1;
|
||||
}
|
||||
Socket *p = Create();
|
||||
p -> Attach(n);
|
||||
p -> SetDeleteByHandler();
|
||||
Handler().Add(p);
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
void SctpSocket::OnRead()
|
||||
{
|
||||
/*
|
||||
int sctp_recvmsg(int sd, void * msg, size_t * len,
|
||||
struct sockaddr * from, socklen_t * fromlen,
|
||||
struct sctp_sndrcvinfo * sinfo, int * msg_flags);
|
||||
|
||||
DESCRIPTION
|
||||
sctp_recvmsg is a wrapper library function that can be used to receive a message from a socket while using the advanced
|
||||
features of SCTP. sd is the socket descriptor on which the message pointed to by msg of length len is received.
|
||||
|
||||
If from is not NULL, the source address of the message is filled in. The argument fromlen is a value-result parameter.
|
||||
initialized to the size of the buffer associated with from , and modified on return to indicate the actual size of the
|
||||
address stored.
|
||||
|
||||
sinfo is a pointer to a sctp_sndrcvinfo structure to be filled upon receipt of the message. msg_flags is a pointer to a
|
||||
integer that is filled with any message flags like MSG_NOTIFICATION or MSG_EOR.
|
||||
|
||||
*/
|
||||
struct sockaddr sa;
|
||||
socklen_t sa_len = 0;
|
||||
struct sctp_sndrcvinfo sinfo;
|
||||
int flags = 0;
|
||||
int n = sctp_recvmsg(GetSocket(), m_buf, SCTP_BUFSIZE_READ, &sa, &sa_len, &sinfo, &flags);
|
||||
if (n == -1)
|
||||
{
|
||||
Handler().LogError(this, "SctpSocket", Errno, StrError(Errno), LOG_LEVEL_FATAL);
|
||||
SetCloseAndDelete();
|
||||
}
|
||||
else
|
||||
{
|
||||
OnReceiveMessage(m_buf, n, &sa, sa_len, &sinfo, flags);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SctpSocket::OnReceiveMessage(const char *buf,size_t sz,struct sockaddr *sa,socklen_t sa_len,struct sctp_sndrcvinfo *sinfo,int msg_flags)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void SctpSocket::OnWrite()
|
||||
{
|
||||
if (Connecting())
|
||||
{
|
||||
int err = SoError();
|
||||
|
||||
// don't reset connecting flag on error here, we want the OnConnectFailed timeout later on
|
||||
/// \todo add to read fd_set here
|
||||
if (!err) // ok
|
||||
{
|
||||
Set(!IsDisableRead(), false);
|
||||
SetConnecting(false);
|
||||
SetCallOnConnect();
|
||||
return;
|
||||
}
|
||||
Handler().LogError(this, "sctp: connect failed", err, StrError(err), LOG_LEVEL_FATAL);
|
||||
Set(false, false); // no more monitoring because connection failed
|
||||
|
||||
// failed
|
||||
#ifdef ENABLE_SOCKS4
|
||||
if (Socks4())
|
||||
{
|
||||
OnSocks4ConnectFailed();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (GetConnectionRetry() == -1 ||
|
||||
(GetConnectionRetry() && GetConnectionRetries() < GetConnectionRetry()) )
|
||||
{
|
||||
// even though the connection failed at once, only retry after
|
||||
// the connection timeout.
|
||||
// should we even try to connect again, when CheckConnect returns
|
||||
// false it's because of a connection error - not a timeout...
|
||||
return;
|
||||
}
|
||||
SetConnecting(false);
|
||||
SetCloseAndDelete( true );
|
||||
/// \todo state reason why connect failed
|
||||
OnConnectFailed();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SctpSocket::OnConnectTimeout()
|
||||
{
|
||||
Handler().LogError(this, "connect", -1, "connect timeout", LOG_LEVEL_FATAL);
|
||||
#ifdef ENABLE_SOCKS4
|
||||
if (Socks4())
|
||||
{
|
||||
OnSocks4ConnectFailed();
|
||||
// retry direct connection
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (GetConnectionRetry() == -1 ||
|
||||
(GetConnectionRetry() && GetConnectionRetries() < GetConnectionRetry()) )
|
||||
{
|
||||
IncreaseConnectionRetries();
|
||||
// ask socket via OnConnectRetry callback if we should continue trying
|
||||
if (OnConnectRetry())
|
||||
{
|
||||
SetRetryClientConnect();
|
||||
}
|
||||
else
|
||||
{
|
||||
SetCloseAndDelete( true );
|
||||
/// \todo state reason why connect failed
|
||||
OnConnectFailed();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SetCloseAndDelete(true);
|
||||
/// \todo state reason why connect failed
|
||||
OnConnectFailed();
|
||||
}
|
||||
//
|
||||
SetConnecting(false);
|
||||
}
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
void SctpSocket::OnException()
|
||||
{
|
||||
if (Connecting())
|
||||
{
|
||||
#ifdef ENABLE_SOCKS4
|
||||
if (Socks4())
|
||||
OnSocks4ConnectFailed();
|
||||
else
|
||||
#endif
|
||||
if (GetConnectionRetry() == -1 ||
|
||||
(GetConnectionRetry() &&
|
||||
GetConnectionRetries() < GetConnectionRetry() ))
|
||||
{
|
||||
// even though the connection failed at once, only retry after
|
||||
// the connection timeout
|
||||
// should we even try to connect again, when CheckConnect returns
|
||||
// false it's because of a connection error - not a timeout...
|
||||
}
|
||||
else
|
||||
{
|
||||
SetConnecting(false); // tnx snibbe
|
||||
SetCloseAndDelete();
|
||||
OnConnectFailed();
|
||||
}
|
||||
return;
|
||||
}
|
||||
// %! exception doesn't always mean something bad happened, this code should be reworked
|
||||
// errno valid here?
|
||||
int err = SoError();
|
||||
Handler().LogError(this, "exception on select", err, StrError(err), LOG_LEVEL_FATAL);
|
||||
SetCloseAndDelete();
|
||||
}
|
||||
#endif // _WIN32
|
||||
|
||||
|
||||
int SctpSocket::Protocol()
|
||||
{
|
||||
return IPPROTO_SCTP;
|
||||
}
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
} // namespace SOCKETS_NAMESPACE
|
||||
#endif
|
||||
|
||||
|
||||
#endif // USE_SCTP
|
||||
|
||||
@@ -1,122 +0,0 @@
|
||||
/**
|
||||
** \file SctpSocket.h
|
||||
** \date 2006-09-04
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2008-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef _SOCKETS_SctpSocket_H
|
||||
#define _SOCKETS_SctpSocket_H
|
||||
#include "sockets-config.h"
|
||||
|
||||
#include "StreamSocket.h"
|
||||
#ifdef USE_SCTP
|
||||
#include <netinet/sctp.h>
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
#define SCTP_BUFSIZE_READ 16400
|
||||
|
||||
class SocketAddress;
|
||||
|
||||
|
||||
class SctpSocket : public StreamSocket
|
||||
{
|
||||
public:
|
||||
/** SctpSocket constructor.
|
||||
\param h Owner
|
||||
\param type SCTP_STREAM or SCTP_SEQPACKET */
|
||||
SctpSocket(ISocketHandler& h,int type);
|
||||
~SctpSocket();
|
||||
|
||||
/** bind() */
|
||||
int Bind(const std::string&,port_t);
|
||||
int Bind(SocketAddress&);
|
||||
/** sctp_bindx() */
|
||||
int AddAddress(const std::string&,port_t);
|
||||
int AddAddress(SocketAddress&);
|
||||
/** sctp_bindx() */
|
||||
int RemoveAddress(const std::string&,port_t);
|
||||
int RemoveAddress(SocketAddress&);
|
||||
|
||||
/** connect() */
|
||||
int Open(const std::string&,port_t);
|
||||
int Open(SocketAddress&);
|
||||
|
||||
/** Connect timeout callback. */
|
||||
void OnConnectTimeout();
|
||||
#ifdef _WIN32
|
||||
/** Connection failed reported as exception on win32 */
|
||||
void OnException();
|
||||
#endif
|
||||
|
||||
#ifndef SOLARIS
|
||||
/** sctp_connectx() */
|
||||
int AddConnection(const std::string&,port_t);
|
||||
int AddConnection(SocketAddress&);
|
||||
#endif
|
||||
|
||||
/** Get peer addresses of an association. */
|
||||
int getpaddrs(sctp_assoc_t id,std::list<std::string>&);
|
||||
/** Get all bound addresses of an association. */
|
||||
int getladdrs(sctp_assoc_t id,std::list<std::string>&);
|
||||
|
||||
/** sctp_peeloff */
|
||||
int PeelOff(sctp_assoc_t id);
|
||||
|
||||
/** recvmsg callback */
|
||||
virtual void OnReceiveMessage(const char *buf,size_t sz,struct sockaddr *sa,socklen_t sa_len,struct sctp_sndrcvinfo *sinfo,int msg_flags) = 0;
|
||||
|
||||
void OnOptions(int,int,int,SOCKET) {}
|
||||
|
||||
virtual int Protocol();
|
||||
|
||||
protected:
|
||||
SctpSocket(const SctpSocket& s) : StreamSocket(s) {}
|
||||
void OnRead();
|
||||
void OnWrite();
|
||||
|
||||
private:
|
||||
SctpSocket& operator=(const SctpSocket& s) {
|
||||
return *this;
|
||||
}
|
||||
int m_type; ///< SCTP_STREAM or SCTP_SEQPACKET
|
||||
char *m_buf; ///< Temporary receive buffer
|
||||
};
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
} // namespace SOCKETS_NAMESPACE
|
||||
#endif
|
||||
|
||||
#endif // USE_SCTP
|
||||
#endif // _SOCKETS_SctpSocket_H
|
||||
|
||||
@@ -1,123 +0,0 @@
|
||||
/**
|
||||
** \file Semaphore.cpp
|
||||
** \date 2007-04-13
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2007-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#include "Semaphore.h"
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
#ifdef _WIN32
|
||||
|
||||
Semaphore::Semaphore(value_t start_val)
|
||||
{
|
||||
m_handle = ::CreateSemaphore((LPSECURITY_ATTRIBUTES)NULL, start_val, 1, (LPCTSTR)NULL);
|
||||
}
|
||||
|
||||
|
||||
Semaphore::~Semaphore()
|
||||
{
|
||||
::CloseHandle(m_handle);
|
||||
}
|
||||
|
||||
|
||||
int Semaphore::Post()
|
||||
{
|
||||
return (::ReleaseSemaphore(m_handle, 1, (LPLONG)NULL) != 0) ? 0 : -1;
|
||||
}
|
||||
|
||||
|
||||
int Semaphore::Wait()
|
||||
{
|
||||
return (WaitForSingleObject(m_handle, INFINITE) == WAIT_OBJECT_0) ? 0 : -1;
|
||||
}
|
||||
|
||||
|
||||
int Semaphore::TryWait()
|
||||
{
|
||||
return -1; // %! not implemented
|
||||
}
|
||||
|
||||
|
||||
int Semaphore::GetValue(int& i)
|
||||
{
|
||||
return 0; // %! not implemented
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
#else
|
||||
|
||||
Semaphore::Semaphore(value_t start_val)
|
||||
{
|
||||
sem_init(&m_sem, 0, start_val);
|
||||
}
|
||||
|
||||
|
||||
Semaphore::~Semaphore()
|
||||
{
|
||||
sem_destroy(&m_sem);
|
||||
}
|
||||
|
||||
|
||||
int Semaphore::Post()
|
||||
{
|
||||
return sem_post(&m_sem);
|
||||
}
|
||||
|
||||
|
||||
int Semaphore::Wait()
|
||||
{
|
||||
return sem_wait(&m_sem);
|
||||
}
|
||||
|
||||
|
||||
int Semaphore::TryWait()
|
||||
{
|
||||
return sem_trywait(&m_sem);
|
||||
}
|
||||
|
||||
|
||||
int Semaphore::GetValue(int& i)
|
||||
{
|
||||
return sem_getvalue(&m_sem, &i);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
} // namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
@@ -1,100 +0,0 @@
|
||||
/**
|
||||
** \file Semaphore.h
|
||||
** \date 2007-04-13
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2007-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef _SOCKETS_Semaphore_H
|
||||
#define _SOCKETS_Semaphore_H
|
||||
|
||||
#include "sockets-config.h"
|
||||
#ifdef _WIN32
|
||||
#include "socket_include.h"
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#ifdef MACOSX
|
||||
#include <sys/semaphore.h>
|
||||
#else
|
||||
#include <semaphore.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
typedef LONG value_t;
|
||||
#else
|
||||
typedef unsigned int value_t;
|
||||
#endif
|
||||
|
||||
/** pthread semaphore wrapper.
|
||||
\ingroup threading */
|
||||
class Semaphore
|
||||
{
|
||||
public:
|
||||
Semaphore(value_t start_val = 0);
|
||||
~Semaphore();
|
||||
|
||||
/** \return 0 if successful */
|
||||
int Post();
|
||||
/** Wait for Post
|
||||
\return 0 if successful */
|
||||
int Wait();
|
||||
|
||||
/** Not implemented for win32 */
|
||||
int TryWait();
|
||||
|
||||
/** Not implemented for win32 */
|
||||
int GetValue(int&);
|
||||
|
||||
private:
|
||||
Semaphore(const Semaphore& ) {} // copy constructor
|
||||
Semaphore& operator=(const Semaphore& ) {
|
||||
return *this; // assignment operator
|
||||
}
|
||||
#ifdef _WIN32
|
||||
HANDLE m_handle;
|
||||
#else
|
||||
sem_t m_sem;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
} // namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
#endif // _SOCKETS_Semaphore_H
|
||||
|
||||
@@ -1,244 +0,0 @@
|
||||
/**
|
||||
** \file SmtpdSocket.cpp
|
||||
** \date 2007-05-10
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2007-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#include "SmtpdSocket.h"
|
||||
#include "Parse.h"
|
||||
#include "Utility.h"
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
SmtpdSocket::SmtpdSocket(ISocketHandler& h)
|
||||
:TcpSocket(h)
|
||||
,m_hello(false)
|
||||
,m_data(false)
|
||||
,m_header(false)
|
||||
{
|
||||
SetLineProtocol();
|
||||
}
|
||||
|
||||
|
||||
void SmtpdSocket::OnAccept()
|
||||
{
|
||||
Send("220 ESMTP; \r\n");
|
||||
}
|
||||
|
||||
|
||||
void SmtpdSocket::OnLine(const std::string& line)
|
||||
{
|
||||
if (m_data)
|
||||
{
|
||||
if (m_header)
|
||||
{
|
||||
if (!line.size())
|
||||
{
|
||||
if (m_header_line.size())
|
||||
{
|
||||
Parse pa(m_header_line, ":");
|
||||
std::string key = pa.getword();
|
||||
OnHeader(key, pa.getrest());
|
||||
}
|
||||
m_header = false;
|
||||
OnHeaderComplete();
|
||||
}
|
||||
else
|
||||
if (line[0] == ' ' || line[0] == '\t')
|
||||
{
|
||||
m_header_line += line;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_header_line.size())
|
||||
{
|
||||
Parse pa(m_header_line, ":");
|
||||
std::string key = pa.getword();
|
||||
OnHeader(key, pa.getrest());
|
||||
}
|
||||
m_header_line = line;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (line == ".")
|
||||
{
|
||||
m_data = false;
|
||||
if (OnDataComplete())
|
||||
Send("250 OK\r\n");
|
||||
else
|
||||
Send("550 Failed\r\n");
|
||||
}
|
||||
else
|
||||
if (line.size() && line[0] == '.')
|
||||
{
|
||||
OnData(line.substr(1));
|
||||
}
|
||||
else
|
||||
{
|
||||
OnData(line);
|
||||
}
|
||||
return;
|
||||
}
|
||||
Parse pa(line);
|
||||
std::string cmd = Utility::ToUpper(pa.getword());
|
||||
|
||||
if (cmd == "EHLO")
|
||||
{
|
||||
if (!OnHello(pa.getrest()))
|
||||
{
|
||||
Send("550 Failed\r\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
m_hello = true;
|
||||
Send("250 mail.alhem.net\r\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
if (cmd == "HELO")
|
||||
{
|
||||
if (!OnHello(pa.getrest()))
|
||||
{
|
||||
Send("550 Failed\r\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
m_hello = true;
|
||||
Send("250 mail.alhem.net\r\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
if (!m_hello)
|
||||
{
|
||||
OnAbort(SMTP_NO_HELLO);
|
||||
SetCloseAndDelete();
|
||||
}
|
||||
else
|
||||
if (cmd == "MAIL") // mail from:
|
||||
{
|
||||
Parse pa(line, ":");
|
||||
pa.getword(); // 'mail'
|
||||
pa.getword(); // 'from'
|
||||
std::string email = Utility::ToLower(pa.getrest());
|
||||
|
||||
EmailAddress addr( email );
|
||||
if (addr.GetName().size() > 64)
|
||||
{
|
||||
OnAbort(SMTP_NAME_TOO_LONG);
|
||||
Send("500 Name too long.\r\n");
|
||||
return;
|
||||
}
|
||||
if (addr.GetDomain().size() > 64)
|
||||
{
|
||||
OnAbort(SMTP_DOMAIN_TOO_LONG);
|
||||
Send("500 Domain too long.\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!OnMailFrom( addr ))
|
||||
{
|
||||
Send("550 Failed\r\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
Send("250 OK\r\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
if (cmd == "RCPT") // rcpt to:
|
||||
{
|
||||
Parse pa(line, ":");
|
||||
pa.getword(); // 'rcpt'
|
||||
pa.getword(); // 'to'
|
||||
std::string email = Utility::ToLower(pa.getrest());
|
||||
// %! reject based on user / domain?
|
||||
EmailAddress addr( email );
|
||||
|
||||
if (addr.GetName().size() > 64)
|
||||
{
|
||||
OnAbort(SMTP_NAME_TOO_LONG);
|
||||
Send("500 Name too long.\r\n");
|
||||
return;
|
||||
}
|
||||
if (addr.GetDomain().size() > 64)
|
||||
{
|
||||
OnAbort(SMTP_DOMAIN_TOO_LONG);
|
||||
Send("500 Domain too long.\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!OnRcptTo( addr ))
|
||||
{
|
||||
Send("553 Failed\r\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
Send("250 OK\r\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
if (cmd == "DATA")
|
||||
{
|
||||
Send("354 Enter mail, end with \".\" on a line by itself\r\n");
|
||||
m_data = true;
|
||||
m_header = false;
|
||||
}
|
||||
else
|
||||
if (cmd == "RSET")
|
||||
{
|
||||
m_data = false;
|
||||
m_header = false;
|
||||
OnRset();
|
||||
Send("250 OK\r\n"); // %! ???
|
||||
}
|
||||
else
|
||||
if (cmd == "QUIT")
|
||||
{
|
||||
OnAbort(SMTP_QUIT);
|
||||
Send("221 Bye Bye\r\n");
|
||||
SetCloseAndDelete();
|
||||
}
|
||||
else
|
||||
if (cmd == "NOOP")
|
||||
{
|
||||
Send("250 OK\r\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
OnNotSupported(cmd, pa.getrest());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
} // namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
@@ -1,171 +0,0 @@
|
||||
/**
|
||||
** \file SmtpdSocket.h
|
||||
** \date 2007-05-10
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2007-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef _SOCKETS_SmtpdSocket_H
|
||||
#define _SOCKETS_SmtpdSocket_H
|
||||
|
||||
#include "sockets-config.h"
|
||||
#include <string>
|
||||
#include "TcpSocket.h"
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
|
||||
/** Smtp server base class. */
|
||||
class SmtpdSocket : public TcpSocket
|
||||
{
|
||||
protected:
|
||||
typedef enum {
|
||||
SMTP_NO_HELLO,
|
||||
SMTP_NAME_TOO_LONG,
|
||||
SMTP_DOMAIN_TOO_LONG,
|
||||
SMTP_QUIT
|
||||
} reason_t;
|
||||
|
||||
public:
|
||||
class EmailAddress
|
||||
{
|
||||
public:
|
||||
EmailAddress(const std::string& str_in) {
|
||||
std::string str = str_in;
|
||||
size_t i = str.find("<");
|
||||
|
||||
if (i != std::string::npos)
|
||||
str = str.substr(i + 1);
|
||||
|
||||
i = str.find("@");
|
||||
|
||||
if (i != std::string::npos) {
|
||||
m_name = str.substr(0, i);
|
||||
str = str.substr(i + 1);
|
||||
i = str.find(">");
|
||||
|
||||
if (i != std::string::npos)
|
||||
str = str.substr(0, i);
|
||||
|
||||
m_domain = str;
|
||||
}
|
||||
|
||||
while (m_name.size() && m_name[m_name.size() - 1] == ' ')
|
||||
m_name.resize(m_name.size() - 1);
|
||||
|
||||
while (m_domain.size() && m_domain[m_domain.size() - 1] == ' ')
|
||||
m_domain.resize(m_domain.size() - 1);
|
||||
|
||||
while (m_name.size() && m_name[0] == ' ')
|
||||
m_name = m_name.substr(1);
|
||||
|
||||
while (m_domain.size() && m_domain[0] == ' ')
|
||||
m_domain = m_domain.substr(1);
|
||||
|
||||
m_top = m_domain;
|
||||
{
|
||||
for (size_t i = 0; i < m_domain.size(); i++) {
|
||||
if (m_domain[i] == '.') {
|
||||
m_sub = m_top;
|
||||
m_top = m_domain.substr(i + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const std::string& GetName() const {
|
||||
return m_name;
|
||||
}
|
||||
const std::string& GetDomain() const {
|
||||
return m_domain;
|
||||
}
|
||||
const std::string& GetTopDomain() const {
|
||||
return m_top;
|
||||
}
|
||||
const std::string& GetSubDomain() const {
|
||||
return m_sub;
|
||||
}
|
||||
|
||||
std::string ToString() const {
|
||||
return m_name + "@" + m_domain;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_name;
|
||||
std::string m_domain;
|
||||
std::string m_top;
|
||||
std::string m_sub;
|
||||
};
|
||||
|
||||
public:
|
||||
SmtpdSocket(ISocketHandler&);
|
||||
|
||||
void OnAccept();
|
||||
void OnLine(const std::string&);
|
||||
|
||||
/** \return 'false' to abort */
|
||||
virtual bool OnHello(const std::string& domain) = 0;
|
||||
|
||||
/** \return 'false' to abort */
|
||||
virtual bool OnMailFrom(const EmailAddress& addr) = 0;
|
||||
|
||||
/** \return 'false' to abort */
|
||||
virtual bool OnRcptTo(const EmailAddress& addr) = 0;
|
||||
|
||||
virtual void OnHeader(const std::string& key, const std::string& value) = 0;
|
||||
|
||||
virtual void OnHeaderComplete() = 0;
|
||||
|
||||
virtual void OnData(const std::string& line) = 0;
|
||||
|
||||
/** \return 'false' if message write failed (message will probably be resent) */
|
||||
virtual bool OnDataComplete() = 0;
|
||||
|
||||
virtual void OnRset() = 0;
|
||||
|
||||
virtual void OnAbort(reason_t) = 0;
|
||||
|
||||
virtual void OnNotSupported(const std::string& cmd, const std::string& arg) = 0;
|
||||
|
||||
private:
|
||||
bool m_hello; // we need HELO or EHLO first of all
|
||||
bool m_data;
|
||||
bool m_header;
|
||||
std::string m_header_line;
|
||||
};
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
} // namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
#endif // _SOCKETS_SmtpdSocket_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,735 +0,0 @@
|
||||
/** \file Socket.h
|
||||
** \date 2004-02-13
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2004-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef _SOCKETS_Socket_H
|
||||
#define _SOCKETS_Socket_H
|
||||
#include "sockets-config.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#ifdef HAVE_OPENSSL
|
||||
#include <openssl/ssl.h>
|
||||
#endif
|
||||
|
||||
#include "socket_include.h"
|
||||
#include <time.h>
|
||||
#include "SocketAddress.h"
|
||||
#include "Thread.h"
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
|
||||
class ISocketHandler;
|
||||
class SocketAddress;
|
||||
class IFile;
|
||||
class SocketThread;
|
||||
|
||||
|
||||
/** \defgroup basic Basic sockets */
|
||||
/** Socket base class.
|
||||
\ingroup basic */
|
||||
class Socket
|
||||
{
|
||||
/** Socket mode flags. */
|
||||
/*
|
||||
enum {
|
||||
// Socket
|
||||
SOCK_DEL = 0x01, ///< Delete by handler flag
|
||||
SOCK_CLOSE = 0x02, ///< Close and delete flag
|
||||
SOCK_DISABLE_READ = 0x04, ///< Disable checking for read events
|
||||
SOCK_CONNECTED = 0x08, ///< Socket is connected (tcp/udp)
|
||||
|
||||
SOCK_ERASED_BY_HANDLER = 0x10, ///< Set by handler before delete
|
||||
// HAVE_OPENSSL
|
||||
SOCK_ENABLE_SSL = 0x20, ///< Enable SSL for this TcpSocket
|
||||
SOCK_SSL = 0x40, ///< ssl negotiation mode (TcpSocket)
|
||||
SOCK_SSL_SERVER = 0x80, ///< True if this is an incoming ssl TcpSocket connection
|
||||
|
||||
// ENABLE_IPV6
|
||||
SOCK_IPV6 = 0x0100, ///< This is an ipv6 socket if this one is true
|
||||
// ENABLE_POOL
|
||||
SOCK_CLIENT = 0x0200, ///< only client connections are pooled
|
||||
SOCK_RETAIN = 0x0400, ///< keep connection on close
|
||||
SOCK_LOST = 0x0800, ///< connection lost
|
||||
|
||||
// ENABLE_SOCKS4
|
||||
SOCK_SOCKS4 = 0x1000, ///< socks4 negotiation mode (TcpSocket)
|
||||
// ENABLE_DETACH
|
||||
SOCK_DETACH = 0x2000, ///< Socket ordered to detach flag
|
||||
SOCK_DETACHED = 0x4000, ///< Socket has been detached
|
||||
// StreamSocket
|
||||
STREAMSOCK_CONNECTING = 0x8000, ///< Flag indicating connection in progress
|
||||
|
||||
STREAMSOCK_FLUSH_BEFORE_CLOSE = 0x010000L, ///< Send all data before closing (default true)
|
||||
STREAMSOCK_CALL_ON_CONNECT = 0x020000L, ///< OnConnect will be called next ISocketHandler cycle if true
|
||||
STREAMSOCK_RETRY_CONNECT = 0x040000L, ///< Try another connection attempt next ISocketHandler cycle
|
||||
STREAMSOCK_LINE_PROTOCOL = 0x080000L, ///< Line protocol mode flag
|
||||
|
||||
};
|
||||
*/
|
||||
|
||||
public:
|
||||
/** "Default" constructor */
|
||||
Socket(ISocketHandler&);
|
||||
|
||||
virtual ~Socket();
|
||||
|
||||
/** Socket class instantiation method. Used when a "non-standard" constructor
|
||||
* needs to be used for the socket class. Note: the socket class still needs
|
||||
* the "default" constructor with one ISocketHandler& as input parameter.
|
||||
*/
|
||||
virtual Socket *Create() {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** Returns reference to sockethandler that owns the socket.
|
||||
If the socket is detached, this is a reference to the slave sockethandler.
|
||||
*/
|
||||
ISocketHandler& Handler() const;
|
||||
|
||||
/** Returns reference to sockethandler that owns the socket.
|
||||
This one always returns the reference to the original sockethandler,
|
||||
even if the socket is detached.
|
||||
*/
|
||||
ISocketHandler& MasterHandler() const;
|
||||
|
||||
/** Called by ListenSocket after accept but before socket is added to handler.
|
||||
* CTcpSocket uses this to create its ICrypt member variable.
|
||||
* The ICrypt member variable is created by a virtual method, therefore
|
||||
* it can't be called directly from the CTcpSocket constructor.
|
||||
* Also used to determine if incoming HTTP connection is normal (port 80)
|
||||
* or ssl (port 443).
|
||||
*/
|
||||
virtual void Init();
|
||||
|
||||
/** Create a socket file descriptor.
|
||||
\param af Address family AF_INET / AF_INET6 / ...
|
||||
\param type SOCK_STREAM / SOCK_DGRAM / ...
|
||||
\param protocol "tcp" / "udp" / ... */
|
||||
SOCKET CreateSocket(int af,int type,const std::string& protocol = "");
|
||||
|
||||
/** Assign this socket a file descriptor created
|
||||
by a call to socket() or otherwise. */
|
||||
void Attach(SOCKET s);
|
||||
|
||||
/** Return file descriptor assigned to this socket. */
|
||||
SOCKET GetSocket();
|
||||
|
||||
/** Close connection immediately - internal use.
|
||||
\sa SetCloseAndDelete */
|
||||
virtual int Close();
|
||||
|
||||
/** Returns true when socket file descriptor is valid
|
||||
and socket is not about to be closed. */
|
||||
virtual bool Ready();
|
||||
|
||||
/** Returns pointer to ListenSocket that created this instance
|
||||
* on an incoming connection. */
|
||||
Socket *GetParent();
|
||||
|
||||
/** Used by ListenSocket to set parent pointer of newly created
|
||||
* socket instance. */
|
||||
void SetParent(Socket *);
|
||||
|
||||
/** Get listening port from ListenSocket<>. */
|
||||
virtual port_t GetPort();
|
||||
|
||||
/** Set socket non-block operation. */
|
||||
bool SetNonblocking(bool);
|
||||
|
||||
/** Set socket non-block operation. */
|
||||
bool SetNonblocking(bool, SOCKET);
|
||||
|
||||
/** Total lifetime of instance. */
|
||||
time_t Uptime();
|
||||
|
||||
/** Set address/port of last connect() call. */
|
||||
void SetClientRemoteAddress(SocketAddress&);
|
||||
|
||||
/** Get address/port of last connect() call. */
|
||||
std::auto_ptr<SocketAddress> GetClientRemoteAddress();
|
||||
|
||||
/** Common interface for SendBuf used by Tcp and Udp sockets. */
|
||||
virtual void SendBuf(const char *,size_t,int = 0);
|
||||
|
||||
/** Common interface for Send used by Tcp and Udp sockets. */
|
||||
virtual void Send(const std::string&,int = 0);
|
||||
|
||||
/** Outgoing traffic counter. */
|
||||
virtual uint64_t GetBytesSent(bool clear = false);
|
||||
|
||||
/** Incoming traffic counter. */
|
||||
virtual uint64_t GetBytesReceived(bool clear = false);
|
||||
|
||||
// LIST_TIMEOUT
|
||||
|
||||
/** Enable timeout control. 0=disable timeout check. */
|
||||
void SetTimeout(time_t secs);
|
||||
|
||||
bool CheckTimeout();
|
||||
|
||||
/** Check timeout. \return true if time limit reached */
|
||||
bool Timeout(time_t tnow);
|
||||
|
||||
/** Used by ListenSocket. ipv4 and ipv6 */
|
||||
void SetRemoteAddress(SocketAddress&);
|
||||
|
||||
/** \name Event callbacks */
|
||||
//@{
|
||||
|
||||
/** Called when there is something to be read from the file descriptor. */
|
||||
virtual void OnRead();
|
||||
/** Called when there is room for another write on the file descriptor. */
|
||||
virtual void OnWrite();
|
||||
/** Called on socket exception. */
|
||||
virtual void OnException();
|
||||
/** Called before a socket class is deleted by the ISocketHandler. */
|
||||
virtual void OnDelete();
|
||||
/** Called when a connection has completed. */
|
||||
virtual void OnConnect();
|
||||
/** Called when an incoming connection has been completed. */
|
||||
virtual void OnAccept();
|
||||
/** Called when a complete line has been read and the socket is in
|
||||
* line protocol mode. */
|
||||
virtual void OnLine(const std::string& );
|
||||
/** Called on connect timeout (5s). */
|
||||
virtual void OnConnectFailed();
|
||||
/** Called when a client socket is created, to set socket options.
|
||||
\param family AF_INET, AF_INET6, etc
|
||||
\param type SOCK_STREAM, SOCK_DGRAM, etc
|
||||
\param protocol Protocol number (tcp, udp, sctp, etc)
|
||||
\param s Socket file descriptor
|
||||
*/
|
||||
virtual void OnOptions(int family,int type,int protocol,SOCKET s) = 0;
|
||||
/** Connection retry callback - return false to abort connection attempts */
|
||||
virtual bool OnConnectRetry();
|
||||
#ifdef ENABLE_RECONNECT
|
||||
/** a reconnect has been made */
|
||||
virtual void OnReconnect();
|
||||
#endif
|
||||
/** TcpSocket: When a disconnect has been detected (recv/SSL_read returns 0 bytes). */
|
||||
virtual void OnDisconnect();
|
||||
/** TcpSocket: When a disconnect has been detected (recv/SSL_read returns 0 bytes).
|
||||
\param info bit 0 read(0)/write(1)
|
||||
bit 1 normal(read or write returned 0)/error(r/w returned -1)
|
||||
bit 2 ssl
|
||||
\param code error code from read/write call (errno / ssl error)
|
||||
*/
|
||||
virtual void OnDisconnect(short info, int code);
|
||||
/** Timeout callback. */
|
||||
virtual void OnTimeout();
|
||||
/** Connection timeout. */
|
||||
virtual void OnConnectTimeout();
|
||||
//@}
|
||||
|
||||
/** \name Socket mode flags, set/reset */
|
||||
//@{
|
||||
/** Set delete by handler true when you want the sockethandler to
|
||||
delete the socket instance after use. */
|
||||
void SetDeleteByHandler(bool = true);
|
||||
/** Check delete by handler flag.
|
||||
\return true if this instance should be deleted by the sockethandler */
|
||||
bool DeleteByHandler();
|
||||
|
||||
// LIST_CLOSE - conditional event queue
|
||||
|
||||
/** Set close and delete to terminate the connection. */
|
||||
void SetCloseAndDelete(bool = true);
|
||||
/** Check close and delete flag.
|
||||
\return true if this socket should be closed and the instance removed */
|
||||
bool CloseAndDelete();
|
||||
|
||||
/** Return number of seconds since socket was ordered to close. \sa SetCloseAndDelete */
|
||||
time_t TimeSinceClose();
|
||||
|
||||
/** Ignore read events for an output only socket. */
|
||||
void DisableRead(bool x = true);
|
||||
/** Check ignore read events flag.
|
||||
\return true if read events should be ignored */
|
||||
bool IsDisableRead();
|
||||
|
||||
/** Set connected status. */
|
||||
void SetConnected(bool = true);
|
||||
/** Check connected status.
|
||||
\return true if connected */
|
||||
bool IsConnected();
|
||||
|
||||
/** Connection lost - error while reading/writing from a socket - TcpSocket only. */
|
||||
void SetLost();
|
||||
/** Check connection lost status flag, used by TcpSocket only.
|
||||
\return true if there was an error while r/w causing the socket to close */
|
||||
bool Lost();
|
||||
|
||||
/** Set flag indicating the socket is being actively deleted by the sockethandler. */
|
||||
void SetErasedByHandler(bool x = true);
|
||||
/** Get value of flag indicating socket is deleted by sockethandler. */
|
||||
bool ErasedByHandler();
|
||||
|
||||
//@}
|
||||
|
||||
/** \name Information about remote connection */
|
||||
//@{
|
||||
/** Returns address of remote end. */
|
||||
std::auto_ptr<SocketAddress> GetRemoteSocketAddress();
|
||||
/** Returns address of remote end: ipv4. */
|
||||
ipaddr_t GetRemoteIP4();
|
||||
//#ifdef ENABLE_IPV6
|
||||
/** Returns address of remote end: ipv6. */
|
||||
//#ifdef IPPROTO_IPV6
|
||||
struct in6_addr GetRemoteIP6();
|
||||
//#endif
|
||||
//#endif
|
||||
/** Returns remote port number: ipv4 and ipv6. */
|
||||
port_t GetRemotePort();
|
||||
/** Returns remote ip as string? ipv4 and ipv6. */
|
||||
std::string GetRemoteAddress();
|
||||
/** ipv4 and ipv6(not implemented) */
|
||||
std::string GetRemoteHostname();
|
||||
//@}
|
||||
|
||||
/** Returns local port number for bound socket file descriptor. */
|
||||
port_t GetSockPort();
|
||||
/** Returns local ipv4 address for bound socket file descriptor. */
|
||||
ipaddr_t GetSockIP4();
|
||||
/** Returns local ipv4 address as text for bound socket file descriptor. */
|
||||
std::string GetSockAddress();
|
||||
//#ifdef ENABLE_IPV6
|
||||
//#ifdef IPPROTO_IPV6
|
||||
/** Returns local ipv6 address for bound socket file descriptor. */
|
||||
struct in6_addr GetSockIP6();
|
||||
/** Returns local ipv6 address as text for bound socket file descriptor. */
|
||||
std::string GetSockAddress6();
|
||||
//#endif
|
||||
//#endif
|
||||
socketuid_t UniqueIdentifier() {
|
||||
return m_uid;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
/** @name IP options
|
||||
When an ip or socket option is available on all of the operating systems
|
||||
I'm testing on (linux 2.4.x, _win32, macosx, solaris9 intel) they are not
|
||||
checked with an #ifdef below.
|
||||
This might cause a compile error on other operating systems. */
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
// IP options
|
||||
//@{
|
||||
|
||||
bool SetIpOptions(const void *p, socklen_t len);
|
||||
bool SetIpTOS(unsigned char tos);
|
||||
unsigned char IpTOS();
|
||||
bool SetIpTTL(int ttl);
|
||||
int IpTTL();
|
||||
bool SetIpHdrincl(bool x = true);
|
||||
bool SetIpMulticastTTL(int);
|
||||
int IpMulticastTTL();
|
||||
bool SetMulticastLoop(bool x = true);
|
||||
bool IpAddMembership(struct ip_mreq&);
|
||||
bool IpDropMembership(struct ip_mreq&);
|
||||
|
||||
#ifdef IP_PKTINFO
|
||||
bool SetIpPktinfo(bool x = true);
|
||||
#endif
|
||||
#ifdef IP_RECVTOS
|
||||
bool SetIpRecvTOS(bool x = true);
|
||||
#endif
|
||||
#ifdef IP_RECVTTL
|
||||
bool SetIpRecvTTL(bool x = true);
|
||||
#endif
|
||||
#ifdef IP_RECVOPTS
|
||||
bool SetIpRecvopts(bool x = true);
|
||||
#endif
|
||||
#ifdef IP_RETOPTS
|
||||
bool SetIpRetopts(bool x = true);
|
||||
#endif
|
||||
#ifdef IP_RECVERR
|
||||
bool SetIpRecverr(bool x = true);
|
||||
#endif
|
||||
#ifdef IP_MTU_DISCOVER
|
||||
bool SetIpMtudiscover(bool x = true);
|
||||
#endif
|
||||
#ifdef IP_MTU
|
||||
int IpMtu();
|
||||
#endif
|
||||
#ifdef IP_ROUTER_ALERT
|
||||
bool SetIpRouterAlert(bool x = true);
|
||||
#endif
|
||||
#ifdef LINUX
|
||||
bool IpAddMembership(struct ip_mreqn&);
|
||||
#endif
|
||||
#ifdef LINUX
|
||||
bool IpDropMembership(struct ip_mreqn&);
|
||||
#endif
|
||||
//@}
|
||||
|
||||
// SOCKET options
|
||||
/** @name Socket Options */
|
||||
//@{
|
||||
|
||||
bool SoAcceptconn();
|
||||
bool SetSoBroadcast(bool x = true);
|
||||
bool SetSoDebug(bool x = true);
|
||||
int SoError();
|
||||
bool SetSoDontroute(bool x = true);
|
||||
bool SetSoLinger(int onoff, int linger);
|
||||
bool SetSoOobinline(bool x = true);
|
||||
bool SetSoRcvlowat(int);
|
||||
bool SetSoSndlowat(int);
|
||||
bool SetSoRcvtimeo(struct timeval&);
|
||||
bool SetSoSndtimeo(struct timeval&);
|
||||
bool SetSoRcvbuf(int);
|
||||
int SoRcvbuf();
|
||||
bool SetSoSndbuf(int);
|
||||
int SoSndbuf();
|
||||
int SoType();
|
||||
bool SetSoReuseaddr(bool x = true);
|
||||
bool SetSoKeepalive(bool x = true);
|
||||
|
||||
#ifdef SO_BSDCOMPAT
|
||||
bool SetSoBsdcompat(bool x = true);
|
||||
#endif
|
||||
#ifdef SO_BINDTODEVICE
|
||||
bool SetSoBindtodevice(const std::string& intf);
|
||||
#endif
|
||||
#ifdef SO_PASSCRED
|
||||
bool SetSoPasscred(bool x = true);
|
||||
#endif
|
||||
#ifdef SO_PEERCRED
|
||||
bool SoPeercred(struct ucred& );
|
||||
#endif
|
||||
#ifdef SO_PRIORITY
|
||||
bool SetSoPriority(int);
|
||||
#endif
|
||||
#ifdef SO_RCVBUFFORCE
|
||||
bool SetSoRcvbufforce(int);
|
||||
#endif
|
||||
#ifdef SO_SNDBUFFORCE
|
||||
bool SetSoSndbufforce(int);
|
||||
#endif
|
||||
#ifdef SO_TIMESTAMP
|
||||
bool SetSoTimestamp(bool x = true);
|
||||
#endif
|
||||
#ifdef SO_NOSIGPIPE
|
||||
bool SetSoNosigpipe(bool x = true);
|
||||
#endif
|
||||
//@}
|
||||
|
||||
// TCP options in TcpSocket.h/TcpSocket.cpp
|
||||
|
||||
|
||||
// LIST_CALLONCONNECT
|
||||
|
||||
/** Instruct socket to call OnConnect callback next sockethandler cycle. */
|
||||
void SetCallOnConnect(bool x = true);
|
||||
|
||||
/** Check call on connect flag.
|
||||
\return true if OnConnect() should be called a.s.a.p */
|
||||
bool CallOnConnect();
|
||||
|
||||
// LIST_RETRY
|
||||
|
||||
/** Set flag to initiate a connection attempt after a connection timeout. */
|
||||
void SetRetryClientConnect(bool x = true);
|
||||
|
||||
/** Check if a connection attempt should be made.
|
||||
\return true when another attempt should be made */
|
||||
bool RetryClientConnect();
|
||||
|
||||
#ifdef HAVE_OPENSSL
|
||||
/** @name SSL Support */
|
||||
//@{
|
||||
/** SSL client/server support - internal use. \sa TcpSocket */
|
||||
virtual void OnSSLConnect();
|
||||
/** SSL client/server support - internal use. \sa TcpSocket */
|
||||
virtual void OnSSLAccept();
|
||||
/** SSL negotiation failed for client connect. */
|
||||
virtual void OnSSLConnectFailed();
|
||||
/** SSL negotiation failed for server accept. */
|
||||
virtual void OnSSLAcceptFailed();
|
||||
/** new SSL support */
|
||||
virtual bool SSLNegotiate();
|
||||
/** Check if SSL is Enabled for this TcpSocket.
|
||||
\return true if this is a TcpSocket with SSL enabled */
|
||||
bool IsSSL();
|
||||
/** Enable SSL operation for a TcpSocket. */
|
||||
void EnableSSL(bool x = true);
|
||||
/** Still negotiating ssl connection.
|
||||
\return true if ssl negotiating is still in progress */
|
||||
bool IsSSLNegotiate();
|
||||
/** Set flag indicating ssl handshaking still in progress. */
|
||||
void SetSSLNegotiate(bool x = true);
|
||||
/** OnAccept called with SSL Enabled.
|
||||
\return true if this is a TcpSocket with an incoming SSL connection */
|
||||
bool IsSSLServer();
|
||||
/** Set flag indicating that this is a TcpSocket with incoming SSL connection. */
|
||||
void SetSSLServer(bool x = true);
|
||||
/** SSL; Get pointer to ssl context structure. */
|
||||
virtual SSL_CTX *GetSslContext() {
|
||||
return NULL;
|
||||
}
|
||||
/** SSL; Get pointer to ssl structure. */
|
||||
virtual SSL *GetSsl() {
|
||||
return NULL;
|
||||
}
|
||||
//@}
|
||||
#endif // HAVE_OPENSSL
|
||||
|
||||
//#ifdef ENABLE_IPV6
|
||||
/** Enable ipv6 for this socket. */
|
||||
void SetIpv6(bool x = true);
|
||||
/** Check ipv6 socket.
|
||||
\return true if this is an ipv6 socket */
|
||||
bool IsIpv6();
|
||||
//#endif
|
||||
|
||||
#ifdef ENABLE_POOL
|
||||
/** @name Connection Pool */
|
||||
//@{
|
||||
/** Client = connecting TcpSocket. */
|
||||
void SetIsClient();
|
||||
/** Socket type from socket() call. */
|
||||
void SetSocketType(int x);
|
||||
/** Socket type from socket() call. */
|
||||
int GetSocketType();
|
||||
/** Protocol type from socket() call. */
|
||||
void SetSocketProtocol(const std::string& x);
|
||||
/** Protocol type from socket() call. */
|
||||
const std::string& GetSocketProtocol();
|
||||
/** Instruct a client socket to stay open in the connection pool after use.
|
||||
If you have connected to a server using tcp, you can call SetRetain
|
||||
to leave the connection open after your socket instance has been deleted.
|
||||
The next connection you make to the same server will reuse the already
|
||||
opened connection, if it is still available.
|
||||
*/
|
||||
void SetRetain();
|
||||
/** Check retain flag.
|
||||
\return true if the socket should be moved to connection pool after use */
|
||||
bool Retain();
|
||||
/** Copy connection parameters from sock. */
|
||||
void CopyConnection(Socket *sock);
|
||||
//@}
|
||||
#endif // ENABLE_POOL
|
||||
|
||||
#ifdef ENABLE_SOCKS4
|
||||
/** \name Socks4 support */
|
||||
//@{
|
||||
/** Socks4 client support internal use. \sa TcpSocket */
|
||||
virtual void OnSocks4Connect();
|
||||
/** Socks4 client support internal use. \sa TcpSocket */
|
||||
virtual void OnSocks4ConnectFailed();
|
||||
/** Socks4 client support internal use. \sa TcpSocket */
|
||||
virtual bool OnSocks4Read();
|
||||
/** Called when the last write caused the tcp output buffer to
|
||||
* become empty. */
|
||||
/** socket still in socks4 negotiation mode */
|
||||
bool Socks4();
|
||||
/** Set flag indicating Socks4 handshaking in progress */
|
||||
void SetSocks4(bool x = true);
|
||||
|
||||
/** Set socks4 server host address to use */
|
||||
void SetSocks4Host(ipaddr_t a);
|
||||
/** Set socks4 server hostname to use. */
|
||||
void SetSocks4Host(const std::string& );
|
||||
/** Socks4 server port to use. */
|
||||
void SetSocks4Port(port_t p);
|
||||
/** Provide a socks4 userid if required by the socks4 server. */
|
||||
void SetSocks4Userid(const std::string& x);
|
||||
/** Get the ip address of socks4 server to use.
|
||||
\return socks4 server host address */
|
||||
ipaddr_t GetSocks4Host();
|
||||
/** Get the socks4 server port to use.
|
||||
\return socks4 server port */
|
||||
port_t GetSocks4Port();
|
||||
/** Get socks4 userid.
|
||||
\return Socks4 userid */
|
||||
const std::string& GetSocks4Userid();
|
||||
//@}
|
||||
#endif // ENABLE_SOCKS4
|
||||
|
||||
#ifdef ENABLE_RESOLVER
|
||||
/** \name Asynchronous Resolver */
|
||||
//@{
|
||||
/** Request an asynchronous dns resolution.
|
||||
\param host hostname to be resolved
|
||||
\param port port number passed along for the ride
|
||||
\return Resolve ID */
|
||||
int Resolve(const std::string& host,port_t port = 0);
|
||||
//#ifdef ENABLE_IPV6
|
||||
int Resolve6(const std::string& host, port_t port = 0);
|
||||
//#endif
|
||||
/** Callback returning a resolved address.
|
||||
\param id Resolve ID from Resolve call
|
||||
\param a resolved ip address
|
||||
\param port port number passed to Resolve */
|
||||
virtual void OnResolved(int id,ipaddr_t a,port_t port);
|
||||
//#ifdef ENABLE_IPV6
|
||||
virtual void OnResolved(int id,in6_addr& a,port_t port);
|
||||
//#endif
|
||||
/** Request asynchronous reverse dns lookup.
|
||||
\param a in_addr to be translated */
|
||||
int Resolve(ipaddr_t a);
|
||||
//#ifdef ENABLE_IPV6
|
||||
int Resolve(in6_addr& a);
|
||||
//#endif
|
||||
/** Callback returning reverse resolve results.
|
||||
\param id Resolve ID
|
||||
\param name Resolved hostname */
|
||||
virtual void OnReverseResolved(int id,const std::string& name);
|
||||
/** Callback indicating failed dns lookup.
|
||||
\param id Resolve ID */
|
||||
virtual void OnResolveFailed(int id);
|
||||
//@}
|
||||
#endif // ENABLE_RESOLVER
|
||||
|
||||
#ifdef ENABLE_DETACH
|
||||
/** \name Thread Support */
|
||||
//@{
|
||||
/** Callback fires when a new socket thread has started and this
|
||||
socket is ready for operation again.
|
||||
\sa ResolvSocket */
|
||||
virtual void OnDetached();
|
||||
|
||||
// LIST_DETACH
|
||||
|
||||
/** Internal use. */
|
||||
void SetDetach(bool x = true);
|
||||
/** Check detach flag.
|
||||
\return true if the socket should detach to its own thread */
|
||||
bool IsDetach();
|
||||
|
||||
/** Internal use. */
|
||||
void SetDetached(bool x = true);
|
||||
/** Check detached flag.
|
||||
\return true if the socket runs in its own thread. */
|
||||
const bool IsDetached() const;
|
||||
/** Order this socket to start its own thread and call OnDetached
|
||||
when ready for operation. */
|
||||
bool Detach();
|
||||
/** Store the slave sockethandler pointer. */
|
||||
void SetSlaveHandler(ISocketHandler *);
|
||||
/** Create new thread for this socket to run detached in. */
|
||||
void DetachSocket();
|
||||
//@}
|
||||
#endif // ENABLE_DETACH
|
||||
|
||||
/** Write traffic to an IFile. Socket will not delete this object. */
|
||||
void SetTrafficMonitor(IFile *p) {
|
||||
m_traffic_monitor = p;
|
||||
}
|
||||
|
||||
protected:
|
||||
/** default constructor not available */
|
||||
Socket() : m_handler(m_handler) {}
|
||||
/** copy constructor not available */
|
||||
Socket(const Socket& s) : m_handler(s.m_handler) {}
|
||||
|
||||
/** assignment operator not available. */
|
||||
Socket& operator=(const Socket& ) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** All traffic will be written to this IFile, if set. */
|
||||
IFile *GetTrafficMonitor() {
|
||||
return m_traffic_monitor;
|
||||
}
|
||||
|
||||
// unsigned long m_flags; ///< boolean flags, replacing old 'bool' members
|
||||
|
||||
private:
|
||||
ISocketHandler& m_handler; ///< Reference of ISocketHandler in control of this socket
|
||||
SOCKET m_socket; ///< File descriptor
|
||||
bool m_bDel; ///< Delete by handler flag
|
||||
bool m_bClose; ///< Close and delete flag
|
||||
time_t m_tCreate; ///< Time in seconds when this socket was created
|
||||
Socket *m_parent; ///< Pointer to ListenSocket class, valid for incoming sockets
|
||||
bool m_b_disable_read; ///< Disable checking for read events
|
||||
bool m_connected; ///< Socket is connected (tcp/udp)
|
||||
bool m_b_erased_by_handler; ///< Set by handler before delete
|
||||
time_t m_tClose; ///< Time in seconds when ordered to close
|
||||
std::auto_ptr<SocketAddress> m_client_remote_address; ///< Address of last connect()
|
||||
std::auto_ptr<SocketAddress> m_remote_address; ///< Remote end address
|
||||
IFile *m_traffic_monitor;
|
||||
time_t m_timeout_start; ///< Set by SetTimeout
|
||||
time_t m_timeout_limit; ///< Defined by SetTimeout
|
||||
bool m_bLost; ///< connection lost
|
||||
static socketuid_t m_next_uid;
|
||||
socketuid_t m_uid;
|
||||
bool m_call_on_connect; ///< OnConnect will be called next ISocketHandler cycle if true
|
||||
bool m_b_retry_connect; ///< Try another connection attempt next ISocketHandler cycle
|
||||
|
||||
#ifdef _WIN32
|
||||
static WSAInitializer m_winsock_init; ///< Winsock initialization singleton class
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENSSL
|
||||
bool m_b_enable_ssl; ///< Enable SSL for this TcpSocket
|
||||
bool m_b_ssl; ///< ssl negotiation mode (TcpSocket)
|
||||
bool m_b_ssl_server; ///< True if this is an incoming ssl TcpSocket connection
|
||||
#endif
|
||||
|
||||
//#ifdef ENABLE_IPV6
|
||||
bool m_ipv6; ///< This is an ipv6 socket if this one is true
|
||||
//#endif
|
||||
|
||||
#ifdef ENABLE_POOL
|
||||
int m_socket_type; ///< Type of socket, from socket() call
|
||||
std::string m_socket_protocol; ///< Protocol, from socket() call
|
||||
bool m_bClient; ///< only client connections are pooled
|
||||
bool m_bRetain; ///< keep connection on close
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_SOCKS4
|
||||
bool m_bSocks4; ///< socks4 negotiation mode (TcpSocket)
|
||||
ipaddr_t m_socks4_host; ///< socks4 server address
|
||||
port_t m_socks4_port; ///< socks4 server port number
|
||||
std::string m_socks4_userid; ///< socks4 server usedid
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_DETACH
|
||||
bool m_detach; ///< Socket ordered to detach flag
|
||||
bool m_detached; ///< Socket has been detached
|
||||
SocketThread *m_pThread; ///< Detach socket thread class pointer
|
||||
ISocketHandler *m_slave_handler; ///< Actual sockethandler while detached
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _SOCKETS_Socket_H
|
||||
|
||||
@@ -1,106 +0,0 @@
|
||||
/**
|
||||
** \file SocketAddress.h
|
||||
** \date 2006-09-21
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2007-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef _SOCKETS_SocketAddress_H
|
||||
#define _SOCKETS_SocketAddress_H
|
||||
|
||||
#include "sockets-config.h"
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include "socket_include.h"
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
This class and its subclasses is intended to be used as replacement
|
||||
for the internal data type 'ipaddr_t' and various implementations of
|
||||
IPv6 addressing found throughout the library.
|
||||
'ipaddr_t' is an IPv4 address in network byte order.
|
||||
'port_t' is the portnumber in host byte order.
|
||||
'struct in6_addr' is an IPv6 address.
|
||||
'struct in_addr' is an IPv4 address.
|
||||
\ingroup basic
|
||||
*/
|
||||
class SocketAddress
|
||||
{
|
||||
public:
|
||||
virtual ~SocketAddress() {}
|
||||
|
||||
/** Get a pointer to the address struct. */
|
||||
virtual operator struct sockaddr *() = 0;
|
||||
|
||||
/** Get length of address struct. */
|
||||
virtual operator socklen_t() = 0;
|
||||
|
||||
/** Compare two addresses. */
|
||||
virtual bool operator==(SocketAddress&) = 0;
|
||||
|
||||
/** Set port number.
|
||||
\param port Port number in host byte order */
|
||||
virtual void SetPort(port_t port) = 0;
|
||||
|
||||
/** Get port number.
|
||||
\return Port number in host byte order. */
|
||||
virtual port_t GetPort() = 0;
|
||||
|
||||
/** Set socket address.
|
||||
\param sa Pointer to either 'struct sockaddr_in' or 'struct sockaddr_in6'. */
|
||||
virtual void SetAddress(struct sockaddr *sa) = 0;
|
||||
|
||||
/** Convert address to text. */
|
||||
virtual std::string Convert(bool include_port) = 0;
|
||||
|
||||
/** Reverse lookup of address. */
|
||||
virtual std::string Reverse() = 0;
|
||||
|
||||
/** Get address family. */
|
||||
virtual int GetFamily() = 0;
|
||||
|
||||
/** Address structure is valid. */
|
||||
virtual bool IsValid() = 0;
|
||||
|
||||
/** Get a copy of this SocketAddress object. */
|
||||
virtual std::auto_ptr<SocketAddress> GetCopy() = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
} // namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
#endif // _SOCKETS_SocketAddress_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,302 +0,0 @@
|
||||
/** \file SocketHandler.h
|
||||
** \date 2004-02-13
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2004-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef _SOCKETS_SocketHandler_H
|
||||
#define _SOCKETS_SocketHandler_H
|
||||
|
||||
#include "sockets-config.h"
|
||||
#include <map>
|
||||
#include <list>
|
||||
|
||||
#include "socket_include.h"
|
||||
#include "ISocketHandler.h"
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
|
||||
class Socket;
|
||||
#ifdef ENABLE_RESOLVER
|
||||
class ResolvServer;
|
||||
#endif
|
||||
class IMutex;
|
||||
class SocketHandlerThread;
|
||||
class UdpSocket;
|
||||
|
||||
/** Socket container class, event generator.
|
||||
\ingroup basic */
|
||||
class SocketHandler : public ISocketHandler
|
||||
{
|
||||
protected:
|
||||
/** Map type for holding file descriptors/socket object pointers. */
|
||||
typedef std::map<SOCKET,Socket *> socket_m;
|
||||
|
||||
public:
|
||||
/** SocketHandler constructor.
|
||||
\param log Optional log class pointer */
|
||||
SocketHandler(StdLog *log = NULL);
|
||||
|
||||
/** SocketHandler threadsafe constructor.
|
||||
\param mutex Externally declared mutex variable
|
||||
\param log Optional log class pointer */
|
||||
SocketHandler(IMutex& mutex,StdLog *log = NULL);
|
||||
|
||||
SocketHandler(IMutex&, ISocketHandler& parent, StdLog * = NULL);
|
||||
|
||||
~SocketHandler();
|
||||
|
||||
virtual ISocketHandler *Create(StdLog * = NULL);
|
||||
virtual ISocketHandler *Create(IMutex&, ISocketHandler&, StdLog * = NULL);
|
||||
|
||||
virtual bool ParentHandlerIsValid();
|
||||
|
||||
virtual ISocketHandler& ParentHandler();
|
||||
|
||||
virtual ISocketHandler& GetRandomHandler();
|
||||
|
||||
virtual ISocketHandler& GetEffectiveHandler();
|
||||
|
||||
virtual void SetNumberOfThreads(size_t n);
|
||||
virtual bool IsThreaded();
|
||||
|
||||
virtual void EnableRelease();
|
||||
virtual void Release();
|
||||
|
||||
/** Get mutex reference for threadsafe operations. */
|
||||
IMutex& GetMutex() const;
|
||||
|
||||
/** Register StdLog object for error callback.
|
||||
\param log Pointer to log class */
|
||||
void RegStdLog(StdLog *log);
|
||||
|
||||
/** Log error to log class for print out / storage. */
|
||||
void LogError(Socket *p,const std::string& user_text,int err,const std::string& sys_err,loglevel_t t = LOG_LEVEL_WARNING);
|
||||
|
||||
/** Add socket instance to socket map. Removal is always automatic. */
|
||||
void Add(Socket *);
|
||||
|
||||
/** Set read/write/exception file descriptor sets (fd_set). */
|
||||
void ISocketHandler_Add(Socket *,bool bRead,bool bWrite);
|
||||
void ISocketHandler_Mod(Socket *,bool bRead,bool bWrite);
|
||||
void ISocketHandler_Del(Socket *);
|
||||
|
||||
/** Wait for events, generate callbacks. */
|
||||
int Select(long sec,long usec);
|
||||
|
||||
/** This method will not return until an event has been detected. */
|
||||
int Select();
|
||||
|
||||
/** Wait for events, generate callbacks. */
|
||||
int Select(struct timeval *tsel);
|
||||
|
||||
/** Check that a socket really is handled by this socket handler. */
|
||||
bool Valid(Socket *);
|
||||
bool Valid(socketuid_t);
|
||||
|
||||
/** Return number of sockets handled by this handler. */
|
||||
size_t GetCount();
|
||||
size_t MaxCount() {
|
||||
return FD_SETSIZE;
|
||||
}
|
||||
|
||||
/** Override and return false to deny all incoming connections.
|
||||
\param p ListenSocket class pointer (use GetPort to identify which one) */
|
||||
bool OkToAccept(Socket *p);
|
||||
|
||||
/** Use with care, always lock with h.GetMutex() if multithreaded */
|
||||
const std::map<SOCKET, Socket *>& AllSockets() {
|
||||
return m_sockets;
|
||||
}
|
||||
|
||||
size_t MaxTcpLineSize() {
|
||||
return TCP_LINE_SIZE;
|
||||
}
|
||||
|
||||
void SetCallOnConnect(bool = true);
|
||||
void SetDetach(bool = true);
|
||||
void SetTimeout(bool = true);
|
||||
void SetRetry(bool = true);
|
||||
void SetClose(bool = true);
|
||||
|
||||
private:
|
||||
static FILE *m_event_file;
|
||||
static unsigned long m_event_counter;
|
||||
|
||||
public:
|
||||
// Connection pool
|
||||
#ifdef ENABLE_POOL
|
||||
/** Find available open connection (used by connection pool). */
|
||||
ISocketHandler::PoolSocket *FindConnection(int type,const std::string& protocol,SocketAddress&);
|
||||
/** Enable connection pool (by default disabled). */
|
||||
void EnablePool(bool x = true);
|
||||
/** Check pool status.
|
||||
\return true if connection pool is enabled */
|
||||
bool PoolEnabled();
|
||||
#endif // ENABLE_POOL
|
||||
|
||||
// Socks4
|
||||
#ifdef ENABLE_SOCKS4
|
||||
/** Set socks4 server ip that all new tcp sockets should use. */
|
||||
void SetSocks4Host(ipaddr_t);
|
||||
/** Set socks4 server hostname that all new tcp sockets should use. */
|
||||
void SetSocks4Host(const std::string& );
|
||||
/** Set socks4 server port number that all new tcp sockets should use. */
|
||||
void SetSocks4Port(port_t);
|
||||
/** Set optional socks4 userid. */
|
||||
void SetSocks4Userid(const std::string& );
|
||||
/** If connection to socks4 server fails, immediately try direct connection to final host. */
|
||||
void SetSocks4TryDirect(bool x = true);
|
||||
/** Get socks4 server ip.
|
||||
\return socks4 server ip */
|
||||
ipaddr_t GetSocks4Host();
|
||||
/** Get socks4 port number.
|
||||
\return socks4 port number */
|
||||
port_t GetSocks4Port();
|
||||
/** Get socks4 userid (optional).
|
||||
\return socks4 userid */
|
||||
const std::string& GetSocks4Userid();
|
||||
/** Check status of socks4 try direct flag.
|
||||
\return true if direct connection should be tried if connection to socks4 server fails */
|
||||
bool Socks4TryDirect();
|
||||
#endif // ENABLE_SOCKS4
|
||||
|
||||
// DNS resolve server
|
||||
#ifdef ENABLE_RESOLVER
|
||||
/** Enable asynchronous DNS.
|
||||
\param port Listen port of asynchronous dns server */
|
||||
void EnableResolver(port_t port = 16667);
|
||||
/** Check resolver status.
|
||||
\return true if resolver is enabled */
|
||||
bool ResolverEnabled();
|
||||
/** Queue a dns request.
|
||||
\param host Hostname to be resolved
|
||||
\param port Port number will be echoed in Socket::OnResolved callback */
|
||||
int Resolve(Socket *,const std::string& host,port_t port);
|
||||
#ifdef ENABLE_IPV6
|
||||
int Resolve6(Socket *,const std::string& host,port_t port);
|
||||
#endif
|
||||
/** Do a reverse dns lookup. */
|
||||
int Resolve(Socket *,ipaddr_t a);
|
||||
#ifdef ENABLE_IPV6
|
||||
int Resolve(Socket *,in6_addr& a);
|
||||
#endif
|
||||
/** Get listen port of asynchronous dns server. */
|
||||
port_t GetResolverPort();
|
||||
/** Resolver thread ready for queries. */
|
||||
bool ResolverReady();
|
||||
/** Returns true if the socket is waiting for a resolve event. */
|
||||
bool Resolving(Socket *);
|
||||
#endif // ENABLE_RESOLVER
|
||||
|
||||
#ifdef ENABLE_DETACH
|
||||
/** Indicates that the handler runs under SocketThread. */
|
||||
void SetSlave(bool x = true);
|
||||
/** Indicates that the handler runs under SocketThread. */
|
||||
bool IsSlave();
|
||||
#endif
|
||||
|
||||
protected:
|
||||
socket_m m_sockets; ///< Active sockets map
|
||||
std::list<Socket *> m_add; ///< Sockets to be added to sockets map
|
||||
std::list<Socket *> m_delete; ///< Sockets to be deleted (failed when Add)
|
||||
|
||||
protected:
|
||||
/** Actual call to select() */
|
||||
int ISocketHandler_Select(struct timeval *);
|
||||
/** Remove socket from socket map, used by Socket class. */
|
||||
void Remove(Socket *);
|
||||
/** Schedule socket for deletion */
|
||||
void DeleteSocket(Socket *);
|
||||
void AddIncoming();
|
||||
void CheckErasedSockets();
|
||||
void CheckCallOnConnect();
|
||||
void CheckDetach();
|
||||
void CheckTimeout(time_t);
|
||||
void CheckRetry();
|
||||
void CheckClose();
|
||||
//
|
||||
StdLog *m_stdlog; ///< Registered log class, or NULL
|
||||
IMutex& m_mutex; ///< Thread safety mutex
|
||||
bool m_b_use_mutex; ///< Mutex correctly initialized
|
||||
ISocketHandler& m_parent;
|
||||
bool m_b_parent_is_valid;
|
||||
|
||||
private:
|
||||
void RebuildFdset();
|
||||
void Set(Socket *,bool,bool);
|
||||
//
|
||||
std::list<SocketHandlerThread *> m_threads;
|
||||
UdpSocket *m_release;
|
||||
//
|
||||
SOCKET m_maxsock; ///< Highest file descriptor + 1 in active sockets list
|
||||
fd_set m_rfds; ///< file descriptor set monitored for read events
|
||||
fd_set m_wfds; ///< file descriptor set monitored for write events
|
||||
fd_set m_efds; ///< file descriptor set monitored for exceptions
|
||||
time_t m_tlast; ///< timeout control
|
||||
|
||||
// state lists
|
||||
std::list<socketuid_t> m_fds_erase; ///< File descriptors that are to be erased from m_sockets
|
||||
|
||||
bool m_b_check_callonconnect;
|
||||
bool m_b_check_detach;
|
||||
bool m_b_check_timeout;
|
||||
bool m_b_check_retry;
|
||||
bool m_b_check_close;
|
||||
|
||||
#ifdef ENABLE_SOCKS4
|
||||
ipaddr_t m_socks4_host; ///< Socks4 server host ip
|
||||
port_t m_socks4_port; ///< Socks4 server port number
|
||||
std::string m_socks4_userid; ///< Socks4 userid
|
||||
bool m_bTryDirect; ///< Try direct connection if socks4 server fails
|
||||
#endif
|
||||
#ifdef ENABLE_RESOLVER
|
||||
int m_resolv_id; ///< Resolver id counter
|
||||
ResolvServer *m_resolver; ///< Resolver thread pointer
|
||||
port_t m_resolver_port; ///< Resolver listen port
|
||||
std::map<socketuid_t, bool> m_resolve_q; ///< resolve queue
|
||||
#endif
|
||||
#ifdef ENABLE_POOL
|
||||
bool m_b_enable_pool; ///< Connection pool enabled if true
|
||||
#endif
|
||||
#ifdef ENABLE_DETACH
|
||||
bool m_slave; ///< Indicates that this is a ISocketHandler run in SocketThread
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _SOCKETS_SocketHandler_H
|
||||
|
||||
@@ -1,216 +0,0 @@
|
||||
/** \file SocketHandler.cpp
|
||||
** \date 2010-02-13
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2004-2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#include "SocketHandlerEp.h"
|
||||
#include "Exception.h"
|
||||
#include "IMutex.h"
|
||||
#include "Utility.h"
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
|
||||
SocketHandlerEp::SocketHandlerEp(StdLog *p)
|
||||
:SocketHandler(p)
|
||||
,m_epoll(-1)
|
||||
{
|
||||
#ifdef LINUX
|
||||
m_epoll = epoll_create(FD_SETSIZE);
|
||||
if (m_epoll == -1)
|
||||
{
|
||||
throw Exception(StrError(Errno));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
SocketHandlerEp::SocketHandlerEp(IMutex& mutex, StdLog *p)
|
||||
:SocketHandler(mutex, p)
|
||||
,m_epoll(-1)
|
||||
{
|
||||
#ifdef LINUX
|
||||
m_epoll = epoll_create(FD_SETSIZE);
|
||||
if (m_epoll == -1)
|
||||
{
|
||||
throw Exception(StrError(Errno));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
SocketHandlerEp::SocketHandlerEp(IMutex& mutex, ISocketHandler& parent, StdLog *p)
|
||||
:SocketHandler(mutex, parent, p)
|
||||
,m_epoll(-1)
|
||||
{
|
||||
#ifdef LINUX
|
||||
m_epoll = epoll_create(FD_SETSIZE);
|
||||
if (m_epoll == -1)
|
||||
{
|
||||
throw Exception(StrError(Errno));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
SocketHandlerEp::~SocketHandlerEp()
|
||||
{
|
||||
#ifdef LINUX
|
||||
if (m_epoll != -1)
|
||||
{
|
||||
close(m_epoll);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
ISocketHandler *SocketHandlerEp::Create(StdLog *log)
|
||||
{
|
||||
return new SocketHandlerEp(log);
|
||||
}
|
||||
|
||||
|
||||
ISocketHandler *SocketHandlerEp::Create(IMutex& mutex, ISocketHandler& parent, StdLog *log)
|
||||
{
|
||||
return new SocketHandlerEp(mutex, parent, log);
|
||||
}
|
||||
|
||||
|
||||
#ifdef LINUX
|
||||
void SocketHandlerEp::ISocketHandler_Add(Socket *p,bool bRead,bool bWrite)
|
||||
{
|
||||
struct epoll_event stat;
|
||||
SOCKET s = p -> GetSocket();
|
||||
stat.data.ptr = p;
|
||||
stat.events = (bRead ? EPOLLIN : 0) | (bWrite ? EPOLLOUT : 0);
|
||||
if (epoll_ctl(m_epoll, EPOLL_CTL_ADD, s, &stat) == -1)
|
||||
{
|
||||
LogError(NULL, "epoll_ctl: EPOLL_CTL_ADD", Errno, StrError(Errno));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SocketHandlerEp::ISocketHandler_Mod(Socket *p,bool r,bool w)
|
||||
{
|
||||
struct epoll_event stat;
|
||||
SOCKET s = p -> GetSocket();
|
||||
stat.data.ptr = p;
|
||||
stat.events = (r ? EPOLLIN : 0) | (w ? EPOLLOUT : 0);
|
||||
if (epoll_ctl(m_epoll, EPOLL_CTL_MOD, s, &stat) == -1)
|
||||
{
|
||||
// LogError(NULL, "epoll_ctl: EPOLL_CTL_MOD", Errno, StrError(Errno));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SocketHandlerEp::ISocketHandler_Del(Socket *p)
|
||||
{
|
||||
struct epoll_event stat;
|
||||
stat.events = 0;
|
||||
stat.data.ptr = p;
|
||||
if (epoll_ctl(m_epoll, EPOLL_CTL_DEL, p -> GetSocket(), &stat) == -1)
|
||||
{
|
||||
// LogError(NULL, "epoll_ctl: EPOLL_CTL_DEL", Errno, StrError(Errno));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int SocketHandlerEp::ISocketHandler_Select(struct timeval *tsel)
|
||||
{
|
||||
int n;
|
||||
if (m_b_use_mutex)
|
||||
{
|
||||
m_mutex.Unlock();
|
||||
n = epoll_wait(m_epoll, m_events, MAX_EVENTS_EP_WAIT, tsel ? tsel -> tv_sec * 1000 + tsel -> tv_usec / 1000 : -1);
|
||||
m_mutex.Lock();
|
||||
}
|
||||
else
|
||||
{
|
||||
n = epoll_wait(m_epoll, m_events, MAX_EVENTS_EP_WAIT, tsel ? tsel -> tv_sec * 1000 + tsel -> tv_usec / 1000 : -1);
|
||||
}
|
||||
if (n == -1)
|
||||
{
|
||||
LogError(NULL, "epoll_wait", Errno, StrError(Errno));
|
||||
}
|
||||
else
|
||||
if (!n)
|
||||
{
|
||||
}
|
||||
else
|
||||
if (n > 0)
|
||||
{
|
||||
for (int x = 0; x < n; x++)
|
||||
{
|
||||
Socket *p = static_cast<Socket *>(m_events[x].data.ptr);
|
||||
if ((m_events[x].events & EPOLLIN) || (m_events[x].events & EPOLLHUP))
|
||||
{
|
||||
#ifdef HAVE_OPENSSL
|
||||
if (p -> IsSSLNegotiate())
|
||||
{
|
||||
p -> SSLNegotiate();
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
p -> OnRead();
|
||||
}
|
||||
}
|
||||
if (m_events[x].events & EPOLLOUT)
|
||||
{
|
||||
#ifdef HAVE_OPENSSL
|
||||
if (p -> IsSSLNegotiate())
|
||||
{
|
||||
p -> SSLNegotiate();
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
p -> OnWrite();
|
||||
}
|
||||
}
|
||||
if (m_events[x].events & EPOLLERR)
|
||||
{
|
||||
p -> OnException();
|
||||
}
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,96 +0,0 @@
|
||||
/** \file SocketHandlerEp.h
|
||||
** \date 2010-02-13
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL, with
|
||||
the additional exemption that compiling, linking, and/or using OpenSSL
|
||||
is allowed.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef _SOCKETHANDLEREP_H
|
||||
#define _SOCKETHANDLEREP_H
|
||||
|
||||
#include "SocketHandler.h"
|
||||
#ifdef LINUX
|
||||
#include <sys/epoll.h>
|
||||
|
||||
#define MAX_EVENTS_EP_WAIT 100
|
||||
#endif // LINUX
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
class SocketHandlerEp : public SocketHandler
|
||||
{
|
||||
public:
|
||||
/** SocketHandler constructor.
|
||||
\param log Optional log class pointer */
|
||||
SocketHandlerEp(StdLog *log = NULL);
|
||||
|
||||
/** SocketHandler threadsafe constructor.
|
||||
\param mutex Externally declared mutex variable
|
||||
\param log Optional log class pointer */
|
||||
SocketHandlerEp(IMutex& mutex,StdLog *log = NULL);
|
||||
|
||||
SocketHandlerEp(IMutex&, ISocketHandler& parent, StdLog * = NULL);
|
||||
|
||||
~SocketHandlerEp();
|
||||
|
||||
ISocketHandler *Create(StdLog * = NULL);
|
||||
ISocketHandler *Create(IMutex&, ISocketHandler&, StdLog * = NULL);
|
||||
|
||||
#ifdef LINUX
|
||||
|
||||
/** Set read/write/exception file descriptor sets (fd_set). */
|
||||
void ISocketHandler_Add(Socket *,bool bRead,bool bWrite);
|
||||
void ISocketHandler_Mod(Socket *,bool bRead,bool bWrite);
|
||||
void ISocketHandler_Del(Socket *);
|
||||
|
||||
size_t MaxCount() {
|
||||
return 10000; // %!
|
||||
}
|
||||
|
||||
protected:
|
||||
/** Actual call to select() */
|
||||
int ISocketHandler_Select(struct timeval *);
|
||||
#endif // LINUX
|
||||
|
||||
private:
|
||||
int m_epoll; ///< epoll file descriptor
|
||||
#ifdef LINUX
|
||||
struct epoll_event m_events[MAX_EVENTS_EP_WAIT];
|
||||
|
||||
#endif // LINUX
|
||||
|
||||
};
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _SOCKETHANDLEREP_H
|
||||
@@ -1,81 +0,0 @@
|
||||
/**
|
||||
** \file SocketHandlerThread.cpp
|
||||
** \date 2010-03-21
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#include "SocketHandlerThread.h"
|
||||
#include "Mutex.h"
|
||||
#include "ISocketHandler.h"
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
|
||||
SocketHandlerThread::SocketHandlerThread(ISocketHandler& parent) : Thread(false)
|
||||
, m_parent(parent)
|
||||
, m_handler(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
SocketHandlerThread::~SocketHandlerThread()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ISocketHandler& SocketHandlerThread::Handler()
|
||||
{
|
||||
return *m_handler;
|
||||
}
|
||||
|
||||
|
||||
void SocketHandlerThread::Run()
|
||||
{
|
||||
Mutex mutex;
|
||||
m_handler = m_parent.Create(mutex, m_parent);
|
||||
m_sem.Post();
|
||||
ISocketHandler& h = *m_handler;
|
||||
h.EnableRelease();
|
||||
while (IsRunning())
|
||||
{
|
||||
h.Select(1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SocketHandlerThread::Wait()
|
||||
{
|
||||
m_sem.Wait();
|
||||
}
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
} // namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
@@ -1,68 +0,0 @@
|
||||
/**
|
||||
** \file SocketHandlerThread.h
|
||||
** \date 2010-03-21
|
||||
** \author grymse@alhem.net
|
||||
**/
|
||||
/*
|
||||
Copyright (C) 2010 Anders Hedstrom
|
||||
|
||||
This library is made available under the terms of the GNU GPL.
|
||||
|
||||
If you would like to use this library in a closed-source application,
|
||||
a separate license agreement is available. For information about
|
||||
the closed-source license agreement for the C++ sockets library,
|
||||
please visit http://www.alhem.net/Sockets/license.html and/or
|
||||
email license@alhem.net.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef _SOCKETHANDLERTHREAD_H
|
||||
#define _SOCKETHANDLERTHREAD_H
|
||||
|
||||
#include "Thread.h"
|
||||
#include "Semaphore.h"
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
namespace SOCKETS_NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
class ISocketHandler;
|
||||
|
||||
class SocketHandlerThread : public Thread
|
||||
{
|
||||
public:
|
||||
SocketHandlerThread(ISocketHandler& parent);
|
||||
~SocketHandlerThread();
|
||||
|
||||
virtual void Run();
|
||||
|
||||
ISocketHandler& Handler();
|
||||
|
||||
void Wait();
|
||||
|
||||
private:
|
||||
ISocketHandler& m_parent;
|
||||
ISocketHandler *m_handler;
|
||||
Semaphore m_sem;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#ifdef SOCKETS_NAMESPACE
|
||||
} // namespace SOCKETS_NAMESPACE {
|
||||
#endif
|
||||
|
||||
#endif // _SOCKETHANDLERTHREAD_H
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user