1 /* logjam - a GTK client for LiveJournal.
2 * Copyright (C) 2000-2004 Evan Martin <martine@danga.com>
8 #include "liblj/getchallenge.h"
9 #include "liblj/livejournal.h"
13 #include "network-internal.h"
16 GQuark
net_error_quark (void) {
17 static GQuark quark
= 0;
18 if (quark
== 0) quark
= g_quark_from_static_string("logjam-net-error-quark");
23 static GString
*real_run_request (const char *url
, GString
*post
, NetStatusCallback cb
, gpointer data
, GError
**err
) {
25 if (conf
.options
.nofork
|| app
.cli
) return net_post_blocking(url
, NULL
, post
, cb
, data
, err
);
26 return net_post_mainloop(url
, NULL
, post
, cb
, data
, err
);
28 return net_post_blocking(url
, NULL
, post
, cb
, data
, err
);
33 gboolean
net_verb_run_directly (LJVerb
*verb
, NetStatusCallback cb
, gpointer data
, GError
**err
) {
38 urlbase
= lj_request_get_user(verb
->request
)->server
->url
;
39 url
= g_strdup_printf("%s/interface/flat", urlbase
);
40 post
= lj_request_to_string(verb
->request
);
41 res
= real_run_request(url
, post
, cb
, data
, err
);
42 g_string_free(post
, TRUE
);
44 if (res
== NULL
) return FALSE
;
45 ret
= lj_verb_handle_response(verb
, res
->str
, err
);
46 g_string_free(res
, TRUE
);
51 gboolean
net_verb_run_internal (LJVerb
*verb
, NetStatusCallback cb
, gpointer data
, GError
**err
) {
52 LJUser
*user
= lj_request_get_user(verb
->request
);
53 LJServer
*server
= user
->server
;
54 if (server
->authscheme
== LJ_AUTH_SCHEME_UNKNOWN
|| server
->authscheme
== LJ_AUTH_SCHEME_C0
) {
55 LJGetChallenge
*getchal
= lj_getchallenge_new(user
);
56 GError
*chalerr
= NULL
;
57 if (!net_verb_run_directly((LJVerb
*) getchal
, cb
, data
, &chalerr
)) {
58 /* failed. no auth scheme available? */
59 server
->authscheme
= LJ_AUTH_SCHEME_NONE
;
61 server
->authscheme
= getchal
->authscheme
;
62 if (server
->authscheme
== LJ_AUTH_SCHEME_C0
) lj_verb_use_challenge(verb
, getchal
->challenge
);
64 lj_getchallenge_free(getchal
);
66 /* if there was a total failure when we tried to send the
67 * challenge, stop here. we don't even need to attempt
68 * the subsequent request. */
69 if (g_error_matches(chalerr
, NET_ERROR
, NET_ERROR_CANCELLED
) || g_error_matches(chalerr
, NET_ERROR
, NET_ERROR_GENERIC
)) {
70 g_propagate_error(err
, chalerr
);
73 g_error_free(chalerr
);
76 return net_verb_run_directly(verb
, cb
, data
, err
);
80 void ctx_cmdline_print_string (NetContext
*ctx
, const char *text
) {
81 if (!app
.quiet
) g_print("%s\n", text
);
85 static void cmdline_statuscb (NetStatusType status
, gpointer statusdata
, gpointer data
) {
90 static GString
*ctx_cmdline_http (NetContext
*ctx
, const char *url
, GSList
*headers
, GString
*post
, GError
**err
) {
91 return net_post_blocking(url
, NULL
, post
, cmdline_statuscb
, ctx
, err
);
95 void ctx_cmdline_error (NetContext
*ctx
, GError
*err
) {
96 g_printerr(_("Error: %s\n"), err
->message
);
100 /* f() means *any* argument list, not just void */
101 void ctx_silent_noop () {
105 static NetContext network_ctx_silent_real
= {
107 .progress_str
= ctx_silent_noop
,
108 .progress_int
= NULL
,
109 .error
= ctx_silent_noop
,
110 .http
= ctx_cmdline_http
,
113 NetContext
*network_ctx_silent
= &network_ctx_silent_real
;
116 static NetContext network_ctx_cmdline_real
= {
118 .progress_str
= ctx_cmdline_print_string
,
119 .progress_int
= NULL
,
120 .error
= ctx_cmdline_error
,
121 .http
= ctx_cmdline_http
,
124 NetContext
*network_ctx_cmdline
= &network_ctx_cmdline_real
;
127 gboolean
run_verb (LJVerb
*verb
, NetContext
*ctx
, GError
**err
) {
132 urlbase
= lj_request_get_user(verb
->request
)->server
->url
;
133 url
= g_strdup_printf("%s/interface/flat", urlbase
);
134 post
= lj_request_to_string(verb
->request
);
135 res
= ctx
->http(ctx
, url
, NULL
, post
, err
);
136 g_string_free(post
, TRUE
);
138 if (res
== NULL
) return FALSE
;
139 ret
= lj_verb_handle_response(verb
, res
->str
, err
);
140 g_string_free(res
, TRUE
);
145 gboolean
net_run_verb_ctx (LJVerb
*verb
, NetContext
*ctx
, GError
**reterr
) {
146 LJUser
*user
= lj_request_get_user(verb
->request
);
147 LJServer
*server
= user
->server
;
149 gboolean success
= FALSE
;
150 if (server
->authscheme
== LJ_AUTH_SCHEME_UNKNOWN
|| server
->authscheme
== LJ_AUTH_SCHEME_C0
) {
151 LJGetChallenge
*getchal
= lj_getchallenge_new(user
);
152 ctx
->progress_str(ctx
, _("Requesting challenge..."));
153 if (!run_verb((LJVerb
*) getchal
, ctx
, &err
)) {
154 /* failed. no auth scheme available? */
155 server
->authscheme
= LJ_AUTH_SCHEME_NONE
;
157 server
->authscheme
= getchal
->authscheme
;
158 if (server
->authscheme
== LJ_AUTH_SCHEME_C0
) lj_verb_use_challenge(verb
, getchal
->challenge
);
160 lj_getchallenge_free(getchal
);
162 /* if there was a total failure when we tried to send the
163 * challenge, stop here. we don't even need to attempt
164 * the subsequent request. */
165 if (g_error_matches(err
, NET_ERROR
, NET_ERROR_CANCELLED
) || g_error_matches(err
, NET_ERROR
, NET_ERROR_GENERIC
)) goto out
;
170 ctx
->progress_str(ctx
, _("Running request..."));
171 success
= run_verb(verb
, ctx
, &err
);
174 if (ctx
->error
) ctx
->error(ctx
, err
);
175 g_propagate_error(reterr
, err
);