chromium中FTP网络资源的加载

FTP网络资源的加载

render进程的处理

我们在浏览器地址中输入ftp://ftp.sjtu.edu.cn/,来请求ftp数据。 
此时windbg会中断,因为浏览器启动了一个render进程来渲染绘制。我们在render进程中如下下断

 bu chrome_child!content::ResourceDispatcher::StartAsync
 
 
  • 1
  • 1

这个函数由render进程调用,用来和browser进程通信,通知browser来加载网络资源

int ResourceDispatcher::StartAsync(const RequestInfo& request_info,
                                   ResourceRequestBody* request_body,
                                   scoped_ptr<RequestPeer> peer) {
  GURL frame_origin;
  scoped_ptr<ResourceHostMsg_Request> request =
      CreateRequest(request_info, request_body, &frame_origin);

  // Compute a unique request_id for this renderer process.
  int request_id = MakeRequestID();
  pending_requests_[request_id] = make_scoped_ptr(new PendingRequestInfo(
      std::move(peer), request->resource_type, request->origin_pid,
      frame_origin, request->url, request_info.download_to_file));

  if (resource_scheduling_filter_.get() &&
      request_info.loading_web_task_runner) {
    resource_scheduling_filter_->SetRequestIdTaskRunner(
        request_id,
        make_scoped_ptr(request_info.loading_web_task_runner->clone()));
  }

  message_sender_->Send(new ResourceHostMsg_RequestResource(
      request_info.routing_id, request_id, *request));

  return request_id;
}

 
 
  • 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
  • 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

通知browser进程的消息是ResourceHostMsg_RequestResource,我们来看一下render进程的调用情况

8:010> kc
 # Call Site
00 chrome_child!content::ResourceDispatcher::StartAsync
01 chrome_child!content::WebURLLoaderImpl::Context::Start
02 chrome_child!blink::ResourceLoader::start
03 chrome_child!blink::Resource::load
04 chrome_child!blink::ResourceFetcher::requestResource
05 chrome_child!blink::RawResource::fetchMainResource
06 chrome_child!blink::DocumentLoader::startLoadingMainResource
07 chrome_child!blink::FrameLoader::startLoad
08 chrome_child!blink::FrameLoader::load
09 chrome_child!blink::WebLocalFrameImpl::load
0a chrome_child!content::RenderFrameImpl::NavigateInternal
0b chrome_child!content::RenderFrameImpl::OnNavigate
0c chrome_child!base::DispatchToMethodImpl
0d chrome_child!base::DispatchToMethod
0e chrome_child!IPC::DispatchToMethod
0f chrome_child!IPC::MessageT<FrameMsg_Navigate_Meta,std::tuple<content::CommonNavigationParams,content::StartNavigationParams,content::RequestNavigationParams>,void>::Dispatch<content::RenderFrameImpl,content::RenderFrameImpl,void,void (__cdecl content::RenderFrameImpl::*)(content::CommonNavigationParams const & __ptr64,content::StartNavigationParams const & __ptr64,content::RequestNavigationParams const & __ptr64) __ptr64>
10 chrome_child!content::RenderFrameImpl::OnMessageReceived
11 chrome_child!IPC::MessageRouter::RouteMessage
12 chrome_child!content::ChildThreadImpl::OnMessageReceived
13 chrome_child!IPC::ChannelProxy::Context::OnDispatchMessage
14 chrome_child!base::Callback<void __cdecl(void)>::Run
15 chrome_child!base::debug::TaskAnnotator::RunTask
16 chrome_child!scheduler::TaskQueueManager::ProcessTaskFromWorkQueue
17 chrome_child!scheduler::TaskQueueManager::DoWork
18 chrome_child!base::internal::RunnableAdapter<void (__cdecl scheduler::TaskQueueManager::*)(base::TimeTicks,bool)>::Run
19 chrome_child!base::internal::InvokeHelper<1,void,base::internal::RunnableAdapter<void (__cdecl scheduler::TaskQueueManager::*)(base::TimeTicks,bool) __ptr64> >::MakeItSo<base::WeakPtr<scheduler::TaskQueueManager>,base::TimeTicks const & __ptr64,bool const & __ptr64>
1a chrome_child!base::internal::Invoker<base::IndexSequence<0,1,2>,base::internal::BindState<base::internal::RunnableAdapter<void (__cdecl scheduler::TaskQueueManager::*)(base::TimeTicks,bool) __ptr64>,void __cdecl(scheduler::TaskQueueManager * __ptr64,base::TimeTicks,bool),base::WeakPtr<scheduler::TaskQueueManager>,base::TimeTicks,bool>,base::internal::InvokeHelper<1,void,base::internal::RunnableAdapter<void (__cdecl scheduler::TaskQueueManager::*)(base::TimeTicks,bool) __ptr64> >,void __cdecl(void)>::Run
1b chrome_child!base::Callback<void __cdecl(void)>::Run
1c chrome_child!base::debug::TaskAnnotator::RunTask
1d chrome_child!base::MessageLoop::RunTask
1e chrome_child!base::MessageLoop::DeferOrRunPendingTask
1f chrome_child!base::MessageLoop::DoWork
20 chrome_child!base::MessagePumpDefault::Run
21 chrome_child!base::MessageLoop::RunHandler
22 chrome_child!base::RunLoop::Run
23 chrome_child!base::MessageLoop::Run
24 chrome_child!content::RendererMain
25 chrome_child!content::RunNamedProcessTypeMain
26 chrome_child!content::ContentMainRunnerImpl::Run
27 chrome_child!content::ContentMain
28 chrome_child!ChromeMain
29 chrome!MainDllLoader::Launch
2a chrome!wWinMain
2b chrome!__tmainCRTStartup
2c kernel32!BaseThreadInitThunk
2d ntdll!RtlUserThreadStart

 
 
  • 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
  • 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

