static int download_file(char *url, char *file, int mode, u64 *size) { int flags = 0; int ret = 0; void *http_p = NULL; void *uri_p = NULL; httpUri uri; s32 transID = 0; s32 clientID; int pool_size = 0; int recv = -1; u64 length = 0; int code = 0; FILE *fp = NULL; float parts = 0; float cpart; char buffer[16384]; use_async_fd = 128; my_f_async.flags = 0; if(mode == 2) { if(size) sprintf(temp_buffer + 4096, "File Size: %u MB\n%s", (u32) (*size/0x100000ULL), strrchr(file, '/') + 1); else sprintf(temp_buffer + 4096, "File: %s", strrchr(file, '/') + 1); single_bar(temp_buffer + 4096); } http_p = malloc(0x10000); if(!http_p) {ret= -1; goto err;} ret = httpInit(http_p, 0x10000); if(ret < 0) goto err; flags|= 1; ret = httpCreateClient(&clientID); if(ret < 0) goto err; flags|= 2; httpClientSetConnTimeout(clientID, 10000000); ret = httpUtilParseUri(NULL, url, NULL, 0, &pool_size); if (ret < 0) goto err; uri_p = malloc(pool_size); if (!uri_p) goto err; ret = httpUtilParseUri(&uri, url, uri_p, pool_size, NULL); if (ret < 0) goto err; ret = httpCreateTransaction(&transID, clientID, HTTP_METHOD_GET, &uri); if (ret < 0) goto err; free(uri_p); uri_p = NULL; ret = httpSendRequest(transID, NULL, 0, NULL); if (ret < 0) goto err; ret = httpResponseGetStatusCode(transID, &code); if (ret < 0) goto err; if (code == 404 || code == 403) {ret=-4; goto err;} ret = httpResponseGetContentLength(transID, &length); if (ret < 0) { if (ret == HTTP_STATUS_CODE_No_Content) { length = 0ULL; ret = 0; } else goto err; } if(size) *size = length; if(mode == 1) goto err; // get only the size if(mode == 2) { parts = (length == 0) ? 0.0f : 100.0f / ((double) length / (double) sizeof(buffer)); cpart = 0; } fp = fopen(file, "wb"); if(!fp) goto err; int acum = 0; while (recv != 0 && length != 0ULL) { memset(buffer, 0x0, sizeof(buffer)); if (httpRecvResponse(transID, buffer, sizeof(buffer) - 1, &recv) < 0) {fclose(fp); ret = -5; goto err;} if (recv == 0) break; if (recv > 0) { //if(fwrite(buffer, 1, recv, fp) != recv) {fclose(fp); fp = NULL; ret = -6; goto err;} /////////////////// loop_write: if(use_async_fd == 128) { use_async_fd = 1; my_f_async.flags = 0; my_f_async.size = recv; my_f_async.fp = fp; my_f_async.mem = malloc(recv); if(my_f_async.mem) memcpy(my_f_async.mem, (void *) buffer, recv); my_f_async.ret = -1; my_f_async.flags = ASYNC_ENABLE; event_thread_send(0x555ULL, (u64) my_func_async, (u64) &my_f_async); } else { if(!(my_f_async.flags & ASYNC_ENABLE)) { if(my_f_async.flags & ASYNC_ERROR) { fclose(fp); fp = NULL; ret = -6; goto err; } my_f_async.flags = 0; my_f_async.size = recv; my_f_async.fp = fp; my_f_async.mem = malloc(recv); if(my_f_async.mem) memcpy(my_f_async.mem, (void *) buffer, recv); my_f_async.ret = -1; my_f_async.flags = ASYNC_ENABLE; event_thread_send(0x555ULL, (u64) my_func_async, (u64) &my_f_async); } else { goto loop_write; } } /////////////////// length -= recv; acum+= recv; } if(mode == 2 && progress_action == 2) {ret = -0x555; goto err;} pad_last_time = 0; if(mode == 2) { if(acum >= sizeof(buffer)) { acum-= sizeof(buffer); cpart += parts; if(cpart >= 1.0f) { update_bar((u32) cpart); cpart-= (float) ((u32) cpart); } } } } ret = 0; err: if(my_f_async.flags & ASYNC_ENABLE){ wait_event_thread(); if(my_f_async.flags & ASYNC_ERROR) { if(fp) fclose(fp); fp = NULL; ret = -6; } my_f_async.flags = 0; } event_thread_send(0x555ULL, (u64) 0, 0); if(mode == 2) { msgDialogAbort(); } if(fp) { fclose(fp); if(ret < 0) unlink_secure(file); } if(transID) httpDestroyTransaction(transID); if(flags & 2) httpDestroyClient(clientID); if(flags & 1) httpEnd(); if(http_p) free(http_p); if(uri_p) free(uri_p); return ret; }
int main(int _argc, const char* _argv[]) { bnet::init(1, 0, s_cert); // const char* url = "http://gravatar.com/avatar/cc47d6856403a62afc5c74d269b7e610.png"; const char* url = "https://encrypted.google.com/"; char* tokens[UrlToken::Count]; char temp[1024]; tokenizeUrl(url, temp, sizeof(temp), tokens); bool secure = false; uint16_t port = 0; if (0 == _stricmp(tokens[UrlToken::Scheme], "http") ) { port = 80; } else if (0 == _stricmp(tokens[UrlToken::Scheme], "https") ) { port = 443; secure = true; } if (0 != port) { uint32_t ip = bnet::toIpv4(tokens[UrlToken::Host]); if ('\0' != tokens[UrlToken::Port][0]) { port = atoi(tokens[UrlToken::Port]); } char header[1024]; snprintf(header , sizeof(header) , "GET /%s HTTP/1.0\r\nHost: %s\r\n\r\n" , tokens[UrlToken::Path] , tokens[UrlToken::Host] ); uint16_t handle = httpSendRequest(ip, port, header, secure); uint32_t size = 0; uint8_t* data = NULL; bool cont = bnet::invalidHandle != handle; if (cont) { printf("Connecting to %s (%d.%d.%d.%d:%d)\n" , url , ip>>24 , (ip>>16)&0xff , (ip>>8)&0xff , ip&0xff , port ); } while (cont) { bnet::Message* msg = bnet::recv(); if (NULL != msg) { if (bnet::MessageId::UserDefined > msg->data[0]) { switch (msg->data[0]) { case bnet::MessageId::Notify: printf("notify!\n"); break; case bnet::MessageId::LostConnection: case bnet::MessageId::ConnectFailed: cont = false; if (NULL != data) { FILE* file = fopen("http.txt", "wb"); fwrite(data, 1, size, file); fclose(file); printf("Received total %d. Data saved into http.txt.\n", size); } break; case bnet::MessageId::RawData: { printf("# raw %d bytes.\n", msg->size); uint32_t pos = size; size += msg->size-1; data = (uint8_t*)realloc(data, size+1); memcpy(&data[pos], &msg->data[1], msg->size-1); data[size-1] = '\0'; } break; } } bnet::release(msg); } } }