Are there methods already existing to get these classes to do this
behind the scenes as it does with "Transfer-Encoding: chunked"? (I
realize that Content-Encoding and Transfer-Encoding are not the same.)
If there aren't built-in methods for these classes, then it seems the
following steps are necessary. I don't want to re-invent the wheel, so
if anyone knows of example code for this please point me in that direction.
I can use the CHttpFile::AddRequestHeaders method to add
"Accept-Encoding: gzip, deflate\r\n", but the data is returned to my
program compressed because CHttpFile doesn't decompress it. To
decompress the returned data, I expect I need to link in a function that
implements the deflate method, give it access to the CString's memory
buffer and have it stick the deflated data somewhere else so that I can
then do my processing.
I see that IE can decompress gzip encoded content, so I would expect
some DLL or class on MS Windows to have the zlib deflate methods. All I
can find references to are WFC for Java. If there are API/VC/MFC methods
already to deflate a gzip stream, I would prefer to use those. If there
aren't, I guess I'll need to have my own copy of zlib1.dll.
Any examples or pointers for where to look are appreciated.
--
Jacob Anawalt
I haven't found any such methods and am surprised that the Internet
Client SDK doesn't expose them since IE clearly sends "Accept-Encoding:
gzip, deflate" and handles "Content-Encoding: gzip" responses. I am just
as surprised that there are no code examples to do this floating around.
I have moved forward and attempted to create gzip enabled methods by
overriding CHttpFile (and thus CHttpConnection and CHttpInternetSession)
and linking to zlib1.lib.
I have put all of these overrides into one definition and one
implementation file. It compiles into an object file, but when I link it
into my program the compiler says:
AfxInetGzip.obj : error LNK2001: unresolved external symbol "protected:
static char const * const * const CHttpConnection::szHtmlVerbs"
(?szHtmlVerbs@CHttpConnection@@1QBQBDB)
The LNK2001 help page suggests that I should move the const
initialization into a header file and only include that header in the
implementation files that need it. Since CHttpConnection::szHtmlVerbs is
defined in INET.H, all I think I can do about this is juggle where I
include afxinet.h, which I have done as liberally as I can think.
Here is the class definition of CHttpConnectionGzip. Hopefully it comes
across correctly.
class CHttpConnectionGzip : public CHttpConnection
{
public:
CHttpConnectionGzip(CInternetSessionGzip* pSession, HINTERNET hConnected,
LPCTSTR pstrServer, DWORD dwContext);
CHttpConnectionGzip(CInternetSessionGzip* pSession, LPCTSTR pstrServer,
INTERNET_PORT nPort = INTERNET_INVALID_PORT_NUMBER,
LPCTSTR pstrUserName = NULL, LPCTSTR pstrPassword = NULL,
DWORD dwContext = 1);
CHttpConnectionGzip(CInternetSessionGzip* pSession, LPCTSTR pstrServer,
DWORD dwFlags, INTERNET_PORT nPort = INTERNET_INVALID_PORT_NUMBER,
LPCTSTR pstrUserName = NULL, LPCTSTR pstrPassword = NULL,
DWORD dwContext = 1);
CHttpFileGzip* OpenRequestGzip(LPCTSTR pstrVerb, LPCTSTR pstrObjectName,
LPCTSTR pstrReferer = NULL,DWORD dwContext = 1,
LPCTSTR* ppstrAcceptTypes = NULL, LPCTSTR pstrVersion = NULL,
DWORD dwFlags = INTERNET_FLAG_EXISTING_CONNECT);
CHttpFileGzip* OpenRequestGzip(int nVerb, LPCTSTR pstrObjectName,
LPCTSTR pstrReferer = NULL, DWORD dwContext = 1,
LPCTSTR* ppstrAcceptTypes = NULL, LPCTSTR pstrVersion = NULL,
DWORD dwFlags = INTERNET_FLAG_EXISTING_CONNECT);
// implementation
~CHttpConnectionGzip();
public:
friend class CInternetSessionGzip; // just to access szHtmlVerbs
//DECLARE_DYNAMIC(CHttpConnectionGzip)
};
If I include the DECLARE_DYNAMIC and IMPLEMENT_DYNAMIC macros, then the
expansion of the IMPLEMENT_DYNAMIC macros also give link errors.
I imagine that I'm making some glaringly obvious mistake and would
appreciate having it pointed out.
--
Jacob
That was a silly mistake. szHtmlVerbs is only defined in INET.CPP. I was
using it in CHttpConnectionGzip::OpenRequestGzip. I didn't call the
parent to handle this because I wanted my OpenRequestGzip to be called
and not just the parent's OpenRequest. I've defined szHtmlVerbs in my
implementation file and it works (until INET.CPP changes szHttpVerbs.)
Any suggestions for a better way to handle this are welcome.
Now for the DECLARE_DYNAMIC and IMPLEMENT_DYNAMIC issues. I believe I
can live without these for my needs, but it irks me that I'm doing
something wrong so that these don't work:
AfxInetGzip.obj : error LNK2001: unresolved external symbol
"__declspec(dllimport) public: static struct CRuntimeClass const
CHttpFile::classCHttpFile"
(__imp_?classCHttpFile@CHttpFile@@2UCRuntimeClass@@B)
AfxInetGzip.obj : error LNK2001: unresolved external symbol
"__declspec(dllimport) public: static struct CRuntimeClass const
CInternetSession::classCInternetSession"
(__imp_?classCInternetSession@CInternetSession@@2UCRuntimeClass@@B)
AfxInetGzip.obj : error LNK2001: unresolved external symbol
"__declspec(dllimport) public: static struct CRuntimeClass const
CHttpConnection::classCHttpConnection"
(__imp_?classCHttpConnection@CHttpConnection@@2UCRuntimeClass@@B)
I've compared my code to many many other examples of
overriding/extending MFC classes and am puzzled on this one. Here are my
declare (pulled from their respective class declarations) and my
implement statements from my implementation file:
DECLARE_DYNAMIC(CInternetSessionGzip)
DECLARE_DYNAMIC(CHttpConnectionGzip)
DECLARE_DYNAMIC(CHttpFileGzip)
IMPLEMENT_DYNAMIC(CHttpFileGzip, CHttpFile)
IMPLEMENT_DYNAMIC(CInternetSessionGzip, CInternetSession)
IMPLEMENT_DYNAMIC(CHttpConnectionGzip, CHttpConnection)
I'm probably not doing the right thing with AFX_DATA.
--
Jacob