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 <yamam...@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;