Commit 4ad8e142 authored by Daniel Stenberg's avatar Daniel Stenberg
Browse files

urldata: clean up the use of the protocol specific structs

1 - always allocate the struct in protocol->setup_connection. Some
protocol handlers had to get this function added.

2 - always free at the end of a request. This is also an attempt to keep
less memory in the handle after it is completed.
parent e3ee73b7
Loading
Loading
Loading
Loading
+2 −3
Original line number Diff line number Diff line
@@ -603,7 +603,6 @@ void Curl_easy_addmulti(struct SessionHandle *data,
void Curl_easy_initHandleData(struct SessionHandle *data)
{
  memset(&data->req, 0, sizeof(struct SingleRequest));

  data->req.maxdownload = -1;
}

+7 −22
Original line number Diff line number Diff line
@@ -5,7 +5,7 @@
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
 * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution. The terms
@@ -186,31 +186,16 @@ static CURLcode file_connect(struct connectdata *conn, bool *done)
  char *actual_path;
#endif

  /* If there already is a protocol-specific struct allocated for this
     sessionhandle, deal with it */
  Curl_reset_reqproto(conn);

  real_path = curl_easy_unescape(data, data->state.path, 0, NULL);
  if(!real_path)
    return CURLE_OUT_OF_MEMORY;

  if(!data->state.proto.file) {
  file = calloc(1, sizeof(struct FILEPROTO));
  if(!file) {
    free(real_path);
    return CURLE_OUT_OF_MEMORY;
  }
  data->state.proto.file = file;
  }
  else {
    /* file is not a protocol that can deal with "persistancy" */
    file = data->state.proto.file;
    Curl_safefree(file->freepath);
    file->path = NULL;
    if(file->fd != -1)
      close(file->fd);
    file->fd = -1;
  }

#ifdef DOS_FILESYSTEM
  /* If the first character is a slash, and there's
@@ -450,7 +435,7 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
    return file_upload(conn);

  /* get the fd from the connection phase */
  fd = conn->data->state.proto.file->fd;
  fd = data->state.proto.file->fd;

  /* VMS: This only works reliable for STREAMLF files */
  if(-1 != fstat(fd, &statbuf)) {
+29 −79
Original line number Diff line number Diff line
@@ -225,7 +225,7 @@ const struct Curl_handler Curl_handler_ftps = {

static const struct Curl_handler Curl_handler_ftp_proxy = {
  "FTP",                                /* scheme */
  ZERO_NULL,                            /* setup_connection */
  Curl_http_setup_conn,                 /* setup_connection */
  Curl_http,                            /* do_it */
  Curl_http_done,                       /* done */
  ZERO_NULL,                            /* do_more */
@@ -251,7 +251,7 @@ static const struct Curl_handler Curl_handler_ftp_proxy = {

static const struct Curl_handler Curl_handler_ftps_proxy = {
  "FTPS",                               /* scheme */
  ZERO_NULL,                            /* setup_connection */
  Curl_http_setup_conn,                 /* setup_connection */
  Curl_http,                            /* do_it */
  Curl_http_done,                       /* done */
  ZERO_NULL,                            /* do_more */
@@ -3158,56 +3158,6 @@ static CURLcode ftp_block_statemach(struct connectdata *conn)
  return result;
}

/*
 * Allocate and initialize the struct FTP for the current SessionHandle.  If
 * need be.
 */

#if defined(__INTEL_COMPILER) && (__INTEL_COMPILER == 910) && \
    defined(__OPTIMIZE__) && defined(__unix__) && defined(__i386__)
  /* workaround icc 9.1 optimizer issue */
#pragma optimize("", off)
#endif

static CURLcode ftp_init(struct connectdata *conn)
{
  struct FTP *ftp;

  if(NULL == conn->data->state.proto.ftp) {
    conn->data->state.proto.ftp = malloc(sizeof(struct FTP));
    if(NULL == conn->data->state.proto.ftp)
      return CURLE_OUT_OF_MEMORY;
  }

  ftp = conn->data->state.proto.ftp;

  /* get some initial data into the ftp struct */
  ftp->bytecountp = &conn->data->req.bytecount;
  ftp->transfer = FTPTRANSFER_BODY;
  ftp->downloadsize = 0;

  /* No need to duplicate user+password, the connectdata struct won't change
     during a session, but we re-init them here since on subsequent inits
     since the conn struct may have changed or been replaced.
  */
  ftp->user = conn->user;
  ftp->passwd = conn->passwd;
  if(isBadFtpString(ftp->user))
    return CURLE_URL_MALFORMAT;
  if(isBadFtpString(ftp->passwd))
    return CURLE_URL_MALFORMAT;

  conn->proto.ftpc.known_filesize = -1; /* unknown size for now */

  return CURLE_OK;
}

#if defined(__INTEL_COMPILER) && (__INTEL_COMPILER == 910) && \
    defined(__OPTIMIZE__) && defined(__unix__) && defined(__i386__)
  /* workaround icc 9.1 optimizer issue */
#pragma optimize("", on)
#endif

/*
 * ftp_connect() should do everything that is to be considered a part of
 * the connection phase.
@@ -3225,14 +3175,6 @@ static CURLcode ftp_connect(struct connectdata *conn,

  *done = FALSE; /* default to not done yet */

  /* If there already is a protocol-specific struct allocated for this
     sessionhandle, deal with it */
  Curl_reset_reqproto(conn);

  result = ftp_init(conn);
  if(CURLE_OK != result)
    return result;

  /* We always support persistent connections on ftp */
  conn->bits.close = FALSE;

@@ -4099,17 +4041,6 @@ static CURLcode ftp_do(struct connectdata *conn, bool *done)
  *done = FALSE; /* default to false */
  ftpc->wait_data_conn = FALSE; /* default to no such wait */

  /*
    Since connections can be re-used between SessionHandles, this might be a
    connection already existing but on a fresh SessionHandle struct so we must
    make sure we have a good 'struct FTP' to play with. For new connections,
    the struct FTP is allocated and setup in the ftp_connect() function.
  */
  Curl_reset_reqproto(conn);
  retcode = ftp_init(conn);
  if(retcode)
    return retcode;

  if(conn->data->set.wildcardmatch) {
    retcode = wc_statemach(conn);
    if(conn->data->wildcard.state == CURLWC_SKIP ||
@@ -4577,6 +4508,7 @@ static CURLcode ftp_setup_connection(struct connectdata * conn)
  struct SessionHandle *data = conn->data;
  char *type;
  char command;
  struct FTP *ftp;

  if(conn->bits.httpproxy && !data->set.tunnel_thru_httpproxy) {
    /* Unless we have asked to tunnel ftp operations through the proxy, we
@@ -4592,18 +4524,18 @@ static CURLcode ftp_setup_connection(struct connectdata * conn)
      return CURLE_UNSUPPORTED_PROTOCOL;
#endif
    }
    /*
     * We explicitly mark this connection as persistent here as we're doing
     * FTP over HTTP and thus we accidentally avoid setting this value
     * otherwise.
     */
    conn->bits.close = FALSE;
    /* set it up as a HTTP connection instead */
    return conn->handler->setup_connection(conn);
#else
    failf(data, "FTP over http proxy requires HTTP support built-in!");
    return CURLE_UNSUPPORTED_PROTOCOL;
#endif
  }

  conn->data->state.proto.ftp =  ftp = malloc(sizeof(struct FTP));
  if(NULL == ftp)
    return CURLE_OUT_OF_MEMORY;

  data->state.path++;   /* don't include the initial slash */
  data->state.slash_removed = TRUE; /* we've skipped the slash */

@@ -4636,6 +4568,24 @@ static CURLcode ftp_setup_connection(struct connectdata * conn)
    }
  }

  /* get some initial data into the ftp struct */
  ftp->bytecountp = &conn->data->req.bytecount;
  ftp->transfer = FTPTRANSFER_BODY;
  ftp->downloadsize = 0;

  /* No need to duplicate user+password, the connectdata struct won't change
     during a session, but we re-init them here since on subsequent inits
     since the conn struct may have changed or been replaced.
  */
  ftp->user = conn->user;
  ftp->passwd = conn->passwd;
  if(isBadFtpString(ftp->user))
    return CURLE_URL_MALFORMAT;
  if(isBadFtpString(ftp->passwd))
    return CURLE_URL_MALFORMAT;

  conn->proto.ftpc.known_filesize = -1; /* unknown size for now */

  return CURLE_OK;
}

+19 −16
Original line number Diff line number Diff line
@@ -105,7 +105,7 @@ static int https_getsock(struct connectdata *conn,
 */
const struct Curl_handler Curl_handler_http = {
  "HTTP",                               /* scheme */
  ZERO_NULL,                            /* setup_connection */
  Curl_http_setup_conn,                 /* setup_connection */
  Curl_http,                            /* do_it */
  Curl_http_done,                       /* done */
  ZERO_NULL,                            /* do_more */
@@ -129,7 +129,7 @@ const struct Curl_handler Curl_handler_http = {
 */
const struct Curl_handler Curl_handler_https = {
  "HTTPS",                              /* scheme */
  ZERO_NULL,                            /* setup_connection */
  Curl_http_setup_conn,                 /* setup_connection */
  Curl_http,                            /* do_it */
  Curl_http_done,                       /* done */
  ZERO_NULL,                            /* do_more */
@@ -149,6 +149,21 @@ const struct Curl_handler Curl_handler_https = {
#endif


CURLcode Curl_http_setup_conn(struct connectdata *conn)
{
  /* allocate the HTTP-specific struct for the SessionHandle, only to survive
     during this request */
  struct HTTP *http;

  DEBUGASSERT(conn->data->state.proto.http == NULL);

  conn->data->state.proto.http = http = calloc(1, sizeof(struct HTTP));
  if(!http)
    return CURLE_OUT_OF_MEMORY;

  return CURLE_OK;
}

/*
 * checkheaders() checks the linked list of custom HTTP headers for a
 * particular header (prefix).
@@ -1442,6 +1457,7 @@ CURLcode Curl_http_done(struct connectdata *conn,
  if(!premature && /* this check is pointless when DONE is called before the
                      entire operation is complete */
     !conn->bits.retry &&
     !data->set.connect_only &&
     ((http->readbytecount +
       data->req.headerbytecount -
       data->req.deductheadercount)) <= 0) {
@@ -1655,19 +1671,6 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
     the rest of the request in the PERFORM phase. */
  *done = TRUE;

  /* If there already is a protocol-specific struct allocated for this
     sessionhandle, deal with it */
  Curl_reset_reqproto(conn);

  if(!data->state.proto.http) {
    /* Only allocate this struct if we don't already have it! */

    http = calloc(1, sizeof(struct HTTP));
    if(!http)
      return CURLE_OUT_OF_MEMORY;
    data->state.proto.http = http;
  }
  else
  http = data->state.proto.http;

  if(!data->state.this_is_a_follow) {
+2 −1
Original line number Diff line number Diff line
@@ -7,7 +7,7 @@
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
 * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution. The terms
@@ -66,6 +66,7 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn,
CURLcode Curl_http(struct connectdata *conn, bool *done);
CURLcode Curl_http_done(struct connectdata *, CURLcode, bool premature);
CURLcode Curl_http_connect(struct connectdata *conn, bool *done);
CURLcode Curl_http_setup_conn(struct connectdata *conn);

/* The following functions are defined in http_chunks.c */
void Curl_httpchunk_init(struct connectdata *conn);
Loading