簡(jiǎn)介
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消息容器的抽象基類(lèi).其子類(lèi)有Mojo::Message::Request和Mojo::Message::Response。
事件
Mojo::Message繼承了Mojo::EventEmitter中的所有事件,并實(shí)現(xiàn)以下事件。
finish
$msg->on(finish => sub {
my $msg = shift;
...
});
消息構(gòu)建或解析完成后觸發(fā)。
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;
...
});
消息構(gòu)建或解析的過(guò)程中觸發(fā)。
# 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實(shí)現(xiàn)了如下屬性。
content
my $msg = $msg->content;
$msg = $msg->content(Mojo::Content::Single->new);
HTTP 消息的內(nèi)容,默認(rèn)為Mojo::Content::Single對(duì)象。
default_charset
my $charset = $msg->default_charset;
$msg = $msg->default_charset('UTF-8');
被text
方法使用的默認(rèn)字符編碼。用于從application/x-www-form-urlencoded或multipart/form-data類(lèi)型的消息體中提取數(shù)據(jù)。默認(rèn)為UTF-8。
max_line_size
my $size = $msg->max_line_size;
$msg = $msg->max_line_size(1024);
“消息”起始行被允許的最大長(zhǎng)度(以字節(jié)為單位),默認(rèn)為MOJO_MAX_LINE_SIZE環(huán)境變量的值或8192(8KiB)。
max_message_size
my $size = $msg->max_message_size;
$msg = $msg->max_message_size(1024);
“消息”體被允許的最大長(zhǎng)度(以字節(jié)為單位),默認(rèn)為MOJO_MAX_MESSAGE_SIZE環(huán)境變量的值16777216(16MiB)。設(shè)置為0表示不限制消息體的大小。
version
my $version = $msg->version;
$msg = $msg->version('1.1');
HTTP的版本信息,默認(rèn)為 1.1。
方法
Mojo::Message繼承了Mojo::EventEmitter中的所有方法,并實(shí)現(xiàn)了以下方法。
body
my $bytes = $msg->body;
$msg = $msg->body('Hello!');
獲取或重置 消息的全部?jī)?nèi)容(消息體)。
body_params
my $params = $msg->body_params;
從application/x-www-form-urlencoded 或 multipart/form-data類(lèi)型編碼的POST體中提取 HTTP請(qǐng)求的表單參數(shù)。通常返回一個(gè)Mojo::Parameters對(duì)象。
注:這個(gè)方法會(huì)對(duì)處理結(jié)果進(jìn)行緩存,所以需要確保所有內(nèi)容已經(jīng)全部傳輸完成再調(diào)用此方法。
消息體的每一塊都需要加載到內(nèi)存中進(jìn)行解析,所以你需要確保消息體不會(huì)太大。默認(rèn)情況下“請(qǐng)求”體被限制在16MiB ,“響應(yīng)”體被限制在2GiB。
# Get POST parameter names and values
my $hash = $msg->body_params->to_hash;
body_size
my $size = $msg->body_size;
“消息”內(nèi)容的尺寸(以字節(jié)為單位)。
build_body
my $bytes = $msg->build_body;
使用get_body_chunk
方法獲取全部消息體的內(nèi)容。
build_headers
my $bytes = $msg->build_headers;
使用get_header_chunk
方法獲取全部消息頭的內(nèi)容。
build_start_line
my $bytes = $msg->build_start_line;
使用get_star_line_chunk
方法獲消息的起始行內(nèi)容。
cookie
my $cookie = $msg->cookie('foo');
訪(fǎng)問(wèn)消息中的cookie,返回一個(gè)Mojo::Cookie::Request或Mojo::Cookie::Response對(duì)象。如果遇到有多個(gè)Cookie值共享同一名稱(chēng)的情況,則返回最后一個(gè);如果你想獲取這個(gè)名稱(chēng)對(duì)應(yīng)的所有值可以使用every_cookie方法。此方法會(huì)將所有Cookie進(jìn)行緩存,以后再調(diào)用將不會(huì)重新從消息頭中計(jì)算,而是使用先前的緩存;所以在所有消息頭接收完成之前,不應(yīng)該調(diào)用此方法。
# Get cookie value
say $msg->cookie('foo')->value;
cookies
my $cookies = $msg->cookies;
返回一個(gè)數(shù)組引用,數(shù)組中存儲(chǔ)的是消息頭中的所有cookie信息。需要在子類(lèi)中重載。
dom
my $dom = $msg->dom;
my $collection = $msg->dom('a[href]');
使用text方法獲取全部消息體,然后使用獲取到的消息休生成Mojo::DOM對(duì)象。如果調(diào)用此方法時(shí)傳遞了一個(gè)參數(shù),則會(huì)把這個(gè)參數(shù)作為選擇器,調(diào)用Mojo::DOM對(duì)象的find方法;這時(shí)返回的是一個(gè)Mojo::Collection對(duì)象。
注:該方法會(huì)緩存所有數(shù)據(jù),所以在整個(gè)消息體接收完成之前,不應(yīng)該調(diào)用此方法。
整個(gè)消息體的需要全部加載到內(nèi)存中進(jìn)行解析,所以你需要確保消息體不會(huì)太大。默認(rèn)情況下“請(qǐng)求”體被限制在16MiB ,“響應(yīng)”體被限制在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'});
獲取或設(shè)置消息的錯(cuò)誤信息,如果返回undef,表示沒(méi)有錯(cuò)誤信息。
# 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方法類(lèi)似,但返回的是一個(gè)數(shù)組引用,其中包含所有共享同名的cookie對(duì)象。
# Get first cookie value
say $msg->every_cookie('foo')->[0]->value;
every_upload
my $uploads = $msg->every_upload('foo');
與upload方法類(lèi)似,但返回的是一個(gè)數(shù)組引用,其中包含所有共享同名的“文件上傳對(duì)象”。
# Get content of first uploaded file
say $msg->every_upload('foo')->[0]->asset->slurp;
extract_start_line
my $bool = $msg->extract_start_line(\$str);
用字符串設(shè)置消息的起始行,需要在子類(lèi)中重載。
finish
$msg = $msg->finish;
完成消息的解析和構(gòu)建。
fix_headers
$msg = $msg->fix_headers;
確保消息具有所必須的頭部信息。
get_body_chunk
my $bytes = $msg->get_body_chunk($offset);
從特定位置獲取消息體的數(shù)據(jù)塊。需要注意的是:如果內(nèi)容是動(dòng)態(tài)生成的,則在多次調(diào)用中可能無(wú)法獲取到相同的內(nèi)容。
get_header_chunk
my $bytes = $msg->get_header_chunk($offset);
從特定位置獲取消息頭的數(shù)據(jù)塊。需要注意的是:這個(gè)方法會(huì)在獲取消息頭數(shù)據(jù)之前調(diào)用fix_headers方法。
get_start_line_chunk
my $bytes = $msg->get_start_line_chunk($offset);
從特定位置獲取消息的起始行數(shù)據(jù)塊。需要在子類(lèi)中重載。
header_size
my $size = $msg->header_size;
消息頭的尺寸(單位為字節(jié))。需要注意的是:這個(gè)方法會(huì)在獲取消息頭數(shù)據(jù)之前調(diào)用fix_headers方法。
headers
my $headers = $msg->headers;
返回當(dāng)前消息對(duì)象的消息頭,通常是Mojo::Headers對(duì)象。
# Longer version
my $headers = $msg->content->headers;
is_finished
my $bool = $msg->is_finished;
檢查消息解析或構(gòu)建是否已經(jīng)完成。
is_limit_exceeded
my $bool = $msg->is_limit_exceeded;
檢查消息中的Mojo::Content對(duì)象是否超過(guò)了'max_line_sice','max_message_size','max_buffer_size',Mojo::Headers對(duì)象是否超過(guò)了max_line_size。
json
my $value = $msg->json;
my $value = $msg->json('/foo/bar');
使用Mojo::JSON解碼消息體中的JSON數(shù)據(jù)。如果返回undef表示消息體為空或解碼失敗。如果調(diào)用此方法時(shí)傳了參數(shù),則參數(shù)會(huì)被用來(lái)從Mojo::JSON::Pointer中提取指定的值。
注:該方法會(huì)緩存所有數(shù)據(jù),所以在整個(gè)消息體接收完成之前,不應(yīng)該調(diào)用此方法。
整個(gè)消息體的需要全部加載到內(nèi)存中進(jìn)行解析,所以你需要確保消息體不會(huì)太大。默認(rèn)情況下“請(qǐng)求”體被限制在16MiB ,“響應(yīng)”體被限制在2GiB。
parse
$msg = $msg->parse('HTTP/1.1 200 OK...');
解析消息塊生成Mojo::Message對(duì)象。
start_line_size
my $size = $msg->start_line_size;
消息起始行的尺寸(單位為字節(jié))。需要在子類(lèi)中重載。
text
my $str = $msg->text;
嘗試使用Mojo::Content中的charset或當(dāng)前對(duì)象中的default_charset對(duì)消息體進(jìn)行解碼并返回。
to_string
my $str = $msg->to_string;
把整個(gè)消息中的所有內(nèi)容(起始行、頭部信息、消息體)轉(zhuǎn)換成字符串返回。實(shí)現(xiàn)代碼如下:
sub to_string {
my $self = shift;
return $self->build_start_line . $self->build_headers . $self->build_body;
}
如果消息是動(dòng)態(tài)生成的,則在多次調(diào)用中可能無(wú)法得到同樣的內(nèi)容。
upload
my $upload = $msg->upload('foo');
訪(fǎng)問(wèn)消息體中指定名稱(chēng)的 multipart/form-data 數(shù)據(jù),解析返回一個(gè)Mojo::Upload對(duì)象。如果遇到有多個(gè)“文件上傳”的值共享同一名稱(chēng)的情況,則返回最后一個(gè)“文件上傳”;如果你想獲取這個(gè)名稱(chēng)對(duì)應(yīng)的所有值可以使用every_upload方法。此方法會(huì)將所有“文件上傳”對(duì)象進(jìn)行緩存,以后再調(diào)用將不會(huì)重新從消息體中計(jì)算,而是使用先前的緩存;所以在所有消息體接收完成之前,不應(yīng)該調(diào)用此方法。
# Get content of uploaded file
say $msg->upload('foo')->asset->slurp;
uploads
my $uploads = $msg->uploads;
返回一個(gè)包含所有 multipart/form-data 類(lèi)型“文件上傳”數(shù)據(jù)的Mojo::Upload對(duì)象組成的數(shù)組引用。
# Names of all uploads
say $_->name for @{$msg->uploads};