apps/netutils/libcurl4nx: This is an initial comit libcurl4nx. It is not complete yet, but I still wish to commit the unfinished bits to describe the roadmap, and because it is already usable. It will be updated and fixed in the future weeks and months, certainly including POST support and later, SSL.

Some improvements could be made by anyone.  For example, I know the main routine in perform() shall be split into several parts for readability. I apologize in advance for this kind of spaghetti code, but I was short on time to refactor it.  Also chunked HTTP transfer encoding would be a nice contribution from anyone interested. It is detected but not yet supported.
This commit is contained in:
Sebastien Lorquet 2019-05-03 07:26:13 -06:00 committed by Gregory Nutt
parent 445e0eef79
commit fc7aa92b57
15 changed files with 2115 additions and 0 deletions

323
include/netutils/curl4nx.h Normal file
View File

@ -0,0 +1,323 @@
/****************************************************************************
* apps/include/netutils/curl4nx.h
*
* This file is part of the NuttX RTOS:
*
* Copyright (C) 2019 Sebastien Lorquet. All rights reserved.
* Author: Sebastien Lorquet <sebastien@lorquet.fr>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
****************************************************************************/
#ifndef __APPS_INCLUDE_NETUTILS_CURL4NX_H
#define __APPS_INCLUDE_NETUTILS_CURL4NX_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
/****************************************************************************
* Public Defines
****************************************************************************/
enum curl4nxerrors_e
{
CURL4NXE_OK,
CURL4NXE_UNSUPPORTED_PROTOCOL,
CURL4NXE_FAILED_INIT,
CURL4NXE_URL_MALFORMAT,
CURL4NXE_NOT_BUILT_IN,
CURL4NXE_COULDNT_RESOLVE_HOST,
CURL4NXE_COULDNT_CONNECT,
CURL4NXE_HTTP2,
CURL4NXE_PARTIAL_FILE,
CURL4NXE_HTTP_RETURNED_ERROR,
CURL4NXE_WRITE_ERROR,
CURL4NXE_UPLOAD_FAILED,
CURL4NXE_READ_ERROR,
CURL4NXE_OUT_OF_MEMORY,
CURL4NXE_OPERATION_TIMEDOUT,
CURL4NXE_RANGE_ERROR,
CURL4NXE_HTTP_POST_ERROR,
CURL4NXE_SSL_CONNECT_ERROR,
CURL4NXE_BAD_DOWNLOAD_RESUME,
CURL4NXE_FUNCTION_NOT_FOUND,
CURL4NXE_ABORTED_BY_CALLBACK,
CURL4NXE_BAD_FUNCTION_ARGUMENT,
CURL4NXE_TOO_MANY_REDIRECTS,
CURL4NXE_UNKNOWN_OPTION,
CURL4NXE_GOT_NOTHING,
CURL4NXE_SEND_ERROR,
CURL4NXE_RECV_ERROR,
CURL4NXE_SSL_CERTPROBLEM,
CURL4NXE_SSL_CIPHER,
CURL4NXE_PEER_FAILED_VERIFICATION,
CURL4NXE_BAD_CONTENT_ENCODING,
CURL4NXE_LOGIN_DENIED,
CURL4NXE_REMOTE_DISK_FULL,
CURL4NXE_REMOTE_FILE_EXISTS,
CURL4NXE_SSL_CACERT_BADFILE,
CURL4NXE_REMOTE_FILE_NOT_FOUND,
CURL4NXE_AGAIN,
CURL4NXE_SSL_ISSUER_ERROR,
CURL4NXE_CHUNK_FAILED,
CURL4NXE_SSL_PINNEDPUBKEYNOTMATCH,
CURL4NXE_SSL_INVALIDCERTSTATUS,
CURL4NXE_HTTP2_STREAM,
CURL4NXE_RECURSIVE_API_CALL,
};
enum curl4nxopt_e
{
/* Options that are currently implemented */
CURL4NXOPT_URL,
CURL4NXOPT_PORT,
CURL4NXOPT_BUFFERSIZE,
CURL4NXOPT_HEADERFUNCTION,
CURL4NXOPT_HEADERDATA,
CURL4NXOPT_FAILONERROR,
CURL4NXOPT_FOLLOWLOCATION,
CURL4NXOPT_MAXREDIRS,
CURL4NXOPT_VERBOSE,
/* Options that will be implemented */
CURL4NXOPT_HEADER,
CURL4NXOPT_NOPROGRESS,
CURL4NXOPT_WRITEFUNCTION,
CURL4NXOPT_WRITEDATA,
CURL4NXOPT_READFUNCTION,
CURL4NXOPT_READDATA,
CURL4NXOPT_XFERINFOFUNCTION,
CURL4NXOPT_XFERINFODATA,
CURL4NXOPT_KEEP_SENDING_ON_ERROR,
CURL4NXOPT_PATH_AS_IS,
CURL4NXOPT_TCP_KEEPALIVE,
CURL4NXOPT_TCP_KEEPIDLE,
CURL4NXOPT_TCP_KEEPINTVL,
CURL4NXOPT_PUT,
CURL4NXOPT_POST,
CURL4NXOPT_POSTFIELDS,
CURL4NXOPT_POSTFIELDSIZE,
CURL4NXOPT_COPYPOSTFIELDS,
CURL4NXOPT_HTTPPOST,
CURL4NXOPT_REFERER,
CURL4NXOPT_USERAGENT,
CURL4NXOPT_HTTPHEADER,
CURL4NXOPT_HEADEROPT,
CURL4NXOPT_HTTPGET,
CURL4NXOPT_HTTP_VERSION,
/* Options that will be implemented later */
CURL4NXOPT_SSL_CTX_FUNCTION,
CURL4NXOPT_SSL_CTX_DATA,
CURL4NXOPT_USERNAME,
CURL4NXOPT_PASSWORD,
CURL4NXOPT_HTTPAUTH,
CURL4NXOPT_POSTREDIR,
CURL4NXOPT_COOKIE,
CURL4NXOPT_COOKIEFILE,
CURL4NXOPT_COOKIEJAR,
CURL4NXOPT_COOKIESESSION,
CURL4NXOPT_COOKIELIST,
CURL4NXOPT_IGNORE_CONTENT_LENGTH,
CURL4NXOPT_RANGE,
CURL4NXOPT_RESUME_FROM,
CURL4NXOPT_CUSTOMREQUEST,
CURL4NXOPT_UPLOAD,
CURL4NXOPT_UPLOAD_BUFFERSIZE,
CURL4NXOPT_TIMEOUT,
CURL4NXOPT_TIMEOUT_MS,
CURL4NXOPT_FRESH_CONNECT,
CURL4NXOPT_CONNECTTIMEOUT,
CURL4NXOPT_CONNECTTIMEOUT_MS,
CURL4NXOPT_USE_SSL,
CURL4NXOPT_SSLCERT,
CURL4NXOPT_SSLKEY,
CURL4NXOPT_KEYPASSWD,
CURL4NXOPT_SSLVERSION,
CURL4NXOPT_SSL_VERIFYHOST,
CURL4NXOPT_SSL_VERIFYPEER,
CURL4NXOPT_SSL_VERIFYSTATUS,
CURL4NXOPT_CAPATH,
CURL4NXOPT_PINNEDPUBLICKEY,
CURL4NXOPT_RANDOM_FILE,
CURL4NXOPT_SSL_CIPHER_LIST,
CURL4NXOPT_TLS13_CIPHERS,
CURL4NXOPT_SSL_OPTIONS,
};
/* For CURL4NXOPT_HTTP_VERSION */
#define CURL4NX_HTTP_VERSION_1_0 0x10
#define CURL4NX_HTTP_VERSION_1_1 0x11
#define CURL4NX_HTTP_VERSION_2_0 0x20 /* Unsupported! */
/****************************************************************************
* Public Types
****************************************************************************/
/****************************************************************************
* Name: curl4nx_iofunction_f
*
* Description: Type of the callback function used with
* CURL4NXOPT_WRITEFUNCTION and CURL4NXOPT_READFUNCTION.
*
****************************************************************************/
typedef size_t (*curl4nx_iofunc_f)(FAR char *ptr, size_t size,
size_t nmemb, FAR void *userdata);
/****************************************************************************
* Name: curl4nx_easy_strerror()
*
* Description: Return a textual description for an error code.
*
****************************************************************************/
typedef int (*curl4nx_xferinfofunc_f)(FAR void *clientp,
uint64_t dltotal, uint64_t dlnow,
uint64_t ultotal, uint64_t ulnow);
#ifdef __cplusplus
extern "C"
{
#endif
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: curl4nx_easy_strerror()
*
* Description: Return a textual description for an error code.
*
****************************************************************************/
FAR const char *curl4nx_easy_strerror(int errornum);
/****************************************************************************
* Name: curl4nx_easy_init()
*
* Description: Initialize a context for curl4nx operations.
*
****************************************************************************/
FAR struct curl4nx_s *curl4nx_easy_init(void);
/****************************************************************************
* Name: curl4nx_easy_escape()
*
* Description: Escape an URL to remove any forbidden character. Returned
* string MUST be released using free().
*
****************************************************************************/
FAR char *curl4nx_easy_escape(FAR struct curl4nx_s *handle,
FAR const char *string, int length);
/****************************************************************************
* Name: curl4nx_easy_unescape()
*
* Description: Unescape an escaped URL to replace all escaped characters.
* Returned string MUST be released using free().
*
****************************************************************************/
FAR char *curl4nx_easy_unescape(FAR struct curl4nx_s *handle,
FAR const char *url, int inlength,
FAR int *outlength);
/****************************************************************************
* Name: curl4nx_easy_setopt()
*
* Description: Define an option in the given curl4nx context.
*
****************************************************************************/
int curl4nx_easy_setopt(FAR struct curl4nx_s *handle, int option,
FAR void *optionptr);
/****************************************************************************
* Name: curl4nx_easy_reset()
*
* Description: Reset all operations that were set using curl4nx_easy_setopt()
* to their default values.
*
****************************************************************************/
void curl4nx_easy_reset(FAR struct curl4nx_s *handle);
/****************************************************************************
* Name: curl4nx_easy_duphandle()
*
* Description: Clone the current state of a handle.
*
****************************************************************************/
FAR struct curl4nx_s *curl4nx_easy_duphandle(FAR struct curl4nx_s *handle);
/****************************************************************************
* Name: curl4nx_easy_perform()
*
* Description: Perform the http operation that was set up in this curl4nx
* context.
*
****************************************************************************/
int curl4nx_easy_perform(FAR struct curl4nx_s *handle);
/****************************************************************************
* Name: curl4nx_easy_getinfo()
*
* Description: Get information about the current transfer.
*
****************************************************************************/
int curl4nx_easy_getinfo(FAR struct curl4nx_s *handle, int info,
FAR void *infoptr);
/****************************************************************************
* Name: curl4nx_easy_cleanup()
*
* Description: Cleanup any resource allocated within a curl4nx context.
*
****************************************************************************/
void curl4nx_easy_cleanup(FAR struct curl4nx_s *handle);
#ifdef __cplusplus
}
#endif
#endif /* __APPS_INCLUDE_NETUTILS_BASE64_H */

