2014년 10월 29일 수요일

Win32 파일 업로드(multipart가 아닌 그냥 post로 파일 스트림 전송)

인터넷에 돌아다니는 Win32 파일 업로드는 전부 multipart로 보내는거다. 대부분 파일 업로드 할 때, multipart로 보내긴 하지만, 굳이 필요 없을 경우, 아래와 같이 하면 된다.



 //파일을 연다.
 if( ( m_hFileHandle = CreateFile( szFilePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ) ) == NULL )
 {
  result = GetLastError();
  goto finish;
 }

 //연결시작
 hInternet = ::InternetOpen( _T("uptest"), INTERNET_OPEN_TYPE_DIRECT, 0, 0, 0 );

 if(hInternet == NULL)
 {
  result = GetLastError();
  goto finish;
 }

 hConnection = InternetConnect( hInternet, _T("주소"), INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0 );
 if( hConnection == NULL )
 {
  result = GetLastError();
  goto finish;
 }

 //쿠키를 HttpAddRequestHeaders로 추가할 경우, INTERNET_FLAG_NO_COOKIES 옵션 필수. INTERNET_FLAG_NO_COOKIES 옵션은 HttpOpenRequest에서 사용.
 m_hRequest = ::HttpOpenRequest( hConnection, _T("POST"), _T("주소이외의 경로"), NULL, NULL, NULL, INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_NO_COOKIES, 0 );
 if( m_hRequest == NULL )
 {
  result = GetLastError();
  goto finish;
 }

 if( !HttpAddRequestHeaders( m_hRequest, _T("Content-Type: application/x-www-form-urlencoded"), -1, HTTP_ADDREQ_FLAG_REPLACE | HTTP_ADDREQ_FLAG_ADD ) )
 {
  result = GetLastError();
  goto finish;
 }

 //길이 설정
 memset( szTemp, 0, sizeof( TCHAR ) * 1024 );
 _stprintf( szTemp, _T("Content-length:%u"), ::GetFileSize( m_hFileHandle, NULL ) );
 if( !HttpAddRequestHeaders( m_hRequest, szTemp, -1, HTTP_ADDREQ_FLAG_REPLACE | HTTP_ADDREQ_FLAG_ADD ) )
 {
  result = GetLastError();
  goto finish;
 }

 //쿠키 설정
 memset( szTemp, 0, sizeof( TCHAR ) * 1024 );
 _stprintf( szTemp, _T("Cookie: filename=%s%s"), szFileName, szExt );
 if( !HttpAddRequestHeaders( m_hRequest, szTemp, -1, HTTP_ADDREQ_FLAG_REPLACE | HTTP_ADDREQ_FLAG_ADD ) )
 {
  result = GetLastError();
  goto finish;
 }

 //Send
 if( !::HttpSendRequestEx( m_hRequest, NULL, NULL, 0, NULL ) )
 {
  result = GetLastError();
  goto finish;
 }

 BYTE buff[ BUFFER_SIZE ];
 DWORD dwRead = 0;
 DWORD dwWrite = 0, dwTotalWrite = 0;
 MSG msg;

 while( ReadFile( m_hFileHandle, (LPVOID)buff, BUFFER_SIZE, &dwRead, NULL ) )
 {
  if (dwRead == 0 )
   break;

  if( InternetWriteFile( m_hRequest, ( LPCVOID )buff, dwRead, &dwWrite ) == FALSE )
  {
   goto finish;
  }

  _stprintf( szTemp, _T("current : %u, total : %u"), dwWrite, dwTotalWrite );
  //m_listBox.AddString( szTemp );
  //m_listBox.SetSel( m_listBox.GetCount() - 1 );

  while( PeekMessage( &msg, NULL, NULL, NULL, TRUE ) ) //만약 화면을 갱신해야 하면, Message를 처리해준다.
  {
   TranslateMessage( &msg );
   DispatchMessage( &msg );
  }
 }



finish :
 if( m_hRequest != NULL )
 {
  ::HttpEndRequest( m_hRequest, NULL, 0, NULL );
  ::InternetCloseHandle( m_hRequest );
  m_hRequest = NULL;
 }

 if( hInternet != NULL )
  ::InternetCloseHandle (hInternet );

 if( hConnection != NULL )
  ::InternetCloseHandle( hConnection );

 if( m_hFileHandle != NULL )
 {
  CloseHandle(m_hFileHandle);
  m_hFileHandle = NULL;
 }
 AfxMessageBox( _T("업로드 끝") );

댓글 없음: