Error occurred in mobile when send video using send_file in Python Flask

对着背影说爱祢 提交于 2019-12-09 21:29:08

问题


I am using Python Flask. I want to send media file(mp4, mp3, mov etc) to user with permission check. I will check user permission with DB and I want to send file only for authenticated user.

So I start to developing that system. I check permission using login, I send file to user using Send_file. On Desktop, It working well. But On my iPad, iPhone, Android phone, it didn't work. Their player alert 'cannot play this video'. In iPhone, player's play button is unavailable.

iPhone error screen shot here http://webhost.swisscom.co.kr/temp/stackoverflow_iphone1.jpg

Flask server(Gunicorn) return

"error: [Errno 107] Transport endpoint is not connected". When python flask debugging server - "error: [Error 32] Broken pipe.

I tested in over 5 different servers, but it still don't working.

I also used x-sendfile or send_from_directory, manual build response headers.

@app.route('/download/<path:filename>')
def download(filename):
    return send_file('data/file/' + filename)

Gunicorn Flask Server error when request video in iOS7, iOS6, android

2013-10-17 16:38:46 [14344] [ERROR] Error processing request.
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/gunicorn/workers/sync.py", line 88, in handle
    self.handle_request(listener, req, client, addr)
  File "/usr/local/lib/python2.7/dist-packages/gunicorn/workers/sync.py", line 145, in handle_request
    client.shutdown(socket.SHUT_RDWR)
  File "/usr/lib/python2.7/socket.py", line 224, in meth
    return getattr(self._sock,name)(*args)
error: [Errno 107] Transport endpoint is not connected
2013-10-17 16:38:47 [14331] [ERROR] Error processing request.
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/gunicorn/workers/sync.py", line 88, in handle
    self.handle_request(listener, req, client, addr)
  File "/usr/local/lib/python2.7/dist-packages/gunicorn/workers/sync.py", line 145, in handle_request
    client.shutdown(socket.SHUT_RDWR)
  File "/usr/lib/python2.7/socket.py", line 224, in meth
    return getattr(self._sock,name)(*args)
error: [Errno 107] Transport endpoint is not connected

Python debugger server error when request video in iOS7 or iOS6 or android

123.123.123.123 - - [17/Oct/2013 16:34:36] "GET /download/welcome.mp4 HTTP/1.1" 200 -
----------------------------------------
Exception happened during processing of request from ('110.70.52.201', 38723)
Traceback (most recent call last):
  File "/usr/lib/python2.7/SocketServer.py", line 295, in _handle_request_noblock
    self.process_request(request, client_address)
  File "/usr/lib/python2.7/SocketServer.py", line 321, in process_request
    self.finish_request(request, client_address)
  File "/usr/lib/python2.7/SocketServer.py", line 334, in finish_request
    self.RequestHandlerClass(request, client_address, self)
  File "/usr/lib/python2.7/SocketServer.py", line 651, in __init__
    self.finish()
  File "/usr/lib/python2.7/SocketServer.py", line 704, in finish
    self.wfile.flush()
  File "/usr/lib/python2.7/socket.py", line 303, in flush
    self._sock.sendall(view[write_offset:write_offset+buffer_size])
error: [Errno 32] Broken pipe

回答1:


To support streaming media on iOS devices, the web server needs to support sending 206 responses (partial content) based on an incoming range header. There are a few examples of send_file replacements that handle this for you, like this one on the mailing list, or this one (NB: I havent tried these exact examples myself, but have implemented something similar for exactly this - so iOS will play videos correctly)




回答2:


I FINALLY solved this problem.

First, I am using Nginx with Gunicorn.

When using Nginx with Gunicorn, you can check auth info before download file using following step.

It is using Nginx intenal redirect only function. It will block unauthenticated access to your file.

User -> Nginx -> Gunicorn -> Check Auth info in python code -> Response Data

Nginx Config

server {
    listen 80;
    server_name yourserver.com;

    location /download_file/ {
        internal; # Receive just internal redirect
        alias    /file/path/in/your/server/;
    }

    # Just for Gunicorn Serving (option)
    location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
         proxy_set_header Host $http_host;
         proxy_redirect off;

         if (!-f $request_filename) {
             proxy_pass http://service;
             break;
         }
    }
}

Python Code

@app.route('/download/<path:filename>')
def download(filename):
    if not authentication():
        abort(404)

    redirect_path = '/download_file/' + filename

    response = make_response("")
    response.headers["X-Accel-Redirect"] = redirect_path
    response.headers["Content-Type"] = mimetypes.guess_type(filename)
    return response

Then your browser will receive file from Nginx

Also working in iOS likes serving from common web server.

Information from

http://mattspitz.me/2013/11/20/serving-authenticated-media-with-nginx.html



来源:https://stackoverflow.com/questions/19421014/error-occurred-in-mobile-when-send-video-using-send-file-in-python-flask

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!