Mojo::Message

简介

package Mojo::Message::MyMessage;
use Mojo::Base 'Mojo::Message';

sub cookies              {...}
sub extract_start_line   {...}
sub get_start_line_chunk {...}
sub start_line_size      {...}

Mojo :: Message是基于RFC 7230,RFC 7231和RFC 2388的 HTTP消息容器的抽象基类.其子类有Mojo::Message::Request和Mojo::Message::Response。

事件

Mojo::Message继承了Mojo::EventEmitter中的所有事件,并实现以下事件。

finish

$msg->on(finish => sub {
  my $msg = shift;
  ...
});

消息构建或解析完成后触发。

my $before = time;
$msg->on(finish => sub {
  my $msg = shift;
  $msg->headers->header('X-Parser-Time' => time - $before);
});

progress

$msg->on(progress => sub {
  my $msg = shift;
  ...
});

消息构建或解析的过程中触发。

# Building
$msg->on(progress => sub {
  my ($msg, $state, $offset) = @_;
  say qq{Building "$state" at offset $offset};
});

# Parsing
$msg->on(progress => sub {
  my $msg = shift;
  return unless my $len = $msg->headers->content_length;
  my $size = $msg->content->progress;
  say 'Progress: ', $size == $len ? 100 : int($size / ($len / 100)), '%';
});

属性

Mojo::Message实现了如下属性。

content

my $msg = $msg->content;
$msg    = $msg->content(Mojo::Content::Single->new);

HTTP 消息的内容,默认为Mojo::Content::Single对象。

default_charset

my $charset = $msg->default_charset;
$msg        = $msg->default_charset('UTF-8');

text方法使用的默认字符编码。用于从application/x-www-form-urlencoded或multipart/form-data类型的消息体中提取数据。默认为UTF-8。

max_line_size

my $size = $msg->max_line_size;
$msg     = $msg->max_line_size(1024);

“消息”起始行被允许的最大长度(以字节为单位),默认为MOJO_MAX_LINE_SIZE环境变量的值或8192(8KiB)。

max_message_size

my $size = $msg->max_message_size;
$msg     = $msg->max_message_size(1024);

“消息”体被允许的最大长度(以字节为单位),默认为MOJO_MAX_MESSAGE_SIZE环境变量的值16777216(16MiB)。设置为0表示不限制消息体的大小。

version

my $version = $msg->version;
$msg        = $msg->version('1.1');

HTTP的版本信息,默认为 1.1。

方法

Mojo::Message继承了Mojo::EventEmitter中的所有方法,并实现了以下方法。

body

my $bytes = $msg->body;
$msg      = $msg->body('Hello!');

获取或重置 消息的全部内容(消息体)。

body_params

my $params = $msg->body_params;

从application/x-www-form-urlencoded 或 multipart/form-data类型编码的POST体中提取 HTTP请求的表单参数。通常返回一个Mojo::Parameters对象。

注:这个方法会对处理结果进行缓存,所以需要确保所有内容已经全部传输完成再调用此方法。

消息体的每一块都需要加载到内存中进行解析,所以你需要确保消息体不会太大。默认情况下“请求”体被限制在16MiB ,“响应”体被限制在2GiB。

# Get POST parameter names and values
my $hash = $msg->body_params->to_hash;

body_size

my $size = $msg->body_size;

“消息”内容的尺寸(以字节为单位)。

build_body

my $bytes = $msg->build_body;

使用get_body_chunk方法获取全部消息体的内容。

build_headers

my $bytes = $msg->build_headers;

使用get_header_chunk方法获取全部消息头的内容。

build_start_line

my $bytes = $msg->build_start_line;

使用get_star_line_chunk方法获消息的起始行内容。

cookie

my $cookie = $msg->cookie('foo');

访问消息中的cookie,返回一个Mojo::Cookie::Request或Mojo::Cookie::Response对象。如果遇到有多个Cookie值共享同一名称的情况,则返回最后一个;如果你想获取这个名称对应的所有值可以使用every_cookie方法。此方法会将所有Cookie进行缓存,以后再调用将不会重新从消息头中计算,而是使用先前的缓存;所以在所有消息头接收完成之前,不应该调用此方法。

# Get cookie value
say $msg->cookie('foo')->value;

cookies

my $cookies = $msg->cookies;

返回一个数组引用,数组中存储的是消息头中的所有cookie信息。需要在子类中重载。

dom

my $dom        = $msg->dom;
my $collection = $msg->dom('a[href]');

使用text方法获取全部消息体,然后使用获取到的消息休生成Mojo::DOM对象。如果调用此方法时传递了一个参数,则会把这个参数作为选择器,调用Mojo::DOM对象的find方法;这时返回的是一个Mojo::Collection对象。

注:该方法会缓存所有数据,所以在整个消息体接收完成之前,不应该调用此方法。

整个消息体的需要全部加载到内存中进行解析,所以你需要确保消息体不会太大。默认情况下“请求”体被限制在16MiB ,“响应”体被限制在2GiB。

# Perform "find" right away
say $msg->dom('h1, h2, h3')->map('text')->join("\n");

# Use everything else Mojo::DOM has to offer
say $msg->dom->at('title')->text;
say $msg->dom->at('body')->children->map('tag')->uniq->join("\n");

