/****************************************************************** * $Id: soap-client.c,v 1.16 2005/05/27 19:28:14 snowdrop Exp $ * * CSOAP Project: A SOAP client/server library in C * Copyright (C) 2003 Ferhat Ayaz * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. * * Email: ayaz@jprogrammer.net ******************************************************************/ #include #include #include /*--------------------------------- */ static int _block_socket = 0; static herror_t _soap_client_build_result(hresponse_t *res, SoapEnv **out); /*--------------------------------- */ void soap_client_block_socket(int block) { _block_socket = block; } int soap_client_get_blockmode() { return _block_socket; } herror_t soap_client_init_args(int argc, char *argv[]) { return httpc_init(argc, argv); } void soap_client_destroy() { httpc_destroy(); } static long _file_get_size(const char* filename) { FILE *f = fopen(filename, "r"); long size; if (!f) return -1; fseek(f, 0, SEEK_END); size=ftell(f); fclose(f); return size; } herror_t soap_client_invoke(SoapCtx *call, SoapCtx** response, const char *url, const char *soap_action) { /* Status */ herror_t status; /* Result document */ SoapEnv* res_env; /* Buffer variables*/ xmlBufferPtr buffer; char *content; char tmp[15]; /* Transport variables */ httpc_conn_t *conn; hresponse_t *res; /* multipart/related start id*/ char start_id[150]; static int counter=1; part_t *part; /* for copy attachments */ char href[MAX_HREF_SIZE]; /* Create buffer */ buffer = xmlBufferCreate(); xmlNodeDump(buffer, call->env->root->doc,call->env->root, 1 ,0); content = (char*)xmlBufferContent(buffer); /* Transport via HTTP */ conn = httpc_new(); conn->block = soap_client_get_blockmode(); /* Set soap action */ if (soap_action != NULL) { httpc_set_header(conn, "SoapAction", soap_action); } /* check for attachments */ if (!call->attachments) { /* content-type is always 'text/xml' */ httpc_set_header(conn, HEADER_CONTENT_TYPE, "text/xml"); sprintf(tmp, "%d", (int)strlen(content)); httpc_set_header(conn, HEADER_CONTENT_LENGTH, tmp); status = httpc_post_begin(conn, url); if (status != H_OK) { httpc_free(conn); xmlBufferFree(buffer); return status; } status = http_output_stream_write_string(conn->out, content); if (status != H_OK) { httpc_free(conn); xmlBufferFree(buffer); return status; } status = httpc_post_end(conn, &res); if (status != H_OK) { httpc_free(conn); xmlBufferFree(buffer); return status; } } else { /* Use chunked transport */ httpc_set_header(conn, HEADER_TRANSFER_ENCODING, TRANSFER_ENCODING_CHUNKED); sprintf(start_id, "289247829121218%d", counter++); status = httpc_mime_begin(conn, url, start_id, "", "text/xml"); if (status != H_OK) { httpc_free(conn); xmlBufferFree(buffer); return status; } status = httpc_mime_next(conn, start_id, "text/xml", "binary"); if (status != H_OK) { httpc_free(conn); xmlBufferFree(buffer); return status; } status = http_output_stream_write(conn->out, content, strlen(content)); if (status != H_OK) { httpc_free(conn); xmlBufferFree(buffer); return status; } for (part=call->attachments->parts; part; part=part->next) { status = httpc_mime_send_file(conn, part->id, part->content_type, part->transfer_encoding, part->filename); if (status != H_OK) { log_error2("Send file failed. Status:%d", status); httpc_free(conn); xmlBufferFree(buffer); return status; } } status = httpc_mime_end(conn, &res); if (status != H_OK) { httpc_free(conn); xmlBufferFree(buffer); return status; } } /* Free buffer */ xmlBufferFree(buffer); /* Build result */ status = _soap_client_build_result(res, &res_env); if (status != H_OK) { hresponse_free(res); httpc_free(conn); return status; } /* Create Context */ *response = soap_ctx_new(res_env); /* soap_ctx_add_files(*response, res->attachments);*/ if (res->attachments!=NULL) { part = res->attachments->parts; while (part) { soap_ctx_add_file(*response, part->filename, part->content_type, href); part->deleteOnExit = 0; part = part->next; } part = (*response)->attachments->parts; while (part) { part->deleteOnExit = 1; part = part->next; } } hresponse_free(res); httpc_free(conn); return H_OK; } static herror_t _soap_client_build_result(hresponse_t *res, SoapEnv** env) { herror_t err; log_verbose2("Building result (%p)", res); if (res == NULL) return herror_new("_soap_client_build_result", GENERAL_INVALID_PARAM, "hresponse_t is NULL"); if (res->in == NULL) return herror_new("_soap_client_build_result", GENERAL_INVALID_PARAM, "Empty response from server"); if (res->errcode != 200) return herror_new("_soap_client_build_result", GENERAL_INVALID_PARAM, "HTTP code is not 200 OK"); err = soap_env_new_from_stream(res->in, env); if (err != H_OK) { return err; } return H_OK; }