Safari forced-close workaround adds LuCI latency on Safari 27 and CriOS: controlled A/B results
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 4/5
- Thời gian dự kiến
- 3-5 ngày
- Mức phù hợp với người mới
- 48/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Khá rõ ràng
- Mức độ hoạt động
- Sôi nổi
- Công nghệ
- c
- Lĩnh vực
- backend, networking
Hướng nghiên cứu
Read client.c at client_header_complete() and the user-agent parser, then inspect any existing parser and connection-behavior tests. Done means Safari with valid Version/27.0-or-newer is exempted while explicit close, HTTP/1.0, global close, and old IE POST behavior remain unchanged; parser results and current-master hardware validation should be reported separately.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Summary
The blanket Safari user-agent workaround in client_header_complete() forces Connection: close even for current Safari and CriOS clients. A controlled off/on/off experiment on a WAS-110 shows substantial LuCI dashboard latency from this decision.
The hardware measurements used uhttpd 3abcc89103799aaa79870fffcd58ec4370815024, shipped in WAS-110 firmware v2.8.3_basic_7d89440. They did not use current master. However, the same unconditional Safari close assignment and Safari UA classification are still present in current master at 373145f72c884c36a2b16f7f47e74ffae06bd754.
Relevant code
case UH_UA_MSIE_OLD:
if (r->method != UH_HTTP_MSG_POST)
break;
/* fall through */
case UH_UA_SAFARI:
r->connection_close = true;
break;
The UA parser checks Chrome/ before classifying a UA containing Safari/ and Mac OS X as Safari. Chrome on this iPhone uses CriOS/, so it also reaches the Safari close workaround. The rule originated in 7635644 (2013); the precise historical Safari defect is not established by our investigation.
Test method
An isolated RAM-only rebuild of the shipped source revision added a process-local switch to skip only the Safari forced-close assignment. It preserved existing close decisions and ran on a separate HTTPS port with the same certificate, web root and Lua/TLS/ubus plugins. Production was never restarted or flashed.
Each browser used the same authenticated dashboard, test hostname/port, certificate, Wi-Fi path and cache across off/on/off modes. Phone measurements came from USB Web Inspector. The Chrome run used one continuous inspector connection after reconnecting between captures proved intermittently unreliable; failed inspector attempts were discarded, not counted as browser-load failures.
| Browser/mode | Dashboard load events | First GPON status responses |
|---|---|---|
| Safari 27, off | 4.541 / 4.157 / 4.077 s | 9.857 / 9.863 / 9.242 s |
| Safari 27, on | 2.133 / 0.415 / 1.376 s | 2.984 / 1.211 / 2.286 s |
| CriOS 153, off | 6.719 / 4.638 / 4.472 s | 11.946 / 9.722 / 10.241 s |
| CriOS 153, on | 2.278 / 0.403 / 0.388 s | 3.111 / 1.144 / 1.150 s |
The third off measurement in each row was taken after returning from on mode. The first on load followed a test-process restart; later on loads could reuse existing connections. Load events are distinct from completion of dashboard data, hence the separate GPON column. These are small samples on one phone, not performance guarantees.
Every captured off-mode response used Connection: close; every captured on-mode response used Keep-Alive. Each browser's 45-second on capture completed 73 HTTP 200/304 responses. Chrome's 45-second run reported no network errors or JavaScript exceptions. Safari had one unmatched cancellation during reload; similar unmatched cancellations occurred on some mode transitions, consistent with canceling previous-page polling. No failure was associated with a captured request in the completed runs. Pending polling at a capture boundary was not classified as failed.
Separate low-rate checks covered same-socket static/login/ETag requests, explicit Connection: close, HTTP/1.0, old IE POST close, and a 20-second idle timeout followed by reconnection. An initial If-Modified-Since test returned 200; date-based caching is not claimed as validated.
Actual browser versions
USB-reported OS: iOS 27.0, build 24A437.
Safari UA:
Mozilla/5.0 (iPhone; CPU iPhone OS 18_7 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/27.0 Mobile/15E148 Safari/604.1
Chrome UA:
Mozilla/5.0 (iPhone; CPU iPhone OS 27_0_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/153.0.8010.24 Mobile/15E148 Safari/604.1
Safari's embedded CPU OS token differs from the actual OS reported over USB. Safari/604.1 is not its product version, and a CriOS version is not a Safari/WebKit version.
Proposed next step
A conservative draft patch can retain the historical workaround for unknown/older clients while exempting Safari with a valid Version/27.0 or greater. Version 27.0 is the tested minimum; allowing newer versions is a compatibility policy, not a claim that they have been tested. Explicit close, HTTP/1.0/global close and old IE POST behavior must remain intact.
The CriOS experiment verifies benefit on Chrome 153.0.8010.24 + iOS 27.0. A separate reliable eligibility policy is still needed before enabling all CriOS clients: the Chrome application version alone does not establish its WebKit version. The initial Safari proposal therefore deliberately excludes CriOS and other alternative iOS-browser tokens, despite the positive Chrome experiment.
Current master also contains newer connection/framing fixes not present in the tested firmware, so current-master hardware validation remains necessary. The final version parser was not part of the hardware A/B; parser tests and hardware behavior must be reported separately.
Downstream report: https://github.com/djGrrr/8311-was-110-firmware-builder/issues/54
Downstream draft/backport materials: https://github.com/djGrrr/8311-was-110-firmware-builder/pull/55
All temporary test rules/listeners were removed; complete IPv4 filter listings matched before and after, and production retained its original PID/binary. No credentials, cookies, private hostnames or packet payloads are included here.
- Ngôn ngữ chính
- C
- Star
- 39
- Fork
- 31
- Chỉ số merge pull request
- Không có pull request nào được merge trong 30 ngày
Chuẩn bị môi trường
Dự án này không cung cấp dev container, Dockerfile hay hướng dẫn đóng góp, nên bạn cần tự thiết lập môi trường: hãy bắt đầu từ README và xem hướng dẫn đóng góp lần đầu của chúng tôi để biết các bước chung.
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của openwrt/uhttpd
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 24/100
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 56/100
Tất cả issue của openwrt/uhttpd
Issue tương tự
-
bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
FujiNetWIFI/fujinet-config#379 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Ship /Local/Applications, the Local domain's Applications folderCó thể đã có người làm @pkgdemon đã nhận hôm nay. Đang mởarea:base enhancement
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 94/100
nextbsd/nextbsd-userland#612 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
zephyrproject-rtos/zephyr#125543 ·
Maintainer thường phản hồi trong vòng 2 ngày
-
good first issue needs-triage
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 88/100
InauguralSystems/EigenScript#2347 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
colbymchenry/codegraph#3277 ·
Maintainer thường phản hồi trong vòng 1 ngày