从上面可以看出,这是通过blink模块进行资源加载,而实际的任务通过browser进程。

browser进程的处理

ResourceLoader

我们到browser进程中的相应函数中下断,看看browser如何进行实际的资源加载和网络访问的。

 bp chrome_7feee760000!content::ResourceDispatcherHostImpl::OnRequestResource
 
 
  • 1
  • 1

下断后,运行,中断。

0:019> kc
 # Call Site
00 chrome_7feee760000!content::ResourceLoader::StartRequest
01 chrome_7feee760000!content::ResourceDispatcherHostImpl::StartLoading
02 chrome_7feee760000!content::ResourceDispatcherHostImpl::BeginRequestInternal
03 chrome_7feee760000!content::ResourceDispatcherHostImpl::BeginRequest
04 chrome_7feee760000!content::ResourceDispatcherHostImpl::OnRequestResource
05 chrome_7feee760000!base::DispatchToMethodImpl
06 chrome_7feee760000!base::DispatchToMethod
07 chrome_7feee760000!IPC::DispatchToMethod
08 chrome_7feee760000!IPC::MessageT<ResourceHostMsg_RequestResource_Meta,std::tuple<int,int,ResourceHostMsg_Request>,void>::Dispatch<content::ResourceDispatcherHostImpl,content::ResourceDispatcherHostImpl,void,void (__cdecl content::ResourceDispatcherHostImpl::*)(int,int,ResourceHostMsg_Request const & __ptr64) __ptr64>
09 chrome_7feee760000!content::ResourceDispatcherHostImpl::OnMessageReceived
0a chrome_7feee760000!content::BrowserMessageFilter::Internal::DispatchMessageW
0b chrome_7feee760000!content::BrowserMessageFilter::Internal::OnMessageReceived
0c chrome_7feee760000!IPC::`anonymous namespace'::TryFiltersImpl
0d chrome_7feee760000!IPC::MessageFilterRouter::TryFilters
0e chrome_7feee760000!IPC::ChannelProxy::Context::TryFilters
0f chrome_7feee760000!IPC::ChannelProxy::Context::OnMessageReceived
10 chrome_7feee760000!IPC::internal::ChannelReader::DispatchMessageW
11 chrome_7feee760000!IPC::internal::ChannelReader::HandleExternalMessage
12 chrome_7feee760000!IPC::internal::ChannelReader::HandleTranslatedMessage
13 chrome_7feee760000!IPC::internal::ChannelReader::TranslateInputData
14 chrome_7feee760000!IPC::internal::ChannelReader::AsyncReadComplete
15 chrome_7feee760000!IPC::ChannelWin::OnIOCompleted
16 chrome_7feee760000!base::MessagePumpForIO::WaitForIOCompletion
17 chrome_7feee760000!base::MessagePumpForIO::DoRunLoop
18 chrome_7feee760000!base::MessagePumpWin::Run
19 chrome_7feee760000!base::MessageLoop::RunHandler
1a chrome_7feee760000!base::RunLoop::Run
1b chrome_7feee760000!base::MessageLoop::Run
1c chrome_7feee760000!base::Thread::Run
1d chrome_7feee760000!content::BrowserThreadImpl::IOThreadRun
1e chrome_7feee760000!content::BrowserThreadImpl::Run
1f chrome_7feee760000!base::Thread::ThreadMain
20 chrome_7feee760000!base::`anonymous namespace'::ThreadFunc
21 kernel32!BaseThreadInitThunk
22 ntdll!RtlUserThreadStart
 
 
  • 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
  • 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

