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 instead of libcurl */
27 #include <quvi/quvi.h>
29 #ifdef HAVE_LIBSOUP_GNOME
30 #include <libsoup/soup-gnome.h>
32 #include <libsoup/soup.h>
37 static QUVIcode
status_callback(long param
, void *data
)
39 quvi_word status
, type
;
41 status
= quvi_loword(param
);
42 type
= quvi_hiword(param
);
46 case QUVISTATUS_RESOLVE
:
47 handle_resolve_status(type
);
50 case QUVISTATUS_FETCH
:
51 handle_fetch_status(type
, data
);
54 case QUVISTATUS_VERIFY
:
55 handle_verify_status(type
);
64 static void set_feat(quvi_net_t n
, SoupMessage
*m
,
65 QUVInetPropertyFeatureName feature
,
68 char *s
= quvi_net_get_one_prop_feat(n
, feature
);
70 soup_message_headers_append(m
->request_headers
, hdr
, s
);
73 static void set_feats_from_lua_script(quvi_net_t n
, SoupMessage
*m
)
75 set_feat(n
, m
, QUVI_NET_PROPERTY_FEATURE_ARBITRARYCOOKIE
, "Cookie");
76 set_feat(n
, m
, QUVI_NET_PROPERTY_FEATURE_USERAGENT
, "User-Agent");
79 quvi_llst_node_t feature
;
80 quvi_net_getprop(n
, QUVI_NET_PROPERTY_FEATURES
, &feature
);
84 char *feature_name
, *feature_value
;
85 quvi_net_propfeat_t pfeat
;
87 pfeat
= (quvi_net_propfeat_t
) quvi_llst_data(feature
);
89 quvi_net_getprop_feat(pfeat
,
90 QUVI_NET_PROPERTY_FEATURE_NAME
, &feature_name
);
92 quvi_net_getprop_feat(pfeat
,
93 QUVI_NET_PROPERTY_FEATURE_VALUE
, &feature_value
);
95 if (strcmp(feature_name
, "arbitrary_cookie") == 0)
97 soup_message_headers_append(
98 m
->request_headers
, "Cookie", feature_value
);
101 if (strcmp(feature_name
, "user_agent") == 0)
103 soup_message_headers_append(
104 m
->request_headers
, "User-Agent", feature_value
);
107 feature
= quvi_llst_next(feature
);
112 static SoupSession
*session
= NULL
;
114 static void send_message(quvi_net_t n
, SoupMessage
**message
,
115 guint
*status
, SoupMessageFlags msg_flags
,
116 const int head_flag
, const int lua_feats
)
120 quvi_net_getprop(n
, QUVI_NET_PROPERTY_URL
, &url
);
122 *message
= soup_message_new(head_flag
? "HEAD":"GET", url
);
125 soup_message_set_flags(*message
, msg_flags
);
127 /* Even if this is conditional here, the current library design sets
128 * these options (set in the LUA website scripts with quvi.fetch
129 * call) for fetch callback only. */
131 set_feats_from_lua_script(n
, *message
);
133 *status
= soup_session_send_message(session
, *message
);
135 quvi_net_setprop(n
, QUVI_NET_PROPERTY_RESPONSECODE
, *status
);
138 static QUVIcode
fetch_callback(quvi_net_t n
)
143 send_message(n
, &m
, &status
, 0, 0, 1 /* Set LUA opts flag */);
145 if (SOUP_STATUS_IS_SUCCESSFUL(status
))
147 quvi_net_setprop(n
, QUVI_NET_PROPERTY_CONTENT
, m
->response_body
->data
);
151 quvi_net_seterr(n
, "%s (http/%d)", m
->reason_phrase
, status
);
153 return (QUVI_CALLBACK
);
156 static QUVIcode
resolve_callback(quvi_net_t n
)
161 send_message(n
, &m
, &status
, SOUP_MESSAGE_NO_REDIRECT
, 0, 0);
163 if (SOUP_STATUS_IS_REDIRECTION(status
))
166 soup_message_headers_get_one(m
->response_headers
, "Location");
168 quvi_net_setprop(n
, QUVI_NET_PROPERTY_REDIRECTURL
, r_url
);
170 else if (!SOUP_STATUS_IS_SUCCESSFUL(status
))
172 quvi_net_seterr(n
, "%s (http/%d)", m
->reason_phrase
, status
);
173 return (QUVI_CALLBACK
);
179 static QUVIcode
verify_callback(quvi_net_t n
)
184 send_message(n
, &m
, &status
, 0, 1 /* HEAD */, 0);
186 if (SOUP_STATUS_IS_SUCCESSFUL(status
))
189 soup_message_headers_get_content_length(m
->response_headers
);
192 soup_message_headers_get_content_type(m
->response_headers
, NULL
);
194 quvi_net_setprop(n
, QUVI_NET_PROPERTY_CONTENTTYPE
, ct
);
195 quvi_net_setprop(n
, QUVI_NET_PROPERTY_CONTENTLENGTH
, cl
);
200 quvi_net_seterr(n
, "%s (http/%d)", m
->reason_phrase
, status
);
202 return (QUVI_CALLBACK
);
208 "Usage: callback_libsoup [--help|--log] [URL]\n\n"
209 " -h,--help .. Print help and exit\n"
210 " -l,--logger .. Enable logger\n\n"
211 "Note: Unless URL is specified, the default URL will be used\n");
215 int main (int argc
, char *argv
[])
217 char *url
= "http://is.gd/yFNPMR";
228 for (i
=1; i
<argc
; ++i
)
230 if (strcmp(argv
[i
], "-l") == 0
231 || strcmp(argv
[i
], "--logger") == 0)
235 else if (strcmp(argv
[i
], "-h") == 0
236 || strcmp(argv
[i
], "--help") == 0)
248 quvi_setopt(q
, QUVIOPT_STATUSFUNCTION
, &status_callback
);
249 quvi_setopt(q
, QUVIOPT_FETCHFUNCTION
, &fetch_callback
);
250 quvi_setopt(q
, QUVIOPT_RESOLVEFUNCTION
, &resolve_callback
);
251 quvi_setopt(q
, QUVIOPT_VERIFYFUNCTION
, &verify_callback
);
255 #ifdef HAVE_LIBSOUP_GNOME
256 session
= soup_session_async_new_with_options(
257 SOUP_SESSION_ADD_FEATURE_BY_TYPE
,
258 SOUP_TYPE_PROXY_RESOLVER_GNOME
,
262 session
= soup_session_async_new();
267 SoupLogger
*log
= soup_logger_new(SOUP_LOGGER_LOG_HEADERS
, -1);
268 soup_session_add_feature(session
, SOUP_SESSION_FEATURE(log
));
272 rc
= quvi_parse(q
, url
, &m
);
275 quvi_parse_close(&m
);
281 /* vim: set ts=2 sw=2 tw=72 expandtab: */