Exemplo n.º 1
0
Arquivo: sendf.c Projeto: ahqmhjk/curl
/*
 * Internal read-from-socket function. This is meant to deal with plain
 * sockets, SSL sockets and kerberos sockets.
 *
 * Returns a regular CURLcode value.
 */
CURLcode Curl_read(struct connectdata *conn, /* connection data */
              curl_socket_t sockfd,     /* read from this socket */
              char *buf,                /* store read data here */
              size_t sizerequested,     /* max amount to read */
              ssize_t *n)               /* amount bytes read */
{
  CURLcode curlcode = CURLE_RECV_ERROR;
  ssize_t nread = 0;
  size_t bytesfromsocket = 0;
  char *buffertofill = NULL;
  bool pipelining = (bool)(conn->data->multi &&
                     Curl_multi_canPipeline(conn->data->multi));

  /* Set 'num' to 0 or 1, depending on which socket that has been sent here.
     If it is the second socket, we set num to 1. Otherwise to 0. This lets
     us use the correct ssl handle. */
  int num = (sockfd == conn->sock[SECONDARYSOCKET]);

  *n=0; /* reset amount to zero */

  /* If session can pipeline, check connection buffer  */
  if(pipelining) {
    size_t bytestocopy = CURLMIN(conn->buf_len - conn->read_pos,
                                 sizerequested);

    /* Copy from our master buffer first if we have some unread data there*/
    if(bytestocopy > 0) {
      memcpy(buf, conn->master_buffer + conn->read_pos, bytestocopy);
      conn->read_pos += bytestocopy;
      conn->bits.stream_was_rewound = FALSE;

      *n = (ssize_t)bytestocopy;
      return CURLE_OK;
    }
    /* If we come here, it means that there is no data to read from the buffer,
     * so we read from the socket */
    bytesfromsocket = CURLMIN(sizerequested, BUFSIZE * sizeof (char));
    buffertofill = conn->master_buffer;
  }
  else {
    bytesfromsocket = CURLMIN((long)sizerequested,
                              conn->data->set.buffer_size ?
                              conn->data->set.buffer_size : BUFSIZE);
    buffertofill = buf;
  }

  nread = conn->recv[num](conn, num, buffertofill, bytesfromsocket, &curlcode);
  if(nread < 0)
    return curlcode;

  if(pipelining) {
    memcpy(buf, conn->master_buffer, nread);
    conn->buf_len = nread;
    conn->read_pos = nread;
  }

  *n += nread;

  return CURLE_OK;
}
int curl_fetch_read(CFContext * h, char * buf, int size)
{
    if (!h) {
        CLOGE("CFContext invalid\n");
        return C_ERROR_UNKNOW;
    }
    if (!h->cwh_h->cfifo) {
        CLOGE("CURLWHandle fifo invalid\n");
        return C_ERROR_UNKNOW;
    }
    int avail = 0;
    pthread_mutex_lock(&h->cwh_h->fifo_mutex);
    avail = curl_fifo_size(h->cwh_h->cfifo);
    if (avail) {
        size = CURLMIN(avail, size);
        curl_fifo_generic_read(h->cwh_h->cfifo, buf, size, NULL);
        pthread_cond_signal(&h->cwh_h->pthread_cond);
        pthread_mutex_unlock(&h->cwh_h->fifo_mutex);
        return size;
    } else if (h->thread_quited) {
        pthread_mutex_unlock(&h->cwh_h->fifo_mutex);
        return h->perform_retval;
    } else {
        pthread_mutex_unlock(&h->cwh_h->fifo_mutex);
        return C_ERROR_EAGAIN;
    }
    pthread_mutex_unlock(&h->cwh_h->fifo_mutex);
    return C_ERROR_OK;
}
Exemplo n.º 3
0
/* Returns timeout in ms. 0 or negative number means the timeout has already
   triggered */
