Problem/Motivation

Enabling Internal Page Cache (page_cache) breaks the httpbl module when enabled to check page requests. There is no apparent conflict when httpbl is used with Internal Dynamic Page Cache (dynamic_page_cache) or no cache at all.

The event that will lead to a crash is when a first time, anonymous visitor hits a cached page. "First time" meaning a visiting host IP that has not already been evaluated and locally stored (or whose past record has expired).

The expected behavior is the visitor's IP will be looked up locally, then, if not not found locally, it is queried against the httpBL service at Project Honeypot. The host is then evaluated and stored locally. The visitor then receives a response. Either they receive the default response for their request (the page they were going to) if no issues were found with their IP, or they receive alternative responses based on whether they will be grey or blacklisted from the site.

The evaluation steps include log entries that include Operations links in reports/dblog that enable a quick lookup of the host at ProjectHoneypot.org. One such log entry is constructed right before a new host is locally stored. That action appears to be the location—in the httpbl module—of the break point, if page_cache is enabled and the event is a "first time" anonymous visitor hitting a cached page.

The specific local function involved builds the "project link" and calls \Drupal\Core\Link::fromTextAndUrl()->toString, which—when page_cache is enabled—never returns.

However, if page_cache is not enabled, there is no problem and the result is the expected behavior (a new IP is logged and stored).

Steps to reproduce the problem

This module is difficult to test alone. Unless you have multiple IP addresses up your sleeve, it's easier to test a remote dev site with some team members, so that you can stay logged in as admin and they can be the anons.

#1 Make sure page_cache is enabled, and select a page to test that should be cached for anonymous users (hit it a few times).
#2 Make sure httpbl is enabled, configured to check all page requests and for verbose logging, and that you or your testing visitors do not already appear as evaluated hosts in (admin/config/people/host/list).

Note: If you are testing alone on a local server, you will have an easier time with shell access so you can use the drush commands to start and stop the page checking. "drush sos --stop" to stop checking long enough to remove your IP from evaluated hosts if it's already stored (if you use the UI to remove yourself and page checking is not turned off, first, your IP will reappear on the next page load after you delete it). Once you are removed, log out, then use "drush sos --start" to restart page checking, before the next step.

#3 You and/or your helpers then hit a cached page as an anonymous user. (BOOM!) You/they should see "The website encountered an unexpected error. Please try again later."

#4 Use "drush sos --stop" to stop page checking.

#5 Check the log. You should see the php error "TypeError: Argument 1 passed to Drupal\Core\Routing\RequestContext::fromRequest()..."

Steps to see what should happen

#1 Clear cache and uninstall page_cache. (Or you can just "drush cr" and go hit that page again)
#2 Repeat above steps 2 thru 3, however this time you and/or your helpers should simply see the page they were expecting to see.
#3 Check evaluated hosts (admin/config/people/host/list). You should see yourself and/or your helpers evaluated IPs.
#4 Check the log. You should see verbose entries that show how httpbl handled each IP.

More Details

More details are included in the attached image (see "fromTextAndUrl()...").

In addition, there are other potential problems when using this module with page_cache enabled.

I tried a brute-force debug of simply commenting out the line of code (the logging) that leads to the problem. That solved the "Argument 1" problem, which only allowed me to see what's next...

When the new host entity is created and before it is saved, an expiry is set by adding a time to the request time. When page_cache is enabled, \Drupal::time()->getRequestTime() blows up. More details in attached "getRequestTime().png".

Once again, these problems disappear when page_cache is not installed.

Proposed resolution

There are no proposed solutions at this time. The problem/conflict has not yet been pin-pointed to this module. This module will behave as expected if page_cache is not installed.

The obvious workaround is to not use page_cache, stick with dynamic_page_cache or don't use httpbl (this module).

Remaining tasks

Further testing/debugging is required to nail this issue down to a root cause, and whether that cause is located in this module or in Drupal core (page_cache?). If a specific location/module/service can be identified, open issues to get it resolved.

In the meantime, update (or create documentation for this module beyond the basic "README" and Drupal Help) documentation to reflect that, for now, this module should not be used in an environment where page_cache is installed.

User interface changes

No UI changes are proposed.

API changes

The httpbl module has been updated to eliminate the deprecated use of REQUEST_TIME.

Report any other API changes required if found.

Data model changes

No data model changes are proposed for this specific issue.

Comments

bryrock created an issue. See original summary.

bryrock’s picture

StatusFileSize
new335.41 KB
bryrock’s picture

Issue summary: View changes
bryrock’s picture

Issue summary: View changes
bryrock’s picture

Issue summary: View changes
niklan’s picture

Hi folks.

I’m not using your module but googled it. I faced the same problem when writing a plugin. The behavior and error just like yours.

I found how this problem was solved in Facets. And this solution helps me as well.

Maybe this helps you to fix the problem or point in the right direction.