2 * Copyright (C) 2011 Toni Gundogdu <legatvs@gmail.com>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 /* callback_libsoup.c -- Use libsoup (async) instead of libcurl (easy) */
27 #include <quvi/quvi.h>
30 #ifdef HAVE_LIBSOUP_GNOME
31 #include <libsoup/soup-gnome.h>
33 #include <libsoup/soup.h>
38 static QUVIcode
status_callback(long param
, void *data
)
40 quvi_word status
, type
;
42 status
= quvi_loword(param
);
43 type
= quvi_hiword(param
);
47 case QUVISTATUS_RESOLVE
:
48 handle_resolve_status(type
);
51 case QUVISTATUS_FETCH
:
52 handle_fetch_status(type
, data
);
55 case QUVISTATUS_VERIFY
:
56 handle_verify_status(type
);
65 static void set_feat(quvi_net_t n
, SoupMessage
*m
,
66 QUVInetPropertyFeatureName feature
,
69 char *s
= quvi_net_get_one_prop_feat(n
, feature
);
71 soup_message_headers_append(m
->request_headers
, hdr
, s
);
74 static void set_feats_from_lua_script(quvi_net_t n
, SoupMessage
*m
)
76 set_feat(n
, m
, QUVI_NET_PROPERTY_FEATURE_ARBITRARYCOOKIE
, "Cookie");
77 set_feat(n
, m
, QUVI_NET_PROPERTY_FEATURE_USERAGENT
, "User-Agent");
81 /* Same as set_feats_from_lua_script above. quvi_net_get_one_prop_feat
82 * is a convinience function that can be used instead unless the
83 * application is expected handle >1 of the same features (e.g. multiple
84 * instances of QUVI_NET_PROPERTY_FEATURE_ARBITRARYCOOKIE in the
86 static void set_feats_from_lua_script_alt(quvi_net_t n
, SoupMessage
*m
)
88 quvi_llst_node_t feature
;
89 quvi_net_getprop(n
, QUVI_NET_PROPERTY_FEATURES
, &feature
);
93 char *feature_name
, *feature_value
;
94 quvi_net_propfeat_t pfeat
;
96 pfeat
= (quvi_net_propfeat_t
) quvi_llst_data(feature
);
98 quvi_net_getprop_feat(pfeat
,
99 QUVI_NET_PROPERTY_FEATURE_NAME
, &feature_name
);
101 quvi_net_getprop_feat(pfeat
,
102 QUVI_NET_PROPERTY_FEATURE_VALUE
, &feature_value
);
104 if (strcmp(feature_name
, "arbitrary_cookie") == 0)
106 soup_message_headers_append(
107 m
->request_headers
, "Cookie", feature_value
);
110 if (strcmp(feature_name
, "user_agent") == 0)
112 soup_message_headers_append(
113 m
->request_headers
, "User-Agent", feature_value
);
116 feature
= quvi_llst_next(feature
);
121 static SoupSession
*session
= NULL
;
123 static void send_message(quvi_net_t n
, SoupMessage
**message
,
124 guint
*status
, SoupMessageFlags msg_flags
,
125 const int head_flag
, const int lua_feats
)
129 quvi_net_getprop(n
, QUVI_NET_PROPERTY_URL
, &url
);
131 *message
= soup_message_new(head_flag
? "HEAD":"GET", url
);
134 soup_message_set_flags(*message
, msg_flags
);
136 /* In reality, the library sets these only for quvi.fetch. */
138 set_feats_from_lua_script(n
, *message
);
140 *status
= soup_session_send_message(session
, *message
);
142 quvi_net_setprop(n
, QUVI_NET_PROPERTY_RESPONSECODE
, *status
);
145 static QUVIcode
fetch_callback(quvi_net_t n
)
150 send_message(n
, &m
, &status
,
151 0, /* Session flags */
153 1); /* Set features from quvi.fetch */
155 if (SOUP_STATUS_IS_SUCCESSFUL(status
))
157 quvi_net_setprop(n
, QUVI_NET_PROPERTY_CONTENT
, m
->response_body
->data
);
161 quvi_net_seterr(n
, "%s (http/%d)", m
->reason_phrase
, status
);
163 return (QUVI_CALLBACK
);
166 static QUVIcode
resolve_callback(quvi_net_t n
)
171 send_message(n
, &m
, &status
,
172 SOUP_MESSAGE_NO_REDIRECT
, /* Session flags */
174 0); /* Set features from quvi.fetch */
176 if (SOUP_STATUS_IS_REDIRECTION(status
))
179 soup_message_headers_get_one(m
->response_headers
, "Location");
181 quvi_net_setprop(n
, QUVI_NET_PROPERTY_REDIRECTURL
, r_url
);
183 else if (!SOUP_STATUS_IS_SUCCESSFUL(status
))
185 quvi_net_seterr(n
, "%s (http/%d)", m
->reason_phrase
, status
);
186 return (QUVI_CALLBACK
);
192 static QUVIcode
verify_callback(quvi_net_t n
)
197 send_message(n
, &m
, &status
,
198 0, /* Session flags */
200 0); /* Set features from quvi.fetch */
202 if (SOUP_STATUS_IS_SUCCESSFUL(status
))
205 soup_message_headers_get_content_length(m
->response_headers
);
208 soup_message_headers_get_content_type(m
->response_headers
, NULL
);
210 quvi_net_setprop(n
, QUVI_NET_PROPERTY_CONTENTTYPE
, ct
);
211 quvi_net_setprop(n
, QUVI_NET_PROPERTY_CONTENTLENGTH
, cl
);
216 quvi_net_seterr(n
, "%s (http/%d)", m
->reason_phrase
, status
);
218 return (QUVI_CALLBACK
);
221 static void dump_media(quvi_media_t m
)
223 char *m_url
, *m_ct
, *m_suffix
;
226 quvi_getprop(m
, QUVIPROP_MEDIAURL
, &m_url
);
227 quvi_getprop(m
, QUVIPROP_MEDIACONTENTTYPE
, &m_ct
);
228 quvi_getprop(m
, QUVIPROP_MEDIACONTENTLENGTH
, &m_cl
);
229 quvi_getprop(m
, QUVIPROP_FILESUFFIX
, &m_suffix
);
235 "content-length: %.0f\n"
237 __func__
, m_url
, m_ct
, m_cl
, m_suffix
);
243 "Usage: callback_libsoup [--help|--log] [URL]\n\n"
244 " -h,--help .. Print help and exit\n"
245 " -l,--logger .. Enable logger\n\n"
246 "Note: Unless URL is specified, the default URL will be used\n");
250 int main (int argc
, char *argv
[])
252 char *url
= "http://is.gd/yFNPMR";
263 for (i
=1; i
<argc
; ++i
)
265 if (strcmp(argv
[i
], "-l") == 0
266 || strcmp(argv
[i
], "--logger") == 0)
270 else if (strcmp(argv
[i
], "-h") == 0
271 || strcmp(argv
[i
], "--help") == 0)
283 quvi_setopt(q
, QUVIOPT_STATUSFUNCTION
, &status_callback
);
284 quvi_setopt(q
, QUVIOPT_FETCHFUNCTION
, &fetch_callback
);
285 quvi_setopt(q
, QUVIOPT_RESOLVEFUNCTION
, &resolve_callback
);
286 quvi_setopt(q
, QUVIOPT_VERIFYFUNCTION
, &verify_callback
);
290 #ifdef HAVE_LIBSOUP_GNOME
291 session
= soup_session_async_new_with_options(
292 SOUP_SESSION_ADD_FEATURE_BY_TYPE
,
293 SOUP_TYPE_PROXY_RESOLVER_GNOME
,
297 session
= soup_session_async_new();
302 SoupLogger
*log
= soup_logger_new(SOUP_LOGGER_LOG_HEADERS
, -1);
303 soup_session_add_feature(session
, SOUP_SESSION_FEATURE(log
));
307 rc
= quvi_parse(q
, url
, &m
);
312 quvi_parse_close(&m
);
318 /* vim: set ts=2 sw=2 tw=72 expandtab: */