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('}'); }
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 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('}'); }
static void create_or_extend_tempfile(const sx_hashfs_volume_t *vol, const char *filename, int extending) { const struct jparse_actions acts = { JPACTS_INT64( JPACT(cb_newfile_size, JPKEY("fileSize")), JPACT(cb_newfile_seq, JPKEY("extendSeq")) ), JPACTS_STRING( JPACT(cb_newfile_block, JPKEY("fileData"), JPANYITM), JPACT(cb_newfile_addmeta, JPKEY("fileMeta"), JPANYKEY) ), JPACTS_NULL( JPACT(cb_newfile_delmeta, JPKEY("fileMeta"), JPANYKEY) ) }; struct cb_newfile_ctx yctx; hash_presence_ctx_t ctx; const char *token; jparse_t *J; int len; rc_ty s; yctx.filesize = -1; yctx.seq = -1; yctx.rc = EINVAL; J = sxi_jparse_create(&acts, &yctx, 0); if(!J) { sx_hashfs_putfile_end(hashfs); quit_errmsg(503, "Cannot create JSON parser"); } while((len = get_body_chunk(hashbuf, sizeof(hashbuf))) > 0) if(sxi_jparse_digest(J, hashbuf, len)) break; if(len || sxi_jparse_done(J)) { send_error(rc2http(yctx.rc), sxi_jparse_geterr(J)); sx_hashfs_putfile_end(hashfs); sxi_jparse_destroy(J); return; } sxi_jparse_destroy(J); auth_complete(); quit_unless_authed(); s = sx_hashfs_putfile_gettoken(hashfs, user, yctx.filesize, yctx.seq, &token, hash_presence_callback, &ctx); if (s != OK) { sx_hashfs_putfile_end(hashfs); if(!*msg_get_reason()) msg_set_reason("Cannot obtain upload token: %s", rc2str(s)); quit_errmsg((s == ENOSPC) ? 413 : rc2http(s), msg_get_reason()); } CGI_PRINTF("Content-type: application/json\r\n\r\n{\"uploadToken\":"); json_send_qstring(extending ? path : token); CGI_PUTS(",\"uploadData\":{"); ctx.h = hashfs; ctx.comma = 0; while((s = sx_hashfs_putfile_getblock(hashfs)) == OK) { /* Nothing to do here, API does a little bit of work at a time by design * We can stick keepalives in here if we ever need to */ } sx_hashfs_putfile_end(hashfs); CGI_PUTS("}"); if(s != ITER_NO_MORE) { quit_itererr("Failed to send file blocks", s); } CGI_PUTS("}"); }