master 6720146c9148 cached
5 files
24.5 KB
7.0k tokens
1 requests
Download .txt
Repository: hpxl/nginx-lua-fastdfs-GraphicsMagick
Branch: master
Commit: 6720146c9148
Files: 5
Total size: 24.5 KB

Directory structure:
gitextract_9ydjmjyn/

├── README.md
├── crontab.sh
├── lua/
│   ├── fastdfs.lua
│   └── restyfastdfs.lua
└── nginx.conf

================================================
FILE CONTENTS
================================================

================================================
FILE: README.md
================================================
nginx-lua-fastdfs-GraphicsMagick
==================
fastdfs开源的分布式文件系统,此脚本利用nginx lua模块,动态生成图片缩略图,fastdfs只存一份原图。lua通过socket获取fastdfs的原图,并存放到本地,根据不同规则url,例如:_60x60.jpg、_80x80.jpg,类似淘宝图片url规则。利用gm命令生成本地缩略图,第二次访问直接返回本地图片。定时任务凌晨清除7天内未访问的图片,节省空间。

图片访问举例
----------------
1. [http://192.168.1.113/group1/M00/00/00/wKgBcVN0wDiAILQXAAdtg6qArdU189.jpg](http://192.168.1.113/group1/M00/00/00/wKgBcVN0wDiAILQXAAdtg6qArdU189.jpg)
2. [http://192.168.1.113/group1/M00/00/00/wKgBcVN0wDiAILQXAAdtg6qArdU189.jpg_80x80.jpg](http://192.168.1.113/group1/M00/00/00/wKgBcVN0wDiAILQXAAdtg6qArdU189.jpg_80x80.jpg)
3. [http://gi1.md.alicdn.com/imgextra/i1/401612253/T2ASPfXE4XXXXXXXXX_!!401612253.jpg_60x60.jpg](http://gi1.md.alicdn.com/imgextra/i1/401612253/T2ASPfXE4XXXXXXXXX_!!401612253.jpg_60x60.jpg)
4. [http://gi1.md.alicdn.com/imgextra/i1/401612253/T2ASPfXE4XXXXXXXXX_!!401612253.jpg_80x80.jpg](http://gi1.md.alicdn.com/imgextra/i1/401612253/T2ASPfXE4XXXXXXXXX_!!401612253.jpg_80x80.jpg)


参考网址
----------------
1. [https://github.com/openresty/lua-nginx-module](https://github.com/openresty/lua-nginx-module)
2. [https://github.com/azurewang/Nginx_Lua-FastDFS](https://github.com/azurewang/Nginx_Lua-FastDFS)
3. [https://github.com/azurewang/lua-resty-fastdfs](https://github.com/azurewang/lua-resty-fastdfs)
4. [http://rhomobi.com/topics/23](http://rhomobi.com/topics/23)
5. [http://bbs.chinaunix.net/thread-4133106-1-1.html](http://bbs.chinaunix.net/thread-4133106-1-1.html)


================================================
FILE: crontab.sh
================================================
# 凌晨2点执行,查找目录下面7天内没有被访问的文件并删除,释放空间
0 2 * * * find /data/images -atime -7 | xargs rm -rf


================================================
FILE: lua/fastdfs.lua
================================================
-- 写入文件
local function writefile(filename, info)
    local wfile=io.open(filename, "w") --写入文件(w覆盖)
    assert(wfile)  --打开时验证是否出错		
    wfile:write(info)  --写入传入的内容
    wfile:close()  --调用结束后记得关闭
end

-- 检测路径是否目录
local function is_dir(sPath)
    if type(sPath) ~= "string" then return false end

    local response = os.execute( "cd " .. sPath )
    if response == 0 then
        return true
    end
    return false
end

-- 检测文件是否存在
local file_exists = function(name)
    local f=io.open(name,"r")
    if f~=nil then io.close(f) return true else return false end
end

local area = nil
local originalUri = ngx.var.uri;
local originalFile = ngx.var.file;
local index = string.find(ngx.var.uri, "([0-9]+)x([0-9]+)");  
if index then 
    originalUri = string.sub(ngx.var.uri, 0, index-2);  
    area = string.sub(ngx.var.uri, index);  
    index = string.find(area, "([.])");  
    area = string.sub(area, 0, index-1);  

    local index = string.find(originalFile, "([0-9]+)x([0-9]+)");  
    originalFile = string.sub(originalFile, 0, index-2)
end

-- check original file
if not file_exists(originalFile) then
    local fileid = string.sub(originalUri, 2);
    -- main
    local fastdfs = require('restyfastdfs')
    local fdfs = fastdfs:new()
    fdfs:set_tracker("192.168.1.113", 22122)
    fdfs:set_timeout(1000)
    fdfs:set_tracker_keepalive(0, 100)
    fdfs:set_storage_keepalive(0, 100)
    local data = fdfs:do_download(fileid)
    if data then
       -- check image dir
        if not is_dir(ngx.var.image_dir) then
            os.execute("mkdir -p " .. ngx.var.image_dir)
        end
        writefile(originalFile, data)
    end
end

-- 创建缩略图
local image_sizes = {"80x80", "800x600", "40x40", "60x60"};  
function table.contains(table, element)  
    for _, value in pairs(table) do  
        if value == element then
            return true  
        end  
    end  
    return false  
end 

if table.contains(image_sizes, area) then  
    local command = "gm convert " .. originalFile  .. " -thumbnail " .. area .. " -background gray -gravity center -extent " .. area .. " " .. ngx.var.file;  
    os.execute(command);  
end;

if file_exists(ngx.var.file) then
    --ngx.req.set_uri(ngx.var.uri, true);  
    ngx.exec(ngx.var.uri)
else
    ngx.exit(404)
end


================================================
FILE: lua/restyfastdfs.lua
================================================
-- Copyright (C) 2012 Azure Wang
-- @link: https://github.com/azurewang/Nginx_Lua-FastDFS

local string = string
local table  = table
local bit    = bit
local ngx    = ngx
local tonumber = tonumber
local setmetatable = setmetatable
local error = error

module(...)

local VERSION = '0.1'

local FDFS_PROTO_PKG_LEN_SIZE = 8
local TRACKER_PROTO_CMD_SERVICE_QUERY_STORE_WITHOUT_GROUP_ONE = 101
local TRACKER_PROTO_CMD_SERVICE_QUERY_STORE_WITH_GROUP_ONE = 104
local TRACKER_PROTO_CMD_SERVICE_QUERY_UPDATE = 103
local TRACKER_PROTO_CMD_SERVICE_QUERY_FETCH_ONE = 102
local STORAGE_PROTO_CMD_UPLOAD_FILE = 11
local STORAGE_PROTO_CMD_DELETE_FILE = 12
local STORAGE_PROTO_CMD_DOWNLOAD_FILE = 14
local STORAGE_PROTO_CMD_UPLOAD_SLAVE_FILE = 21
local STORAGE_PROTO_CMD_QUERY_FILE_INFO = 22
local STORAGE_PROTO_CMD_UPLOAD_APPENDER_FILE = 23
local STORAGE_PROTO_CMD_APPEND_FILE = 24
local FDFS_FILE_EXT_NAME_MAX_LEN = 6
local FDFS_PROTO_CMD_QUIT = 82
local TRACKER_PROTO_CMD_RESP = 100

local mt = { __index = _M }

function new(self)
    return setmetatable({}, mt)
end

function set_tracker(self, host, port)
    local tracker = {host = host, port = port}
    self.tracker = tracker
end

function set_timeout(self, timeout)
    if timeout then
        self.timeout = timeout
    end
end

function set_tracker_keepalive(self, timeout, size)
    local keepalive = {timeout = timeout, size = size}
    self.tracker_keepalive = keepalive
end

function set_storage_keepalive(self, timeout, size)
    local keepalive = {timeout = timeout, size = size}
    self.storage_keepalive = keepalive
end

function int2buf(n)
    -- only trans 32bit  full is 64bit
    return string.rep("\00", 4) .. string.char(bit.band(bit.rshift(n, 24), 0xff), bit.band(bit.rshift(n, 16), 0xff), bit.band(bit.rshift(n, 8), 0xff), bit.band(n, 0xff))
end

function buf2int(buf)
    -- only trans 32bit  full is 64bit
    local c1, c2, c3, c4 = string.byte(buf, 5, 8)
    return bit.bor(bit.lshift(c1, 24), bit.lshift(c2, 16),bit.lshift(c3, 8), c4)
end

function read_fdfs_header(sock)
    local header = {}
    local buf, err = sock:receive(10)
    if not buf then
        ngx.log(ngx.ERR, "fdfs: read header error")
        sock:close()
        ngx.exit(500)
    end
    header.len = buf2int(string.sub(buf, 1, 8))
    header.cmd = string.byte(buf, 9)
    header.status = string.byte(buf, 10)
    return header
end

function fix_string(str, fix_length)
    local len = string.len(str)
    if len > fix_length then
        len = fix_length
    end
    local fix_str = string.sub(str, 1, len)
    if len < fix_length then
        fix_str = fix_str .. string.rep("\00", fix_length - len )
    end
    return fix_str
end

function strip_string(str)
    local pos = string.find(str, "\00")
    if pos then
        return string.sub(str, 1, pos - 1)
    else
        return str
    end
end

function get_ext_name(filename)
    local extname = filename:match("%.(%w+)$")
    if extname then
        return fix_string(extname, FDFS_FILE_EXT_NAME_MAX_LEN)
    else
        return nil
    end
end

function read_tracket_result(sock, header)
    if header.len > 0 then
        local res = {}
        local buf = sock:receive(header.len)
        res.group_name = strip_string(string.sub(buf, 1, 16))
        res.host       = strip_string(string.sub(buf, 17, 31)) 
        res.port       = buf2int(string.sub(buf, 32, 39))
        res.store_path_index = string.byte(string.sub(buf, 40, 40))
        return res
    else
        return nil
    end
end

function read_storage_result(sock, header)
    if header.len > 0 then
        local res = {}
        local buf = sock:receive(header.len)
        res.group_name = strip_string(string.sub(buf, 1, 16))
        res.file_name  = strip_string(string.sub(buf, 17, header.len))
        return res
    else
        return nil
    end
end

function query_upload_storage(self, group_name)
    local tracker = self.tracker
    if not tracker then
        return nil
    end
    local out = {}
    if group_name then
        -- query upload with group_name
        -- package length
        table.insert(out, int2buf(16))
        -- cmd
        table.insert(out, string.char(TRACKER_PROTO_CMD_SERVICE_QUERY_STORE_WITH_GROUP_ONE))
        -- status
        table.insert(out, "\00")
        -- group name
        table.insert(out, fix_string(group_name, 16))
    else
        -- query upload without group_name
        -- package length
        table.insert(out,  string.rep("\00", FDFS_PROTO_PKG_LEN_SIZE))
        -- cmd
        table.insert(out, string.char(TRACKER_PROTO_CMD_SERVICE_QUERY_STORE_WITHOUT_GROUP_ONE))
        -- status
        table.insert(out, "\00")
    end
    -- init socket
    local sock, err = ngx.socket.tcp()
    if not sock then
        return nil, err
    end
    if self.timeout then
        sock:settimeout(self.timeout)
    end
    -- connect tracker
    local ok, err = sock:connect(tracker.host, tracker.port)
    if not ok then
        return nil, err
    end
    -- send request
    local bytes, err = sock:send(out)
    -- read request header
    local hdr = read_fdfs_header(sock)
    -- read body
    local res = read_tracket_result(sock, hdr)
    -- keepalive
    local keepalive = self.tracker_keepalive
    if keepalive then
        sock:setkeepalive(keepalive.timeout, keepalive.size)
    end
    return res
end

function do_upload_appender(self, ext_name)
    local storage = self:query_upload_storage()
    if not storage then
        return nil
    end
    -- ext_name
    if ext_name then
        ext_name = fix_string(ext_name, FDFS_FILE_EXT_NAME_MAX_LEN)
    end
    -- get file size
    local file_size = tonumber(ngx.var.content_length)
    if not file_size or file_size <= 0 then
        return nil
    end
    local sock, err = ngx.socket.tcp()
    if not sock then
        return nil, err
    end
    if self.timeout then
        sock:settimeout(self.timeout)
    end
    local ok, err = sock:connect(storage.host, storage.port)
    if not ok then
        return nil, err
    end
    -- send header
    local out = {}
    table.insert(out, int2buf(file_size + 15))
    table.insert(out, string.char(STORAGE_PROTO_CMD_UPLOAD_APPENDER_FILE))
    -- status
    table.insert(out, "\00")
    -- store_path_index
    table.insert(out, string.char(storage.store_path_index))
    -- filesize
    table.insert(out, int2buf(file_size))
    -- exitname
    table.insert(out, ext_name)
    local bytes, err = sock:send(out)
    -- send file data
    local send_count = 0
    local req_sock, err = ngx.req.socket()
    if not req_sock then
        ngx.log(ngx.ERR, err)
        ngx.exit(500)
    end
        while true do
        local chunk, _, part = req_sock:receive(1024 * 32)
        if not part then
            local bytes, err = sock:send(chunk)
            if not bytes then
                ngx.log(ngx.ngx.ERR, "fdfs: send body error")
                sock:close()
                ngx.exit(500)
            end
            send_count = send_count + bytes
        else
            -- part have data, not read full end
            local bytes, err = sock:send(part)
            if not bytes then
                ngx.log(ngx.ngx.ERR, "fdfs: send body error")
                sock:close()
                ngx.exit(500)
            end
            send_count = send_count + bytes
            break
        end
    end
    if send_count ~= file_size then
        -- send file not full
        ngx.log(ngx.ngx.ERR, "fdfs: read file body not full")
        sock:close()
        ngx.exit(500)
    end
    -- read response
    local res_hdr = read_fdfs_header(sock)
    local res = read_storage_result(sock, res_hdr)
    local keepalive = self.storage_keepalive
    if keepalive then
        sock:setkeepalive(keepalive.timeout, keepalive.size)
    end
    return res
end

function do_upload(self, ext_name)
    local storage = self:query_upload_storage()
    if not storage then
        return nil
    end
    -- ext_name
    if ext_name then
        ext_name = fix_string(ext_name, FDFS_FILE_EXT_NAME_MAX_LEN)
    end
    -- get file size
    local file_size = tonumber(ngx.var.content_length)
    if not file_size or file_size <= 0 then
        return nil
    end
    local sock, err = ngx.socket.tcp()
    if not sock then
        return nil, err
    end
    if self.timeout then
        sock:settimeout(self.timeout)
    end
    local ok, err = sock:connect(storage.host, storage.port)
    if not ok then
        return nil, err
    end
    -- send header
    local out = {}
    table.insert(out, int2buf(file_size + 15))
    table.insert(out, string.char(STORAGE_PROTO_CMD_UPLOAD_FILE))
    -- status
    table.insert(out, "\00")
    -- store_path_index
    table.insert(out, string.char(storage.store_path_index))
    -- filesize
    table.insert(out, int2buf(file_size))
    -- exitname
    table.insert(out, ext_name)
    local bytes, err = sock:send(out)
    -- send file data
    local send_count = 0
    local req_sock, err = ngx.req.socket()
    if not req_sock then
        ngx.log(ngx.ERR, err)
        ngx.exit(500)
    end
    while true do
        local chunk, _, part = req_sock:receive(1024 * 32)
        if not part then
            local bytes, err = sock:send(chunk)
            if not bytes then
                ngx.log(ngx.ngx.ERR, "fdfs: send body error")
                sock:close()
                ngx.exit(500)
            end
            send_count = send_count + bytes
        else
            -- part have data, not read full end
            local bytes, err = sock:send(part)
            if not bytes then
                ngx.log(ngx.ngx.ERR, "fdfs: send body error")
                sock:close()
                ngx.exit(500)
            end
            send_count = send_count + bytes
            break
        end
    end
    if send_count ~= file_size then
        -- send file not full
        ngx.log(ngx.ngx.ERR, "fdfs: read file body not full")
        sock:close()
        ngx.exit(500)
    end
    -- read response
    local res_hdr = read_fdfs_header(sock)
    local res = read_storage_result(sock, res_hdr)
    local keepalive = self.storage_keepalive
    if keepalive then
        sock:setkeepalive(keepalive.timeout, keepalive.size)
    end
    return res
end

function query_update_storage_ex(self, group_name, file_name)
    local out = {}
    -- package length
    table.insert(out, int2buf(16 + string.len(file_name)))
    -- cmd
    table.insert(out, string.char(TRACKER_PROTO_CMD_SERVICE_QUERY_UPDATE))
    -- status
    table.insert(out, "\00")
    -- group_name
    table.insert(out, fix_string(group_name, 16))
    -- file name
    table.insert(out, file_name)
    -- get tracker
    local tracker = self.tracker
    if not tracker then
        return nil
    end
    -- init socket
    local sock, err = ngx.socket.tcp()
    if not sock then
        return nil, err
    end
    if self.timeout then
        sock:settimeout(self.timeout)
    end
    -- connect tracker
    local ok, err = sock:connect(tracker.host, tracker.port)
    if not ok then
        return nil, err
    end
    -- send request
    local bytes, err = sock:send(out)
    -- read request header
    local hdr = read_fdfs_header(sock)
    -- read body
    local res = read_tracket_result(sock, hdr)
    -- keepalive
    local keepalive = self.tracker_keepalive
    if keepalive then
        sock:setkeepalive(keepalive.timeout, keepalive.size)
    end
    return res
end

function query_update_storage(self, fileid)
    local pos = fileid:find('/')
    if not pos then
        return nil
    else
        local group_name = fileid:sub(1, pos-1)
        local file_name  = fileid:sub(pos + 1)
        local res = self:query_update_storage_ex(group_name, file_name)
        if res then
            res.file_name = file_name
        end
        return res
    end
end

function do_delete(self, fileid)
    local storage = self:query_update_storage(fileid)
    if not storage then
        return nil
    end
    local out = {}
    table.insert(out, int2buf(16 + string.len(storage.file_name)))
    table.insert(out, string.char(STORAGE_PROTO_CMD_DELETE_FILE))
    table.insert(out, "\00")
    -- group name
    table.insert(out, fix_string(storage.group_name, 16))
    -- file name
    table.insert(out, storage.file_name)
    -- init socket
    local sock, err = ngx.socket.tcp()
    if not sock then
        return nil, err
    end
    sock:settimeout(self.timeout)
    local ok, err = sock:connect(storage.host, storage.port)
    if not ok then
        return nil, err
    end
    local bytes, err = sock:send(out)
    if not bytes then
        ngx.log(ngx.ngx.ERR, "fdfs: send body error")
        sock:close()
        ngx.exit(500)
    end
    -- read request header
    local hdr = read_fdfs_header(sock)
    local keepalive = self.storage_keepalive
    if keepalive then
        sock:setkeepalive(keepalive.timeout, keepalive.size)
    end
    return hdr
end

function query_download_storage(self, fileid)
    local pos = fileid:find('/')
    if not pos then
        return nil
    else
        local group_name = fileid:sub(1, pos-1)
        local file_name  = fileid:sub(pos + 1)
        local res = self:query_download_storage_ex(group_name, file_name)
        res.file_name = file_name
        return res
    end
end

function query_download_storage_ex(self, group_name, file_name)
    local out = {}
    -- package length
    table.insert(out, int2buf(16 + string.len(file_name)))
    -- cmd
    table.insert(out, string.char(TRACKER_PROTO_CMD_SERVICE_QUERY_FETCH_ONE))
    -- status
    table.insert(out, "\00")
    -- group_name
    table.insert(out, fix_string(group_name, 16))
    -- file name
    table.insert(out, file_name)
    -- get tracker
    local tracker = self.tracker
    if not tracker then
        return nil
    end
    -- init socket
    local sock, err = ngx.socket.tcp()
    if not sock then
        return nil, err
    end
    if self.timeout then
        sock:settimeout(self.timeout)
    end
    -- connect tracker
    local ok, err = sock:connect(tracker.host, tracker.port)
    if not ok then
        return nil, err
    end
    -- send request
    local bytes, err = sock:send(out)
    -- read request header
    local hdr = read_fdfs_header(sock)
    -- read body
    local res = read_tracket_result(sock, hdr)
    -- keepalive
    local keepalive = self.tracker_keepalive
    if keepalive then
        sock:setkeepalive(keepalive.timeout, keepalive.size)
    end
    return res
end

function do_download(self, fileid)
    local storage = self:query_download_storage(fileid)
    if not storage then
        return nil
    end
    local out = {}
    -- file_offset(8)  download_bytes(8)  group_name(16)  file_name(n)
    table.insert(out, int2buf(32 + string.len(storage.file_name)))
    table.insert(out, string.char(STORAGE_PROTO_CMD_DOWNLOAD_FILE))
    table.insert(out, "\00")
    -- file_offset  download_bytes  8 + 8
    table.insert(out, string.rep("\00", 16))
    -- group name
    table.insert(out, fix_string(storage.group_name, 16))
    -- file name
    table.insert(out, storage.file_name)
    -- init socket
    local sock, err = ngx.socket.tcp()
    if not sock then
        return nil, err
    end
    sock:settimeout(self.timeout)
    local ok, err = sock:connect(storage.host, storage.port)
    if not ok then
        return nil, err
    end
    local bytes, err = sock:send(out)
    if not bytes then
        ngx.log(ngx.ERR, "fdfs: send request error" .. err)
        sock:close()
        ngx.exit(500)
    end
    -- read request header
    local hdr = read_fdfs_header(sock)
    -- read request bodya
    local data, partial
    if hdr.len > 0 then
        data, err, partial = sock:receive(hdr.len)
        if not data then
            ngx.log(ngx.ERR, "read file body error:" .. err)
            sock:close()
            ngx.exit(500)
        end
    end
    local keepalive = self.storage_keepalive
    if keepalive then
        sock:setkeepalive(keepalive.timeout, keepalive.size)
    end
    return data
end

function do_append(self, fileid)
    local storage = self:query_update_storage(fileid)
    if not storage then
        return nil
    end
    local file_name = storage.file_name
    local file_name_len = string.len(file_name)
    -- get file size
    local file_size = tonumber(ngx.var.content_length)
    if not file_size or file_size <= 0 then
        return nil
    end
    local sock, err = ngx.socket.tcp()
    if not sock then
        return nil, err
    end
    if self.timeout then
        sock:settimeout(self.timeout)
    end
    local ok, err = sock:connect(storage.host, storage.port)
    if not ok then
        return nil, err
    end
    -- send request
    local out = {}
    table.insert(out, int2buf(file_size + file_name_len + 16))
    table.insert(out, string.char(STORAGE_PROTO_CMD_APPEND_FILE))
    -- status
    table.insert(out, "\00")
    table.insert(out, int2buf(file_name_len))
    table.insert(out, int2buf(file_size))
    table.insert(out, file_name)
    local bytes, err = sock:send(out)
    -- send file data
    local send_count = 0
    local req_sock, err = ngx.req.socket()
    if not req_sock then
        ngx.log(ngx.ERR, err)
        ngx.exit(500)
    end
    while true do
        local chunk, _, part = req_sock:receive(1024 * 32)
        if not part then
            local bytes, err = sock:send(chunk)
            if not bytes then
                ngx.log(ngx.ngx.ERR, "fdfs: send body error")
                sock:close()
                ngx.exit(500)
            end
            send_count = send_count + bytes
        else
            -- part have data, not read full end
            local bytes, err = sock:send(part)
            if not bytes then
                ngx.log(ngx.ngx.ERR, "fdfs: send body error")
                sock:close()
                ngx.exit(500)
            end
            send_count = send_count + bytes
            break
        end
    end
    if send_count ~= file_size then
        -- send file not full
        ngx.log(ngx.ngx.ERR, "fdfs: read file body not full")
        sock:close()
        ngx.exit(500)
    end
    -- read response
    local res_hdr = read_fdfs_header(sock)
    local res = read_storage_result(sock, res_hdr)
    local keepalive = self.storage_keepalive
    if keepalive then
        sock:setkeepalive(keepalive.timeout, keepalive.size)
    end
    return res_hdr
end

-- _M.query_upload_storage = query_upload_storage
-- _M.do_upload_storage    = do_upload_storage
-- _M.do_delete_storage    = do_delete_storage

local class_mt = {
    -- to prevent use of casual module global variables
    __newindex = function (table, key, val)
        error('attempt to write to undeclared variable "' .. key .. '"')
    end
}

setmetatable(_M, class_mt)


================================================
FILE: nginx.conf
================================================

#user  nobody;
worker_processes  1;

error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;
    #
    lua_package_path "/usr/local/openresty/nginx/conf/lua/?.lua;;";


    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}


    # HTTPS server
    #
    #server {
    #    listen       443 ssl;
    #    server_name  localhost;

    #    ssl_certificate      cert.pem;
    #    ssl_certificate_key  cert.key;

    #    ssl_session_cache    shared:SSL:1m;
    #    ssl_session_timeout  5m;

    #    ssl_ciphers  HIGH:!aNULL:!MD5;
    #    ssl_prefer_server_ciphers  on;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}

    server {
    	listen 80;
        location / {
            default_type text/html;
            content_by_lua '
                ngx.say("<p>hello, world</p>")
                ';
        }

        location /hello {
            default_type text/html;
            echo "hello, world";
        }

        location /group1/M00 {
            alias /data/images;

            #set $image_root "/usr/local/openresty/nginx/proxy_tmp/images";
            set $image_root "/data/images";
            if ($uri ~ "/([a-zA-Z0-9]+)/([a-zA-Z0-9]+)/([a-zA-Z0-9]+)/([a-zA-Z0-9]+)/(.*)") {
                set $image_dir "$image_root/$3/$4/";
                set $image_name "$5";
                set $file "$image_dir$image_name";
            }

            if (!-f $file) {
                # 关闭lua代码缓存,方便调试lua脚本
                #lua_code_cache off;
                content_by_lua_file "conf/lua/fastdfs.lua";
            }

            #ngx_fastdfs_module;
        }
    }
}
Download .txt
gitextract_9ydjmjyn/

├── README.md
├── crontab.sh
├── lua/
│   ├── fastdfs.lua
│   └── restyfastdfs.lua
└── nginx.conf
Condensed preview — 5 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (27K chars).
[
  {
    "path": "README.md",
    "chars": 1460,
    "preview": "nginx-lua-fastdfs-GraphicsMagick\n==================\nfastdfs开源的分布式文件系统,此脚本利用nginx lua模块,动态生成图片缩略图,fastdfs只存一份原图。lua通过sock"
  },
  {
    "path": "crontab.sh",
    "chars": 88,
    "preview": "# 凌晨2点执行,查找目录下面7天内没有被访问的文件并删除,释放空间\n0 2 * * * find /data/images -atime -7 | xargs rm -rf\n"
  },
  {
    "path": "lua/fastdfs.lua",
    "chars": 2272,
    "preview": "-- 写入文件\nlocal function writefile(filename, info)\n    local wfile=io.open(filename, \"w\") --写入文件(w覆盖)\n    assert(wfile)  -"
  },
  {
    "path": "lua/restyfastdfs.lua",
    "chars": 18760,
    "preview": "-- Copyright (C) 2012 Azure Wang\n-- @link: https://github.com/azurewang/Nginx_Lua-FastDFS\n\nlocal string = string\nlocal t"
  },
  {
    "path": "nginx.conf",
    "chars": 2492,
    "preview": "\n#user  nobody;\nworker_processes  1;\n\nerror_log  logs/error.log;\n#error_log  logs/error.log  notice;\n#error_log  logs/er"
  }
]

About this extraction

This page contains the full source code of the hpxl/nginx-lua-fastdfs-GraphicsMagick GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 5 files (24.5 KB), approximately 7.0k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!