Homebrew Using HTTPC - Not working?

  • Thread starter Thread starter JackMacWindows
  • Start date Start date
  • Views Views 1,491
  • Replies Replies 1
  • Likes Likes 1

JackMacWindows

Well-Known Member
Newcomer
Joined
Jan 16, 2016
Messages
54
Reaction score
46
Trophies
0
XP
295
Country
United States
Hello,
I am creating a program that connects to the internet to download files. I am trying to download a file from the program, but httpcInit() returns -522183694 and httpcOpenContext() returns -656406537. I am connected to the Internet when I run the program. Here is my code:
Code:
//
//  main.cpp
//  Homebrew Manager
//
//  Created by JackMacWindows on 1/15/16.
//  Copyright © 2016 MCJack123. All rights reserved.
//

#include "utils.h"
#include "parser.h"
#include "execute.h"

Result ret = 0;
u8 *packagesF;
httpcContext context;
char *url = "http://raw.githubusercontent.com/MCJack123/HBM-repo/master/Packages";

//from utils.h
u8 * http_download(httpcContext *context) { //This error handling needs updated with proper text printing once ctrulib itself supports that.
    Result ret = 0;
    u32 statuscode = 0;
    u32 contentsize = 0;
    u8 *buf;
    ret = httpcBeginRequest(context);
    if (ret != 0) {debugPrint("\x1b[31mFailed to connect: request denied\x1b[37m"); return (u8*)"";}
    ret = httpcGetResponseStatusCode(context, &statuscode);
    if (ret != 0) {debugPrint("\x1b[31mFailed to connect: could not get status code\x1b[37m"); return (u8*)"";}
    if (statuscode != 200) {
#ifdef __DEBUG
        printf("\x1b[31mError: Failed to connect: Bad status code (%lu %s)\x1b[37m\n", statuscode, httpResponses[statuscode]);
#endif
        return (u8*)"";
    }
    ret=httpcGetDownloadSizeState(context, NULL, &contentsize);
    if (ret != 0) {debugPrint("\x1b[31mFailed to connect: could not get size\x1b[37m"); return (u8*)"";}
    gfxFlushBuffers();
    buf = (u8*)malloc(contentsize);
    if (buf == NULL) {debugPrint("\x1b[31mError: could not allocate memory\x1b[37m"); return (u8*)"";}
    memset(buf, 0, contentsize);
    ret = httpcDownloadData(context, buf, contentsize, NULL);
    if (ret != 0) {
        debugPrint("\x1b[31mFailed to connect: failed to download file\x1b[37m");
        free(buf);
        return (u8*)"";
    }
    return buf;
}
//done

int main(int argc, char* argv[]) {
    gfxInitDefault();
    //Initialize console on top screen. Using NULL as the second argument tells the console library to use the internal console structure as current one
    consoleInit(GFX_TOP, &screen);
    consoleInit(GFX_BOTTOM,&debug);
    consoleSelect(&screen);
    APT_CheckNew3DS(&consoletype);
    printf("Console type: %s\n",consoletype?"New 3DS. Good job!":"Old 3DS. This may be a bit slow.");
    debugPrint("Downloading packages file");
    consoleSelect(&debug);
    printf("%li ", httpcInit(256)); //httpcInit() returns -522183694
    ret = httpcOpenContext(&context, HTTPC_METHOD_GET, url, 1); //returns -656406537
    printf("%li", ret);
    consoleSelect(&screen);
    if (ret == 0) {
        debugPrint("Starting download");
        packagesF = http_download(&context);
        debugPrint((const char*)packagesF);
        parsePackagesFile(std::string((char*)packagesF));
        httpcCloseContext(&context);
        debugPrint("Done.");
    } else printf("\x1b[31mError: Failed to connect\x1b[37m\n");
    int selection = 0;
    consoleSelect(&screen);
    while (aptMainLoop()) {
        consoleClear();
        printf("Homebrew Manager for 3DS by JackMacWindows\nPlease select an option:\n\n %s Install official package\n %s Add/install unofficial repository\n %s Download other zip file", selection==0?"*":" ", selection==1?"*":" ", selection==2?"*":" ");
        hidScanInput();
        u32 kDown = hidKeysDown();
        if (kDown) {
            if (kDown & KEY_DOWN) selection = incIntWithMax(selection, 2);
            else if (kDown & KEY_UP) selection = decIntWithMax(selection, 2);
            else if (kDown & KEY_A) {
                consoleClear();
                printf("\n\nSelected option: ");
                runManager(selection);
            }
            else if (kDown & KEY_START) goto End;
        }
        gfxFlushBuffers();
        gfxSwapBuffers();
        //Wait for VBlank
        gspWaitForVBlank();
        sleep(.075);
    }
End:
    // Exit services
    httpcExit();
    gfxExit();
    return 0;
}
What is wrong with my program? If you need anything else, just ask me.
 
