diff options
Diffstat (limited to 'mod_gsoap/gsoap_win/isapi/samples/dime/dimeserver.cpp')
-rw-r--r-- | mod_gsoap/gsoap_win/isapi/samples/dime/dimeserver.cpp | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/mod_gsoap/gsoap_win/isapi/samples/dime/dimeserver.cpp b/mod_gsoap/gsoap_win/isapi/samples/dime/dimeserver.cpp new file mode 100644 index 0000000..eb59c5e --- /dev/null +++ b/mod_gsoap/gsoap_win/isapi/samples/dime/dimeserver.cpp @@ -0,0 +1,144 @@ +/* dimesrv.cpp + + Example simple image server using DIME, + Adapted by Ch. Aberger to demonstrate dime for Win32 IIS. + Copyright (C) 2000-2002 Robert A. van Engelen. All Rights Reserved. + Copyright (C) 2003 Christian T. Aberger. + + Runs as mod_gsoap (http://www.aberger.at/SOAP) as IIS SOAP service + Web service + + NOTE: THE SERVER WILL ONLY SEND FILES THAT ARE IN THE CURRENT DIR FOR + SECURITY REASONS. HOWEVER, THE AUTHOR IS NOT RESPONSIBLE FOR ANY DAMAGES + THAT MAY RESULT FROM THE USE OF THIS PROGRAM. + AND ALSO ABERGER IS RESPONSIBLE FOR NOTHING. +*/ + +#include "soapH.h" +#include "dime.nsmap" +#include <sys/stat.h> // use fstat() for streaming DIME +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +#include <windows.h> + +#define MAX_FILE_SIZE (10000) // Max. file size + +// streaming DIME callbacks for sending data to client. +static void *dime_read_open(struct soap*, void*, const char*, const char*, const char*); +static void dime_read_close(struct soap*, void*); +static size_t dime_read(struct soap*, void*, char*, size_t); + +// streaming DIME callbacks for receiving data from client. +static void *dime_write_open(struct soap*, const char*, const char*, const char*); +static void dime_write_close(struct soap*, void*); +static int dime_write(struct soap*, void*, const char*, size_t); + + +extern "C" { + +/** This function is called by mod_gsoap after the dll was successfully loaded and before processing begins. + You can do any one-time initialization here. +*/ +int mod_gsoap_init() { + // todo: add your initialization code here + return SOAP_OK; +} +/** This function is called after all processing was done before dll is unloaded. + You can do any cleanup here. +*/ +int mod_gsoap_terminate() { + // todo: add your termination code here + return SOAP_OK; +} + +} + + +int ns__getImage(struct soap *soap, char *name, xsd__base64Binary &image) { + /* in this sample, due to security reasons the file must be in the system's %TEMP% folder */ + TCHAR szPath[_MAX_PATH]; + if (0 == ::GetTempPath(sizeof szPath, szPath)) { + return soap_receiver_fault(soap, "cannot find the TEMP folder", NULL); + } + if (name) { + FILE *fd = NULL; + // do some checks on the file name to verify it is local: + if (!strchr(name, '/') && !strchr(name, '\\') && !strchr(name, ':')) { + strcat(szPath, name); + fd = fopen(szPath, "rb"); + } + if (!fd) { + char szMsg[MAX_PATH + 64]; + strcpy(szMsg, "Cannot open file: "); + strcat(szMsg, szPath); + return soap_receiver_fault(soap, szMsg, NULL); + } + struct stat sb; + if (!fstat(fileno(fd), &sb) && sb.st_size > 0) { // since we can get the length of the file, we can stream it + soap->fdimereadopen = dime_read_open; + soap->fdimereadclose = dime_read_close; + soap->fdimeread = dime_read; + image.__ptr = (unsigned char*)fd; // must set to non-NULL (this is our fd handle which we need in the callbacks) + image.__size = sb.st_size; // must set size + } else { // don't know the size, so buffer it + image.__ptr = (unsigned char*)soap_malloc(soap, MAX_FILE_SIZE); + for (int i = 0; i < MAX_FILE_SIZE; i++) { + int c; + if ((c = fgetc(fd)) == EOF) { + break; + } + image.__ptr[i] = c; + } + fclose(fd); + image.__size = i; + } + image.type = "image/jpeg"; + image.options = soap_dime_option(soap, 0, "My picture"); + } else { + return soap_receiver_fault(soap, "Name required", NULL); + } + return SOAP_OK; +} + +/** save a file sent by the client to our server */ +static void *dime_read_open(struct soap *soap, void *handle, const char *id, const char *type, const char *options) +{ // we should return NULL without setting soap->error if we don't want to use the streaming callback for this DIME attachment. The handle contains the non-NULL __ptr field value which should have been set in the application. + // the value of the handle can be changed and will be passed on to the fdimeread and fdimereadclose callbacks. The value will not affect the __ptr field. + return handle; +} + +static void dime_read_close(struct soap *soap, void *handle) +{ fclose((FILE*)handle); +} + +static size_t dime_read(struct soap *soap, void *handle, char *buf, size_t len) +{ return fread(buf, 1, len, (FILE*)handle); +} + +int ns__putImage(struct soap *soap, char *name, xsd__base64Binary *image, int &status) { + int nRet = SOAP_OK; + TCHAR szPath[_MAX_PATH]; + if (0 == ::GetTempPath(sizeof szPath, szPath)) { + return soap_receiver_fault(soap, "cannot find the TEMP folder", NULL); + } + strcat(szPath, "upload"); + if (INVALID_FILE_ATTRIBUTES == ::GetFileAttributes(szPath)) { + ::CreateDirectory(szPath, NULL); // create it if it ain't exist. + if (INVALID_FILE_ATTRIBUTES == ::GetFileAttributes(szPath)) { + return soap_receiver_fault(soap, "Failed to create output directory", szPath); + } + } + strcat(szPath, "\\"); + strcat(szPath, name); + FILE *fp = fopen(szPath, "wb"); + status = 0; + if (NULL != fp) { + status = fwrite(image->__ptr, sizeof(char), image->__size, fp); + fclose(fp); + } else { + return soap_receiver_fault(soap, "Failed to open output file", szPath); + } + if (status != image->__size) { + return soap_receiver_fault(soap, "Failed to write all bytes to file.", szPath); + } + return SOAP_OK; +} |