|
Can this class be used in ATL ?
Are the Bugs reported in the Posts are updated in the download ?
Thanks !
Wonderful effort
|
|
|
|
|
In my case, This class was created for ATL(Active X Server Component).
So, this class will work well done in ATL.
thanks..
------------------------------
http://gooshin.zzem.net
|
|
|
|
|
I found a few instances of CloseHandle in your code. It should have used InternetCloseHandle().
In the GenericHTTPClient::Connect function and GenericHTTPClient::Close. You should also NULL out the handles on closing the handles.
Finally, if you really want this code to be tight, I would recommend changing the functions to explicitly load wininet.dll, vs dynamic loading. Dynamic linking of dlls in a uncontrolled target environment is not a good idea for production grade code. Applications linking in this class will not always function appropriately if the wininet.dll is not installed, or older versions are installed, etc, etc.
Try something like this:
static HINTERNET (WINAPI *f_InternetOpen)(
IN LPCTSTR lpszAgent,
IN DWORD dwAccessType,
IN LPCTSTR lpszProxy OPTIONAL,
IN LPCTSTR lpszProxyBypass OPTIONAL,
IN DWORD dwFlags) = NULL;
static HINTERNET (WINAPI *f_InternetConnect)(
IN HINTERNET hInternet,
IN LPCTSTR lpszServerName,
IN INTERNET_PORT nServerPort,
IN LPCTSTR lpszUsername,
IN LPCTSTR lpszPassword,
IN DWORD dwService,
IN DWORD dwFlags,
IN DWORD_PTR dwContext) = NULL;
static DWORD (WINAPI *f_InternetAttemptConnect)(
IN DWORD dwReserved ) = NULL;
static BOOL (WINAPI *f_InternetCloseHandle)(
IN HINTERNET hInternet) = NULL;
static HINTERNET (WINAPI *f_HttpOpenRequest)(
IN HINTERNET hConnect,
IN LPCTSTR lpszVerb,
IN LPCTSTR lpszObjectName,
IN LPCTSTR lpszVersion,
IN LPCTSTR lpszReferer,
IN LPCTSTR* lpszAcceptTypes,
IN DWORD dwFlags,
IN DWORD_PTR dwContext ) = NULL;
static BOOL (WINAPI *f_HttpAddRequestHeaders)(
IN HINTERNET hConnect,
IN LPCTSTR lpszHeaders,
IN DWORD dwHeadersLength,
IN DWORD dwModifiers ) = NULL;
static BOOL (WINAPI *f_HttpSendRequest)(
IN HINTERNET hRequest,
IN LPCTSTR lpszHeaders,
IN DWORD dwHeadersLength,
IN LPVOID lpOptional,
IN DWORD dwOptionalLength ) = NULL;
static BOOL (WINAPI *f_InternetQueryOption)(
IN HINTERNET hInternet,
IN DWORD dwOption,
OUT LPVOID lpBuffer,
IN LPDWORD lpdwBufferLength ) = NULL;
static BOOL (WINAPI *f_InternetSetOption)(
HINTERNET hInternet,
DWORD dwOption,
LPVOID lpBuffer,
DWORD dwBufferLength ) = NULL;
static BOOL (WINAPI *f_HttpSendRequestEx)(
HINTERNET hRequest,
LPINTERNET_BUFFERS lpBuffersIn,
LPINTERNET_BUFFERS lpBuffersOut,
DWORD dwFlags,
DWORD dwContext ) = NULL;
static BOOL (WINAPI *f_InternetWriteFile)(
HINTERNET hFile,
LPCVOID lpBuffer,
DWORD dwNumberOfBytesToWrite,
LPDWORD lpdwNumberOfBytesWritten ) = NULL;
static BOOL (WINAPI *f_HttpEndRequest)(
HINTERNET hRequest,
LPINTERNET_BUFFERS lpBuffersOut,
DWORD dwFlags,
DWORD dwContext ) = NULL;
static BOOL (WINAPI *f_InternetReadFile)(
IN HINTERNET hFile,
IN LPVOID lpBuffer,
IN DWORD dwNumberOfBytesToRead,
OUT LPDWORD lpdwNumberOfBytesRead) = NULL;
static BOOL (WINAPI *f_HttpQueryInfo)(
IN HINTERNET hRequest,
IN DWORD dwInfoLevel,
IN OUT LPVOID lpBuffer OPTIONAL,
IN OUT LPDWORD lpdwBufferLength,
IN OUT LPDWORD lpdwIndex OPTIONAL) = NULL;
static HMODULE wininet = NULL;
static int InitWinInet(void)
{
wininet = LoadLibrary("wininet.dll");
if (!wininet)
{
return -1;
}
CPPASS f_InternetOpen = GetProcAddress(wininet, "InternetOpenA");
CPPASS f_InternetConnect = GetProcAddress(wininet, "InternetConnectA");
CPPASS f_InternetAttemptConnect = GetProcAddress(wininet, "InternetAttemptConnect");
CPPASS f_InternetCloseHandle = GetProcAddress(wininet, "InternetCloseHandle");
CPPASS f_HttpOpenRequest = GetProcAddress(wininet, "HttpOpenRequestA");
CPPASS f_HttpAddRequestHeaders = GetProcAddress(wininet, "HttpAddRequestHeadersA");
CPPASS f_HttpSendRequest = GetProcAddress(wininet, "HttpSendRequestA");
CPPASS f_InternetQueryOption = GetProcAddress(wininet, "InternetQueryOptionA");
CPPASS f_InternetSetOption = GetProcAddress(wininet, "InternetSetOptionA");
CPPASS f_HttpSendRequestEx = GetProcAddress(wininet, "HttpSendRequestExA");
CPPASS f_InternetWriteFile = GetProcAddress(wininet, "InternetWriteFile");
CPPASS f_HttpEndRequest = GetProcAddress(wininet, "HttpEndRequestA");
CPPASS f_InternetReadFile = GetProcAddress(wininet, "InternetReadFile");
CPPASS f_HttpQueryInfo = GetProcAddress(wininet, "HttpQueryInfoA");
if ( !f_InternetOpen ||
!f_InternetConnect ||
!f_InternetAttemptConnect ||
!f_InternetCloseHandle ||
!f_HttpOpenRequest ||
!f_HttpAddRequestHeaders ||
!f_HttpSendRequest ||
!f_InternetQueryOption ||
!f_InternetSetOption ||
!f_HttpSendRequestEx ||
!f_InternetWriteFile ||
!f_HttpEndRequest ||
!f_InternetReadFile ||
!f_HttpQueryInfo )
{
return -2;
}
return 0;
}
void UnloadWinInet()
{
if (wininet)
FreeLibrary(wininet);
wininet = NULL;
}
Finally, I thing your sample is excellent. I would make two other ammendments, per some of the suggestions:
1. Add HTTPS support
2. Add custom content types
(remove underscores to retrieve my email address).
k_e_i_t_h@p_i_r_k_l_s.com
|
|
|
|
|
Has anyone tried to use this sample with Unicode? I have some apprehensions, though apparently the code seems to be Unicode.
At many places the TEXT / _T macro is missing?
Anyways the code is nicely written!!! Cheers..
- SUDESH SAWANT
Bond with the best
|
|
|
|
|
When I set the project with Unicode, and replace the string with TEXT / _T, it still compile error. The error is in HttpOpenRequest().
=============================================
The original code is:
CONST TCHAR *szAcceptType=__HTTP_ACCEPT_TYPE;
_hHTTPRequest=::HttpOpenRequest( _hHTTPConnection,
__HTTP_VERB_GET, // HTTP Verb
szURI, // Object Name
HTTP_VERSION, // Version
_T(""), // Reference
&szAcceptType, // Accept Type
INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_NO_CACHE_WRITE,
0); // context call-back point
=============================================
Fix:
LPTSTR AcceptTypes[2]={0};
AcceptTypes[0]=__HTTP_ACCEPT_TYPE;
_hHTTPRequest=::HttpOpenRequest( _hHTTPConnection,
__HTTP_VERB_GET, // HTTP Verb
szURI, // Object Name
HTTP_VERSION, // Version
_T(""), // Reference
(LPCTSTR*)AcceptTypes, // Accept Type
INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_NO_CACHE_WRITE,
0); // context call-back point
chilan
|
|
|
|
|
in line 759:
::CopyMemory((pInBuffer+dwPosition+2+_tcslen(szBoundary)), "--\r\n", 3);
should be
::CopyMemory((pInBuffer+dwPosition+2+_tcslen(szBoundary)), "--\r\n", 4);
in line 761
return dwPosition+5+_tcslen(szBoundary);
should be
::return dwPosition+6+_tcslen(szBoundary);
right?
tyt
|
|
|
|
|
|
your class is easy to use?
I like it
tyt
|
|
|
|
|
Just use folowwing coding to upload file to server...
Its Tooooooooooooooo much easy..
suppose site(CompleteUploadURL is: www.xxx.com/index.jsp
file is: C:\\fax0.tif
--------------------------------------
GenericHTTPClient *pClient=new GenericHTTPClient();
pClient->Connect("http://xxx.com/index.jsp");
pClient->InitilizePostArguments();
pClient->AddPostArguments("uplFile1", "C:\\Fax0.tif", TRUE);
if(pClient->Request(CompleteUploadURL,
GenericHTTPClient::RequestPostMethodMultiPartsFormData)){
LPCTSTR szResult=pClient->QueryHTTPResponse();
MessageBox(szResult);
}
----------------------------------------
That's solve...Easy..na
Sumit Kapoor
|
|
|
|
|
|
well...but...
your code is
pClient->Connect()...
GenericHTTPClient::connect() is invoked Request()..
so,.
your code is modified follow this :
GenericHTTPClient *pClient=new GenericHTTPClient();
pClient->InitilizePostArguments();
pClient->AddPostArguments("uplFile1", "C:\\Fax0.tif", TRUE);
if(pClient->Request("http://xxx.com/index.jsp",
GenericHTTPClient::RequestPostMethodMultiPartsFormData)){
LPCTSTR szResult=pClient->QueryHTTPResponse();
MessageBox(szResult);
}
thanks.
------------------------------
http://gooshin.zzem.net
|
|
|
|
|
Very Thanks....
One thing is sure..that you have written very nice code...
It's tooo much complex to understand...But Nice B'cos I like complex....
Also thanks for Improvement in my code...
OK! Good Bye..Have a nice Life...Bye..Sumit
Sumit Kapoor
|
|
|
|
|
:(One problem I find in following code...
--------------------------------------------------------
GenericHTTPClient *pClient=new GenericHTTPClient();
pClient->InitilizePostArguments();
pClient->AddPostArguments("uplFile1", "C:\\Fax0.tif", TRUE);
if(pClient->Request("http://xxx.com/index.jsp",
GenericHTTPClient::RequestPostMethodMultiPartsFormData)){
LPCTSTR szResult=pClient->QueryHTTPResponse();
MessageBox(szResult);
}
----------------------------------------------------
If I change following line(3)......
pClient->AddPostArguments("uplFile1", "C:\\Fax0.tif", TRUE);
with.....
//------------------------------------
CString File1,File2;
File1="uplFile1";
File2="C:\\Fax0.tif";
pClient->AddPostArguments(File1,File2, TRUE);
//------------------------------------------
then This code is not working....
even...if I change
pClient->AddPostArguments((LPCTSTR)File1,(LPCTSTR)File2, TRUE);
Please tell me any solution...b'cos if we can not pass variable then how can we define different files....
Thanks..Sumit
Sumit Kapoor
|
|
|
|
|
|
But Please help me..I'm not getting result what I wish from your code...
I hope u help me..Please please please
Thanks
Sumit
Sumit Kapoor
|
|
|
|
|
CComBSTR bszAccount=szUserID;
CComBSTR bszJumin=szJumin;
CComBSTR bszSource=szSource;
CComBSTR bszDest=szDestination;
CComBSTR bszFile=szFile;
.....
GenericHTTPClient *phttpClient=new GenericHTTPClient();
if(!phttpClient)
throw __ERR_NOTALLOCATEMEMORY;
phttpClient->InitializePostArguments();
phttpClient->AddPostArguments(__TAG_USRID, (LPCTSTR)(CString)bszAccount);
phttpClient->AddPostArguments(__TAG_JUMIN, (LPCTSTR)(CString)bszJumin);
phttpClient->AddPostArguments(__TAG_SRC, (LPCTSTR)(CString)bszSource);
phttpClient->AddPostArguments(__TAG_DST, (LPCTSTR)(CString)bszDest);
phttpClient->AddPostArguments(__TAG_FILE, (LPCTSTR)(CString)bszFile, TRUE);
....
if(phttpClient->Request(szURL, GenericHTTPClient::RequestPostMethod, __TAG_HTTP_AGENT)){
_szResponseCode=phttpClient->QueryHTTPResponse();
....
phttpClient->Close();
}
delete phttpClient;
this is my code, this code works fine.
what's your problem?
------------------------------
http://gooshin.zzem.net
|
|
|
|
|
Hi...
My problem is:
I define all my string variable using CString type...
& I wish to use that varable as for sending to AddPostArguments()
Now Question is How to pass these values....
e.g:-
//------------------------------------
CString File1,File2;
File1="uplFile1";
File2="C:\\Fax0.tif";
pClient->AddPostArguments(File1,File2, TRUE);
//------------------------------------------
pClient->AddPostArguments((LPCTSTR)File1,(LPCTSTR)File2, TRUE);
//--------------------------------------------
This is my problem...
Please help me How to pass Arguments to AddPostArguments()
Thanks..Sumit
Sumit Kapoor
|
|
|
|
|
when c/c++ invoke function or method, arguments is copyed.
invoking with class arguments is very heavy,
so AddPortArguments's prototype is "AddPostArguments(LPCTSTR, LPCTSTR, BOOL)"
if u want "AddPostArguments(CString, CString, BOOL)",
do overriding. AddPostArguments()!!!
VOID GenericHTTPClient::AddPostArguments(CString szName, CString szValue, BOOL bBinary){
AllocArgument(_pArguments, (LPCTSTR)szName, (LPCTSTR)szValue, bBinary);
return;
}
good luck..
------------------------------
http://gooshin.zzem.net
|
|
|
|
|
Thanks for help, Code is now working....
But one other doubt is still remain to solve...& u only can better know about this...
Doubt: If we have to send multiple files, then what to do with this code....
e.g.:- I want to upload two files to server...then is it fine to upload these files in separate request...I don't think this is right to send as separate request....
this means there may be any solution to send all two or more files data in one request...
Do u have any idea about this ( how to upload more than one file in a single request)
I hope u know this & share with me...
Thanks...Sumit
Sumit Kapoor
|
|
|
|
|
multiple file send is so very easy...
do you have been read RFC 1945(HTTP/1.0) and RFC 2068(HTTP/1.1) ?
when you send multiple files, you add only more "AddPostArguments()"
.....
AddPostArguments("file1", "d:\\tmp\\file1.dat");
AddPostArguments("file2", "d:\\tmp\\file2.day");
.....
good luck
------------------------------
http://gooshin.zzem.net
|
|
|
|
|
Hi..
That's great...Its Toooooo much easy..;)
I never expected u made it so easy...but u have done great.;)
Also, U have asked about reading:
--------------------------------------------
RFC 1945(HTTP/1.0) and RFC 2068(HTTP/1.1) ?
--------------------------------------------
Ans: I don't have much knowledge about these topic...But as any topic come to my use then I start search on that... this is happened in this case also....
I'm searching....
If have any special Tips,Tricks,Advice, or Suggestion....
U can share with me....
It's great for me to be guided by u...
Thanks again for suggestion of multiple files..
OK! Good Bye..Have a Nice Life..bye..Sumit
Sumit Kapoor
|
|
|
|
|
Hi Sumit,
Could you please give me entire source code for the above problem..i mean sending file to a server...I appreciate your help.
thanks
Christina
|
|
|
|
|
Dear author,
I found that it cause error when try to connect the https, the reason behind is that you haven't set the INTERNET_FLAG option to INTERNET_FLAG_SECURE in HttpOpenRequest.
Thx
Terry
|
|
|
|
|
Could you give an example of how to use your class to post a file?
-- Joel Parker
|
|
|
|
|
this is posting file example with multi-part form data
<br />
GenericHTTPClient *pClient=new GenericHTTPClient();<br />
<br />
pClient->InitilizePostArguments();<br />
pClient->AddPostArguments(__TAG_USRID, szUserID);<br />
pClient->AddPostArguments(__TAG_JUMIN, szSocialIndex);<br />
pClient->AddPostArguments(__TAG_SRC, szSource);<br />
pClient->AddPostArguments(__TAG_DST, szDestination); <br />
pClient->AddPostArguments(__TAG_FORMAT, szFormat);<br />
pClient->AddPostArguments(__TAG_SUBJECT, szMessage);<br />
<br />
if(bCharge){<br />
pClient->AddPostArguments(__TAG_CHARGE, "Y");<br />
}else{<br />
pClient->AddPostArguments(__TAG_CHARGE, "N");<br />
}<br />
pClient->AddPostArguments(__TAG_CPCODE, szCPCode);<br />
pClient->AddPostArguments(__TAG_FILE, szFile, TRUE);<br />
<br />
if(pClient->Request(szURL, GenericHTTPClient::RequestPostMethodMultiPartsFormData)){ <br />
LPCTSTR szResult=pClient->QueryHTTPResponse();<br />
}else{<br />
#ifdef _DEBUG<br />
LPVOID lpMsgBuffer;<br />
DWORD dwRet=FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,<br />
NULL,<br />
pClient->GetLastError(),<br />
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),<br />
reinterpret_cast<LPTSTR>(&lpMsgBuffer),<br />
0,<br />
NULL);<br />
OutputDebugString(reinterpret_cast<LPTSTR>(lpMsgBuffer));<br />
LocalFree(lpMsgBuffer);<br />
#endif<br />
}<br />
<br />
}<br />
thanks your concern.
------------------------------
http://gooshin.zzem.net
|
|
|
|
|