Menu

#1248 curl_multi_socket_action and HTTP redirect does not work when using epoll

closed-fixed
5
2014-08-16
2013-06-19
No

(Also posted to mail list: http://curl.haxx.se/mail/lib-2013-03/0045.html)

While trying to use curl_multi_socket_action together with epoll I noticed that it didn't work in combination with HTTP redirect.

When a socket is first connected, CURLMOPT_SOCKETFUNCTION is called and the socket is added to the epoll set. Later on when libcurl connects to the HTTP server and sees the redirect it closes the socket (which makes the kernel remove the socket from the epoll set) and opens a new. Unfortunately this new socket gets the same number as the old, and thus the socket function callback is never called to add it to the epoll set.

Tested with libcurl from git: e305f5ec
OS: Linux 3.8.0 (Ubuntu 13.04) x86_64

How to reproduce:

  • Run the attached httpserver.py. It will output:
Connect to http://127.0.0.1:9800 to be redirected to http://127.0.0.1:5400
  • Build and run the attached curlepoll.c like this:
# ./curlepoll http://127.0.0.1:9800
...
>>> calling epoll_wait
>>> calling epoll_wait
>>> calling epoll_wait
^C

It hangs in epoll_wait and must be aborted with Ctrl-C.

  • Now test with poll instead:
# ./curlepoll http://127.0.0.1:9800 poll
...
>>> calling poll
Hello Port 5400!
>>> calling poll
>>> socketCallback: removing fd=4
>>> bye bye

Works as expected.

1 Attachments

Discussion

  • Erik Johansson

    Erik Johansson - 2013-06-19

    httpserver.py

     
  • Daniel Stenberg

    Daniel Stenberg - 2013-06-19

    Thanks for your report. I haven't verified exactly this, but the problem you describe follow a pattern of bugs we've had before and I can see exactly how it happens. We need to fix this once and for all to make sure we don't keep on getting the same problem...

     
  • Daniel Stenberg

    Daniel Stenberg - 2013-06-19

    I hope you don't mind working with me a little here and testing out an idea of mine - I haven't actually tried to repeat the problem with your script etc yet.

    Please try out the attached patch and see if it makes things better. It is an attempt to remove the socket properly on socket close so that the new one will be noticed properly and thus inform the callback as it should.

     
  • Erik Johansson

    Erik Johansson - 2013-06-20

    That patch worked perfectly with my test case. I now get a callback to remove the socket and one to add a new socket with the same file descriptor number.

     
  • Daniel Stenberg

    Daniel Stenberg - 2013-06-20

    Lovely, then it worked exactly as intended. I felt confident enough to push this to the git repo just now as commit 88c5c63ffc3312a8c.

    Thanks for your test and verification. Case closed!

     
  • Daniel Stenberg

    Daniel Stenberg - 2013-06-20
    • status: open --> closed-fixed