6
netutils/libcurl4nx/.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
/.built
/.depend
/Make.dep
/*.src
/*.obj
/*.lst

View File

@ -0,0 +1,49 @@
#
# For a description of the syntax of this configuration file,
# see the file kconfig-language.txt in the NuttX tools repository.
#
config NETUTILS_LIBCURL4NX
tristate "cURL4nx HTTP client library"
default n
depends on NET_TCP
select LIBC_NETDB
select NETUTILS_NETLIB_GENERICURLPARSER
---help---
Enable the NuttX cURL like library.
if NETUTILS_LIBCURL4NX
config LIBCURL4NX_MAXHOST
int "Maximum URL host length"
default 128
config LIBCURL4NX_MAXPATH
int "Maximum URL path length"
default 128
config LIBCURL4NX_MAXMETHOD
int "Maximum HTTP method length"
default 16
config LIBCURL4NX_MAXUSERAGENT
int "Maximum HTTP user agent length"
default 64
config LIBCURL4NX_MAXHEADERLINE
int "Maximum receivable header line"
default 128
config LIBCURL4NX_RXBUFLEN
int "Initial RX buffer size"
default 512
config LIBCURL4NX_MINRXBUFLEN
int "Minimum RX buffer size for CURL4NXOPT_BUFFERSIZE"
default 16
config LIBCURL4NX_MAXRXBUFLEN
int "Maximum RX buffer size for CURL4NXOPT_BUFFERSIZE"
default 2048
endif

View File

@ -0,0 +1,39 @@
# apps/netutils/libcurl4nx/Make.defs
# Adds selected applications to apps/ build
#
# Copyright (C) 2019 Gregory Nutt. All rights reserved.
# Author: Sebastien Lorquet <sebastien@lorquet.fr>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# 3. Neither the name NuttX nor the names of its contributors may be
# used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
############################################################################
ifeq ($(CONFIG_NETUTILS_LIBCURL4NX),y)
CONFIGURED_APPS += netutils/libcurl4nx
endif

View File

@ -0,0 +1,46 @@
############################################################################
# apps/netutils/libcurl4nx/Makefile
#
# Copyright (C) 2019 Gregory Nutt. All rights reserved.
# Author: Sebastien Lorquet <sebastien@lorquet.fr>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# 3. Neither the name NuttX nor the names of its contributors may be
# used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
############################################################################
-include $(TOPDIR)/Make.defs
# Web client library
CSRCS = curl4nx_easy_init.c curl4nx_easy_cleanup.c \
curl4nx_easy_reset.c curl4nx_easy_duphandle.c \
curl4nx_easy_escape.c curl4nx_easy_unescape.c \
curl4nx_easy_setopt.c curl4nx_easy_perform.c \
curl4nx_easy_getinfo.c
include $(APPDIR)/Application.mk

View File

@ -0,0 +1,78 @@
/****************************************************************************
* apps/netutils/libcurl4nx/curl4nx_easy_cleanup.c
* Implementation of the HTTP client, cURL like interface.
*
* Copyright (C) 2019 Gregory Nutt. All rights reserved.
* Author: Sebastien Lorquet <sebastien@lorquet.fr>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/compiler.h>
#include <debug.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <nuttx/version.h>
#include "netutils/netlib.h"
#include "netutils/curl4nx.h"
#include "curl4nx_private.h"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: curl4nx_easy_cleanup()
****************************************************************************/
void curl4nx_easy_cleanup(FAR struct curl4nx_s *handle)
{
curl4nx_info("handle=%p\n", handle);
/* Reset custom options in the context, effectively freeing the headers */
curl4nx_easy_reset(handle);
/* And release allocated memory */
if (handle->rxbuf != NULL)
{
free(handle->rxbuf);
handle->rxbufsize = 0;
}
free(handle);
}

