Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix crashes on HTTPServer's SIGPIPE #1130

Merged
merged 1 commit into from
Jan 26, 2016

Conversation

Globidev
Copy link
Contributor

Case in point

Working on a project of my own that uses Livestreamer, I stumbled upon an issue while using the --player-external-http option

Basically, if a socket sends an HTTP request and closes before Livestreamer's HTTP server sends the response, consequent calls to send on the socket will send a SIGPIPE to Livestreamer's process which will raise a socket.error exception that was currently not caught.

Possible environment to reproduce
For example, running this command:

livestreamer twitch.tv/dotamajor best \
    --player-external-http \
    --player-external-http-port 12345

Followed by this little script:

while true; do 
    curl http://localhost:12345 &> /dev/null & sleep .5 && kill $! ;
done

Will make the first command crash after a short time with an output like:

[cli][info] Found matching plugin twitch for URL twitch.tv/dotamajor
[cli][info] Available streams: audio, high, low, medium, mobile (worst), source (best)
[cli][info] Starting server, access with one of:
[cli][info]  http://127.0.0.1:12345/
[cli][info]  http://172.17.0.2:12345/
[cli][info] Got HTTP request from curl/7.35.0
[cli][info] Opening stream: source (hls)
[cli][info] HTTP connection closed
[cli][info] Stream ended
[cli][info] Got HTTP request from curl/7.35.0
[cli][info] Opening stream: source (hls)
[cli][info] HTTP connection closed
[cli][info] Stream ended
Traceback (most recent call last):
  File "/usr/local/bin/livestreamer", line 9, in <module>
    load_entry_point('livestreamer==1.12.2', 'console_scripts', 'livestreamer')()
  File "/usr/local/lib/python2.7/dist-packages/livestreamer_cli/main.py", line 885, in main
    handle_url()
  File "/usr/local/lib/python2.7/dist-packages/livestreamer_cli/main.py", line 490, in handle_url
    handle_stream(plugin, streams, stream_name)
  File "/usr/local/lib/python2.7/dist-packages/livestreamer_cli/main.py", line 371, in handle_stream
    port=args.player_external_http_port)
  File "/usr/local/lib/python2.7/dist-packages/livestreamer_cli/main.py", line 152, in output_stream_http
    for req in iter_http_requests(server, player):
  File "/usr/local/lib/python2.7/dist-packages/livestreamer_cli/main.py", line 118, in iter_http_requests
    yield server.open(timeout=2.5)
  File "/usr/local/lib/python2.7/dist-packages/livestreamer_cli/utils/http_server.py", line 87, in open
    conn.send(b"Server: Livestreamer\r\n")
socket.error: [Errno 32] Broken pipe
Resolution

I just added a try-except block around the code that was calling send on the client's socket and forwarded the exception as an OSError
Those are ignored at an upper level in the call stack so no more crashes

chrippa added a commit that referenced this pull request Jan 26, 2016
@chrippa chrippa merged commit c80bdb4 into chrippa:develop Jan 26, 2016
@chrippa
Copy link
Owner

chrippa commented Jan 26, 2016

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants