Skip to content
url.c 184 KiB
Newer Older

    /* If we had an error already, make sure we return that one. But
       if we got a new error, return that. */
    if(!result && res2)
      result = res2;
  }
    /* the connection is no longer in use */
    if(ConnectionDone(data, conn)) {
      /* remember the most recently used connection */
      data->state.lastconnect = conn;

      infof(data, "Connection #%ld to host %s left intact\n",
            conn->connection_id,
            conn->bits.httpproxy?conn->proxy.dispname:conn->host.dispname);
    }
    else
      data->state.lastconnect = NULL;
  *connp = NULL; /* to make the caller of this function better detect that
                    this was either closed or handed over to the connection
                    cache here, and therefore cannot be used from this point on
                 */
  Curl_free_request_state(data);
/*
 * do_init() inits the readwrite session. This is inited each time (in the DO
 * function before the protocol-specific DO functions are invoked) for a
 * transfer, sometimes multiple times on the same SessionHandle. Make sure
 * nothing in here depends on stuff that are setup dynamically for the
 * transfer.
 */

static CURLcode do_init(struct connectdata *conn)
{
  struct SessionHandle *data = conn->data;

  conn->bits.done = FALSE; /* Curl_done() is not called yet */
  conn->bits.do_more = FALSE; /* by default there's no curl_do_more() to use */
  data->state.expect100header = FALSE;
  if(data->set.opt_no_body)
    /* in HTTP lingo, no body means using the HEAD request... */
    data->set.httpreq = HTTPREQ_HEAD;
  else if(HTTPREQ_HEAD == data->set.httpreq)
    /* ... but if unset there really is no perfect method that is the
       "opposite" of HEAD but in reality most people probably think GET
       then. The important thing is that we can't let it remain HEAD if the
       opt_no_body is set FALSE since then we'll behave wrong when getting
       HTTP. */
    data->set.httpreq = HTTPREQ_GET;

  k->start = Curl_tvnow(); /* start time */
  k->now = k->start;   /* current time is now */
  k->header = TRUE; /* assume header */

  k->bytecount = 0;

  k->buf = data->state.buffer;
  k->uploadbuf = data->state.uploadbuffer;
  k->hbufp = data->state.headerbuff;
  k->ignorebody=FALSE;

  Curl_speedinit(data);

  Curl_pgrsSetUploadCounter(data, 0);
  Curl_pgrsSetDownloadCounter(data, 0);

  return CURLE_OK;
}

/*
 * do_complete is called when the DO actions are complete.
 *
 * We init chunking and trailer bits to their default values here immediately
 * before receiving any header data for the current request in the pipeline.
 */
static void do_complete(struct connectdata *conn)
{
  conn->data->req.maxfd = (conn->sockfd>conn->writesockfd?
                           conn->sockfd:conn->writesockfd)+1;
  Curl_pgrsTime(conn->data, TIMER_PRETRANSFER);
CURLcode Curl_do(struct connectdata **connp, bool *done)
  CURLcode result=CURLE_OK;
  struct connectdata *conn = *connp;
  struct SessionHandle *data = conn->data;
    /* generic protocol-specific function pointer set in curl_connect() */
    result = conn->handler->do_it(conn, done);
    /* This was formerly done in transfer.c, but we better do it here */
    if((CURLE_SEND_ERROR == result) && conn->bits.reuse) {
      /*
       * If the connection is using an easy handle, call reconnect
       * to re-establish the connection.  Otherwise, let the multi logic
       * figure out how to re-establish the connection.
       */
      if(!data->multi) {
        result = Curl_reconnect_request(connp);

          /* ... finally back to actually retry the DO phase */
          conn = *connp; /* re-assign conn since Curl_reconnect_request
                            creates a new connection */
          result = conn->handler->do_it(conn, done);
    if(!result && *done)
      /* do_complete must be called after the protocol-specific DO function */
/*
 * Curl_do_more() is called during the DO_MORE multi state. It is basically a
 * second stage DO state which (wrongly) was introduced to support FTP's
 * second connection.
 *
 * TODO: A future libcurl should be able to work away this state.
 *
 * 'complete' can return 0 for incomplete, 1 for done and -1 for go back to
 * DOING state there's more work to do!
CURLcode Curl_do_more(struct connectdata *conn, int *complete)
    result = conn->handler->do_more(conn, complete);
  if(!result && (*complete == 1))
    /* do_complete must be called after the protocol-specific DO function */
    do_complete(conn);