Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: create request context from network context #14656

Merged
merged 22 commits into from Oct 4, 2018

Conversation

deepak1556
Copy link
Member

@deepak1556 deepak1556 commented Sep 17, 2018

Description of Change

Create request context using the network service apis, the service is disabled and will simply be created on the io thread in the browser process. So there should be no change in behavior of these apis. This change is a prerequisite to use the mojo proxy resolver and cookie change notifiers.

Fixes #14441
Fixes #13829
Fixes corrupted net log generation in 3.x and above

Checklist
  • PR description included and stakeholders cc'd
  • npm test passes
  • tests are changed or added
  • relevant documentation is changed or added
  • PR title follows semantic commit guidelines
Release Notes

Notes: no-notes

@deepak1556 deepak1556 requested a review from a team September 17, 2018 23:50
@deepak1556 deepak1556 force-pushed the network_service_patch branch 3 times, most recently from 50c448e to 2ce9271 Compare September 21, 2018 08:55
@deepak1556 deepak1556 changed the title [WIP] refactor: create request context from network context refactor: create request context from network context Sep 21, 2018
@deepak1556
Copy link
Member Author

This PR is ready for review, there are some minor cleanups that will follow up separately. Its easier to review if looked at individual commits, after this change all network code now live under one place in atom/browser/net. Thanks!

@deepak1556 deepak1556 force-pushed the network_service_patch branch 2 times, most recently from 7d04f1f to 440296b Compare September 23, 2018 02:19
Copy link
Member

@nornagon nornagon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only a few commits in, but here's what i got so far

atom/browser/atom_browser_client.cc Show resolved Hide resolved
atom/browser/cookie_change_notifier.cc Show resolved Hide resolved
content::BrowserContext::GetDefaultStoragePartition(browser_context_)
->GetCookieManagerForBrowserProcess();
if (!cookie_manager)
return;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be a noisier error? What does a null return from GetCookieManagerForBrowserProcess indicate?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The cookie manager should be initialized whenever a network context is initialized, if there is none then there should be no reason to observe cookie changes in this context. But I can't think of situations where this can happen though.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps it should be a CHECK then?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated it to a CHECK

DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

binding_.Close();
StartListening();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the cookie service goes down, will this result in us spinning very quickly trying to reconnect to a service that isn't coming back?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes the situation needs to be handled, but its not a service yet.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I understand—what isn't a service yet?

return WrapRefCounted(browser_context_map_[key].get());
auto* browser_context = browser_context_map_[key].get();
if (browser_context)
return browser_context;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need to WrapRefCounted any more?

