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

系统 2166 0
 

上一次说到通过 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_ 里,在这个缓冲区里保存了所有网络接收到的数据,那么这些数据又将要流向何方呢?下一次再来分析这个问题。

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


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论