1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
#include "WinHttpRewindInputStream.hpp"
#include "WinHttpFetcher.hpp"
#include "SpoolRewindInputStream.hpp"
#include "win32/errormsg.hpp"
#include "win32/stringutils.hpp"
using namespace std;
class winhttp_buffer : public spool_streambuf
{
public:
explicit winhttp_buffer( HINTERNET connect, HINTERNET request, size_t bufSize = 256, size_t putBack = 1, size_t spoolBufSize = 8192 );
protected:
virtual streambuf::int_type readFromSource( );
private:
HINTERNET m_connect;
HINTERNET m_request;
};
winhttp_buffer::winhttp_buffer( HINTERNET connect, HINTERNET request, size_t bufSize, size_t putBack, size_t spoolBufSize )
: spool_streambuf( bufSize, putBack, spoolBufSize ),
m_connect( connect ), m_request( request )
{
}
streambuf::int_type winhttp_buffer::readFromSource( )
{
DWORD avail = 0;
if( !WinHttpQueryDataAvailable( m_request, &avail ) ) {
// TODO error handling
return traits_type::eof( );
}
if( avail == 0 ) {
return traits_type::eof( );
}
DWORD n;
DWORD size = min( avail, m_buf.size( ) - ( m_start - m_base ) );
if( !WinHttpReadData( m_request, (LPVOID)m_start, size, &n ) ) {
// TODO error handling
return traits_type::eof( );
}
return n;
}
WinHttpRewindInputStream::WinHttpRewindInputStream( const URL &url, WinHttpFetcher *fetcher )
: SpoolRewindInputStream( url ), m_fetcher( fetcher ), m_connect( 0 ), m_request( 0 )
{
m_connect = WinHttpConnect( m_fetcher->session( ), s2ws( url.host( ) ).c_str( ),
INTERNET_DEFAULT_HTTP_PORT, 0 );
if( !m_connect ) {
setstate( badbit );
return;
}
m_request = WinHttpOpenRequest( m_connect, L"GET", s2ws( url.path( ) ).c_str( ),
NULL, WINHTTP_NO_REFERER, NULL, NULL );
if( !m_request ) {
setstate( badbit );
return;
}
if( !WinHttpSendRequest( m_request, WINHTTP_NO_ADDITIONAL_HEADERS,
0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0 ) ) {
setstate( badbit );
return;
}
if( !WinHttpReceiveResponse( m_request, NULL ) ) {
setstate( badbit );
return;
}
m_buf = new winhttp_buffer( m_connect, m_request );
rdbuf( m_buf );
}
WinHttpRewindInputStream::~WinHttpRewindInputStream( )
{
if( m_buf ) delete m_buf;
if( m_request ) WinHttpCloseHandle( m_request );
if( m_connect ) WinHttpCloseHandle( m_connect );
}
std::string WinHttpRewindInputStream::lastErrMsg( ) const
{
return getLastError( );
}
|