2014년 10월 29일 수요일

mfc 파일업로드(mfc multipart request)

Win32나 mfc로 파일 업로드 하는 방법은 다음과 같다.



static TCHAR hdrs[] = _T("Content-Type: multipart/form-data; boundary=---------------------8cba7c0b4681f6e");

static char frmdata[] = "-----------------------8cba7c0b4681f6e\r\nContent-Disposition: form-data; name=\"file\"; filename=\"test.txt\"\r\nContent-Type: application/octet-stream\r\n\r\nhello\r\n\r\n-----------------------8cba7c0b4681f6e--\r\n";



// for clarity, error-checking has been removed

HINTERNET hSession = InternetOpen(_T(""), INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);

HINTERNET hConnect = InternetConnect(hSession, _T("서버주소"), INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 1);

HINTERNET hRequest = HttpOpenRequest(hConnect, _T("POST"), _T("/FileServer/Upload.aspx?filename=test.txt&mydir=TEST1"), NULL, NULL, NULL, 0, 1);

//HttpAddRequsetHeaders

HttpSendRequest(hRequest, hdrs, wcslen(hdrs), frmdata, strlen(frmdata));



먼저 InternetOpen으로 세션을 열고, InternetConnect를 연결을 한다.

그 다음 HttpOpenRequest로 연결한 주소의 호출할 페이지 위치를 접속한 후, HttpSendRequest로 파일을 업로드 한다.

필요하다면(거의 필요하지만), HttpAddRequsetHeaders를 이용하여 multipart로 날아간다는 헤더(위의 코드에서 hdrs 변수)를 설정하면 된다. 아니면 HttpSendRequest의 2,3번째 인자를 통해 설정해도 된다. 미리 HttpAddRequsetHeaders를 통해 설정했다면, HttpSendRequest의 2,3번째 변수의 값은 NULL과 0이 될 것이다.



데이터가 날아가는 순서는 다음과 같다.



접속-> multipart 헤더 전송(설정) -> 필요한 파라미터 전송(설정) -> 실제 파일 데이터 전송 이렇게 된다.



위의 샘플은 multipart로 날릴 데이터를 한번에 보낼 때 저렇게 하면 된다는 것이다. frmdata 변수의 내용을 보면, 실제 데이터(hello)와 앞에 파일의 이름과 바운더리가 앞 뒤로 다 붙어있는 것을 볼 수 있다.



이렇게 보낼 수도 있지만, 파라미터를 먼저 보내고 그 다음 파일을 보낼 수도 있다. 이럴 때는 코드가 약간 달라진다.



hInternet = InternetOpen( _T( "Mozilla" ), INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0 );

hConnect = InternetConnect( hInternet, sServer, nPort, NULL, NULL, INTERNET_SERVICE_HTTP, 0, NULL );

hRequest = HttpOpenRequest( hConnect, _T( "POST" ), sObject, NULL, NULL, NULL,INTERNET_FLAG_NO_CACHE_WRITE  , NULL );

if( !HttpAddRequestHeaders( hRequest, strHeaders, strHeaders.GetLength(), HTTP_ADDREQ_FLAG_REPLACE | HTTP_ADDREQ_FLAG_ADD ) )    //헤더는 hdrs 임. multipart/form-data

{

result = GetLastError();

goto finish;

}



ss.Format( _T("Content-length:%u"), nTotalLength  );

//nTotalLength는 실제 파라미터들의 길이 + 파일의 길이 이다. 실제 파일의 길이를 넘겨주지 않으면, 중간에 세션이 닫혀버린다.

if( !HttpAddRequestHeaders( hRequest, ss, ss.GetLength(), HTTP_ADDREQ_FLAG_REPLACE | HTTP_ADDREQ_FLAG_ADD ) )

{

result = GetLastError();

goto finish;

}

if( !::HttpSendRequestEx( hRequest, NULL, NULL, NULL, NULL ) )

{

result = GetLastError();

goto finish;

}

이 뒤로 InternetWriteFile 메소드를 이용하여 파라미터를 먼저 날리고 그 다음 파일을 날리면 된다.

이와 같은 방식으로 파일을 올리는 예제코드이다.

devideUpload.zip

댓글 없음: