[vlc-commits] http: add vlc_h1_request() for TCP Fast Open
Rémi Denis-Courmont
git at videolan.org
Sat Mar 4 18:56:02 CET 2017
vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Sat Mar 4 19:11:22 2017 +0200| [af7d7c742ca2090272411dbfdaeaa8580372ff95] | committer: Rémi Denis-Courmont
http: add vlc_h1_request() for TCP Fast Open
...with insecure HTTP.
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=af7d7c742ca2090272411dbfdaeaa8580372ff95
---
modules/access/http/conn.h | 36 +++++++++++++++++++++++++
modules/access/http/h1conn.c | 63 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 99 insertions(+)
diff --git a/modules/access/http/conn.h b/modules/access/http/conn.h
index 27f0e31..1f6705f 100644
--- a/modules/access/http/conn.h
+++ b/modules/access/http/conn.h
@@ -66,6 +66,42 @@ struct vlc_http_conn *vlc_h1_conn_create(void *ctx, struct vlc_tls *,
struct vlc_http_stream *vlc_chunked_open(struct vlc_http_stream *,
struct vlc_tls *);
+/**
+ * Sends an HTTP/1.x request through a new connection.
+ *
+ * This function resolves a the specified HTTP server hostname, establishes a
+ * connection to specified TCP port of the server, then sends an HTTP request.
+ * The connection is not protected with TLS.
+ *
+ * All those operations are combined in a single function call in order to
+ * support TCP Fast Open. That can save one round-trip when establishing a new
+ * HTTP connection.
+
+ * \note In the case of TLS, TCP Fast Open would convey the TLS Client Hello
+ * message rather than the HTTP request header. The HTTP request header can
+ * however be sent with the TLS False Start. This is handled by the TLS stack
+ * and does not require a combined function call.
+ *
+ * \param ctx opaque context pointer for the HTTP connection
+ * \param hostname HTTP server or proxy hostname to connect to
+ * \param port TCP port number to connect to
+ * \param proxy true of the hostname and port correspond to an HTTP proxy,
+ * or false if they correspond to an HTTP origin server
+ * \param req HTTP request message
+ * \param idempotent whether the HTTP request is idempotent (e.g. GET),
+ * or not (e.g. POST)
+ * \param connp pointer to storage space for the established HTTP connection
+ * (or NULL if the connection is not to be reused) [OUT]
+ * can be NULL if the connection is not meant to be reused
+ * \return an HTTP stream on success, NULL on error
+ * \note *connp is undefined on error.
+ */
+struct vlc_http_stream *vlc_h1_request(void *ctx, const char *hostname,
+ unsigned port, bool proxy,
+ const struct vlc_http_msg *req,
+ bool idempotent,
+ struct vlc_http_conn **restrict connp);
+
/** @} */
/**
diff --git a/modules/access/http/h1conn.c b/modules/access/http/h1conn.c
index eaedcbf..963715f 100644
--- a/modules/access/http/h1conn.c
+++ b/modules/access/http/h1conn.c
@@ -338,3 +338,66 @@ struct vlc_http_conn *vlc_h1_conn_create(void *ctx, vlc_tls_t *tls, bool proxy)
return &conn->conn;
}
+
+struct vlc_http_stream *vlc_h1_request(void *ctx, const char *hostname,
+ unsigned port, bool proxy,
+ const struct vlc_http_msg *req,
+ bool idempotent,
+ struct vlc_http_conn **restrict connp)
+{
+ struct addrinfo hints =
+ {
+ .ai_socktype = SOCK_STREAM,
+ .ai_protocol = IPPROTO_TCP,
+ }, *res;
+
+ vlc_http_dbg(ctx, "resolving %s ...", hostname);
+
+ int val = vlc_getaddrinfo_i11e(hostname, port, &hints, &res);
+ if (val != 0)
+ { /* TODO: C locale for gai_strerror() */
+ vlc_http_err(ctx, "cannot resolve %s: %s", hostname,
+ gai_strerror(val));
+ return NULL;
+ }
+
+ for (const struct addrinfo *p = res; p != NULL; p = p->ai_next)
+ {
+ vlc_tls_t *tcp = vlc_tls_SocketOpenAddrInfo(p, idempotent);
+ if (tcp == NULL)
+ {
+ vlc_http_err(ctx, "socket error: %s", vlc_strerror_c(errno));
+ continue;
+ }
+
+ struct vlc_http_conn *conn = vlc_h1_conn_create(ctx, tcp, proxy);
+ if (unlikely(conn == NULL))
+ {
+ vlc_tls_SessionDelete(tcp);
+ continue;
+ }
+
+ /* Send the HTTP request */
+ struct vlc_http_stream *stream = vlc_http_stream_open(conn, req);
+
+ if (stream != NULL)
+ {
+ if (connp != NULL)
+ *connp = conn;
+ else
+ vlc_http_conn_release(conn);
+
+ freeaddrinfo(res);
+ return stream;
+ }
+
+ vlc_http_conn_release(conn);
+
+ if (!idempotent)
+ break; /* If the request is nonidempotent, it cannot be resent. */
+ }
+
+ /* All address info failed. */
+ freeaddrinfo(res);
+ return NULL;
+}
More information about the vlc-commits
mailing list