Reduce HTTP code duplication.

This commit is contained in:
Steveice10 2016-12-22 17:40:30 -08:00
parent a5120e0981
commit d4d0aca13d
8 changed files with 179 additions and 196 deletions

View File

@ -291,9 +291,7 @@ static Result FSUSER_AddSeed(u64 titleId, const void* seed) {
return ret;
}
static u32 import_response_code = 0;
Result util_import_seed(u64 titleId) {
Result util_import_seed(u32* responseCode, u64 titleId) {
char pathBuf[64];
snprintf(pathBuf, 64, "/fbi/seed/%016llX.dat", titleId);
@ -324,17 +322,14 @@ Result util_import_seed(u64 titleId) {
snprintf(url, 128, "https://kagiya-ctr.cdn.nintendo.net/title/0x%016llX/ext_key?country=%s", titleId, regionStrings[region]);
httpcContext context;
if(R_SUCCEEDED(res = httpcOpenContext(&context, HTTPC_METHOD_GET, url, 1))) {
if(R_SUCCEEDED(res = httpcSetSSLOpt(&context, SSLCOPT_DisableVerify)) && R_SUCCEEDED(res = httpcBeginRequest(&context)) && R_SUCCEEDED(res = httpcGetResponseStatusCode(&context, &import_response_code))) {
if(import_response_code == 200) {
u32 bytesRead = 0;
res = httpcDownloadData(&context, seed, sizeof(seed), &bytesRead);
} else {
res = R_FBI_HTTP_RESPONSE_CODE;
}
}
if(R_SUCCEEDED(res = util_http_open(&context, responseCode, url, false))) {
u32 bytesRead = 0;
res = util_http_read(&context, &bytesRead, seed, sizeof(seed));
httpcCloseContext(&context);
Result closeRes = util_http_close(&context);
if(R_SUCCEEDED(res)) {
res = closeRes;
}
}
} else {
res = R_FBI_OUT_OF_RANGE;
@ -351,10 +346,6 @@ Result util_import_seed(u64 titleId) {
return res;
}
u32 util_get_seed_response_code() {
return import_response_code;
}
FS_MediaType util_get_title_destination(u64 titleId) {
u16 platform = (u16) ((titleId >> 48) & 0xFFFF);
u16 category = (u16) ((titleId >> 32) & 0xFFFF);
@ -647,4 +638,81 @@ void util_smdh_region_to_string(char* out, u32 region, size_t size) {
}
}
}
}
static char util_http_redirect_buffer[1024];
Result util_http_open(httpcContext* context, u32* responseCode, const char* url, bool userAgent) {
return util_http_open_ranged(context, responseCode, url, userAgent, 0, 0);
}
Result util_http_open_ranged(httpcContext* context, u32* responseCode, const char* url, bool userAgent, u32 rangeStart, u32 rangeEnd) {
if(context == NULL || url == NULL) {
return R_FBI_INVALID_ARGUMENT;
}
Result res = 0;
if(R_SUCCEEDED(res = httpcOpenContext(context, HTTPC_METHOD_GET, url, 1))) {
char agent[128];
snprintf(agent, sizeof(agent), "Mozilla/5.0 (Nintendo 3DS; Mobile; rv:10.0) Gecko/20100101 FBI/%d.%d.%d", VERSION_MAJOR, VERSION_MINOR, VERSION_MICRO);
char range[64];
if(rangeEnd > rangeStart) {
snprintf(range, sizeof(range), "%lu-%lu", rangeStart, rangeEnd);
} else {
snprintf(range, sizeof(range), "%lu-", rangeStart);
}
u32 response = 0;
if(R_SUCCEEDED(res = httpcSetSSLOpt(context, SSLCOPT_DisableVerify)) && (!userAgent || R_SUCCEEDED(res = httpcAddRequestHeaderField(context, "User-Agent", agent))) && (rangeStart == 0 || R_SUCCEEDED(res = httpcAddRequestHeaderField(context, "Range", range))) && R_SUCCEEDED(res = httpcSetKeepAlive(context, HTTPC_KEEPALIVE_ENABLED)) && R_SUCCEEDED(res = httpcBeginRequest(context)) && R_SUCCEEDED(res = httpcGetResponseStatusCode(context, &response))) {
if(response == 301 || response == 302 || response == 303) {
memset(util_http_redirect_buffer, '\0', sizeof(util_http_redirect_buffer));
if(R_SUCCEEDED(res = httpcGetResponseHeader(context, "Location", util_http_redirect_buffer, sizeof(util_http_redirect_buffer)))) {
httpcCloseContext(context);
return util_http_open_ranged(context, responseCode, util_http_redirect_buffer, userAgent, rangeStart, rangeEnd);
}
} else {
if(responseCode != NULL) {
*responseCode = response;
}
if(response != 200) {
res = R_FBI_HTTP_RESPONSE_CODE;
}
}
}
if(R_FAILED(res)) {
httpcCloseContext(context);
}
}
return res;
}
Result util_http_get_size(httpcContext* context, u32* size) {
if(context == NULL || size == NULL) {
return R_FBI_INVALID_ARGUMENT;
}
return httpcGetDownloadSizeState(context, NULL, size);
}
Result util_http_read(httpcContext* context, u32* bytesRead, void* buffer, u32 size) {
if(context == NULL || buffer == NULL) {
return R_FBI_INVALID_ARGUMENT;
}
Result res = httpcDownloadData(context, buffer, size, bytesRead);
return res != HTTPC_RESULTCODE_DOWNLOADPENDING ? res : 0;
}
Result util_http_close(httpcContext* context) {
if(context == NULL) {
return R_FBI_INVALID_ARGUMENT;
}
return httpcCloseContext(context);
}

View File

@ -55,8 +55,7 @@ void util_get_parent_path(char* out, const char* path, u32 size);
bool util_is_string_empty(const char* str);
Result util_import_seed(u64 titleId);
u32 util_get_seed_response_code();
Result util_import_seed(u32* responseCode, u64 titleId);
FS_MediaType util_get_title_destination(u64 titleId);
@ -84,4 +83,10 @@ const char* util_get_display_size_units(u64 size);
void util_escape_file_name(char* out, const char* in, size_t size);
void util_smdh_region_to_string(char* out, u32 region, size_t size);
void util_smdh_region_to_string(char* out, u32 region, size_t size);
Result util_http_open(httpcContext* context, u32* responseCode, const char* url, bool userAgent);
Result util_http_open_ranged(httpcContext* context, u32* responseCode, const char* url, bool userAgent, u32 rangeStart, u32 rangeEnd);
Result util_http_get_size(httpcContext* context, u32* size);
Result util_http_read(httpcContext* context, u32* bytesRead, void* buffer, u32 size);
Result util_http_close(httpcContext* context);

View File

@ -16,7 +16,8 @@
static void action_import_seed_update(ui_view* view, void* data, float* progress, char* text) {
title_info* info = (title_info*) data;
Result res = util_import_seed(info->titleId);
u32 responseCode = 0;
Result res = util_import_seed(&responseCode, info->titleId);
ui_pop();
info_destroy(view);
@ -24,7 +25,7 @@ static void action_import_seed_update(ui_view* view, void* data, float* progress
if(R_SUCCEEDED(res)) {
prompt_display("Success", "Seed imported.", COLOR_TEXT, false, info, ui_draw_title_info, NULL);
} else if(res == R_FBI_HTTP_RESPONSE_CODE) {
error_display(NULL, NULL, "Failed to import seed.\nHTTP server returned response code %d", util_get_seed_response_code());
error_display(NULL, NULL, "Failed to import seed.\nHTTP server returned response code %d", responseCode);
} else {
error_display_res(info, ui_draw_title_info, res, "Failed to import seed.");
}

View File

@ -59,21 +59,9 @@ static Result action_install_cdn_open_src(void* data, u32 index, u32* handle) {
snprintf(url, 256, "http://ccs.cdn.c.shop.nintendowifi.net/ccs/download/%016llX/%08lX", installData->ticket->titleId, installData->contentIds[index - 1]);
}
if(R_SUCCEEDED(res = httpcOpenContext(context, HTTPC_METHOD_GET, url, 1))) {
if(R_SUCCEEDED(res = httpcSetSSLOpt(context, SSLCOPT_DisableVerify)) && R_SUCCEEDED(res = httpcBeginRequest(context)) && R_SUCCEEDED(res = httpcGetResponseStatusCode(context, &installData->responseCode))) {
if(installData->responseCode == 200) {
*handle = (u32) context;
} else {
res = R_FBI_HTTP_RESPONSE_CODE;
}
}
if(R_FAILED(res)) {
httpcCloseContext(context);
}
}
if(R_FAILED(res)) {
if(R_SUCCEEDED(res = util_http_open(context, &installData->responseCode, url, false))) {
*handle = (u32) context;
} else {
free(context);
}
} else {
@ -84,20 +72,19 @@ static Result action_install_cdn_open_src(void* data, u32 index, u32* handle) {
}
static Result action_install_cdn_close_src(void* data, u32 index, bool succeeded, u32 handle) {
return httpcCloseContext((httpcContext*) handle);
return util_http_close((httpcContext*) handle);
}
static Result action_install_cdn_get_src_size(void* data, u32 handle, u64* size) {
u32 downloadSize = 0;
Result res = httpcGetDownloadSizeState((httpcContext*) handle, NULL, &downloadSize);
Result res = util_http_get_size((httpcContext*) handle, &downloadSize);
*size = downloadSize;
return res;
}
static Result action_install_cdn_read_src(void* data, u32 handle, u32* bytesRead, void* buffer, u64 offset, u32 size) {
Result res = httpcDownloadData((httpcContext*) handle, buffer, size, bytesRead);
return res != HTTPC_RESULTCODE_DOWNLOADPENDING ? res : 0;
return util_http_read((httpcContext*) handle, bytesRead, buffer, size);
}
static Result action_install_cdn_open_dst(void* data, u32 index, void* initialReadBlock, u64 size, u32* handle) {
@ -222,7 +209,7 @@ static void action_install_cdn_update(ui_view* view, void* data, float* progress
if(R_SUCCEEDED(installData->installInfo.result)) {
if(R_SUCCEEDED(res = AM_InstallTitleFinish())
&& R_SUCCEEDED(res = AM_CommitImportTitles(util_get_title_destination(installData->ticket->titleId), 1, false, &installData->ticket->titleId))) {
util_import_seed(installData->ticket->titleId);
util_import_seed(NULL, installData->ticket->titleId);
if(installData->ticket->titleId == 0x0004013800000002 || installData->ticket->titleId == 0x0004013820000002) {
res = AM_InstallFirm(installData->ticket->titleId);

View File

@ -160,7 +160,7 @@ static Result action_install_cias_close_dst(void* data, u32 index, bool succeede
Result res = 0;
if(R_SUCCEEDED(res = AM_FinishCiaInstall(handle))) {
util_import_seed(installData->currTitleId);
util_import_seed(NULL, installData->currTitleId);
if(installData->currTitleId == 0x0004013800000002 || installData->currTitleId == 0x0004013820000002) {
res = AM_InstallFirm(installData->currTitleId);

View File

@ -58,32 +58,9 @@ static Result action_url_install_open_src(void* data, u32 index, u32* handle) {
httpcContext* context = (httpcContext*) calloc(1, sizeof(httpcContext));
if(context != NULL) {
if(R_SUCCEEDED(res = httpcOpenContext(context, HTTPC_METHOD_GET, installData->urls[index], 1))) {
char userAgent[128];
snprintf(userAgent, sizeof(userAgent), "Mozilla/5.0 (Nintendo 3DS; Mobile; rv:10.0) Gecko/20100101 FBI/%d.%d.%d", VERSION_MAJOR, VERSION_MINOR, VERSION_MICRO);
if(R_SUCCEEDED(res = httpcSetSSLOpt(context, SSLCOPT_DisableVerify)) && R_SUCCEEDED(res = httpcAddRequestHeaderField(context, "User-Agent", userAgent)) && R_SUCCEEDED(res = httpcBeginRequest(context)) && R_SUCCEEDED(res = httpcGetResponseStatusCode(context, &installData->responseCode))) {
if(installData->responseCode == 200) {
*handle = (u32) context;
} else if(installData->responseCode == 301 || installData->responseCode == 302 || installData->responseCode == 303) {
memset(installData->urls[index], '\0', URL_MAX);
if(R_SUCCEEDED(res = httpcGetResponseHeader(context, "Location", installData->urls[index], URL_MAX))) {
httpcCloseContext(context);
free(context);
return action_url_install_open_src(data, index, handle);
}
} else {
res = R_FBI_HTTP_RESPONSE_CODE;
}
}
if(R_FAILED(res)) {
httpcCloseContext(context);
}
}
if(R_FAILED(res)) {
if(R_SUCCEEDED(res = util_http_open(context, &installData->responseCode, installData->urls[index], true))) {
*handle = (u32) context;
} else {
free(context);
}
} else {
@ -94,20 +71,19 @@ static Result action_url_install_open_src(void* data, u32 index, u32* handle) {
}
static Result action_url_install_close_src(void* data, u32 index, bool succeeded, u32 handle) {
return httpcCloseContext((httpcContext*) handle);
return util_http_close((httpcContext*) handle);
}
static Result action_url_install_get_src_size(void* data, u32 handle, u64* size) {
u32 downloadSize = 0;
Result res = httpcGetDownloadSizeState((httpcContext*) handle, NULL, &downloadSize);
Result res = util_http_get_size((httpcContext*) handle, &downloadSize);
*size = downloadSize;
return res;
}
static Result action_url_install_read_src(void* data, u32 handle, u32* bytesRead, void* buffer, u64 offset, u32 size) {
Result res = httpcDownloadData((httpcContext*) handle, buffer, size, bytesRead);
return res != HTTPC_RESULTCODE_DOWNLOADPENDING ? res : 0;
return util_http_read((httpcContext*) handle, bytesRead, buffer, size);
}
static Result action_url_install_open_dst(void* data, u32 index, void* initialReadBlock, u64 size, u32* handle) {
@ -190,7 +166,7 @@ static Result action_url_install_close_dst(void* data, u32 index, bool succeeded
}
} else {
if(R_SUCCEEDED(res = AM_FinishCiaInstall(handle))) {
util_import_seed(installData->currTitleId);
util_import_seed(NULL, installData->currTitleId);
if(installData->currTitleId == 0x0004013800000002 || installData->currTitleId == 0x0004013820000002) {
res = AM_InstallFirm(installData->currTitleId);

View File

@ -17,39 +17,14 @@
static Result task_populate_titledb_download(u32* downloadSize, void* buffer, u32 maxSize, const char* url) {
Result res = 0;
if(downloadSize != NULL) {
*downloadSize = 0;
}
httpcContext context;
if(R_SUCCEEDED(res = httpcOpenContext(&context, HTTPC_METHOD_GET, url, 1))) {
char userAgent[128];
snprintf(userAgent, sizeof(userAgent), "Mozilla/5.0 (Nintendo 3DS; Mobile; rv:10.0) Gecko/20100101 FBI/%d.%d.%d", VERSION_MAJOR, VERSION_MINOR, VERSION_MICRO);
if(R_SUCCEEDED(res = util_http_open(&context, NULL, url, true))) {
res = util_http_read(&context, downloadSize, buffer, maxSize);
u32 responseCode = 0;
if(R_SUCCEEDED(res = httpcSetSSLOpt(&context, SSLCOPT_DisableVerify))
&& R_SUCCEEDED(res = httpcAddRequestHeaderField(&context, "User-Agent", userAgent))
&& R_SUCCEEDED(res = httpcAddRequestHeaderField(&context, "Connection", "Keep-Alive"))
&& R_SUCCEEDED(res = httpcBeginRequest(&context))
&& R_SUCCEEDED(res = httpcGetResponseStatusCode(&context, &responseCode))) {
if(responseCode == 200) {
u32 size = 0;
u32 bytesRead = 0;
while(size < maxSize && (res = httpcDownloadData(&context, &((u8*) buffer)[size], maxSize - size < 0x1000 ? maxSize - size : 0x1000, &bytesRead)) == HTTPC_RESULTCODE_DOWNLOADPENDING) {
size += bytesRead;
}
size += bytesRead;
if(R_SUCCEEDED(res) && downloadSize != NULL) {
*downloadSize = size;
}
} else {
res = R_FBI_HTTP_RESPONSE_CODE;
}
Result closeRes = util_http_close(&context);
if(R_SUCCEEDED(res)) {
res = closeRes;
}
httpcCloseContext(&context);
}
return res;

View File

@ -39,28 +39,9 @@ static Result update_open_src(void* data, u32 index, u32* handle) {
httpcContext* context = (httpcContext*) calloc(1, sizeof(httpcContext));
if(context != NULL) {
if(R_SUCCEEDED(res = httpcOpenContext(context, HTTPC_METHOD_GET, updateData->url, 1))) {
if(R_SUCCEEDED(res = httpcSetSSLOpt(context, SSLCOPT_DisableVerify)) && R_SUCCEEDED(res = httpcBeginRequest(context)) && R_SUCCEEDED(res = httpcGetResponseStatusCode(context, &updateData->responseCode))) {
if(updateData->responseCode == 200) {
*handle = (u32) context;
} else if(updateData->responseCode == 301 || updateData->responseCode == 302 || updateData->responseCode == 303) {
if(R_SUCCEEDED(res = httpcGetResponseHeader(context, "Location", updateData->url, URL_MAX))) {
httpcCloseContext(context);
free(context);
return update_open_src(data, index, handle);
}
} else {
res = R_FBI_HTTP_RESPONSE_CODE;
}
}
if(R_FAILED(res)) {
httpcCloseContext(context);
}
}
if(R_FAILED(res)) {
if(R_SUCCEEDED(res = util_http_open(context, &updateData->responseCode, updateData->url, true))) {
*handle = (u32) context;
} else {
free(context);
}
} else {
@ -71,20 +52,19 @@ static Result update_open_src(void* data, u32 index, u32* handle) {
}
static Result update_close_src(void* data, u32 index, bool succeeded, u32 handle) {
return httpcCloseContext((httpcContext*) handle);
return util_http_close((httpcContext*) handle);
}
static Result update_get_src_size(void* data, u32 handle, u64* size) {
u32 downloadSize = 0;
Result res = httpcGetDownloadSizeState((httpcContext*) handle, NULL, &downloadSize);
Result res = util_http_get_size((httpcContext*) handle, &downloadSize);
*size = downloadSize;
return res;
}
static Result update_read_src(void* data, u32 handle, u32* bytesRead, void* buffer, u64 offset, u32 size) {
Result res = httpcDownloadData((httpcContext*) handle, buffer, size, bytesRead);
return res != HTTPC_RESULTCODE_DOWNLOADPENDING ? res : 0;
return util_http_read((httpcContext*) handle, bytesRead, buffer, size);
}
static Result update_open_dst(void* data, u32 index, void* initialReadBlock, u64 size, u32* handle) {
@ -183,96 +163,87 @@ static void update_check_update(ui_view* view, void* data, float* progress, char
u32 responseCode = 0;
httpcContext context;
if(R_SUCCEEDED(res = httpcOpenContext(&context, HTTPC_METHOD_GET, "https://api.github.com/repos/Steveice10/FBI/releases/latest", 1))) {
char userAgent[128];
snprintf(userAgent, sizeof(userAgent), "Mozilla/5.0 (Nintendo 3DS; Mobile; rv:10.0) Gecko/20100101 FBI/%d.%d.%d", VERSION_MAJOR, VERSION_MINOR, VERSION_MICRO);
if(R_SUCCEEDED(res = util_http_open(&context, &responseCode, "https://api.github.com/repos/Steveice10/FBI/releases/latest", true))) {
u32 size = 0;
if(R_SUCCEEDED(res = util_http_get_size(&context, &size))) {
char* jsonText = (char*) calloc(sizeof(char), size);
if(jsonText != NULL) {
u32 bytesRead = 0;
if(R_SUCCEEDED(res = util_http_read(&context, &bytesRead, (u8*) jsonText, size))) {
json_value* json = json_parse(jsonText, size);
if(json != NULL) {
if(json->type == json_object) {
json_value* name = NULL;
json_value* assets = NULL;
if(R_SUCCEEDED(res = httpcSetSSLOpt(&context, SSLCOPT_DisableVerify))
&& R_SUCCEEDED(res = httpcAddRequestHeaderField(&context, "User-Agent", userAgent))
&& R_SUCCEEDED(res = httpcBeginRequest(&context))
&& R_SUCCEEDED(res = httpcGetResponseStatusCode(&context, &responseCode))) {
if(responseCode == 200) {
u32 size = 0;
if(R_SUCCEEDED(res = httpcGetDownloadSizeState(&context, NULL, &size))) {
char* jsonText = (char*) calloc(sizeof(char), size);
if(jsonText != NULL) {
u32 bytesRead = 0;
if(R_SUCCEEDED(res = httpcDownloadData(&context, (u8*) jsonText, size, &bytesRead))) {
json_value* json = json_parse(jsonText, size);
if(json != NULL) {
if(json->type == json_object) {
json_value* name = NULL;
json_value* assets = NULL;
for(u32 i = 0; i < json->u.object.length; i++) {
json_value* val = json->u.object.values[i].value;
if(strncmp(json->u.object.values[i].name, "name", json->u.object.values[i].name_length) == 0 && val->type == json_string) {
name = val;
} else if(strncmp(json->u.object.values[i].name, "assets", json->u.object.values[i].name_length) == 0 && val->type == json_array) {
assets = val;
}
}
for(u32 i = 0; i < json->u.object.length; i++) {
json_value* val = json->u.object.values[i].value;
if(strncmp(json->u.object.values[i].name, "name", json->u.object.values[i].name_length) == 0 && val->type == json_string) {
name = val;
} else if(strncmp(json->u.object.values[i].name, "assets", json->u.object.values[i].name_length) == 0 && val->type == json_array) {
assets = val;
}
}
if(name != NULL && assets != NULL) {
char versionString[16];
snprintf(versionString, sizeof(versionString), "%d.%d.%d", VERSION_MAJOR, VERSION_MINOR, VERSION_MICRO);
if(name != NULL && assets != NULL) {
char versionString[16];
snprintf(versionString, sizeof(versionString), "%d.%d.%d", VERSION_MAJOR, VERSION_MINOR, VERSION_MICRO);
if(strncmp(name->u.string.ptr, versionString, name->u.string.length) != 0) {
char* url = NULL;
if(strncmp(name->u.string.ptr, versionString, name->u.string.length) != 0) {
char* url = NULL;
for(u32 i = 0; i < assets->u.array.length; i++) {
json_value* val = assets->u.array.values[i];
if(val->type == json_object) {
json_value* assetName = NULL;
json_value* assetUrl = NULL;
for(u32 i = 0; i < assets->u.array.length; i++) {
json_value* val = assets->u.array.values[i];
if(val->type == json_object) {
json_value* assetName = NULL;
json_value* assetUrl = NULL;
for(u32 j = 0; j < val->u.object.length; j++) {
json_value* subVal = val->u.object.values[j].value;
if(strncmp(val->u.object.values[j].name, "name", val->u.object.values[j].name_length) == 0 && subVal->type == json_string) {
assetName = subVal;
} else if(strncmp(val->u.object.values[j].name, "browser_download_url", val->u.object.values[j].name_length) == 0 && subVal->type == json_string) {
assetUrl = subVal;
}
}
if(assetName != NULL && assetUrl != NULL) {
if(strncmp(assetName->u.string.ptr, util_get_3dsx_path() != NULL ? "FBI.3dsx" : "FBI.cia", assetName->u.string.length) == 0) {
url = assetUrl->u.string.ptr;
break;
}
}
for(u32 j = 0; j < val->u.object.length; j++) {
json_value* subVal = val->u.object.values[j].value;
if(strncmp(val->u.object.values[j].name, "name", val->u.object.values[j].name_length) == 0 && subVal->type == json_string) {
assetName = subVal;
} else if(strncmp(val->u.object.values[j].name, "browser_download_url", val->u.object.values[j].name_length) == 0 && subVal->type == json_string) {
assetUrl = subVal;
}
}
if(url != NULL) {
strncpy(updateData->url, url, URL_MAX);
hasUpdate = true;
} else {
res = R_FBI_BAD_DATA;
if(assetName != NULL && assetUrl != NULL) {
if(strncmp(assetName->u.string.ptr, util_get_3dsx_path() != NULL ? "FBI.3dsx" : "FBI.cia", assetName->u.string.length) == 0) {
url = assetUrl->u.string.ptr;
break;
}
}
}
}
if(url != NULL) {
strncpy(updateData->url, url, URL_MAX);
hasUpdate = true;
} else {
res = R_FBI_BAD_DATA;
}
} else {
res = R_FBI_BAD_DATA;
}
} else {
res = R_FBI_PARSE_FAILED;
res = R_FBI_BAD_DATA;
}
} else {
res = R_FBI_BAD_DATA;
}
free(jsonText);
} else {
res = R_FBI_OUT_OF_MEMORY;
res = R_FBI_PARSE_FAILED;
}
}
free(jsonText);
} else {
res = R_FBI_HTTP_RESPONSE_CODE;
res = R_FBI_OUT_OF_MEMORY;
}
}
httpcCloseContext(&context);
Result closeRes = util_http_close(&context);
if(R_SUCCEEDED(res)) {
res = closeRes;
}
}
ui_pop();