您的位置:首页 > 其它

谷歌浏览器的源码分析(29)

2008-11-02 19:40 253 查看
上一次说到通过WinHTTP来接收网络数据,但没有具体介绍怎么样接收,现在就来分析这方面的代码。首先是通过函数WinHttpQueryHeaders来查询HTTP协议头的大小,接着还是通过函数WinHttpQueryHeaders把数据接收到缓冲区里。下面这段代码,就是做这样的事情:
#001 int HttpTransactionWinHttp::DidReceiveHeaders() {
#002 session_callback_->set_load_state(LOAD_STATE_IDLE);
#003

第一次调用函数WinHttpQueryHeaders查看接收到协议头的大小。[/b]
#004 DWORD size = 0;
#005 if (!WinHttpQueryHeaders(request_handle_,
#006 WINHTTP_QUERY_RAW_HEADERS,
#007 WINHTTP_HEADER_NAME_BY_INDEX,
#008 NULL,
#009 &size,
#010 WINHTTP_NO_HEADER_INDEX)) {
#011 DWORD error = GetLastError();
#012 if (error != ERROR_INSUFFICIENT_BUFFER) {
#013 DLOG(ERROR) << "WinHttpQueryHeaders failed: " << GetLastError();
#014 return TranslateLastOSError();
#015 }
#016 // OK, size should tell us how much to allocate...
#017 DCHECK(size > 0);
#018 }
#019

第二次调用函数WinHttpQueryHeaders来接收协议头的数据。[/b]
#020 std::wstring raw_headers;
#021
#022 // 'size' is the number of bytes rather than the number of characters.
#023 DCHECK(size % 2 == 0);
#024 if (!WinHttpQueryHeaders(request_handle_,
#025 WINHTTP_QUERY_RAW_HEADERS,
#026 WINHTTP_HEADER_NAME_BY_INDEX,
#027 WriteInto(&raw_headers, size/2 + 1),
#028 &size,
#029 WINHTTP_NO_HEADER_INDEX)) {
#030 DLOG(ERROR) << "WinHttpQueryHeaders failed: " << GetLastError();
#031 return TranslateLastOSError();
#032 }
#033

设置回应的一些状态。[/b]
#034 response_.response_time = Time::Now();
#035
#036 // From experimentation, it appears that WinHttp translates non-ASCII bytes
#037 // found in the response headers to UTF-16 assuming that they are encoded
#038 // using the default system charset. We attempt to undo that here.
#039 response_.headers =
#040 new HttpResponseHeaders(base::SysWideToNativeMB(raw_headers));
#041
#042 // WinHTTP truncates a response longer than 2GB. Perhaps it stores the
#043 // response's content length in a signed 32-bit integer. We fail rather
#044 // than reading a truncated response.
#045 if (response_.headers->GetContentLength() > 0x80000000)
#046 return ERR_FILE_TOO_BIG;
#047
#048 response_.vary_data.Init(*request_, *response_.headers);
#049 PopulateAuthChallenge();
#050
#051 // Unfortunately, WinHttp does not close the connection when a non-keepalive
#052 // response is _not_ followed by the server closing the connection. So, we
#053 // attempt to hack around this bug.
#054 if (!response_.headers->IsKeepAlive())
#055 content_length_remaining_ = response_.headers->GetContentLength();
#056
#057 return OK;
#058 }

通过上面的函数处理,就可以收到HTTP协议头的数据,这样就可以进一步处理了。那么接着下来就是收到HTTP协议里的数据,这个主要通过下面的函数来接收到的,如下:
#001 BOOL HttpTransactionWinHttp::SessionCallback::ReadData(
#002 HINTERNET request_handle) {
#003 DCHECK(bytes_available_ >= 0);
#004 char* buf = read_buf_;
#005 read_buf_ = NULL;
#006 int bytes_to_read = std::min(bytes_available_, read_buf_len_);
#007 read_buf_len_ = 0;
#008 if (!bytes_to_read)
#009 bytes_to_read = 1;
#010
#011 // Because of how WinHTTP fills memory when used asynchronously, Purify isn't
#012 // able to detect that it's been initialized, so it scans for 0xcd in the
#013 // buffer and reports UMRs (uninitialized memory reads) for those individual
#014 // bytes. We override that to avoid the false error reports.
#015 // See http://b/issue?id=1173916. #016 base::MemoryDebug::MarkAsInitialized(buf, bytes_to_read);
#017 return WinHttpReadData[/b](request_handle, buf, bytes_to_read, NULL);
#018 }
上面通过判断可以接收到多少字节,然后通过函数WinHttpReadData[/b]把数据保存到缓冲区read_buf_里,在这个缓冲区里保存了所有网络接收到的数据,那么这些数据又将要流向何方呢?下一次再来分析这个问题。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: