提交 2f89274f authored 作者: zhanrongzhen's avatar zhanrongzhen

静态服务器使用更高效的openresty

上级
FROM docker.1ms.run/openresty/openresty:1.27.1.2-4-alpine-fat
# 安装必要的软件包并清理缓存
RUN opm install spacewander/luafilesystem
RUN rm /usr/local/openresty/nginx/conf/nginx.conf
# 复制配置文件和脚本
COPY detect_mime_by_magic.lua /usr/local/openresty/lualib/
COPY nginx.conf /usr/local/openresty/nginx/conf/
# 创建日志文件并设置权限
RUN touch /usr/local/openresty/nginx/logs/access.log && chmod 777 /usr/local/openresty/nginx/logs/access.log && \
touch /usr/local/openresty/nginx/logs/error.log && chmod 777 /usr/local/openresty/nginx/logs/error.log && \
ln -sf /dev/stdout /usr/local/openresty/nginx/logs/access.log && ln -sf /dev/stderr /usr/local/openresty/nginx/logs/error.log
# 启动openresty服务
CMD ["/usr/local/openresty/bin/openresty", "-g", "daemon off;"]
1、首先拉openresty镜像
docker pull docker.1ms.run/openresty/openresty:1.21.4.1-0-jammy
2、
-- detect_mime_by_magic.lua
local function detect(filepath)
local f = io.open(filepath, "rb")
if not f then return "application/octet-stream" end
local header = f:read(8) -- 读前8字节足够判断多数类型
f:close()
if not header or #header < 4 then
return "application/octet-stream"
end
-- 常见魔数(Magic Bytes)匹配
local b1, b2, b3, b4 = string.byte(header, 1, 4)
-- PNG
if b1 == 0x89 and b2 == 0x50 and b3 == 0x4E and b4 == 0x47 then
return "image/png"
end
-- JPEG
if b1 == 0xFF and b2 == 0xD8 and b3 == 0xFF then
return "image/jpeg"
end
-- GIF
if string.sub(header, 1, 3) == "GIF" then
return "image/gif"
end
-- PDF
if string.sub(header, 1, 4) == "%PDF" then
return "application/pdf"
end
-- ZIP (包括 JAR, DOCX 等)
if b1 == 0x50 and b2 == 0x4B and b3 == 0x03 and b4 == 0x04 then
return "application/zip"
end
-- WebP
if string.sub(header, 1, 4) == "RIFF" and string.sub(header, 7, 8) == "WEBP" then
return "image/webp"
end
-- JSON: 以 { 开头(简单判断)
if b1 == 0x7B then -- '{'
return "application/json"
end
-- XML: 以 <?xml 开头
if string.sub(header, 1, 5) == "<?xml" then
return "application/xml"
end
-- 文本文件(UTF-8 或 ASCII)
if b1 < 0x80 and b2 < 0x80 and b3 < 0x80 and b4 < 0x80 then
return "text/plain; charset=utf-8"
end
-- 默认未知二进制
return "application/octet-stream"
end
return detec
worker_processes auto;
error_log logs/error.log warn;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
lua_package_path "/usr/local/openresty/lualib/?.lua;;";
lua_shared_dict file_check_cache 10m;
server {
listen 8080;
server_name localhost;
# 静态资源根目录
set $root_path "/var/www/html";
#location ~ ^/static/(.+)$ {
location /resources/ {
content_by_lua_block {
local filename = string.match(ngx.var.uri, "([^/]+)$")
local current_uri = ngx.var.uri
-- 判断是不是蒙城网站的验证码
local filepath
if base_file ~= "1710935454" then -- 如果不是蒙城验证码图片
filepath = ngx.var.root_path .. "/resources/default/" .. filename
else
filepath = ngx.var.root_path .. current_uri
end
local max_retries = 10 -- 重试次数(含首次检查)
local retry_delay = 1 -- 重试延迟(秒)
ngx.log(ngx.WARN, "AFA request filpath: ", filepath, "filename: ",filename)
local mime_types = {
["html"] = "text/html",
["css"] = "text/css",
["cssx"] = "text/css",
["js"] = "application/javascript",
["json"] = "application/json",
["png"] = "image/png",
["apng"] = "image/apng",
["jpg"] = "image/jpeg",
["jpeg"] = "image/jpeg",
["jfif"] = "image/jpeg",
["gif"] = "image/gif",
["avif"] = "image/avif",
["txt"] = "text/plain",
["xml"] = "application/xml",
["pdf"] = "application/pdf",
-- 添加你需要的类型
}
local function get_mime_type(ext)
return mime_types[ext] or "application/octet-stream"
end
local lfs = require('lfs_ffi')
-- 判断文件是否存在,不存在延迟retry_delay秒后再探测,重试次数max_retries
local attributes, err
for attempt = 1, max_retries do
-- 获取文件属性
attributes, err = lfs.attributes(filepath)
if attributes then
break -- 文件存在,跳出循环
end
-- 如果文件不存在且不是最后一次尝试,则延迟后重试
if attempt < max_retries then
ngx.log(ngx.WARN, "File not found on attempt " .. attempt .. ", retrying in " .. retry_delay .. "s: ", filepath)
ngx.sleep(retry_delay) -- 关键:延迟等待
end
end
if not attributes then
ngx.log(ngx.WARN, "File not found: ", filepath, ", error: ", err)
ngx.header["Content-Type"] = "text/html; charset=utf-8"
ngx.status = ngx.HTTP_NOT_FOUND
ngx.say("<html><body><h1>404 - File Not Found</h1><p>The requested file does not exist.</p></body></html>")
return ngx.exit(ngx.HTTP_NOT_FOUND)
end
-- 2. 判断是否有扩展名
local ext = string.match(filename, "%.([^%.]+)$")
local mime_type
local detect = require "detect_mime_by_magic"
if ext then
-- mime_type = get_mime_type(ext)
-- 有扩展名,用download下载
return ngx.exec("/download/" .. filename)
else
-- 无扩展名:用 Lua 魔数检测
mime_type = detect(filepath)
end
-- 3. 设置响应头
ngx.header["Content-Type"] = mime_type
ngx.header["Content-Length"] = attributes.size
ngx.header["Cache-Control"] = "no-store, no-cache, must-revalidate, max-age=0"
ngx.header["Pragma"] = "no-cache"
ngx.header["Expires"] = "0"
local file = io.open(filepath, "rb")
if file then
ngx.say(file:read("*all"))
file:close()
else
ngx.status = 500
ngx.say("Failed to open file")
end
}
}
location /download/ {
internal; # 标记为内部 location,不允许外部直接访问
alias /var/www/html/resources/default/; # 设置文件根目录
add_header Cache-Control "no-store, no-cache, must-revalidate, max-age=0";
add_header Pragma "no-cache";
add_header Expires "0";
sendfile on;
}
# 未匹配的请求
location / {
return 404;
}
}
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论