Commit dd1df30
committed
Honour a declared Content-Length in send_stream, and reject a chunk size rather than salvaging it
Review of the change this branch already carries. The defect it reports is real
and the fix is placed correctly --- `dispatch` is the single funnel for every
body byte on both framing paths, and `captureBody` is decided after the headers
are read, where the status is final. Measured against master, one program, one
source file:
master status=418 events=0 body.size()=0
this status=418 events=0 body.size()=135
What follows is what that fix could not do on its own.
--- 1. A DECLARED LENGTH, WHICH IS WHY THE TEST HAD TO CLOSE THE CONNECTION ----
`send_stream` had no branch for `Content-Length`: a response that was not
chunked was read until the connection closed, whatever its headers said. On this
library's own defaults --- `keepAlive = true`, so the request carries
`Connection: keep-alive` --- the server does not close, and the read loop ran
until `readTimeoutMs` expired. Measured against httpbin's `/status/418`:
keepAlive = false status=418 body=135 elapsed 1370 ms
keepAlive = true status=418 body=135 elapsed 9379 ms (timeout 8000)
The error body arrived either way, and on the defaults it arrived a full read
timeout late --- sixty seconds, as the defaults stand. `send()` has had this
branch throughout, which is the same asymmetry between the two entry points that
this branch exists to remove.
The live test set `keepAlive = false`, "so the server closes and the read loop
ends". That comment was the defect, and the test was examining the one
arrangement in which it does not appear. It now runs on the defaults and asserts
the elapsed time.
after: keepAlive = true status=418 body=135 elapsed 1192 ms
--- 2. A CHUNK SIZE THAT DOES NOT PARSE IS NOT A TERMINAL CHUNK ---------------
`parse_hex` returns what it accumulated when it meets a character it does not
recognise, and zero for an empty line --- and `read_line` returns an empty line
on a timeout or a closed connection. So a stream that was cut short read as a
stream that ended cleanly and this loop reported success. #9 established
`parse_chunk_size_line` for exactly this and it reached `download_to_file`
alone; `send` and `send_stream` were left on the old one.
--- 3. Content-Length WAS PARSED BY KEEPING THE DIGITS ------------------------
Measured, by compiling that parser on its own:
"135" -> 135
"abc" -> 0 <- a refusal read as a real zero
"12abc" -> 12 <- stops twelve bytes in
"-1" -> 1 <- the sign is discarded
"99999999999999999999" -> 7766279631452241919 <- wraps, in silence
The last two are the ones no care at the call site could recover from, because
what it receives is a plausible number. `parse_content_length` is exported and
shaped like `parse_chunk_size_line`, for the reason #9 gave: it is the half of
the body framing that can be examined without a server. Both readers use it.
--- criteria -----------------------------------------------------------------
Six unit tests over the two pure parsers, and two live ones: the failed stream
now runs on the DEFAULT configuration with the elapsed time asserted, and a
chunked 2xx is asserted to leave `body` empty and to return promptly --- the
success path is the one this change restructured around, so it is observed
rather than assumed.
17 tests from 6 suites pass, plus 3 in test_resolver.1 parent f99fe73 commit dd1df30
2 files changed
Lines changed: 191 additions & 9 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
242 | 242 | | |
243 | 243 | | |
244 | 244 | | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
245 | 276 | | |
246 | 277 | | |
247 | 278 | | |
| |||
478 | 509 | | |
479 | 510 | | |
480 | 511 | | |
481 | | - | |
482 | | - | |
483 | | - | |
484 | | - | |
485 | | - | |
486 | | - | |
| 512 | + | |
| 513 | + | |
| 514 | + | |
| 515 | + | |
| 516 | + | |
487 | 517 | | |
488 | 518 | | |
489 | 519 | | |
| |||
723 | 753 | | |
724 | 754 | | |
725 | 755 | | |
| 756 | + | |
726 | 757 | | |
727 | 758 | | |
728 | 759 | | |
| |||
745 | 776 | | |
746 | 777 | | |
747 | 778 | | |
| 779 | + | |
| 780 | + | |
| 781 | + | |
| 782 | + | |
| 783 | + | |
| 784 | + | |
748 | 785 | | |
749 | 786 | | |
750 | 787 | | |
| |||
782 | 819 | | |
783 | 820 | | |
784 | 821 | | |
785 | | - | |
| 822 | + | |
| 823 | + | |
| 824 | + | |
| 825 | + | |
| 826 | + | |
| 827 | + | |
| 828 | + | |
| 829 | + | |
| 830 | + | |
| 831 | + | |
| 832 | + | |
| 833 | + | |
| 834 | + | |
| 835 | + | |
| 836 | + | |
| 837 | + | |
786 | 838 | | |
787 | 839 | | |
788 | 840 | | |
| |||
801 | 853 | | |
802 | 854 | | |
803 | 855 | | |
| 856 | + | |
| 857 | + | |
| 858 | + | |
| 859 | + | |
| 860 | + | |
| 861 | + | |
| 862 | + | |
| 863 | + | |
| 864 | + | |
| 865 | + | |
| 866 | + | |
| 867 | + | |
| 868 | + | |
| 869 | + | |
| 870 | + | |
| 871 | + | |
| 872 | + | |
| 873 | + | |
| 874 | + | |
| 875 | + | |
| 876 | + | |
| 877 | + | |
| 878 | + | |
| 879 | + | |
| 880 | + | |
| 881 | + | |
| 882 | + | |
| 883 | + | |
| 884 | + | |
| 885 | + | |
| 886 | + | |
| 887 | + | |
| 888 | + | |
| 889 | + | |
| 890 | + | |
804 | 891 | | |
805 | | - | |
| 892 | + | |
| 893 | + | |
806 | 894 | | |
807 | 895 | | |
808 | 896 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
20 | 20 | | |
21 | 21 | | |
22 | 22 | | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
23 | 69 | | |
24 | 70 | | |
25 | 71 | | |
| |||
68 | 114 | | |
69 | 115 | | |
70 | 116 | | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
71 | 132 | | |
72 | 133 | | |
73 | 134 | | |
74 | 135 | | |
75 | | - | |
| 136 | + | |
76 | 137 | | |
77 | 138 | | |
78 | 139 | | |
79 | 140 | | |
80 | 141 | | |
81 | 142 | | |
82 | 143 | | |
| 144 | + | |
83 | 145 | | |
84 | 146 | | |
85 | 147 | | |
86 | 148 | | |
| 149 | + | |
| 150 | + | |
87 | 151 | | |
88 | 152 | | |
89 | 153 | | |
90 | 154 | | |
91 | 155 | | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
92 | 186 | | |
93 | 187 | | |
94 | 188 | | |
| |||
0 commit comments