You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2021/01/18 02:44:27 UTC
[incubator-nuttx-apps] 01/02: webclient: Implement AF_LOCAL
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx-apps.git
commit 1131cbe14d8fc32f300ed34310d0a171e3aa899f
Author: YAMAMOTO Takashi <ya...@midokura.com>
AuthorDate: Thu Jan 14 12:22:47 2021 +0900
webclient: Implement AF_LOCAL
---
include/netutils/webclient.h | 20 ++++++-----
netutils/webclient/webclient.c | 78 ++++++++++++++++++++++++++++++++----------
2 files changed, 72 insertions(+), 26 deletions(-)
diff --git a/include/netutils/webclient.h b/include/netutils/webclient.h
index 7aaa5d7..8725d2f 100644
--- a/include/netutils/webclient.h
+++ b/include/netutils/webclient.h
@@ -186,18 +186,22 @@ struct webclient_context
{
/* request parameters
*
- * method - HTTP method like "GET", "POST".
- * The default value is "GET".
- * url - A pointer to a string containing the full URL.
- * (e.g., http://www.nutt.org/index.html, or
- * http://192.168.23.1:80/index.html)
- * headers - An array of pointers to the extra headers.
- * nheaders - The number of elements in the "headers" array.
- * bodylen - The size of the request body.
+ * method - HTTP method like "GET", "POST".
+ * The default value is "GET".
+ * url - A pointer to a string containing the full URL.
+ * (e.g., http://www.nutt.org/index.html, or
+ * http://192.168.23.1:80/index.html)
+ * unix_socket_path - If not NULL, the path to an AF_LOCAL socket.
+ * headers - An array of pointers to the extra headers.
+ * nheaders - The number of elements in the "headers" array.
+ * bodylen - The size of the request body.
*/
FAR const char *method;
FAR const char *url;
+#if defined(CONFIG_WEBCLIENT_NET_LOCAL)
+ FAR const char *unix_socket_path;
+#endif
FAR const char * FAR const *headers;
unsigned int nheaders;
size_t bodylen;
diff --git a/netutils/webclient/webclient.c b/netutils/webclient/webclient.c
index 26b4d1b..73c18dc 100644
--- a/netutils/webclient/webclient.c
+++ b/netutils/webclient/webclient.c
@@ -67,6 +67,9 @@
#include <arpa/inet.h>
#include <netinet/in.h>
+#if defined(CONFIG_WEBCLIENT_NET_LOCAL)
+#include <sys/un.h>
+#endif
#include <nuttx/version.h>
@@ -649,7 +652,6 @@ static int wget_gethostip(FAR char *hostname, FAR struct in_addr *dest)
int webclient_perform(FAR struct webclient_context *ctx)
{
- struct sockaddr_in server;
struct wget_s *ws;
struct timeval tv;
bool redirected;
@@ -722,15 +724,70 @@ int webclient_perform(FAR struct webclient_context *ctx)
{
char port_str[sizeof("65535")];
+#if defined(CONFIG_WEBCLIENT_NET_LOCAL)
+ if (ctx->unix_socket_path != NULL)
+ {
+ nerr("ERROR: TLS on AF_LOCAL socket is not implemented\n");
+ free(ws);
+ return -ENOTSUP;
+ }
+#endif
+
snprintf(port_str, sizeof(port_str), "%u", ws->port);
ret = tls_ops->connect(tls_ctx, ws->hostname, port_str,
CONFIG_WEBCLIENT_TIMEOUT, &conn.tls_conn);
}
else
{
+#if defined(CONFIG_WEBCLIENT_NET_LOCAL)
+ struct sockaddr_un server_un;
+#endif
+ struct sockaddr_in server_in;
+ int domain;
+ const struct sockaddr *server_address;
+ socklen_t server_address_len;
+
+#if defined(CONFIG_WEBCLIENT_NET_LOCAL)
+ if (ctx->unix_socket_path != NULL)
+ {
+ domain = PF_LOCAL;
+
+ memset(&server_un, 0, sizeof(server_un));
+ server_un.sun_family = AF_LOCAL;
+ strncpy(server_un.sun_path, ctx->unix_socket_path,
+ sizeof(server_un.sun_path));
+#if !defined(__NuttX__) && !defined(__linux__)
+ server_un.sun_len = SUN_LEN(&server_un);
+#endif
+ server_address = (const struct sockaddr *)&server_un;
+ server_address_len = sizeof(server_un);
+ }
+ else
+#endif
+ {
+ domain = PF_INET;
+
+ /* Get the server address from the host name */
+
+ server_in.sin_family = AF_INET;
+ server_in.sin_port = htons(ws->port);
+ ret = wget_gethostip(ws->hostname, &server_in.sin_addr);
+ if (ret < 0)
+ {
+ /* Could not resolve host (or malformed IP address) */
+
+ nwarn("WARNING: Failed to resolve hostname\n");
+ ret = -EHOSTUNREACH;
+ goto errout_with_errno;
+ }
+
+ server_address = (const struct sockaddr *)&server_in;
+ server_address_len = sizeof(struct sockaddr_in);
+ }
+
/* Create a socket */
- conn.sockfd = socket(AF_INET, SOCK_STREAM, 0);
+ conn.sockfd = socket(domain, SOCK_STREAM, 0);
if (conn.sockfd < 0)
{
/* socket failed. It will set the errno appropriately */
@@ -750,27 +807,12 @@ int webclient_perform(FAR struct webclient_context *ctx)
setsockopt(conn.sockfd, SOL_SOCKET, SO_SNDTIMEO,
(FAR const void *)&tv, sizeof(struct timeval));
- /* Get the server address from the host name */
-
- server.sin_family = AF_INET;
- server.sin_port = htons(ws->port);
- ret = wget_gethostip(ws->hostname, &server.sin_addr);
- if (ret < 0)
- {
- /* Could not resolve host (or malformed IP address) */
-
- nwarn("WARNING: Failed to resolve hostname\n");
- ret = -EHOSTUNREACH;
- goto errout_with_errno;
- }
-
/* Connect to server. First we have to set some fields in the
* 'server' address structure. The system will assign me an
* arbitrary local port that is not in use.
*/
- ret = connect(conn.sockfd, (struct sockaddr *)&server,
- sizeof(struct sockaddr_in));
+ ret = connect(conn.sockfd, server_address, server_address_len);
if (ret == -1)
{
ret = -errno;