码神之路:Perl篇

Mojo::Message

2017-09-30  本文已影响13人  JSON_NULL

简介

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};
上一篇下一篇

猜你喜欢

热点阅读