Last edited by JackMacWindows,
  • Like
Reactions: Quantumcat
Ok, I fixed it by using another download function. I now have a new problem: when downloading a ZIP file, it stops on the first "0x00" character or NULL character, and returns without continuing past that character. Here is the code for the download:
Code:
bool httpGet(const char* url, u8** buf, u32* size, const bool verbose) {
    httpcContext context;
    if (!CHECK(httpcOpenContext(&context, HTTPC_METHOD_GET, (char*)url, 0), "Could not open HTTP context")) return false;
    // Add User Agent field (required by Github API calls)
    if (!CHECK(httpcAddRequestHeaderField(&context, (char*)"User-Agent", (char*)"Mozilla/5.0 (Nintendo 3DS; U; ; en) Version/1.7498.US"), "Could not set User Agent")) return false;

    // Add root CA required for Github and AWS URLs
    CHECK(httpcAddTrustedRootCA(&context, cybertrust_cer, cybertrust_cer_len), "Could not add Cybertrust root CA");
    CHECK(httpcAddTrustedRootCA(&context, digicert_cer, digicert_cer_len), "Could not add Digicert root CA");

    if (!CHECK(httpcBeginRequest(&context), "Could not begin request")) return false;

    u32 statuscode = 0;
    if (!CHECK(httpcGetResponseStatusCode(&context, &statuscode), "Could not get status code")) return false;
    if (statuscode != 200) {
        // Handle 3xx codes
        if (statuscode >= 300 && statuscode < 400) {
            char newUrl[1024];
            if (!CHECK(httpcGetResponseHeader(&context, (char*)"Location", newUrl, 1024), "Could not get Location header for 3xx reply")) return false;
            if (!CHECK(httpcCloseContext(&context), "Could not close HTTP context")) return false;
            return httpGet(newUrl, buf, size, verbose);
        }
        debugPrint(formatErrMessage(std::string("Non-200 status code: " + std::string(httpResponses[statuscode])).c_str(), statuscode).c_str());
        return false;
    }

    u32 pos = 0;
    u32 dlstartpos = 0;
    u32 dlpos = 0;
    Result dlret = HTTPC_RESULTCODE_DOWNLOADPENDING;

    if (!CHECK(httpcGetDownloadSizeState(&context, &dlstartpos, size), "Could not get file size")) return false;
   
    *buf = (u8*)std::malloc(*size);
    if (*buf == NULL) {debugPrint(formatErrMessage("Could not allocate enough memory", *size).c_str()); return false;}
    std::memset(*buf, 0, *size);
    printf("%lu ", *size);
    while (pos < *size && dlret == (s32)HTTPC_RESULTCODE_DOWNLOADPENDING)
    {
        u32 sz = *size - pos;
        printf("%lu %lu ", sz, pos);
        dlret = httpcReceiveData(&context, *buf + pos, sz);
        if (!CHECK(httpcGetDownloadSizeState(&context, &dlpos, NULL), "Could not get file size")) return false;
        pos = dlpos - dlstartpos;
        printf("%lu %lu %lu ", dlpos, sz, pos);
        if (verbose) {
            consoleSelect(&debug);
            consoleClear();
            printf("Download progress: %lu / %lu", dlpos, *size);
            gfxFlushBuffers();
        }
    }
   
    if (verbose) {
        printf("\n");
    }

    if (!CHECK(httpcCloseContext(&context), "Could not close HTTP context")) return false;
    return true;
}
The ZIP file I am reading is http://raw.githubusercontent.com/MCJack123/HBM-repo/master/files/sample.hbp .
 

Site & Scene News

Popular threads in this forum