公司的考勤系统有两套,一套是门卡打卡上班,另一套是计算机登陆考勤网站上班。像我这样成天乘公交上班的人,不知道什么时候一堵车就迟到了。因此无聊加无奈,才写了下面的程序。。。。
首先考察一下门卡系统。因为要刷卡才能上班,刷卡数据保存在公司linux服务器上,没啥手脚可以动。于是转向网站考勤系统。这个网站是用jsp写得,于是打算用EffeTech HTTP Sniffer侦查一下。本来以为需要很费劲的,其实嗅探下来结果非常简单,登陆请求就是用URL rewrite技术包装的。把这个url请求截获之后,就可以开始模拟请求了。用啥语言呢,java中可以直接用socket发请求,但是win32的Platform Sdk中有更高层的HTTP协议包装——winhttp。于是就简单地设计了下面的请求发送类
//-----------------------------------------------------------------------
// Name: class CMyWinHttp
// Desc: Connect to the web server, process the interaction based on http
//-----------------------------------------------------------------------
class CMyWinHttp
{
HINTERNET m_hSession;
HINTERNET m_hConnect;
HINTERNET m_hRequest;
public:
CMyWinHttp();
INT Init();
VOID Close();
BOOL ProcessOneRequest(LPCWSTR pwszObjectName);
};
构造函数就不说了,反正是初始化成员变量为NULL。Init函数比较简单,其中HOST和PORT就是服务器IP和80端口。
///---------------------------------------------------------------
/// DESC: Init the connection
/// Unless the host/port/user-agent changes...
///---------------------------------------------------------------
INT CMyWinHttp::Init()
{
// Use WinHttpOpen to obtain a session handle.
m_hSession = WinHttpOpen( USER_AGENT,
WINHTTP_ACCESS_TYPE_NO_PROXY,
WINHTTP_NO_PROXY_NAME,
WINHTTP_NO_PROXY_BYPASS, 0 );
// Specify an HTTP server.
if( m_hSession )
m_hConnect = WinHttpConnect( m_hSession,
HOST,
PORT, 0 );
if ( m_hConnect )
return 0;
return GetLastError();
}
Close()函数也不说了,关闭一些句柄。对生成和发送Get请求的包装处理如下:
BOOL CMyWinHttp::ProcessOneRequest(LPCWSTR pwszObjectName)
{
DWORD dwSize = 0;
DWORD dwDownloaded = 0;
LPSTR pszOutBuffer;
BOOL bResults = FALSE;
// Create an HTTP request handle.
if( m_hConnect )
m_hRequest = WinHttpOpenRequest( m_hConnect,
L"GET",
pwszObjectName,
NULL,
WINHTTP_NO_REFERER,
WINHTTP_DEFAULT_ACCEPT_TYPES,
0 );
// Send a request.
if( m_hRequest )
bResults = WinHttpSendRequest( m_hRequest,
ADDITIONAL, -1L,
WINHTTP_NO_REQUEST_DATA, 0,
0, 0 );
// End the request.
if( bResults )
bResults = WinHttpReceiveResponse( m_hRequest, NULL );
// Keep checking for data until there is nothing left.
if( bResults )
{
do
{
// Check for available data.