3
Example simple image server using DIME,
4
Adapted by Ch. Aberger to demonstrate dime for Win32 IIS.
5
Copyright (C) 2000-2002 Robert A. van Engelen. All Rights Reserved.
6
Copyright (C) 2003 Christian T. Aberger.
8
Runs as mod_gsoap (http://www.aberger.at/SOAP) as IIS SOAP service
11
NOTE: THE SERVER WILL ONLY SEND FILES THAT ARE IN THE CURRENT DIR FOR
12
SECURITY REASONS. HOWEVER, THE AUTHOR IS NOT RESPONSIBLE FOR ANY DAMAGES
13
THAT MAY RESULT FROM THE USE OF THIS PROGRAM.
14
AND ALSO ABERGER IS RESPONSIBLE FOR NOTHING.
19
#include <sys/stat.h> // use fstat() for streaming DIME
20
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
23
#define MAX_FILE_SIZE (10000) // Max. file size
25
// streaming DIME callbacks for sending data to client.
26
static void *dime_read_open(struct soap*, void*, const char*, const char*, const char*);
27
static void dime_read_close(struct soap*, void*);
28
static size_t dime_read(struct soap*, void*, char*, size_t);
30
// streaming DIME callbacks for receiving data from client.
31
static void *dime_write_open(struct soap*, const char*, const char*, const char*);
32
static void dime_write_close(struct soap*, void*);
33
static int dime_write(struct soap*, void*, const char*, size_t);
38
/** This function is called by mod_gsoap after the dll was successfully loaded and before processing begins.
39
You can do any one-time initialization here.
41
int mod_gsoap_init() {
42
// todo: add your initialization code here
45
/** This function is called after all processing was done before dll is unloaded.
46
You can do any cleanup here.
48
int mod_gsoap_terminate() {
49
// todo: add your termination code here
56
int ns__getImage(struct soap *soap, char *name, xsd__base64Binary &image) {
57
/* in this sample, due to security reasons the file must be in the system's %TEMP% folder */
58
TCHAR szPath[_MAX_PATH];
59
if (0 == ::GetTempPath(sizeof szPath, szPath)) {
60
return soap_receiver_fault(soap, "cannot find the TEMP folder", NULL);
64
// do some checks on the file name to verify it is local:
65
if (!strchr(name, '/') && !strchr(name, '\\') && !strchr(name, ':')) {
67
fd = fopen(szPath, "rb");
70
char szMsg[MAX_PATH + 64];
71
strcpy(szMsg, "Cannot open file: ");
72
strcat(szMsg, szPath);
73
return soap_receiver_fault(soap, szMsg, NULL);
76
if (!fstat(fileno(fd), &sb) && sb.st_size > 0) { // since we can get the length of the file, we can stream it
77
soap->fdimereadopen = dime_read_open;
78
soap->fdimereadclose = dime_read_close;
79
soap->fdimeread = dime_read;
80
image.__ptr = (unsigned char*)fd; // must set to non-NULL (this is our fd handle which we need in the callbacks)
81
image.__size = sb.st_size; // must set size
82
} else { // don't know the size, so buffer it
83
image.__ptr = (unsigned char*)soap_malloc(soap, MAX_FILE_SIZE);
84
for (int i = 0; i < MAX_FILE_SIZE; i++) {
86
if ((c = fgetc(fd)) == EOF) {
94
image.type = "image/jpeg";
95
image.options = soap_dime_option(soap, 0, "My picture");
97
return soap_receiver_fault(soap, "Name required", NULL);
102
/** save a file sent by the client to our server */
103
static void *dime_read_open(struct soap *soap, void *handle, const char *id, const char *type, const char *options)
104
{ // 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.
105
// 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.
109
static void dime_read_close(struct soap *soap, void *handle)
110
{ fclose((FILE*)handle);
113
static size_t dime_read(struct soap *soap, void *handle, char *buf, size_t len)
114
{ return fread(buf, 1, len, (FILE*)handle);
117
int ns__putImage(struct soap *soap, char *name, xsd__base64Binary *image, int &status) {
119
TCHAR szPath[_MAX_PATH];
120
if (0 == ::GetTempPath(sizeof szPath, szPath)) {
121
return soap_receiver_fault(soap, "cannot find the TEMP folder", NULL);
123
strcat(szPath, "upload");
124
if (INVALID_FILE_ATTRIBUTES == ::GetFileAttributes(szPath)) {
125
::CreateDirectory(szPath, NULL); // create it if it ain't exist.
126
if (INVALID_FILE_ATTRIBUTES == ::GetFileAttributes(szPath)) {
127
return soap_receiver_fault(soap, "Failed to create output directory", szPath);
130
strcat(szPath, "\\");
131
strcat(szPath, name);
132
FILE *fp = fopen(szPath, "wb");
135
status = fwrite(image->__ptr, sizeof(char), image->__size, fp);
138
return soap_receiver_fault(soap, "Failed to open output file", szPath);
140
if (status != image->__size) {
141
return soap_receiver_fault(soap, "Failed to write all bytes to file.", szPath);