📄 mtom-stream-test.c
字号:
\******************************************************************************/int run_client(int argc, char **argv){ struct soap soap; int ret = 0; soap_init1(&soap, SOAP_ENC_MTOM); /* Enable MTOM */ /* Set the MIME callbacks */ soap.fmimereadopen = mime_read_open; soap.fmimereadclose = mime_read_close; soap.fmimeread = mime_read; soap.fmimewriteopen = mime_client_write_open; soap.fmimewriteclose = mime_client_write_close; soap.fmimewrite = mime_client_write; /* Connect timeout value (sec) (not supported by Linux) */ soap.connect_timeout = 10; /* IO timeouts (sec) */ soap.send_timeout = 30; soap.recv_timeout = 30; /* Unix/Linux SIGPIPE, this is OS dependent: soap.accept_flags = SO_NOSIGPIPE; // some systems like this soap.socket_flags = MSG_NOSIGNAL; // others need this signal(SIGPIPE, sigpipe_handle); // or a sigpipe handler (more portable) */ switch (argv[1][1]) { case 'p': ret = client_putData(&soap, argc, argv); break; case 'g': ret = client_getData(&soap, argc, argv); break; default: fprintf(stderr, "Usage: mtom-stream-test -p file1 file2 file3 ...\n"); fprintf(stderr, " mtom-stream-test -g key1 key2 key3 ...\n"); } soap_destroy(&soap); soap_end(&soap); soap_done(&soap); return ret;}int open_data(struct soap *soap, const char *file, struct x__Data *data){ struct stat sb; FILE *fd = NULL; int size; soap_default_x__Data(soap, data); fd = fopen(file, "rb"); if (!fd) { fprintf(stderr, "Cannot open file %s\n", file); return soap->error = SOAP_EOF; } /* The handle for the streaming MIME callback is the open file fd */ data->xop__Include.__ptr = (unsigned char*)fd; if (!fstat(fileno(fd), &sb) && sb.st_size > 0) size = sb.st_size; else { /* File size is unknown, so must use HTTP chunking and set size = 0 */ soap_set_omode(soap, SOAP_IO_CHUNK); size = 0; } data->xop__Include.__size = size; data->xmime4__contentType = file_type(file); data->xop__Include.id = NULL; data->xop__Include.type = data->xmime4__contentType; data->xop__Include.options = NULL; return SOAP_OK;}int client_putData(struct soap *soap, int argc, char **argv){ int i; struct x__DataSet data; struct m__PutDataResponse response; data.__size = argc - 2; data.item = soap_malloc(soap, (argc - 2)*sizeof(struct x__Data)); for (i = 2; i < argc; i++) open_data(soap, argv[i], &data.item[i - 2]); if (soap_call_m__PutData(soap, endpoint, NULL, &data, &response)) soap_print_fault(soap, stderr); else { printf("Data stored with keys:\n"); for (i = 0; i < response.x__keys.__size; i++) printf("\t%s\n", response.x__keys.key[i]); printf("Use these keys to retrieve the data with -g key1 key2 ...\n"); } return soap->error;}int client_getData(struct soap *soap, int argc, char **argv){ int i; struct x__Keys keys; struct m__GetDataResponse response; keys.__size = argc - 2; keys.key = soap_malloc(soap, (argc - 2)*sizeof(char*)); for (i = 2; i < argc; i++) keys.key[i - 2] = argv[i]; /* Pass this information to the callbacks using the soap->user variable */ soap->user = (void*)keys.key; if (soap_call_m__GetData(soap, endpoint, NULL, &keys, &response)) soap_print_fault(soap, stderr); else printf("Data retrieved\n"); return soap->error;}/******************************************************************************\ * * Server Operations *\******************************************************************************/int m__PutData(struct soap *soap, struct x__DataSet *data, struct m__PutDataResponse *response){ int i; /* This operation is called AFTER the streaming MIME attachment callbacks handled the data. gSOAP switches to SOAP_IO_STORE when SOAP_IO_CHUNK (HTTP chunking) is not supported by the client. Since it is undesirable to use SOAP_IO_STORE to buffer the entire message, we reset it to the default SOAP_IO_BUFFER for socket connections. */ if ((soap->omode & SOAP_IO) == SOAP_IO_STORE) soap->omode = (soap->omode & ~SOAP_IO) | SOAP_IO_BUFFER; if (!data) return soap_sender_fault(soap, "No data", NULL); /* Set up array of keys to return a key for each data item saved */ response->x__keys.__size = data->__size; response->x__keys.key = soap_malloc(soap, data->__size*sizeof(char**)); /* Each key is stored in the mime_server_handle object, set by the callbacks and accessible through the data __ptr */ for (i = 0; i < data->__size; i++) { if (data->item[i].xop__Include.__ptr) { const char *key = ((struct mime_server_handle*)(data->item[i].xop__Include.__ptr))->key; const char *s; if (!key) return soap_sender_fault(soap, "Missing name", NULL); s = strrchr(key, '/'); if (!s) s = strrchr(key, '\\'); if (!s) s = key; else s++; response->x__keys.key[i] = soap_strdup(soap, s); } else response->x__keys.key[i] = "-"; } return SOAP_OK;}int m__GetData(struct soap *soap, struct x__Keys *keys, struct m__GetDataResponse *response){ int i; if ((soap->omode & SOAP_IO) == SOAP_IO_STORE) soap->omode = (soap->omode & ~SOAP_IO) | SOAP_IO_BUFFER; if (!keys) return soap_sender_fault(soap, "No keys", NULL); /* Set up array of attachments to return */ response->x__data.__size = keys->__size; response->x__data.item = soap_malloc(soap, keys->__size*sizeof(struct x__Data)); for (i = 0; i < keys->__size; ++i) open_data(soap, keys->key[i], &response->x__data.item[i]); return SOAP_OK;}/******************************************************************************\ * * Streaming MIME Callbacks *\******************************************************************************/void *mime_read_open(struct soap *soap, void *handle, const char *id, const char *type, const char *description){ FILE *fd = (FILE*)handle; /* we should return NULL without setting soap->error if we don't want to use the streaming callback for this MIME attachment. The handle contains the non-NULL __ptr field value of xop__Include which should have been set in the application. The return value of this function will be passed on to the fmimeread and fmimereadclose callbacks. The return value will not affect the value of the __ptr field. */ fprintf(stderr, "Opening streaming outbound MIME channel for id=%s type=%s\n", id, type); return (void*)fd;}size_t mime_read(struct soap *soap, void *handle, char *buf, size_t len){ return fread(buf, 1, len, (FILE*)handle);}void mime_read_close(struct soap *soap, void *handle){ fprintf(stderr, "Closing streaming outbound MIME channel\n"); fclose((FILE*)handle);}/******************************************************************************\ * * Server-Side Streaming MIME Callbacks *\******************************************************************************/void *mime_server_write_open(struct soap *soap, void *unused_handle, const char *id, const char *type, const char *description, enum soap_mime_encoding encoding){ /* Note: the 'unused_handle' is always NULL */ /* Return NULL without setting soap->error if we don't want to use the streaming callback for this DIME attachment */ const char *file; struct mime_server_handle *handle = soap_malloc(soap, sizeof(struct mime_server_handle)); if (!handle) { soap->error = SOAP_EOM; return NULL; } /* Create a new file */ file = tempnam(TMPDIR, "data"); /* The file name is also the key */ handle->key = soap_strdup(soap, file); handle->fd = fopen(file, "wb"); free((void*)file); if (!handle->fd) { soap->error = soap_sender_fault(soap, "Cannot save data to file", handle->key); soap->errnum = errno; /* get reason */ return NULL; } fprintf(stderr, "Saving file %s type %s\n", handle->key, type?type:""); return (void*)handle;}void mime_server_write_close(struct soap *soap, void *handle){ fclose(((struct mime_server_handle*)handle)->fd);}int mime_server_write(struct soap *soap, void *handle, const char *buf, size_t len){ FILE *fd = ((struct mime_server_handle*)handle)->fd; while (len) { size_t nwritten = fwrite(buf, 1, len, fd); if (!nwritten) { soap->errnum = errno; return SOAP_EOF; } len -= nwritten; buf += nwritten; } return SOAP_OK;}/******************************************************************************\ * * Client-Side Streaming MIME Callbacks *\******************************************************************************/void *mime_client_write_open(struct soap *soap, void *unused_handle, const char *id, const char *type, const char *description, enum soap_mime_encoding encoding){ /* Note: the 'unused_handle' is always NULL */ FILE *fd; const char *file; fprintf(stderr, "Opening streaming inbound MIME channel for id=%s type=%s\n", id, type); /* soap->user points to array of keys (strings) that are file names */ file = *(char**)soap->user; soap->user = (void*)(((char**)soap->user)++); fd = fopen(file, "wb"); if (!fd) soap->error = soap_receiver_fault(soap, "Cannot save data to file", file); return (void*)fd;}void mime_client_write_close(struct soap *soap, void *handle){ fprintf(stderr, "Closing streaming inbound MIME channel\n"); fclose((FILE*)handle);}int mime_client_write(struct soap *soap, void *handle, const char *buf, size_t len){ FILE *fd = (FILE*)handle; while (len) { size_t nwritten = fwrite(buf, 1, len, fd); if (!nwritten) { soap->errnum = errno; return SOAP_EOF; } len -= nwritten; buf += nwritten; } return SOAP_OK;}/******************************************************************************\ * * Misc *\******************************************************************************/char *file_type(const char *file){ int n = strlen(file); if (n > 4 && (!strcmp(file + n - 4, ".xml") || !strcmp(file + n - 4, ".xsd") || !strcmp(file + n - 5, ".wsdl"))) return "text/xml"; if (n > 4 && !strcmp(file + n - 4, ".jpg")) return "image/jpg"; return "*/*";}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -