Add support for wget POST interface; from Darcy Gong

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5301 42af7a65-404d-4744-a932-0658087f49c3
diff --git a/ChangeLog.txt b/ChangeLog.txt
index 0b8b3cd..ff90d50 100644
--- a/ChangeLog.txt
+++ b/ChangeLog.txt
@@ -397,3 +397,5 @@
 	* apps/examples/wgetjson: Test example contributed by Darcy Gong
 	* apps/examples/cxxtest:  A test for the uClibc++ library provided by
 	  Qiang Yu and the RGMP team.
+	* apps/netutils/webclient, apps/netutils.codes, and apps/examples/wgetjson:
+	  Add support for wget POST interface.  Contributed by Darcy Gong.
diff --git a/examples/wgetjson/Kconfig b/examples/wgetjson/Kconfig
index f7f4f23..f7f9096 100644
--- a/examples/wgetjson/Kconfig
+++ b/examples/wgetjson/Kconfig
@@ -20,4 +20,8 @@
 	string "wget URL"
 	default "http://10.0.0.1/wgetjson/json_cmd.php"
 
+config EXAMPLES_WGETPOST_URL
+	string "wget_post URL"
+	default "http://10.0.0.1/wgetjson/post_cmd.php"
+
 endif
diff --git a/examples/wgetjson/webserver/wgetjson/post_cmd.php b/examples/wgetjson/webserver/wgetjson/post_cmd.php
new file mode 100644
index 0000000..a352300
--- /dev/null
+++ b/examples/wgetjson/webserver/wgetjson/post_cmd.php
@@ -0,0 +1,3 @@
+<?php

+echo json_encode($_POST);

+?>
\ No newline at end of file
diff --git a/examples/wgetjson/wgetjson_main.c b/examples/wgetjson/wgetjson_main.c
index a137af4..8f82d1f 100644
--- a/examples/wgetjson/wgetjson_main.c
+++ b/examples/wgetjson/wgetjson_main.c
@@ -58,13 +58,19 @@
  ****************************************************************************/
 
 #ifndef CONFIG_EXAMPLES_WGETJSON_MAXSIZE
-# define  CONFIG_EXAMPLES_WGETJSON_MAXSIZE 1024
+# define CONFIG_EXAMPLES_WGETJSON_MAXSIZE 1024
 #endif
 
-#ifndef CONFIG_EXAMPLES_EXAMPLES_WGETJSON_URL
-# define  CONFIG_EXAMPLES_EXAMPLES_WGETJSON_URL "http://10.0.0.1/wgetjson/json_cmd.php"
+#ifndef CONFIG_EXAMPLES_WGETJSON_URL
+# define CONFIG_EXAMPLES_WGETJSON_URL "http://10.0.0.1/wgetjson/json_cmd.php"
 #endif
 
+#ifndef CONFIG_EXAMPLES_WGETPOST_URL
+# define CONFIG_EXAMPLES_WGETPOST_URL "http://10.0.0.1/wgetjson/post_cmd.php"
+#endif
+
+#define MULTI_POST_NDATA 3
+
 /****************************************************************************
  * Private Types
  ****************************************************************************/
@@ -85,6 +91,21 @@
  * Private Functions
  ****************************************************************************/
 
+static void wgetjson_postdebug_callback(FAR char **buffer, int offset,
+                                        int datend, FAR int *buflen,
+                                        FAR void *arg)
+{
+  int len = datend - offset;
+  if (len <= 0)
+    {
+      printf("Callback No Data!\n");
+      return;
+    }
+
+  ((*buffer)[datend]) = '\0';
+  printf("Callback Data(Length:%d):\n%s\n", len, &((*buffer)[offset]));
+}
+
 /****************************************************************************
  * Name: wgetjson_callback
  ****************************************************************************/
@@ -271,20 +292,102 @@
 int wgetjson_main(int argc, char *argv[])
 {
   char *buffer = NULL;
-  char *url = CONFIG_EXAMPLES_EXAMPLES_WGETJSON_URL;
-  int ret;
+  int buffer_len = 512;
+  char *url = CONFIG_EXAMPLES_WGETJSON_URL;
+  int ret = -1;
+  int option;
+  bool is_post = false;
+  bool is_post_multi = false;
+  bool badarg=false;
+  bool is_debug=false;
+  char *post_buff = NULL;
+  int post_buff_len = 0;
+  char *post_single_name  = "type";
+  char *post_single_value = "string";
+  char *post_multi_names[MULTI_POST_NDATA]  = {"name", "gender", "country"};
+  char *post_multi_values[MULTI_POST_NDATA] = {"darcy", "man", "china"};
+  wget_callback_t wget_cb = wgetjson_callback;
 
-  buffer = malloc(512);
+  while ((option = getopt(argc, argv, ":pPD")) != ERROR)
+    {
+      switch (option)
+        {
+          case 'p':
+            is_post = true;
+            break;
+
+          case 'P':
+            is_post = true;
+            is_post_multi = true;
+            break;
+
+          case 'D':
+            is_debug = true;
+            break;
+
+          case ':':
+            badarg = true;
+            break;
+
+          case '?':
+          default:
+            badarg = true;
+            break;
+        }
+    }
+
+  if (badarg)
+    {
+      printf("usage: wgetjson -p(single post) -P(multi post) -D(debug wget callback)\n");
+      return -1;
+    }
+
+  if (is_debug)
+    {
+      wget_cb = wgetjson_postdebug_callback;
+    }
+
+  if (is_post)
+    {
+      buffer_len = 512*2;
+    }
+
+  buffer = malloc(buffer_len);
   wgetjson_json_release();
 
   printf("URL: %s\n", url);
 
-  ret = wget(url, buffer, 512, wgetjson_callback, NULL);
+  if (is_post)
+    {
+      url = CONFIG_EXAMPLES_WGETPOST_URL;
+      if (is_post_multi)
+        {
+          post_buff_len = web_posts_strlen(post_multi_names, post_multi_values, MULTI_POST_NDATA);
+          post_buff = malloc(post_buff_len);
+          web_posts_str(post_buff, &post_buff_len, post_multi_names, post_multi_values, MULTI_POST_NDATA);
+        }
+      else
+        {
+          post_buff_len = web_post_strlen(post_single_name, post_single_value);
+          post_buff = malloc(post_buff_len);
+          web_post_str(post_buff, &post_buff_len, post_single_name, post_single_value);
+        }
+
+      if (post_buff)
+        {
+          ret = wget_post(url, post_buff, buffer, buffer_len, wget_cb, NULL);
+        }
+    }
+  else
+    {
+      ret = wget(url, buffer, buffer_len, wget_cb , NULL);
+    }
+
   if (ret < 0)
     {
       printf("get json size: %d\n",g_json_bufflen);
     }
-  else
+  else if (!is_debug)
     {
       g_has_json = false;
       if (wgetjson_json_parse(g_json_buff) == OK && g_has_json)
@@ -301,5 +404,10 @@
 
   wgetjson_json_release();
   free(buffer);
+  if (post_buff)
+    {
+      free(post_buff);
+    }
+
   return 0;
 }
diff --git a/include/netutils/urldecode.h b/include/netutils/urldecode.h
index 136d330..e3c726b 100644
--- a/include/netutils/urldecode.h
+++ b/include/netutils/urldecode.h
@@ -1,74 +1,76 @@
-/****************************************************************************

- * apps/include/netutils/urldecode.h

- *

- * This file is part of the NuttX RTOS:

- *

- *   Copyright (C) 2012 Gregory Nutt. All rights reserved.

- *   Author: Darcy Gong

- *

- * 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_URLDECODE_H

-#define __APPS_INCLUDE_NETUTILS_URLDECODE_H

-

-/****************************************************************************

- * Included Files

- ****************************************************************************/

-

-#include <nuttx/config.h>

-

-#ifdef __cplusplus

-extern "C"

-{

-#endif

-

-/****************************************************************************

- * Public Function Prototypes

- ****************************************************************************/

-

-#ifdef CONFIG_CODECS_URLCODE_NEWMEMORY

-char *url_encode(char *str);

-char *url_decode(char *str);

-#endif /* CONFIG_CODECS_URLCODE_NEWMEMORY */

-

-#ifdef CONFIG_CODECS_URLCODE

-char *urlencode(const char *src, const int src_len, char *dest, int *dest_len);

-char *urldecode(const char *src, const int src_len, char *dest, int *dest_len);

-#endif /* CONFIG_CODECS_URLCODE */

-

-#ifdef CONFIG_CODECS_AVR_URLCODE

-void urlrawdecode(char *urlbuf);

-void urlrawencode(char *str,char *urlbuf);

-#endif /* CONFIG_CODECS_AVR_URLCODE */

-

-#ifdef __cplusplus

-}

-#endif

-

-#endif /* __APPS_INCLUDE_NETUTILS_URLDECODE_H */

-

+/****************************************************************************
+ * apps/include/netutils/urldecode.h
+ *
+ * This file is part of the NuttX RTOS:
+ *
+ *   Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ *   Author: Darcy Gong
+ *
+ * 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_URLDECODE_H
+#define __APPS_INCLUDE_NETUTILS_URLDECODE_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+#ifdef CONFIG_CODECS_URLCODE_NEWMEMORY
+char *url_encode(char *str);
+char *url_decode(char *str);
+#endif /* CONFIG_CODECS_URLCODE_NEWMEMORY */
+
+#ifdef CONFIG_CODECS_URLCODE
+char *urlencode(const char *src, const int src_len, char *dest, int *dest_len);
+char *urldecode(const char *src, const int src_len, char *dest, int *dest_len);
+int urlencode_len(const char *src, const int src_len);
+int urldecode_len(const char *src, const int src_len);
+#endif /* CONFIG_CODECS_URLCODE */
+
+#ifdef CONFIG_CODECS_AVR_URLCODE
+void urlrawdecode(char *urlbuf);
+void urlrawencode(char *str,char *urlbuf);
+#endif /* CONFIG_CODECS_AVR_URLCODE */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __APPS_INCLUDE_NETUTILS_URLDECODE_H */
+
diff --git a/include/netutils/webclient.h b/include/netutils/webclient.h
index 5c07f20..3a4c4ea 100644
--- a/include/netutils/webclient.h
+++ b/include/netutils/webclient.h
@@ -109,6 +109,13 @@
 #define EXTERN extern
 #endif
 
+EXTERN char *web_post_str(FAR char *buffer, int *size, FAR char *name,
+                          FAR char *value);
+EXTERN char *web_posts_str(FAR char *buffer, int *size, FAR char **name,
+                           FAR char **value, int len);
+EXTERN int web_post_strlen(FAR char *name, FAR char *value);
+EXTERN int web_posts_strlen(FAR char **name, FAR char **value, int len);
+
 /****************************************************************************
  * Name: wget
  *
@@ -141,6 +148,11 @@
 EXTERN int wget(FAR const char *url, FAR char *buffer, int buflen,
                 wget_callback_t callback, FAR void *arg);
 
+
+EXTERN int wget_post(FAR const char *url, FAR const char *posts,
+                     FAR char *buffer, int buflen, wget_callback_t callback,
+                     FAR void *arg);
+
 #undef EXTERN
 #ifdef __cplusplus
 }
diff --git a/netutils/codecs/urldecode.c b/netutils/codecs/urldecode.c
index 9b3b609..90cc330 100644
--- a/netutils/codecs/urldecode.c
+++ b/netutils/codecs/urldecode.c
@@ -351,6 +351,73 @@
 #endif
 
 /****************************************************************************
+ * Name: urlencode_len
+ ****************************************************************************/
+
+#ifdef CONFIG_CODECS_URLCODE
+int urlencode_len(const char *src, const int src_len)
+{
+  const unsigned char *pSrc;
+  const unsigned char *pEnd;
+  int len = 0;
+
+  pEnd = (unsigned char *)src + src_len;
+  for (pSrc = (unsigned char *)src; pSrc < pEnd; pSrc++)
+    {
+      if ((*pSrc >= '0' && *pSrc <= '9') ||
+          (*pSrc >= 'a' && *pSrc <= 'z') ||
+          (*pSrc >= 'A' && *pSrc <= 'Z') ||
+          (*pSrc == '_' || *pSrc == '-' || *pSrc == '.' || *pSrc == '~' || *pSrc == ' '))
+        {
+          len++;
+        }
+      else
+        {
+          len+=3;
+        }
+    }
+
+  return len;
+}
+#endif
+
+/****************************************************************************
+ * Name: urldecode_len
+ ****************************************************************************/
+
+#ifdef CONFIG_CODECS_URLCODE
+int urldecode_len(const char *src, const int src_len)
+{
+  const unsigned char *pSrc;
+  const unsigned char *pEnd;
+  int len = 0;
+  unsigned char cHigh;
+  unsigned char cLow;
+
+  pSrc = (unsigned char *)src;
+  pEnd = (unsigned char *)src + src_len;
+  while (pSrc < pEnd)
+    {
+      if (*pSrc == '%' && pSrc + 2 < pEnd)
+        {
+          cHigh = *(pSrc + 1);
+          cLow = *(pSrc + 2);
+
+          if (IS_HEX_CHAR(cHigh) && IS_HEX_CHAR(cLow))
+            {
+              pSrc += 2;
+            }
+        }
+
+      len++;
+      pSrc++;
+    }
+
+  return len;
+}
+#endif
+
+/****************************************************************************
  * Name: urlrawdecode
  *
  * Description:
diff --git a/netutils/webclient/Kconfig b/netutils/webclient/Kconfig
index c53195d..68b13ce 100644
--- a/netutils/webclient/Kconfig
+++ b/netutils/webclient/Kconfig
@@ -10,4 +10,9 @@
 		Enable support for the uIP web client.
 
 if NETUTILS_WEBCLIENT
+
+config NSH_WGET_USERAGENT
+	string "wget Usert Agent"
+	default "NuttX/6.xx.x (; http://www.nuttx.org/)"
+
 endif
diff --git a/netutils/webclient/webclient.c b/netutils/webclient/webclient.c
index 8ce7b93..4dbd130 100644
--- a/netutils/webclient/webclient.c
+++ b/netutils/webclient/webclient.c
@@ -69,9 +69,31 @@
 
 #include <arpa/inet.h>
 #include <netinet/in.h>
+
+#include <nuttx/version.h>
 #include <apps/netutils/uiplib.h>
 #include <apps/netutils/webclient.h>
 
+#if defined(CONFIG_NETUTILS_CODECS)
+#  if defined(CONFIG_CODECS_URLCODE)
+#    define     WGET_USE_URLENCODE      1
+#    include <apps/netutils/urldecode.h>
+#  endif
+#  if defined(CONFIG_CODECS_BASE64)
+#    include <apps/netutils/base64.h>
+#  endif
+#endif
+
+#ifndef CONFIG_NSH_WGET_USERAGENT
+#  if CONFIG_VERSION_MAJOR != 0 || CONFIG_VERSION_MINOR != 0
+#    define CONFIG_NSH_WGET_USERAGENT \
+     "NuttX/" CONFIG_VERSION_STRING " (; http://www.nuttx.org/)"
+#  else
+#    define CONFIG_NSH_WGET_USERAGENT \
+    "NuttX/6.xx.x (; http://www.nuttx.org/)"
+#  endif
+#endif
+
 /****************************************************************************
  * Definitions
  ****************************************************************************/
@@ -92,6 +114,9 @@
 #define ISO_cr                     0x0d
 #define ISO_space                  0x20
 
+#define WGET_MODE_GET              0
+#define WGET_MODE_POST             1
+
 /****************************************************************************
  * Private Types
  ****************************************************************************/
@@ -136,10 +161,13 @@
 static const char g_httphost[]        = "host: ";
 static const char g_httplocation[]    = "location: ";
 static const char g_httpget[]         = "GET ";
+static const char g_httppost[]        = "POST ";
 
 static const char g_httpuseragentfields[] =
   "Connection: close\r\n"
-  "User-Agent: NuttX/0.4.x (; http://www.nuttx.org/)\r\n\r\n";
+  "User-Agent: "
+  CONFIG_NSH_WGET_USERAGENT
+  "\r\n\r\n";
 
 static const char g_http200[]         = "200 ";
 static const char g_http301[]         = "301 ";
@@ -147,6 +175,11 @@
 
 static const char g_httpcrnl[]        = "\r\n";
 
+static const char g_httpform[]        = "Content-Type: application/x-www-form-urlencoded";
+static const char g_httpcontsize[]    = "Content-Length: ";
+//static const char g_httpconn[]      = "Connection: Keep-Alive";
+//static const char g_httpcache[]     = "Cache-Control: no-cache";
+
 /****************************************************************************
  * Private Functions
  ****************************************************************************/
@@ -162,12 +195,29 @@
 static char *wget_strcpy(char *dest, const char *src)
 {
   int len = strlen(src);
+
   memcpy(dest, src, len);
   dest[len] = '\0';
   return dest + len;
 }
 
 /****************************************************************************
+ * Name: wget_urlencode_strcpy
+ ****************************************************************************/
+
+#ifdef  WGET_USE_URLENCODE
+static char *wget_urlencode_strcpy(char *dest, const char *src)
+{
+  int len = strlen(src);
+  int d_len;
+
+  d_len = urlencode_len(src, len);
+  urlencode(src, len, dest, &d_len);
+  return dest + d_len;
+}
+#endif
+
+/****************************************************************************
  * Name: wget_parsestatus
  ****************************************************************************/
 
@@ -320,11 +370,7 @@
 }
 
 /****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: wget
+ * Name: wget_base
  *
  * Description:
  *   Obtain the requested file from an HTTP server using the GET method.
@@ -344,6 +390,7 @@
  *   buflen   - The size of the user provided buffer
  *   callback - As data is obtained from the host, this function is
  *              to dispose of each block of file data as it is received.
+ *   mode     - Indicates GET or POST modes
  *
  * Returned Value:
  *   0: if the GET operation completed successfully;
@@ -351,15 +398,16 @@
  *
  ****************************************************************************/
 
