2010-10-07 15:35:36 +02:00
/*
2011-01-01 15:01:13 +01:00
* Copyright (C) 2008-2011 TrinityCore <http://www.trinitycore.org/>
2010-10-07 15:35:36 +02:00
*
* 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, see <http://www.gnu.org/licenses/>.
2010-07-23 09:26:23 +02:00
*/
#include "TCSoap.h"
#include "soapH.h"
#include "soapStub.h"
void TCSoapRunnable :: run ()
{
2010-07-23 11:27:04 +02:00
struct soap soap ;
soap_init ( & soap );
soap_set_imode ( & soap , SOAP_C_UTFSTRING );
soap_set_omode ( & soap , SOAP_C_UTFSTRING );
// check every 3 seconds if world ended
soap . accept_timeout = 3 ;
soap . recv_timeout = 5 ;
soap . send_timeout = 5 ;
2010-12-06 02:07:53 +01:00
if ( soap_bind ( & soap , m_host . c_str (), m_port , 100 ) < 0 )
2010-07-23 09:26:23 +02:00
{
2010-12-23 23:25:44 +01:00
sLog -> outError ( "TCSoap: couldn't bind to %s:%d" , m_host . c_str (), m_port );
2010-07-23 11:27:04 +02:00
exit ( - 1 );
2010-07-23 09:26:23 +02:00
}
2010-12-23 23:25:44 +01:00
sLog -> outString ( "TCSoap: bound to http://%s:%d" , m_host . c_str (), m_port );
2010-07-23 09:26:23 +02:00
2011-08-08 17:46:23 +02:00
while ( ! World :: IsStopped ())
2010-07-23 09:26:23 +02:00
{
2011-02-15 02:00:16 +01:00
if ( ! soap_valid_socket ( soap_accept ( & soap )))
2010-07-23 11:27:04 +02:00
continue ; // ran into an accept timeout
2010-07-23 09:26:23 +02:00
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_NETWORKIO , "TCSoap: accepted connection from IP=%d.%d.%d.%d" , ( int )( soap . ip >> 24 ) & 0xFF , ( int )( soap . ip >> 16 ) & 0xFF , ( int )( soap . ip >> 8 ) & 0xFF , ( int ) soap . ip & 0xFF );
2010-07-23 11:27:04 +02:00
struct soap * thread_soap = soap_copy ( & soap ); // make a safe copy
2010-07-23 09:26:23 +02:00
2010-07-23 11:27:04 +02:00
ACE_Message_Block * mb = new ACE_Message_Block ( sizeof ( struct soap * ));
2011-08-08 17:46:23 +02:00
ACE_OS :: memcpy ( mb -> wr_ptr (), & thread_soap , sizeof ( struct soap * ));
process_message ( mb );
2010-07-23 09:26:23 +02:00
}
2010-07-23 11:27:04 +02:00
soap_done ( & soap );
2010-07-23 09:26:23 +02:00
}
2011-08-08 17:46:23 +02:00
void TCSoapRunnable :: process_message ( ACE_Message_Block * mb )
2010-07-23 09:26:23 +02:00
{
2010-07-23 11:27:04 +02:00
ACE_TRACE ( ACE_TEXT ( "SOAPWorkingThread::process_message" ));
2010-07-23 09:26:23 +02:00
2010-07-23 11:27:04 +02:00
struct soap * soap ;
2011-08-08 17:46:23 +02:00
ACE_OS :: memcpy ( & soap , mb -> rd_ptr (), sizeof ( struct soap * ));
2010-07-23 11:27:04 +02:00
mb -> release ();
2010-07-23 09:26:23 +02:00
2010-07-23 11:27:04 +02:00
soap_serve ( soap );
soap_destroy ( soap ); // dealloc C++ data
soap_end ( soap ); // dealloc data and clean up
soap_done ( soap ); // detach soap struct
free ( soap );
2010-07-23 09:26:23 +02:00
}
/*
Code used for generating stubs:
int ns1__executeCommand(char* command, char** result);
*/
int ns1__executeCommand ( soap * soap , char * command , char ** result )
{
2010-07-23 11:27:04 +02:00
// security check
if ( ! soap -> userid || ! soap -> passwd )
2010-07-23 09:26:23 +02:00
{
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_NETWORKIO , "TCSoap: Client didn't provide login information" );
2010-07-23 11:27:04 +02:00
return 401 ;
2010-07-23 09:26:23 +02:00
}
2011-09-08 10:49:58 +02:00
uint32 accountId = AccountMgr :: GetId ( soap -> userid );
2010-07-23 11:27:04 +02:00
if ( ! accountId )
2010-07-23 09:26:23 +02:00
{
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_NETWORKIO , "TCSoap: Client used invalid username '%s'" , soap -> userid );
2010-07-23 11:27:04 +02:00
return 401 ;
2010-07-23 09:26:23 +02:00
}
2011-09-08 10:49:58 +02:00
if ( ! AccountMgr :: CheckPassword ( accountId , soap -> passwd ))
2010-07-23 09:26:23 +02:00
{
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_NETWORKIO , "TCSoap: invalid password for account '%s'" , soap -> userid );
2010-07-23 11:27:04 +02:00
return 401 ;
2010-07-23 09:26:23 +02:00
}
2011-09-08 10:49:58 +02:00
if ( AccountMgr :: GetSecurity ( accountId ) < SEC_ADMINISTRATOR )
2010-07-23 09:26:23 +02:00
{
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_NETWORKIO , "TCSoap: %s's gmlevel is too low" , soap -> userid );
2010-07-23 11:27:04 +02:00
return 403 ;
2010-07-23 09:26:23 +02:00
}
2010-07-23 11:27:04 +02:00
if ( ! command || !* command )
return soap_sender_fault ( soap , "Command mustn't be empty" , "The supplied command was an empty string" );
2010-07-23 09:26:23 +02:00
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_NETWORKIO , "TCSoap: got command '%s'" , command );
2010-07-23 11:27:04 +02:00
SOAPCommand connection ;
2010-07-23 09:26:23 +02:00
2010-07-23 11:27:04 +02:00
// commands are executed in the world thread. We have to wait for them to be completed
{
// CliCommandHolder will be deleted from world, accessing after queueing is NOT save
CliCommandHolder * cmd = new CliCommandHolder ( & connection , command , & SOAPCommand :: print , & SOAPCommand :: commandFinished );
2010-12-23 23:25:44 +01:00
sWorld -> QueueCliCommand ( cmd );
2010-07-23 11:27:04 +02:00
}
2010-07-23 09:26:23 +02:00
2010-07-23 11:27:04 +02:00
// wait for callback to complete command
2010-07-23 09:26:23 +02:00
2010-07-23 11:27:04 +02:00
int acc = connection . pendingCommands . acquire ();
if ( acc )
2010-07-23 09:26:23 +02:00
{
2010-12-23 23:25:44 +01:00
sLog -> outError ( "TCSoap: Error while acquiring lock, acc = %i, errno = %u" , acc , errno );
2010-07-23 09:26:23 +02:00
}
2010-07-23 11:27:04 +02:00
// alright, command finished
2010-07-23 09:26:23 +02:00
2010-07-23 11:27:04 +02:00
char * printBuffer = soap_strdup ( soap , connection . m_printBuffer . c_str ());
if ( connection . hasCommandSucceeded ())
2010-07-23 09:26:23 +02:00
{
2010-07-23 11:27:04 +02:00
* result = printBuffer ;
return SOAP_OK ;
2010-07-23 09:26:23 +02:00
}
2010-07-23 11:27:04 +02:00
else
return soap_sender_fault ( soap , printBuffer , printBuffer );
2010-07-23 09:26:23 +02:00
}
void SOAPCommand :: commandFinished ( void * soapconnection , bool success )
{
2010-07-23 11:27:04 +02:00
SOAPCommand * con = ( SOAPCommand * ) soapconnection ;
con -> setCommandSuccess ( success );
con -> pendingCommands . release ();
2010-07-23 09:26:23 +02:00
}
////////////////////////////////////////////////////////////////////////////////
//
// Namespace Definition Table
//
////////////////////////////////////////////////////////////////////////////////
struct Namespace namespaces [] =
2010-08-23 14:10:24 +02:00
{ { "SOAP-ENV" , "http://schemas.xmlsoap.org/soap/envelope/" , NULL , NULL }, // must be first
{ "SOAP-ENC" , "http://schemas.xmlsoap.org/soap/encoding/" , NULL , NULL }, // must be second
{ "xsi" , "http://www.w3.org/1999/XMLSchema-instance" , "http://www.w3.org/*/XMLSchema-instance" , NULL },
{ "xsd" , "http://www.w3.org/1999/XMLSchema" , "http://www.w3.org/*/XMLSchema" , NULL },
{ "ns1" , "urn:TC" , NULL , NULL }, // "ns1" namespace prefix
{ NULL , NULL , NULL , NULL }
2010-07-23 11:27:04 +02:00
};