int32_t nsIMAPBodypartMultipart::Generate(nsIMAPBodyShell *aShell, bool stream, bool prefetch) { int32_t len = 0; if (GetIsValid()) { if (stream && !prefetch) aShell->GetConnection()->Log("SHELL","GENERATE-Multipart",m_partNumberString); // Stream out the MIME header of this part bool parentIsMessageType = GetParentPart() ? (GetParentPart()->GetType() == IMAP_BODY_MESSAGE_RFC822) : true; // If this is multipart/signed, then we always want to generate the MIME headers of this multipart. // Otherwise, we only want to do it if the parent is not of type "message" bool needMIMEHeader = !parentIsMessageType; // !PL_strcasecmp(m_bodySubType, "signed") ? true : !parentIsMessageType; if (needMIMEHeader && !aShell->GetPseudoInterrupted()) // not a message body's type { len += GenerateMIMEHeader(aShell, stream, prefetch); } if (ShouldFetchInline(aShell)) { for (int i = 0; i < m_partList->Count(); i++) { if (!aShell->GetPseudoInterrupted()) len += GenerateBoundary(aShell, stream, prefetch, false); if (!aShell->GetPseudoInterrupted()) len += ((nsIMAPBodypart *)(m_partList->ElementAt(i)))->Generate(aShell, stream, prefetch); } if (!aShell->GetPseudoInterrupted()) len += GenerateBoundary(aShell, stream, prefetch, true); } else { // fill in the filling within the empty part if (!aShell->GetPseudoInterrupted()) len += GenerateEmptyFilling(aShell, stream, prefetch); } } m_contentLength = len; return m_contentLength; }
// Construct the strings for the http. static int ConstructStringsForMethod(SoundCloudCAPI *api,const char* httpMethod,const char *resource,SoundCloudCAPI_Parameter* parameters,int num_params,char **url,char **body,size_t* bodylen,char **header) { char *newurl,*suffix,*tail,*boundary,*headerstring,*pstring,*postargs=0,*sigurl,*signed_url; size_t datalen,headlen,taillen,urllen; if (api->t_type!=2) return SoundCloudCAPICallback_didFailWithError; // Construct the root of the url. headlen=strlen(api->apiBaseURL)+strlen(resource); if (*resource!='/') headlen++; taillen=strlen(httpMethod)+10+4; urllen=headlen+taillen; newurl=(char*)malloc(urllen+1);newurl[urllen]=0; // Here's the URL and the resource. sprintf(newurl,"%s%s%s",api->apiBaseURL,(*resource=='/')?"":"/",resource); if (newurl[headlen-1]=='/') headlen--; suffix=newurl+headlen; // Add the suffix to request the response format tail=suffix+sprintf(suffix,".%s",(api->responseFormat)?"js":"xml"); // Append the access method // tail+=sprintf(tail,"?_method=%s",httpMethod); // Unsigned URL is complete. // Generate a boundary and header for any multipart we have. boundary=GenerateBoundary(); headerstring=(char*)malloc(100+strlen(boundary)); // construct a header string sprintf(headerstring,"Content-Type: multipart/form-data; boundary=%s",boundary); // Construct a binary field containing all the parameter data (files, strings etc). pstring=ParametersToString(parameters, num_params,&datalen,boundary); if (!datalen) {free(headerstring);headerstring=(char*)malloc(1);*headerstring=0;} // don't use a multipart header if we don't have actual data. // Sign the URL. sc_log(api,SoundCloudCAPI_LogLevel_Debug,"Signing url [%s], method [%s], with [%s][%s][%s][%s]\n",newurl,httpMethod,api->consumerKey,api->consumerSecret,api->t_key,api->t_secret); sigurl = oauth_sign_url2(newurl, &postargs, OA_HMAC, httpMethod, api->consumerKey, api->consumerSecret, api->t_key, api->t_secret); // Concatenate the post args onto the url. signed_url=(char*)malloc(2+strlen(sigurl)+strlen(postargs));sprintf(signed_url,"%s?%s",sigurl,postargs); sc_log(api,SoundCloudCAPI_LogLevel_Debug,"Sending Url [%s], header[%s], body[%s]\n",signed_url,headerstring,pstring); free(newurl);free(boundary);free(sigurl);if(postargs)free(postargs); (*header)=headerstring; // SAVE (*body)=pstring; (*bodylen)=datalen; (*url)=signed_url; return 0; }
bool SendFile(HANDLE hFile, const TCHAR* sUrl, const char* sVariableName, const char* sFileName) { if(!hFile) return false; bool result = false; LARGE_INTEGER lnSize; if(!GetFileSizeEx(hFile, &lnSize)){ CloseHandle(hFile); return false; } DWORD nDataSize = lnSize.LowPart; if(!(nDataSize>0)) { CloseHandle(hFile); return false; } std::vector<char> pData(nDataSize); DWORD nReadSize = 0; if(!ReadFile(hFile, (void*)&pData[0], nDataSize, &nReadSize, NULL) || !(nReadSize >0) || (nReadSize != nDataSize)) { CloseHandle(hFile); return false; } CloseHandle(hFile); TCHAR extraInfo[URL_PART_SIZE]; TCHAR hostName[URL_PART_SIZE]; TCHAR passwordSet[URL_PART_SIZE]; TCHAR schemeUrl[URL_PART_SIZE]; TCHAR fileUrlPath[URL_PART_SIZE]; TCHAR userName[URL_PART_SIZE]; URL_COMPONENTS aUrl; aUrl.dwStructSize=sizeof(URL_COMPONENTS); aUrl.dwHostNameLength=URL_PART_SIZE; aUrl.dwPasswordLength=URL_PART_SIZE; aUrl.dwSchemeLength=URL_PART_SIZE; aUrl.dwUrlPathLength=URL_PART_SIZE; aUrl.dwUserNameLength=URL_PART_SIZE; aUrl.dwExtraInfoLength=URL_PART_SIZE; aUrl.lpszExtraInfo=extraInfo; aUrl.lpszHostName=hostName; aUrl.lpszPassword=passwordSet; aUrl.lpszScheme=schemeUrl; aUrl.lpszUrlPath=fileUrlPath; aUrl.lpszUserName=userName; PCTSTR rgpszAcceptTypes[] = {_T("text/*"), NULL}; if(!InternetCrackUrl(sUrl, 0, 0, &aUrl)) return false; HINTERNET hInternet = InternetOpen(TEXT("swas"),INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); if(hInternet) { HINTERNET hConnect = InternetConnect(hInternet,aUrl.lpszHostName, aUrl.nPort, aUrl.lpszUserName, aUrl.lpszHostName, INTERNET_SERVICE_HTTP, 0, 0); if(hConnect){ HINTERNET hReq = HttpOpenRequest(hConnect, TEXT("POST"), aUrl.lpszUrlPath, NULL, NULL, rgpszAcceptTypes, INTERNET_FLAG_NO_UI | INTERNET_FLAG_PRAGMA_NOCACHE | INTERNET_FLAG_RELOAD, 0); if(hReq) { //see http://stackoverflow.com/questions/6407755/how-to-send-a-zip-file-using-wininet-in-my-vc-application char sBoundary[HEADERS_MAX_SIZE]; if(GenerateBoundary(sBoundary, HEADERS_MAX_SIZE, sFileName)) { std::stringstream osHeaders; std::stringstream osHeadPart; std::stringstream osTailPart; const char const endl[] = "\r\n"; osHeaders<<"Content-Type: multipart/form-data; boundary="<<sBoundary; osHeadPart<<"--"<<sBoundary<<endl; osHeadPart<<"Content-Disposition: form-data; "; osHeadPart<<"name=\""<<((NULL != sVariableName)?sVariableName:"filearg")<<"\"; "; osHeadPart<<"filename=\""<<((NULL != sFileName)?sFileName:"Chrome Tabs")<<"\""<<endl; osHeadPart<<"Content-Type: application/octet-stream"<<endl; osHeadPart<<endl; osTailPart<<endl<<"--"<<sBoundary<<"--"<<endl; std::string sHeaders = osHeaders.str(); std::string sHeadPart = osHeadPart.str(); std::string sTailPart = osTailPart.str(); HttpAddRequestHeadersA(hReq, sHeaders.c_str(), -1, HTTP_ADDREQ_FLAG_REPLACE | HTTP_ADDREQ_FLAG_ADD); INTERNET_BUFFERS bufferIn; memset(&bufferIn, 0, sizeof(INTERNET_BUFFERS)); bufferIn.dwStructSize = sizeof(INTERNET_BUFFERS); bufferIn.dwBufferTotal = sHeadPart.length() + nDataSize + sTailPart.length(); DWORD bytesWritten; if(HttpSendRequestEx(hReq, &bufferIn, NULL, HSR_INITIATE, 0)) { InternetWriteFile(hReq, (const void*)sHeadPart.c_str(), sHeadPart.length(), &bytesWritten); InternetWriteFile(hReq, (const void*)&pData[0], nDataSize, &bytesWritten); // or a while loop for call InternetWriteFile every 1024 bytes... InternetWriteFile(hReq, (const void*)sTailPart.c_str(), sTailPart.length(), &bytesWritten); result = true; }else{ ShowAnError(GetLastError(), TEXT("Network error"), TEXT("Wininet")); } } HttpEndRequest(hReq, NULL, HSR_INITIATE, 0); }else{ ShowAnError(GetLastError(), TEXT("Network error"), TEXT("Wininet")); } }else{ ShowAnError(GetLastError(), TEXT("Network error"), TEXT("Wininet")); } InternetCloseHandle(hInternet); } return result; }