Skip to content
url.c 97.8 KiB
Newer Older
Daniel Stenberg's avatar
Daniel Stenberg committed

Daniel Stenberg's avatar
Daniel Stenberg committed
  if(data->set.encoding) {
    if(conn->allocptr.accept_encoding)
      free(conn->allocptr.accept_encoding);
    conn->allocptr.accept_encoding =
      aprintf("Accept-Encoding: %s\015\012", data->set.encoding);
  }

  conn->bytecount = 0;
  conn->headerbytecount = 0;
Daniel Stenberg's avatar
Daniel Stenberg committed
  if(-1 == conn->firstsocket) {
Daniel Stenberg's avatar
Daniel Stenberg committed
    /* Connect only if not already connected! */
    result = ConnectPlease(conn, hostaddr, &connected);

      result = Curl_protocol_connect(conn, hostaddr);
      if(CURLE_OK == result)
        conn->bits.tcpconnect = TRUE;
    }
    else
      conn->bits.tcpconnect = FALSE;

Daniel Stenberg's avatar
Daniel Stenberg committed
    if(CURLE_OK != result)
      return result;
Daniel Stenberg's avatar
Daniel Stenberg committed
  }
  else {
    Curl_pgrsTime(data, TIMER_CONNECT); /* we're connected already */
Daniel Stenberg's avatar
Daniel Stenberg committed
  }

  conn->now = Curl_tvnow(); /* time this *after* the connect is done, we
                               set this here perhaps a second time */
Daniel Stenberg's avatar
Daniel Stenberg committed

#ifdef __EMX__
  /* 20000330 mgs
   * the check is quite a hack...
   * we're calling _fsetmode to fix the problem with fwrite converting newline
   * characters (you get mangled text files, and corrupted binary files when
   * you download to stdout and redirect it to a file). */

  if ((data->set.out)->_handle == NULL) {
    _fsetmode(stdout, "b");
  }
#endif

CURLcode Curl_connect(struct SessionHandle *data,
                      struct connectdata **in_connect)
{
  CURLcode code;
  struct connectdata *conn;

  /* call the stuff that needs to be called */
  code = CreateConnection(data, in_connect);

  if(CURLE_OK != code) {
    /* We're not allowed to return failure with memory left allocated
       in the connectdata struct, free those here */
    conn = (struct connectdata *)*in_connect;
      Curl_disconnect(conn);      /* close the connection */
CURLcode Curl_done(struct connectdata *conn)
  struct SessionHandle *data=conn->data;
  CURLcode result;

  /* cleanups done even if the connection is re-used */

  if(conn->bits.rangestringalloc) {
    free(conn->range);
    conn->bits.rangestringalloc = FALSE;
  }

  /* Cleanup possible redirect junk */
  if(conn->newurl) {
    free(conn->newurl);
    conn->newurl = NULL;
  }
    Curl_resolv_unlock(conn->data, conn->connect_addr); /* done with this */
#if defined(CURLDEBUG) && defined(AGGRESIVE_TEST)
  /* scan for DNS cache entries still marked as in use */
  Curl_hash_apply(data->hostcache,
                  NULL, Curl_scan_cache_used);
#endif

  /* this calls the protocol-specific function pointer previously set */
  if(conn->curl_done)
    result = conn->curl_done(conn);
  else
    result = CURLE_OK;

  Curl_pgrsDone(conn); /* done with the operation */
  /* if data->set.reuse_forbid is TRUE, it means the libcurl client has
     forced us to close this no matter what we think.
     if conn->bits.close is TRUE, it means that the connection should be
     closed in spite of all our efforts to be nice, due to protocol
     restrictions in our or the server's end */
     ((CURLE_OK == result) && conn->bits.close))
    result = Curl_disconnect(conn); /* close the connection */
    infof(data, "Connection #%d left intact\n", conn->connectindex);
CURLcode Curl_do(struct connectdata **connp)
  CURLcode result=CURLE_OK;
  struct connectdata *conn = *connp;
  struct SessionHandle *data=conn->data;
  conn->bits.do_more = FALSE; /* by default there's no curl_do_more() to use */
    /* generic protocol-specific function pointer set in curl_connect() */
    result = conn->curl_do(conn);

    /* This was formerly done in transfer.c, but we better do it here */
    if((CURLE_SEND_ERROR == result) && conn->bits.reuse) {
      /* This was a re-use of a connection and we got a write error in the
       * DO-phase. Then we DISCONNECT this connection and have another attempt
       * to CONNECT and then DO again! The retry cannot possibly find another
       * connection to re-use, since we only keep one possible connection for
       * each.  */

      infof(data, "Re-used connection seems dead, get a new one\n");

      conn->bits.close = TRUE; /* enforce close of this connetion */
      result = Curl_done(conn);   /* we are so done with this */
      if(CURLE_OK == result) {
        /* Now, redo the connect and get a new connection */
        result = Curl_connect(data, connp);
        if(CURLE_OK == result)
          /* ... finally back to actually retry the DO phase */
          result = conn->curl_do(*connp);
      }
    }
  }
CURLcode Curl_do_more(struct connectdata *conn)
{
  CURLcode result=CURLE_OK;

  if(conn->curl_do_more)
    result = conn->curl_do_more(conn);

  return result;
}

static bool safe_strequal(char* str1, char* str2)
{
  if(str1 && str2)
    /* both pointers point to something then compare them */
    return strequal(str1, str2);
  else
    /* if both pointers are NULL then treat them as equal */
    return (!str1 && !str2);
}

bool
Curl_ssl_config_matches(struct ssl_config_data* data,
                        struct ssl_config_data* needle)
{
  if((data->version == needle->version) &&
     (data->verifypeer == needle->verifypeer) &&
     (data->verifyhost == needle->verifyhost) &&
     safe_strequal(data->CApath, needle->CApath) &&
     safe_strequal(data->CAfile, needle->CAfile) &&
     safe_strequal(data->random_file, needle->random_file) &&
     safe_strequal(data->egdsocket, needle->egdsocket) &&
     safe_strequal(data->cipher_list, needle->cipher_list))
    return TRUE;
  return FALSE;
bool
Curl_clone_ssl_config(struct ssl_config_data *source,
                      struct ssl_config_data *dest)
  dest->verifyhost = source->verifyhost;
  dest->verifypeer = source->verifypeer;
  dest->version = source->version;
  if(source->CAfile) {
    dest->CAfile = strdup(source->CAfile);
    if(!dest->CAfile)
      return FALSE;
  if(source->CApath) {
    dest->CApath = strdup(source->CApath);
    if(!dest->CApath)
      return FALSE;
  if(source->cipher_list) {
    dest->cipher_list = strdup(source->cipher_list);
    if(!dest->cipher_list)
      return FALSE;
  if(source->egdsocket) {
    dest->egdsocket = strdup(source->egdsocket);
    if(!dest->egdsocket)
      return FALSE;
  if(source->random_file) {
    dest->random_file = strdup(source->random_file);
    if(!dest->random_file)
      return FALSE;
void Curl_free_ssl_config(struct ssl_config_data* sslc)
{
  if(sslc->CAfile)
    free(sslc->CAfile);

  if(sslc->CApath)
    free(sslc->CApath);

  if(sslc->cipher_list)
    free(sslc->cipher_list);

  if(sslc->egdsocket)
    free(sslc->egdsocket);

  if(sslc->random_file)
    free(sslc->random_file);
}