HTTP::Bodyと互換性のある HTTPのEntityをパースするモジュールをリリースしました。

https://metacpan.org/release/HTTP-Entity-Parser
https://github.com/kazeburo/HTTP-Entity-Parser/

HTTPのEntityってのは、こういう範囲を指します。

POST /foo HTTP/1.1          # Not part of the entity.
Content-Type: text/plain    # ┬ The entity is from this line down...
Content-Length: 1234        # │
                            # │
Hello, World! ...           # ┘

元ネタは「java - What exactly is an HTTP Entity? - Stack Overflow

HTTP::Entity::Parserの使い方はこんな感じ。

use HTTP::Entity::Parser;

my $parser = HTTP::Entity::Parser->new;
$parser->register('application/x-www-form-urlencoded','HTTP::Entity::Parser::UrlEncoded');
$parser->register('multipart/form-data','HTTP::Entity::Parser::MultiPart');
$parser->register('application/json','HTTP::Entity::Parser::JSON');

sub app {
    my $env = shift;
    my ( $params, $uploads) = $parser->parse($env);
}

このモジュール、元々は tokuhirom の Plackへのpullreqにあるものですが、「だれか別モジュールにして」とのことでしたので、テスト書いてHTTP::Bodyとの互換性を検証して、リリースしました。

このモジュールの開発動機はこのスライドにありますね。ただ、スライド中にでてくるURL::Encodeは互換性の問題で使ってません。

公平かどうか微妙かもですが、一応ベンチマーク。

#!/usr/bin/perl

use strict;
use warnings;
use HTTP::Entity::Parser;
use HTTP::Body;
use Benchmark qw/:all/;

my $content = 'xxx=hogehoge&yyy=aaaaaaaaaaaaaaaaaaaaa';

my $parser = HTTP::Entity::Parser->new;
$parser->register('application/x-www-form-urlencoded','HTTP::Entity::Parser::UrlEncoded');

cmpthese(timethese(-1, {
    'http_entity' => sub {
        open my $input, '<', \$content;
        my $env = {
            'psgi.input' => $input,
            'psgix.input.buffered' => 1,
            CONTENT_LENGTH => length($content),
            CONTENT_TYPE => 'application/x-www-form-urlencoded',
        };
        $parser->parse($env);
    },
    'http_body' => sub {
        open my $input, '<', \$content;
        my $body   = HTTP::Body->new( 'application/x-www-form-urlencoded', length($content) );
        $input->read( my $buffer, 8192);
        $body->add($buffer);
        $body->param;
    }
}));

__END__
Benchmark: running http_body, http_entity for at least 1 CPU seconds...
 http_body:  1 wallclock secs ( 1.08 usr +  0.00 sys =  1.08 CPU) @ 36201.85/s (n=39098)
http_entity:  1 wallclock secs ( 1.10 usr +  0.01 sys =  1.11 CPU) @ 51661.26/s (n=57344)
               Rate   http_body http_entity
http_body   36202/s          --        -30%
http_entity 51661/s         43%          --

NYTProfでプロファイルをとると、application/x-www-form-urlencodedのパースがそれなりの時間を占めるので、互換性があるXSモジュールがあるともう少し速くなるんじゃないかなーと思ってる。

このブログ記事について

このページは、Masahiro Naganoが2014年2月 5日 14:51に書いたブログ記事です。

ひとつ前のブログ記事は「Q4Mを簡単に導入する方法 for MySQL 5.6」です。

次のブログ記事は「Just released WWW::Form::UrlEncoded and HTTP::Entity::Parser 0.03. Faster than ever」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

ウェブページ

OpenID対応しています OpenIDについて
Powered by Movable Type 4.27-ja