编码为array还是object
编码为array还是object
首先大家请看这段源码:
-- http://www.kyne.com.au/~mark/software/lua-cjson.php
-- version: 2.1 devel
local json = require("cjson")
ngx.say("value --> ", json.encode({dogs={}}))
输出结果
value --> {“dogs”:{}}
注意看下encode后key的值类型,“{}” 代表key的值是个object,“[]” 则代表key的值是个数组。对于强类型语言(c/c++, java等),这时候就有点不爽。因为类型不是他期望的要做容错。对于Lua本身,是把数组和字典融合到一起了,所以他是无法区分空数组和空字典的。
参考openresty-cjson中额外贴出测试案例,我们就很容易找到思路了。
-- 内容节选lua-cjson-2.1.0.2/tests/agentzh.t
=== TEST 1: empty tables as objects
--- ...
防止 SQL 注入
防止 SQL 注入
所谓 SQL 注入,就是通过把 SQL 命令插入到 Web 表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的 SQL 命令。具体来说,它是利用现有应用程序,将(恶意)的 SQL 命令注入到后台数据库引擎执行的能力,它可以通过在 Web 表单中输入(恶意)SQL 语句得到一个存在安全漏洞的网站上的数据库,而不是按照设计者意图去执行 SQL 语句。比如先前的很多影视网站泄露 VIP 会员密码大多就是通过 Web 表单递交查询字符暴出的,这类表单特别容易受到 SQL 注入式攻击。
SQL 注入例子
下面给了一个完整的可复现的 SQL 注入例子,实际上注入的 SQL 语句写法有很多,下例是比较简单的。
location /test {
content_by_lua_block {
local mysql = require "resty.mysql"
local db, err = mysql:new()
if not db then
ngx.say ...
json解析的异常捕获
json解析的异常捕获
首先来看最最普通的一个json解析的例子(被解析的json字符串是错误的,缺少一个双引号):
-- http://www.kyne.com.au/~mark/software/lua-cjson.php
-- version: 2.1 devel
local json = require("cjson")
local str = [[ {"key:"value"} ]]
local t = json.decode(str)
ngx.say(" --> ", type(t))
-- ... do the other things
ngx.say("all fine")
代码执行错误日志如下:
2015/06/27 00:01:42 [error] 2714#0: *25 lua entry thread aborted: runtime error: ...ork/git/github.com/lua-resty-memcached-server/t/tes ...
跨平台的库选择
跨平台的库选择
大家看过上面三个json的例子就发现,都是围绕cjson库的。原因也比较简单,就是cjson是默认绑定到openresty上的。很多开发喜欢 windows 系统,可以选择 dkjson(编解码效率没有cjson快,优势是纯Lua,完美跨任何平台)。
并且我们的代码肯定不会因为 win、linux 的并存而写两套程序。那么我们就必须要把json处理部分封装一下,隐藏系统差异造成的差异化处理。
local _M = { _VERSION = '1.0' }
-- require("ffi").os 获取系统类型
local json = require(require("ffi").os == "Windows" and "dkjson" or "cjson")
function _M.json_decode( str )
return json.decode(str)
end
function _M.json_encode( data )
return json.encode(data)
end
return _M
在我们的应 ...
输出响应体
输出响应体
HTTP响应报文分为三个部分:
响应行
响应头
响应体
对于 HTTP 响应体的输出,在 OpenResty 中调用 ngx.say 或 ngx.print 即可。经过查看官方 wiki ,这两者都是输出响应体,区别是 ngx.say 会对输出响应体多输出一个 \n 。如果你用的是浏览器完成的功能调试,使用这两着是没有区别的。但是如果使用各种终端工具,这时候使用 ngx.say 明显就更方便了。
ngx.say 与 ngx.print 均为异步输出
首先需要明确一下的,是这两个函数都是异步输出的,也就是说当调用 ngx.say 后并不会立刻输出响应体。参考下面的例子:
server {
listen 80;
location /test {
content_by_lua_block {
ngx.say("hello")
ngx.sleep(3)
ngx.say("the world")
} ...
Crontab在SAE中的应用。
例行性工作(crontab)
【闲话】
现在是在用蓝牙和手机无限键盘在写这篇博客,测试一下,发现用系统默认的输入法比较痛苦,不知道为什么,光标焦点在手机屏幕上飞来飞去,根本就没有办法正常的进行编辑,换了一个输入法以后,此问题基本上不发生了。
[问题]什么事crontab?
如果简单的翻译成例行性工作没错,但是对于为首次接受此概念的人说,理解上还是模棱两可的。
整体来说,crontab是用户的一个时间计划安排表,用户自定义时间表,去安排各种程序任务的执行。
[输入]
cron是Linux上的一个服务程序,并且此程序要求用户有特定的数据输入。
Linux系统:
在Linux系统上有特定的配置文件,接受用户的配置输入数据,位置实在 /etc/m目录下,文件名是crontab。
cat /etc/crontab
SAE云平台:
在SAE平台上,同样通过配置文件接受用户的输入设定数据。
稀疏数组
稀疏数组
请看示例代码(注意data的数组下标):
-- http://www.kyne.com.au/~mark/software/lua-cjson.php
-- version: 2.1 devel
local json = require("cjson")
local data = {1, 2}
data[1000] = 99
-- ... do the other things
ngx.say(json.encode(data))
运行日志报错结果:
2015/06/27 00:23:13 [error] 2714#0: *40 lua entry thread aborted: runtime error: ...ork/git/github.com/lua-resty-memcached-server/t/test.lua:13: Cannot serialise table: excessively sparse array
stack traceback:
corouti ...
环境搭建
环境搭建
实践的前提是搭建环境,本节的几个小节将介绍在几种常见操作平台上 OpenResty 的安装。
为了降低用户安装门槛,对于不同系统安装,部分章节存在比较大的重复内容。读者只需要选择自己需要的平台并尝试安装即可。除了 windows 版本是以二进制发行,其他平台由于系统自身的兼容性,推荐的都是源码编译方式。
在 OpenResty 的规划路线中,准备发行独立的 opm 安装工具(截止到目前,目前还没完成,名称可能依然会变),帮会我们完成从环境到周边库的下载、更新。
HTML转换PDF工具Prince的软件包依赖
HTML转换PDF工具Prince的软件包依赖
libxml2 libtiff5 libgif4 libfontconfig
解决jekyll主题无法处理重名问题
作者:糖果
jekyll会把多个同名的markdown文件,只生成一个html文件,需要批量的改所有markdown文件的前缀。
rename -n ‘s/^/2016-09-18-/’ *.markdown