Mercurial > openid
diff src/c/openid.c @ 3:f59083771ee2
Saving associations
author | Adam Chlipala <adam@chlipala.net> |
---|---|
date | Sun, 26 Dec 2010 15:11:23 -0500 |
parents | b757dc2bd2f6 |
children | 2d409aff8800 |
line wrap: on
line diff
--- a/src/c/openid.c Sun Dec 26 13:28:06 2010 -0500 +++ b/src/c/openid.c Sun Dec 26 15:11:23 2010 -0500 @@ -6,6 +6,9 @@ #include <openid.h> +#define BUF_MAX 10240 +#define BUF_INIT 1024 + struct uw_OpenidFfi_discovery { uw_Basis_string endpoint, localId; }; @@ -72,10 +75,10 @@ typedef struct { XML_Parser parser; int any_errors; -} curl_data; +} curl_discovery_data; -static size_t write_data(void *buffer, size_t size, size_t nmemb, void *userp) { - curl_data *d = userp; +static size_t write_discovery_data(void *buffer, size_t size, size_t nmemb, void *userp) { + curl_discovery_data *d = userp; if (!XML_Parse(d->parser, buffer, size * nmemb, 0)) d->any_errors = 1; @@ -86,7 +89,7 @@ uw_OpenidFfi_discovery *uw_OpenidFfi_discover(uw_context ctx, uw_Basis_string id) { char *s; CURL *c = curl(ctx); - curl_data cd = {}; + curl_discovery_data cd = {}; uw_OpenidFfi_discovery dy = uw_malloc(ctx, sizeof(struct uw_OpenidFfi_discovery)); endpoint ep = {ctx, dy}; CURLcode code; @@ -110,7 +113,7 @@ XML_SetElementHandler(cd.parser, startElement, endElement); curl_easy_setopt(c, CURLOPT_URL, id); - curl_easy_setopt(c, CURLOPT_WRITEFUNCTION, write_data); + curl_easy_setopt(c, CURLOPT_WRITEFUNCTION, write_discovery_data); curl_easy_setopt(c, CURLOPT_WRITEDATA, &cd); code = curl_easy_perform(c); @@ -124,3 +127,101 @@ return dyp; } } + +uw_OpenidFfi_inputs uw_OpenidFfi_createInputs(uw_context ctx) { + uw_buffer *r = uw_malloc(ctx, sizeof(uw_buffer)); + uw_buffer_init(BUF_MAX, r, BUF_INIT); + return r; +} + +static int okForPost(const char *s) { + for (; *s; ++s) + if (*s == '=' || *s == '&') + return 0; + return 1; +} + +uw_unit uw_OpenidFfi_addInput(uw_context ctx, uw_OpenidFfi_inputs buf, uw_Basis_string key, uw_Basis_string value) { + if (!okForPost(key)) + uw_error(ctx, FATAL, "Invalid key for OpenID inputs"); + if (!okForPost(value)) + uw_error(ctx, FATAL, "Invalid value for OpenID inputs"); + + if (uw_buffer_used(buf) > 0) + uw_buffer_append(buf, "&", 1); + + uw_buffer_append(buf, key, strlen(key)); + uw_buffer_append(buf, "=", 1); + uw_buffer_append(buf, value, strlen(value)); + + return uw_unit_v; +} + +uw_Basis_string uw_OpenidFfi_getOutput(uw_context ctx, uw_OpenidFfi_outputs buf, uw_Basis_string key) { + char *s = buf->start; + + for (; *s; s = strchr(strchr(s, 0)+1, 0)+1) + if (!strcmp(key, s)) + return strchr(s, 0)+1; + + return NULL; +} + +static size_t write_buffer_data(void *buffer, size_t size, size_t nmemb, void *userp) { + uw_buffer *buf = userp; + + uw_buffer_append(buf, buffer, size * nmemb); + + return size * nmemb; +} + +const char curl_failure[] = "error\0Error fetching URL"; + +uw_OpenidFfi_outputs uw_OpenidFfi_indirect(uw_context ctx, uw_Basis_string url, uw_OpenidFfi_inputs inps) { + uw_buffer *buf = uw_malloc(ctx, sizeof(uw_buffer)); + CURL *c = curl(ctx); + CURLcode code; + + uw_buffer_init(BUF_MAX, buf, BUF_INIT); + + uw_buffer_append(inps, "", 1); + + curl_easy_setopt(c, CURLOPT_URL, url); + curl_easy_setopt(c, CURLOPT_POSTFIELDS, inps->start); + curl_easy_setopt(c, CURLOPT_WRITEFUNCTION, write_buffer_data); + curl_easy_setopt(c, CURLOPT_WRITEDATA, buf); + + code = curl_easy_perform(c); + + uw_buffer_append(buf, "", 1); + + if (code) { + uw_buffer_reset(buf); + uw_buffer_append(buf, curl_failure, sizeof curl_failure); + } else { + char *s; + + s = buf->start; + while (*s) { + char *colon = strchr(s, ':'), *newline; + + if (!colon) { + *s = 0; + break; + } + + newline = strchr(colon+1, '\n'); + + if (!newline) { + *s = 0; + break; + } + + *colon = 0; + *newline = 0; + s = newline+1; + } + } + + return buf; +}