SOAP_INT32 SOAP_ActionInit ( SOAPAction* action, HTTPManagedClient* httpClient, SOAP_INT16 ipType, const SOAP_CHAR* destUri, const SOAP_CHAR* soapAction, SOAP_CHAR* headerStr, SOAP_INT32 headerLen, SOAP_CHAR* bodyStr, SOAP_INT32 bodyLen, SOAPActionCallback callbackFn, void* callbackData ) { action->state = SOAP_ACTION_CONNECTING_POST; action->httpClient = httpClient; action->headerStr = headerStr; action->headerLen = headerLen; action->bodyStr = bodyStr; action->bodyLen = bodyLen; action->callbackFn = callbackFn; action->callbackData = callbackData; rtp_strncpy(action->soapAction, soapAction, SOAP_ACTION_MAX_LEN-1); action->soapAction[SOAP_ACTION_MAX_LEN-1] = 0; if (URL_Parse(&action->postTargetURL, destUri, URL_PROTOCOL_HTTP, ipType) >= 0) { if (SOAP_CreateHttpSession(action) >= 0) { return (0); } URL_Free(&action->postTargetURL); } return (-1); }
def(void, Get, String prefix, ListingItem *item, String url) { this->location.len = 0; HTTP_Client client; URL_Parts parts = URL_Parse(url); HTTP_Client_Init(&client, parts.host); HTTP_Client_Events events; events.onVersion = (HTTP_OnVersion) EmptyCallback(); events.onHeader = (HTTP_OnHeader) Callback(this, ref(OnHeader)); HTTP_Client_SetEvents(&client, events); HTTP_Client_Request(&client, HTTP_Client_CreateRequest( parts.host, parts.path)); Logger_Debug(this->logger, $("URL: %"), url); URL_Parts_Destroy(&parts); HTTP_Client_FetchResponse(&client); size_t cnt = 0; bool error = false; if (this->location.len > 0) { if (cnt > 3) { Logger_Error(this->logger, $("Redirection loop.")); goto out; } cnt++; Logger_Debug(this->logger, $("Redirecting...")); call(Get, prefix, item, this->location); goto out; } String full = call(BuildPath, prefix, item, scall(GetMediaExtension, parts.path)); Logger_Debug(this->logger, $("Destination: %"), full); File file; File_Open(&file, full, FileStatus_Create | FileStatus_Truncate | FileStatus_WriteOnly); String_Destroy(&full); BufferedStream output; BufferedStream_Init(&output, File_AsStream(&file)); BufferedStream_SetOutputBuffer(&output, 128 * 1024); u64 got = 0; s64 total = HTTP_Client_GetLength(&client); size_t prevPercent = 100; String buf = String_New(HTTP_Client_ReadChunkSize); Terminal_ProgressBar pbar; Terminal_ProgressBar_Init(&pbar, &term); while (HTTP_Client_Read(&client, &buf)) { got += buf.len; try { BufferedStream_Write(&output, buf.buf, buf.len); } clean catch(File, WritingFailed) { error = true; excBreak; } finally { } tryEnd; size_t percent = (size_t) ((float) got / (float) total * 100); if (prevPercent != percent) { float gotmb = (float) got / 1024 / 1024; float totalmb = (float) total / 1024 / 1024; String strGot = Float_ToString(gotmb, 0.01, '.'); String strTotal = Float_ToString(totalmb, 0.01, '.'); String msg = String_Format($("Received % MiB of % MiB"), strGot, strTotal); String_Destroy(&strTotal); String_Destroy(&strGot); Terminal_ProgressBar_Render(&pbar, percent, msg); String_Destroy(&msg); } prevPercent = percent; } Terminal_ProgressBar_Clear(&pbar); String_Destroy(&buf); if (error) { /* Don't flush when closing the file. */ BufferedStream_Reset(&output); } BufferedStream_Close(&output); BufferedStream_Destroy(&output); out: HTTP_Client_Destroy(&client); if (error) { throw(DownloadFailed); } }