/* * Copyright (C) 2010 Martin Willi * Copyright (C) 2010 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 . * * 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 "soup_fetcher.h" #include #include #include #define DEFAULT_TIMEOUT 10 typedef struct private_soup_fetcher_t private_soup_fetcher_t; /** * private data of a soup_fetcher_t object. */ struct private_soup_fetcher_t { /** * Public data */ soup_fetcher_t public; /** * HTTP request method */ const char *method; /** * Request content type */ char *type; /** * Request data */ chunk_t data; /** * Request timeout */ u_int timeout; /** * HTTP request version */ SoupHTTPVersion version; }; METHOD(fetcher_t, fetch, status_t, private_soup_fetcher_t *this, char *uri, chunk_t *result) { SoupSession *session; SoupMessage *message; status_t status = FAILED; message = soup_message_new(this->method, uri); if (!message) { return NOT_SUPPORTED; } if (this->type) { soup_message_set_request(message, this->type, SOUP_MEMORY_STATIC, this->data.ptr, this->data.len); } soup_message_set_http_version(message, this->version); session = soup_session_sync_new(); g_object_set(G_OBJECT(session), SOUP_SESSION_TIMEOUT, (guint)this->timeout, NULL); DBG2(DBG_LIB, "sending http request to '%s'...", uri); soup_session_send_message(session, message); if (SOUP_STATUS_IS_SUCCESSFUL(message->status_code)) { *result = chunk_clone(chunk_create((u_char*)message->response_body->data, message->response_body->length)); status = SUCCESS; } else { DBG1(DBG_LIB, "HTTP request failed, code %d", message->status_code); } g_object_unref(G_OBJECT(message)); g_object_unref(G_OBJECT(session)); return status; } METHOD(fetcher_t, set_option, bool, private_soup_fetcher_t *this, fetcher_option_t option, ...) { bool supported = TRUE; va_list args; va_start(args, option); switch (option) { case FETCH_REQUEST_DATA: this->method = SOUP_METHOD_POST; this->data = va_arg(args, chunk_t); break; case FETCH_REQUEST_TYPE: this->type = va_arg(args, char*); break; case FETCH_HTTP_VERSION_1_0: this->version = SOUP_HTTP_1_0; break; case FETCH_TIMEOUT: this->timeout = va_arg(args, u_int); break; default: supported = FALSE; break; } va_end(args); return supported; } METHOD(fetcher_t, destroy, void, private_soup_fetcher_t *this) { free(this); } /* * Described in header. */ soup_fetcher_t *soup_fetcher_create() { private_soup_fetcher_t *this; INIT(this, .public = { .interface = { .fetch = _fetch, .set_option = _set_option, .destroy = _destroy, }, }, .method = SOUP_METHOD_GET, .version = SOUP_HTTP_1_1, .timeout = DEFAULT_TIMEOUT, ); return &this->public; }