windows mobile下的wininet的使用2(整理后)
#pragma once
#include <vector>
#include <WinInet.h>
#include "NetDefine.h"
#define T_ACCEPT_ENCODING "Accept-Encoding"
#define T_CLIENTAGENT "Client-Agent"
#define T_CALLINGLINEID "x-up-calling-line-id"
#define T_APIVERSION "APIVersion"
#define T_USERID "user-id"
#define T_ACTION "Action"
#define T_COOKIE "Cookie"
#define T_CONTENTTYPE "Content-Type"
#define T_CLIENTTYPE "X-ClientType"
#define T_CONTENTLEN "Content-Length"
#define T_HOST "Host"
#define T_RESULT_CODE "result-code"
//一个CHttpSession为一个会话,只负责数据部分
class CHttpSession
{
public:
CHttpSession( CRequestBase& aRequest );
~CHttpSession();
public:
void SetHWnd( HWND aWnd );
HWND GetHWnd()
{
return m_hWnd;
}
//在调用Get函数时,需要网络返回完成消息才行
inline const char* GetRecvHead();
//获取返回的数据体
const char* GetRecvieData( )
{
return m_pRecvBuf;
}
//获取返回数据的长度
DWORD GetReceivedDataLen()
{
return m_dwRecvBodySize;
}
//获取返回码
int GetRetCode();
//获取返回数据头中的字段的值,返回字符串的指针需要自己删除
char* GetRetHeadValue( const char* aKey );
int GetResultCode()
{
char* szResultCode = GetRetHeadValue( T_RESULT_CODE );
if ( !szResultCode )
{
return -1;
}
int nResultCode = atoi( szResultCode );
FREEARRAYIF( szResultCode );
return nResultCode;
}
EM_RequestID GetRequestID()
{
return m_RequestID ;
}
//aRecvHead在函数内分配空间,调用者必须释放
BOOL RetrievingHeaders(HINTERNET hHttp);
//重置状态,在发起新的请求之前调用
//void Reset();
const char* GetHost()
{
return m_pHost;
}
int GetPort()
{
return m_pPort;
}
char* GetRequestBody()
{
return m_pRequestBody ;
}
int GetRequestBodyLen()
{
return m_dwRequestBodyLen;
}
const char* GetRequestUrl()
{
return m_pRequestUrl;
}
std::vector<char*>& GetRequestHeadVector()
{
return m_vtRequestHead;
}
protected:
//返回不包含http://和域名的
char* SetRequestUrl( const char* aUrl );
//添加请求头字符串
bool SetHeadValue( const char* aKey, const char* aValue );
//设置服务器地址
bool SetServer( const char* aServer );
//设置端口
bool SetPort( int aPort );
//设置请求数据,仅用于POST请求,GET请求无需使用
bool SetRequestData( const char* aData );
//设置请求头
bool SetRequestHead( NetMsgHead* pHead );
public:
HANDLE m_hThread; //下载子线程句柄
DWORD m_dwThreadID; //线程ID
HINTERNET hInstance;
HINTERNET hConnect;
HINTERNET hRequest;
HANDLE hEvent[3]; //0:句柄被创建事件或者读数据请求成功完成事件,1://句柄被关闭事件,2:用户要求终止子线程事件或者发生错误事件
char* m_pRecvHead; //接收到的数据头
char* m_pRecvBuf; //接收的缓存
DWORD m_dwRecvBodySize; //收到数据的总大小
DWORD m_dwMaxBuf; //接收数据缓存的总容器大小
DWORD m_dwStartPos; //当前缓存的偏移,已存放在缓存中的数据长度
protected:
std::vector<char*> m_vtRequestHead; //请求消息头的字符串
char* m_pRequestBody; //请求的消息体
DWORD m_dwRequestBodyLen; //请求消息体的长度
char* m_pHost; //服务器地址
int m_pPort; //端口
char* m_pRequestUrl; //请求URL地址
HWND m_hWnd; //用于接收网络通知的窗口句柄
EM_RequestID m_RequestID; //保留当前网络会话ID
};
class CAsyncWinINet
{
public:
static DWORD download( CHttpSession& aHttpSession );
protected:
static BOOL WaitExitEvent(CHttpSession *p);
static DWORD WINAPI AsyncThread(LPVOID lpParameter);
static VOID CALLBACK AsyncInternetCallback(HINTERNET hInternet,
DWORD dwContext,
DWORD dwInternetStatus,
LPVOID lpvStatusInformation,
DWORD dwStatusInformationLength);
};
#include "stdafx.h"
#include "HttpSession.h"
#include "Util.h"
#pragma comment(lib, "Wininet.lib")
HWND g_hWnd ;
#define CONNECTION_CONTEXT 1
#define REQUEST_CONTEXT 2
#define MAX_BODY_SIZE 10*1024
#define RECV_STEP 1024
DWORD CAsyncWinINet::download( CHttpSession& aHttpSession )
{
aHttpSession.m_hThread = CreateThread(NULL,
0,
CAsyncWinINet::AsyncThread,
&aHttpSession,
NULL,
&aHttpSession.m_dwThreadID);
if ( aHttpSession.m_hThread )
{
TraceLog( L"Create DownloadThread sucess, ThreadHandle = %d!\r\n", aHttpSession.m_dwThreadID );
}
//等待子线程安全退出
WaitForSingleObject(aHttpSession.m_hThread, INFINITE);
TraceLog( L"download Thread:%d exit!\r\n",aHttpSession.m_dwThreadID );
//关闭线程句柄
CloseHandle(aHttpSession.m_hThread);
return TRUE;
}
DWORD WINAPI CAsyncWinINet::AsyncThread(LPVOID lpParameter)
{
CHttpSession* pSession = (CHttpSession*)lpParameter;
pSession->hInstance = InternetOpenA( ""
,INTERNET_OPEN_TYPE_PRECONFIG
,NULL
,NULL
,INTERNET_FLAG_ASYNC);
if( !pSession->hInstance ) //有些手机用上面的参数访问不了Internet
pSession->hInstance = InternetOpenA( ""
,INTERNET_OPEN_TYPE_DIRECT
,NULL
,NULL
,INTERNET_FLAG_ASYNC);
if ( !pSession->hInstance )
{
TraceLog( L"InternetOpen failed, error : %d \r\n",GetLastError() );
return false;
}
TraceLog( L"InternetOpen suceess !\r\n");
// Setup callback function
//ResetEvent(p->hEvent[0]);
//p->hCallbackThread = CreateThread(NULL,
// 0,
// AsyncWinINet::AsyncCallbackThread,
// p,
// NULL,
// &p->dwCallbackThreadID);
//WaitForSingleObject(p->hEvent[0], INFINITE);//等待回调函数设置成功事件
if ( InternetSetStatusCallbackA( pSession->hInstance,CAsyncWinINet::AsyncInternetCallback )
== INTERNET_INVALID_STATUS_CALLBACK )
{
TraceLog( L"InternetSetStatusCallback failed, error : %d \r\n",GetLastError() );
return false;
}
TraceLog( L"InternetSetStatusCallback suceess :%d \r\n",GetLastError() );
// First call that will actually complete asynchronously even though there is no network traffic
pSession->hConnect = InternetConnectA( pSession->hInstance
,pSession->GetHost()
,pSession->GetPort()
,NULL
,NULL
,INTERNET_SERVICE_HTTP
,0
,(DWORD)pSession); // Connection handle's Context
if ( !pSession->hConnect )
{
TraceLog( L"hConnect == NULL, errno = %d \r\n ",GetLastError() );
if (GetLastError() != ERROR_IO_PENDING)
{
//TODO:退出线程
return false;
}
}
// Wait until we get the connection handle
//WaitForSingleObject( pSession->hEvent[0], INFINITE);
TraceLog( L"Ready To openRequest \r\n");
char* pRequestBody = pSession->GetRequestBody();
char* pVerb = !pRequestBody ? "GET" : "POST" ;
// Open the request
ResetEvent( pSession->hEvent[0] );
pSession->hRequest = HttpOpenRequestA(pSession->hConnect
,pVerb
,pSession->GetRequestUrl()
,NULL // HTTP version ,If this parameter is NULL, the function uses HTTP/1.1 as the version
,NULL // Reference
,NULL // A pointer to a null-terminated array of strings that indicates media types accepted by the client.
,INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_CACHE_WRITE
,(DWORD)pSession); // Request handle's context
// Wait until we get the request handle
//WaitForSingleObject( pSession->hEvent[0], INFINITE );
TraceLog( L"HttpOpenRequest Sucess\r\n" );
//Add Request HeadInfo
std::vector<char*> vtHead = pSession->GetRequestHeadVector();
for( unsigned int i = 0 ; i < vtHead.size(); i++ )
{
char* pItem = vtHead[i];
HttpAddRequestHeadersA(pSession->hRequest, pItem, -1, HTTP_ADDREQ_FLAG_ADD|HTTP_ADDREQ_FLAG_REPLACE );
}
int nRequestBodyLen = pSession->GetRequestBodyLen();
// Sends the specified request to the HTTP server.
//ResetEvent( pSession->hEvent[0] );
if ( !HttpSendRequestA( pSession->hRequest
,NULL // Pointer to a null-terminated string that contains the additional headers to be appended to the request.
,0 // Size of the additional headers
,pRequestBody // Pointer to a buffer containing any optional data to be sent immediately after the request headers.
,nRequestBodyLen )) // Size of the optional data, in bytes.
{
if (GetLastError() != ERROR_IO_PENDING)
{
TraceLog( L"HttpSendRequest failed, error = %d \r\n", GetLastError() );
return false;
}
}
TraceLog( L"HttpSendRequest Sucess \r\n" );
WaitForSingleObject( pSession->hEvent[0], INFINITE );
//receive Head
pSession->RetrievingHeaders( pSession->hRequest );
//网络错误处理:返回0为正常,非0为错误
int nResultCode = pSession->GetResultCode();
if ( nResultCode > 0 )
{
PostMessage(pSession->GetHWnd(), Event_NetError, nResultCode, NULL );
}
else
{
char lpReadBuff[RECV_STEP] ;
DWORD dwStartPos = 0;
while( true )
{
memset(lpReadBuff, 0, RECV_STEP);
INTERNET_BUFFERSA InetBuff;
FillMemory(&InetBuff, sizeof(InetBuff), 0);
InetBuff.dwStructSize = sizeof(InetBuff);
InetBuff.lpvBuffer = (LPVOID)lpReadBuff;
InetBuff.dwBufferLength = RECV_STEP;
TraceLog( L"Calling InternetReadFileExA \r\n" );
ResetEvent( pSession->hEvent[0] );
if ( !InternetReadFileExA(pSession->hRequest,&InetBuff,IRF_ASYNC, (DWORD)pSession) )
{
if (GetLastError() == ERROR_IO_PENDING)
{
TraceLog( L"Waiting for InternetReadFileEx to complete \r\n" );
if (WaitExitEvent(pSession)) break;
//WaitForSingleObject(pSession->hRequestCompleteEvent, INFINITE);
}
else
{
TraceLog( L"InternetReadFileEx failed, error :%d \r\n", GetLastError() );
return false;
}
}
else
{
//在网络传输速度快,步长较小的情况下,InternetReadFileEx 经常会直接返回成功,
//因此要判断是否发生了用户要求终止子线程事件。
if (WAIT_OBJECT_0 == WaitForSingleObject(pSession->hEvent[2], 0))
{
ResetEvent(pSession->hEvent[2]);
break;
}
}
TraceLog( L"InternetReadFileEx success! ReadBufLen = %d \r\n", InetBuff.dwBufferLength );
if (InetBuff.dwBufferLength == 0)
{
//TraceLog( L"RecvBuf Complete \r\n");
//bAllDone = TRUE;
//FILE *file;
//file = fopen( "\\a1.jpg", "wb" );
//int nwrite;
//if ( file )
//{
// nwrite = fwrite( m_pRecvBuf, 1, m_dwRecvBodySize, file);
//}
//fclose(file);
//Reset();
PostMessage(pSession->GetHWnd(), Event_NetState, INTERNET_STATUS_REQUEST_COMPLETE, NULL );
break;//接收数据完成,跳出循环
}
else
{
pSession->m_dwRecvBodySize += InetBuff.dwBufferLength;
if ( !pSession->m_pRecvBuf )
{
pSession->m_pRecvBuf = new char[MAX_BODY_SIZE];
memset( pSession->m_pRecvBuf, 0, MAX_BODY_SIZE );
pSession->m_dwMaxBuf = MAX_BODY_SIZE;
}
//剩余空间不足,重新分配空间
if ( pSession->m_dwMaxBuf - dwStartPos < InetBuff.dwBufferLength + 1)
{
TraceLog( L" Memspace is not enough!" );
char* pTempBuf = pSession->m_pRecvBuf;
pSession->m_pRecvBuf = new char[pSession->m_dwMaxBuf + MAX_BODY_SIZE];
memset( pSession->m_pRecvBuf, 0, pSession->m_dwMaxBuf + MAX_BODY_SIZE);
pSession->m_dwMaxBuf += MAX_BODY_SIZE;
memcpy( pSession->m_pRecvBuf, pTempBuf, dwStartPos);
delete[] pTempBuf;
pTempBuf = NULL;
}
TraceLog( L" Memspace is enough!" );
memcpy( pSession->m_pRecvBuf + dwStartPos, lpReadBuff, InetBuff.dwBufferLength );
TraceLog( L"InternetReadFileEx startPos = %d, curRecvLen = %d, totalSize = %d! \r\n", dwStartPos, InetBuff.dwBufferLength , pSession->m_dwRecvBodySize);
dwStartPos += InetBuff.dwBufferLength;
}
}
}
if( pSession->hRequest )
{
InternetCloseHandle( pSession->hRequest );//关闭 m_hFile
while (!WaitExitEvent( pSession )) //等待句柄被关闭事件或者要求子线程退出事件
{
ResetEvent( pSession->hEvent[0] );
}
}
//清理资源,结束子进程
//设置子线程退出事件,通知回调线程退出
SetEvent( pSession->hEvent[2] );
//注销回调函数
InternetSetStatusCallback( pSession->hInstance, NULL);
InternetCloseHandle( pSession->hInstance );
return TRUE;
}
BOOL CAsyncWinINet::WaitExitEvent(CHttpSession *aSession)
{
DWORD dwRet = WaitForMultipleObjects(3, aSession->hEvent, FALSE, INFINITE);
switch (dwRet)
{
case WAIT_OBJECT_0://句柄被创建事件或者读数据请求成功完成事件
case WAIT_OBJECT_0+1://句柄被关闭事件
case WAIT_OBJECT_0+2://用户要求终止子线程事件或者发生错误事件
break;
}
return WAIT_OBJECT_0 != dwRet;
}
VOID CALLBACK CAsyncWinINet::AsyncInternetCallback(HINTERNET hInternet,
DWORD dwContext,
DWORD dwInternetStatus,
LPVOID lpvStatusInformation,
DWORD dwStatusInformationLength)
{
CHttpSession* pSession = (CHttpSession*)dwContext;
//在我们的应用中,我们只关心下面三个状态
switch(dwInternetStatus)
{
//句柄被创建
case INTERNET_STATUS_HANDLE_CREATED:
{
INTERNET_ASYNC_RESULT *pRes = (INTERNET_ASYNC_RESULT *)lpvStatusInformation;
pSession->hConnect = (HINTERNET)pRes->dwResult;
TraceLog( L"Connect handle created \r\n");
SetEvent( pSession->hConnect );
break;
}
//句柄被关闭
case INTERNET_STATUS_HANDLE_CLOSING:
SetEvent( pSession->hEvent[1] );
break;
//一个请求完成,比如一次句柄创建的请求,或者一次读数据的请求
case INTERNET_STATUS_REQUEST_COMPLETE:
if (ERROR_SUCCESS == ((LPINTERNET_ASYNC_RESULT)
(lpvStatusInformation))->dwError)
{
//设置句柄被创建事件或者读数据成功完成事件
SetEvent( pSession->hEvent[0] );
}
else
{
//如果发生错误,则设置子线程退出事件 这里也是一个陷阱,经常会忽视处理这个错误,
SetEvent( pSession->hEvent[2] );
}
break;
case INTERNET_STATUS_CONNECTION_CLOSED:
SetEvent( pSession->hEvent[2] );
break;
}
};
CHttpSession::CHttpSession( CRequestBase& aRequest )
:m_pRequestBody(NULL),m_pHost(NULL), m_pRequestUrl( NULL ),m_pRecvBuf(NULL),m_pRecvHead(NULL)
,m_dwRecvBodySize(0), m_dwMaxBuf(0) ,m_dwStartPos(0),m_dwRequestBodyLen(0), m_hWnd(0),m_RequestID(EM_Req_Start)
,m_dwThreadID(0),m_hThread(0)
{
m_vtRequestHead.clear();
for(int i = 0; i < 3; ++i)
{
hEvent[i] = CreateEvent(NULL,TRUE,FALSE,NULL);
}
NetMsgHead* pHead = aRequest.GetRequestHead();
if ( !SetRequestHead(pHead) )
return ;
const char* pHost = pHead->GetHost();
SetServer( pHost );
int port = pHead->GetPort();
SetPort( port );
const char* pRequestURL = aRequest.GetUrl();
m_pRequestUrl = SetRequestUrl( pRequestURL );
m_RequestID = aRequest.GetRequestID();
bool bPost = aRequest.GetIsPostMsg();
if ( bPost )
{
const char* pData = (( CPostRsqBase* )&aRequest)->GetRequestBody();
SetRequestData( pData );
}
else
{
SetRequestData( NULL );
}
}
CHttpSession::~CHttpSession()
{
FREEARRAYIF( m_pRequestBody );
FREEARRAYIF( m_pHost );
FREEARRAYIF( m_pRequestUrl );
FREEARRAYIF( m_pRecvBuf );
FREEARRAYIF( m_pRecvHead );
if(hConnect)
{
InternetCloseHandle(hConnect);
hConnect = NULL;
}
if(hInstance)
{
//卸载回调
InternetSetStatusCallback(hInstance,NULL);
InternetCloseHandle(hInstance);
hInstance=NULL;
}
if(hRequest)
{
InternetCloseHandle(hRequest);
hRequest = NULL;
}
for ( int i = 0 ; i < 3; i++ )
{
if ( hEvent[i] )
{
CloseHandle(hEvent[i]);
hEvent[i] = NULL;
}
}
}
// void CHttpSession::Reset()
// {
// FREEARRAYIF( m_pRequestBody );
// FREEARRAYIF( m_pHost );
// FREEARRAYIF( m_pRequestUrl );
// FREEARRAYIF( m_pRecvBuf );
// FREEARRAYIF( m_pRecvHead );
//
// m_dwRecvBodySize = 0;
// m_dwMaxBuf = 0;
// m_dwStartPos = 0;
// m_dwRequestBodyLen = 0;
// m_RequestID = EM_Req_Start;
// m_pPort = 0;
//
// if(hConnect)
// {
// InternetCloseHandle(hConnect);
// hConnect = NULL;
// }
//
// if(hInstance)
// {
// //卸载回调
// InternetSetStatusCallback(hInstance,NULL);
// InternetCloseHandle(hInstance);
// hInstance=NULL;
// }
//
// if(hRequest)
// {
// InternetCloseHandle(hRequest);
// hRequest = NULL;
// }
//
// for ( int i = 0 ; i < 3; i++ )
// {
// if ( hEvent[i] )
// {
// CloseHandle(hEvent[i]);
// hEvent[i] = NULL;
// }
// }
//
// //if(hRequestCompleteEvent)
// //{
// // CloseHandle(hRequestCompleteEvent);
// // hRequestCompleteEvent = NULL;
// //}
// //
// //if(hConnectedEvent)
// //{
// // CloseHandle(hConnectedEvent);
// // hConnectedEvent = NULL;
// //}
// //
// //if(hRequestOpenedEvent)
// //{
// // CloseHandle(hRequestOpenedEvent);
// // hRequestOpenedEvent = NULL;
// //}
//
// for ( unsigned int i = 0 ; i < m_vtRequestHead.size(); i++ )
// {
// char* pItem = m_vtRequestHead[i];
// FREEARRAYIF( pItem );
// }
// m_vtRequestHead.clear();
// }
//
void CHttpSession::SetHWnd( HWND aWnd )
{
m_hWnd = aWnd;
g_hWnd = aWnd;
}
bool CHttpSession::SetHeadValue( const char* aKey, const char* aValue )
{
if ( !aKey )
return false;
char* buf = new char[256];
memset( buf, 0, 256 );
sprintf( buf, "%s: %s\r\n", aKey, aValue );
m_vtRequestHead.push_back( buf );
return true;
}
bool CHttpSession::SetRequestData( const char* aData )
{
if( !aData )
return false;
m_pRequestBody = new char[strlen( aData ) + 1];
memset( m_pRequestBody, 0, strlen( aData ) + 1 );
memcpy( m_pRequestBody, aData, strlen( aData ) );
m_dwRequestBodyLen = strlen( aData );
return true;
}
bool CHttpSession::SetServer( const char* aServer )
{
if( !aServer )
return false;
m_pHost = new char[strlen( aServer ) + 1 ];
memset( m_pHost, 0, strlen( aServer ) + 1 );
memcpy( m_pHost, aServer, strlen( aServer ) );
return true;
}
char* CHttpSession::SetRequestUrl( const char* aUrl )
{
if( !aUrl )
return false;
const char* pUrl = aUrl;
//检查是否存在http://
const char* pUrlHead = "http://";
char* pTemp = strstr( pUrl, pUrlHead );
char* pResult = NULL;
//在开始处
if ( pTemp )
{
if( pTemp == pUrl )
{
pTemp += strlen( pUrlHead );
//查找第一个 "/",去掉域名
pTemp = strstr( pTemp, "/" );
if ( !pTemp )
{
return NULL;
}
pResult = new char[ strlen( pTemp ) + 1 ] ;
memset( pResult, 0, strlen( pTemp ) + 1 );
memcpy( pResult, pTemp, strlen( pTemp ) );
return pResult;
}
}
else
{
//没有找到
pResult = new char[ strlen( pUrl ) + 1 ] ;
memset( pResult, 0, strlen( pUrl ) + 1 );
memcpy( pResult, pUrl, strlen( pUrl ) );
return pResult;
}
return pResult;
}
bool CHttpSession::SetPort( int aPort )
{
if ( aPort < 0 )
{
return false;
}
m_pPort = aPort;
return true;
}
bool CHttpSession::SetRequestHead( NetMsgHead* pHead )
{
if( !pHead )
return false;
const char* pszBuf = pHead->GetAcceptEncoding();
SetHeadValue( T_ACCEPT_ENCODING, pszBuf );
pszBuf = pHead->GetClientAgent();
SetHeadValue( T_CLIENTAGENT, pszBuf );
pszBuf = pHead->GetCallingLineID();
SetHeadValue( T_CALLINGLINEID, pszBuf );
pszBuf = pHead->GetApiVersion();
SetHeadValue( T_APIVERSION, pszBuf );
pszBuf = pHead->GetContentType();
SetHeadValue( T_CONTENTTYPE, pszBuf );
pszBuf = pHead->GetXClientType();
SetHeadValue( T_CLIENTTYPE, pszBuf );
pszBuf = pHead->GetUserid();
SetHeadValue( T_USERID, pszBuf );
pszBuf = pHead->GetCookie();
SetHeadValue( T_COOKIE, pszBuf );
pszBuf = pHead->GetAction();
SetHeadValue( T_ACTION, pszBuf );
return true;
}
BOOL CHttpSession::RetrievingHeaders( HINTERNET hHttp )
{
//LPVOID lpOutBuffer=NULL;
DWORD dwSize = 0;
retry:
// This call will fail on the first pass, because no buffer is allocated.
if(!HttpQueryInfoA(
hHttp,
HTTP_QUERY_RAW_HEADERS_CRLF,
(LPVOID)m_pRecvHead,
&dwSize,
NULL))
{
if (GetLastError()==ERROR_HTTP_HEADER_NOT_FOUND)
{
TraceLog( L"HttpQueryInfo error : ERROR_HTTP_HEADER_NOT_FOUND \r\n" );
// Code to handle the case where the header isn't available.
return TRUE;
}
else
{
// Check for an insufficient buffer.
if ( GetLastError()==ERROR_INSUFFICIENT_BUFFER )
{
TraceLog( L"HttpQueryInfo error : ERROR_HTTP_HEADER_NOT_FOUND \r\n" );
m_pRecvHead = new char[dwSize];
// Retry the call.
goto retry;
}
else
{
TraceLog( L"HttpQueryInfo error : %d \r\n", GetLastError() );
// Error handling code.
if (m_pRecvHead)
{
delete [] m_pRecvHead;
}
return FALSE;
}
}
}
TraceLog( L"HttpQueryInfo sucess lpOutBuffer = %s\r\n", m_pRecvHead );
return TRUE;
}
int CHttpSession::GetRetCode()
{
if ( !m_pRecvHead )
{
return -1;
}
//寻找第一个空格
char* pRet1 = strstr( m_pRecvHead, " " );
if ( !pRet1 )
{
return -1;
}
char* pStart = pRet1 + 1;
char* pRet2 = strstr( pStart, " " );
if ( !pRet2 )
{
return -1;
}
int nLen = pRet2 - pStart;
char* pRetCode = new char[nLen + 1];
memset( pRetCode, 0, nLen + 1);
memcpy( pRetCode, pStart, nLen );
int nRet = atoi( pRetCode );
FREEARRAYIF( pRetCode );
return nRet;
}
char* CHttpSession::GetRetHeadValue( const char* aKey )
{
if ( !m_pRecvHead )
{
return NULL;
}
//寻找key
char* pResult1 = strstr( m_pRecvHead, aKey );
if ( !pResult1 )
{
return NULL;
}
pResult1 = strstr( pResult1, ": " );
if ( !pResult1 )
{
return NULL;
}
pResult1 += strlen( ": " );
char* pResult2 = strstr( pResult1, "\r\n" );
int nValueLen = pResult2 - pResult1 ;
char* pRet = new char[nValueLen + 1];
memset( pRet, 0, nValueLen + 1 );
memcpy( pRet, pResult1, nValueLen );
return pRet;
}
const char* CHttpSession::GetRecvHead()
{
return m_pRecvHead;
}