static char * wiki_html_cache() { fs_stats *stats = fs_stat(CLIB_SEARCH_CACHE); if (NULL == stats) goto set_cache; long now = (long) time(NULL); long modified = stats->st_mtime; long delta = now - modified; free(stats); if (delta < CLIB_SEARCH_CACHE_TIME) return fs_read(CLIB_SEARCH_CACHE); set_cache: ; http_get_response_t *res = http_get(CLIB_WIKI_URL); if (!res->ok) return NULL; char *html = str_copy(res->data); if (NULL == html) return NULL; http_get_free(res); if (NULL == html) return html; fs_write(CLIB_SEARCH_CACHE, html); return html; }
static char * wiki_html_cache() { char *cache_file = clib_search_file(); if (NULL == cache_file) return NULL; fs_stats *stats = fs_stat(cache_file); if (NULL == stats) goto set_cache; long now = (long) time(NULL); long modified = stats->st_mtime; long delta = now - modified; free(stats); if (delta < CLIB_SEARCH_CACHE_TIME) { char *data = fs_read(cache_file); free(cache_file); return data; } set_cache:; http_get_response_t *res = http_get(CLIB_WIKI_URL); if (!res->ok) return NULL; char *html = strdup(res->data); if (NULL == html) return NULL; http_get_free(res); if (NULL == html) return html; fs_write(cache_file, html); free(cache_file); return html; }
clib_package_t * clib_package_new_from_slug(const char *_slug, int verbose) { if (!_slug) return NULL; // sanitize `_slug` char *author = clib_package_parse_author(_slug); if (!author) return NULL; char *name = clib_package_parse_name(_slug); if (!name) return NULL; char *version = clib_package_parse_version(_slug); if (!version) return NULL; char *url = clib_package_url(author, name, version); if (!url) return NULL; char *json_url = clib_package_file_url(url, "package.json"); if (!json_url) { free(url); return NULL; } if (verbose) clib_package_log("fetch", json_url); http_get_response_t *res = http_get(json_url); if (!res || !res->ok) { clib_package_error("error", "unable to fetch %s", json_url); free(url); return NULL; } clib_package_t *pkg = clib_package_new(res->data, verbose); if (pkg) { // force version if (NULL == pkg->version || 0 != strcmp(version, pkg->version)) pkg->version = version; // force author if (NULL == pkg->author || 0 == strcmp(author, pkg->author)) pkg->author = author; // force repo char *repo = clib_package_repo(author, name); if (NULL == pkg->repo || 0 != strcmp(repo, pkg->repo)) { pkg->repo = repo; } else { free(repo); } pkg->url = url; } http_get_free(res); return pkg; }
/* * Send a "regular" HTTP GET message to "addr" and stuff the response * into the connection buffer. * Return the HTTP error code or <0 on failure. */ static long nreq(struct conn *c, const char *addr) { struct httpget *g; struct source src[MAX_SERVERS_DNS]; char *host, *path; short port; size_t srcsz; ssize_t ssz; long code; if (NULL == (host = url2host(addr, &port, &path))) return(-1); if ((ssz = urlresolve(c->dfd, host, src)) < 0) { free(host); free(path); return(-1); } srcsz = ssz; g = http_get(src, srcsz, host, port, path, NULL, 0); free(host); free(path); if (NULL == g) return(-1); code = g->code; /* Copy the body part into our buffer. */ free(c->buf.buf); c->buf.sz = g->bodypartsz; c->buf.buf = malloc(c->buf.sz); memcpy(c->buf.buf, g->bodypart, c->buf.sz); http_get_free(g); if (NULL == c->buf.buf) { warn("malloc"); return(-1); } return(code); }
clib_package_t * clib_package_new_from_slug(const char *slug, int verbose) { char *author = NULL; char *name = NULL; char *version = NULL; char *url = NULL; char *json_url = NULL; char *repo = NULL; http_get_response_t *res = NULL; clib_package_t *pkg = NULL; // parse chunks if (!slug) goto error; if (!(author = parse_repo_owner(slug, DEFAULT_REPO_OWNER))) goto error; if (!(name = parse_repo_name(slug))) goto error; if (!(version = parse_repo_version(slug, DEFAULT_REPO_VERSION))) goto error; if (!(url = clib_package_url(author, name, version))) goto error; if (!(json_url = clib_package_file_url(url, "package.json"))) goto error; if (!(repo = clib_package_repo(author, name))) goto error; // fetch json if (verbose) logger_info("fetch", json_url); res = http_get(json_url); if (!res || !res->ok) { logger_error("error", "unable to fetch %s", json_url); goto error; } free(json_url); json_url = NULL; free(name); name = NULL; // build package pkg = clib_package_new(res->data, verbose); http_get_free(res); res = NULL; if (!pkg) goto error; // force version number if (pkg->version) { if (0 != strcmp(version, pkg->version)) { free(pkg->version); pkg->version = version; } else { free(version); } } else { pkg->version = version; } // force package author (don't know how this could fail) if (pkg->author) { if (0 != strcmp(author, pkg->author)) { free(pkg->author); pkg->author = author; } else { free(author); } } else { pkg->author = author; } // force package repo if (pkg->repo) { if (0 != strcmp(repo, pkg->repo)) { free(pkg->repo); pkg->repo = repo; } else { free(repo); } } else { pkg->repo = repo; } pkg->url = url; return pkg; error: if (author) free(author); if (name) free(name); if (version) free(version); if (url) free(url); if (json_url) free(json_url); if (repo) free(repo); if (res) http_get_free(res); if (pkg) clib_package_free(pkg); return NULL; }
/* * Create and send a signed communication to the ACME server. * Stuff the response into the communication buffer. * Return <0 on failure on the HTTP error code otherwise. */ static long sreq(struct conn *c, const char *addr, const char *req) { struct httpget *g; struct source src[MAX_SERVERS_DNS]; char *host, *path, *nonce, *reqsn; short port; struct httphead *h; ssize_t ssz; long code; if (NULL == (host = url2host(c->na, &port, &path))) return(-1); if ((ssz = urlresolve(c->dfd, host, src)) < 0) { free(host); free(path); return(-1); } g = http_get(src, (size_t)ssz, host, port, path, NULL, 0); free(host); free(path); if (NULL == g) return(-1); h = http_head_get("Replay-Nonce", g->head, g->headsz); if (NULL == h) { warnx("%s: no replay nonce", c->na); http_get_free(g); return(-1); } else if (NULL == (nonce = strdup(h->val))) { warn("strdup"); http_get_free(g); return(-1); } http_get_free(g); /* * Send the nonce and request payload to the acctproc. * This will create the proper JSON object we need. */ if (writeop(c->fd, COMM_ACCT, ACCT_SIGN) <= 0) { free(nonce); return(-1); } else if (writestr(c->fd, COMM_PAY, req) <= 0) { free(nonce); return(-1); } else if (writestr(c->fd, COMM_NONCE, nonce) <= 0) { free(nonce); return(-1); } free(nonce); /* Now read back the signed payload. */ if (NULL == (reqsn = readstr(c->fd, COMM_REQ))) return(-1); /* Now send the signed payload to the CA. */ if (NULL == (host = url2host(addr, &port, &path))) { free(reqsn); return(-1); } else if ((ssz = urlresolve(c->dfd, host, src)) < 0) { free(host); free(path); free(reqsn); return(-1); } g = http_get(src, (size_t)ssz, host, port, path, reqsn, strlen(reqsn)); free(host); free(path); free(reqsn); if (NULL == g) return(-1); /* Stuff response into parse buffer. */ code = g->code; free(c->buf.buf); c->buf.sz = g->bodypartsz; c->buf.buf = malloc(c->buf.sz); memcpy(c->buf.buf, g->bodypart, c->buf.sz); http_get_free(g); if (NULL == c->buf.buf) { warn("malloc"); return(-1); } return(code); }