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 }