# nginx-upload-return-200 **Repository Path**: dev_ma/nginx-upload-return-200 ## Basic Information - **Project Name**: nginx-upload-return-200 - **Description**: nginx with upload module and return 200 without upstream backend - **Primary Language**: C - **License**: GPL-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 1 - **Created**: 2025-01-05 - **Last Updated**: 2025-07-14 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # nginx-upload-return-200 * [介绍](#介绍) * [成功运行平台](#成功运行平台) * [安装编译环境](#安装编译环境) * [1. Cygwin环境](#1--cygwin环境) * [2. MinGW64环境](#2--mingw64环境) * [3. MinGW32环境](#3--mingw32环境) * [4. Ubuntu环境](#4--ubuntu环境) * [使用说明](#使用说明) * [1. 编译](#1--编译) * [2. 模块加载](#2--模块加载) * [3. Nginx UTF8](#3--nginx-utf8) * [4. C99 variadic macros](#4--c99-variadic-macros) * [5. curl post](#5--curl-post) * [上传](#上传) * [断点续传](#断点续传) * [Post body sample](#post-body-sample) * [UTF-8 filename](#utf-8-filename) * [6. Run nginx and dump logs](#6--run-nginx-and-dump-logs) * [7. Check uploaded files](#7--check-uploaded-files) * [8. Check errors in log](#8--check-errors-in-log) * [补丁文件](#补丁文件) * [1. http-upload-module patch](#1-http-upload-module-patch) * [2. nginx-release patch](#2-nginx-release-patch) * [3. markdown.perl.patch](#3-markdownperlpatch) * [工具](#工具) * [1. gen-rd-patches.sh](#1-gen-rd-patchessh) * [2. apl-rd-patches.sh](#2-apl-rd-patchessh) * [3. gen-md-toc.sh](#3-gen-md-tocsh) * [4. playList.html](#4-playlisthtml) * [5. upload.js](#5-uploadjs) * [已知问题](#已知问题) * [1. Microsoft-WebDAV-MiniRedir of Windows File Explorer not work with Webdav via https](#1-microsoft-webdav-miniredir-of-windows-file-explorer-not-work-with-webdav-via-https) * [2. MinGW UCRT64 console fails to run cmd.exe with commands](#2-mingw-ucrt64-console-fails-to-run-cmdexe-with-commands) ## 介绍 一个程序独立运行 Nginx with upload module and return 200 without upstream backend. Ningx服务器集成多个功能,包括文件上传和webdav。 编译 ``` sh build.nginx.sh ``` Yocto build请参见"meta-poky-patch/README.txt". 运行 ``` # run in MinGW, Cygwin and Linux ( set -xv; cd nginx-release-1.24.0._install && mkdir -p logs temp && sbin/nginx -p $(pwd) -c conf/nginx.conf; echo $? ) # run in cmd.exe cmd /c "echo on && cd nginx-release-1.24.0._install && sbin\nginx -p . -c conf/nginx.conf && echo cmd.exe run nginx OK" ``` 浏览器中查探 http://127.0.0.1:8080 cmd.exe中可以直接运行Cygwin和MinGW中编译出来的。 ## 成功运行平台 俺旧电脑编译环境 ``` uname -a gcc -v ``` Ubuntu 20.04.1 LTS in LXC container, x86\_64-linux-gnu gcc version 9.3.0 (Ubuntu 9.3.0-17ubuntu1~20.04) CYGWIN\_NT-10.0 hostname 2.5.2(0.297/5/3) 2016-06-23 14:29 x86\_64 Cygwin, x86\_64-pc-cygwin gcc version 5.4.0 (GCC) MINGW64\_NT-10.0-17134 hostname 3.4.10.x86\_64 2023-12-22 10:06 UTC x86\_64 Msys, x86\_64-w64-mingw32 gcc version 13.2.0 (Rev3, Built by MSYS2 project) MINGW32\_NT-6.2 hostname 1.0.19(0.48/3/2) 2016-07-13 17:45 i686 Msys, mingw32 gcc version 6.3.0 (MinGW.org GCC-6.3.0-1) ## 安装编译环境 ### 1. Cygwin环境 最接近俺的是这个版本 ``` http://ctm.crouchingtigerhiddenfruitbat.org/pub/cygwin/setup/snapshots/setup-x86_64-2.874.exe http://www.crouchingtigerhiddenfruitbat.org/Cygwin/timemachine.html ``` 安装 ``` setup-x86_64.exe --help setup-x86_64.exe --no-admin --package-manager --only-site --site http://ctm.crouchingtigerhiddenfruitbat.org/pub/cygwin/circa/64bit/2016/07/25/221302 --no-verify --local-package-dir %cd% ``` 得安装GCC-5.4和libcrypt-devel。 ### 2. MinGW64环境 俺用的是这个版本 ``` https://repo.msys2.org/distrib/x86_64/ https://github.com/msys2/msys2-installer/releases/tag/2024-01-13 msys2-base-x86_64-20240113.tar.xz ``` 安装GCC mingw-w64-ucrt-x86\_64-gcc 13.2.0-3 ``` pacman -v -S mingw-w64-ucrt-x86_64-gcc ``` 安装libcrypt-devel ``` pacman -v -S libxcrypt-devel ``` ### 3. MinGW32环境 俺用的是这个版本 ``` https://sourceforge.net/projects/mingw/files/Installer/ mingw-get-setup.exe 0.6.2-beta-20131004-1, 0.602.22340.1 ``` 木有命令行,只能点鼠标。安装gcc-6.3和libcrypt-devel。 ### 4. Ubuntu环境 Ubuntu 20.04.1 LTS, x86\_64-linux-gnu gcc-9.3.0 Host lxd and lxc version 4.0.10. ``` https://documentation.ubuntu.com/lxd/ ``` 俺电脑快满盘了,木有再试docker。 ## 使用说明 ### 1. 编译 遇事不决看帮助 ``` sh build.nginx.sh -h ``` 有问题先运行 ``` sh -xv build.nginx.sh -vv 2>&1 | tee build.nginx.log ``` 再查看build.nginx.log ### 2. 模块加载 模块加载多出在依赖库跟nginx.exe不在一个目录,或者库文件名木进符号表。 ``` # In MinGW64 and Cygwin, check loaded dll and so files in proc maps file "/proc//maps". grep -i -e '\.so' -e '\.dll' /proc/54321/maps # check symble table objdump -x nginx-release-1.24.0.build/objs/ngx_http_dav_ext_module.so | grep NEEDED ``` MinGW GCC-6.3有个缺陷 Need linker options: -static-libgcc -static-libstdc++ Or need dll file: libgcc\_s\_dw2-1.dll ``` https://stackoverflow.com/questions/4702732/the-program-cant-start-because-libgcc-s-dw2-1-dll-is-missing ``` ### 3. Nginx UTF8 Nginx-1.20 built in MinGW autoindex module output charset is CP936 (GB2312). But built in Cygwin autoindex output charset is UTF-8. In Windows and MinGW, autoindex charset shall match "Current code page" of "cmd.exe". In Linux and Cygwin, autoindex charset shall match "LANG" and "LC\_" env var of bash. In Windows and nginx is built by MinGW, When charset is not utf-8, browser display well, but cannot download file. To solve this problem, patches needed. The fix is merged since nginx-1.23.4. ``` https://github.com/myfreeer/nginx-build-msys2 https://github.com/nginx/nginx/commits/release-1.23.4/src/os/win32 ``` 一言难尽,上代码。 ``` /* # Test gcc string encoding and terminal charset # # Check charset of terminal # Mintty Terminal emulator settings -> Text -> Character set # Windows cmd.exe window -> Properties -> Current code page # # Compile ( set -xv; env | grep -i -e utf -e LC_ -e LANG; gcc -g -Wall -o u utf8.c && ( LC_ALL=en_US.UTF-8; LC_CTYPE=en_US.UTF-8; LANG=en_US.UTF-8; export LC_CTYPE LC_ALL LANG; gcc -g -Wall -o u.e utf8.c ) && gcc -fexec-charset=utf-8 -g -Wall -o u.fu utf8.c && gcc -fexec-charset=gb2312 -g -Wall -o u.fg utf8.c; echo rt=$? ) # # Run tests in Cygwin, MinGW32 and MinGW64 ( set -xv; env | grep -i -e utf -e LC_ -e LANG; ./u && ./u.e && ./u.fu && ./u.fg && ( LC_ALL=en_US.UTF-8; LC_CTYPE=en_US.UTF-8; LANG=en_US.UTF-8; export LC_CTYPE LC_ALL LANG; ./u.e ) && ./u | iconv -f utf-8 -t cp936 && ./u.fg -f gb2312 -t utf-8 && ./u | iconv -f cp936 -t utf-8 && ./u.fg -f utf-8 -t gb2312; echo rt=$? ) # Run tests in Windows cmd.exe cmd /c "echo on && .\u && .\u.e && .\u.fu && .\u.fg && echo OK" */ #include int main( int argc, char * agrv[]) { printf("Hello.\n"); printf("LuanMa乱码LuanMa\n"); printf("End.\n"); // return 0; } ``` 在各种终端运行更头晕。 ### 4. C99 variadic macros 好东西,好使。 ``` https://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html https://en.wikipedia.org/wiki/Variadic_macro_in_the_C_preprocessor ``` ### 5. curl post #### 上传 上传文件b.log和t.exe ``` ( set -xv; history | tail -n1; curl --output - --dump-header - --include --verbose --progress-bar --insecure --user usr:123 -F "useruploadfile[]=@\"b.log\"" -F "useruploadfile[]=@\"t.exe\"" -F "description=SomeDescription" http://127.0.0.1:8080/ptupload/doupload && d=nginx-release-1.24.0._install/logs && for i in $d/*.log; do cat $i; done; echo rt=$? ) 2>&1 | tee curl.upload.log ``` #### 断点续传 ``` ( set -xv; history | tail -n1; f=b.log; s=$(stat -c %s "$f"); e=$(( $s / 2 + 1)); dd if="$f" of="$f.pt1" bs=$e count=1 && curl --output - --dump-header - --include --verbose --progress-bar --insecure --user usr:123 -H "Session-ID: 0123456789" -H "Content-Range: bytes 0-$(( $e - 1 ))/$s" -H "Content-Type: application/octet-stream" -H "Content-Disposition: form-data; name=\"useruploadfile.name\"; filename=\"$f\"" --data-binary @"$f.pt1" http://127.0.0.1:8080/ptupload/doupload && dd if="$f" of="$f.pt2" bs=$e skip=1 count=1 && curl --output - --dump-header - --include --verbose --progress-bar --insecure --user usr:123 -H "Session-ID: 0123456789" -H "Content-Range: bytes $e-$(( $s - 1 ))/$s" -H "Content-Type: application/octet-stream" -H "Content-Disposition: form-data; name=\"useruploadfile.name\"; filename=\"$f\"" --data-binary @"$f.pt2" http://127.0.0.1:8080/ptupload/doupload && d=nginx-release-1.24.0._install/logs && for i in $d/*.log; do cat $i; done; echo rt=$? ) 2>&1 | tee curl.upload.log ``` 参考资料 ``` https://developer.mozilla.org/en-US/docs/Web/HTTP/Range_requests https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Range https://curl.se/docs/manpage.html#--data-binary ``` #### Post body sample ``` --------------------------d2f4c15433d52118 Content-Disposition: form-data; name="useruploadfile.name" "b.log" --------------------------d2f4c15433d52118 # Content-Disposition: form-data; name="file1"; filename="..."^M # Content-Type: application/octet-stream^M ``` #### UTF-8 filename curl-7.64 failed to post UTF-8 filename, curl-8.5 works well. ``` https://superuser.com/questions/1338056/how-can-i-upload-a-file-using-curl-instead-of-the-form https://github.com/curl/curl/issues/1888 ( set -xv; history | tail -n1; curl --output - --dump-header - --include --verbose --progress-bar --insecure -H "Content-Type: multipart/form-data; charset=UTF-8" --user usr:123 -F "useruploadfile[]=@\"b.log\"" -F "file=@\"莫言 :人类的好日子不多了,文学也将毫无意义.html\";filename*=utf-8''\"莫言:人类的好日子不多了 ,文学也将毫无意义.html\"" -F "description=SomeDescription" http://127.0.0.1:8080/ptupload/doupload && d=nginx-release-1.24.0._install/logs && for i in $d/*.log; do echo cat $i; done; echo rt=$? ) 2>&1 ``` ### 6. Run nginx and dump logs ``` ( set -xv; cd nginx-release-1.24.0._install || exit $?; mkdir -p logs temp && echo | tee logs/access.log logs/error.log && { tail -F logs/* logs/nginx.pid & eval pt=\$\!; ( set +xv; while true; do sleep 3; [ -e logs/nginx.pid ] || break; done; set -xv; kill $pt; sleep 1; ps -ef | grep -i -e nginx -e tail ) & } && pwd && sbin/nginx -p $(pwd) -c conf/nginx.conf ; echo $? ) ``` ### 7. Check uploaded files ``` ( set -xv; d=nginx-release-1.24.0._install/upload/upload_store; find "$d/" -name '*.sum.txt' | while read f; do i=${f%.sum.txt}; printf "%s *$i\n" $(grep -o -e 'md5=.*' "$f" | cut -d= -f2) | tee -a _s_.md5.txt && printf "%s *$i\n" $(grep -o -e 'sha256=.*' "$f" | cut -d= -f2) | tee -a _s_.sha256.txt || exit $?; done && md5sum -c _s_.md5.txt && sha256sum -c _s_.sha256.txt && rm _s_.md5.txt _s_.sha256.txt; echo rt=$? ) ``` ### 8. Check errors in log ``` grep -i -e Unexpect -e fail -e error -e abnorm -e abort nginx-release-1.24.0._install/logs/error.log | grep -v -e SSL_get_error -e 'http script value' -e 'http script var' ``` ## 补丁文件 补丁文件都放在patches目录。 ### 1. http-upload-module patch 源码来自:`https://github.com/fdintino/nginx-upload-module` 采用版本:2.3.0 新增功能和配置参数请参考"README.en.md" ### 2. nginx-release patch 主要针对MinGW和Cygwin中编译遇到的问题。 源码来自:`https://github.com/nginx/nginx/` 采用版本:1.24.0 从官网(nginx.org)下载的源码无法在MinGW中编译。"src/os/win32" only exists in source tarball from github. ### 3. markdown.perl.patch Ubuntu有个工具markdown,将markdown文档转成html。 源码来自:`https://daringfireball.net/projects/downloads/Markdown_1.0.1.zip` Ubuntu有改动。此处再次改动,更好支持code block。 ## 工具 期间用到几个小工具。 ### 1. gen-rd-patches.sh 将改动分成Debug补丁和Realease补丁。 ### 2. apl-rd-patches.sh 将Debug补丁和Release补丁补到指定文件。 ### 3. gen-md-toc.sh 给markdown文档生成目录。可顺带转html。 ### 4. playList.html 网页MP3播放器。可配合nginx autoindex使用,也可离线使用playList.js。 ### 5. upload.js 使用Selenium WebDriver的nodejs脚本,驱动浏览器上传文件。 ## 已知问题 ### 1. Microsoft-WebDAV-MiniRedir of Windows File Explorer not work with Webdav via https Firefox webdav plugin works well with webdav, both http and https. ``` https://github.com/WebDAVDevs/webdav-browser-extension ``` Microsoft-WebDAV-MiniRedir can connect http webdav, but failed to connect https webdav. It can view, move and delete files, but can only create empty new file, until apply this patch to support PROPPATCH. ``` https://github.com/arut/nginx-dav-ext-module/issues/52 https://github.com/arut/nginx-dav-ext-module/files/3835180/proppatch.patch.gz ``` ### 2. MinGW UCRT64 console fails to run cmd.exe with commands MinGW UCRT64 minitty-3.7.0 fails to run cmd.exe with commands. For example, command line below expects to return 0, but will stuck in cmd.exe: ``` ( set -xv; cmd.exe /c "echo test"; echo rt=$? ) ```