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 \
--- /dev/null
+/*
+ * 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;
+}
/*
- * 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
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>
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 {
* 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.
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_ @}*/
}
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;
{
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;
}
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)
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.
}
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;
};
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)