Add 15s timeout to GitLab UrlBlocker
What does this MR do?
The URL blocker checks for resolvable addresses of the URLs it receives.
In some cases, bad/stale URLs do not resolve in a finite time, and lead to a hang of the call for over the rack/puma timeout levels.
The Addrinfo.getaddrinfo
call supports passing a timeout since
Ruby 2.7.0, and this change applies a 15 seconds
timeout to the operation.
The "arbitrary" 15 seconds value choice here copies the value also used for "resolver" work in the app/services/verify_pages_domain_service.rb
file. With 15s, upto 4 bad resolving URLs could be checked without triggering the default rack/puma timeout.
I've defined it as a constant just in case it requires quick updating.
Screenshots (strongly suggested)
Sanitized sample error log when there's a bad URL being checked as part of project badges:
{
"method": "GET",
"path": "/group/project",
"format": "html",
"controller": "ProjectsController",
"action": "show",
"status": 500,
"time": "2021-01-26T10:30:10.621Z",
"gitaly_calls": 3,
"gitaly_duration_s": 0.012923,
"redis_calls": 13,
[…]
"queue_duration_s": 0.002724,
"cpu_s": 0.28,
"exception.class": "Rack::Timeout::RequestTimeoutException",
"exception.message": "Request ran for longer than 60000ms",
"exception.backtrace": [
"lib/gitlab/url_blocker.rb:111:in `getaddrinfo'",
"lib/gitlab/url_blocker.rb:111:in `get_address_info'",
"lib/gitlab/url_blocker.rb:48:in `validate!'",
"app/validators/addressable_url_validator.rb:83:in `validate_each'",
"app/models/badge.rb:43:in `build_rendered_url'",
"app/models/badge.rb:31:in `rendered_link_url'",
"app/models/badges/project_badge.rb:10:in `rendered_link_url'",
"app/views/projects/_home_panel.html.haml:85",
"app/views/projects/_home_panel.html.haml:84",
"app/views/projects/show.html.haml:11",
"app/controllers/application_controller.rb:134:in `render'",
[…]
],
}
Source: customer ticket (internal link)
Does this MR meet the acceptance criteria?
Conformity
-
Changelog entry -
Documentation (if required) -
Code review guidelines -
Merge request performance guidelines -
Style guides -
Database guides -
Separation of EE specific content
Availability and Testing
Biggest risk is that the code will not work on versions lower than Ruby 2.7.
Testing is not included as simulating a low level resolver timeout does not appear to be straight-forward from within an rspec unit test. But I'm open to ideas if I've missed a simple way to simulate it.
-
Review and add/update tests for this feature/bug. Consider all test levels. See the Test Planning Process. - [-] Tested in all supported browsers
- [-] Informed Infrastructure department of a default or new setting change, if applicable per definition of done
Security
If this MR contains changes to processing or storing of credentials or tokens, authorization and authentication methods and other items described in the security review guidelines:
- [-] Label as security and @ mention
@gitlab-com/gl-security/appsec
- [-] The MR includes necessary changes to maintain consistency between UI, API, email, or other methods
- [-] Security reports checked/validated by a reviewer from the AppSec team