예제 #1
0
int conn_comm_get_server_address(struct sockaddr_in *addr,
                                 const char *hostname)
{
  int ret;

  DEBUGASSERT(addr && hostname);

  con_dbg("Getting IP address for '%s'\n", hostname);

  ret = dns_gethostip(hostname, &addr->sin_addr.s_addr);
  if (ret != OK)
    {
      con_dbg("Failed to get address for '%s'\n", hostname);
      return ret;
    }

  addr->sin_family = AF_INET;

  con_dbg("Got address %d.%d.%d.%d for '%s'\n",
      addr->sin_addr.s_addr & 0xff,
      (addr->sin_addr.s_addr >> 8) & 0xff,
      (addr->sin_addr.s_addr >> 16) & 0xff,
      addr->sin_addr.s_addr >> 24,
      hostname);
  return OK;
}
예제 #2
0
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;
  struct timeval tv;
  bool redirected;
  char *dest,post_size[8];
  int sockfd;
  int len,post_len;
  int ret;

  /* Initialize the state structure */

  memset(&ws, 0, sizeof(struct wget_s));
  ws.buffer = buffer;
  ws.buflen = buflen;
  ws.port   = 80;

  /* Parse the hostname (with optional port number) and filename from the URL */

  ret = netlib_parsehttpurl(url, &ws.port,
                            ws.hostname, CONFIG_WEBCLIENT_MAXHOSTNAME,
                            ws.filename, CONFIG_WEBCLIENT_MAXFILENAME);
  if (ret != 0)
    {
      ndbg("ERROR: Malformed HTTP URL: %s\n", url);
      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 */

  do
    {
      /* Re-initialize portions of the state structure that could have
       * been left from the previous time through the loop and should not
       * persist with the new connection.
       */

      ws.httpstatus = HTTPSTATUS_NONE;
      ws.offset     = 0;
      ws.datend     = 0;
      ws.ndx        = 0;

      /* Create a socket */

      sockfd = socket(AF_INET, SOCK_STREAM, 0);
      if (sockfd < 0)
        {
          /* socket failed.  It will set the errno appropriately */

          ndbg("ERROR: socket failed: %d\n", errno);
          return ERROR;
        }

      /* Set send and receive timeout values */

      tv.tv_sec  = CONFIG_WEBCLIENT_TIMEOUT;
      tv.tv_usec = 0;

      (void)setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (FAR const void *)&tv,
                       sizeof(struct timeval));
      (void)setsockopt(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 = dns_gethostip(ws.hostname, &server.sin_addr.s_addr);
      if (ret < 0)
        {
          /* Could not resolve host (or malformed IP address) */

          ndbg("ERROR: 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(sockfd, (struct sockaddr *)&server, sizeof(struct sockaddr_in));
      if (ret < 0)
        {
          ndbg("ERROR: connect failed: %d\n", errno);
          goto errout;
        }

      /* Send the GET request */

      dest = ws.buffer;
      if (mode == WGET_MODE_POST)
        {
          dest = wget_strcpy(dest, g_httppost);
        }
      else
        {
          dest = wget_strcpy(dest, g_httpget);
        }

#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("ERROR: send failed: %d\n", errno);
          goto errout;
        }

      /* Now loop to get the file sent in response to the GET.  This
       * loop continues until either we read the end of file (nbytes == 0)
       * or until we detect that we have been redirected.
       */

      ws.state   = WEBCLIENT_STATE_STATUSLINE;
      redirected = false;
      for (;;)
        {
          ws.datend = recv(sockfd, ws.buffer, ws.buflen, 0);
          if (ws.datend < 0)
            {
              ndbg("ERROR: recv failed: %d\n", errno);
              ret = ws.datend;
              goto errout_with_errno;
            }
          else if (ws.datend == 0)
            {
              nvdbg("Connection lost\n");
              close(sockfd);
              break;
            }

          /* Handle initial parsing of the status line */

          ws.offset = 0;
          if (ws.state == WEBCLIENT_STATE_STATUSLINE)
            {
              ret = wget_parsestatus(&ws);
              if (ret < 0)
                {
                  goto errout_with_errno;
                }
            }

          /* Parse the HTTP data */

          if (ws.state == WEBCLIENT_STATE_HEADERS)
            {
              ret = wget_parseheaders(&ws);
              if (ret < 0)
                {
                  goto errout_with_errno;
                }
            }

          /* Dispose of the data payload */

          if (ws.state == WEBCLIENT_STATE_DATA)
            {
              if (ws.httpstatus != HTTPSTATUS_MOVED)
                {
                  /* Let the client decide what to do with the received file */

                  callback(&ws.buffer, ws.offset, ws.datend, &buflen, arg);
                }
              else
                {
                  redirected = true;
                  close(sockfd);
                  break;
                }
            }
        }
    }
  while (redirected);

  return OK;

errout_with_errno:
  set_errno(-ret);
errout:
  close(sockfd);
  return ERROR;
}