I have a script that fetches an rss feed from blogs.com. A couple of days ago it broke. Reason: server is sending gzip encoded content. I felt that was mightly impolite, but it turns out the HTTP spec is on their side:
If no Accept-Encoding field is present in a request, the server MAY assume that the client will accept any content coding. In this case, if "identity" is one of the available content-codings, then the server SHOULD use the "identity" content-coding, unless it has additional information that a different content-coding is meaningful to the client.
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html , Section 14.3
Since LWP by default does not send any Accept-Encoding request header, this means sending gzip'ed content is perfectly acceptable. But LWP doesn't handle that, and simply gives us the undecoded content.
It would seem - to me at least - that the quickest fix to LWP would be to include a 'Accept-Encoding: identity' in the request headers by default:
If an Accept-Encoding field is present in a request, and if the server cannot send a response which is acceptable according to the Accept-Encoding header, then the server SHOULD send an error response with the 406 (Not Acceptable) status code.
ibid.
(Although I'd have to say that a 406 response would be pretty useless.)
Unfortunately, with this particular server, that does not do the trick:
[user@host]% GET -H 'Accept-Encoding: identity' -U -e -d http://$blog_id.blogs.com/index.rdf
GET http://$blog_id.blogs.com/index.rdf
Accept-Encoding: identity
User-Agent: lwp-request/2.06
Connection: close
Date: Thu, 28 Jul 2005 18:46:27 GMT
Accept-Ranges: bytes
Age: 63019
ETag: "1cc057-75c4-427c6400"
Server: Apache
Content-Encoding: gzip
Content-Length: 8956
Content-Type: application/rdf+xml
Last-Modified: Wed, 20 Jul 2005 14:00:48 GMT
Client-Date: Fri, 29 Jul 2005 12:16:46 GMT
Client-Peer: 216.129.107.21:80
Client-Response-Num: 1
X-Cache: HIT from www.sixapart.com
If you don't have a plain text version, then where's the 406, guys?
Which means that it would be nice if LWP could decode the content when it sees the Content-Encoding: gzip header, and if a suitable Compress module is available.
I'd like to point out that - in my opinion - the content-encoding is a transport detail, and should not have to matter to the user. In other words, I would appreciate LWP to handle that for me transparently.
Maybe I should send in a patch....
I always lived with the idea that "use base" was introduced with perl 5.6.0, and that we had to write
require BaseClass; # Thanks, merlyn
:)
use vars qw/@ISA/;
@ISA = qw/BaseClass/;
to be compatible with older perls.
Today I learned (http://search.cpan.org/dist/base/lib/base.pm) that "use base" was introduced with Perl 5.004_04!
Is this an odd case of cargo cult? Does it mean we can stop doing the "use vars '@ISA'" thing now?
Who wants their OO code to be compatible with perls older than 5.005?
And where did I get this notion from that it only became available in 5.6?
Sometimes it seems that experience just means you're set in your ways....
Sarge is now officially stable. I'm pleased with that
Norway may not be the richest country in the world, but it sure is astonishingly beautiful.
With a view like this, right from our balcony, I consider us pretty well off. And I definitely don't need an expensive car when I can walk in the snow.
This is more likely an issue with Parallel::UserAgent, but I couldn't resist that title
I'm using POE::Component::Client::UserAgent to fetch multiple RSS feeds. Every once in a while, one of the servers is down, so that request times out with a 500 error. The problem I have is that all requests that are queued behind this one also time out with a 408 error!
I don't feel like starting a bug hunt on monday morning; and this one looks like it's going to be hard
Had some good feedback on module-authors and the code-review-ladder lists (thanks, Bart, Mark, Stephen and Smylers
http://search.cpan.org/~rhesa/DBIx-Counter-0.01/lib/DBIx/Counter.pm
Now for some advertising... Where do I go to announce my precious code to the world?
Hi,
I've been a CPAN consumer for so long, I thought it's about time to start contributing.
I wrote a little module that does exactly the same as File::CounterFile, but with a database as storage engine.
It came into this world after a thread on www.experts-exchange.com; so there's at least one interested user for it.
Granted, it's nothing earth-shattering, but it's simple and generic enough to be useful outside my usual work, and it presents me with a manageable package to start my CPAN career.
Before I go all the way by applying for a PAUSE account and uploading it, I would like to put it to public scrutiny first. I'd like to know I'm doing things properly from the start.
Here's my list of questions:
- what about the module name? is it good?
- code review would be nice
- documentation: clear enough?
- tests: for a module this simple?
- exception handling: should I do this myself, or let DBI throw them?
The archive is here: http://www.rhesa.com/DBIx-Counter-0.01.tar.gz
Thanks for your attention!
Rhesa
Here's the pod:
NAME
DBIx::Counter - Manipulate named counters stored in a database
SYNOPSIS
use DBIx::Counter;
$c = new DBIx::Counter('my counter',
dsn => 'dbi:mysql:mydb',
login => 'username',
password => 'secret'
);
print $c->value;
$c->inc;
DESCRIPTION
This module creates and maintains named counters in a database. It has a
simple interface, with methods to increment and decrement the counter by
one, and a method for retrieving the value. It supports operator
overloading for increment (++), decrement (--) and stringification ("").
It should perform well in persistent environments, since it uses the
connect_cached and prepare_cached methods of DBI. The biggest advantage
over its main inspiration - File::CounterFile - is that it allows
distributed, concurrent access to the counters and isn't tied to a
single file system.
Connection settings can be set in the constructor, or by using the
package variables $DSN, $LOGIN and $PASSWORD and $TABLENAME. The table
name is configurable, but the column names are currently hard-coded to
counter_id and value. The following SQL statement can be used to create
the table:
CREATE TABLE counters (
counter_id varchar(64) primary key,
value int not null default 0
);
This module attempts to mimick the File::CounterFile interface, except
currently it only supports integer counters. The locking functions in
File::CounterFile are present for compatibility only: they always return
0.
METHODS
new Creates a new counter instance. First parameter is the required
counter name. Second, optional, argument is an initial value for the
counter on its very first use. It also accepts named parameters for
the dbi connection string, dbi login and dbi password, and the table
name:
dsn - overrides $DBIx::Counter::DSN
login - overrides $DBIx::Counter::LOGIN
password - overrides $DBIx::Counter::PASSWORD
tablename - overrides $DBIx::Counter::TABLENAME
Examples:
$c = new DBIx::Counter('my counter');
$c = new DBIx::Counter('my counter',
dsn => 'dbi:mysql:mydb',
login => 'username',
password => 'secret'
);
$c = new DBIx::Counter('my counter',
42,
dsn => 'dbi:mysql:mydb',
tablename => 'gauges'
);
inc increases the counter by one.
$c->inc;
# or using overload:
$c++;
dec decreases the counter by one.
$c->dec;
# or using overload:
$c--;
value
returns the current value of the counter.
print $c->value;
# or using overload:
print $c;
SEE ALSO
File::CounterFile
AUTHOR
Rhesa Rozendaal, .
COPYRIGHT AND LICENSE
Copyright (C) 2005 by Rhesa Rozendaal
This library is free software; you can redistribute it and/or modify it
under the same terms as Perl itself, either Perl version 5.8.2 or, at
your option, any later version of Perl 5 you may have available.