Mercurial > openid
comparison src/c/openid.c @ 1:c230e6da3ff6
Discovered LiveJournal endpoint
author | Adam Chlipala <adam@chlipala.net> |
---|---|
date | Sun, 26 Dec 2010 13:10:36 -0500 |
parents | 3c209338e596 |
children | b757dc2bd2f6 |
comparison
equal
deleted
inserted
replaced
0:3c209338e596 | 1:c230e6da3ff6 |
---|---|
1 #include <string.h> | |
2 | |
1 #include <openssl/sha.h> | 3 #include <openssl/sha.h> |
2 #include <curl/curl.h> | 4 #include <curl/curl.h> |
5 #include <expat.h> | |
3 | 6 |
4 #include <urweb/urweb.h> | 7 #include <openid.h> |
5 | 8 |
6 uw_unit uw_OpenidFfi_init(uw_context ctx) { | 9 uw_unit uw_OpenidFfi_init(uw_context ctx) { |
7 curl_global_init(CURL_GLOBAL_ALL); | 10 curl_global_init(CURL_GLOBAL_ALL); |
8 | 11 |
9 return uw_unit_v; | 12 return uw_unit_v; |
10 } | 13 } |
14 | |
15 static CURL *curl(uw_context ctx) { | |
16 CURL *r; | |
17 | |
18 if (!(r = uw_get_global(ctx, "curl"))) { | |
19 r = curl_easy_init(); | |
20 if (r) | |
21 uw_set_global(ctx, "curl", r, curl_easy_cleanup); | |
22 } | |
23 | |
24 return r; | |
25 } | |
26 | |
27 typedef struct { | |
28 uw_context ctx; | |
29 char *result; | |
30 } endpoint; | |
31 | |
32 static void XMLCALL startElement(void *userData, const XML_Char *name, const XML_Char **atts) { | |
33 endpoint *ep = userData; | |
34 | |
35 if (!strcmp(name, "link")) { | |
36 const XML_Char **attp; | |
37 int found = 0; | |
38 | |
39 for (attp = atts; *attp; attp += 2) { | |
40 if (!strcmp(attp[0], "rel") && !strcmp(attp[1], "openid2.provider")) { | |
41 found = 1; | |
42 break; | |
43 } | |
44 } | |
45 | |
46 if (found) { | |
47 for (attp = atts; *attp; attp += 2) { | |
48 if (!strcmp(attp[0], "href")) { | |
49 ep->result = uw_strdup(ep->ctx, attp[1]); | |
50 return; | |
51 } | |
52 } | |
53 } | |
54 } | |
55 } | |
56 | |
57 static void XMLCALL endElement(void *userData, const XML_Char *name) { | |
58 } | |
59 | |
60 typedef struct { | |
61 XML_Parser parser; | |
62 int any_errors; | |
63 } curl_data; | |
64 | |
65 static size_t write_data(void *buffer, size_t size, size_t nmemb, void *userp) { | |
66 curl_data *d = userp; | |
67 | |
68 if (!XML_Parse(d->parser, buffer, size * nmemb, 0)) | |
69 d->any_errors = 1; | |
70 | |
71 return size * nmemb; | |
72 } | |
73 | |
74 uw_Basis_string uw_OpenidFfi_discover(uw_context ctx, uw_Basis_string id) { | |
75 char *s; | |
76 CURL *c = curl(ctx); | |
77 curl_data cd = {}; | |
78 endpoint ep = {ctx}; | |
79 CURLcode code; | |
80 | |
81 if (!strchr(id, ':')) { | |
82 id = uw_Basis_strcat(ctx, "http://", id); | |
83 if ((s = strchr(id, '#')) != NULL) | |
84 *s = 0; | |
85 } else if ((s = strchr(id, '#')) != NULL) { | |
86 char *id2 = uw_malloc(ctx, s - id + 1); | |
87 memcpy(id2, s, s - id); | |
88 id2[s - id] = 0; | |
89 id = id2; | |
90 } | |
91 | |
92 cd.parser = XML_ParserCreate(NULL); | |
93 XML_SetUserData(cd.parser, &ep); | |
94 uw_push_cleanup(ctx, (void (*)(void *))XML_ParserFree, cd.parser); | |
95 XML_SetElementHandler(cd.parser, startElement, endElement); | |
96 | |
97 curl_easy_setopt(c, CURLOPT_URL, id); | |
98 curl_easy_setopt(c, CURLOPT_WRITEFUNCTION, write_data); | |
99 curl_easy_setopt(c, CURLOPT_WRITEDATA, &cd); | |
100 | |
101 code = curl_easy_perform(c); | |
102 uw_pop_cleanup(ctx); | |
103 | |
104 if (code) | |
105 return NULL; | |
106 else | |
107 return ep.result; | |
108 } |