time_t Curl_pp_state_timeout(struct pingpong *pp)
{
  struct connectdata *conn = pp->conn;
  struct Curl_easy *data = conn->data;
  time_t timeout_ms; /* in milliseconds */
  time_t timeout2_ms; /* in milliseconds */
  long response_time = (data->set.server_response_timeout)?
    data->set.server_response_timeout: pp->response_time;

  /* if CURLOPT_SERVER_RESPONSE_TIMEOUT is set, use that to determine
     remaining time, or use pp->response because SERVER_RESPONSE_TIMEOUT is
     supposed to govern the response for any given server response, not for
     the time from connect to the given server response. */

  /* Without a requested timeout, we only wait 'response_time' seconds for the
     full response to arrive before we bail out */
  timeout_ms = response_time -
    Curl_timediff(Curl_now(), pp->response); /* spent time */

  if(data->set.timeout) {
    /* if timeout is requested, find out how much remaining time we have */
    timeout2_ms = data->set.timeout - /* timeout time */
      Curl_timediff(Curl_now(), conn->now); /* spent time */

    /* pick the lowest number */
    timeout_ms = CURLMIN(timeout_ms, timeout2_ms);
  }

  return timeout_ms;
}
Exemplo n.º 4
0
static ssize_t get_pre_recved(struct connectdata *conn, int num, char *buf,
                              size_t len)
{
  struct postponed_data * const psnd = &(conn->postponed[num]);
  size_t copysize;
  if(!psnd->buffer)
    return 0;

  DEBUGASSERT(psnd->allocated_size > 0);
  DEBUGASSERT(psnd->recv_size <= psnd->allocated_size);
  DEBUGASSERT(psnd->recv_processed <= psnd->recv_size);
  /* Check and process data that already received and storied in internal
     intermediate buffer */
  if(psnd->recv_size > psnd->recv_processed) {
    DEBUGASSERT(psnd->bindsock == conn->sock[num]);
    copysize = CURLMIN(len, psnd->recv_size - psnd->recv_processed);
    memcpy(buf, psnd->buffer + psnd->recv_processed, copysize);
    psnd->recv_processed += copysize;
  }
  else
    copysize = 0; /* buffer was allocated, but nothing was received */

  /* Free intermediate buffer if it has no unprocessed data */
  if(psnd->recv_processed == psnd->recv_size) {
    free(psnd->buffer);
    psnd->buffer = NULL;
    psnd->allocated_size = 0;
    psnd->recv_size = 0;
    psnd->recv_processed = 0;
#ifdef DEBUGBUILD
    psnd->bindsock = CURL_SOCKET_BAD;
#endif /* DEBUGBUILD */
  }
  return (ssize_t)copysize;
}
Exemplo n.º 5
0
/*
 * Internal read-from-socket function. This is meant to deal with plain
 * sockets, SSL sockets and kerberos sockets.
 *
 * Returns a regular CURLcode value.
 */
