OregonCore  revision 3611e8a-git
Your Favourite TBC server
OCSoap.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of the OregonCore Project. See AUTHORS file for Copyright information
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License as published by the
6  * Free Software Foundation; either version 2 of the License, or (at your
7  * option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include "OCSoap.h"
19 
20 #define POOL_SIZE 5
21 
23 {
24  // create pool
25  SOAPWorkingThread pool;
26  pool.activate (THR_NEW_LWP | THR_JOINABLE, POOL_SIZE);
27 
28  struct soap soap;
29  soap_init(&soap);
30  soap_set_imode(&soap, SOAP_C_UTFSTRING);
31  soap_set_omode(&soap, SOAP_C_UTFSTRING);
32 
33  // check every 3 seconds if world ended
34  soap.accept_timeout = 3;
35  soap.recv_timeout = 5;
36  soap.send_timeout = 5;
37  if (soap_bind(&soap, m_host.c_str(), m_port, 100) < 0)
38  {
39  sLog.outError("OCSoap: couldn't bind to %s:%d", m_host.c_str(), m_port);
40  pool.msg_queue()->deactivate();
41  pool.wait();
42  soap_done(&soap);
43  return;
44  }
45 
46  sLog.outString("OCSoap: bound to http://%s:%d", m_host.c_str(), m_port);
47 
48  while (!World::IsStopped())
49  {
50  if (!soap_valid_socket(soap_accept(&soap)))
51  continue; // ran into an accept timeout
52 
53  sLog.outDebug("OCSoap: 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);
54  struct soap* thread_soap = soap_copy(&soap);// make a safe copy
55 
56  ACE_Message_Block* mb = new ACE_Message_Block(sizeof(struct soap*));
57  ACE_OS::memcpy (mb->wr_ptr(), &thread_soap, sizeof(struct soap*));
58  pool.putq(mb);
59  }
60 
61  pool.msg_queue()->deactivate();
62  pool.wait();
63 
64  soap_done(&soap);
65 }
66 
67 void SOAPWorkingThread::process_message (ACE_Message_Block* mb)
68 {
69  ACE_TRACE (ACE_TEXT ("SOAPWorkingThread::process_message"));
70 
71  struct soap* soap;
72  ACE_OS::memcpy (&soap, mb->rd_ptr (), sizeof(struct soap*));
73  mb->release();
74 
75  soap_serve(soap);
76  soap_destroy(soap); // dealloc C++ data
77  soap_end(soap); // dealloc data and clean up
78  soap_done(soap); // detach soap struct
79  free(soap);
80 }
81 /*
82 Code used for generating stubs:
83 
84 int ns1__executeCommand(char* command, char** result);
85 */
86 int ns1__executeCommand(soap* soap, char* command, char** result)
87 {
88  // security check
89  if (!soap->userid || !soap->passwd)
90  {
91  sLog.outDebug("OCSoap: Client didn't provide login information");
92  return 401;
93  }
94 
95  uint32 accountId = sAccountMgr->GetId(soap->userid);
96  if (!accountId)
97  {
98  sLog.outDebug("OCSoap: Client used invalid username '%s'", soap->userid);
99  return 401;
100  }
101 
102  if (!sAccountMgr->CheckPassword(accountId, soap->passwd))
103  {
104  sLog.outDebug("OCSoap: invalid password for account '%s'", soap->userid);
105  return 401;
106  }
107 
108  if (sAccountMgr->GetSecurity(accountId) < SEC_ADMINISTRATOR)
109  {
110  sLog.outDebug("OCSoap: %s's gmlevel is too low", soap->userid);
111  return 403;
112  }
113 
114  if (!command || !*command)
115  return soap_sender_fault(soap, "Command must not be empty", "The supplied command was an empty string");
116 
117  sLog.outDebug("OCSoap: got command '%s'", command);
118  SOAPCommand connection;
119 
120  // commands are executed in the world thread. We have to wait for them to be completed
121  {
122  // CliCommandHolder will be deleted from world, accessing after queueing is NOT save
124  sWorld.QueueCliCommand(cmd);
125  }
126 
127  // wait for callback to complete command
128 
129  int acc = connection.pendingCommands.acquire();
130  if (acc)
131  sLog.outError("OCSoap: Error while acquiring lock, acc = %i, errno = %u", acc, errno);
132 
133  // alright, command finished
134 
135  char* printBuffer = soap_strdup(soap, connection.m_printBuffer.c_str());
136  if (connection.hasCommandSucceeded())
137  {
138  *result = printBuffer;
139  return SOAP_OK;
140  }
141  else
142  return soap_sender_fault(soap, printBuffer, printBuffer);
143 }
144 
145 
146 void SOAPCommand::commandFinished(void* soapconnection, bool success)
147 {
148  SOAPCommand* con = (SOAPCommand*)soapconnection;
149  con->setCommandSuccess(success);
150  con->pendingCommands.release();
151 }
152 
154 //
155 // Namespace Definition Table
156 //
158 
159 struct Namespace namespaces[] =
160 {
161  { "SOAP-ENV", "http://schemas.xmlsoap.org/soap/envelope/", NULL, NULL }, // must be first
162  { "SOAP-ENC", "http://schemas.xmlsoap.org/soap/encoding/", NULL, NULL }, // must be second
163  { "xsi", "http://www.w3.org/1999/XMLSchema-instance", "http://www.w3.org/*/XMLSchema-instance", NULL },
164  { "xsd", "http://www.w3.org/1999/XMLSchema", "http://www.w3.org/*/XMLSchema", NULL, },
165  { "ns1", "urn:Oregon", NULL, NULL }, // "ns1" namespace prefix
166  { NULL, NULL, NULL, NULL }
167 };
168 
ACE_Semaphore pendingCommands
Definition: OCSoap.h:94
int ns1__executeCommand(soap *soap, char *command, char **result)
Definition: OCSoap.cpp:86
uint16 m_port
Definition: OCSoap.h:45
void process_message(ACE_Message_Block *mb)
Definition: OCSoap.cpp:67
std::string m_host
Definition: OCSoap.h:44
struct Namespace namespaces[]
Definition: OCSoap.cpp:159
#define sLog
Log class singleton.
Definition: Log.h:187
static void print(void *callbackArg, const char *msg)
Definition: OCSoap.h:105
static bool IsStopped()
Definition: World.h:638
void setCommandSuccess(bool val)
Definition: OCSoap.h:96
static void commandFinished(void *callbackArg, bool success)
Definition: OCSoap.cpp:146
bool hasCommandSucceeded()
Definition: OCSoap.h:100
void run()
Definition: OCSoap.cpp:22
#define sAccountMgr
Definition: AccountMgr.h:60
#define sWorld
Definition: World.h:860
std::string m_printBuffer
Definition: OCSoap.h:113
ACE_UINT32 uint32
Definition: Define.h:71
#define POOL_SIZE
Definition: OCSoap.cpp:20