error

my $err = $msg->error;
$msg    = $msg->error({message => 'Parser error'});

获取或设置消息的错误信息,如果返回undef,表示没有错误信息。

# Connection or parser error
$msg->error({message => 'Connection refused'});

# 4xx/5xx response
$msg->error({message => 'Internal Server Error', code => 500});

every_cookie

my $cookies = $msg->every_cookie('foo');

与cookie方法类似,但返回的是一个数组引用,其中包含所有共享同名的cookie对象。

# Get first cookie value
say $msg->every_cookie('foo')->[0]->value;

every_upload

my $uploads = $msg->every_upload('foo');

与upload方法类似,但返回的是一个数组引用,其中包含所有共享同名的“文件上传对象”。

# Get content of first uploaded file
say $msg->every_upload('foo')->[0]->asset->slurp;

extract_start_line

my $bool = $msg->extract_start_line(\$str);

用字符串设置消息的起始行,需要在子类中重载。

finish

$msg = $msg->finish;

完成消息的解析和构建。

fix_headers

$msg = $msg->fix_headers;

确保消息具有所必须的头部信息。

get_body_chunk

my $bytes = $msg->get_body_chunk($offset);

从特定位置获取消息体的数据块。需要注意的是:如果内容是动态生成的,则在多次调用中可能无法获取到相同的内容。

get_header_chunk

my $bytes = $msg->get_header_chunk($offset);

从特定位置获取消息头的数据块。需要注意的是:这个方法会在获取消息头数据之前调用fix_headers方法。

get_start_line_chunk

my $bytes = $msg->get_start_line_chunk($offset);

从特定位置获取消息的起始行数据块。需要在子类中重载。

header_size

my $size = $msg->header_size;

消息头的尺寸(单位为字节)。需要注意的是:这个方法会在获取消息头数据之前调用fix_headers方法。

headers

my $headers = $msg->headers;

返回当前消息对象的消息头,通常是Mojo::Headers对象。

# Longer version
my $headers = $msg->content->headers;

is_finished

my $bool = $msg->is_finished;

检查消息解析或构建是否已经完成。

is_limit_exceeded

my $bool = $msg->is_limit_exceeded;

检查消息中的Mojo::Content对象是否超过了'max_line_sice','max_message_size','max_buffer_size',Mojo::Headers对象是否超过了max_line_size。

json

my $value = $msg->json;
my $value = $msg->json('/foo/bar');

使用Mojo::JSON解码消息体中的JSON数据。如果返回undef表示消息体为空或解码失败。如果调用此方法时传了参数,则参数会被用来从Mojo::JSON::Pointer中提取指定的值。

注:该方法会缓存所有数据,所以在整个消息体接收完成之前,不应该调用此方法。

整个消息体的需要全部加载到内存中进行解析,所以你需要确保消息体不会太大。默认情况下“请求”体被限制在16MiB ,“响应”体被限制在2GiB。

parse

$msg = $msg->parse('HTTP/1.1 200 OK...');

解析消息块生成Mojo::Message对象。

start_line_size

my $size = $msg->start_line_size;

消息起始行的尺寸(单位为字节)。需要在子类中重载。

text

my $str = $msg->text;

尝试使用Mojo::Content中的charset或当前对象中的default_charset对消息体进行解码并返回。

to_string

my $str = $msg->to_string;

把整个消息中的所有内容(起始行、头部信息、消息体)转换成字符串返回。实现代码如下:

sub to_string {
  my $self = shift;
  return $self->build_start_line . $self->build_headers . $self->build_body;
}

如果消息是动态生成的,则在多次调用中可能无法得到同样的内容。

upload

my $upload = $msg->upload('foo');

访问消息体中指定名称的 multipart/form-data 数据,解析返回一个Mojo::Upload对象。如果遇到有多个“文件上传”的值共享同一名称的情况,则返回最后一个“文件上传”;如果你想获取这个名称对应的所有值可以使用every_upload方法。此方法会将所有“文件上传”对象进行缓存,以后再调用将不会重新从消息体中计算,而是使用先前的缓存;所以在所有消息体接收完成之前,不应该调用此方法。

# Get content of uploaded file
say $msg->upload('foo')->asset->slurp;

uploads

my $uploads = $msg->uploads;

返回一个包含所有 multipart/form-data 类型“文件上传”数据的Mojo::Upload对象组成的数组引用。

# Names of all uploads
say $_->name for @{$msg->uploads};
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 195,980评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,422评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,130评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,553评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,408评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,326评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,720评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,373评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,678评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,722评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,486评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,335评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,738评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,283评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,692评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,893评论 2 335

推荐阅读更多精彩内容

  • 简介 Mojo :: Message :: Request是基于RFC 7230,RFC 7231,RFC 723...
    JSON_NULL阅读 259评论 0 0
  • 简介 Mojo :: Message :: Response是基于RFC 7230和RFC 7231的 HTTP响...
    JSON_NULL阅读 369评论 0 0
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,510评论 18 139
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,513评论 18 399
  • 作者 花七妹 在有意识开始管理自己时间之后,我详细记录了其中一天的时间使用情况,晚上整理在了EXCEL中,并做了一...
    花七妹阅读 867评论 0 3