void json_send_qstring(const char *s) { const char *hex_digits = "0123456789abcdef", *begin = s; unsigned int len = 0; char escaped[6] = { '\\', 'u', '0', '0', 'x', 'x' }; CGI_PUTC('"'); while(1) { unsigned char c = begin[len]; /* flush on end of string and escape quotation mark, reverse solidus, * and the control characters (U+0000 through U+001F) */ if(c < ' ' || c == '"' || c== '\\') { if(len) /* flush */ CGI_PUTD(begin, len); begin = &begin[len+1]; len = 0; if(!c) { CGI_PUTC('"'); return; } escaped[4] = hex_digits[c >> 4]; escaped[5] = hex_digits[c & 0xf]; CGI_PUTD(escaped, 6); } else len++; }
void fcgi_send_file_meta(void) { const char *metakey; const void *metavalue; unsigned int created_at; sx_hash_t etag; int metasize; int comma = 0; rc_ty s; s = sx_hashfs_getfilemeta_begin(hashfs, volume, path, get_arg("rev"), &created_at, &etag); if(s != OK) quit_errnum(s == ENOENT ? 404 : 500); if(is_object_fresh(&etag, 'M', created_at)) return; CGI_PUTS("Content-type: application/json\r\n\r\n{\"fileMeta\":{"); while((s = sx_hashfs_getfilemeta_next(hashfs, &metakey, &metavalue, &metasize)) == OK) { char hexval[SXLIMIT_META_MAX_VALUE_LEN*2+1]; if(comma) CGI_PUTC(','); else comma |= 1; json_send_qstring(metakey); CGI_PUTS(":\""); bin2hex(metavalue, metasize, hexval, sizeof(hexval)); CGI_PUTS(hexval); CGI_PUTC('"'); } CGI_PUTS("}"); if (s != ITER_NO_MORE) quit_itererr("Failed to get file metadata", s); CGI_PUTS("}"); }
static int hash_presence_callback(const char *hexhash, unsigned int index, int code, void *context) { hash_presence_ctx_t *ctx = (hash_presence_ctx_t*)context; sx_hashfs_t *h = ctx->h; sx_nodelist_t *nodes; sx_hash_t hash; if (code != 200) { if (code < 0) WARN("Failed to query hash %.*s: %s", 40, hexhash, sx_hashfs_geterrmsg(h)); if (hex2bin(hexhash, SXI_SHA1_TEXT_LEN, hash.b, sizeof(hash.b))) { WARN("hex2bin failed on %.*s", 40, hexhash); return -1; } nodes = sx_hashfs_putfile_hashnodes(h, &hash); if (!nodes) { WARN("hashnodes failed"); return -1; } if(ctx->comma) CGI_PUTC(','); else ctx->comma |= 1; DEBUG("Requesting from user: #%.*s#", 40, hexhash); send_qstring_hash(&hash); CGI_PUTC(':'); /* Although there is no danger in doing so, nodes SHOULD NOT be randomized: * hdist already does a pretty good job here */ send_nodes(nodes); sx_nodelist_delete(nodes); } send_keepalive(); return 0; }
void fcgi_send_file(void) { sx_hashfs_file_t filedata; const sx_hash_t *hash; sx_nodelist_t *nodes; sx_hash_t etag; int comma = 0; rc_ty s = sx_hashfs_getfile_begin(hashfs, volume, path, get_arg("rev"), &filedata, &etag); if(s != OK) quit_errnum(s == ENOENT ? 404 : 500); if(is_object_fresh(&etag, 'F', filedata.created_at)) { sx_hashfs_getfile_end(hashfs); return; } CGI_PRINTF("Content-type: application/json\r\n\r\n{\"blockSize\":%d,\"fileSize\":", filedata.block_size); CGI_PUTLL(filedata.file_size); CGI_PRINTF(",\"createdAt\":%u,\"fileRevision\":\"%s\",\"fileData\":[", filedata.created_at, filedata.revision); while((s = sx_hashfs_getfile_block(hashfs, &hash, &nodes)) == OK) { if(comma) CGI_PUTC(','); else comma |= 1; CGI_PUTC('{'); send_qstring_hash(hash); CGI_PUTC(':'); /* Nodes are in NL_PREVNEXT order and MUST NOT be randomized * (see comments in sx_hashfs_getfile_block) */ send_nodes(nodes); CGI_PUTC('}'); sx_nodelist_delete(nodes); } sx_hashfs_getfile_end(hashfs); CGI_PUTS("]"); if(s != ITER_NO_MORE) quit_itererr("Failed to list file blocks", s); CGI_PUTS("}"); }
static void send_error_helper(const char sep, int errnum, const char *message) { sx_uuid_t node_uuid; CGI_PRINTF("%c\"ErrorMessage\":", sep); json_send_qstring(message ? message : ""); if (errnum == 500 || errnum == 400) { if (message) WARN("HTTP %d: %s", errnum, message); CGI_PUTS(",\"ErrorDetails\":"); json_send_qstring(msg_log_end()); } CGI_PUTS(",\"NodeId\":"); json_send_qstring(sx_hashfs_self_uuid(hashfs, &node_uuid)==OK ? node_uuid.string : "<UNKNOWN>"); CGI_PUTS(",\"ErrorId\":"); json_send_qstring(msg_get_id()); CGI_PUTC('}'); }
static void send_error_helper(const char sep, int errnum, const char *message) { CGI_PRINTF("%c\"ErrorMessage\":", sep); json_send_qstring(message); if (errnum == 500 || errnum == 400) { if (message) WARN("HTTP %d: %s", errnum, message); CGI_PUTS(",\"ErrorDetails\":"); json_send_qstring(msg_log_end()); } CGI_PUTS(",\"NodeId\":"); const sx_node_t *me = sx_hashfs_self(hashfs); json_send_qstring(me ? sx_node_uuid(me)->string : "<UNKNOWN>"); CGI_PUTS(",\"ErrorId\":"); json_send_qstring(msg_get_id()); CGI_PUTC('}'); }