Added support for FETCH_CALLBACK to soup fetcher

This commit is contained in:
Martin Willi
2011-04-04 08:48:27 +02:00
parent c5a46f3b63
commit f27705cea1
+45 -9
View File
@@ -58,45 +58,77 @@ struct private_soup_fetcher_t {
* HTTP request version * HTTP request version
*/ */
SoupHTTPVersion version; SoupHTTPVersion version;
/**
* Fetcher callback function
*/
fetcher_callback_t cb;
}; };
/**
* Data to pass to soup callback
*/
typedef struct {
fetcher_callback_t cb;
void *user;
SoupSession *session;
} cb_data_t;
/**
* Soup callback invoking our callback
*/
static void soup_cb(SoupMessage *message, SoupBuffer *chunk, cb_data_t *data)
{
if (!data->cb(data->user, chunk_create((u_char*)chunk->data, chunk->length)))
{
soup_session_cancel_message(data->session, message,
SOUP_STATUS_CANCELLED);
}
}
METHOD(fetcher_t, fetch, status_t, METHOD(fetcher_t, fetch, status_t,
private_soup_fetcher_t *this, char *uri, void *userdata) private_soup_fetcher_t *this, char *uri, void *userdata)
{ {
SoupSession *session;
SoupMessage *message; SoupMessage *message;
status_t status = FAILED; status_t status = FAILED;
chunk_t *result = userdata; cb_data_t data = {
.cb = this->cb,
.user = userdata,
};
message = soup_message_new(this->method, uri); message = soup_message_new(this->method, uri);
if (!message) if (!message)
{ {
return NOT_SUPPORTED; return NOT_SUPPORTED;
} }
if (this->cb == fetcher_default_callback)
{
*(chunk_t*)userdata = chunk_empty;
}
if (this->type) if (this->type)
{ {
soup_message_set_request(message, this->type, SOUP_MEMORY_STATIC, soup_message_set_request(message, this->type, SOUP_MEMORY_STATIC,
this->data.ptr, this->data.len); this->data.ptr, this->data.len);
} }
soup_message_set_http_version(message, this->version); soup_message_set_http_version(message, this->version);
session = soup_session_sync_new(); soup_message_body_set_accumulate(message->response_body, FALSE);
g_object_set(G_OBJECT(session), g_signal_connect(message, "got-chunk", G_CALLBACK(soup_cb), &data);
data.session = soup_session_sync_new();
g_object_set(G_OBJECT(data.session),
SOUP_SESSION_TIMEOUT, (guint)this->timeout, NULL); SOUP_SESSION_TIMEOUT, (guint)this->timeout, NULL);
DBG2(DBG_LIB, "sending http request to '%s'...", uri); DBG2(DBG_LIB, "sending http request to '%s'...", uri);
soup_session_send_message(session, message); soup_session_send_message(data.session, message);
if (SOUP_STATUS_IS_SUCCESSFUL(message->status_code)) 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; status = SUCCESS;
} }
else else
{ {
DBG1(DBG_LIB, "HTTP request failed, code %d", message->status_code); DBG1(DBG_LIB, "HTTP request failed: %s", message->reason_phrase);
} }
g_object_unref(G_OBJECT(message)); g_object_unref(G_OBJECT(message));
g_object_unref(G_OBJECT(session)); g_object_unref(G_OBJECT(data.session));
return status; return status;
} }
@@ -122,6 +154,9 @@ METHOD(fetcher_t, set_option, bool,
case FETCH_TIMEOUT: case FETCH_TIMEOUT:
this->timeout = va_arg(args, u_int); this->timeout = va_arg(args, u_int);
break; break;
case FETCH_CALLBACK:
this->cb = va_arg(args, fetcher_callback_t);
break;
default: default:
supported = FALSE; supported = FALSE;
break; break;
@@ -154,6 +189,7 @@ soup_fetcher_t *soup_fetcher_create()
.method = SOUP_METHOD_GET, .method = SOUP_METHOD_GET,
.version = SOUP_HTTP_1_1, .version = SOUP_HTTP_1_1,
.timeout = DEFAULT_TIMEOUT, .timeout = DEFAULT_TIMEOUT,
.cb = fetcher_default_callback,
); );
return &this->public; return &this->public;