/* * * 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; }