Mojo::Message

簡(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};
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 簡(jiǎn)介 Mojo :: Message :: Request是基于RFC 7230,RFC 7231,RFC 723...
    JSON_NULL閱讀 295評(píng)論 0 0
  • 簡(jiǎn)介 Mojo :: Message :: Response是基于RFC 7230和RFC 7231的 HTTP響...
    JSON_NULL閱讀 391評(píng)論 0 0
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,973評(píng)論 19 139
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法,類(lèi)相關(guān)的語(yǔ)法,內(nèi)部類(lèi)的語(yǔ)法,繼承相關(guān)的語(yǔ)法,異常的語(yǔ)法,線(xiàn)程的語(yǔ)...
    子非魚(yú)_t_閱讀 31,767評(píng)論 18 399
  • 作者 花七妹 在有意識(shí)開(kāi)始管理自己時(shí)間之后,我詳細(xì)記錄了其中一天的時(shí)間使用情況,晚上整理在了EXCEL中,并做了一...
    花七妹閱讀 907評(píng)論 0 3