[FFmpeg-devel] Controlling the server reply (was: 9/9] doc/example: Add http multi-client) example code
klaxa1337 at googlemail.com
Sun Jul 12 10:49:13 CEST 2015
On Sat, Jul 11, 2015 at 11:55 AM, Nicolas George <george at nsup.org> wrote:
> Le primidi 21 messidor, an CCXXIII, Stephan Holljes a écrit :
>> Good question, I haven't thought about that myself. Adding a 404 error
>> to handle_http_errors() and calling it with AVERROR_HTTP_NOT_FOUND
>> could be a solution. I feel like the name "handle_http_errors" is not
>> well chosen then, though.
> Unfortunately, that will not do, because handle_http_errors() is not public
> And this is a rather fundamental issue, we can not disregard it just by
> making handle_http_errors() public. I had hoped we could finish this patch
> series and handle this issue afterwards, but it seems it must be addressed
> sooner. Let me explain.
> Returning 404 Not found, or 401 Unauthorized, or... is performed by the
> library, but it is the decision of the application (I hope the distinction
> between application and library is clear). The library can not know if a
> particular file exists or not, because it does not even know if the
> application is getting the files from the filesystem or from a database or
> from on-the-fly computations. And the library can even less know the policy
> for authorizing files.
> I can see three rather distinct sub-issues:
> Q1. how the library communicates to the application the details of the
> Q2. how the application communicates to the library the decision it made;
> Q3. when the application can make its decision.
> Q3 is the crux of the problem: remember we had to split avio_accept() into
> avio_accept() and avio_handshake() to give the application a chance of
> forking or any other solution to handle several clients in parallel. Just
> the same, we will have to split avio_handshake() further to give the
> application a chance of making a decision.
> Furthermore, we need something that will work not only for HTTP but for any
> protocol that FFmpeg may support as a server.
> Q1 is the logical equivalent to the "address" parameter to the accept()
> system call. To be sure of it, think of an application that serves files
> without authentication on the local network but requires authentication
> otherwise: the client's address is part of the decision making.
> Q1 has a rather obvious and easy answer, that is the reason I hoped we could
> leave it for later: put the request parameters in the context and access
> them with the AVOption system. Thus, the application would access the
> request path with something like "av_opt_get(client_ctx,
> "http_request_path", AV_OPT_SEARCH_CHILDREN)".
> Q2 have the same obvious answer: "av_opt_set_int(client_ctx,
> "http_reply_code", 404)".
> Q3 is the hard part.
> I can see an answer to Q3, but since this is your internship, I think it is
> better to give you a chance to find your own answer first.
> When thinking on it, remember two situations that the API must be able to
> * A protocol can have several round-trips with decision to make at each
> step. For example, first negotiate the authentication scheme, then
> authenticate, then request a resource. All this is part of the handshake,
> but the application needs an entry point at each step.
> * Nested protocols: in HTTP-over-TCP, there is no decision to make until we
> have the full request, but in HTTP-over-TLS, i.e. HTTPS, the application
> needs a hook during the TLS handshake to handle Server Name Indication,
> and then the normal HTTP hook to set the reply code. We do not want to add
> special code in the upper protocol to handle the lower protocol.
> Please let me know your thoughts about that.
> Nicolas George
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
the best thing I thought of was some kind of generic communication
function that either uses the client's AVOption system to pass around
values or just uses an AVDictionary.
Giving the application access to the results of the library could be
done in a similar way it is being done in http_read_header() by
repeatedly calling the communicate function and checking for its error
code (return < 0 in case of error, > 0 in case of success, but
unfinished processing and 0 on success and finished processing.) Since
we have to deal with protocol-specific decisions, each protocol should
implement its own communication function with something like a
url_comm_params() function added to the URLProtocol struct, which is
called like most (all?) other URLProtocol functions with
ffurl_comm_params() and avio_comm_params(). I'm not really sure how to
tell the application what parameters were negotiated, but maybe this
can be done in a similar fashion it has been done with unused_opts,
but instead with used_opts.
More information about the ffmpeg-devel