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;
}
Exemple #3
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;
}