-int wget(FAR const char *url, FAR char *buffer, int buflen,
-         wget_callback_t callback, FAR void *arg)
+static int wget_base(FAR const char *url, FAR char *buffer, int buflen,
+                     wget_callback_t callback, FAR void *arg,
+                     FAR const char *posts, uint8_t mode)
 {
   struct sockaddr_in server;
   struct wget_s ws;
   bool redirected;
-  char *dest;
+  char *dest,post_size[8];
   int sockfd;
-  int len;
+  int len,post_len;
   int ret = OK;
 
   /* Initialize the state structure */
@@ -380,6 +428,7 @@
       set_errno(-ret);
       return ERROR;
     }
+
   nvdbg("hostname='%s' filename='%s'\n", ws.hostname, ws.filename);
 
   /* The following sequence may repeat indefinitely if we are redirected */
@@ -435,19 +484,53 @@
 
       /* Send the GET request */
 
-      dest   = ws.buffer;
-      dest   = wget_strcpy(dest, g_httpget);
-      dest   = wget_strcpy(dest, ws.filename);
-     *dest++ = ISO_space;
-      dest   = wget_strcpy(dest, g_http10);
-      dest   = wget_strcpy(dest, g_httpcrnl);
-      dest   = wget_strcpy(dest, g_httphost);
-      dest   = wget_strcpy(dest, ws.hostname);
-      dest   = wget_strcpy(dest, g_httpcrnl);
-      dest   = wget_strcpy(dest, g_httpuseragentfields);
-      len    = dest - buffer;
+      dest = ws.buffer;
+      if (mode == WGET_MODE_POST)
+        {
+          dest = wget_strcpy(dest, g_httppost);
+        }
+      else
+        {
+          dest = wget_strcpy(dest, g_httpget);
+        }
 
