L'octidi 8 messidor, an CCXXIII, Stephan Holljes a écrit : > I think I implemented everything necessary, but I don't know how to > test it. The old behaviour of accepting a single client is now also > broken.
Since that behaviour was already established, breaking it without notice is not an option :( > How do I detect which behaviour the user wants? Should I introduce a new > option for http and tcp connections or make the listen field take more > values than just 0 and 1? Increasing the range for listen is a good idea. I am afraid it will make the accept functions a but awkward, having to work with either two contexts (server and client) or only one (server that will become client). > Attached are patches with the changes I made so far. It compiles, but > breaks http server capabilities for now. To actually test multi-client code, it will be necessary to write a multi-client sample application. Fortunately, that should not be very hard. > From 22f958ad8d0058865c94847ca8cd2488e2a61c9e Mon Sep 17 00:00:00 2001 > From: Stephan Holljes <klaxa1...@googlemail.com> > Date: Fri, 26 Jun 2015 20:48:49 +0200 > Subject: [PATCH 1/6] lavf/network: split ff_listen_bind into ff_listen and > ff_accept > > Signed-off-by: Stephan Holljes <klaxa1...@googlemail.com> > --- > libavformat/network.c | 27 +++++++++++++++++++++------ > libavformat/network.h | 4 ++++ > 2 files changed, 25 insertions(+), 6 deletions(-) > > diff --git a/libavformat/network.c b/libavformat/network.c > index 47ade8c..8d61746 100644 > --- a/libavformat/network.c > +++ b/libavformat/network.c > @@ -187,12 +187,11 @@ int ff_socket(int af, int type, int proto) > return fd; > } > > -int ff_listen_bind(int fd, const struct sockaddr *addr, > - socklen_t addrlen, int timeout, URLContext *h) > +int ff_listen(int fd, const struct sockaddr *addr, > + socklen_t addrlen) > { > int ret; > int reuse = 1; > - struct pollfd lp = { fd, POLLIN, 0 }; > if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse))) { > av_log(NULL, AV_LOG_WARNING, "setsockopt(SO_REUSEADDR) failed\n"); > } > @@ -203,6 +202,13 @@ int ff_listen_bind(int fd, const struct sockaddr *addr, > ret = listen(fd, 1); > if (ret) > return ff_neterrno(); > + return ret; > +} > + > +int ff_accept(int fd, int timeout, URLContext *h) > +{ > + int ret; > + struct pollfd lp = { fd, POLLIN, 0 }; > > ret = ff_poll_interrupt(&lp, 1, timeout, &h->interrupt_callback); > if (ret < 0) > @@ -211,15 +217,24 @@ int ff_listen_bind(int fd, const struct sockaddr *addr, > ret = accept(fd, NULL, NULL); > if (ret < 0) > return ff_neterrno(); > - > - closesocket(fd); > - > if (ff_socket_nonblock(ret, 1) < 0) > av_log(NULL, AV_LOG_DEBUG, "ff_socket_nonblock failed\n"); > > return ret; > } > > +int ff_listen_bind(int fd, const struct sockaddr *addr, > + socklen_t addrlen, int timeout, URLContext *h) > +{ > + int ret; > + if ((ret = ff_listen(fd, addr, addrlen)) < 0) > + return ret; > + ret = ff_accept(fd, timeout, h); > + closesocket(fd); > + return ret; > + > +} > + > int ff_listen_connect(int fd, const struct sockaddr *addr, > socklen_t addrlen, int timeout, URLContext *h, > int will_try_next) > diff --git a/libavformat/network.h b/libavformat/network.h > index 86fb656..44e109c 100644 > --- a/libavformat/network.h > +++ b/libavformat/network.h > @@ -254,6 +254,10 @@ int ff_listen_bind(int fd, const struct sockaddr *addr, > socklen_t addrlen, int timeout, > URLContext *h); > > +int ff_listen(int fd, const struct sockaddr *addr, socklen_t addrlen); > + > +int ff_accept(int fd, int timeout, URLContext *h); > + > /** > * Connect to a file descriptor and poll for result. > * > -- > 2.1.0 > > From 4d0b5e42882f180d76a3a64da96dc87bf0ba0635 Mon Sep 17 00:00:00 2001 > From: Stephan Holljes <klaxa1...@googlemail.com> > Date: Fri, 26 Jun 2015 20:50:35 +0200 > Subject: [PATCH 2/6] lavf/avio: add ffurl_accept > > Signed-off-by: Stephan Holljes <klaxa1...@googlemail.com> > --- > libavformat/avio.c | 5 +++++ > libavformat/url.h | 9 +++++++++ > 2 files changed, 14 insertions(+) > > diff --git a/libavformat/avio.c b/libavformat/avio.c > index aff8d10..153230f 100644 > --- a/libavformat/avio.c > +++ b/libavformat/avio.c > @@ -211,6 +211,11 @@ int ffurl_connect(URLContext *uc, AVDictionary **options) > return 0; > } > > +int ffurl_accept(URLContext *sc, URLContext *cc) > +{ > + return sc->prot->url_accept(sc, cc); > +} > + > #define URL_SCHEME_CHARS \ > "abcdefghijklmnopqrstuvwxyz" \ > "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \ > diff --git a/libavformat/url.h b/libavformat/url.h > index 99a3201..34fdea2 100644 > --- a/libavformat/url.h > +++ b/libavformat/url.h > @@ -58,6 +58,7 @@ typedef struct URLProtocol { > * for those nested protocols. > */ > int (*url_open2)(URLContext *h, const char *url, int flags, > AVDictionary **options); > + int (*url_accept)(URLContext *s, URLContext *c); > > /** > * Read data from the protocol. > @@ -140,6 +141,14 @@ int ffurl_open(URLContext **puc, const char *filename, > int flags, > const AVIOInterruptCB *int_cb, AVDictionary **options); > > /** > + * Accept an URLContext c on an URLContext s > + * @param s server context > + * @param c client context > + * @return 0 on success, ff_neterrno() on failure. > + */ > +int ffurl_accept(URLContext *s, URLContext *c); > + > +/** > * Read up to size bytes from the resource accessed by h, and store > * the read bytes in buf. > * > -- > 2.1.0 > > From 4a2f643af7cc5a7692a6267f484ba3f8d0363066 Mon Sep 17 00:00:00 2001 > From: Stephan Holljes <klaxa1...@googlemail.com> > Date: Fri, 26 Jun 2015 20:51:26 +0200 > Subject: [PATCH 3/6] lavf/avio: add avio_accept > > Signed-off-by: Stephan Holljes <klaxa1...@googlemail.com> > --- > libavformat/avio.h | 1 + > libavformat/aviobuf.c | 12 ++++++++++++ > 2 files changed, 13 insertions(+) > > diff --git a/libavformat/avio.h b/libavformat/avio.h > index 5ac5d38..f688851 100644 > --- a/libavformat/avio.h > +++ b/libavformat/avio.h > @@ -648,4 +648,5 @@ struct AVBPrint; > */ > int avio_read_to_bprint(AVIOContext *h, struct AVBPrint *pb, size_t > max_size); > > +int avio_accept(AVIOContext *s, AVIOContext **c); > #endif /* AVFORMAT_AVIO_H */ > diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c > index ff85081..dcdc1a4 100644 > --- a/libavformat/aviobuf.c > +++ b/libavformat/aviobuf.c > @@ -1021,6 +1021,18 @@ int avio_read_to_bprint(AVIOContext *h, AVBPrint *pb, > size_t max_size) > return 0; > } > > +int avio_accept(AVIOContext *s, AVIOContext **c) { > + URLContext *sc = s->opaque; > + URLContext *cc; > + int ret; > + if ((ret = ffurl_open(&cc, sc->filename, AVIO_FLAG_READ_WRITE, > &sc->interrupt_callback, NULL)) < 0) > + return ret; > + if ((ret = ffio_fdopen(c, cc)) < 0) > + return ret; > + ret = ffurl_accept(sc, cc); > + return ret; > +} > + > /* output in a dynamic buffer */ > > typedef struct DynBuffer { > -- > 2.1.0 > > From 8e83b82efb5ae26296bed8244fba1fd93b978f48 Mon Sep 17 00:00:00 2001 > From: Stephan Holljes <klaxa1...@googlemail.com> > Date: Fri, 26 Jun 2015 20:55:58 +0200 > Subject: [PATCH 4/6] lavf/tcp: make tcp_open return with a listening socket > without calling accept() > > Signed-off-by: Stephan Holljes <klaxa1...@googlemail.com> > --- > libavformat/tcp.c | 4 +--- > 1 file changed, 1 insertion(+), 3 deletions(-) > > diff --git a/libavformat/tcp.c b/libavformat/tcp.c > index f24cad2..04210b3 100644 > --- a/libavformat/tcp.c > +++ b/libavformat/tcp.c > @@ -126,11 +126,9 @@ static int tcp_open(URLContext *h, const char *uri, int > flags) > } > > if (s->listen) { > - if ((ret = ff_listen_bind(fd, cur_ai->ai_addr, cur_ai->ai_addrlen, > - s->listen_timeout, h)) < 0) { > + if ((ret = ff_listen(fd, cur_ai->ai_addr, cur_ai->ai_addrlen)) < 0) { > goto fail1; > } > - fd = ret; > } else { > if ((ret = ff_listen_connect(fd, cur_ai->ai_addr, cur_ai->ai_addrlen, > s->open_timeout / 1000, h, > !!cur_ai->ai_next)) < 0) { > -- > 2.1.0 > > From 418fcd63d8e5ff721ba38763f3677d1b5be6396b Mon Sep 17 00:00:00 2001 > From: Stephan Holljes <klaxa1...@googlemail.com> > Date: Fri, 26 Jun 2015 20:56:27 +0200 > Subject: [PATCH 5/6] lavf/tcp: add tcp_accept > > Signed-off-by: Stephan Holljes <klaxa1...@googlemail.com> > --- > libavformat/tcp.c | 15 +++++++++++++++ > 1 file changed, 15 insertions(+) > > diff --git a/libavformat/tcp.c b/libavformat/tcp.c > index 04210b3..588e602 100644 > --- a/libavformat/tcp.c > +++ b/libavformat/tcp.c > @@ -161,6 +161,20 @@ static int tcp_open(URLContext *h, const char *uri, int > flags) > return ret; > } > > +static int tcp_accept(URLContext *s, URLContext *c) > +{ > + TCPContext *sc = s->priv_data; > + TCPContext *cc = c->priv_data; > + int ret; > + ret = accept(sc->fd, NULL, NULL); > + if (ret < 0) { > + return ff_neterrno(); > + } > + cc->fd = ret; > + return 0; > + > +} > + > static int tcp_read(URLContext *h, uint8_t *buf, int size) > { > TCPContext *s = h->priv_data; > @@ -221,6 +235,7 @@ static int tcp_get_file_handle(URLContext *h) > URLProtocol ff_tcp_protocol = { > .name = "tcp", > .url_open = tcp_open, > + .url_accept = tcp_accept, > .url_read = tcp_read, > .url_write = tcp_write, > .url_close = tcp_close, > -- > 2.1.0 > > From 88632fa0d54a68c8876e8024c76ead5245be73d1 Mon Sep 17 00:00:00 2001 > From: Stephan Holljes <klaxa1...@googlemail.com> > Date: Fri, 26 Jun 2015 20:58:56 +0200 > Subject: [PATCH 6/6] lavf/http: add http_accept and move connection logic to > it, since ffurl_open in http_listen returns without a connected client > > Signed-off-by: Stephan Holljes <klaxa1...@googlemail.com> > --- > libavformat/http.c | 29 +++++++++++++++++++++-------- > 1 file changed, 21 insertions(+), 8 deletions(-) > > diff --git a/libavformat/http.c b/libavformat/http.c > index 676bfd5..65ac507 100644 > --- a/libavformat/http.c > +++ b/libavformat/http.c > @@ -320,11 +320,10 @@ static int http_listen(URLContext *h, const char *uri, > int flags, > AVDictionary **options) { > HTTPContext *s = h->priv_data; > int ret; > - static const char header[] = "HTTP/1.1 200 OK\r\nContent-Type: > application/octet-stream\r\nTransfer-Encoding: chunked\r\n\r\n"; > char hostname[1024], proto[10]; > char lower_url[100]; > const char *lower_proto = "tcp"; > - int port, new_location; > + int port; > s->chunked_post = 1; > av_url_split(proto, sizeof(proto), NULL, 0, hostname, sizeof(hostname), > &port, > NULL, 0, uri); > @@ -336,12 +335,6 @@ static int http_listen(URLContext *h, const char *uri, > int flags, > if ((ret = ffurl_open(&s->hd, lower_url, AVIO_FLAG_READ_WRITE, > &h->interrupt_callback, options)) < 0) > goto fail; > - if ((ret = http_read_header(h, &new_location)) < 0) > - goto fail; > - if ((ret = ffurl_write(s->hd, header, strlen(header))) < 0) > - goto fail; > - return 0; > - > fail: > handle_http_errors(h, ret); > av_dict_free(&s->chained_options); > @@ -382,6 +375,25 @@ static int http_open(URLContext *h, const char *uri, int > flags, > return ret; > } > > +static int http_accept(URLContext *s, URLContext *c) > +{ > + int ret, new_location; > + static const char header[] = "HTTP/1.1 200 OK\r\nContent-Type: > application/octet-stream\r\nTransfer-Encoding: chunked\r\n\r\n"; > + HTTPContext *sh = s->priv_data; > + HTTPContext *ch = c->priv_data; > + URLContext *sl = sh->hd; > + URLContext *cl = ch->hd; > + if ((ret = ffurl_accept(sl, cl)) < 0) > + goto fail; > + if ((ret = http_read_header(s, &new_location)) < 0) > + goto fail; This is what I explained earlier: These need to be in two separate API functions, because the application will probably want to fork a new thread between ffurl_accept() and http_read_header(). > + if ((ret = ffurl_write(sl, header, strlen(header))) < 0) > + goto fail; > +fail: > + handle_http_errors(s, ret); > + return ret; > +} > + > static int http_getc(HTTPContext *s) > { > int len; > @@ -1477,6 +1489,7 @@ static int http_proxy_write(URLContext *h, const > uint8_t *buf, int size) > URLProtocol ff_httpproxy_protocol = { > .name = "httpproxy", > .url_open = http_proxy_open, > + .url_accept = http_accept, > .url_read = http_buf_read, > .url_write = http_proxy_write, > .url_close = http_proxy_close, Thanks for the timely update. I will look at the code more carefully but it seems to be going in the right direction. Regards, -- Nicolas George
signature.asc
Description: Digital signature
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel