Annotation of embedaddon/strongswan/src/libstrongswan/plugins/soup/soup_fetcher.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2010 Martin Willi
3: * Copyright (C) 2010 revosec AG
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 "soup_fetcher.h"
17:
18: #include <libsoup/soup.h>
19:
20: #include <library.h>
21: #include <utils/debug.h>
22:
23: #define DEFAULT_TIMEOUT 10
24:
25: typedef struct private_soup_fetcher_t private_soup_fetcher_t;
26:
27: /**
28: * private data of a soup_fetcher_t object.
29: */
30: struct private_soup_fetcher_t {
31:
32: /**
33: * Public data
34: */
35: soup_fetcher_t public;
36:
37: /**
38: * HTTP request method
39: */
40: const char *method;
41:
42: /**
43: * Request content type
44: */
45: char *type;
46:
47: /**
48: * Request data
49: */
50: chunk_t data;
51:
52: /**
53: * Request timeout
54: */
55: u_int timeout;
56:
57: /**
58: * HTTP request version
59: */
60: SoupHTTPVersion version;
61:
62: /**
63: * Fetcher callback function
64: */
65: fetcher_callback_t cb;
66:
67: /**
68: * Response status
69: */
70: u_int *result;
71: };
72:
73: /**
74: * Data to pass to soup callback
75: */
76: typedef struct {
77: fetcher_callback_t cb;
78: void *user;
79: SoupSession *session;
80: } cb_data_t;
81:
82: /**
83: * Soup callback invoking our callback
84: */
85: static void soup_cb(SoupMessage *message, SoupBuffer *chunk, cb_data_t *data)
86: {
87: if (!data->cb(data->user, chunk_create((u_char*)chunk->data, chunk->length)))
88: {
89: soup_session_cancel_message(data->session, message,
90: SOUP_STATUS_CANCELLED);
91: }
92: }
93:
94: METHOD(fetcher_t, fetch, status_t,
95: private_soup_fetcher_t *this, char *uri, void *userdata)
96: {
97: SoupMessage *message;
98: status_t status = FAILED;
99: cb_data_t data = {
100: .cb = this->cb,
101: .user = userdata,
102: };
103:
104: message = soup_message_new(this->method, uri);
105: if (!message)
106: {
107: return NOT_SUPPORTED;
108: }
109: if (this->cb == fetcher_default_callback)
110: {
111: *(chunk_t*)userdata = chunk_empty;
112: }
113: if (this->type)
114: {
115: soup_message_set_request(message, this->type, SOUP_MEMORY_STATIC,
116: this->data.ptr, this->data.len);
117: }
118: soup_message_set_http_version(message, this->version);
119: soup_message_body_set_accumulate(message->response_body, FALSE);
120: g_signal_connect(message, "got-chunk", G_CALLBACK(soup_cb), &data);
121: data.session = soup_session_new();
122: g_object_set(G_OBJECT(data.session),
123: SOUP_SESSION_TIMEOUT, (guint)this->timeout, NULL);
124:
125: DBG2(DBG_LIB, "sending http request to '%s'...", uri);
126: soup_session_send_message(data.session, message);
127: if (this->result)
128: {
129: *this->result = message->status_code;
130: }
131: if (SOUP_STATUS_IS_SUCCESSFUL(message->status_code))
132: {
133: status = SUCCESS;
134: }
135: else if (!this->result)
136: { /* only log an error if the code is not returned */
137: DBG1(DBG_LIB, "HTTP request failed: %s", message->reason_phrase);
138: }
139: g_object_unref(G_OBJECT(message));
140: g_object_unref(G_OBJECT(data.session));
141: return status;
142: }
143:
144: METHOD(fetcher_t, set_option, bool,
145: private_soup_fetcher_t *this, fetcher_option_t option, ...)
146: {
147: bool supported = TRUE;
148: va_list args;
149:
150: va_start(args, option);
151: switch (option)
152: {
153: case FETCH_REQUEST_DATA:
154: this->method = SOUP_METHOD_POST;
155: this->data = va_arg(args, chunk_t);
156: break;
157: case FETCH_REQUEST_TYPE:
158: this->type = va_arg(args, char*);
159: break;
160: case FETCH_HTTP_VERSION_1_0:
161: this->version = SOUP_HTTP_1_0;
162: break;
163: case FETCH_TIMEOUT:
164: this->timeout = va_arg(args, u_int);
165: break;
166: case FETCH_CALLBACK:
167: this->cb = va_arg(args, fetcher_callback_t);
168: break;
169: case FETCH_RESPONSE_CODE:
170: this->result = va_arg(args, u_int*);
171: break;
172: default:
173: supported = FALSE;
174: break;
175: }
176: va_end(args);
177: return supported;
178: }
179:
180: METHOD(fetcher_t, destroy, void,
181: private_soup_fetcher_t *this)
182: {
183: free(this);
184: }
185:
186: /*
187: * Described in header.
188: */
189: soup_fetcher_t *soup_fetcher_create()
190: {
191: private_soup_fetcher_t *this;
192:
193: INIT(this,
194: .public = {
195: .interface = {
196: .fetch = _fetch,
197: .set_option = _set_option,
198: .destroy = _destroy,
199: },
200: },
201: .method = SOUP_METHOD_GET,
202: .version = SOUP_HTTP_1_1,
203: .timeout = DEFAULT_TIMEOUT,
204: .cb = fetcher_default_callback,
205: );
206:
207: return &this->public;
208: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>