如上的堆栈示意,这是位于IO线程中,通过IPC的完成端口接收到来自render进程的消息,然后分发这个消息,遇到了浏览器的BrowserMessageFilter,将消息分发到ResourceDispatcherHostImpl来专门的处理这个消息,ResourceDispatcherHostImpl进一步的通过ResourceLoader来加载资源。

void ResourceLoader::StartRequest() {
  if (delegate_->HandleExternalProtocol(this, request_->url())) {
    CancelAndIgnore();
    return;
  }

  // Give the handler a chance to delay the URLRequest from being started.
  bool defer_start = false;
  if (!handler_->OnWillStart(request_->url(), &defer_start)) {
    Cancel();
    return;
  }

  if (defer_start) {
    deferred_stage_ = DEFERRED_START;
  } else {
    StartRequestInternal();
  }
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

在ResourceLoader中有个延迟启动的策略,我们这个情况下就是延迟启动的。

URLRequest

不过无论是延迟启动还是正常的启动都是要创建URLrequest的。如下下断:

 bp chrome_7feee760000!net::URLRequestFtpJob::Start
 
 
  • 1
  • 1

我们是个ftp协议,针对的是ftp的URLRequestFtpJob进行特殊的处理。

0:019> kc
 # Call Site
00 chrome_7feee760000!net::FtpNetworkTransaction::Start
01 chrome_7feee760000!net::URLRequestFtpJob::StartFtpTransaction
02 chrome_7feee760000!net::URLRequestFtpJob::OnResolveProxyComplete
03 chrome_7feee760000!net::URLRequestFtpJob::Start
04 chrome_7feee760000!net::URLRequest::StartJob
05 chrome_7feee760000!net::URLRequest::BeforeRequestComplete
06 chrome_7feee760000!net::URLRequest::Start
07 chrome_7feee760000!content::ResourceLoader::StartRequestInternal
08 chrome_7feee760000!content::ResourceLoader::Resume
09 chrome_7feee760000!content::ThrottlingResourceHandler::ResumeStart
0a chrome_7feee760000!content::ThrottlingResourceHandler::Resume
0b chrome_7feee760000!base::internal::RunnableAdapter<void (__cdecl extensions::NativeMessageProcessHost::*)(int)>::Run
0c chrome_7feee760000!base::internal::InvokeHelper<1,void,base::internal::RunnableAdapter<void (__cdecl extensions::NativeMessageProcessHost::*)(int)> >::MakeItSo
0d chrome_7feee760000!base::internal::Invoker<base::IndexSequence<0>,base::internal::BindState<base::internal::RunnableAdapter<void (__cdecl extensions::NativeMessageProcessHost::*)(int) __ptr64>,void __cdecl(extensions::NativeMessageProcessHost * __ptr64,int),base::WeakPtr<extensions::NativeMessageProcessHost> >,base::internal::InvokeHelper<1,void,base::internal::RunnableAdapter<void (__cdecl extensions::NativeMessageProcessHost::*)(int) __ptr64> >,void __cdecl(int const & __ptr64)>::Run
0e chrome_7feee760000!base::Callback<void __cdecl(std::list<content::IndexedDBInfo,std::allocator<content::IndexedDBInfo> > const &)>::Run
0f chrome_7feee760000!base::internal::InvokeHelper<0,void,base::Callback<void __cdecl(std::list<content::IndexedDBInfo,std::allocator<content::IndexedDBInfo> > const &)> >::MakeItSo
10 chrome_7feee760000!base::internal::Invoker<base::IndexSequence<0>,base::internal::BindState<base::Callback<void __cdecl(std::list<content::IndexedDBInfo,std::allocator<content::IndexedDBInfo> > const & __ptr64)>,void __cdecl(std::list<content::IndexedDBInfo,std::allocator<content::IndexedDBInfo> > const & __ptr64),std::list<content::IndexedDBInfo,std::allocator<content::IndexedDBInfo> > & __ptr64>,base::internal::InvokeHelper<0,void,base::Callback<void __cdecl(std::list<content::IndexedDBInfo,std::allocator<content::IndexedDBInfo> > const & __ptr64)> >,void __cdecl(void)>::Run
11 chrome_7feee760000!base::Callback<void __cdecl(void)>::Run
12 chrome_7feee760000!base::debug::TaskAnnotator::RunTask
13 chrome_7feee760000!base::MessageLoop::RunTask
14 chrome_7feee760000!base::MessageLoop::DeferOrRunPendingTask
15 chrome_7feee760000!base::MessageLoop::DoWork
16 chrome_7feee760000!base::MessagePumpForIO::DoRunLoop
17 chrome_7feee760000!base::MessagePumpWin::Run
18 chrome_7feee760000!base::MessageLoop::RunHandler
19 chrome_7feee760000!base::RunLoop::Run
1a chrome_7feee760000!base::MessageLoop::Run
1b chrome_7feee760000!base::Thread::Run
1c chrome_7feee760000!content::BrowserThreadImpl::IOThreadRun
1d chrome_7feee760000!content::BrowserThreadImpl::Run
1e chrome_7feee760000!base::Thread::ThreadMain
1f chrome_7feee760000!base::`anonymous namespace'::ThreadFunc
20 kernel32!BaseThreadInitThunk
21 ntdll!RtlUserThreadStart
 
 
  • 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
  • 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

当URLRequest处理过后,会启动一个针对ftp的URLRequestFtpJob来继续处理,后者启动ftp的网络传输FtpNetworkTransaction。

void URLRequestFtpJob::StartFtpTransaction() {
  // Create a transaction.
  DCHECK(!ftp_transaction_);

  ftp_request_info_.url = request_->url();
  ftp_transaction_ = ftp_transaction_factory_->CreateTransaction();

  int rv;
  if (ftp_transaction_) {
    rv = ftp_transaction_->Start(
        &ftp_request_info_,
        base::Bind(&URLRequestFtpJob::OnStartCompleted,
                   base::Unretained(this)),
        request_->net_log());
    if (rv == ERR_IO_PENDING)
      return;
  } else {
    rv = ERR_FAILED;
  }
  // The transaction started synchronously, but we need to notify the
  // URLRequest delegate via the message loop.
  OnStartCompletedAsync(rv);
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
FtpNetworkTransaction
资源加载的启动过程

job启动ftp传输的时候,先使用ftp_transaction_factory_来创建一个网络传输。而这个成员变量是在创建URLRequestFtpJob的时候就传递了数据,传递者是URLRequest。

int FtpNetworkTransaction::Start(const FtpRequestInfo* request_info,
                                 const CompletionCallback& callback,
                                 const BoundNetLog& net_log) {
  net_log_ = net_log;
  request_ = request_info;

  ctrl_response_buffer_.reset(new FtpCtrlResponseBuffer(net_log_));

  if (request_->url.has_username()) {
    base::string16 username;
    base::string16 password;
    GetIdentityFromURL(request_->url, &username, &password);
    credentials_.Set(username, password);
  } else {
    credentials_.Set(base::ASCIIToUTF16("anonymous"),
                     base::ASCIIToUTF16("chrome@example.com"));
  }

  DetectTypecode();

  next_state_ = STATE_CTRL_RESOLVE_HOST;
  int rv = DoLoop(OK);
  if (rv == ERR_IO_PENDING)
    user_callback_ = callback;
  return rv;
}

 
 
  • 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
  • 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

当网络传输创建完成后悔启动这个网络传输,设置用户名和密码,然后设置传输状态,首先就是要解析主机地址,设置状态为STATE_CTRL_RESOLVE_HOST,,进入状态循环处理函数。 
FTP所要处理的状态如下:

  enum State {
    // Control connection states:
    STATE_CTRL_RESOLVE_HOST,
    STATE_CTRL_RESOLVE_HOST_COMPLETE,
    STATE_CTRL_CONNECT,
    STATE_CTRL_CONNECT_COMPLETE,
    STATE_CTRL_READ,
    STATE_CTRL_READ_COMPLETE,
    STATE_CTRL_WRITE,
    STATE_CTRL_WRITE_COMPLETE,
    STATE_CTRL_WRITE_USER,
    STATE_CTRL_WRITE_PASS,
    STATE_CTRL_WRITE_SYST,
    STATE_CTRL_WRITE_TYPE,
    STATE_CTRL_WRITE_EPSV,
    STATE_CTRL_WRITE_PASV,
    STATE_CTRL_WRITE_PWD,
    STATE_CTRL_WRITE_RETR,
    STATE_CTRL_WRITE_SIZE,
    STATE_CTRL_WRITE_CWD,
    STATE_CTRL_WRITE_LIST,
    STATE_CTRL_WRITE_QUIT,
    // Data connection states:
    STATE_DATA_CONNECT,
    STATE_DATA_CONNECT_COMPLETE,
    STATE_DATA_READ,
    STATE_DATA_READ_COMPLETE,
    STATE_NONE
  };
 
 
  • 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
  • 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

分控制连接状态和数据连接状态,我们接触了第一个状态就是解析主机的状态,我们看这些状态,还有的状态是完成状态,当一种控制或数据完成后会设置一个完成状态,在完成状态的处理函数中进行必要的处理。

int FtpNetworkTransaction::DoLoop(int result) {
  DCHECK(next_state_ != STATE_NONE);

  int rv = result;
  do {
    State state = next_state_;
    next_state_ = STATE_NONE;
    switch (state) {
      case STATE_CTRL_RESOLVE_HOST:
        DCHECK(rv == OK);
        rv = DoCtrlResolveHost();
        break;
      case STATE_CTRL_RESOLVE_HOST_COMPLETE:
        rv = DoCtrlResolveHostComplete(rv);
        break;
        ......

    }
  } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE);
  return rv;
}

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

而状态循环的函数是DoLoop,仿佛状态机的处理函数,我们当前的状态是解析主机状态,自然我们进入的函数是DoCtrlResolveHost。

int FtpNetworkTransaction::DoCtrlResolveHost() {
  next_state_ = STATE_CTRL_RESOLVE_HOST_COMPLETE;

  HostResolver::RequestInfo info(HostPortPair::FromURL(request_->url));
  // No known referrer.
  return resolver_.Resolve(
      info,
      DEFAULT_PRIORITY,
      &addresses_,
      base::Bind(&FtpNetworkTransaction::OnIOComplete, base::Unretained(this)),
      net_log_);
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

函数中首先设置了下一跳状态为STATE_CTRL_RESOLVE_HOST_COMPLETE,然后使用resolver来解析主机地址,并设置了回调函数。我们在回调函数上下断。

void FtpNetworkTransaction::OnIOComplete(int result) {
  int rv = DoLoop(result);
  if (rv != ERR_IO_PENDING)
    DoCallback(rv);
}
int FtpNetworkTransaction::DoCtrlResolveHostComplete(int result) {
  if (result == OK)
    next_state_ = STATE_CTRL_CONNECT;
  return result;
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

当地址解析完成后,调用IO完成回调函数,函数中继续进行循环处理,处理下一状态,在解析主机完成函数中设置状态为控制连接状态,开始准备连接。


int FtpNetworkTransaction::DoCtrlConnect() {
  next_state_ = STATE_CTRL_CONNECT_COMPLETE;
  ctrl_socket_ = socket_factory_->CreateTransportClientSocket(
      addresses_, net_log_.net_log(), net_log_.source());
  net_log_.AddEvent(
      NetLog::TYPE_FTP_CONTROL_CONNECTION,
      ctrl_socket_->NetLog().source().ToEventParametersCallback());
  return ctrl_socket_->Connect(io_callback_);
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

连接状态中创建传输客户端socket,这是一个控制socket,然后使用这个socket来连接主机,并设置连接完成回调。 
当连接完成后会交互一些命令,就是上面的一列状态的处理。 
当控制连接建立完成后,会建立数据连接,都这一切都准备好了之后,上层会调用读取操作。

资源加载的读取过程

启动完成后,ResourceLoader会进行持续的读取操作。

0:019> kc
 # Call Site
00 chrome_7feee760000!net::FtpNetworkTransaction::Read
01 chrome_7feee760000!net::URLRequestFtpJob::ReadRawData
02 chrome_7feee760000!net::URLRequestJob::ReadRawDataHelper
03 chrome_7feee760000!net::URLRequestJob::Read
04 chrome_7feee760000!net::URLRequest::Read
05 chrome_7feee760000!content::ResourceLoader::ReadMore
06 chrome_7feee760000!content::ResourceLoader::StartReading
07 chrome_7feee760000!content::ResourceLoader::ResumeReading
08 chrome_7feee760000!base::internal::RunnableAdapter<void (__cdecl syncer_v2::SharedModelTypeProcessor::*)(void)>::Run
09 chrome_7feee760000!base::internal::InvokeHelper<1,void,base::internal::RunnableAdapter<void (__cdecl syncer_v2::SharedModelTypeProcessor::*)(void)> >::MakeItSo
0a chrome_7feee760000!base::internal::Invoker<base::IndexSequence<0>,base::internal::BindState<base::internal::RunnableAdapter<void (__cdecl syncer_v2::SharedModelTypeProcessor::*)(void) __ptr64>,void __cdecl(syncer_v2::SharedModelTypeProcessor * __ptr64),base::WeakPtr<syncer_v2::SharedModelTypeProcessor> >,base::internal::InvokeHelper<1,void,base::internal::RunnableAdapter<void (__cdecl syncer_v2::SharedModelTypeProcessor::*)(void) __ptr64> >,void __cdecl(void)>::Run
0b chrome_7feee760000!base::Callback<void __cdecl(void)>::Run
0c chrome_7feee760000!base::debug::TaskAnnotator::RunTask
0d chrome_7feee760000!base::MessageLoop::RunTask
0e chrome_7feee760000!base::MessageLoop::DeferOrRunPendingTask
0f chrome_7feee760000!base::MessageLoop::DoWork
10 chrome_7feee760000!base::MessagePumpForIO::DoRunLoop
11 chrome_7feee760000!base::MessagePumpWin::Run
12 chrome_7feee760000!base::MessageLoop::RunHandler
13 chrome_7feee760000!base::RunLoop::Run
14 chrome_7feee760000!base::MessageLoop::Run
15 chrome_7feee760000!base::Thread::Run
16 chrome_7feee760000!content::BrowserThreadImpl::IOThreadRun
17 chrome_7feee760000!content::BrowserThreadImpl::Run
18 chrome_7feee760000!base::Thread::ThreadMain
19 chrome_7feee760000!base::`anonymous namespace'::ThreadFunc
1a kernel32!BaseThreadInitThunk
1b ntdll!RtlUserThreadStart
 
 
  • 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
  • 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
int FtpNetworkTransaction::Read(IOBuffer* buf,
                                int buf_len,
                                const CompletionCallback& callback) {
  DCHECK(buf);
  DCHECK_GT(buf_len, 0);

  read_data_buf_ = buf;
  read_data_buf_len_ = buf_len;

  next_state_ = STATE_DATA_READ;
  int rv = DoLoop(OK);
  if (rv == ERR_IO_PENDING)
    user_callback_ = callback;
  return rv;
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

函数中设置了状态,进入状态循环函数,处理数据读取。

int FtpNetworkTransaction::DoDataRead() {
  DCHECK(read_data_buf_.get());
  DCHECK_GT(read_data_buf_len_, 0);

  if (data_socket_ == NULL || !data_socket_->IsConnected()) {
    // If we don't destroy the data socket completely, some servers will wait
    // for us (http://crbug.com/21127). The half-closed TCP connection needs
    // to be closed on our side too.
    data_socket_.reset();

    if (ctrl_socket_->IsConnected()) {
      // Wait for the server's response, we should get it before sending QUIT.
      next_state_ = STATE_CTRL_READ;
      return OK;
    }

    // We are no longer connected to the server, so just finish the transaction.
    return Stop(OK);
  }

  next_state_ = STATE_DATA_READ_COMPLETE;
  read_data_buf_->data()[0] = 0;
  return data_socket_->Read(
      read_data_buf_.get(), read_data_buf_len_, io_callback_);
}

int FtpNetworkTransaction::DoDataReadComplete(int result) {
  return result;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值