File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libstrongswan / fetcher / fetcher_manager.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Jun 3 09:46:44 2020 UTC (4 years, 3 months ago) by misho
Branches: strongswan, MAIN
CVS tags: v5_9_2p0, v5_8_4p7, HEAD
Strongswan

    1: /*
    2:  * Copyright (C) 2008 Martin Willi
    3:  * HSR Hochschule fuer Technik Rapperswil
    4:  *
    5:  * This program is free software; you can redistribute it and/or modify it
    6:  * under the terms of the GNU General Public License as published by the
    7:  * Free Software Foundation; either version 2 of the License, or (at your
    8:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
    9:  *
   10:  * This program is distributed in the hope that it will be useful, but
   11:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
   12:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   13:  * for more details.
   14:  */
   15: 
   16: #include "fetcher_manager.h"
   17: 
   18: #include <utils/debug.h>
   19: #include <threading/rwlock.h>
   20: #include <collections/linked_list.h>
   21: 
   22: typedef struct private_fetcher_manager_t private_fetcher_manager_t;
   23: 
   24: /**
   25:  * private data of fetcher_manager
   26:  */
   27: struct private_fetcher_manager_t {
   28: 
   29: 	/**
   30: 	 * public functions
   31: 	 */
   32: 	fetcher_manager_t public;
   33: 
   34: 	/**
   35: 	 * list of registered fetchers, as entry_t
   36: 	 */
   37: 	linked_list_t *fetchers;
   38: 
   39: 	/**
   40: 	 * read write lock to list
   41: 	 */
   42: 	rwlock_t *lock;
   43: };
   44: 
   45: typedef struct {
   46: 	/** associated fetcher construction function */
   47: 	fetcher_constructor_t create;
   48: 	/** URL this fetcher support */
   49: 	char *url;
   50: } entry_t;
   51: 
   52: /**
   53:  * destroy an entry_t
   54:  */
   55: static void entry_destroy(entry_t *entry)
   56: {
   57: 	free(entry->url);
   58: 	free(entry);
   59: }
   60: 
   61: METHOD(fetcher_manager_t, fetch, status_t,
   62: 	private_fetcher_manager_t *this, char *url, void *userdata, ...)
   63: {
   64: 	enumerator_t *enumerator;
   65: 	status_t status = NOT_SUPPORTED;
   66: 	entry_t *entry;
   67: 	bool capable = FALSE;
   68: 
   69: 	this->lock->read_lock(this->lock);
   70: 	enumerator = this->fetchers->create_enumerator(this->fetchers);
   71: 	while (enumerator->enumerate(enumerator, &entry))
   72: 	{
   73: 		fetcher_option_t opt;
   74: 		fetcher_t *fetcher;
   75: 		bool good = TRUE;
   76: 		host_t *host;
   77: 		va_list args;
   78: 
   79: 		/* check URL support of fetcher */
   80: 		if (strncasecmp(entry->url, url, strlen(entry->url)))
   81: 		{
   82: 			continue;
   83: 		}
   84: 		/* create fetcher instance and set options */
   85: 		fetcher = entry->create();
   86: 		if (!fetcher)
   87: 		{
   88: 			continue;
   89: 		}
   90: 		va_start(args, userdata);
   91: 		while (good)
   92: 		{
   93: 			opt = va_arg(args, int);
   94: 			switch (opt)
   95: 			{
   96: 				case FETCH_REQUEST_DATA:
   97: 					good = fetcher->set_option(fetcher, opt,
   98: 											va_arg(args, chunk_t));
   99: 					continue;
  100: 				case FETCH_REQUEST_TYPE:
  101: 				case FETCH_REQUEST_HEADER:
  102: 					good = fetcher->set_option(fetcher, opt,
  103: 											va_arg(args, char*));
  104: 					continue;
  105: 				case FETCH_HTTP_VERSION_1_0:
  106: 					good = fetcher->set_option(fetcher, opt);
  107: 					continue;
  108: 				case FETCH_TIMEOUT:
  109: 					good = fetcher->set_option(fetcher, opt,
  110: 											va_arg(args, u_int));
  111: 					continue;
  112: 				case FETCH_CALLBACK:
  113: 					good = fetcher->set_option(fetcher, opt,
  114: 											va_arg(args, fetcher_callback_t));
  115: 					continue;
  116: 				case FETCH_RESPONSE_CODE:
  117: 					good = fetcher->set_option(fetcher, opt,
  118: 											va_arg(args, u_int*));
  119: 					continue;
  120: 				case FETCH_SOURCEIP:
  121: 					host = va_arg(args, host_t*);
  122: 					if (host && !host->is_anyaddr(host))
  123: 					{
  124: 						good = fetcher->set_option(fetcher, opt, host);
  125: 					}
  126: 					continue;
  127: 				case FETCH_END:
  128: 					break;
  129: 			}
  130: 			break;
  131: 		}
  132: 		va_end(args);
  133: 		if (!good)
  134: 		{	/* fetcher does not support supplied options, try another */
  135: 			fetcher->destroy(fetcher);
  136: 			continue;
  137: 		}
  138: 
  139: 		status = fetcher->fetch(fetcher, url, userdata);
  140: 		fetcher->destroy(fetcher);
  141: 		/* try another fetcher only if this one does not support that URL */
  142: 		if (status == NOT_SUPPORTED)
  143: 		{
  144: 			continue;
  145: 		}
  146: 		capable = TRUE;
  147: 		break;
  148: 	}
  149: 	enumerator->destroy(enumerator);
  150: 	this->lock->unlock(this->lock);
  151: 	if (!capable)
  152: 	{
  153: 		DBG1(DBG_LIB, "unable to fetch from %s, no capable fetcher found", url);
  154: 	}
  155: 	return status;
  156: }
  157: 
  158: METHOD(fetcher_manager_t, add_fetcher, void,
  159: 	private_fetcher_manager_t *this, fetcher_constructor_t create, char *url)
  160: {
  161: 	entry_t *entry;
  162: 
  163: 	INIT(entry,
  164: 		.url = strdup(url),
  165: 		.create = create,
  166: 	);
  167: 	this->lock->write_lock(this->lock);
  168: 	this->fetchers->insert_last(this->fetchers, entry);
  169: 	this->lock->unlock(this->lock);
  170: }
  171: 
  172: METHOD(fetcher_manager_t, remove_fetcher, void,
  173: 	private_fetcher_manager_t *this, fetcher_constructor_t create)
  174: {
  175: 	enumerator_t *enumerator;
  176: 	entry_t *entry;
  177: 
  178: 	this->lock->write_lock(this->lock);
  179: 	enumerator = this->fetchers->create_enumerator(this->fetchers);
  180: 	while (enumerator->enumerate(enumerator, &entry))
  181: 	{
  182: 		if (entry->create == create)
  183: 		{
  184: 			this->fetchers->remove_at(this->fetchers, enumerator);
  185: 			entry_destroy(entry);
  186: 		}
  187: 	}
  188: 	enumerator->destroy(enumerator);
  189: 	this->lock->unlock(this->lock);
  190: }
  191: 
  192: METHOD(fetcher_manager_t, destroy, void,
  193: 	private_fetcher_manager_t *this)
  194: {
  195: 	this->fetchers->destroy_function(this->fetchers, (void*)entry_destroy);
  196: 	this->lock->destroy(this->lock);
  197: 	free(this);
  198: }
  199: 
  200: /*
  201:  * see header file
  202:  */
  203: fetcher_manager_t *fetcher_manager_create()
  204: {
  205: 	private_fetcher_manager_t *this;
  206: 
  207: 	INIT(this,
  208: 		.public = {
  209: 			.fetch = _fetch,
  210: 			.add_fetcher = _add_fetcher,
  211: 			.remove_fetcher = _remove_fetcher,
  212: 			.destroy = _destroy,
  213: 		},
  214: 		.fetchers = linked_list_create(),
  215: 		.lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
  216: 	);
  217: 
  218: 	return &this->public;
  219: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>