MartinF
2008-05-12 16:06:20 UTC
Hello All,
I need to programmatically upload a file to an IIS server. For this I wrote
a small proof of concept app that uses WinInet.lib that runs on my Vista
machine and connects to a server that runs IIS 7.0 The app appears to work
just fine, but at the end of the HttpQueryInfo() call with the
HTTP_QUERY_STATUS_CODE I get a 404 response. Analyzing the log on the IIS
server reveals the following:
#Date: 2008-05-09 23:43:40
#Fields: date time s-ip cs-method cs-uri-stem cs-uri-query s-port
cs-username c-ip cs(User-Agent) sc-status sc-substatus sc-win32-status
time-taken
2008-05-09 23:43:40 192.168.1.253 GET /Upload/ - 80 - 192.168.1.253
Mozilla/4.0+(compatible;+MSIE+7.0;+Windows+NT+6.0;+SLCC1;+.NET+CLR+2.0.50727;+.NET+CLR+3.0.04506)
200 0 0 50
2008-05-09 23:44:02 192.168.1.253 PUT /Upload/Test.txt - 80 - 192.168.1.185
HttpSend 404 0 2 200
2008-05-09 23:47:12 192.168.1.253 GET / - 80 - 192.168.1.253
Mozilla/4.0+(compatible;+MSIE+7.0;+Windows+NT+6.0;+SLCC1;+.NET+CLR+2.0.50727;+.NET+CLR+3.0.04506)
200 0 0 100
2008-05-09 23:48:44 192.168.1.253 PUT /Upload/Test.txt - 80 - 192.168.1.185
HttpSend 404 0 64 110
2008-05-09 23:58:16 192.168.1.253 PUT /Upload/Test.txt - 80 - 192.168.1.185
HttpSend 404 0 64 150
I abbreviate the code here for the sake of brevety:
1.- Calling my class as follows:
int _tmain(int argc, _TCHAR* argv[])
{
CHttpSend Http;
if ( Http.Init( TEXT("http://192.168.1.253/Upload/Test.txt") ) == true )
{
Http.SendFile( TEXT("c:\\Develop\\Test.txt") );
}
return 0;
}
2.- Abbreviated CHttpSend::Init() is as follows:
m_hInternet = InternetOpen( TEXT("HttpSend"),
INTERNET_OPEN_TYPE_PRECONFIG,
0, 0, 0) ;
URL_COMPONENTS urlComp = { 0 };
TCHAR szHostName[INTERNET_MAX_HOST_NAME_LENGTH] = { 0 };
TCHAR szPath[INTERNET_MAX_PATH_LENGTH] = { 0 };
TCHAR szExtra[INTERNET_MAX_PATH_LENGTH] = { 0 };
urlComp.dwStructSize = sizeof(urlComp);
urlComp.lpszHostName = szHostName;
urlComp.dwHostNameLength = sizeof(szHostName) - 1;
urlComp.lpszUrlPath = szPath;
urlComp.dwUrlPathLength = sizeof(szPath) - 1;
urlComp.lpszExtraInfo = szExtra;
urlComp.dwExtraInfoLength= sizeof(szExtra) - 1;
InternetCrackUrl( pszUrl, 0, ICU_ESCAPE, &urlComp);
// At this point szHostName contains "192.168.1.253"
// At this point urlComp.nPort is 80. I made sure it doesn't conflict with
default website.
m_hHttp = InternetConnect( m_hInternet, szHostName, urlComp.nPort,
0, 0, INTERNET_SERVICE_HTTP, 0, 0);
3.- Abbreviated CHttpSend::SendFile() is as follows:
hRequest = HttpOpenRequest (
m_hHttp, TEXT("PUT"), m_pszUrl, NULL,
NULL, NULL, INTERNET_FLAG_KEEP_CONNECTION, 0
);
memset(&IBuff, 0, sizeof(IBuff));
IBuff.dwStructSize = sizeof(IBuff);
IBuff.dwBufferTotal = File.Length();
ulBytesToSend = IBuff.dwBufferTotal;
HttpSendRequestEx( hRequest, &IBuff, NULL, HSR_INITIATE, 0);
// Do a number of InternetWriteFile() calls as we are reading from
// the file to send.
InternetWriteFile( hRequest, pBuff, ulBytes, &ulWritten );
// Once all the file content was process
HttpEndRequest( hRequest, NULL, 0, 0 );
// And finally I do the HttpQueryInfo() which fails with a 404
if ( HttpQueryInfo( hRequest, HTTP_QUERY_STATUS_CODE, szBuff, &dwSize, &dw )
== TRUE )
{
UINT uRetCode = _wtol( szBuff );
if ( uRetCode < 400 )
bRet = true;
}
I suspect that there could be some IIS related configuration, but I think to
have it wide open from a security point of view. I am able to browse the
directory from a remote Internet Explorer.
Any help in this matter is greatly appreciated and thank you in advance.
Martin
I need to programmatically upload a file to an IIS server. For this I wrote
a small proof of concept app that uses WinInet.lib that runs on my Vista
machine and connects to a server that runs IIS 7.0 The app appears to work
just fine, but at the end of the HttpQueryInfo() call with the
HTTP_QUERY_STATUS_CODE I get a 404 response. Analyzing the log on the IIS
server reveals the following:
#Date: 2008-05-09 23:43:40
#Fields: date time s-ip cs-method cs-uri-stem cs-uri-query s-port
cs-username c-ip cs(User-Agent) sc-status sc-substatus sc-win32-status
time-taken
2008-05-09 23:43:40 192.168.1.253 GET /Upload/ - 80 - 192.168.1.253
Mozilla/4.0+(compatible;+MSIE+7.0;+Windows+NT+6.0;+SLCC1;+.NET+CLR+2.0.50727;+.NET+CLR+3.0.04506)
200 0 0 50
2008-05-09 23:44:02 192.168.1.253 PUT /Upload/Test.txt - 80 - 192.168.1.185
HttpSend 404 0 2 200
2008-05-09 23:47:12 192.168.1.253 GET / - 80 - 192.168.1.253
Mozilla/4.0+(compatible;+MSIE+7.0;+Windows+NT+6.0;+SLCC1;+.NET+CLR+2.0.50727;+.NET+CLR+3.0.04506)
200 0 0 100
2008-05-09 23:48:44 192.168.1.253 PUT /Upload/Test.txt - 80 - 192.168.1.185
HttpSend 404 0 64 110
2008-05-09 23:58:16 192.168.1.253 PUT /Upload/Test.txt - 80 - 192.168.1.185
HttpSend 404 0 64 150
I abbreviate the code here for the sake of brevety:
1.- Calling my class as follows:
int _tmain(int argc, _TCHAR* argv[])
{
CHttpSend Http;
if ( Http.Init( TEXT("http://192.168.1.253/Upload/Test.txt") ) == true )
{
Http.SendFile( TEXT("c:\\Develop\\Test.txt") );
}
return 0;
}
2.- Abbreviated CHttpSend::Init() is as follows:
m_hInternet = InternetOpen( TEXT("HttpSend"),
INTERNET_OPEN_TYPE_PRECONFIG,
0, 0, 0) ;
URL_COMPONENTS urlComp = { 0 };
TCHAR szHostName[INTERNET_MAX_HOST_NAME_LENGTH] = { 0 };
TCHAR szPath[INTERNET_MAX_PATH_LENGTH] = { 0 };
TCHAR szExtra[INTERNET_MAX_PATH_LENGTH] = { 0 };
urlComp.dwStructSize = sizeof(urlComp);
urlComp.lpszHostName = szHostName;
urlComp.dwHostNameLength = sizeof(szHostName) - 1;
urlComp.lpszUrlPath = szPath;
urlComp.dwUrlPathLength = sizeof(szPath) - 1;
urlComp.lpszExtraInfo = szExtra;
urlComp.dwExtraInfoLength= sizeof(szExtra) - 1;
InternetCrackUrl( pszUrl, 0, ICU_ESCAPE, &urlComp);
// At this point szHostName contains "192.168.1.253"
// At this point urlComp.nPort is 80. I made sure it doesn't conflict with
default website.
m_hHttp = InternetConnect( m_hInternet, szHostName, urlComp.nPort,
0, 0, INTERNET_SERVICE_HTTP, 0, 0);
3.- Abbreviated CHttpSend::SendFile() is as follows:
hRequest = HttpOpenRequest (
m_hHttp, TEXT("PUT"), m_pszUrl, NULL,
NULL, NULL, INTERNET_FLAG_KEEP_CONNECTION, 0
);
memset(&IBuff, 0, sizeof(IBuff));
IBuff.dwStructSize = sizeof(IBuff);
IBuff.dwBufferTotal = File.Length();
ulBytesToSend = IBuff.dwBufferTotal;
HttpSendRequestEx( hRequest, &IBuff, NULL, HSR_INITIATE, 0);
// Do a number of InternetWriteFile() calls as we are reading from
// the file to send.
InternetWriteFile( hRequest, pBuff, ulBytes, &ulWritten );
// Once all the file content was process
HttpEndRequest( hRequest, NULL, 0, 0 );
// And finally I do the HttpQueryInfo() which fails with a 404
if ( HttpQueryInfo( hRequest, HTTP_QUERY_STATUS_CODE, szBuff, &dwSize, &dw )
== TRUE )
{
UINT uRetCode = _wtol( szBuff );
if ( uRetCode < 400 )
bRet = true;
}
I suspect that there could be some IIS related configuration, but I think to
have it wide open from a security point of view. I am able to browse the
directory from a remote Internet Explorer.
Any help in this matter is greatly appreciated and thank you in advance.
Martin