package Perlbal::XS::HTTPHeaders; use 5.008; use strict; use warnings; use Carp; require Exporter; use AutoLoader; use Perlbal; use Perlbal::HTTPHeaders; # inherit things from Perlbal::HTTPHeaders when we can our @ISA = qw(Exporter Perlbal::HTTPHeaders); # flag we set when we are enabled or disabled our $Enabled = 0; # Items to export into callers namespace by default. Note: do not export # names by default without a very good reason. Use EXPORT_OK instead. # Do not simply export all your public functions/methods/constants. # This allows declaration use HTTPHeaders ':all'; # If you do not need this, moving things directly into @EXPORT or @EXPORT_OK # will save memory. our %EXPORT_TAGS = ( 'all' => [ qw( H_REQUEST H_RESPONSE M_DELETE M_GET M_OPTIONS M_POST M_PUT M_HEAD ) ] ); our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); our @EXPORT = qw( H_REQUEST H_RESPONSE M_DELETE M_GET M_OPTIONS M_POST M_PUT M_HEAD ); our $VERSION = '0.19'; sub AUTOLOAD { # This AUTOLOAD is used to 'autoload' constants from the constant() # XS function. my $constname; our $AUTOLOAD; ($constname = $AUTOLOAD) =~ s/.*:://; croak "&Perlbal::XS::HTTPHeaders::constant not defined" if $constname eq 'constant'; my ($error, $val) = constant($constname); if ($error) { croak $error; } { no strict 'refs'; # Fixed between 5.005_53 and 5.005_61 #XXX if ($] >= 5.00561) { #XXX *$AUTOLOAD = sub () { $val }; #XXX } #XXX else { *$AUTOLOAD = sub { $val }; #XXX } } goto &$AUTOLOAD; } require XSLoader; XSLoader::load('Perlbal::XS::HTTPHeaders', $VERSION); # create a very bare response to send to a user (mostly used internally) sub new_response { my $code = $_[1]; my $msg = $Perlbal::HTTPHeaders::HTTPCode->{$code} || ""; my $hdr = Perlbal::XS::HTTPHeaders->new(\"HTTP/1.0 $code $msg\r\n\r\n"); return $hdr; } # do some magic to determine content length sub content_length { my Perlbal::XS::HTTPHeaders $self = $_[0]; if ($self->isRequest()) { return 0 if $self->getMethod() == M_HEAD(); } else { my $code = $self->getStatusCode(); if ($code == 304 || $code == 204 || ($code >= 100 && $code <= 199)) { return 0; } } if (defined (my $clen = $self->getHeader('Content-length'))) { return $clen+0; } return undef; } sub set_version { my Perlbal::XS::HTTPHeaders $self = $_[0]; my $ver = $_[1]; die "Bogus version" unless $ver =~ /^(\d+)\.(\d+)$/; my ($ver_ma, $ver_mi) = ($1, $2); $self->setVersionNumber($ver_ma * 1000 + $ver_mi); return $self; } sub clone { return Perlbal::XS::HTTPHeaders->new( $_[0]->to_string_ref ); } ### Perlbal::XS interface implementation my @subs = qw{ new new_response DESTROY getReconstructed getHeader setHeader getMethod getStatusCode getVersionNumber setVersionNumber isRequest isResponse setStatusCode getURI header to_string to_string_ref code request_method request_uri response_code res_keep_alive req_keep_alive set_version content_length clone http_code_english }; sub enable { return if $Enabled; $Enabled = 1; *Perlbal::HTTPHeaders::new = *Perlbal::XS::HTTPHeaders::new; *Perlbal::HTTPHeaders::new_response = *Perlbal::XS::HTTPHeaders::new_response; return 1; } sub disable { return unless $Enabled; *Perlbal::HTTPHeaders::new_response = *Perlbal::HTTPHeaders::new_response_PERL; *Perlbal::HTTPHeaders::new = *Perlbal::HTTPHeaders::new_PERL; $Enabled = 0; return 1; } sub code { my Perlbal::XS::HTTPHeaders $self = shift; my ($code, $msg) = @_; $msg ||= $self->http_code_english($code); $self->setCodeText($code, $msg); } # save pointer to the old way of creating new objects $Perlbal::XSModules{headers} = 'Perlbal::XS::HTTPHeaders'; #enable(); # Preloaded methods go here. # Autoload methods go after =cut, and are processed by the autosplit program. 1; __END__ # Below is stub documentation for your module. You'd better edit it! # Right, I'm editing it. =head1 NAME Perlbal::XS::HTTPHeaders - Perlbal extension for processing HTTP headers. =head1 SYNOPSIS use HTTPHeaders; my $hdr = Perlbal::XS::HTTPHeaders->new("GET / HTTP/1.0\r\nConnection: keep-alive\r\n\r\n"); if ($hdr->getMethod == M_GET()) { print "GET: ", $hdr->getURI(), "\n"; print "Connection: ", $hdr->getHeader('Connection'), "\n"; } =head1 DESCRIPTION This module is used to read HTTP headers from a string and to parse them into an internal storage format for easy access and modification. You can also ask the module to reconstitute the headers into one big string, useful if you're writing a proxy and need to read and write headers while maintaining the ability to modify individual parts of the whole. The goal is to be fast. This is a lot faster than doing all of the text processing in Perl directly, and a lot of the flexibility of Perl is maintained by implementing the library in Perl and descending from Perlbal::HTTPHeaders. =head2 Exportable constants H_REQUEST H_RESPONSE M_GET M_POST M_HEAD M_OPTIONS M_PUT M_DELETE =head1 KNOWN BUGS There are no known bugs at this time. Please report any you find! =head1 SEE ALSO Perlbal, and by extension this module, can be discussed by joining the Perlbal mailing list on http://lists.danga.com/. Please see the original HTTPHeaders module implemented entirely in Perl in the Perlbal source tree available at http://cvs.danga.com/ in the wcmtools repository perlbal/lib/Perlbal/ directory. =head1 AUTHOR Mark Smith, Ejunior@danga.comE =head1 COPYRIGHT AND LICENSE Copyright (C) 2004 by Danga Interactive, Inc. Copyright (C) 2005 by Six Apart, Ltd. 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.4 or, at your option, any later version of Perl 5 you may have available. =cut