aboutsummaryrefslogtreecommitdiff
path: root/mod_gsoap/gsoap_win/isapi/samples/dime/dimeserver.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'mod_gsoap/gsoap_win/isapi/samples/dime/dimeserver.cpp')
-rw-r--r--mod_gsoap/gsoap_win/isapi/samples/dime/dimeserver.cpp144
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;
+}