diff options
-rw-r--r-- | src/libstrongswan/Makefile.am | 2 | ||||
-rw-r--r-- | src/libstrongswan/fetcher/fetcher.c | 33 | ||||
-rw-r--r-- | src/libstrongswan/fetcher/fetcher.h | 51 | ||||
-rw-r--r-- | src/libstrongswan/fetcher/fetcher_manager.c | 18 | ||||
-rw-r--r-- | src/libstrongswan/fetcher/fetcher_manager.h | 9 | ||||
-rw-r--r-- | src/libstrongswan/plugins/curl/curl_fetcher.c | 3 | ||||
-rw-r--r-- | src/libstrongswan/plugins/soup/soup_fetcher.c | 3 |
7 files changed, 97 insertions, 22 deletions
diff --git a/src/libstrongswan/Makefile.am b/src/libstrongswan/Makefile.am index 6a29d8eea..b6c70daea 100644 --- a/src/libstrongswan/Makefile.am +++ b/src/libstrongswan/Makefile.am @@ -46,7 +46,7 @@ credentials/sets/callback_cred.c credentials/sets/callback_cred.h \ credentials/auth_cfg.c credentials/auth_cfg.h credentials/credential_set.h \ credentials/cert_validator.h \ database/database.h database/database_factory.h database/database_factory.c \ -fetcher/fetcher.h fetcher/fetcher_manager.h fetcher/fetcher_manager.c \ +fetcher/fetcher.h fetcher/fetcher.c fetcher/fetcher_manager.h fetcher/fetcher_manager.c \ eap/eap.h eap/eap.c \ plugins/plugin_loader.c plugins/plugin_loader.h plugins/plugin.h \ processing/jobs/job.h \ diff --git a/src/libstrongswan/fetcher/fetcher.c b/src/libstrongswan/fetcher/fetcher.c new file mode 100644 index 000000000..ca5a72165 --- /dev/null +++ b/src/libstrongswan/fetcher/fetcher.c @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2011 Martin Willi + * Copyright (C) 2011 revosec AG + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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 General Public License + * for more details. + */ + +#include "fetcher.h" + +/** + * See header. + */ +bool fetcher_default_callback(void *userdata, chunk_t chunk) +{ + chunk_t *accu = userdata; + + accu->ptr = realloc(accu->ptr, accu->len + chunk.len); + if (accu->ptr) + { + memcpy(&accu->ptr[accu->len], chunk.ptr, chunk.len); + accu->len += chunk.len; + return TRUE; + } + return FALSE; +} diff --git a/src/libstrongswan/fetcher/fetcher.h b/src/libstrongswan/fetcher/fetcher.h index f312206bb..5b734da3d 100644 --- a/src/libstrongswan/fetcher/fetcher.h +++ b/src/libstrongswan/fetcher/fetcher.h @@ -1,6 +1,7 @@ /* - * Copyright (C) 2008 Martin Willi + * Copyright (C) 2008-2011 Martin Willi * Hochschule fuer Technik Rapperswil + * Copyright (C) 2011 revosec AG * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -25,6 +26,23 @@ typedef struct fetcher_t fetcher_t; typedef enum fetcher_option_t fetcher_option_t; #include <stdarg.h> +#include <chunk.h> + +/** + * Constructor function which creates fetcher instances. + * + * @return fetcher instance + */ +typedef fetcher_t* (*fetcher_constructor_t)(); + +/** + * Callback function used with FETCH_CALLBACK. + * + * @param userdata userdata passed to fetcher_t.fetch() + * @param chunk chunk with next chunk of data + * @return TRUE to continue with transfer, FALSE to abort + */ +typedef bool (*fetcher_callback_t)(void *userdata, chunk_t chunk); #include <library.h> @@ -64,19 +82,20 @@ enum fetcher_option_t { FETCH_TIMEOUT, /** + * Callback to invoke with each chunk of data. + * Additional argument fetch_callback_t. + * If this option is not given, the fetcher_default_callback is used, + * which accumulates the data into an allocated chunk. + */ + FETCH_CALLBACK, + + /** * end of fetching options */ FETCH_END, }; /** - * Constructor function which creates fetcher instances. - * - * @return fetcher instance - */ -typedef fetcher_t* (*fetcher_constructor_t)(); - -/** * Fetcher interface, an implementation fetches data from an URL. */ struct fetcher_t { @@ -87,15 +106,18 @@ struct fetcher_t { * The fetcher returns NOT_SUPPORTED to indicate that it is uncappable * to handle such URLs. Other return values indicate a failure, and * fetching of that URL gets cancelled. + * If no FETCH_CALLBACK function is set as option, userdata must be + * a chunk_t*. This chunk gets allocated, accumulated data using the + * fetcher_default_callback() function. * * @param uri URI to fetch from - * @param result chunk which receives allocated data + * @param userdata userdata to pass to callback function. * @return * - SUCCESS if fetch was successful * - NOT_SUPPORTED if fetcher does not support such URLs * - FAILED, NOT_FOUND, PARSE_ERROR on failure */ - status_t (*fetch)(fetcher_t *this, char *uri, chunk_t *result); + status_t (*fetch)(fetcher_t *this, char *uri, void *userdata); /** * Set a fetcher option, as defined in fetcher_option_t. @@ -114,4 +136,13 @@ struct fetcher_t { void (*destroy)(fetcher_t *this); }; +/** + * Default fetcher callback function, accumulates data to a chunk. + * + * @param userdata chunk for allocated data, empty on first invocation + * @param chunk current chunk of data + * @return FALSE if chunk too large to allocate + */ +bool fetcher_default_callback(void *userdata, chunk_t chunk); + #endif /** FETCHER_H_ @}*/ diff --git a/src/libstrongswan/fetcher/fetcher_manager.c b/src/libstrongswan/fetcher/fetcher_manager.c index 7e49be4dc..9b363c7eb 100644 --- a/src/libstrongswan/fetcher/fetcher_manager.c +++ b/src/libstrongswan/fetcher/fetcher_manager.c @@ -59,7 +59,7 @@ static void entry_destroy(entry_t *entry) } METHOD(fetcher_manager_t, fetch, status_t, - private_fetcher_manager_t *this, char *url, chunk_t *response, ...) + private_fetcher_manager_t *this, char *url, void *userdata, ...) { enumerator_t *enumerator; status_t status = NOT_SUPPORTED; @@ -86,25 +86,31 @@ METHOD(fetcher_manager_t, fetch, status_t, { continue; } - va_start(args, response); + va_start(args, userdata); while (good) { opt = va_arg(args, int); switch (opt) { case FETCH_REQUEST_DATA: - good = fetcher->set_option(fetcher, opt, va_arg(args, chunk_t)); + good = fetcher->set_option(fetcher, opt, + va_arg(args, chunk_t)); continue; case FETCH_REQUEST_TYPE: case FETCH_REQUEST_HEADER: - good = fetcher->set_option(fetcher, opt, va_arg(args, char*)); + good = fetcher->set_option(fetcher, opt, + va_arg(args, char*)); continue; case FETCH_HTTP_VERSION_1_0: good = fetcher->set_option(fetcher, opt); continue; case FETCH_TIMEOUT: - good = fetcher->set_option(fetcher, opt, va_arg(args, u_int)); + good = fetcher->set_option(fetcher, opt, + va_arg(args, u_int)); continue; + case FETCH_CALLBACK: + good = fetcher->set_option(fetcher, opt, + va_arg(args, fetcher_callback_t)); case FETCH_END: break; } @@ -117,7 +123,7 @@ METHOD(fetcher_manager_t, fetch, status_t, continue; } - status = fetcher->fetch(fetcher, url, response); + status = fetcher->fetch(fetcher, url, userdata); fetcher->destroy(fetcher); /* try another fetcher only if this one does not support that URL */ if (status == NOT_SUPPORTED) diff --git a/src/libstrongswan/fetcher/fetcher_manager.h b/src/libstrongswan/fetcher/fetcher_manager.h index a7ac6611e..15250d531 100644 --- a/src/libstrongswan/fetcher/fetcher_manager.h +++ b/src/libstrongswan/fetcher/fetcher_manager.h @@ -31,17 +31,20 @@ typedef struct fetcher_manager_t fetcher_manager_t; struct fetcher_manager_t { /** - * Fetch data from URI into chunk. + * Fetch data from URI. * * The variable argument list contains fetcher_option_t's, followed * by a option specific data argument. + * If no FETCH_CALLBACK function is given as option, userdata must be + * a chunk_t*. This chunk gets allocated, accumulated data using the + * fetcher_default_callback() function. * * @param uri URI to fetch from - * @param result chunk which receives allocated data + * @param userdata userdata to pass to callback function. * @param options FETCH_END terminated fetcher_option_t arguments * @return status indicating result of fetch */ - status_t (*fetch)(fetcher_manager_t *this, char *url, chunk_t *response, ...); + status_t (*fetch)(fetcher_manager_t *this, char *url, void *userdata, ...); /** * Register a fetcher implementation. diff --git a/src/libstrongswan/plugins/curl/curl_fetcher.c b/src/libstrongswan/plugins/curl/curl_fetcher.c index 82e24e810..6c03ebe66 100644 --- a/src/libstrongswan/plugins/curl/curl_fetcher.c +++ b/src/libstrongswan/plugins/curl/curl_fetcher.c @@ -62,10 +62,11 @@ static size_t append(void *ptr, size_t size, size_t nmemb, chunk_t *data) } METHOD(fetcher_t, fetch, status_t, - private_curl_fetcher_t *this, char *uri, chunk_t *result) + private_curl_fetcher_t *this, char *uri, void *userdata) { char error[CURL_ERROR_SIZE]; status_t status; + chunk_t *result = userdata; *result = chunk_empty; diff --git a/src/libstrongswan/plugins/soup/soup_fetcher.c b/src/libstrongswan/plugins/soup/soup_fetcher.c index fd97631bd..2c99c90ed 100644 --- a/src/libstrongswan/plugins/soup/soup_fetcher.c +++ b/src/libstrongswan/plugins/soup/soup_fetcher.c @@ -61,11 +61,12 @@ struct private_soup_fetcher_t { }; METHOD(fetcher_t, fetch, status_t, - private_soup_fetcher_t *this, char *uri, chunk_t *result) + private_soup_fetcher_t *this, char *uri, void *userdata) { SoupSession *session; SoupMessage *message; status_t status = FAILED; + chunk_t *result = userdata; message = soup_message_new(this->method, uri); if (!message) |