I had an installed version of the Browscap module on a site that had been upgraded several times, but the Browscap file had not been fetched. (this site is running PHP 5.5.9) In 7.x-2.3, I started seeing a message in the Status Report about Browscap not being installed, and attempted to do so via drush.

Tried to run drush browscap-import several times, and kept getting an error message regarding line 95 in import.inc. On further inspection, I realized it was failing because the data being downloaded from browscap.org was not compressed, and the code is trying to perform a gzdecode.

After commenting out the $browscap_data->data = gzdecode($browscap_data->data); line of code, the browscap data was successfully imported into the database.

I've written a patch that catches for this exception, and will post in a minute for review.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

ron_s created an issue. See original summary.

ron_s’s picture

Status: Active » Needs review
FileSize
846 bytes

Here is a patch for review. Thanks.

ruloweb’s picture

Hi ron_s, thanks for the patch, did you try it?

It doesnt work for me, because gzdecode doesnt throw an exception, just a warning and the try sentence wont catch it.

Im uploading a new patch which tries to solve it in a different way, if gzdecode returns FALSE, do nothing.

Thanks!

ron_s’s picture

@ruloweb, your patch is better. I didn't have a chance to test #2 since the import successfully ran after I commented out the gzdecode. I had moved on to other issues.

Thanks for taking the time to make an updated version!

AohRveTPV’s picture

If your PHP has gzdecode(), the response from browscap.org should have gzip-encoded data, because it is requested using the Accept-Encoding: gzip header. So I don't see why this problem should occur.

ron_s, ruloweb: Could you please tell me which OS version, PHP version, and Drupal version you are using so I can try to reproduce the problem?

ruloweb’s picture

Hey @AohRveTPV, I was using Ubuntu 16.04, PHP 5.6 and Drupal 7.x (can't remember the version because I'm not on that project anymore)

rockthedrop’s picture

Got same error:
gzdecode(): data error import.inc:95

Patch #3 worked for me. Can't believe it's 2 years waiting for a test. Shame on us.

- rock

alexh’s picture

I also had same Warning: gzdecode(): data error in _browscap_import() (line 95 of ...modules/browscap/import.inc).
Noticed it starting a few days ago.
Running on Browscap 7.x-2.3 and PHP 7.0.31.
Patch #3 solved it.
Thanks!

bobburns’s picture

PHP 7.3.5 still there and patch 3 solved it

+RTBC

gngn’s picture

#3 worked for me, too.
The failing messages started on 2019-05-16 in my case.

I noticed that we do not give any feedback to the user (or the log) if we cannot parse the ini file.
So I added watchdog() and drupal_set_message() for the last return BROWSCAP_IMPORT_DATA_ERROR;.
Both used functions parse_ini_string() and parse_ini_file() return an associative array on success, and false on failure - so I test if we have FALSE or empty as data.

Otherwise the attached patch is identical with #3.

To re-test after an successfull update you can reset the browscap version number via drush, so the module will go for another download:
drush vset browscap_version 6000032

jrb’s picture

Status: Needs review » Reviewed & tested by the community

#10 solved the problem for me. I think the logging is a good addition to #3.

AohRveTPV’s picture

Thanks for #10 but this line strikes me as a hack:

$browscap_data->data = ($data = @gzdecode($browscap_data->data)) ? $data : $browscap_data->data;

Why should we need to attempt a gzdecode()? Why would the data be gzip compressed for some requests but not others? Would like to understand the cause of the problem.

To the people experiencing this problem: Which OS version and PHP version are you using? Would like to reproduce the bug.

AohRveTPV’s picture

I'm able to reproduce this with PHP 5.6 and Debian 8.

Maybe there was a change in PHP somewhere between 5.3 and 5.6 that caused gzip data to be decompressed transparently before it is returned from drupal_http_request(). Will investigate.

jrb’s picture

Status: Reviewed & tested by the community » Needs review
FileSize
1.35 KB

I think the ultimate cause of the problem is that the browscap.org server isn't returning gzipped data when it's requested:

# curl 'https://www.browscap.org/stream?q=PHP_BrowsCapINI' --silent --write-out "%{size_download}\n" --output /dev/null
17504827
# curl 'https://www.browscap.org/stream?q=PHP_BrowsCapINI' --silent -H "Accept-Encoding: gzip,deflate" --write-out "%{size_download}\n" --output /dev/null
17504827

The module code assumes that, if it requests gzipped data, it's going to get gzipped data back. It tries to decode it and fails.

I've attached a patch that actually checks the response headers to see if the response is gzipped before trying to decode it. I haven't been able to test it very well (because browscap.org isn't gzipping!), but it does work for me. I've also kept the error logging from #10.

jrb’s picture

@AohRveTPV,

It's possible that there was just a configuration change on the browscap.org server where they stopped supporting gzip output on that download.

AohRveTPV’s picture

jrb, nice investigation. I was confused because I had a D7 site where Browscap was running fine, but the reason is clear now: It is using PHP 5.3, which does not have gzdecode().

How about we just remove the gzdecode() code completely, since browscap.org no longer supports it?

We could also submit an issue to the Browscap project requesting that gzip support be re-added. If it is, then we could test and re-add code to support it (as in #14) to the Browscap module.

AohRveTPV’s picture

AohRveTPV’s picture

The error checking code from #10 could be be added as a separate issue.

jrb’s picture

@AohRveTPV,

In my opinion, we should keep the header check in #14 so that we can get the benefit of gzipped content if they end up supporting it. Especially since it won't cause and problems if they don't. We could submit that issue to the Browscap project as you suggested. It'll just start working, if they change it.

I'd also lean towards keeping the error message addition. It seems like it's related enough to this issue (failing to get the data correctly from Browscap), that it makes sense. Not a big deal either way, though.

Anybody’s picture

I agree with #19 and can confirm #14 works correctly. To get this into the module I'd vote for #14 RTBC!