블로그 이미지
랜달프

calendar

1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30

Notice

    2008. 12. 12. 11:05 Programming/VC++(API,MFC,WTL,ATL)


    #include "stdafx.h"
    #include "UploadTest.h"
    #include "UploadHTTP.h"

    #ifdef _DEBUG
    #undef THIS_FILE
    static char THIS_FILE[]=__FILE__;
    #define new DEBUG_NEW
    #endif

    //////////////////////////////////////////////////////////////////////
    // Construction/Destruction
    //////////////////////////////////////////////////////////////////////

    CUploadHTTP::CUploadHTTP()
    {
      m_strBoundary = _T("kljsladfjlkasjdfljasdkfj");
    }

    CUploadHTTP::~CUploadHTTP()
    {

    }

    BOOL CUploadHTTP::UploadFile(LPCTSTR lpszFilePath, LPCTSTR lpszFileName, _bstr_t* lpStrRemotePath)
    {
      BOOL bResult = FALSE;
      INTERNET_BUFFERS BufferIn;

      HINTERNET hInternet = ::InternetOpen(_T("IDASClient"), INTERNET_OPEN_TYPE_PRECONFIG, 0, 0, 0);

      if(hInternet == NULL)
        return FALSE;

      HINTERNET hConnection = InternetConnect(hInternet, m_strHost, m_nPort, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
      if(hConnection == NULL)
      {
        ::InternetCloseHandle(hInternet);
        return FALSE;
      }

      HINTERNET hRequest = ::HttpOpenRequest(hConnection, _T("POST"), m_strPageObject, NULL, NULL, NULL, INTERNET_FLAG_NO_CACHE_WRITE, 0);
      if(hRequest == NULL)
      {
        ::InternetCloseHandle(hConnection);
        ::InternetCloseHandle(hInternet);
        return FALSE;
      }


      // HTTP Header
      _bstr_t strHeader;
      strHeader  = _T("Content-Type: multipart/form-data; boundary=");
      strHeader += m_strBoundary;

      ::HttpAddRequestHeaders(hRequest, (LPCTSTR)strHeader, -1, 0);

     

      // Part Header
      _bstr_t  strFilePartHead("--");
      strFilePartHead += m_strBoundary;
      strFilePartHead += "\r\nContent-Disposition: form-data; name=\"attfile\"; filename=\"";
      strFilePartHead += lpszFileName;
      strFilePartHead += "\"\r\nContent-Type: application/octet-stream\r\n\r\n";

     

      // Part Tail
      _bstr_t  strFilePartTail("\r\n");
      strFilePartTail += "--";
      strFilePartTail += m_strBoundary;
      strFilePartTail += "--\r\n";

     

      BufferIn.dwStructSize = sizeof(INTERNET_BUFFERS);
      BufferIn.dwHeadersLength = lstrlen((LPCTSTR)strHeader);
      BufferIn.dwHeadersTotal  = lstrlen((LPCTSTR)strHeader);
      BufferIn.lpcszHeader     = (LPCTSTR)strHeader;
      BufferIn.lpvBuffer       = NULL;
      BufferIn.Next            = NULL;
      BufferIn.dwBufferLength  = 0;
      BufferIn.dwBufferTotal   = GetFileSize(lpszFilePath) + strlen((LPCSTR)strFilePartHead) + strlen((LPCSTR)strFilePartTail);
      BufferIn.dwOffsetHigh    = 0;
      BufferIn.dwOffsetLow     = 0;

     

      if(!::HttpSendRequestEx(hRequest, &BufferIn, NULL, 0, NULL))
      {
        DWORD dwError = GetLastError();

        ::InternetCloseHandle(hRequest);
        ::InternetCloseHandle(hConnection);
        ::InternetCloseHandle(hInternet);
        return FALSE;
      }

     

      // Send Header(반드시 LPCSTR 타입으로 LPCTSTR 타입이면 UNICODE 시 오류)
      DWORD dwWritten = 0;
      InternetWriteFile(hRequest, (LPCVOID)(LPCSTR)strFilePartHead, strlen((LPCSTR)strFilePartHead), &dwWritten);

     

      // Send File content
      WriteFile(hRequest, lpszFilePath);

     

      // Send Tailer(반드시 LPCSTR 타입으로 LPCTSTR 타입이면 UNICODE 시 오류)
      InternetWriteFile(hRequest, (LPCVOID)(LPCSTR)strFilePartTail, strlen((LPCSTR)strFilePartTail), &dwWritten);

     

     

      // 이 문장을 빼먹으면 아래 InternetQueryDataAvailable 실행 시 12019 오류 발생
      // 몇 시간 동안 삽질했음.
      ::HttpEndRequest(hRequest, NULL, 0, NULL);


      // 서버는 올린 파일을 네이밍 룰에 맞춰 저장한 후, 저장된 이름을 알려 주므로
      // 그걸 얻기 위해 필요한 것이지, 일반적인 경우는 알아서..
      DWORD dwSize = 0;
      DWORD dwRead = 0;
      if(InternetQueryDataAvailable(hRequest, &dwSize, 0, 0))
      {
        LPSTR lpszBuff = new char[dwSize+1];
        ZeroMemory(lpszBuff, dwSize+1);
        if(!InternetReadFile(hRequest, (LPVOID)lpszBuff, dwSize, &dwRead))
        {
          DWORD dwErrorCode = GetLastError();
          delete lpszBuff;
        }
        else
        {
          bResult = TRUE;
          delete lpszBuff;
          *lpStrRemotePath = (LPTSTR)lpszBuff;
        }
      }

      HttpEndRequest(hRequest, NULL, 0, 0);

      InternetCloseHandle(hRequest);
      InternetCloseHandle(hConnection);
      InternetCloseHandle(hInternet);

      return bResult;
    }


    BOOL CUploadHTTP::WriteFile(HINTERNET hInternet, LPCTSTR lpszFilePath)
    {
      BYTE chBuff[4096];
      DWORD dwRead = 0;
      DWORD dwWrite = 0;
      DWORD dwErrorCode = 0;
      BOOL  bResult = TRUE;

      HANDLE hFile = CreateFile(lpszFilePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

      if(hFile == INVALID_HANDLE_VALUE)
      {
        dwErrorCode = GetLastError();
        return FALSE;
      }

      while(ReadFile(hFile, (LPVOID)chBuff, 4096, &dwRead, NULL))
      {
        if(dwRead == 0)
          break;

        if(InternetWriteFile(hInternet, (LPCVOID)chBuff, dwRead, &dwWrite) == FALSE)
        {
          bResult = FALSE;
          break;
        }
      }

      CloseHandle(hFile);

      return bResult;
    }

    DWORD CUploadHTTP::GetFileSize(LPCTSTR lpszFilePath)
    {
      DWORD dwLength = 0;
      HANDLE hFile = CreateFile(lpszFilePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

      if(hFile != INVALID_HANDLE_VALUE)
      {
        BY_HANDLE_FILE_INFORMATION  FileInfo;
        GetFileInformationByHandle(hFile, &FileInfo);
        dwLength = FileInfo.nFileSizeLow;
      }

      CloseHandle(hFile);

      return dwLength;
    }

    posted by 랜달프