CURLcode Curl_read(struct connectdata *conn, /* connection data */
                   curl_socket_t sockfd,     /* read from this socket */
                   char *buf,                /* store read data here */
                   size_t sizerequested,     /* max amount to read */
                   ssize_t *n)               /* amount bytes read */
{
  CURLcode result = CURLE_RECV_ERROR;
  ssize_t nread = 0;
  size_t bytesfromsocket = 0;
  char *buffertofill = NULL;
  struct Curl_easy *data = conn->data;

  /* Set 'num' to 0 or 1, depending on which socket that has been sent here.
     If it is the second socket, we set num to 1. Otherwise to 0. This lets
     us use the correct ssl handle. */
  int num = (sockfd == conn->sock[SECONDARYSOCKET]);

  *n = 0; /* reset amount to zero */

  bytesfromsocket = CURLMIN(sizerequested, (size_t)data->set.buffer_size);
  buffertofill = buf;

  nread = conn->recv[num](conn, num, buffertofill, bytesfromsocket, &result);
  if(nread < 0)
    return result;

  *n += nread;

  return CURLE_OK;
}
/*
*   headers must composed of fields split with "\r\n".
*   This is just temporary, need to modify later
*/
int curl_fetch_http_set_headers(CFContext * h, const char * headers)
{
    CLOGI("curl_fetch_http_set_headers enter\n");
    if (!h) {
        CLOGE("CFContext invalid\n");
        return -1;
    }
    char fields[2048];
    char * end_ptr = headers;
    char * beg_ptr = headers;
    while (*beg_ptr != '\0') {
        if (!(end_ptr = strstr(beg_ptr, "\r\n"))) {
            break;
        }
        if (beg_ptr == end_ptr) {
            beg_ptr += 2;
            continue;
        }
        memset(fields, 0x00, sizeof(fields));
        int tmp = CURLMIN(end_ptr - beg_ptr + 1, sizeof(fields) - 1);
        c_strlcpy(fields, beg_ptr, tmp);
        fields[tmp] = '\0';
        /*
        char * tmp_ptr = c_strrstr(fields, "\r\n"); // must remove CRLF
        if(tmp_ptr) {
            *tmp_ptr = '\0';
        }
        beg_ptr = end_ptr + 5;
        */
        beg_ptr = end_ptr + 2;
#if 0
        if (c_stristart(fields, "Connection:", NULL) || c_stristart(fields, "X-Playback-Session-Id:", NULL)) {
            h->chunk = curl_slist_append(h->chunk, fields);
            CLOGI("curl_fetch_http_set_headers fields=[%s]", fields);
        }
#else
        h->chunk = curl_slist_append(h->chunk, fields);
        CLOGI("curl_fetch_http_set_headers fields=[%s]", fields);
#endif
    }
    int ret = 0;
    if (h->prot_type == C_PROT_HTTP) {
        ret = curl_wrapper_set_para(h->cwh_h, (void *)h->chunk, C_HTTPHEADER, 0, NULL);
    }
    return ret;
}
Exemplo n.º 7
0
/*
 * Internal read-from-socket function. This is meant to deal with plain
 * sockets, SSL sockets and kerberos sockets.
 *
 * Returns a regular CURLcode value.
 */
CURLcode Curl_read(struct connectdata *conn, /* connection data */
                   curl_socket_t sockfd,     /* read from this socket */
                   char *buf,                /* store read data here */
                   size_t sizerequested,     /* max amount to read */
                   ssize_t *n)               /* amount bytes read */
{
  CURLcode result = CURLE_RECV_ERROR;
  ssize_t nread = 0;
  size_t bytesfromsocket = 0;
  char *buffertofill = NULL;
  struct Curl_easy *data = conn->data;

  /* if HTTP/1 pipelining is both wanted and possible */
  bool pipelining = Curl_pipeline_wanted(data->multi, CURLPIPE_HTTP1) &&
    (conn->bundle->multiuse == BUNDLE_PIPELINING);

  /* Set 'num' to 0 or 1, depending on which socket that has been sent here.
     If it is the second socket, we set num to 1. Otherwise to 0. This lets
     us use the correct ssl handle. */
  int num = (sockfd == conn->sock[SECONDARYSOCKET]);

  *n = 0; /* reset amount to zero */

  /* If session can pipeline, check connection buffer  */
  if(pipelining) {
    size_t bytestocopy = CURLMIN(conn->buf_len - conn->read_pos,
                                 sizerequested);

    /* Copy from our master buffer first if we have some unread data there*/
    if(bytestocopy > 0) {
      memcpy(buf, conn->master_buffer + conn->read_pos, bytestocopy);
      conn->read_pos += bytestocopy;
      conn->bits.stream_was_rewound = FALSE;

      *n = (ssize_t)bytestocopy;
      return CURLE_OK;
    }
    /* If we come here, it means that there is no data to read from the buffer,
     * so we read from the socket */
    bytesfromsocket = CURLMIN(sizerequested, MASTERBUF_SIZE);
    buffertofill = conn->master_buffer;
  }
  else {
    bytesfromsocket = CURLMIN(sizerequested, (size_t)data->set.buffer_size);
    buffertofill = buf;
  }

  nread = conn->recv[num](conn, num, buffertofill, bytesfromsocket, &result);
  if(nread < 0)
    return result;

  if(pipelining) {
    memcpy(buf, conn->master_buffer, nread);
    conn->buf_len = nread;
    conn->read_pos = nread;
  }

  *n += nread;

  return CURLE_OK;
}
Exemplo n.º 8
0
/*
 * Internal read-from-socket function. This is meant to deal with plain
 * sockets, SSL sockets and kerberos sockets.
 *
 * If the read would block (EWOULDBLOCK) we return -1. Otherwise we return
 * a regular CURLcode value.
 */