View File

@ -0,0 +1,87 @@
/****************************************************************************
* apps/netutils/libcurl4nx/curl4nx_easy_duphandle.c
* Implementation of the HTTP client, cURL like interface.
*
* Copyright (C) 2019 Gregory Nutt. All rights reserved.
* Author: Sebastien Lorquet <sebastien@lorquet.fr>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/compiler.h>
#include <debug.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <stdint.h>
#include <stdio.h>
#include <stdbool.h>
#include <unistd.h>
#include <netdb.h>
#include <strings.h>
#include <errno.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <nuttx/version.h>
#include "netutils/netlib.h"
#include "netutils/curl4nx.h"
#include "curl4nx_private.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Types
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: curl4nx_easy_duphandle()
****************************************************************************/
FAR struct curl4nx_s *curl4nx_easy_duphandle(FAR struct curl4nx_s *handle)
{
#warning TODO, this requires duplicating header entries
return NULL;
}

View File

@ -0,0 +1,75 @@
/****************************************************************************
* apps/netutils/libcurl4nx/curl4nx_easy_escape.c
* Implementation of the HTTP client, cURL like interface.
*
* Copyright (C) 2019 Gregory Nutt. All rights reserved.
* Author: Sebastien Lorquet <sebastien@lorquet.fr>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/compiler.h>
#include <debug.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <stdint.h>
#include <stdio.h>
#include <stdbool.h>
#include <unistd.h>
#include <netdb.h>
#include <strings.h>
#include <errno.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <nuttx/version.h>
#include "netutils/netlib.h"
#include "netutils/curl4nx.h"
#include "curl4nx_private.h"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: curl4nx_easy_escape()
****************************************************************************/
FAR char *curl4nx_easy_escape(FAR struct curl4nx_s *curl,
FAR const char *string, int length)
{
return NULL;
}

View File

