什么是Plug?
看下github上说的:
A plug takes two shapes. It is a function that receives a connection and a set of options as arguments and returns the connection or it is a module that provides an init/1 function to initialize options and implement the call/2 function, receiving the connection and the initialized options, and returning the connection.
这个基本上是一段英文绕口令。。。
大致说一个plug就是
* 一个函数 或者
* 一个模块
函数
入参为
1. connection
2. 一组选项(options)
返回
1. connection
模块
这块模块提供了两个函数, 一个是 init/1 一个是 call/2。init 初始化选项(options),call 入参为 connection 还有 初始化了的选项(options)返回一个connection
这样看下来Plug类似一个middleware。
connection
Plug.Conn struct描述一个connection
elixir
%Plug.Conn{host: "www.tiddr.de",
path_info: ["bar", "baz"],
...}
数据可以从这个结构体里直接读出, 或者用 pattern match。一般使用 Plug.Conn
提供的函数来操作 connection
。比如 put_resp_content_type/2
send_resp/3
等等。
需要注意的是 connection
是不可修改的 immutable
。
Finally, keep in mind that a connection is a direct interface to the underlying web server. When you call send_resp/3 above, it will immediately send the given status and body back to the client. This makes features like streaming a breeze to work with.
文档这段看懂了,没看明白。 没有缓存?
Plug Router
一个Plug Router
就是一个 plug
,他还有自己的 plug 管道。
```elixir
defmodule AppRouter do
use Plug.Router
plug :match
plug :dispatch
get /hello
do
send_resp(conn, 200, TTTing
)
end
match _ do
send_resp(conn, 404, oops
)
end
end
``
match
这个例子里,会先调用plug,之后再调用
dispatch` plug。match 找出处理的函数, dispatch 执行这个函数。
路由是放在一个查找树里的, 所以比线性查找要快的多。
测试 plugs
Plug自带了一个 Plug.Test
模块用来方便测试plug。
```elixir
defmodule PlugTestTest do
use ExUnit.Case
use Plug.Test
@opts AppRouter.init([])
test return hello world
do
conn = conn(:get, /hello
)
conn = AppRouter.call(conn, @opts)
assert conn.state == :sent
assert conn.status == 200
assert conn.resp_body == TTTing
end
end
```
可用的Plugs
Plug 包提供了很多的 plugs
1. Plug.CSRFProtection - 提供 SCRF 包含, 当你用 Plug.Session 的时候会需要他
2. Plug.Head - 把 HEAD 头改为 GET (不知道为了什么?)
3. Plug.Logger - 日志请求
4. Plug.MethodOverride - 用头里定义的方法重载request的method (?)
5. Plug.Parsers - 根据 content-type 解析 request body
6. Plug.RequestId - 为log设置一个request ID
7. Plug.Session - session管理、存储
8. Plug.SSL - 强制要求request走SSL
9. Plug.Static - 静态文件服务
帮助模块
- Plug.Debugger - 当处理request出错的时候显示调试信息
- Plug.ErrorHandler - 出错的时候显示制定的错误页面