[vlc-commits] http: add manager flag for non-idempotent requests
Rémi Denis-Courmont
git at videolan.org
Sun Oct 4 16:19:23 CEST 2020
vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Sun Oct 4 16:56:32 2020 +0300| [075d089cc3873aeece38f2e5d8cbb9dbdf674807] | committer: Rémi Denis-Courmont
http: add manager flag for non-idempotent requests
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=075d089cc3873aeece38f2e5d8cbb9dbdf674807
---
modules/access/http/connmgr.c | 53 +++++++++++++++++++++++++----------------
modules/access/http/connmgr.h | 4 +++-
modules/access/http/file_test.c | 4 +++-
modules/access/http/resource.c | 2 +-
4 files changed, 40 insertions(+), 23 deletions(-)
diff --git a/modules/access/http/connmgr.c b/modules/access/http/connmgr.c
index 5105fdc3fe..7f16405536 100644
--- a/modules/access/http/connmgr.c
+++ b/modules/access/http/connmgr.c
@@ -136,11 +136,6 @@ struct vlc_http_msg *vlc_http_mgr_reuse(struct vlc_http_mgr *mgr,
struct vlc_http_msg *m = vlc_http_msg_get_initial(stream);
if (m != NULL)
return m;
-
- /* NOTE: If the request were not idempotent, we would not know if it
- * was processed by the other end. Thus POST is not used/supported so
- * far, and CONNECT is treated as if it were idempotent (which works
- * fine here). */
}
/* Get rid of closing or reset connection */
vlc_http_mgr_release(mgr, conn);
@@ -149,7 +144,8 @@ struct vlc_http_msg *vlc_http_mgr_reuse(struct vlc_http_mgr *mgr,
static struct vlc_http_msg *vlc_https_request(struct vlc_http_mgr *mgr,
const char *host, unsigned port,
- const struct vlc_http_msg *req)
+ const struct vlc_http_msg *req,
+ bool idempotent)
{
vlc_tls_t *tls;
bool http2 = true;
@@ -164,10 +160,16 @@ static struct vlc_http_msg *vlc_https_request(struct vlc_http_mgr *mgr,
return NULL;
}
- /* TODO? non-idempotent request support */
- struct vlc_http_msg *resp = vlc_http_mgr_reuse(mgr, host, port, req);
- if (resp != NULL)
- return resp; /* existing connection reused */
+ if (idempotent)
+ { /* If the request is idempotent, try to reuse an existing connection.
+ * Otherwise, it is possible but unadvisable as we would not know if
+ * the nonidempotent request was processed if the connection fails
+ * before the response is received.
+ */
+ struct vlc_http_msg *resp = vlc_http_mgr_reuse(mgr, host, port, req);
+ if (resp != NULL)
+ return resp; /* existing connection reused */
+ }
char *proxy = vlc_http_proxy_find(host, port, true);
if (proxy != NULL)
@@ -202,21 +204,27 @@ static struct vlc_http_msg *vlc_https_request(struct vlc_http_mgr *mgr,
return NULL;
}
- mgr->conn = conn;
+ if (mgr->conn != NULL)
+ vlc_http_mgr_release(mgr, mgr->conn);
+ mgr->conn = conn;
return vlc_http_mgr_reuse(mgr, host, port, req);
}
static struct vlc_http_msg *vlc_http_request(struct vlc_http_mgr *mgr,
const char *host, unsigned port,
- const struct vlc_http_msg *req)
+ const struct vlc_http_msg *req,
+ bool idempotent)
{
if (mgr->creds != NULL && mgr->conn != NULL)
return NULL; /* switch from HTTPS to HTTP not implemented */
- struct vlc_http_msg *resp = vlc_http_mgr_reuse(mgr, host, port, req);
- if (resp != NULL)
- return resp;
+ if (idempotent)
+ {
+ struct vlc_http_msg *resp = vlc_http_mgr_reuse(mgr, host, port, req);
+ if (resp != NULL)
+ return resp;
+ }
struct vlc_http_conn *conn;
struct vlc_http_stream *stream;
@@ -232,7 +240,7 @@ static struct vlc_http_msg *vlc_http_request(struct vlc_http_mgr *mgr,
if (url.psz_host != NULL)
stream = vlc_h1_request(mgr->logger, url.psz_host,
url.i_port ? url.i_port : 80, true, req,
- true, false, &conn);
+ idempotent, false, &conn);
else
stream = NULL;
@@ -240,30 +248,35 @@ static struct vlc_http_msg *vlc_http_request(struct vlc_http_mgr *mgr,
}
else
stream = vlc_h1_request(mgr->logger, host, port ? port : 80, false,
- req, true, false, &conn);
+ req, idempotent, false, &conn);
if (stream == NULL)
return NULL;
- resp = vlc_http_msg_get_initial(stream);
+ struct vlc_http_msg *resp = vlc_http_msg_get_initial(stream);
if (resp == NULL)
{
vlc_http_conn_release(conn);
return NULL;
}
+ if (mgr->conn != NULL)
+ vlc_http_mgr_release(mgr, mgr->conn);
+
mgr->conn = conn;
return resp;
}
struct vlc_http_msg *vlc_http_mgr_request(struct vlc_http_mgr *mgr, bool https,
const char *host, unsigned port,
- const struct vlc_http_msg *m)
+ const struct vlc_http_msg *m,
+ bool idempotent)
{
if (port && vlc_http_port_blocked(port))
return NULL;
- return (https ? vlc_https_request : vlc_http_request)(mgr, host, port, m);
+ return (https ? vlc_https_request : vlc_http_request)(mgr, host, port, m,
+ idempotent);
}
struct vlc_http_cookie_jar_t *vlc_http_mgr_get_jar(struct vlc_http_mgr *mgr)
diff --git a/modules/access/http/connmgr.h b/modules/access/http/connmgr.h
index a4c258842d..e853e1fde6 100644
--- a/modules/access/http/connmgr.h
+++ b/modules/access/http/connmgr.h
@@ -45,12 +45,14 @@ struct vlc_http_cookie_jar_t;
* @param host name of authoritative HTTP server to send the request to
* @param port TCP server port number, or 0 for the default port number
* @param req HTTP request header to send
+ * @param idempotent whether the request is idempotent
*
* @return The initial HTTP response header, or NULL in case of failure.
*/
struct vlc_http_msg *vlc_http_mgr_request(struct vlc_http_mgr *mgr, bool https,
const char *host, unsigned port,
- const struct vlc_http_msg *req);
+ const struct vlc_http_msg *req,
+ bool idempotent);
struct vlc_http_cookie_jar_t *vlc_http_mgr_get_jar(struct vlc_http_mgr *);
diff --git a/modules/access/http/file_test.c b/modules/access/http/file_test.c
index 5779812056..fbe55d4689 100644
--- a/modules/access/http/file_test.c
+++ b/modules/access/http/file_test.c
@@ -336,7 +336,8 @@ static struct vlc_http_stream stream = { &stream_callbacks };
struct vlc_http_msg *vlc_http_mgr_request(struct vlc_http_mgr *mgr, bool https,
const char *host, unsigned port,
- const struct vlc_http_msg *req)
+ const struct vlc_http_msg *req,
+ bool idempotent)
{
const char *str;
char *end;
@@ -345,6 +346,7 @@ struct vlc_http_msg *vlc_http_mgr_request(struct vlc_http_mgr *mgr, bool https,
assert(mgr == NULL);
assert(!strcmp(host, "www.example.com"));
assert(port == 8443);
+ assert(idempotent);
str = vlc_http_msg_get_method(req);
assert(!strcmp(str, "GET"));
diff --git a/modules/access/http/resource.c b/modules/access/http/resource.c
index 5f5406a11c..2550146d00 100644
--- a/modules/access/http/resource.c
+++ b/modules/access/http/resource.c
@@ -91,7 +91,7 @@ retry:
return NULL;
struct vlc_http_msg *resp = vlc_http_mgr_request(res->manager, res->secure,
- res->host, res->port, req);
+ res->host, res->port, req, true);
vlc_http_msg_destroy(req);
resp = vlc_http_msg_get_final(resp);
More information about the vlc-commits
mailing list