Khi sử dụng nginx và bản đồ, có thể viết lại nhiều URL bằng tệp bản đồ. Vấn đề là khi URL chứa các ký tự đặc biệt. Tôi đã suy nghĩ rất nhiều để cố gắng giải quyết vấn đề này và hy vọng Câu hỏi/Giải pháp này có thể cứu những người khác khỏi tóc bạc.
Hãy thiết lập kịch bản.
Một máy chủ Linux (Debian/Ubuntu) chạy nginx tiêu chuẩn.
DNS trỏ đến máy chủ này phân giải thành cấu hình máy chủ.
Bản đồ không chứa các mục nhập trùng lặp với URL đến và đi (có thể giải quyết)
Thiết lập bản đồ sẽ chứa những điều sau đây:
bản đồ $host$request_uri $rewrite_uri {
bao gồm /<đường dẫn đến tên tệp>;
}
bản thân tệp bản đồ chứa một mục trên mỗi dòng được kết thúc bằng dấu chấm phẩy.
example.com/Böhme https://anotherexample.org/SomeWeirdPath/Böhme;
Cấu hình máy chủ để ánh xạ này hoạt động
người phục vụ {
nghe 443 ssl http2;
ssl_certificate /<đường dẫn tuyệt đối tới tệp crt>;
ssl_certificate_key /<đường dẫn tuyệt đối tới tệp khóa>;
server_name example.com;
proxy_set_header X-Forwarded-For $remote_addr;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers CAO:!aNULL:!MD5;
ssl_dhparam <đường dẫn tuyệt đối đến khóa Diffie Hellman>;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
server_tokens tắt;
nếu ($rewrite_uri) {
viết lại ^ chuyển hướng $rewrite_uri;
}
viết lại chuyển hướng ^ <URL mặc định>;
}
Tôi đã đơn giản hóa cấu hình của cấu hình máy chủ này để chúng tôi có thể tập trung vào cài đặt bản đồ.Cấu hình giả định rằng miền sẽ sử dụng SSL và chứng chỉ hợp lệ. Câu lệnh if sẽ chỉ thực thi nếu $host$request_uri nằm trong danh sách có $rewrite_uri, nếu không thì lần viết lại cuối cùng sẽ được thực thi.
Câu hỏi
Làm cách nào để chuyển đổi $request_uri để nginx hiểu chính xác? Tệp bản đồ chứa giá trị ở dạng UTF8, nhưng có vẻ như nginx muốn URL $request_uri được mã hóa và ở dạng thập lục phân.
$request_uri như trong mapfile
example.com/Böhme
$request_uri URLĐược mã hóa theo Trình duyệt
example.com/B%C3%B6hme
$request_uri vì tôi nghĩ nginx muốn nó
example.com/B\xC3\xB6hme
Tôi dường như không thể tìm thấy một gói hệ thống có tính năng này, nhưng tôi nghĩ rằng tôi đang bắt đầu phát minh lại bánh xe ở đây.
tôi sẽ cần phải:
tạo một hàm sẽ mã hóa URL danh sách,
theo Làm cách nào để giải mã chuỗi được mã hóa URL trong shell?
hàm urldecode() { local i="${*//+/ }"; tiếng vang -e "${i//%/\x}"; }
và sau đó sử dụng kết xuất Octal theo Chuyển đổi chuỗi thành thập lục phân trên dòng lệnh, do đó, bộ chứa bản đồ được tạo trong bộ nhớ với các giá trị chính xác cho nếu kiểm tra tuyên bố.
Nó bắt đầu giống như khoa học tên lửa và tôi không thể tin rằng chưa có ai khác giải quyết vấn đề này trước đây, tôi dường như không thể tìm ra giải pháp.