400使用公共Lisp usocket发送http请求时请求错误

400使用公共Lisp usocket发送http请求时请求错误,http,lisp,httprequest,common-lisp,usocket,Http,Lisp,Httprequest,Common Lisp,Usocket,我使用以下代码获取urlhttp://brandonhsiao.com/essays.html: (defparameter *new-line* '(#\Return #\Newline)) (defun read-url (host port path) (let ((sock (usocket:socket-connect host port))) (format (usocket:socket-stream sock) "~A" (concatena

我使用以下代码获取url
http://brandonhsiao.com/essays.html

(defparameter *new-line* '(#\Return #\Newline))

(defun read-url (host port path)
  (let ((sock (usocket:socket-connect host port)))
    (format (usocket:socket-stream sock) "~A"
            (concatenate 'string
                         "GET " path " HTTP/1.1" *new-line*
                         "Connection: close" *new-line* *new-line*))
    (force-output (usocket:socket-stream sock))
    (do ((line
           (read-line (usocket:socket-stream sock) nil)
           (read-line (usocket:socket-stream sock) nil))
         (all ""))
      ((not line) all)
      (setf all (concatenate 'string all line *new-line*)))))

(print (read-url "brandonhsiao.com" 80 "/essays.html"))

这给了我一个
400错误请求
错误,但是当我访问
http://brandonhsiao.com/essays.html
使用Firefox,一切都很好。我做错了什么?

看起来我需要包括主机

(defparameter *new-line* '(#\Return #\Newline))

(defun read-url (host port path)
  (let ((sock (usocket:socket-connect host port)))
    (format (usocket:socket-stream sock) "~A"
            (concatenate 'string
                         "GET " path " HTTP/1.1" *new-line*
                         "Host: " host *new-line* *new-line*))
    (force-output (usocket:socket-stream sock))
    (do ((line
           (read-line (usocket:socket-stream sock) nil)
           (read-line (usocket:socket-stream sock) nil))
         (all ""))
      ((not line) all)
      (setf all (concatenate 'string all line " ")))))

确保新行作为CRLF发送到套接字(HTTP要求新行完全是CRLF)。由于您使用
格式
将文本写入套接字流,所以换行符可能会转换为LF。您可以使用tcpdump或wireshark来查看哪些字节被发送到套接字。我建议您使用“drakma”包,该包旨在完成这类工作。它可以从Quicklisp获得。