您的位置:首页 > 其它

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

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

#001 int HttpTransactionWinHttp::DidReceiveHeaders() {

#002 session_callback_->set_load_state(LOAD_STATE_IDLE);

#003

第一次调用函数WinHttpQueryHeaders查看接收到协议头的大小。

#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来接收协议头的数据。

#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

设置回应的一些状态。

#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(request_handle, buf, bytes_to_read, NULL);

#018 }

上面通过判断可以接收到多少字节,然后通过函数WinHttpReadData把数据保存到缓冲区read_buf_里,在这个缓冲区里保存了所有网络接收到的数据,那么这些数据又将要流向何方呢?下一次再来分析这个问题。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: