From 7b58a8fb0b95d6809fbe3e8c7dc7a05729b6c828 Mon Sep 17 00:00:00 2001 From: snowdrop Date: Fri, 29 Oct 2004 09:27:02 +0000 Subject: added hoption feature --- examples/csoap/echoattachments-client.c | 4 +- libcsoap/soap-client.c | 33 ++++++++++++-- libcsoap/soap-ctx.h | 6 ++- nanohttp/nanohttp-client.c | 14 +----- nanohttp/nanohttp-common.c | 81 +++++++++++++++++++++++++++++++-- nanohttp/nanohttp-common.h | 18 ++++++-- nanohttp/nanohttp-mime.c | 11 ++--- nanohttp/nanohttp-response.c | 23 +++++++--- nanohttp/nanohttp-server.c | 7 ++- nanohttp/nanohttp-socket.c | 43 ++++++++++------- nanohttp/nanohttp-stream.c | 13 ++++-- nanohttp/nanohttp-stream.h | 10 ++-- 12 files changed, 195 insertions(+), 68 deletions(-) diff --git a/examples/csoap/echoattachments-client.c b/examples/csoap/echoattachments-client.c index 1550c93..0f62fa7 100755 --- a/examples/csoap/echoattachments-client.c +++ b/examples/csoap/echoattachments-client.c @@ -1,5 +1,5 @@ /****************************************************************** - * $Id: echoattachments-client.c,v 1.4 2004/10/28 10:30:41 snowdrop Exp $ + * $Id: echoattachments-client.c,v 1.5 2004/10/29 09:27:02 snowdrop Exp $ * * CSOAP Project: CSOAP examples project * Copyright (C) 2003-2004 Ferhat Ayaz @@ -27,7 +27,7 @@ static const char *urn = "urn:examples"; -static const char *url = "http://localhost:10000/echoattachment"; +static const char *url = "http://localhost:10000/echoattachments"; static const char *method = "echo"; diff --git a/libcsoap/soap-client.c b/libcsoap/soap-client.c index 2a56e11..160b255 100644 --- a/libcsoap/soap-client.c +++ b/libcsoap/soap-client.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: soap-client.c,v 1.10 2004/10/28 10:30:46 snowdrop Exp $ +* $Id: soap-client.c,v 1.11 2004/10/29 09:27:05 snowdrop Exp $ * * CSOAP Project: A SOAP client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -89,7 +89,10 @@ soap_client_invoke(SoapCtx *call, SoapCtx** response, const char *url, const cha static int counter=1; part_t *part; int file_count=0; - + + /* for copy attachments */ + char href[MAX_HREF_SIZE]; + /* Create buffer */ buffer = xmlBufferCreate(); xmlNodeDump(buffer, call->env->root->doc,call->env->root, 1 ,0); @@ -189,13 +192,33 @@ soap_client_invoke(SoapCtx *call, SoapCtx** response, const char *url, const cha /* Build result */ status = _soap_client_build_result(res, &res_env); - if (status != H_OK) + 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); - +/* 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; } diff --git a/libcsoap/soap-ctx.h b/libcsoap/soap-ctx.h index 2ea107b..0aa8520 100755 --- a/libcsoap/soap-ctx.h +++ b/libcsoap/soap-ctx.h @@ -1,5 +1,5 @@ /****************************************************************** - * $Id: soap-ctx.h,v 1.2 2004/10/28 10:30:46 snowdrop Exp $ + * $Id: soap-ctx.h,v 1.3 2004/10/29 09:27:05 snowdrop Exp $ * * CSOAP Project: A SOAP client/server library in C * Copyright (C) 2003-2004 Ferhat Ayaz @@ -41,6 +41,10 @@ SoapCtx* soap_ctx_new(SoapEnv *env); /* should only be used internally */ /* Size of destination dest_href should be MAX_HREF_SIZE */ herror_t soap_ctx_add_file(SoapCtx* ctx, const char* filename, const char* content_type, char *dest_href); +/* +Used internally. Will switch the deleteOnExit flag from the +given one to the added part. +*/ void soap_ctx_add_files(SoapCtx* ctx, attachments_t *attachments); void soap_ctx_free(SoapCtx* ctx); diff --git a/nanohttp/nanohttp-client.c b/nanohttp/nanohttp-client.c index c393573..039fda4 100644 --- a/nanohttp/nanohttp-client.c +++ b/nanohttp/nanohttp-client.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: nanohttp-client.c,v 1.23 2004/10/28 10:30:46 snowdrop Exp $ +* $Id: nanohttp-client.c,v 1.24 2004/10/29 09:27:05 snowdrop Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -51,18 +51,8 @@ NOTE: This will be called from soap_client_init_args() herror_t httpc_init(int argc, char *argv[]) { - int i; - + hoption_init_args(argc, argv); hsocket_module_init(); - - /* initialize from arguments */ - for (i = 0; i < argc; i++) - { - if (!strcmp (argv[i], NHTTP_ARG_LOGFILE) && i < argc - 1) - { - log_set_file(argv[i+1]); - } - } return H_OK; } diff --git a/nanohttp/nanohttp-common.c b/nanohttp/nanohttp-common.c index 819c98b..67301e3 100644 --- a/nanohttp/nanohttp-common.c +++ b/nanohttp/nanohttp-common.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: nanohttp-common.c,v 1.15 2004/10/28 10:30:46 snowdrop Exp $ +* $Id: nanohttp-common.c,v 1.16 2004/10/29 09:27:05 snowdrop Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -35,6 +35,72 @@ #endif +#define MAX_OPTION_SIZE 50 +#define MAX_OPTION_VALUE_SIZE 150 + +static char _hoption_table[MAX_OPTION_SIZE][MAX_OPTION_VALUE_SIZE]; + +/* option stuff */ +void hoption_set(int opt, const char* value) +{ + if (opt >= MAX_OPTION_SIZE) { + log_warn3("Option to high (%d >= %d)", opt, MAX_OPTION_SIZE); + return; + } + + strncpy(_hoption_table[opt], value, MAX_OPTION_VALUE_SIZE); +} + + +char *hoption_get(int opt) +{ + if (opt >= MAX_OPTION_SIZE) { + log_warn3("Option to high (%d >= %d)", opt, MAX_OPTION_SIZE); + return ""; + } + + return _hoption_table[opt]; +} + + +void hoption_init_args(int argc, char* argv[]) +{ + int i; + + hoption_set(HOPTION_TMP_DIR, "."); /* default value */ + + /* initialize from arguments */ + for (i = 0; i < argc; i++) + { + if (!strcmp (argv[i], NHTTP_ARG_TMPDIR) && i < argc - 1) + { + hoption_set(HOPTION_TMP_DIR, argv[i+1]); + } + else if (!strcmp (argv[i], NHTTP_ARG_LOGFILE) && i < argc - 1) + { + log_set_file(argv[i+1]); + } + } + + +} + + +#ifdef WIN32 +#ifndef __MINGW32__ + +/* not thread safe!*/ +char *VisualC_funcname(const char* file, int line) +{ + static char buffer[256]; + int i = strlen(file)-1; + while (i>0 && file[i]!='\\')i--; + sprintf(buffer, "%s:%d", (file[i]!='\\')?file:(file+i+1), line); + return buffer; +} + +#endif +#endif typedef struct _herror_impl_t { @@ -634,7 +700,8 @@ part_t *part_new(const char *id, const char* filename, { part_t *part = (part_t*)malloc(sizeof(part_t)); part->header = NULL; - part->next = next; + part->next = next; + part->deleteOnExit = 0; strcpy(part->id, id); strcpy(part->filename, filename); if (content_type) @@ -662,6 +729,10 @@ void part_free(part_t *part) if (part == NULL) return; + if (part->deleteOnExit) { + remove(part->filename); + } + hpairnode_free_deep(part->header); free(part); @@ -707,9 +778,11 @@ void attachments_free(attachments_t *message) part_free(part); part= tmp; } - + + if (message->root_part) + part_free(message->root_part); /* TODO (#1#): HERE IS A BUG!!!! */ -/* free(message);*/ + free(message); } diff --git a/nanohttp/nanohttp-common.h b/nanohttp/nanohttp-common.h index 79ca625..1d89d30 100644 --- a/nanohttp/nanohttp-common.h +++ b/nanohttp/nanohttp-common.h @@ -1,5 +1,5 @@ /****************************************************************** - * $Id: nanohttp-common.h,v 1.14 2004/10/28 10:30:46 snowdrop Exp $ + * $Id: nanohttp-common.h,v 1.15 2004/10/29 09:27:05 snowdrop Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003-2004 Ferhat Ayaz @@ -43,6 +43,7 @@ #define NHTTPD_ARG_TERMSIG "-NHTTPtsig" #define NHTTPD_ARG_MAXCONN "-NHTTPmaxconn" #define NHTTP_ARG_LOGFILE "-NHTTPlog" +#define NHTTP_ARG_TMPDIR "-NHTTPtmpdir" #ifndef SAVE_STR #define SAVE_STR(str) ((str==0)?("(null)"):(str)) @@ -416,7 +417,8 @@ typedef struct _part char content_type[128]; char transfer_encoding[128]; char filename[250]; - struct _part *next; + struct _part *next; + int deleteOnExit; /* default is 0 */ }part_t; @@ -447,8 +449,13 @@ attachments_t *attachments_new(); /* should be used internally */ */ void attachments_free(attachments_t *message); void attachments_add_part(attachments_t *attachments, part_t *part); + - +/* tmp directory for multipart/related stuff */ +#define HOPTION_TMP_DIR 2 +void hoption_init_args(int argc, char* argv[]); +void hoption_set(int opt, const char* value); +char *hoption_get(int opt); /* logging stuff */ @@ -471,8 +478,9 @@ void log_set_file(const char *filename); char *log_get_file(); #ifdef WIN32 - #ifndef __MINGW32__ - #define __FUNCTION__ "***" + #ifndef __MINGW32__ + char *VisualC_funcname(const char* file, int line); /* not thread safe!*/ + #define __FUNCTION__ VisualC_funcname(__FILE__, __LINE__) #endif #endif diff --git a/nanohttp/nanohttp-mime.c b/nanohttp/nanohttp-mime.c index 2b6794d..5b8a5f4 100755 --- a/nanohttp/nanohttp-mime.c +++ b/nanohttp/nanohttp-mime.c @@ -3,7 +3,7 @@ * | \/ | | | | \/ | | _/ * |_''_| |_| |_''_| |_'/ PARSER * -* $Id: nanohttp-mime.c,v 1.3 2004/10/28 10:30:46 snowdrop Exp $ +* $Id: nanohttp-mime.c,v 1.4 2004/10/29 09:27:05 snowdrop Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003-2004 Ferhat Ayaz @@ -582,7 +582,9 @@ void _mime_part_begin(void *data) sprintf(buffer, "%s/mime_%p_%d.part", cbdata->root_dir, cbdata, cbdata->part_id++); #endif - + +/* log_info2("Creating FILE ('%s') deleteOnExit=1", buffer);*/ + part->deleteOnExit = 1; cbdata->current_fd = fopen(buffer, "wb"); if (cbdata->current_fd) strcpy(cbdata->current_part->filename, buffer); @@ -898,10 +900,7 @@ herror_t mime_get_attachments(content_type_t *ctype, http_input_stream_t *in, at "'start' not set for multipart/related"); } - /* TODO (#1#): Set this not to working directory - This must be configured */ - - mimeMessage = mime_message_parse(in, root_id, boundary, "."); + mimeMessage = mime_message_parse(in, root_id, boundary, hoption_get(HOPTION_TMP_DIR)); if (mimeMessage == NULL) { /* TODO (#1#): Handle Error in http form */ diff --git a/nanohttp/nanohttp-response.c b/nanohttp/nanohttp-response.c index f2e13c5..3883950 100755 --- a/nanohttp/nanohttp-response.c +++ b/nanohttp/nanohttp-response.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: nanohttp-response.c,v 1.2 2004/10/28 10:30:46 snowdrop Exp $ +* $Id: nanohttp-response.c,v 1.3 2004/10/29 09:27:05 snowdrop Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003-2004 Ferhat Ayaz @@ -186,8 +186,15 @@ read_header: /* for errorcode: 100 (continue) */ } else { - res->attachments = mimeMessage; - res->in = http_input_stream_new_from_file(mimeMessage->root_part->filename); + res->attachments = mimeMessage; + http_input_stream_free(res->in); + res->in = http_input_stream_new_from_file(mimeMessage->root_part->filename); + if (!res->in) { + /* TODO (#1#): Handle error */ + + } else { + /*res->in->deleteOnExit = 1;*/ + } } } *out = res; @@ -195,9 +202,9 @@ read_header: /* for errorcode: 100 (continue) */ } - -void -hresponse_free(hresponse_t * res) + +void +hresponse_free(hresponse_t * res) { if (res == NULL) return; @@ -210,7 +217,9 @@ hresponse_free(hresponse_t * res) if (res->content_type) content_type_free(res->content_type); - + + if (res->attachments) + attachments_free(res->attachments); free(res); } diff --git a/nanohttp/nanohttp-server.c b/nanohttp/nanohttp-server.c index 71dbba7..566a760 100644 --- a/nanohttp/nanohttp-server.c +++ b/nanohttp/nanohttp-server.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: nanohttp-server.c,v 1.28 2004/10/28 10:30:46 snowdrop Exp $ +* $Id: nanohttp-server.c,v 1.29 2004/10/29 09:27:05 snowdrop Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -99,7 +99,10 @@ httpd_init (int argc, char *argv[]) { int i; herror_t status; - status = hsocket_module_init (); + + hoption_init_args(argc, argv); + + status = hsocket_module_init (); if (status != H_OK) return status; diff --git a/nanohttp/nanohttp-socket.c b/nanohttp/nanohttp-socket.c index 7b378fc..6d93fe2 100644 --- a/nanohttp/nanohttp-socket.c +++ b/nanohttp/nanohttp-socket.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: nanohttp-socket.c,v 1.30 2004/10/28 10:30:46 snowdrop Exp $ +* $Id: nanohttp-socket.c,v 1.31 2004/10/29 09:27:05 snowdrop Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -67,6 +67,14 @@ #ifdef MEM_DEBUG #include #endif + + +#ifdef WIN32 +#undef errno +#define errno WSAGetLastError() +#endif + + /*-------------------------------------------------- FUNCTION: hsocket_module_init @@ -133,12 +141,12 @@ hsocket_open (hsocket_t * dsock, const char *hostname, int port) sock = socket (AF_INET, SOCK_STREAM, 0); if (sock <= 0) - return herror_new("hsocket_open", HSOCKET_ERROR_CREATE, strerror (errno)); + return herror_new("hsocket_open", HSOCKET_ERROR_CREATE, "Socket error: %d", errno); /* Get host data */ host = gethostbyname (hostname); if (host == NULL) - return herror_new("hsocket_open", HSOCKET_ERROR_GET_HOSTNAME, strerror (errno)); + return herror_new("hsocket_open", HSOCKET_ERROR_GET_HOSTNAME, "Socket error: %d", errno); ip = inet_ntoa (*(struct in_addr *) *host->h_addr_list); address.sin_addr.s_addr = inet_addr (ip); @@ -149,7 +157,8 @@ hsocket_open (hsocket_t * dsock, const char *hostname, int port) /* connect to the server */ if (connect (sock, (struct sockaddr *) &address, sizeof (address)) != 0) - return herror_new("hsocket_open", HSOCKET_ERROR_CONNECT, "Connect to '%s:%d' failed", hostname, port); +/* return herror_new("hsocket_open", HSOCKET_ERROR_CONNECT, "Connect to '%s:%d' failed", hostname, port);*/ + return herror_new("hsocket_open", HSOCKET_ERROR_CONNECT, "Socket error: %d", errno); *dsock = sock; return H_OK; @@ -168,8 +177,8 @@ hsocket_bind (hsocket_t * dsock, int port) sock = socket (AF_INET, SOCK_STREAM, 0); if (sock == -1) { - log_error2 ("Can not create socket: '%s'", strerror (errno)); - return herror_new("hsocket_bind", HSOCKET_ERROR_CREATE, strerror (errno)); + log_error3 ("Can not create socket: '%s'", "Socket error: %d", errno); + return herror_new("hsocket_bind", HSOCKET_ERROR_CREATE, "Socket error: %d", errno); } /* bind socket */ addr.sin_family = AF_INET; @@ -180,8 +189,8 @@ hsocket_bind (hsocket_t * dsock, int port) if (bind (sock, (struct sockaddr *) &addr, sizeof (struct sockaddr)) == -1) { - log_error2 ("Can not bind: '%s'", strerror (errno)); - return herror_new("hsocket_bind", HSOCKET_ERROR_BIND, strerror (errno)); + log_error3 ("Can not bind: '%s'", "Socket error: %d", errno); + return herror_new("hsocket_bind", HSOCKET_ERROR_BIND, "Socket error: %d", errno); } *dsock = sock; return H_OK; @@ -208,7 +217,7 @@ hsocket_accept (hsocket_t sock, hsocket_t * dest) sockfd = accept (sock, (struct sockaddr *) &addr, &asize); if (sockfd == INVALID_SOCKET) { if (WSAGetLastError () != WSAEWOULDBLOCK) - return herror_new("hsocket_accept", HSOCKET_ERROR_ACCEPT, strerror (errno)); + return herror_new("hsocket_accept", HSOCKET_ERROR_ACCEPT, "Socket error: %d", errno); } else { break; } @@ -217,7 +226,7 @@ hsocket_accept (hsocket_t sock, hsocket_t * dest) /* TODO (#1#): why not a loop like in win32? */ sockfd = accept (sock, (struct sockaddr *) &addr, &asize); if (sockfd == -1) { - return herror_new("hsocket_accept", HSOCKET_ERROR_ACCEPT, strerror (errno)); + return herror_new("hsocket_accept", HSOCKET_ERROR_ACCEPT, "Socket error: %d", errno); } #endif /* TODO (#1#): Write to access.log file */ @@ -241,8 +250,8 @@ hsocket_listen (hsocket_t sock) if (listen (sock, 15) == -1) { - log_error2 ("Can not listen: '%s'", strerror (errno)); - return herror_new("hsocket_listen", HSOCKET_ERROR_LISTEN, strerror (errno)); + log_error3 ("Can not listen: '%s'", "Socket error: %d", errno); + return herror_new("hsocket_listen", HSOCKET_ERROR_LISTEN, "Socket error: %d", errno); } return H_OK; @@ -353,10 +362,10 @@ hsocket_nsend (hsocket_t sock, const byte_t *bytes, int n) if (WSAGetLastError () == WSAEWOULDBLOCK) continue; else - return herror_new("hsocket_nsend", HSOCKET_ERROR_SEND, strerror (errno)); + return herror_new("hsocket_nsend", HSOCKET_ERROR_SEND, "Socket error: %d", errno); #else if (size == -1) - return herror_new("hsocket_nsend", HSOCKET_ERROR_SEND, strerror (errno)); + return herror_new("hsocket_nsend", HSOCKET_ERROR_SEND, "Socket error: %d", errno); #endif n -= size; total += size; @@ -403,7 +412,7 @@ hsocket_read (hsocket_t sock, byte_t *buffer, int total, int force, int *receive continue; default: log_error2("WSAGetLastError()=%d", wsa_error); - return herror_new("hsocket_read", HSOCKET_ERROR_RECEIVE, strerror (errno)); + return herror_new("hsocket_read", HSOCKET_ERROR_RECEIVE, "Socket error: %d", errno); } } @@ -417,7 +426,7 @@ hsocket_read (hsocket_t sock, byte_t *buffer, int total, int force, int *receive } */ if (status == -1) - return herror_new("hsocket_read", HSOCKET_ERROR_RECEIVE, strerror (errno)); + return herror_new("hsocket_read", HSOCKET_ERROR_RECEIVE, "Socket error: %d", errno); #endif if (!force) { @@ -462,7 +471,7 @@ hsocket_block(hsocket_t sock, int block) if (ioctlsocket (sock, FIONBIO, (u_long FAR *) & iMode) == INVALID_SOCKET) { log_error1 ("ioctlsocket error"); - return herror_new("hsocket_block", HSOCKET_ERROR_IOCTL, strerror (errno)); + return herror_new("hsocket_block", HSOCKET_ERROR_IOCTL, "Socket error: %d", errno); } #else /* fcntl(sock, F_SETFL, O_NONBLOCK); */ /* TODO (#1#): check for *nix the non blocking sockets */ diff --git a/nanohttp/nanohttp-stream.c b/nanohttp/nanohttp-stream.c index 991d2ab..1951c8a 100755 --- a/nanohttp/nanohttp-stream.c +++ b/nanohttp/nanohttp-stream.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: nanohttp-stream.c,v 1.4 2004/10/28 10:30:47 snowdrop Exp $ +* $Id: nanohttp-stream.c,v 1.5 2004/10/29 09:27:05 snowdrop Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003-2004 Ferhat Ayaz @@ -132,7 +132,8 @@ http_input_stream_t *http_input_stream_new_from_file(const char* filename) result = (http_input_stream_t*)malloc(sizeof(http_input_stream_t)); result->type = HTTP_TRANSFER_FILE; result->fd = fd; - + result->deleteOnExit = 0; + strcpy(result->filename, filename); return result; } @@ -141,8 +142,12 @@ http_input_stream_t *http_input_stream_new_from_file(const char* filename) */ void http_input_stream_free(http_input_stream_t *stream) { - if (stream->type == HTTP_TRANSFER_FILE && stream->fd) - fclose(stream->fd); + if (stream->type == HTTP_TRANSFER_FILE && stream->fd) { + fclose(stream->fd); + if (stream->deleteOnExit) + log_info2("Removing '%s'", stream->filename); + /*remove(stream->filename);*/ + } free(stream); } diff --git a/nanohttp/nanohttp-stream.h b/nanohttp/nanohttp-stream.h index 7b0f0f8..b8b345c 100755 --- a/nanohttp/nanohttp-stream.h +++ b/nanohttp/nanohttp-stream.h @@ -1,5 +1,5 @@ /****************************************************************** - * $Id: nanohttp-stream.h,v 1.3 2004/10/28 10:30:47 snowdrop Exp $ + * $Id: nanohttp-stream.h,v 1.4 2004/10/29 09:27:05 snowdrop Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003-2004 Ferhat Ayaz @@ -93,8 +93,12 @@ typedef struct http_input_stream int received; int content_length; int chunk_size; - byte_t connection_closed; - FILE *fd; + byte_t connection_closed; + + /* file handling */ + FILE *fd; + char filename[255]; + int deleteOnExit; /* default is 0 */ }http_input_stream_t; -- cgit v1.1-32-gdbae