@@ -76,6 +74,7 @@ network::mojom::NetworkContextParamsPtr CreateDefaultNetworkContextParams(
network_context_params->accept_language =
net::HttpUtil::GenerateAcceptLanguageHeader(
brightray::BrowserClient::Get()->GetApplicationLocale());
network_context_params->allow_gssapi_library_load = true;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this new functionality that we weren't previously enabling?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope this has been a default parameter on the HttpAuthHandlerFactory creation and gets enabled indirectly with the old interface, I am just explicitly specifying for this interface.

job_factory->SetProtocolHandler(url::kAboutScheme,
std::make_unique<AboutProtocolHandler>());
job_factory->SetProtocolHandler(url::kDataScheme,
std::unique_ptr<net::DataProtocolHandler>());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why handle these protocols here rather than allowing the network context to handle them (presuming that's what enable_data_url_support = true does)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is because of the protocol module we provide https://github.com/electron/electron/blob/master/docs/api/protocol.md, to intercept some of the standard schemes with atom/browser/net/atom_url_request_job_factory we need to establish these handlers explicitly so that they can replaced dynamically.

#if !BUILDFLAG(DISABLE_FTP_SUPPORT)
auto* host_resolver = url_request_context->host_resolver();
job_factory->SetProtocolHandler(
url::kFtpScheme, net::FtpProtocolHandler::Create(host_resolver));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is the host_resolver guaranteed to have a longer lifetime than the job_factory here?

Copy link
Member

@zcbenz zcbenz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did a rough check of the code and everything seems to be fine.

}

void NetLog::StopLogging(mate::Arguments* args) {
base::OnceClosure callback;
args->GetNext(&callback);
args->GetNext(&stop_callback_);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if this gets called twice quickly, then only one of the callbacks will get called.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's by design with the OnceClosure but I agree it could be problematic if used wrongly.

Maybe a DCHECK(stop_callback_.is_null()); at the front of the func?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have updated to queue up the callbacks when the logging is not stopped 5fa25ad

})
server.listen(0, '127.0.0.1', () => {
const config = { pacScript: `http://127.0.0.1:${server.address().port}` }
session.defaultSession.setProxy(config, () => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you need to reset this back to the default config after the test? (or better, use a fresh session?)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated to use a custom session.

Copy link
Member

@nornagon nornagon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall LGTM.

}

void NetLog::StopLogging(mate::Arguments* args) {
base::OnceClosure callback;
args->GetNext(&callback);
args->GetNext(&stop_callback_);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's by design with the OnceClosure but I agree it could be problematic if used wrongly.

Maybe a DCHECK(stop_callback_.is_null()); at the front of the func?

@@ -22,15 +27,20 @@ class NetLog : public mate::Wrappable<NetLog> {

void StartLogging(mate::Arguments* args);
bool IsCurrentlyLogging();
base::FilePath::StringType GetCurrentlyLoggingPath();
std::string GetCurrentlyLoggingPath();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(nit) this could be a const method

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

net_log_->StopDynamicLogging(std::move(callback));
const auto* current_log_state =
state.FindKeyOfType("state", base::Value::Type::STRING);
if (current_log_state && current_log_state->GetString() == "STOPPING_LOG")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(minor, DRY) this sequence is similar to the IsCurrentlyLogging impl. Might be better to have a std::string GetLoggingState() const that does this and returns the GetString() so that both places can use that code

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

atom/browser/api/atom_api_session.cc Show resolved Hide resolved
atom/browser/atom_browser_client.cc Show resolved Hide resolved
network::mojom::NetworkContextPtr AtomBrowserClient::CreateNetworkContext(
content::BrowserContext* browser_context,
bool in_memory,
const base::FilePath& relative_partition_path) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(minor) As per style guide, I think in_memory and relative_partition_path should be commented out as unused, e.g.

content::BrowserContext* browser_context,
bool /*in_memory*/,
const base::FilePath& /*relative_partition_path*/) {

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this is only required when the parameter names are omitted which is not in this case ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand this comment -- if the name is omitted, then by definition the name can't be commented out? 😃

Unused variables which are obvious from context can have their names omitted entirely, e.g. class Foo { Foo(Foo&&); }; but those not obvious from context should have a name commented out, e.g. void Circle::Rotate(double /*radians*/) {}

ref

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm seems like I misread the style guide, will update them. Thanks!

atom/browser/atom_browser_context.cc Show resolved Hide resolved
atom/browser/atom_browser_context.h Show resolved Hide resolved
atom/browser/atom_browser_context.cc Show resolved Hide resolved
// for the global requests, like the cert fetchers below and
// geolocation requests.
// 3) There is also ongoing work in upstream which will eventually allow
// localizing these global fetchers to their own URLRequestContexts.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉

the breadcrumbs & rationale are appreciated

@deepak1556
Copy link
Member Author

deepak1556 commented Oct 2, 2018

@nornagon @ckerr have updated the PR to address the review comments. Thanks!

Copy link
Contributor

@nitsakh nitsakh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍 !

"includes": [28750],
},
+ "electron/electron_resources.grd": {
+ "includes": [31750],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other than the fact that the number should be greater than 31000, no special reason for this number, right?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup that is the only reason.


net_log_->StopDynamicLogging(std::move(callback));
if (stop_callback_queue_.empty())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't matter right now, because we're not doing much here; but ☝️ should be checked inside the if block 👇 in the stop logging case or it can be removed.

protocol_interceptors_.clear();
}
top_job_factory_->Chain(std::move(inner_job_factory));
main_request_context_->set_job_factory(top_job_factory_.get());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ownership is transferred here. How will the lifetimes work for top_job_factory_?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its not transferred, URLRequestContext only has weak references to its members, any reason to think the ownership was transferred here ?

return current_log_path->GetString();
}

return std::string();
}

void NetLog::StopLogging(mate::Arguments* args) {
base::OnceClosure callback;
args->GetNext(&callback);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if the callback not provided case is taken care of here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its actually checked on the js side atom/browser/lib/net-log.js, could have moved that code here but its better to do that check on js side avoiding an extra js<->c++ type conversion

std::unique_ptr<content::ZoomLevelDelegate>
AtomBrowserContext::CreateZoomLevelDelegate(
const base::FilePath& partition_path) {
if (!IsOffTheRecord()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For my understanding, what does this if condition mean, and why do we need it?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IsOffTheRecord is the incognito mode in Electron, we don't persist any of the user preferences to file system when the app exits. Users will get this mode when they create a temporary partition for a session.

@deepak1556 deepak1556 requested a review from a team October 4, 2018 16:10
@ckerr ckerr merged commit 434a6e3 into master Oct 4, 2018
@release-clerk
Copy link

release-clerk bot commented Oct 4, 2018

No Release Notes

@ckerr ckerr deleted the network_service_patch branch October 4, 2018 18:09
deepak1556 added a commit to deepak1556/atom-shell that referenced this pull request Nov 20, 2018
* [ci skip] refactor: create request context from network context

* [ci skip] refactor: subscribe to mojo cookiemanager for cookie changes

* [ci skip] refactor: manage the lifetime of custom URLRequestJobFactory

* refactor: use OOP mojo proxy resolver

* revert: add support for kIgnoreCertificateErrorsSPKIList

* build: provide service manifest overlays for content services

* chore: gn format

* fix: log-net-log switch not working as expected

* spec: verify proxy settings are respected from pac script with session.setProxy

* chore: use chrome constants where possible

* fix: initialize request context for global cert fetcher

* refactor: fix destruction of request context getters

* spec: use custom session for proxy tests

* fix: queue up additional stop callbacks while net log is being stopped

* fix: Add CHECK for cookie manager retrieval

* chore: add helper to retrieve logging state for net log module

* fix: ui::ResourceBundle::GetRawDataResourceForScale => GetRawDataResource

* style: comment unused parameters

* build: move //components/certificate_transparency deps from //brightray

* chore: update gritsettings_resource_ids patch

* chore: update api for chromium 68

* fix: net log instance is now a property of session
@deepak1556 deepak1556 mentioned this pull request Nov 21, 2018
15 tasks
deepak1556 added a commit that referenced this pull request Nov 23, 2018
deepak1556 added a commit that referenced this pull request Nov 23, 2018
@talon266
Copy link

talon266 commented Dec 5, 2018

Hey guys!
First of all thanks for this fix and cudos to all who made it happen.
Is there an estimation on the release of this fix? we sure could use it.

Thanks again.

@deepak1556
Copy link
Member Author

@tallev266 3.1.0-beta.x has this fix and also 4.x release line.

@talon266
Copy link

talon266 commented Dec 5, 2018

@deepak1556 - Thanks! I guess we'll wait for the RC then

@bughit
Copy link
Contributor

bughit commented Dec 5, 2018

@deepak1556 #14411 is fixed in 3.1?

@bughit
Copy link
Contributor

bughit commented Dec 5, 2018

@deepak1556 #14411 is fixed in 3.1?

already in v3.1.0-beta.2 or in next release?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
10 participants