|
@@ -1935,6 +1935,85 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers,
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+ if (!strcmpstart(url,"/tor/status-vote/current/") ||
|
|
|
+ !strcmpstart(url,"/tor/status-vote/next/")) {
|
|
|
+ char *url_mem = url;
|
|
|
+ size_t url_len = strlen(url);
|
|
|
+ int deflated = !strcmp(url+url_len-2, ".z");
|
|
|
+ int current = 1;
|
|
|
+ ssize_t body_len = 0;
|
|
|
+ smartlist_t *items = smartlist_create();
|
|
|
+ smartlist_t *dir_items = smartlist_create();
|
|
|
+ int lifetime = 60; /* XXXX020 should actually use vote intervals. */
|
|
|
+ if (deflated)
|
|
|
+ url[url_len-2] = '\0';
|
|
|
+ url += strlen("/tor/status-vote/");
|
|
|
+ current = !strcmpstart(url, "current/");
|
|
|
+ url = strchr(url, '/');
|
|
|
+ tor_assert(url);
|
|
|
+ ++url;
|
|
|
+ if (!strcmp(url, "consensus")) {
|
|
|
+ const char *item;
|
|
|
+ tor_assert(!current); /* we handle current consensus specially above,
|
|
|
+ * since it wants to be spooled. */
|
|
|
+ if ((item = dirvote_get_pending_consensus()))
|
|
|
+ smartlist_add(items, (char*)item);
|
|
|
+ } else if (current && !strcmp(url, "consensus-signatures")) {
|
|
|
+ /* XXXX020 the spec says that we should implement
|
|
|
+ * currrent/consensus-signatures too. Why? */
|
|
|
+ const char *item;
|
|
|
+ if ((item=dirvote_get_pending_detached_signatures()))
|
|
|
+ smartlist_add(items, (char*)item);
|
|
|
+ } else if (current && !strcmp(url, "authority")) {
|
|
|
+ const cached_dir_t *d;
|
|
|
+ if ((d=dirvote_get_vote(NULL)))
|
|
|
+ smartlist_add(dir_items, (cached_dir_t*)d);
|
|
|
+ } else if (current) {
|
|
|
+ const cached_dir_t *d;
|
|
|
+ smartlist_t *fps = smartlist_create();
|
|
|
+ dir_split_resource_into_fingerprints(url, fps, NULL, 1, 1);
|
|
|
+ SMARTLIST_FOREACH(fps, char *, fp, {
|
|
|
+ if ((d = dirvote_get_vote(fp)))
|
|
|
+ smartlist_add(dir_items, (cached_dir_t*)d);
|
|
|
+ tor_free(fp);
|
|
|
+ });
|
|
|
+ smartlist_free(fps);
|
|
|
+ }
|
|
|
+ if (!smartlist_len(dir_items) && !smartlist_len(items)) {
|
|
|
+ write_http_status_line(conn, 404, "Not found");
|
|
|
+ tor_free(url_mem);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ SMARTLIST_FOREACH(items, const char *, item,
|
|
|
+ if (!deflated)
|
|
|
+ body_len += strlen(item));
|
|
|
+ SMARTLIST_FOREACH(dir_items, cached_dir_t *, d,
|
|
|
+ body_len += deflated ? d->dir_z_len : d->dir_len);
|
|
|
+ write_http_response_header(conn, body_len ? body_len : -1,
|
|
|
+ deflated?"application/octet_stream":"text/plain",
|
|
|
+ deflated?"deflate":NULL,
|
|
|
+ lifetime);
|
|
|
+
|
|
|
+ if (smartlist_len(items)) {
|
|
|
+ if (deflated) {
|
|
|
+ conn->zlib_state = tor_zlib_new(1, ZLIB_METHOD);
|
|
|
+ SMARTLIST_FOREACH(items, const char *, c,
|
|
|
+ connection_write_to_buf_zlib(c, strlen(c), conn, 0));
|
|
|
+ connection_write_to_buf_zlib("", 0, conn, 1);
|
|
|
+ } else {
|
|
|
+ SMARTLIST_FOREACH(items, const char *, c,
|
|
|
+ connection_write_to_buf(c, strlen(c), TO_CONN(conn)));
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ SMARTLIST_FOREACH(dir_items, cached_dir_t *, d,
|
|
|
+ connection_write_to_buf(deflated ? d->dir_z : d->dir,
|
|
|
+ deflated ? d->dir_z_len : d->dir_len,
|
|
|
+ TO_CONN(conn)));
|
|
|
+ }
|
|
|
+ tor_free(url_mem);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
if (!strcmpstart(url,"/tor/server/") ||
|
|
|
!strcmpstart(url,"/tor/extra/")) {
|
|
|
char *url_mem = url;
|