/*
*
* ProLinga-Soap
*
* Copyright (C) 2002-2008 Xobas Software.
* All rights reserved.
*
* This file is part of ProLinga-Soap.
*
* ProLinga-Soap 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 3 of the License, or
* (at your option) any later version.
*
* ProLinga-Soap 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 ProLinga-Soap. If not, see .
*
* More information is available at the following addresses:
*
* Website : http://www.prolinga.org
*
* Email : prolinga-list@prolinga.org
*
*
*/
#include "SoapCommon.h"
#include "SoapConfig.hpp"
#include "soapH.h"
#include "ProLinga_4GL_Net.nsmap"
#include
void AddLogLine(char *logFile, char *formatString, ...)
{
va_list argp;
FILE *log;
struct tm ltime;
time_t t;
int year;
char logLine[255];
/* Initialize time data*/
time(&t);
ltime = *localtime(&t);
year = 1900 + ltime.tm_year;
/* Create log line string */
va_start(argp, formatString);
vsprintf(logLine, formatString, argp);
va_end(argp);
log = fopen(logFile, "a");
fprintf(log, "[%d-%02d-%02dT%02d:%02d:%02d] %s\n", year, ltime.tm_mon + 1 , ltime.tm_mday, ltime.tm_hour, ltime.tm_min, ltime.tm_sec, logLine);
fclose(log);
}
PlSoapService::PlSoapService()
{
/* Init */
}
PlSoapService::~PlSoapService()
{
/* Free */
}
int PlSoapService::soapServiceStart(char *serverhost, int serverport, int num_threads, int server_comp, char *log_file, int log_level)
{
struct soap gSoapEnv;
/* master and slave sockets */
int master, slave;
/* Set Defaults */
if ((strcmp(serverhost, "") == 0) || (serverhost == NULL))
serverhost = DEF_SERVICE_HOST;
if (serverport == 0)
serverport = DEF_SERVICE_PORT;
if (num_threads == 0)
num_threads = DEF_THREADS;
if (server_comp <= 0)
server_comp = 0;
else if (server_comp >= 9)
server_comp = 9;
if ((strcmp(log_file, "") == 0) || (log_file == NULL))
log_file = DEF_LOG_FILE;
if (log_level <= 0)
log_level = 0;
else if (log_level >= 5)
log_level = 5;
/* One runtime environment per thread */
struct soap* soap_thr[num_threads];
pthread_t tid[num_threads];
/* Service Start */
AddLogLine(log_file, "Start Service ...");
soap_init(&gSoapEnv);
gSoapEnv.encodingStyle = NULL;
master = soap_bind(&gSoapEnv, serverhost, serverport, 5);
if (master < 0)
{
soap_print_fault(&gSoapEnv, stderr);
exit(-1);
}
if (log_level >= 2)
{
AddLogLine(log_file, "Socket connection successful:");
AddLogLine(log_file, "master socket = %d", master);
}
for (int i = 0; i < num_threads; i++)
{
soap_thr[i] = NULL;
}
/* infinite loop */
for (;;)
{
for (int i = 0; i < num_threads; i++)
{
slave = soap_accept(&gSoapEnv);
if (slave < 0)
{
soap_print_fault(&gSoapEnv, stderr);
exit(-1);
}
//j = i - 1;
//if (j == -1)
//j = num_threads - 1;
//if (soap_thr[j] != NULL)
// printf("Compression ratio2: %f%% (in) %f%% (out)\n", 100*soap_thr[j]->z_ratio_in, 100*soap_thr[j]->z_ratio_out);
struct in_addr in;
in.s_addr = htonl(gSoapEnv.ip);
if (log_level >= 4)
{
AddLogLine(log_file, "%d accepted from %s socket:%d",
i, inet_ntoa (in), slave);
}
/* first time */
if (soap_thr[i] == NULL)
{
soap_thr[i] = soap_new();
if (soap_thr[i] == NULL)
{
soap_print_fault(&gSoapEnv, stderr);
exit(-1);
}
if (log_level >= 4)
AddLogLine(log_file, "Thread %d initialized", i);
}
else
{
/* already initialized, reuse soap environment */
pthread_join(tid[i], NULL);
if (log_level >= 4)
AddLogLine(log_file, "Thread %d completed", i);
/* free up old thread data */
//soap_free(soap_thr[i]);
//soap_dealloc(soap_thr[i], NULL);
soap_end(soap_thr[i]);
}
/* Set send compression level */
if (server_comp > 0)
{
soap_set_omode(soap_thr[i], SOAP_ENC_ZLIB);
soap_thr[i]->z_level = server_comp;
}
else
soap_clr_omode(soap_thr[i], SOAP_ENC_ZLIB);
soap_thr[i]->socket = slave;
pthread_create(&tid[i], NULL, (void*(*)(void*))soap_serve,(void*)soap_thr[i]);
if (log_level >= 4)
AddLogLine(log_file, "request served by thread #%d",i);
}
}
/* Return */
exit(0);
}
PlSoapProcess::PlSoapProcess()
{
/* Init */
processRequest = NULL;
processResponse = NULL;
}
PlSoapProcess::~PlSoapProcess()
{
/* Free */
if (processRequest != NULL)
xmlFreeDoc(processRequest);
if (processResponse != NULL)
xmlFreeDoc(processResponse);
}
xmlDocPtr PlSoapProcess::getRequest()
{
return processRequest;
}
void PlSoapProcess::putResponse(xmlDocPtr docRes)
{
if (processResponse != NULL)
xmlFreeDoc(processResponse);
processResponse = docRes;
}
xmlDocPtr PlSoapProcess::getResponse()
{
return processResponse;
}
void PlSoapProcess::putRequest(xmlDocPtr docReq)
{
if (processRequest != NULL)
xmlFreeDoc(processRequest);
processRequest = docReq;
}
int ns1__GetProLingaDocument(struct soap* gSoapEnv, XML pldoc1__RequestDoc, XML &pldoc1__ResponseDoc)
{
int length;
xmlNodePtr curResponse = NULL;
xmlBufferPtr bufResponse = NULL;
PlSoapProcess link;
/* DEBUG */
//printf("SOAP REQUEST %s\n", (XML)pldoc1__RequestDoc);
/* Parse string */
link.putRequest(xmlParseMemory((char *)pldoc1__RequestDoc, strlen((char *)pldoc1__RequestDoc)));
/* Execute Command */
PlSoapLink(&link);
/* Dump return doc to string */
bufResponse = xmlBufferCreate();
curResponse = xmlDocGetRootElement(link.getResponse());
xmlNodeDump(bufResponse, link.getResponse(), curResponse, 0, 1);
/* Return value */
length = strlen((char *)xmlBufferContent(bufResponse)) + 1;
pldoc1__ResponseDoc = (char *)soap_malloc(gSoapEnv, length);
strcpy(pldoc1__ResponseDoc, (char *)xmlBufferContent(bufResponse));
/* Cleanup return pointer */
xmlBufferFree(bufResponse);
/* Return */
return SOAP_OK;
}