@ -0,0 +1,75 @@
/****************************************************************************
* apps/netutils/libcurl4nx/curl4nx_easy_getinfo.c
* Implementation of the HTTP client, cURL like interface.
*
* Copyright (C) 2019 Gregory Nutt. All rights reserved.
* Author: Sebastien Lorquet <sebastien@lorquet.fr>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/compiler.h>
#include <debug.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <stdint.h>
#include <stdio.h>
#include <stdbool.h>
#include <unistd.h>
#include <netdb.h>
#include <strings.h>
#include <errno.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <nuttx/version.h>
#include "netutils/netlib.h"
#include "netutils/curl4nx.h"
#include "curl4nx_private.h"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: curl4nx_easy_getinfo()
****************************************************************************/
int curl4nx_easy_getinfo(FAR struct curl4nx_s *curl, int info,
FAR void *value)
{
return 0;
}

View File

@ -0,0 +1,77 @@
/****************************************************************************
* apps/netutils/libcurl4nx/curl4nx_easy_init.c
* Implementation of the HTTP client, cURL like interface.
*
* Copyright (C) 2019 Gregory Nutt. All rights reserved.
* Author: Sebastien Lorquet <sebastien@lorquet.fr>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/compiler.h>
#include <debug.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "netutils/curl4nx.h"
#include "curl4nx_private.h"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: curl4nx_easy_init()
****************************************************************************/
FAR struct curl4nx_s * curl4nx_easy_init(void)
{
FAR struct curl4nx_s *handle = malloc(sizeof(struct curl4nx_s));
if (!handle)
{
curl4nx_err("Unable to allocate memory\n");
return NULL;
}
curl4nx_info("handle=%p\n", handle);
memset(handle, 0, sizeof(struct curl4nx_s));
curl4nx_easy_reset(handle);
return handle;
}

View File