-      ret    = send(sockfd, buffer, len, 0);
+#ifndef WGET_USE_URLENCODE
+      dest = wget_strcpy(dest, ws.filename);
+#else
+    //dest = wget_urlencode_strcpy(dest, ws.filename);
+      dest = wget_strcpy(dest, ws.filename);
+#endif
+
+      *dest++ = ISO_space;
+      dest = wget_strcpy(dest, g_http10);
+      dest = wget_strcpy(dest, g_httpcrnl);
+      dest = wget_strcpy(dest, g_httphost);
+      dest = wget_strcpy(dest, ws.hostname);
+      dest = wget_strcpy(dest, g_httpcrnl);
+
+      if (mode == WGET_MODE_POST)
+        {
+          dest = wget_strcpy(dest, g_httpform);
+          dest = wget_strcpy(dest, g_httpcrnl);
+          dest = wget_strcpy(dest, g_httpcontsize);
+
+          /* Post content size */
+
+          post_len = strlen((char *)posts);
+          sprintf(post_size,"%d", post_len);
+          dest = wget_strcpy(dest, post_size);
+          dest = wget_strcpy(dest, g_httpcrnl);
+        }
+
+      dest = wget_strcpy(dest, g_httpuseragentfields);
+      if (mode == WGET_MODE_POST)
+        {
+          dest = wget_strcpy(dest, (char *)posts);
+        }
+
+      len = dest - buffer;
+
+      ret = send(sockfd, buffer, len, 0);
       if (ret < 0)
         {
           ndbg("send failed: %d\n", errno);
@@ -528,3 +611,119 @@
   close(sockfd);
   return ERROR;
 }
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: web_post_str
+ ****************************************************************************/
+
+char *web_post_str(FAR char *buffer, int *size, FAR char *name,
+                   FAR char *value)
+{
+  char *dst=buffer;
+  buffer = wget_strcpy(buffer,name);
+  buffer = wget_strcpy(buffer, "=");
+  buffer = wget_urlencode_strcpy(buffer,value);
+  *size  = buffer - dst;
+  return dst;
+}
+
+/****************************************************************************
+ * Name: web_post_strlen
+ ****************************************************************************/
+
+int web_post_strlen(FAR char *name, FAR char *value)
+{
+  return strlen(name) + urlencode_len(value,strlen(value)) + 1;
+}
+
+/****************************************************************************
+ * Name: web_posts_str
+ ****************************************************************************/
+
+char *web_posts_str(FAR char *buffer, int *size, FAR char **name,
+                    FAR char **value, int len)
+{
+  char *dst=buffer;
+  int wlen;
+  int i;
+
+  for (i = 0; i < len; i++)
+    {
+      if (i > 0)
+        {
+          buffer = wget_strcpy(buffer,"&");
+        }
+
+      wlen    = *size;
+      buffer  = web_post_str(buffer, &wlen, name[i], value[i]);
+      buffer += wlen;
+    }
+
+  *size=buffer-dst;
+  return dst;
+}
+
+/****************************************************************************
+ * Name: web_posts_strlen
+ ****************************************************************************/
+
+int web_posts_strlen(FAR char **name, FAR char **value, int len)
+{
+  int wlen = 0;
+  int i;
+
+  for (i = 0; i < len; i++)
+    {
+      wlen += web_post_strlen(name[i], value[i]);
+    }
+
+  return wlen + len - 1;
+}
+
+/****************************************************************************
+ * Name: wget
+ *
+ * Description:
+ *   Obtain the requested file from an HTTP server using the GET method.
+ *
+ *   Note: If the function is passed a host name, it must already be in
+ *   the resolver cache in order for the function to connect to the web
+ *   server. It is therefore up to the calling module to implement the
+ *   resolver calls and the signal handler used for reporting a resolv
+ *   query answer.
+ *
+ * Input Parameters
+ *   url      - A pointer to a string containing either the full URL to
+ *              the file to get (e.g., http://www.nutt.org/index.html, or
+ *              http://192.168.23.1:80/index.html).
+ *   buffer   - A user provided buffer to receive the file data (also
+ *              used for the outgoing GET request
+ *   buflen   - The size of the user provided buffer
+ *   callback - As data is obtained from the host, this function is
+ *              to dispose of each block of file data as it is received.
+ *
+ * Returned Value:
+ *   0: if the GET operation completed successfully;
+ *  -1: On a failure with errno set appropriately
+ *
+ ****************************************************************************/
+
+int wget(FAR const char *url, FAR char *buffer, int buflen,
+         wget_callback_t callback, FAR void *arg)
+{
+  return wget_base(url, buffer, buflen, callback, arg, NULL, WGET_MODE_GET);
+}
+
+/****************************************************************************
+ * Name: web_posts_strlen
+ ****************************************************************************/
+
+int wget_post(FAR const char *url, FAR const char *posts, FAR char *buffer,
+              int buflen, wget_callback_t callback, FAR void *arg)
+{
+  return wget_base(url, buffer, buflen, callback, arg, posts, WGET_MODE_POST);
+}
diff --git a/nshlib/nsh_netinit.c b/nshlib/nsh_netinit.c
index 535efd6..bb1c73d 100644
--- a/nshlib/nsh_netinit.c
+++ b/nshlib/nsh_netinit.c
@@ -47,7 +47,7 @@
 #include <net/if.h>
 
 #include <apps/netutils/uiplib.h>
-#if defined(CONFIG_NSH_DHCPC)
+#if defined(CONFIG_NSH_DHCPC) || defined(CONFIG_NSH_DNS)
 #  include <apps/netutils/resolv.h>
 #  include <apps/netutils/dhcpc.h>
 #endif
@@ -135,7 +135,7 @@
   resolv_init();
 #if defined(CONFIG_NSH_DNS)
   addr.s_addr = HTONL(CONFIG_NSH_DNSIPADDR);
-  resolv_conf(&addr.s_addr);
+  resolv_conf(&addr);
 #endif
 #endif