Re: error produced with cl-http by latest Mozilla browsers (Revised CL-HTTP Patch)
"John C. Mallery" <[email protected]> Fri, 18 Jun 2004 15:14:16 -0400
| Newsgroups | gmane.lisp.cl-http |
|---|---|
| Message-ID | <p0602041bbcf8ef025db8@[10.0.1.3]> |
Consult the HTTP 1.1 specification: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
You will need to verify that http 1.0 clients behave as expected, and report back if
there are issues.
People doing more advanced redirects should probably use standard-url-redirect for
added control.
The patch below corrects CL-HTTP to use 303 for redirects within a POST response.
;; Use the forward condition for all redirects within a post method per HTTP 1.1 spec
;; http:server;report.lisp
(defun %standard-url-redirect (url target-url redirection-type method target-window)
(check-type target-window (or null string))
(let ((alternate-urls (ensure-list target-url)))
(unless alternate-urls
(signal 'document-not-found :url url))
(ecase redirection-type
(:temporary-redirect
(case method
(:get (signal 'document-found :url url :method method :new-urls alternate-urls :target-window target-window))
(t (signal 'document-moved-temporarily :url url :method method :new-urls alternate-urls :target-window target-window))))
(:permanent-redirect
(signal 'document-moved-permanently :url url :method method :new-urls alternate-urls :target-window target-window))
(:forward
(if (case method
(:get (not (explicit-expiration-p url)))
(:post t))
(signal 'document-forwarded :url url :method method :new-urls alternate-urls :target-window target-window)
(signal 'document-moved-temporarily :url url :method method :new-urls alternate-urls :target-window target-window)))
(:proxy
(signal 'document-access-via-proxy :url url :method method :new-urls alternate-urls :target-window target-window))
(:multiple-choices
(signal 'document-multiple-choices :url url :method method :new-urls alternate-urls :target-window target-window)))))
;; http:server;server.lisp
(defmethod redirect-request ((server basic-server-mixin) (target-uri uri) &optional target-window)
(with-slots (url method) server
(let ((redirection (case method (:post :forward) (t :temporary-redirect))))
(%standard-url-redirect url target-uri redirection method target-window))))
(defmethod redirect-request ((server basic-server-mixin) (target-uris cons) &optional target-window)
(with-slots (url method) server
(let ((redirection (case method (:post :forward) (t :multiple-choice))))
(if (every #'url::uri-p target-uris)
(%standard-url-redirect url target-uris redirection method target-window)
(let ((alternate-uris (mapcar #'(lambda (uri) (intern-url uri :if-does-not-exist :create)) target-uris)))
(declare (dynamic-extent alternate-uris))
(%standard-url-redirect url alternate-uris redirection method target-window))))))
I tested the patch on Mozilla 1.6 and Safari running under Mac OS X 10.3.4
This will be incorporated into the next release.
Good test case. Thanks for Martin's comment.
This is a rather interesting example of the high-level abstraction in CL-HTTP, where a small change here implements
the desired functionality without forcing the application to know what is going on below. Note also that
(report-status-line (condition http/1.1-redirection-downgrade-mixin) (stream t))
automatically conditionalizes the output for http 1.0 clients.