emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: URL not following some 302 redirects after recent changes


From: Chong Yidong
Subject: Re: URL not following some 302 redirects after recent changes
Date: Wed, 31 Jan 2007 19:21:12 -0500
User-agent: Gnus/5.11 (Gnus v5.11) Emacs/22.0.93 (gnu/linux)

Diane Murray <address@hidden> writes:

> On Wed, 22 Nov 2006 03:35:17 +0100 I wrote:
>> Sometime after 2006-10-26 URL redirects stopped working correctly
>> (Emacs CVS of 2006-09-19 and 2006-10-26 works, 2006-10-31 and
>> 2006-11-19 don't work), perhaps due to changes made in revision 1.36
>> of url-http.el.

I think I know the problem.

In url-http-async-sentinel, before sending the http request, the code
attempts to change the process sentinel to
url-http-end-of-document-sentinel, which is supposed to parse the
headers when the connection is closed:

 (cond
   ((string= (substring why 0 4) "open")
    (set-process-sentinel proc 'url-http-end-of-document-sentinel)
    (process-send-string proc (url-http-create-request)))

However, attempting to change the process sentinel in the sentinel
itself has no effect (see the elisp manual).  That's why the headers
don't get parsed when the connection is closed.

The reason HTTP 1.1 does not have this problem is that it reports the
total length of the document, so the headers get parsed as soon as we
realise, in url-http-content-length-after-change-function, that we are
at the end of the document.  For HTTP 1.0, we have to wait till the
connection is closed before realizing that we are at the end of the
document.

A quick fix is to introduce a variable url-http-catch-end-of-document,
and have url-http-async-sentinel call
url-http-end-of-document-sentinel instead of doing its usual job if
that is non-nil.  Then url-http-async-sentinel can set
url-http-catch-end-of-document instead of trying to change the process
sentinel.

The patch below implements this.  I will commit it if there are no
objections in the next couple of days.

*** emacs/lisp/url/url-http.el.~1.49.~  2007-01-21 08:38:56.000000000 -0500
--- emacs/lisp/url/url-http.el  2007-01-31 19:12:53.000000000 -0500
***************
*** 30,35 ****
--- 30,36 ----
  (defvar url-http-extra-headers)
  (defvar url-http-target-url)
  (defvar url-http-proxy)
+ (defvar url-http-catch-end-of-document)
  (require 'url-gw)
  (require 'url-util)
  (require 'url-parse)
***************
*** 1118,1123 ****
--- 1119,1125 ----
                       url-http-extra-headers
                       url-http-data
                       url-http-target-url
+                      url-http-catch-end-of-document
                       url-http-proxy))
          (set (make-local-variable var) nil))
  
***************
*** 1132,1137 ****
--- 1134,1140 ----
              url-callback-arguments cbargs
              url-http-after-change-function 
'url-http-wait-for-headers-change-function
              url-http-target-url url-current-object
+             url-http-catch-end-of-document nil
              url-http-proxy url-using-proxy)
  
        (set-process-buffer connection buffer)
***************
*** 1140,1145 ****
--- 1143,1149 ----
          (cond
           ((eq status 'connect)
            ;; Asynchronous connection
+           (setq url-http-catch-end-of-document nil)
            (set-process-sentinel connection 'url-http-async-sentinel))
           ((eq status 'failed)
            ;; Asynchronous connection failed
***************
*** 1153,1170 ****
    (declare (special url-callback-arguments))
    ;; We are performing an asynchronous connection, and a status change
    ;; has occurred.
!   (with-current-buffer (process-buffer proc)
!     (cond
!      ((string= (substring why 0 4) "open")
!       (set-process-sentinel proc 'url-http-end-of-document-sentinel)
!       (process-send-string proc (url-http-create-request)))
!      (t
!       (setf (car url-callback-arguments)
!           (nconc (list :error (list 'error 'connection-failed why
!                                     :host (url-host (or url-http-proxy 
url-current-object))
!                                     :service (url-port (or url-http-proxy 
url-current-object))))
!                  (car url-callback-arguments)))
!       (url-http-activate-callback)))))
  
  ;; Since Emacs 19/20 does not allow you to change the
  ;; `after-change-functions' hook in the midst of running them, we fake
--- 1157,1176 ----
    (declare (special url-callback-arguments))
    ;; We are performing an asynchronous connection, and a status change
    ;; has occurred.
!   (if url-http-catch-end-of-document
!       (url-http-end-of-document-sentinel proc why)
!     (with-current-buffer (process-buffer proc)
!       (cond
!        ((string= (substring why 0 4) "open")
!       (setq url-http-catch-end-of-document t)
!       (process-send-string proc (url-http-create-request)))
!        (t
!       (setf (car url-callback-arguments)
!             (nconc (list :error (list 'error 'connection-failed why
!                                       :host (url-host (or url-http-proxy 
url-current-object))
!                                       :service (url-port (or url-http-proxy 
url-current-object))))
!                    (car url-callback-arguments)))
!       (url-http-activate-callback))))))
  
  ;; Since Emacs 19/20 does not allow you to change the
  ;; `after-change-functions' hook in the midst of running them, we fake




reply via email to

[Prev in Thread] Current Thread [Next in Thread]