@ -0,0 +1,642 @@
/****************************************************************************
* apps/netutils/libcurl4nx/curl4nx_easy_perform.c
* Implementation of the HTTP client, cURL like interface.
*
* Copyright (C) 2019 Gregory Nutt. All rights reserved.
* Author: Sebastien Lorquet <sebastien@lorquet.fr>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/compiler.h>
#include <debug.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <stdint.h>
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <unistd.h>
#include <netdb.h>
#include <strings.h>
#include <errno.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <nuttx/version.h>
#include "netutils/netlib.h"
#include "netutils/curl4nx.h"
#include "curl4nx_private.h"
#if defined(CONFIG_NETUTILS_CODECS)
# if defined(CONFIG_CODECS_URLCODE)
# define WGET_USE_URLENCODE 1
# include "netutils/urldecode.h"
# endif
# if defined(CONFIG_CODECS_BASE64)
# include "netutils/base64.h"
# endif
#else
# undef CONFIG_CODECS_URLCODE
# undef CONFIG_CODECS_BASE64
#endif
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define CURL4NX_STATE_STATUSLINE 0
#define CURL4NX_STATE_STATUSCODE 1
#define CURL4NX_STATE_STATUSREASON 2
#define CURL4NX_STATE_HEADERS 3
#define CURL4NX_STATE_DATA_NORMAL 4
#define CURL4NX_STATE_DATA_CHUNKED 5
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: curl4nx_easy_perform()
*
* Description:
* Resolve the hostname to an IP address. There are 3 cases:
* - direct IP: inet_aton is used
* - using internal curl4nx resolution
* - DNS resolution, if available
****************************************************************************/
/****************************************************************************
* Name: curl4nx_resolve
* Description:
* Translate a host name to an IP addres (V4 only for the moment)
* - either the host is a string with an IP
* - either the known hosts were defined by CURL4NXOPT_
****************************************************************************/
static int curl4nx_resolve(FAR struct curl4nx_s *handle, FAR char *hostname,
FAR struct in_addr *ip)
{
int ret = inet_aton(hostname, ip);
if (ret != 0)
{
return CURL4NXE_OK; /* IP address is valid */
}
curl4nx_warn("Not a valid IP address, trying hostname resolution\n");
return CURL4NXE_COULDNT_RESOLVE_HOST;
}
/****************************************************************************
* Name: curl4nx_is_header
* Description:
* Return TRUE if buf contains header, then update off to point at the
* beginning of header value
****************************************************************************/
static int curl4nx_is_header(FAR char *buf, int len,
FAR const char *header, FAR int *off)
{
if (strncasecmp(buf, header, strlen(header)))
{
return false;
}
*off = strlen(header);
while ((*off) < len && buf[*off] == ' ')
{
(*off)++;
}
return true;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: curl4nx_easy_perform()
****************************************************************************/
int curl4nx_easy_perform(FAR struct curl4nx_s *handle)
{
struct sockaddr_in server;
FILE * stream; /* IOSTREAM used to printf in the socket TODO avoid */
int rxoff; /* Current offset within RX buffer */
char tmpbuf[16]; /* Buffer to hold small strings */
int tmplen; /* Number of bytes used in tmpbuffer */
int state; /* Current state of the parser */
int ret; /* Return value from internal calls */
char * headerbuf;
int headerlen;
char * end;
int cret = CURL4NXE_OK; /* Public return value */
bool redirected = false; /* Boolean to manage HTTP redirections */
bool chunked = false;
unsigned long long done = 0;
int redircount = 0;
curl4nx_info("started\n");
stream = NULL;
headerbuf = malloc(CONFIG_LIBCURL4NX_MAXHEADERLINE);
if (!headerbuf)
{
cret = CURL4NXE_OUT_OF_MEMORY;
goto abort;
}
if (handle->host[0] == 0 || handle->port == 0)
{
/* URL has not been set */
cret = CURL4NXE_URL_MALFORMAT;
goto freebuf;
}
/* TODO: check that host and port have changed or are the same, so we can
* recycle the socket for the next request.
*/
do
{
handle->sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (handle->sockfd < 0)
{
/* socket failed. It will set the errno appropriately */
curl4nx_err("ERROR: socket failed: %d\n", errno);
cret = CURL4NXE_COULDNT_CONNECT;
goto freebuf;
}
/* TODO: timeouts */
server.sin_family = AF_INET;
server.sin_port = htons(handle->port);
cret = curl4nx_resolve(handle, handle->host, &server.sin_addr);
if (cret != CURL4NXE_OK)
{
/* Could not resolve host (or malformed IP address) */
curl4nx_err("ERROR: Failed to resolve hostname\n");
cret = CURL4NXE_COULDNT_RESOLVE_HOST;
goto freebuf;
}
/* 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(handle->sockfd,
(struct sockaddr *)&server, sizeof(struct sockaddr_in));
if (ret < 0)
{
curl4nx_err("ERROR: connect failed: %d\n", errno);
cret = CURL4NXE_COULDNT_CONNECT;
goto close;
}
curl4nx_info("Connected...\n");
stream = fdopen(handle->sockfd, "wb");
/* Send request */
fprintf(stream, "%s %s HTTP/%d.%d\r\n",
handle->method,
handle->path,
handle->version >> 4,
handle->version & 0x0f);
/* Send headers */
fprintf(stream, "Host: %s\r\n", handle->host);
/* For the moment we do not support compression */
fprintf(stream, "Content-encoding: identity\r\n");
/* Send more headers */
/* End of headers */
fprintf(stream, "\r\n");
/* TODO send data */
fflush(stream);
curl4nx_info("Request sent\n");
/* Now wait for the result */
redirected = false; /* for now */
state = CURL4NX_STATE_STATUSLINE;
tmplen = 0;
while (1)
{
ret = recv(handle->sockfd, handle->rxbuf, handle->rxbufsize, 0);
if (ret < 0)
{
curl4nx_err("RECV failed, errno=%d\n", errno);
cret = CURL4NXE_RECV_ERROR;
goto close;
}
else if (ret == 0)
{
curl4nx_err("Connection lost\n");
cret = CURL4NXE_GOT_NOTHING;
goto close;
}
curl4nx_info("Received %d bytes\n", ret);
rxoff = 0;
if (state == CURL4NX_STATE_STATUSLINE)
{
/* Accumulate HTTP/x.y until space */
while ((tmplen < sizeof(tmpbuf)) && (rxoff < ret))
{
if (handle->rxbuf[rxoff] == ' ')
{
/* found space after http version */
tmpbuf[tmplen] = 0; /* Finish pending string */
rxoff++;
curl4nx_info("received version: [%s]\n", tmpbuf);
tmplen = 0; /* reset buffer to look at code */
state = CURL4NX_STATE_STATUSCODE;
break;
}
/* Not a space: accumulate chars */
tmpbuf[tmplen] = handle->rxbuf[rxoff];
tmplen++;
rxoff++;
}
/* Check for overflow, version code should not fill the tmpbuf */
if (tmplen == sizeof(tmpbuf))
{
/* extremely long http version -> invalid response */
curl4nx_err("Buffer overflow while reading version\n");
cret = CURL4NXE_RECV_ERROR;
goto close;
}
/* No overflow and no space found: wait for next buffer */
}
/* NO ELSE HERE, state may have changed and require new management
* for the same rx buffer.
*/
if (state == CURL4NX_STATE_STATUSCODE)
{
/* Accumulate response code until space */
while ((tmplen < sizeof(tmpbuf)) && (rxoff < ret))
{
if (handle->rxbuf[rxoff] == ' ')
{
/* Found space after http version */
tmpbuf[tmplen] = 0; /* Finish pending string */
rxoff++;
curl4nx_info("received code: [%s]\n", tmpbuf);
handle->status = strtol(tmpbuf, &end, 10);
if (*end != 0)
{
curl4nx_err("Bad status code [%s]\n", tmpbuf);
cret = CURL4NXE_RECV_ERROR;
goto close;
}
tmplen = 0; /* reset buffer to look at code */
state = CURL4NX_STATE_STATUSREASON;
break;
}
/* Not a space: accumulate chars */
tmpbuf[tmplen] = handle->rxbuf[rxoff];
tmplen++;
rxoff++;
}
/* Check for overflow, version code should not fill the tmpbuf */
if (tmplen == sizeof(tmpbuf))
{
/* Extremely long http code -> invalid response */
curl4nx_err("Buffer overflow while reading code\n");
cret = CURL4NXE_RECV_ERROR;
goto close;
}
/* No overflow and no space found: wait for next buffer */
}
if (state == CURL4NX_STATE_STATUSREASON)
{
/* Accumulate response code until CRLF */
while (rxoff < ret)
{
if (handle->rxbuf[rxoff] == 0x0d ||
handle->rxbuf[rxoff] == 0x0a)
{
/* Accumulate all contiguous CR and LF in any order */
tmpbuf[tmplen] = handle->rxbuf[rxoff];
tmplen++;
if (tmplen == 2)
{
if (tmpbuf[0] == 0x0d && tmpbuf[1] == 0x0a)
{
headerlen = 0;
handle->content_length = 0;
state = CURL4NX_STATE_HEADERS;
break;
}
else
{
tmplen = 0; /* Reset search for CRLF */
}
}
}
else
{
/* This char is not interesting: reset storage */
tmplen = 0;
/* curl4nx_info("-> %c\n", handle->rxbuf[rxoff]); */
}
rxoff++;
}
}
if (state == CURL4NX_STATE_HEADERS)
{
while (rxoff < ret)
{
if (handle->rxbuf[rxoff] == 0x0d ||
handle->rxbuf[rxoff] == 0x0a)
{
/* Accumulate all contiguous CR and LF in any order */
tmpbuf[tmplen] = handle->rxbuf[rxoff];
tmplen++;
if (tmplen == 2)
{
if (tmpbuf[0] == 0x0d && tmpbuf[1] == 0x0a)
{
if (headerlen == 0) /* Found an empty header */
{
curl4nx_info("<End of headers>\n");
rxoff++; /* Skip this char */
state = chunked ?
CURL4NX_STATE_DATA_CHUNKED :
CURL4NX_STATE_DATA_NORMAL;
break;
}
else
{
int off;
curl4nx_iofunc_f func;
headerbuf[headerlen] = 0;
func = handle->headerfunc;
if (func == NULL)
{
func = handle->writefunc;
}
func(headerbuf, headerlen, 1,
handle->headerdata);
/* Find the content-length */
if (curl4nx_is_header(headerbuf, headerlen,
"content-length:",
&off))
{
handle->content_length =
strtoull(headerbuf + off, &end, 10);
if (*end != 0)
{
curl4nx_err("Stray chars after "
"content length!\n");
cret = CURL4NXE_RECV_ERROR;
goto close;
}
curl4nx_info("Found content length: "
"%llu\n",
handle->content_length);
}
/* Find the transfer encoding */
if (curl4nx_is_header(headerbuf, headerlen,
"transfer-encoding:",
&off))
{
chunked = !strncasecmp(headerbuf + off,
"chunked", 7);
if (chunked)
{
curl4nx_info("Transfer using "
"chunked format\n");
}
}
/* Find the location */
if (curl4nx_is_header(headerbuf, headerlen,
"location:",
&off))
{
/* Parse the new URL if we get a
* redirection code.
*/
if (handle->status >= 300 &&
handle->status < 400)
{
if (handle->flags &
CURL4NX_FLAGS_FOLLOWLOCATION)
{
if ((handle->max_redirs > 0) &&
(redircount >=
handle->max_redirs))
{
curl4nx_info(
"Too many redirections\n");
cret = CURL4NXE_TOO_MANY_REDIRECTS;
goto close;
}
cret =
curl4nx_easy_setopt(handle,
CURL4NXOPT_URL,
headerbuf + off);
if (cret != CURL4NXE_OK)
{
goto close;
}
redirected = true;
redircount += 1;
curl4nx_info("REDIRECTION (%d) -> %s\n",
redircount,
headerbuf + off);
}
}
}
/* Prepare for next header */
headerlen = 0;
tmplen = 0; /* Reset search for CRLF */
}
}
else
{
tmplen = 0; /* Reset search for CRLF */
}
}
}
else
{
tmplen = 0; /* Reset CRLF detection */
/* Plus one for final zero */
if (headerlen < (CONFIG_LIBCURL4NX_MAXHEADERLINE - 1))
{
headerbuf[headerlen] = handle->rxbuf[rxoff];
headerlen++;
}
else
{
curl4nx_warn("prevented header overload\n");
}
}
rxoff++;
}
}
if (state == CURL4NX_STATE_DATA_NORMAL)
{
if ((handle->flags & CURL4NX_FLAGS_FAILONERROR) &&
handle->status >= 400)
{
cret = CURL4NXE_HTTP_RETURNED_ERROR;
goto close;
}
curl4nx_info("now in normal data state, rxoff=%d rxlen=%d\n",
rxoff, ret);
done += (ret - rxoff);
handle->writefunc(handle->rxbuf + rxoff, ret - rxoff, 1,
handle->writedata);
if (handle->content_length != 0)
{
curl4nx_info("Done %llu of %llu\n",
done, handle->content_length);
if (handle->progressfunc)
{
handle->progressfunc(handle->progressdata,
handle->content_length,
done, 0, 0);
}
if (handle->content_length == done)
{
/* Transfer is complete */
goto close;
}
}
}
if (state == CURL4NX_STATE_DATA_CHUNKED)
{
if ((handle->flags & CURL4NX_FLAGS_FAILONERROR) &&
handle->status >= 400)
{
cret = CURL4NXE_HTTP_RETURNED_ERROR;
goto close;
}
curl4nx_info("now in chunked data state, rxoff=%d rxlen=%d\n",
rxoff, ret);
curl4nx_err("Not supported yet.\n");
goto close;
}
}
/* Done with this connection - this will also close the socket */
close:
curl4nx_info("Closing\n");
if (stream)
{
fclose(stream);
}
}
while (redirected);
freebuf:
free(headerbuf);
abort:
curl4nx_info("done\n");
return cret;
}

View File

@ -0,0 +1,119 @@
/****************************************************************************
* apps/netutils/libcurl4nx/curl4nx_easy_reset.c
* Implementation of the HTTP client, cURL like interface.
*
* Copyright (C) 2019 Gregory Nutt. All rights reserved.
* Author: Sebastien Lorquet <sebastien@lorquet.fr>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/compiler.h>
#include <debug.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <nuttx/version.h>
#include "netutils/netlib.h"
#include "netutils/curl4nx.h"
#include "curl4nx_private.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#ifndef CONFIG_LIBCURL4NX_USERAGENT
# if CONFIG_VERSION_MAJOR != 0 || CONFIG_VERSION_MINOR != 0
# define CONFIG_LIBCURL4NX_USERAGENT \
"NuttX/" CONFIG_VERSION_STRING " (; http://www.nuttx.org/)"
# else
# define CONFIG_LIBCURL4NX_USERAGENT \
"NuttX/7.x (; http://www.nuttx.org/)"
# endif
#endif
/****************************************************************************
* Private Functions
****************************************************************************/
static size_t curl4nx_default_writefunc(FAR char *ptr, size_t size,
size_t nmemb, FAR void *data)
{
fwrite(ptr, size, nmemb, stdout);
fflush(stdout);
return size * nmemb;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: curl4nx_easy_reset()
****************************************************************************/
void curl4nx_easy_reset(FAR struct curl4nx_s *handle)
{
curl4nx_info("handle=%p\n", handle);
/* Setup default options */
handle->port = 80;
strncpy(handle->useragent, CONFIG_LIBCURL4NX_USERAGENT,
sizeof(handle->useragent));
strncpy(handle->method, "GET", sizeof(handle->method));
handle->version = CURL4NX_HTTP_VERSION_1_1;
handle->writefunc = curl4nx_default_writefunc;
if (handle->rxbufsize == 0)
{
/* RX buffer not initialized */
handle->rxbufsize = CONFIG_LIBCURL4NX_RXBUFLEN;
}
if (handle->rxbuf != NULL)
{
free(handle->rxbuf);
handle->rxbuf = NULL;
}
handle->rxbuf = malloc(handle->rxbufsize);
curl4nx_info("Allocated a %d bytes RX buffer\n", handle->rxbufsize);
/* Delete all custom headers */
}

View File

@ -0,0 +1,235 @@
/****************************************************************************
* apps/netutils/libcurl4nx/curl4nx_easy_setopt.c
* Implementation of the HTTP client, cURL like interface.
*
* Copyright (C) 2019 Gregory Nutt. All rights reserved.
* Author: Sebastien Lorquet <sebastien@lorquet.fr>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/compiler.h>
#include <debug.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <nuttx/version.h>
#include "netutils/netlib.h"
#include "netutils/curl4nx.h"
#include "curl4nx_private.h"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: curl4nx_easy_setopt()
****************************************************************************/
int curl4nx_easy_setopt(FAR struct curl4nx_s *handle, int option,
FAR void *param)
{
int ret;
int cret = CURL4NXE_OK;
char scheme[16];
switch (option)
{
case CURL4NXOPT_URL:
{
struct url_s url;
memset(&url, 0, sizeof(struct url_s));
url.scheme = scheme;
url.schemelen = sizeof(scheme);
url.host = handle->host;
url.hostlen = CONFIG_LIBCURL4NX_MAXHOST;
url.path = handle->path;
url.pathlen = CONFIG_LIBCURL4NX_MAXPATH;
ret = netlib_parseurl(param, &url);
if (ret == -E2BIG)
{
cret = CURL4NXE_OUT_OF_MEMORY;
break;
}
else if (ret != 0) /* includes -EINVAL */
{
curl4nx_warn("Malformed URL: %s\n", param);
cret = CURL4NXE_URL_MALFORMAT;
break;
}
if (url.port == 0)
{
curl4nx_err("Invalid port 0\n");
cret = CURL4NXE_URL_MALFORMAT; /* User passed invalid port */
break;
}
if (url.host[0] == 0)
{
curl4nx_err("Empty host\n");
cret = CURL4NXE_URL_MALFORMAT; /* User passed empty host */
break;
}
if (strncmp(scheme, "http", strlen(scheme)))
{
curl4nx_err("Unsupported protocol '%s'\n", scheme);
cret = CURL4NXE_UNSUPPORTED_PROTOCOL;
break;
}
handle->port = url.port;
curl4nx_info("found scheme: %s\n", scheme);
curl4nx_info("found host : %s\n", handle->host);
curl4nx_info("found port : %d\n", handle->port);
curl4nx_info("found path : %s\n", handle->path);
break;
}
case CURL4NXOPT_PORT:
{
long port = (long)param;
if (port == 0)
{
cret = CURL4NXE_BAD_FUNCTION_ARGUMENT;
break;
}
handle->port = (uint16_t)(port & 0xffff);
break;
}
case CURL4NXOPT_BUFFERSIZE:
{
long len = (long)param;
if (len < CONFIG_LIBCURL4NX_MINRXBUFLEN ||
len > CONFIG_LIBCURL4NX_MAXRXBUFLEN)
{
cret = CURL4NXE_BAD_FUNCTION_ARGUMENT;
break;
}
if (handle->rxbuf)
{
curl4nx_info("Freeing previous buffer\n");
free(handle->rxbuf);
}
handle->rxbuf = malloc(len);
if (!handle->rxbuf)
{
cret = CURL4NXE_OUT_OF_MEMORY;
break;
}
handle->rxbufsize = len;
break;
}
case CURL4NXOPT_HEADERFUNCTION:
if (param == NULL)
{
cret = CURL4NXE_BAD_FUNCTION_ARGUMENT;
break;
}
handle->headerfunc = param;
break;
case CURL4NXOPT_HEADERDATA:
handle->headerdata = param;
break;
case CURL4NXOPT_FAILONERROR:
if ((long)param)
{
handle->flags |= CURL4NX_FLAGS_FAILONERROR;
}
else
{
handle->flags &= ~CURL4NX_FLAGS_FAILONERROR;
}
break;
case CURL4NXOPT_FOLLOWLOCATION:
if ((long)param)
{
handle->flags |= CURL4NX_FLAGS_FOLLOWLOCATION;
}
else
{
handle->flags &= ~CURL4NX_FLAGS_FOLLOWLOCATION;
}
break;
case CURL4NXOPT_MAXREDIRS:
{
long redirs = (long)param;
if (redirs < -1 ||
redirs > CONFIG_LIBCURL4NX_MAXREDIRS)
{
cret = CURL4NXE_BAD_FUNCTION_ARGUMENT;
break;
}
handle->max_redirs = redirs;
break;
}
case CURL4NXOPT_VERBOSE:
if ((long)param)
{
handle->flags |= CURL4NX_FLAGS_VERBOSE;
}
else
{
handle->flags &= ~CURL4NX_FLAGS_VERBOSE;
}
break;
default:
cret = CURL4NXE_UNKNOWN_OPTION;
break;
}
return cret;
}

View File

@ -0,0 +1,76 @@
/****************************************************************************
* apps/netutils/libcurl4nx/curl4nx_easy_unescape.c
* Implementation of the HTTP client, cURL like interface.
*
* Copyright (C) 2019 Gregory Nutt. All rights reserved.
* Author: Sebastien Lorquet <sebastien@lorquet.fr>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/compiler.h>
#include <debug.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <stdint.h>
#include <stdio.h>
#include <stdbool.h>
#include <unistd.h>
#include <netdb.h>
#include <strings.h>
#include <errno.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <nuttx/version.h>
#include "netutils/netlib.h"
#include "netutils/curl4nx.h"
#include "curl4nx_private.h"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: curl4nx_easy_unescape()
****************************************************************************/
FAR char *curl4nx_easy_unescape(FAR struct curl4nx_s *curl,
FAR const char *url,
int inlength, int *outlength)
{
return NULL;
}

View File

@ -0,0 +1,188 @@
/****************************************************************************
* apps/netutils/curl4nx/curl4nx_private.h
*
* Copyright (C) 2019 Gregory Nutt. All rights reserved.
* Author: Sebastien Lorquet <sebastien@lorquet.fr>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
#ifndef __APPS_NETUTILS_CURL4NX_CURL4NX_PRIVATE_H
#define __APPS_NETUTILS_CURL4NX_CURL4NX_PRIVATE_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <errno.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#ifndef CONFIG_LIBCURL4NX_MAXHOST
#define CONFIG_LIBCURL4NX_MAXHOST 128
#endif
#ifndef CONFIG_LIBCURL4NX_MAXPATH
#define CONFIG_LIBCURL4NX_MAXPATH 128
#endif
#ifndef CONFIG_LIBCURL4NX_MAXMETHOD
#define CONFIG_LIBCURL4NX_MAXMETHOD 10
#endif
#ifndef CONFIG_LIBCURL4NX_MAXUSERAGENT
#define CONFIG_LIBCURL4NX_MAXUSERAGENT 64
#endif
#ifndef CONFIG_LIBCURL4NX_RXBUFLEN
#define CONFIG_LIBCURL4NX_RXBUFLEN 512
#endif
#ifndef CONFIG_LIBCURL4NX_MAXHEADERLINE
#define CONFIG_LIBCURL4NX_MAXHEADERLINE 128
#endif
#ifndef CONFIG_LIBCURL4NX_MAXREDIRS
#define CONFIG_LIBCURL4NX_MAXREDIRS -1 /* Means unlimited */
#endif
#define CURL4NX_FLAGS_FAILONERROR 0x00000001
#define CURL4NX_FLAGS_FOLLOWLOCATION 0x00000002
#define CURL4NX_FLAGS_VERBOSE 0x00000004
#define curl4nx_err(fmt, ...) \
do \
{ \
if(handle->flags & CURL4NX_FLAGS_VERBOSE) \
_err(fmt, ##__VA_ARGS__); \
} \
while(0)
#define curl4nx_warn(fmt, ...) \
do \
{ \
if(handle->flags & CURL4NX_FLAGS_VERBOSE) \
_warn(fmt, ##__VA_ARGS__); \
} \
while(0)
#define curl4nx_info(fmt, ...) \
do \
{ \
if(handle->flags & CURL4NX_FLAGS_VERBOSE) \
_info(fmt, ##__VA_ARGS__); \
} \
while(0)
/****************************************************************************
* Private Types
****************************************************************************/
/****************************************************************************
* Name: struct curl4nx_header_s
*
* Description: Holds data for an individual http header added in a request.
*
****************************************************************************/
struct curl4nx_header_s
{
struct curl4nx_header_s *next;
FAR const char *value;
};
/****************************************************************************
* Name: struct curl4nx_s
*
* Description: Holds the integrity of all informations required for a curl4nx
* transfer.
*
****************************************************************************/
struct curl4nx_s
{
/* Network stuff */
int sockfd;
/* General stuff */
uint32_t flags;
bool verbose;
curl4nx_xferinfofunc_f progressfunc; /* Called when data chunks are received */
FAR void * progressdata;
/* Request side */
char host[CONFIG_LIBCURL4NX_MAXHOST];
char path[CONFIG_LIBCURL4NX_MAXPATH];
uint16_t port;
int version;
char method[CONFIG_LIBCURL4NX_MAXMETHOD];
char useragent[CONFIG_LIBCURL4NX_MAXUSERAGENT];
FAR struct curl4nx_header_s *headers;
int max_redirs;
curl4nx_iofunc_f writefunc; /* Called when data has to be uploaded */
FAR void * writedata;
/* Response side */
int rxbufsize;
FAR char * rxbuf;
int status;
unsigned long long content_length;
curl4nx_iofunc_f readfunc; /* Called when data has to be downloaded */
FAR void * readdata;
curl4nx_iofunc_f headerfunc; /* Called when a complete HTTP header has been received */
FAR void * headerdata;
};
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
#endif /* __APPS_NETLIB_CURL4NX_CURL4NX_PRIVATE_H */