int Curl_read(struct connectdata *conn, /* connection data */
              curl_socket_t sockfd,     /* read from this socket */
              char *buf,                /* store read data here */
              size_t sizerequested,     /* max amount to read */
              ssize_t *n)               /* amount bytes read */
{
  ssize_t nread = 0;
  size_t bytesfromsocket = 0;
  char *buffertofill = NULL;
  bool pipelining = (bool)(conn->data->multi &&
                     Curl_multi_canPipeline(conn->data->multi));

  /* Set 'num' to 0 or 1, depending on which socket that has been sent here.
     If it is the second socket, we set num to 1. Otherwise to 0. This lets
     us use the correct ssl handle. */
  int num = (sockfd == conn->sock[SECONDARYSOCKET]);

  *n=0; /* reset amount to zero */

  /* If session can pipeline, check connection buffer  */
  if(pipelining) {
    size_t bytestocopy = CURLMIN(conn->buf_len - conn->read_pos,
                                 sizerequested);

    /* Copy from our master buffer first if we have some unread data there*/
    if(bytestocopy > 0) {
      memcpy(buf, conn->master_buffer + conn->read_pos, bytestocopy);
      conn->read_pos += bytestocopy;
      conn->bits.stream_was_rewound = FALSE;

      *n = (ssize_t)bytestocopy;
      return CURLE_OK;
    }
    /* If we come here, it means that there is no data to read from the buffer,
     * so we read from the socket */
    bytesfromsocket = CURLMIN(sizerequested, BUFSIZE * sizeof (char));
    buffertofill = conn->master_buffer;
  }
  else {
    bytesfromsocket = CURLMIN((long)sizerequested,
                              conn->data->set.buffer_size ?
                              conn->data->set.buffer_size : BUFSIZE);
    buffertofill = buf;
  }

  if(conn->ssl[num].state == ssl_connection_complete) {
    int curlcode = CURLE_RECV_ERROR;
    nread = Curl_ssl_recv(conn, num, buffertofill, bytesfromsocket, &curlcode);

    if(nread == -1)
      return curlcode;
  }
  else if(Curl_ssh_enabled(conn, (PROT_SCP|PROT_SFTP))) {
    if(conn->protocol & PROT_SCP)
      nread = Curl_scp_recv(conn, num, buffertofill, bytesfromsocket);
    else if(conn->protocol & PROT_SFTP)
      nread = Curl_sftp_recv(conn, num, buffertofill, bytesfromsocket);
#ifdef LIBSSH2CHANNEL_EAGAIN
    if(nread == LIBSSH2CHANNEL_EAGAIN)
      /* EWOULDBLOCK */
      return -1;
#endif
    if(nread < 0)
      /* since it is negative and not EAGAIN, it was a protocol-layer error */
      return CURLE_RECV_ERROR;
  }
  else {
    if(conn->sec_complete)
      nread = Curl_sec_read(conn, sockfd, buffertofill,
                            bytesfromsocket);
    /* TODO: Need to handle EAGAIN here somehow, similar to how it
     * is done in Curl_read_plain, either right here or in Curl_sec_read
     * itself. */
    else {
      int ret = Curl_read_plain(sockfd, buffertofill, bytesfromsocket,
                                     &nread);
      if(ret)
        return ret;
    }
  }
  if(nread >= 0) {
    if(pipelining) {
      memcpy(buf, conn->master_buffer, nread);
      conn->buf_len = nread;
      conn->read_pos = nread;
    }

    *n += nread;
  }

  return CURLE_OK;
}