2002-10-24 10:47:49 +00:00
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Name: BaseServ.cpp
|
|
|
|
// Purpose: Simple base Server
|
|
|
|
// Author: Guy
|
|
|
|
// Modified by:
|
|
|
|
// Created: 21/08/2002
|
|
|
|
// Copyright: (c) 2002 Guy
|
|
|
|
// Licence: wxWindows licence
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
// ==========================================================================
|
|
|
|
// declarations
|
|
|
|
// ==========================================================================
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------------
|
|
|
|
// headers
|
|
|
|
// --------------------------------------------------------------------------
|
|
|
|
|
2004-03-25 10:35:14 +00:00
|
|
|
#include "baseserv.h"
|
2002-10-24 10:47:49 +00:00
|
|
|
|
|
|
|
#include <wx/config.h>
|
2006-01-23 15:47:36 +00:00
|
|
|
#include <wx/filename.h>
|
2003-05-16 09:24:31 +00:00
|
|
|
#include <wx/image.h>
|
2002-10-24 10:47:49 +00:00
|
|
|
#include <wx/mimetype.h>
|
2007-08-21 09:07:11 +00:00
|
|
|
#include <wx/mstream.h>
|
2002-10-24 10:47:49 +00:00
|
|
|
#include <wx/sckstrm.h>
|
2007-08-21 09:07:11 +00:00
|
|
|
|
2004-03-25 12:12:11 +00:00
|
|
|
#ifdef WIN32
|
|
|
|
#include <wx/fileconf.h>
|
2004-03-25 10:35:14 +00:00
|
|
|
#endif
|
2002-10-24 10:47:49 +00:00
|
|
|
|
|
|
|
#include <wx/app.h>
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
// Utilities
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
|
2003-05-16 09:24:31 +00:00
|
|
|
TBaseServerApp& GetServerApp()
|
|
|
|
{
|
|
|
|
return (TBaseServerApp&)*wxTheApp;
|
|
|
|
}
|
|
|
|
|
2002-10-24 10:47:49 +00:00
|
|
|
wxString Date2String(const wxDateTime& date)
|
|
|
|
{
|
|
|
|
return date.Format("%d-%m-%Y");
|
|
|
|
}
|
|
|
|
|
|
|
|
wxDateTime String2Date(const wxString& str)
|
|
|
|
{
|
|
|
|
int d, m, y;
|
|
|
|
sscanf(str, "%d-%d-%d", &d, &m, &y);
|
|
|
|
wxDateTime date(d, wxDateTime::Month(m-1), y);
|
|
|
|
return date;
|
|
|
|
}
|
|
|
|
|
2002-12-20 17:08:30 +00:00
|
|
|
wxSocketBase& operator<<(wxSocketBase& outf, const wxChar* str)
|
|
|
|
{
|
|
|
|
if (str && *str)
|
2007-08-21 09:07:11 +00:00
|
|
|
outf.Write(str, (wxUint32)wxStrlen(str));
|
2002-12-20 17:08:30 +00:00
|
|
|
return outf;
|
|
|
|
}
|
|
|
|
|
|
|
|
wxSocketBase& operator<<(wxSocketBase& outf, wxString str)
|
|
|
|
{
|
|
|
|
if (!str.IsEmpty())
|
2007-08-21 09:07:11 +00:00
|
|
|
outf.Write(str, (wxUint32)str.Length());
|
2002-12-20 17:08:30 +00:00
|
|
|
return outf;
|
|
|
|
}
|
|
|
|
|
|
|
|
wxSocketBase& operator<<(wxSocketBase& outf, size_t num)
|
|
|
|
{
|
|
|
|
return outf << wxString::Format("%u", num);
|
|
|
|
}
|
|
|
|
|
2002-10-24 10:47:49 +00:00
|
|
|
// --------------------------------------------------------------------------
|
|
|
|
// classes
|
|
|
|
// --------------------------------------------------------------------------
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
// THashTable
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
void THashTable::Put(const wxString& key, const wxString& value)
|
|
|
|
{
|
|
|
|
THashString* entry = new THashString(value);
|
|
|
|
m_Hash.Put(key, entry);
|
|
|
|
}
|
|
|
|
|
|
|
|
wxString THashTable::Get(const wxChar* key) const
|
|
|
|
{
|
|
|
|
wxString strValue;
|
|
|
|
THashString* str = (THashString*)m_Hash.Get(key);
|
|
|
|
if (str != NULL)
|
|
|
|
strValue = str->m_str;
|
|
|
|
return strValue;
|
|
|
|
}
|
|
|
|
|
|
|
|
THashTable::THashTable(size_t size) : m_Hash(wxKEY_STRING, size)
|
|
|
|
{
|
|
|
|
m_Hash.DeleteContents(true);
|
|
|
|
}
|
|
|
|
|
2003-05-16 09:24:31 +00:00
|
|
|
#ifdef WIN32
|
|
|
|
|
2002-10-24 10:47:49 +00:00
|
|
|
///////////////////////////////////////////////////////////
|
2003-05-16 09:24:31 +00:00
|
|
|
// TTaskbarIcon
|
2002-10-24 10:47:49 +00:00
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
|
2003-05-16 09:24:31 +00:00
|
|
|
BEGIN_EVENT_TABLE(TTaskBarIcon, wxTaskBarIcon)
|
|
|
|
EVT_TASKBAR_LEFT_DOWN(TTaskBarIcon::OnTaskBarClick)
|
|
|
|
END_EVENT_TABLE()
|
|
|
|
|
2007-08-21 09:07:11 +00:00
|
|
|
void TTaskBarIcon::OnTaskBarClick(wxTaskBarIconEvent& WXUNUSED(e))
|
2002-10-24 10:47:49 +00:00
|
|
|
{
|
2003-05-16 09:24:31 +00:00
|
|
|
wxString url;
|
2007-08-21 09:07:11 +00:00
|
|
|
// wxIPV4address addr; addr.AnyAddress();
|
|
|
|
// addr.Service(GetServerApp().GetDefaultPort());
|
|
|
|
// url << addr.Hostname() << ":" << addr.Service();
|
2003-05-16 09:24:31 +00:00
|
|
|
url << "http://127.0.0.1:" << GetServerApp().GetDefaultPort();
|
2007-08-21 09:07:11 +00:00
|
|
|
|
2003-05-16 09:24:31 +00:00
|
|
|
::ShellExecute(0, "open", url, NULL, NULL, SW_SHOWNORMAL);
|
2002-10-24 10:47:49 +00:00
|
|
|
}
|
|
|
|
|
2003-05-16 09:24:31 +00:00
|
|
|
void TTaskBarIcon::Init()
|
|
|
|
{
|
|
|
|
const TBaseServerApp& a = GetServerApp();
|
|
|
|
wxIcon icon;
|
|
|
|
|
|
|
|
const wxString strIcon = a.GetConfigString("Icon");
|
|
|
|
if (wxFileExists(strIcon))
|
|
|
|
{
|
|
|
|
wxInitAllImageHandlers();
|
|
|
|
wxImage img(strIcon);
|
|
|
|
img.Rescale(32,32);
|
2006-08-01 12:38:52 +00:00
|
|
|
const wxBitmap bmp(img);
|
2006-04-13 11:47:04 +00:00
|
|
|
icon.CopyFromBitmap(bmp);
|
2003-05-16 09:24:31 +00:00
|
|
|
}
|
|
|
|
else
|
2006-08-01 12:38:52 +00:00
|
|
|
icon.LoadFile("soap", wxBITMAP_TYPE_ICO_RESOURCE);
|
2003-05-16 09:24:31 +00:00
|
|
|
|
|
|
|
SetIcon(icon, a.GetAppName());
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
// TBaseServerApp
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
|
2002-10-24 10:47:49 +00:00
|
|
|
enum
|
|
|
|
{
|
|
|
|
SERVER_ID = 1001,
|
|
|
|
SOCKET_ID = 1002
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
BEGIN_EVENT_TABLE(TBaseServerApp, wxApp)
|
|
|
|
EVT_SOCKET(SERVER_ID, TBaseServerApp::OnServerEvent)
|
|
|
|
EVT_SOCKET(SOCKET_ID, TBaseServerApp::OnSocketEvent)
|
2008-04-30 15:49:26 +00:00
|
|
|
EVT_IDLE(TBaseServerApp::OnIdle)
|
2002-10-24 10:47:49 +00:00
|
|
|
END_EVENT_TABLE()
|
|
|
|
|
|
|
|
void TBaseServerApp::WriteLog(const wxChar* str) const
|
|
|
|
{
|
|
|
|
if (m_log != NULL)
|
|
|
|
*m_log << str << endl;
|
|
|
|
}
|
|
|
|
|
2008-05-01 09:08:35 +00:00
|
|
|
wxString TBaseServerApp::GetTempFilename(const wxChar * ext)
|
2002-10-24 10:47:49 +00:00
|
|
|
{
|
|
|
|
wxString strTmp;
|
|
|
|
if (m_strTempDir.IsEmpty())
|
|
|
|
{
|
|
|
|
const wxString strPrefix = "Srv";
|
|
|
|
::wxGetTempFileName(strPrefix, strTmp);
|
|
|
|
::wxRemoveFile(strTmp);
|
|
|
|
(wxString&)m_strTempDir << ::wxPathOnly(strTmp) << "/";
|
|
|
|
}
|
|
|
|
strTmp = m_strTempDir;
|
2008-05-01 09:08:35 +00:00
|
|
|
strTmp += wxString::Format("%s_%d.%s", GetAppName(), m_nTmpCounter, ext);
|
2002-10-24 10:47:49 +00:00
|
|
|
m_nTmpCounter++;
|
2008-05-01 09:08:35 +00:00
|
|
|
if (m_nTmpCounter >= 32)
|
2002-10-24 10:47:49 +00:00
|
|
|
m_nTmpCounter = 0;
|
|
|
|
|
|
|
|
return strTmp;
|
|
|
|
}
|
|
|
|
|
|
|
|
TXmlItem& TBaseServerApp::AddLogo(TXmlItem& tr) const
|
|
|
|
{
|
|
|
|
TXmlItem& td = tr.AddChild("td");
|
|
|
|
td.SetAttr("width", "15%");
|
|
|
|
td.SetAttr("align", "center");
|
|
|
|
|
|
|
|
TXmlItem& a = td.AddChild("a");
|
|
|
|
a.SetAttr("href", "/index.htm");
|
|
|
|
|
|
|
|
const wxString gif = GetConfigString("Icon", "euro.gif");
|
|
|
|
TXmlItem& img = a.AddChild("img");
|
|
|
|
img.SetAttr("src", gif);
|
|
|
|
img.SetAttr("border", "0");
|
|
|
|
img.SetAttr("alt", "Return to Home Page");
|
|
|
|
|
|
|
|
return td;
|
|
|
|
}
|
|
|
|
|
|
|
|
TXmlItem& TBaseServerApp::CreatePageBody(TXmlItem& html, wxString header) const
|
|
|
|
{
|
|
|
|
if (header.IsEmpty())
|
|
|
|
header << GetAppName() << " Server";
|
|
|
|
|
|
|
|
html.SetTag("html");
|
|
|
|
|
|
|
|
TXmlItem& head = html.AddChild("head");
|
|
|
|
TXmlItem& meta1 = head.AddChild("meta");
|
|
|
|
meta1.SetAttr("name", "GENERATOR");
|
|
|
|
meta1.SetAttr("content", GetAppName());
|
|
|
|
TXmlItem& meta2 = head.AddChild("meta");
|
|
|
|
meta2.SetAttr("HTTP-EQUIV", "Content-Type");
|
|
|
|
meta2.SetAttr("content", "text/html; charset=iso-8859-1");
|
|
|
|
head.AddChild("title") << header;
|
|
|
|
|
|
|
|
TXmlItem& body = html.AddChild("body");
|
2002-12-20 17:08:30 +00:00
|
|
|
body.SetAttr("bgcolor", "#EFCEAD");
|
|
|
|
if (m_bRunning)
|
|
|
|
body.SetAttr("background", "back.gif");
|
2002-10-24 10:47:49 +00:00
|
|
|
|
|
|
|
TXmlItem& title = body.AddChild("table");
|
|
|
|
title.SetAttr("border", "5"); title.SetAttr("width", "100%");
|
|
|
|
TXmlItem& title_tr = title.AddChild("tr");
|
|
|
|
|
|
|
|
if (m_bRunning)
|
|
|
|
AddLogo(title_tr);
|
|
|
|
|
|
|
|
TXmlItem& td1 = title_tr.AddChild("td");
|
|
|
|
td1.AddChild("h1").AddChild("center") << header;
|
|
|
|
|
|
|
|
if (m_bRunning)
|
|
|
|
AddLogo(title_tr);
|
|
|
|
|
|
|
|
body.AddChild("br");
|
|
|
|
return body;
|
|
|
|
}
|
|
|
|
|
|
|
|
TXmlItem& TBaseServerApp::AddLinkButton(TXmlItem& body, const wxChar* strCaption, const wxChar* strHref) const
|
|
|
|
{
|
|
|
|
TXmlItem& table = body.AddChild("table");
|
|
|
|
table.SetAttr("border", "2"); table.SetAttr("bgcolor", "#C0C0C0");
|
|
|
|
|
|
|
|
TXmlItem& td = table.AddChild("tr").AddChild("td");
|
|
|
|
td.SetAttr("align", "center");
|
|
|
|
td.AddChild("a").SetAttr("href", strHref) << strCaption;
|
|
|
|
|
|
|
|
return table;
|
|
|
|
}
|
|
|
|
|
|
|
|
void TBaseServerApp::MessageBox(const wxChar* caption, const wxChar* msg, wxSocketBase& outs)
|
|
|
|
{
|
|
|
|
TXmlItem html;
|
|
|
|
TXmlItem& body = CreatePageBody(html);
|
|
|
|
|
|
|
|
TXmlItem& table = body.AddChild("center").AddChild("table");
|
|
|
|
table.SetAttr("width", "70%"); table.SetAttr("border", "2");
|
|
|
|
table.AddChild("caption").AddChild("h2") << caption;
|
|
|
|
|
|
|
|
TXmlItem& td0 = table.AddChild("tr").AddChild("td");
|
|
|
|
td0.SetAttr("align", "justify");
|
|
|
|
td0.AddChild("h3") << msg;
|
|
|
|
|
|
|
|
TXmlItem& td1 = table.AddChild("tr").AddChild("td");
|
|
|
|
td1.SetAttr("align", "center");
|
|
|
|
AddLinkButton(td1, "Return to main page", "index.htm");
|
|
|
|
|
|
|
|
const wxString strTmp = GetTempFilename();
|
|
|
|
html.Save(strTmp);
|
|
|
|
SendFile(strTmp, outs);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool TBaseServerApp::CanProcessCommand(wxString& cmd, wxSocketBase& outs)
|
|
|
|
{
|
|
|
|
if (cmd.Find("stop.cgi") > 0)
|
|
|
|
{
|
|
|
|
m_bRunning = false; // Disable gif on title
|
2008-05-30 10:36:34 +00:00
|
|
|
if (outs.IsOk())
|
|
|
|
MessageBox("Warning!", "Server Stopped", outs);
|
2002-10-24 10:47:49 +00:00
|
|
|
ExitMainLoop();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2002-12-20 17:08:30 +00:00
|
|
|
void TBaseServerApp::SendContent(wxFileInputStream& inf, wxSocketBase& sock)
|
|
|
|
{
|
|
|
|
const size_t nSize = inf.GetSize();
|
2007-08-21 09:07:11 +00:00
|
|
|
WriteLog(wxString::Format("Sending %lu bytes", nSize));
|
2002-12-20 17:08:30 +00:00
|
|
|
|
2007-08-21 09:07:11 +00:00
|
|
|
const size_t BUF_TEMP_SIZE = 1024*1024; // was 1024*16
|
2002-12-20 17:08:30 +00:00
|
|
|
char* buf = new char[BUF_TEMP_SIZE];
|
|
|
|
size_t bytes = BUF_TEMP_SIZE;
|
|
|
|
size_t nTotalWritten = 0;
|
|
|
|
while (bytes == BUF_TEMP_SIZE)
|
|
|
|
{
|
|
|
|
bytes = inf.Read(buf, bytes).LastRead();
|
2007-08-21 09:07:11 +00:00
|
|
|
size_t nWritten = sock.Write(buf, wxUint32(bytes)).LastCount();
|
2002-12-20 17:08:30 +00:00
|
|
|
nTotalWritten += nWritten;
|
|
|
|
}
|
|
|
|
delete buf;
|
|
|
|
|
|
|
|
if (nTotalWritten < nSize)
|
2007-08-21 09:07:11 +00:00
|
|
|
WriteLog(wxString::Format("I sent %lu of %lu bytes only.", nTotalWritten, nSize));
|
2002-12-20 17:08:30 +00:00
|
|
|
}
|
|
|
|
|
2002-10-24 10:47:49 +00:00
|
|
|
void TBaseServerApp::SendFile(wxString strFilename, wxSocketBase& sock)
|
|
|
|
{
|
|
|
|
const bool bFound = wxFileExists(strFilename);
|
|
|
|
if (!bFound)
|
|
|
|
{
|
|
|
|
const wxString strTmp = GetTempFilename();
|
|
|
|
if (!strTmp.IsEmpty())
|
|
|
|
{
|
|
|
|
TXmlItem html;
|
|
|
|
TXmlItem& body = CreatePageBody(html);
|
|
|
|
body.AddChild("h1") << "Sorry: File not found!";
|
|
|
|
body.AddChild("br");
|
|
|
|
body.AddChild("h2") << strFilename;
|
|
|
|
html.Save(strTmp);
|
|
|
|
}
|
|
|
|
strFilename = strTmp;
|
|
|
|
}
|
|
|
|
|
|
|
|
wxString strType;
|
|
|
|
wxSplitPath(strFilename, NULL, NULL, &strType);
|
|
|
|
wxFileType* type = wxTheMimeTypesManager->GetFileTypeFromExtension(strType);
|
|
|
|
if (type != NULL)
|
|
|
|
type->GetMimeType(&strType);
|
|
|
|
else
|
|
|
|
strType = "text/plain";
|
|
|
|
const wxDateTime date = ::wxFileModificationTime(strFilename);
|
|
|
|
|
2002-12-20 17:08:30 +00:00
|
|
|
wxFileInputStream inf(strFilename);
|
|
|
|
const size_t nSize = inf.GetSize();
|
|
|
|
|
2002-10-24 10:47:49 +00:00
|
|
|
if (bFound)
|
2002-12-20 17:08:30 +00:00
|
|
|
sock << "HTTP/1.1 200 OK\n";
|
2002-10-24 10:47:49 +00:00
|
|
|
else
|
2002-12-20 17:08:30 +00:00
|
|
|
sock << "HTTP/1.1 401 Not found\n";
|
|
|
|
sock << "Server: " << GetAppName() << "\n";
|
|
|
|
sock << "Host: " << wxGetFullHostName() << "\n";
|
2002-10-24 10:47:49 +00:00
|
|
|
if (bFound && m_bRunning)
|
2002-12-20 17:08:30 +00:00
|
|
|
sock << "Connection: keep-alive\n";
|
2002-10-24 10:47:49 +00:00
|
|
|
else
|
2002-12-20 17:08:30 +00:00
|
|
|
sock << "Connection: close\n";
|
|
|
|
sock << "Content-Type: " << strType << "\n";
|
|
|
|
sock << "Content-Length: " << nSize << "\n";
|
|
|
|
sock << "Date: " << date.Format("%#c") << "\n";
|
2002-10-24 10:47:49 +00:00
|
|
|
|
2002-12-20 17:08:30 +00:00
|
|
|
wxDateTime dtFraUnPo = wxDateTime::Now();
|
|
|
|
const wxTimeSpan minuto(0, 1, 0); // Zero ore, Un minuto, Zero secondi
|
|
|
|
dtFraUnPo += minuto;
|
|
|
|
sock << "Expires: " << dtFraUnPo.Format("%#c") << "\n";
|
2002-10-24 10:47:49 +00:00
|
|
|
|
2002-12-20 17:08:30 +00:00
|
|
|
sock << "\n";
|
|
|
|
|
|
|
|
SendContent(inf, sock);
|
|
|
|
}
|
|
|
|
|
2007-08-21 09:07:11 +00:00
|
|
|
void TBaseServerApp::SoapProcessMethod(const TXmlItem& WXUNUSED(xmlMethod), TXmlItem& WXUNUSED(xmlAnswer))
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void TBaseServerApp::ProcessSoapCommand(wxString cmd, wxSocketBase& sock)
|
|
|
|
{
|
|
|
|
TXmlItem xmlEnvelope;
|
|
|
|
xmlEnvelope.SetTag("SOAP-ENV:Envelope");
|
|
|
|
TXmlItem& xmlBody = xmlEnvelope.AddChild("SOAP-ENV:Body");
|
|
|
|
|
|
|
|
const int soapstart = cmd.Find("<SOAP-ENV:");
|
|
|
|
if (soapstart > 0)
|
|
|
|
{
|
|
|
|
const size_t soaplen = cmd.length() - soapstart;
|
|
|
|
const char* buff = (const char*)cmd;
|
|
|
|
buff += soapstart;
|
|
|
|
wxMemoryInputStream input(buff, soaplen);
|
|
|
|
TXmlItem query;
|
|
|
|
if (query.Read(input))
|
|
|
|
{
|
|
|
|
const TXmlItem* pxmlBody = query.FindFirst("SOAP-ENV:Body");
|
|
|
|
if (pxmlBody != NULL) for (int m = 0; ; m++)
|
|
|
|
{
|
|
|
|
const TXmlItem* pxmlMethod = pxmlBody->GetChild(m);
|
|
|
|
if (pxmlMethod == NULL)
|
|
|
|
break;
|
|
|
|
if (pxmlMethod->GetTag().StartsWith("m:"))
|
|
|
|
{
|
|
|
|
wxString str = pxmlMethod->GetTag(); str += "Result";
|
|
|
|
TXmlItem& xmlAnswer = xmlBody.AddChild(str);
|
|
|
|
SoapProcessMethod(*pxmlMethod, xmlAnswer);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
const wxString strResult = xmlEnvelope.AsString();
|
|
|
|
|
|
|
|
sock << "HTTP/1.1 200 OK" << endl;
|
|
|
|
sock << "Connection: keep-alive" << endl;
|
|
|
|
sock << "Content-Length: " << strResult.Length() << endl;
|
|
|
|
sock << "Content-Type: text/xml; charset=utf-8" << endl;
|
|
|
|
sock << "Date: " << wxDateTime::Now().Format("%#c") << endl;
|
|
|
|
sock << "Server: " << GetAppName() << endl;
|
|
|
|
sock << "Host: " << wxGetFullHostName() << endl;
|
|
|
|
sock << endl;
|
|
|
|
sock << strResult;
|
|
|
|
}
|
|
|
|
|
|
|
|
void TBaseServerApp::ProcessHttpGet(wxString cmd, wxSocketBase& sock)
|
|
|
|
{
|
|
|
|
const int stop = cmd.Find(" HTTP");
|
|
|
|
wxString str = cmd.Mid(4, stop-4).Trim();
|
|
|
|
if (str == "/")
|
|
|
|
str += "index.htm";
|
|
|
|
wxString strFilename = GetDocumentRoot() + str;
|
|
|
|
SendFile(strFilename, sock);
|
|
|
|
}
|
|
|
|
|
|
|
|
void TBaseServerApp::ProcessFormCommand(wxString WXUNUSED(cmd),
|
|
|
|
wxSocketBase& WXUNUSED(sock))
|
|
|
|
{ }
|
|
|
|
|
2002-12-20 17:08:30 +00:00
|
|
|
void TBaseServerApp::SendNotModifiedFile(wxSocketBase& sock)
|
|
|
|
{
|
|
|
|
sock << "HTTP/1.1 304 Not Modified\n";
|
|
|
|
sock << "Date: " << wxDateTime::Now().Format("%#c") << "\n";
|
|
|
|
sock << "Server: " << GetAppName() << "\n";
|
|
|
|
sock << "Connection: close\n";
|
2002-10-24 10:47:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const wxChar* TBaseServerApp::GetAppName() const
|
|
|
|
{
|
|
|
|
// Pure virtual function
|
|
|
|
return "Server";
|
|
|
|
}
|
|
|
|
|
|
|
|
void TBaseServerApp::ProcessCommand(wxString cmd, wxSocketBase& outs)
|
|
|
|
{
|
2007-08-21 09:07:11 +00:00
|
|
|
if (cmd.StartsWith("POST "))
|
|
|
|
{
|
|
|
|
if (cmd.Find("SOAPAction") > 0)
|
|
|
|
ProcessSoapCommand(cmd, outs);
|
|
|
|
else
|
|
|
|
ProcessFormCommand(cmd, outs);
|
|
|
|
} else
|
|
|
|
if (cmd.StartsWith("GET "))
|
|
|
|
ProcessHttpGet(cmd, outs);
|
2002-10-24 10:47:49 +00:00
|
|
|
}
|
|
|
|
|
2007-12-18 16:22:22 +00:00
|
|
|
void TBaseServerApp::OnServerEvent(wxSocketEvent& e)
|
2002-10-24 10:47:49 +00:00
|
|
|
{
|
2002-12-20 17:08:30 +00:00
|
|
|
wxString s = "--- OnServerEvent: ";
|
2002-10-24 10:47:49 +00:00
|
|
|
|
2007-12-18 16:22:22 +00:00
|
|
|
switch(e.GetSocketEvent())
|
2002-10-24 10:47:49 +00:00
|
|
|
{
|
|
|
|
case wxSOCKET_CONNECTION : s.Append("wxSOCKET_CONNECTION"); break;
|
|
|
|
default : s.Append("Unexpected event!"); break;
|
|
|
|
}
|
|
|
|
|
|
|
|
WriteLog(s);
|
|
|
|
|
|
|
|
// Accept new connection if there is one in the pending
|
|
|
|
// connections queue, else exit. We use Accept(FALSE) for
|
|
|
|
// non-blocking accept (although if we got here, there
|
|
|
|
// should ALWAYS be a pending connection).
|
|
|
|
|
|
|
|
wxSocketBase* sock = m_server->Accept(FALSE);
|
|
|
|
if (sock)
|
|
|
|
{
|
2002-12-20 17:08:30 +00:00
|
|
|
WriteLog("--- New client connection accepted");
|
2002-10-24 10:47:49 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2002-12-20 17:08:30 +00:00
|
|
|
WriteLog("### Error: couldn't accept a new connection");
|
2002-10-24 10:47:49 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
sock->SetEventHandler(*this, SOCKET_ID);
|
|
|
|
sock->SetNotify(wxSOCKET_INPUT_FLAG | wxSOCKET_LOST_FLAG);
|
|
|
|
sock->Notify(TRUE);
|
|
|
|
}
|
|
|
|
|
2008-05-30 10:36:34 +00:00
|
|
|
struct TCommand : public wxObject
|
|
|
|
{
|
|
|
|
wxSocketBase * m_Sock;
|
|
|
|
wxString m_Command;
|
|
|
|
};
|
|
|
|
|
2007-08-21 09:07:11 +00:00
|
|
|
void TBaseServerApp::OnSocketEvent(wxSocketEvent& e)
|
2002-10-24 10:47:49 +00:00
|
|
|
{
|
2008-05-30 10:36:34 +00:00
|
|
|
wxSocketBase * sock = e.GetSocket();
|
2007-08-21 09:07:11 +00:00
|
|
|
switch(e.GetSocketEvent())
|
2002-10-24 10:47:49 +00:00
|
|
|
{
|
2007-08-21 09:07:11 +00:00
|
|
|
case wxSOCKET_INPUT:
|
2002-10-24 10:47:49 +00:00
|
|
|
{
|
|
|
|
// We disable input events, so that the test doesn't trigger
|
|
|
|
// wxSocketEvent again.
|
2008-05-30 10:36:34 +00:00
|
|
|
TCommand * message = new TCommand;
|
|
|
|
message->m_Sock = sock;
|
|
|
|
const size_t BUFSIZE = 1024;
|
|
|
|
wxChar buf[BUFSIZE + 1];
|
|
|
|
|
|
|
|
// Read the data
|
|
|
|
|
|
|
|
memset(buf, 0, sizeof(buf));
|
|
|
|
while (sock->Read(buf, BUFSIZE).LastCount() == BUFSIZE)
|
|
|
|
{
|
|
|
|
message->m_Command << buf;
|
|
|
|
memset(buf, 0, sizeof(buf));
|
|
|
|
}
|
|
|
|
message->m_Command << buf;
|
|
|
|
m_Sockets.Add(message);
|
2002-10-24 10:47:49 +00:00
|
|
|
}
|
2007-08-21 09:07:11 +00:00
|
|
|
break;
|
|
|
|
case wxSOCKET_LOST:
|
2008-05-30 10:36:34 +00:00
|
|
|
WriteLog("--- Socket lost.");
|
2007-08-21 09:07:11 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
2002-10-24 10:47:49 +00:00
|
|
|
}
|
|
|
|
}
|
2008-04-30 15:49:26 +00:00
|
|
|
void TBaseServerApp::OnIdle(wxIdleEvent& event)
|
|
|
|
{
|
|
|
|
if (m_Sockets.GetCount() > 0)
|
|
|
|
{
|
2008-05-30 10:36:34 +00:00
|
|
|
wxSocketBase& sock = *(((TCommand *) m_Sockets[0])->m_Sock);
|
|
|
|
const bool valid_socket = sock.IsOk();
|
|
|
|
if (valid_socket)
|
|
|
|
sock.SetNotify(wxSOCKET_LOST_FLAG);
|
2008-04-30 15:49:26 +00:00
|
|
|
|
2008-05-30 10:36:34 +00:00
|
|
|
wxString & str = ((TCommand *) m_Sockets[0])->m_Command;
|
2008-04-30 15:49:26 +00:00
|
|
|
WriteLog(str);
|
|
|
|
|
|
|
|
if (CanProcessCommand(str, sock))
|
|
|
|
{
|
|
|
|
const wxSocketFlags flags = sock.GetFlags();
|
2008-05-30 10:36:34 +00:00
|
|
|
if (valid_socket)
|
|
|
|
sock.SetFlags(wxSOCKET_WAITALL);
|
2008-04-30 15:49:26 +00:00
|
|
|
ProcessCommand(str, sock);
|
2008-05-30 10:36:34 +00:00
|
|
|
if (valid_socket)
|
|
|
|
sock.SetFlags(flags);
|
2008-04-30 15:49:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Enable input events again.
|
2008-05-30 10:36:34 +00:00
|
|
|
|
|
|
|
if (valid_socket)
|
|
|
|
{
|
|
|
|
sock.SetNotify(wxSOCKET_LOST_FLAG | wxSOCKET_INPUT_FLAG);
|
|
|
|
sock.Notify(TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
m_Sockets.RemoveAt(0);
|
2008-04-30 15:49:26 +00:00
|
|
|
}
|
|
|
|
wxApp::OnIdle(event);
|
|
|
|
}
|
2002-10-24 10:47:49 +00:00
|
|
|
|
2006-01-23 15:47:36 +00:00
|
|
|
const wxString& TBaseServerApp::GetConfigName() const
|
2002-10-24 10:47:49 +00:00
|
|
|
{
|
2006-01-23 15:47:36 +00:00
|
|
|
if (m_strIni.IsEmpty())
|
2006-07-11 13:10:51 +00:00
|
|
|
{
|
2007-08-21 09:07:11 +00:00
|
|
|
wxFileName name(argv[0]); // Prendo il persorso completo del server in esecuzione
|
|
|
|
name.SetName("servers"); // Trasformo il nome in servers ...
|
|
|
|
name.SetExt("ini"); // ... e l'esetensione in .ini
|
2006-07-11 13:10:51 +00:00
|
|
|
(wxString&)m_strIni = name.GetFullPath();
|
|
|
|
}
|
2006-01-23 15:47:36 +00:00
|
|
|
return m_strIni;
|
2002-10-24 10:47:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void TBaseServerApp::SetConfigString(const wxChar* key, const wxChar* val, const wxChar* app) const
|
|
|
|
{
|
2004-03-25 10:35:14 +00:00
|
|
|
wxFileConfig ini("", "", GetConfigName(), "", wxCONFIG_USE_LOCAL_FILE | wxCONFIG_USE_RELATIVE_PATH);
|
2002-10-24 10:47:49 +00:00
|
|
|
wxString str;
|
|
|
|
if (app == NULL || *app == '\0')
|
|
|
|
app = GetAppName();
|
|
|
|
str << '/' << app;
|
|
|
|
ini.SetPath(str);
|
|
|
|
ini.Write(key, val);
|
|
|
|
}
|
|
|
|
|
|
|
|
void TBaseServerApp::SetConfigInt(const wxChar* key, int val, const wxChar* app) const
|
|
|
|
{
|
2007-08-21 09:07:11 +00:00
|
|
|
wxString str; str.Printf("%d", val);
|
2002-10-24 10:47:49 +00:00
|
|
|
SetConfigString(key, str, app);
|
|
|
|
}
|
|
|
|
|
|
|
|
wxString TBaseServerApp::GetConfigString(const wxChar* key, const wxChar* def, const wxChar* app) const
|
|
|
|
{
|
2004-03-25 10:35:14 +00:00
|
|
|
wxFileConfig ini("", "", GetConfigName(), "", wxCONFIG_USE_LOCAL_FILE | wxCONFIG_USE_RELATIVE_PATH);
|
2002-10-24 10:47:49 +00:00
|
|
|
wxString str;
|
|
|
|
if (app == NULL || *app == '\0')
|
|
|
|
app = GetAppName();
|
|
|
|
str << '/' << app;
|
|
|
|
ini.SetPath(str);
|
|
|
|
ini.Read(key, &str, def);
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
|
|
|
int TBaseServerApp::GetConfigInt(const wxChar* key, int def, const wxChar* app) const
|
|
|
|
{
|
2006-07-11 13:10:51 +00:00
|
|
|
const wxString str = GetConfigString(key, "*", app);
|
|
|
|
return str != "*" ? atoi(str) : def;
|
2002-10-24 10:47:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool TBaseServerApp::GetConfigBool(const wxChar* key, bool def, const wxChar* app) const
|
|
|
|
{
|
|
|
|
bool val = def;
|
2006-01-23 15:47:36 +00:00
|
|
|
const wxString str = GetConfigString(key, "*", app);
|
2002-10-24 10:47:49 +00:00
|
|
|
if (str != "*")
|
2006-07-11 13:10:51 +00:00
|
|
|
val = (str[0u] == '1') || (str[0u] == 'X') || (str[0u] == 'Y') || (str.CmpNoCase("On") == 0);
|
2006-04-13 17:56:02 +00:00
|
|
|
|
2002-10-24 10:47:49 +00:00
|
|
|
return val;
|
|
|
|
}
|
|
|
|
|
|
|
|
int TBaseServerApp::GetDefaultPort() const
|
|
|
|
{
|
|
|
|
return GetConfigInt("Port", 3883);
|
|
|
|
}
|
|
|
|
|
|
|
|
wxString TBaseServerApp::GetLogFileName() const
|
|
|
|
{
|
|
|
|
return GetConfigString("LogFile");
|
|
|
|
}
|
|
|
|
|
|
|
|
wxString TBaseServerApp::GetDocumentRoot() const
|
|
|
|
{
|
2008-02-05 10:52:12 +00:00
|
|
|
return GetConfigString("DocumentRoot", m_strPath);
|
2002-10-24 10:47:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool TBaseServerApp::OnInit()
|
|
|
|
{
|
2002-12-20 17:08:30 +00:00
|
|
|
m_server = NULL;
|
|
|
|
m_log = NULL;
|
|
|
|
|
|
|
|
m_SingleInstance = new wxSingleInstanceChecker(GetAppName());
|
|
|
|
if (m_SingleInstance->IsAnotherRunning())
|
|
|
|
{
|
|
|
|
delete m_SingleInstance;
|
|
|
|
m_SingleInstance = NULL;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2008-02-05 10:52:12 +00:00
|
|
|
wxFileName::SplitPath(argv[0], &m_strPath, NULL, NULL);
|
|
|
|
if (!m_strPath.IsEmpty())
|
|
|
|
{
|
|
|
|
wxSetWorkingDirectory(m_strPath);
|
|
|
|
if (!wxEndsWithPathSeparator(m_strPath))
|
|
|
|
m_strPath += wxFILE_SEP_PATH;
|
|
|
|
}
|
2004-03-25 10:35:14 +00:00
|
|
|
|
2002-10-24 10:47:49 +00:00
|
|
|
// Create the address - defaults to localhost:0 initially
|
|
|
|
wxIPV4address addr;
|
2007-08-21 09:07:11 +00:00
|
|
|
addr.AnyAddress(); // I docs affermano che AnyAddress sia meglio di LocalHost
|
2002-10-24 10:47:49 +00:00
|
|
|
addr.Service(GetDefaultPort());
|
|
|
|
// Create the socket
|
|
|
|
m_server = new wxSocketServer(addr);
|
|
|
|
|
|
|
|
// Create the Log file
|
|
|
|
wxString str;
|
|
|
|
|
|
|
|
str = GetLogFileName();
|
|
|
|
if (!str.IsEmpty())
|
|
|
|
m_log = new wxFileOutputStream(str);
|
|
|
|
else
|
|
|
|
m_log = NULL;
|
|
|
|
|
|
|
|
m_nTmpCounter = 0;
|
|
|
|
|
|
|
|
// We use Ok() here to see if the server is really listening
|
|
|
|
str.Empty();
|
|
|
|
if (m_server->Ok())
|
|
|
|
{
|
|
|
|
// Setup the event handler and subscribe to connection events
|
|
|
|
m_server->SetEventHandler(*this, SERVER_ID);
|
|
|
|
m_server->SetNotify(wxSOCKET_CONNECTION_FLAG);
|
|
|
|
m_server->Notify(TRUE);
|
|
|
|
|
2007-08-21 09:07:11 +00:00
|
|
|
str << GetAppName() << " listening at " << addr.Hostname() << ":" << addr.Service();
|
2002-10-24 10:47:49 +00:00
|
|
|
m_bRunning = true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
str << GetAppName() << " could not listen to port " << addr.Service();
|
|
|
|
}
|
|
|
|
WriteLog(str);
|
|
|
|
|
|
|
|
bool ok = m_server->Ok();
|
|
|
|
if (ok)
|
|
|
|
ok = Initialization();
|
|
|
|
|
2003-05-16 09:24:31 +00:00
|
|
|
#ifdef WIN32
|
2003-09-11 07:16:13 +00:00
|
|
|
m_Tray = NULL;
|
|
|
|
if (ok)
|
|
|
|
{
|
|
|
|
m_Tray = new TTaskBarIcon;
|
|
|
|
m_Tray->Init();
|
|
|
|
}
|
2003-05-16 09:24:31 +00:00
|
|
|
#endif
|
|
|
|
|
2002-10-24 10:47:49 +00:00
|
|
|
return ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
int TBaseServerApp::OnExit()
|
|
|
|
{
|
|
|
|
if (m_server != NULL)
|
2002-12-20 17:08:30 +00:00
|
|
|
{
|
|
|
|
Deinitialization();
|
|
|
|
delete m_SingleInstance;
|
2002-10-24 10:47:49 +00:00
|
|
|
delete m_server;
|
2002-12-20 17:08:30 +00:00
|
|
|
}
|
2002-10-24 10:47:49 +00:00
|
|
|
if (m_log != NULL)
|
|
|
|
{
|
|
|
|
wxString str;
|
|
|
|
str << GetAppName() << " shutting down.";
|
|
|
|
WriteLog(str);
|
|
|
|
delete m_log;
|
|
|
|
}
|
2002-12-20 17:08:30 +00:00
|
|
|
|
2003-09-11 07:16:13 +00:00
|
|
|
#ifdef WIN32
|
|
|
|
if (m_Tray != NULL)
|
|
|
|
{
|
|
|
|
delete m_Tray;
|
|
|
|
m_Tray = NULL;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2002-10-24 10:47:49 +00:00
|
|
|
return wxApp::OnExit();
|
|
|
|
}
|
|
|
|
|
|
|
|
wxString TBaseServerApp::UnformatString(const wxString& strFormString) const
|
|
|
|
{
|
|
|
|
wxString strResult;
|
|
|
|
for (int i = 0; strFormString[i]; i++)
|
|
|
|
{
|
|
|
|
switch(strFormString[i])
|
|
|
|
{
|
|
|
|
case '+':
|
|
|
|
strResult += ' '; break;
|
|
|
|
case '%':
|
|
|
|
{
|
|
|
|
const wxChar c = hex2int(strFormString.Mid(i+1, 2));
|
|
|
|
strResult += c;
|
|
|
|
i += 2;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
strResult += strFormString[i]; break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return strResult;
|
|
|
|
}
|
|
|
|
|
2007-08-21 09:07:11 +00:00
|
|
|
size_t TBaseServerApp::ParseArguments(wxString args, THashTable& hashArgs) const
|
2002-10-24 10:47:49 +00:00
|
|
|
{
|
|
|
|
int uguale = args.Find('=');
|
|
|
|
while (uguale > 0)
|
|
|
|
{
|
|
|
|
wxString name = args.Left(uguale);
|
|
|
|
name.Trim(false); name.Trim(true);
|
|
|
|
|
|
|
|
wxString value;
|
|
|
|
const int acapo = args.Find('&');
|
|
|
|
if (acapo > uguale)
|
|
|
|
value = args.Mid(uguale+1, acapo-uguale-1);
|
|
|
|
else
|
|
|
|
value = args.Mid(uguale+1);
|
|
|
|
value.Trim(false); value.Trim(true);
|
|
|
|
hashArgs.Put(name, UnformatString(value));
|
|
|
|
|
|
|
|
if (acapo > 0)
|
|
|
|
{
|
|
|
|
args = args.Mid(acapo+1);
|
|
|
|
uguale = args.Find('=');
|
|
|
|
}
|
|
|
|
else
|
|
|
|
uguale = -1;
|
|
|
|
}
|
|
|
|
return hashArgs.GetCount();
|
|
|
|
}
|