TE
科技回声
首页24小时热榜最新最佳问答展示工作
GitHubTwitter
首页

科技回声

基于 Next.js 构建的科技新闻平台,提供全球科技新闻和讨论内容。

GitHubTwitter

首页

首页最新最佳问答展示工作

资源链接

HackerNews API原版 HackerNewsNext.js

© 2025 科技回声. 版权所有。

Tell HN: Fiddler complains about Hacker News

42 点作者 barrydahlberg超过 14 年前
Minor issue but I was debugging something else with Fiddler and it kept telling me this about responses from HN:<p><i>Fiddler has detected a protocol violation in session #122.<p>The Server did not return properly formatted HTTP Headers. HTTP headers should be terminated with CRLFCRLF. These were terminated with LFLF.</i><p>Presumably this is an issue in the Arc code outputting the headers. Also, is this where I should report this or is there a support email or something I can address?

2 条评论

jgrahamc超过 14 年前
The problem appears to be in srv.arc where there's the following:<p><pre><code> (def gen-type-header (ctype) (+ "HTTP/1.0 200 OK Content-Type: " ctype " Connection: close")) </code></pre> hexl-mode on the file shows that those line endings are 0x0A:<p><pre><code> 00001630: 2874 6162 6c65 2929 0a0a 2864 6566 2067 (table))..(def g 00001640: 656e 2d74 7970 652d 6865 6164 6572 2028 en-type-header ( 00001650: 6374 7970 6529 0a20 2028 2b20 2248 5454 ctype). (+ "HTT 00001660: 502f 312e 3020 3230 3020 4f4b 0a43 6f6e P/1.0 200 OK.Con 00001670: 7465 6e74 2d54 7970 653a 2022 0a20 2020 tent-Type: ". 00001680: 2020 6374 7970 650a 2020 2020 2022 0a43 ctype. ".C 00001690: 6f6e 6e65 6374 696f 6e3a 2063 6c6f 7365 onnection: close 000016a0: 2229 290a 0a28 6d61 7020 2866 6e20 2828 "))..(map (fn (( </code></pre> Eventually the headers get printed to the socket via prn:<p><pre><code> (let filetype (static-filetype op) (aif (and filetype (file-exists (string staticdir* op))) (do (prn (type-header* filetype)) </code></pre> prn is defined in arc.arc<p><pre><code> (def pr args (map1 disp args) (car args)) (def prn args (do1 (apply pr args) (pr #\newline))) ; writec doesn't implicitly flush </code></pre> which is using disp which is defined in ac.scm<p><pre><code> (define (printwith f args)u (let ((port (if (&#62; (length args) 1) (cadr args) (current-output-port)))) (when (pair? args) (f (ac-denil (car args)) port)) (unless (ar-bflag 'explicit-flush) (flush-output port))) 'nil) (defarc write (arc-write . args) (printwith write args)) (xdef disp (lambda args (printwith display args))) </code></pre> That's using the MzScheme display method which appears to just do writing of bytes and doesn't do any CRLF translation (<a href="http://docs.racket-lang.org/reference/Writing.html?q=display#(def._((quote._~23~25kernel)._display))" rel="nofollow">http://docs.racket-lang.org/reference/Writing.html?q=display...</a>)<p>Quick verification of that:<p><pre><code> $ cat test.scm (display "Hello, World!") (display #\return) (display #\newline) $ mzscheme -r test.scm | hexdump -C 00000000 48 65 6c 6c 6f 2c 20 57 6f 72 6c 64 21 0d 0a |Hello, World!..| </code></pre> So, there are a couple of possible solutions: explicitly specify CRLF as line endings when needed (i.e. insert #\return), or have a special version of pr for network communication that does LF -&#62; CRLF translation).<p>Within the respond function there are other instances of using prn to send to the socket that need to be fixed:<p><pre><code> (def respond (str op args cooks clen ctype in ip) (w/stdout str (iflet f (srvops* op) (let req (inst 'request 'args args 'cooks cooks 'ctype ctype 'clen clen 'in in 'ip ip) (if (redirector* op) (do (prn rdheader*) (prn "Location: " (f str req)) (prn)) (do (prn header*) (awhen (max-age* op) (prn "Cache-Control: max-age=" it)) (f str req)))) (let filetype (static-filetype op) (aif (and filetype (file-exists (string staticdir* op))) (do (prn (type-header* filetype)) (awhen static-max-age* (prn "Cache-Control: max-age=" it)) (prn) (w/infile i it (whilet b (readb i) (writeb b str)))) (respond-err str unknown-msg*)))))) </code></pre> I'm guessing that altering gen-type-header and creating a special prcrlf function is the way to go.<p><pre><code> (def prcrlf args (do1 (apply pr args) (pr #\return) (pr #\newline))) (def gen-type-header (ctype) (+ "HTTP/1.0 200 OK#\return Content-Type: " ctype "#\return Connection: close")) </code></pre> Although, personally, I don't like the assumption that the editor is inserting 0x0A for line-endings and would rather be totally certain with something like:<p><pre><code> (def gen-type-header (ctype) (+ "HTTP/1.0 200 OK" #\return #\newline "Content-Type: " ctype #\return #\newline "Connection: close")) </code></pre> Since you'll need to do this sort of thing a lot a little helper would probably make sense (and I'd add the CRLF on the last line explicitly):<p><pre><code> (def crlf (a) (+ a #\return #\newline)) (def gen-type-header (ctype) (+ (crlf "HTTP/1.0 200 OK") (crlf (+ "Content-Type: " ctype)) (crlf "Connection: close"))) </code></pre> And change every instance of prn in respond to prcrlf. Except for (prn (type-header* filetype)) which becomes (pr (type-header* filetype)).<p>Note: I have not tested this change. Probably some other small gotchas.
plaes超过 14 年前
<a href="https://bugzilla.gnome.org/show_bug.cgi?id=571283" rel="nofollow">https://bugzilla.gnome.org/show_bug.cgi?id=571283</a> ;)