/***************************************************************************
 *                                  _   _ ____  _
 *  Project                     ___| | | |  _ \| |
 *                             / __| | | | |_) | |
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) 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
 * are also available at https://curl.se/docs/copyright.html.
 *
 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
 * copies of the Software, and permit persons to whom the Software is
 * furnished to do so, under the terms of the COPYING file.
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 * SPDX-License-Identifier: curl
 *
 ***************************************************************************/

#include "curl_setup.h"

#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif

#ifdef HAVE_LINUX_TCP_H
#include <linux/tcp.h>
#elif defined(HAVE_NETINET_TCP_H)
#include <netinet/tcp.h>
#endif

#include <curl/curl.h>

#include "urldata.h"
#include "sendf.h"
#include "cfilters.h"
#include "connect.h"
#include "content_encoding.h"
#include "vtls/vtls.h"
#include "vssh/ssh.h"
#include "easyif.h"
#include "multiif.h"
#include "strerror.h"
#include "select.h"
#include "strdup.h"
#include "http2.h"
#include "headers.h"
#include "progress.h"
#include "ws.h"

/* The last 3 #include files should be in this order */
#include "curl_printf.h"
#include "curl_memory.h"
#include "memdebug.h"


static CURLcode do_init_stack(struct Curl_easy *data);

#if defined(CURL_DO_LINEEND_CONV) && !defined(CURL_DISABLE_FTP)
/*
 * convert_lineends() changes CRLF (\r\n) end-of-line markers to a single LF
 * (\n), with special processing for CRLF sequences that are split between two
 * blocks of data.  Remaining, bare CRs are changed to LFs.  The possibly new
 * size of the data is returned.
 */
static size_t convert_lineends(struct Curl_easy *data,
                               char *startPtr, size_t size)
{
  char *inPtr, *outPtr;

  /* sanity check */
  if(!startPtr || (size < 1)) {
    return size;
  }

  if(data->state.prev_block_had_trailing_cr) {
    /* The previous block of incoming data
       had a trailing CR, which was turned into a LF. */
    if(*startPtr == '\n') {
      /* This block of incoming data starts with the
         previous block's LF so get rid of it */
      memmove(startPtr, startPtr + 1, size-1);
      size--;
      /* and it wasn't a bare CR but a CRLF conversion instead */
      data->state.crlf_conversions++;
    }
    data->state.prev_block_had_trailing_cr = FALSE; /* reset the flag */
  }

  /* find 1st CR, if any */
  inPtr = outPtr = memchr(startPtr, '\r', size);
  if(inPtr) {
    /* at least one CR, now look for CRLF */
    while(inPtr < (startPtr + size-1)) {
      /* note that it's size-1, so we'll never look past the last byte */
      if(memcmp(inPtr, "\r\n", 2) == 0) {
        /* CRLF found, bump past the CR and copy the NL */
        inPtr++;
        *outPtr = *inPtr;
        /* keep track of how many CRLFs we converted */
        data->state.crlf_conversions++;
      }
      else {
        if(*inPtr == '\r') {
          /* lone CR, move LF instead */
          *outPtr = '\n';
        }
        else {
          /* not a CRLF nor a CR, just copy whatever it is */
          *outPtr = *inPtr;
        }
      }
      outPtr++;
      inPtr++;
    } /* end of while loop */

    if(inPtr < startPtr + size) {
      /* handle last byte */
      if(*inPtr == '\r') {
        /* deal with a CR at the end of the buffer */
        *outPtr = '\n'; /* copy a NL instead */
        /* note that a CRLF might be split across two blocks */
        data->state.prev_block_had_trailing_cr = TRUE;
      }
      else {
        /* copy last byte */
        *outPtr = *inPtr;
      }
      outPtr++;
    }
    if(outPtr < startPtr + size)
      /* tidy up by null terminating the now shorter data */
      *outPtr = '\0';

    return (outPtr - startPtr);
  }
  return size;
}
#endif /* CURL_DO_LINEEND_CONV && !CURL_DISABLE_FTP */

/*
 * Curl_nwrite() is an internal write function that sends data to the
 * server. Works with a socket index for the connection.
 *
 * If the write would block (CURLE_AGAIN), it returns CURLE_OK and
 * (*nwritten == 0). Otherwise we return regular CURLcode value.
 */
CURLcode Curl_nwrite(struct Curl_easy *data,
                     int sockindex,
                     const void *buf,
                     size_t blen,
                     ssize_t *pnwritten)
{
  ssize_t nwritten;
  CURLcode result = CURLE_OK;
  struct connectdata *conn;

  DEBUGASSERT(sockindex >= 0 && sockindex < 2);
  DEBUGASSERT(pnwritten);
  DEBUGASSERT(data);
  DEBUGASSERT(data->conn);
  conn = data->conn;
#ifdef CURLDEBUG
  {
    /* Allow debug builds to override this logic to force short sends
    */
    char *p = getenv("CURL_SMALLSENDS");
    if(p) {
      size_t altsize = (size_t)strtoul(p, NULL, 10);
      if(altsize)
        blen = CURLMIN(blen, altsize);
    }
  }
#endif
  nwritten = conn->send[sockindex](data, sockindex, buf, blen, &result);
  if(result == CURLE_AGAIN) {
    nwritten = 0;
    result = CURLE_OK;
  }
  else if(result) {
    nwritten = -1; /* make sure */
  }
  else {
    DEBUGASSERT(nwritten >= 0);
  }

  *pnwritten = nwritten;
  return result;
}

/*
 * Curl_write() is an internal write function that sends data to the
 * server. Works with plain sockets, SCP, SSL or kerberos.
 *
 * If the write would block (CURLE_AGAIN), we return CURLE_OK and
 * (*written == 0). Otherwise we return regular CURLcode value.
 */
CURLcode Curl_write(struct Curl_easy *data,
                    curl_socket_t sockfd,
                    const void *mem,
                    size_t len,
                    ssize_t *written)
{
  struct connectdata *conn;
  int num;

  DEBUGASSERT(data);
  DEBUGASSERT(data->conn);
  conn = data->conn;
  num = (sockfd != CURL_SOCKET_BAD && sockfd == conn->sock[SECONDARYSOCKET]);
  return Curl_nwrite(data, num, mem, len, written);
}

static CURLcode pausewrite(struct Curl_easy *data,
                           int type, /* what type of data */
                           bool paused_body,
                           const char *ptr,
                           size_t len)
{
  /* signalled to pause sending on this connection, but since we have data
     we want to send we need to dup it to save a copy for when the sending
     is again enabled */
  struct SingleRequest *k = &data->req;
  struct UrlState *s = &data->state;
  unsigned int i;
  bool newtype = TRUE;

  Curl_conn_ev_data_pause(data, TRUE);

  if(s->tempcount) {
    for(i = 0; i< s->tempcount; i++) {
      if(s->tempwrite[i].type == type &&
         !!s->tempwrite[i].paused_body == !!paused_body) {
        /* data for this type exists */
        newtype = FALSE;
        break;
      }
    }
    DEBUGASSERT(i < 3);
    if(i >= 3)
      /* There are more types to store than what fits: very bad */
      return CURLE_OUT_OF_MEMORY;
  }
  else
    i = 0;

  if(newtype) {
    /* store this information in the state struct for later use */
    Curl_dyn_init(&s->tempwrite[i].b, DYN_PAUSE_BUFFER);
    s->tempwrite[i].type = type;
    s->tempwrite[i].paused_body = paused_body;
    s->tempcount++;
  }

  if(Curl_dyn_addn(&s->tempwrite[i].b, (unsigned char *)ptr, len))
    return CURLE_OUT_OF_MEMORY;

  /* mark the connection as RECV paused */
  k->keepon |= KEEP_RECV_PAUSE;

  return CURLE_OK;
}


/* chop_write() writes chunks of data not larger than CURL_MAX_WRITE_SIZE via
 * client write callback(s) and takes care of pause requests from the
 * callbacks.
 */
static CURLcode chop_write(struct Curl_easy *data,
                           int type,
                           bool skip_body_write,
                           char *optr,
                           size_t olen)
{
  struct connectdata *conn = data->conn;
  curl_write_callback writeheader = NULL;
  curl_write_callback writebody = NULL;
  char *ptr = optr;
  size_t len = olen;
  void *writebody_ptr = data->set.out;

  if(!len)
    return CURLE_OK;

  /* If reading is paused, append this data to the already held data for this
     type. */
  if(data->req.keepon & KEEP_RECV_PAUSE)
    return pausewrite(data, type, !skip_body_write, ptr, len);

  /* Determine the callback(s) to use. */
  if(!skip_body_write &&
     ((type & CLIENTWRITE_BODY) ||
      ((type & CLIENTWRITE_HEADER) && data->set.include_header))) {
    writebody = data->set.fwrite_func;
  }
  if((type & (CLIENTWRITE_HEADER|CLIENTWRITE_INFO)) &&
     (data->set.fwrite_header || data->set.writeheader)) {
    /*
     * Write headers to the same callback or to the especially setup
     * header callback function (added after version 7.7.1).
     */
    writeheader =
      data->set.fwrite_header? data->set.fwrite_header: data->set.fwrite_func;
  }

  /* Chop data, write chunks. */
  while(len) {
    size_t chunklen = len <= CURL_MAX_WRITE_SIZE? len: CURL_MAX_WRITE_SIZE;

    if(writebody) {
      size_t wrote;
      Curl_set_in_callback(data, true);
      wrote = writebody(ptr, 1, chunklen, writebody_ptr);
      Curl_set_in_callback(data, false);

      if(CURL_WRITEFUNC_PAUSE == wrote) {
        if(conn->handler->flags & PROTOPT_NONETWORK) {
          /* Protocols that work without network cannot be paused. This is
             actually only FILE:// just now, and it can't pause since the
             transfer isn't done using the "normal" procedure. */
          failf(data, "Write callback asked for PAUSE when not supported");
          return CURLE_WRITE_ERROR;
        }
        return pausewrite(data, type, TRUE, ptr, len);
      }
      if(wrote != chunklen) {
        failf(data, "Failure writing output to destination");
        return CURLE_WRITE_ERROR;
      }
    }

    ptr += chunklen;
    len -= chunklen;
  }

#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_HEADERS_API)
  /* HTTP header, but not status-line */
  if((conn->handler->protocol & PROTO_FAMILY_HTTP) &&
     (type & CLIENTWRITE_HEADER) && !(type & CLIENTWRITE_STATUS) ) {
    unsigned char htype = (unsigned char)
      (type & CLIENTWRITE_CONNECT ? CURLH_CONNECT :
       (type & CLIENTWRITE_1XX ? CURLH_1XX :
        (type & CLIENTWRITE_TRAILER ? CURLH_TRAILER :
         CURLH_HEADER)));
    CURLcode result = Curl_headers_push(data, optr, htype);
    if(result)
      return result;
  }
#endif

  if(writeheader) {
    size_t wrote;

    Curl_set_in_callback(data, true);
    wrote = writeheader(optr, 1, olen, data->set.writeheader);
    Curl_set_in_callback(data, false);

    if(CURL_WRITEFUNC_PAUSE == wrote)
      return pausewrite(data, type, FALSE, optr, olen);
    if(wrote != olen) {
      failf(data, "Failed writing header");
      return CURLE_WRITE_ERROR;
    }
  }

  return CURLE_OK;
}


/* Curl_client_write() sends data to the write callback(s)

   The bit pattern defines to what "streams" to write to. Body and/or header.
   The defines are in sendf.h of course.

   If CURL_DO_LINEEND_CONV is enabled, data is converted IN PLACE to the
   local character encoding.  This is a problem and should be changed in
   the future to leave the original data alone.
 */
CURLcode Curl_client_write(struct Curl_easy *data,
                           int type, char *buf, size_t blen)
{
  CURLcode result;

#if !defined(CURL_DISABLE_FTP) && defined(CURL_DO_LINEEND_CONV)
  /* FTP data may need conversion. */
  if((type & CLIENTWRITE_BODY) &&
     (data->conn->handler->protocol & PROTO_FAMILY_FTP) &&
     data->conn->proto.ftpc.transfertype == 'A') {
    /* convert end-of-line markers */
    blen = convert_lineends(data, buf, blen);
  }
#endif
  /* it is one of those, at least */
  DEBUGASSERT(type & (CLIENTWRITE_BODY|CLIENTWRITE_HEADER|CLIENTWRITE_INFO));
  /* BODY is only BODY (with optional EOS) */
  DEBUGASSERT(!(type & CLIENTWRITE_BODY) ||
              ((type & ~(CLIENTWRITE_BODY|CLIENTWRITE_EOS)) == 0));
  /* INFO is only INFO (with optional EOS) */
  DEBUGASSERT(!(type & CLIENTWRITE_INFO) ||
              ((type & ~(CLIENTWRITE_INFO|CLIENTWRITE_EOS)) == 0));

  if(!data->req.writer_stack) {
    result = do_init_stack(data);
    if(result)
      return result;
    DEBUGASSERT(data->req.writer_stack);
  }

  return Curl_cwriter_write(data, data->req.writer_stack, type, buf, blen);
}

CURLcode Curl_client_unpause(struct Curl_easy *data)
{
  CURLcode result = CURLE_OK;

  if(data->state.tempcount) {
    /* there are buffers for sending that can be delivered as the receive
       pausing is lifted! */
    unsigned int i;
    unsigned int count = data->state.tempcount;
    struct tempbuf writebuf[3]; /* there can only be three */

    /* copy the structs to allow for immediate re-pausing */
    for(i = 0; i < data->state.tempcount; i++) {
      writebuf[i] = data->state.tempwrite[i];
      Curl_dyn_init(&data->state.tempwrite[i].b, DYN_PAUSE_BUFFER);
    }
    data->state.tempcount = 0;

    for(i = 0; i < count; i++) {
      /* even if one function returns error, this loops through and frees
         all buffers */
      if(!result)
        result = chop_write(data, writebuf[i].type,
                            !writebuf[i].paused_body,
                            Curl_dyn_ptr(&writebuf[i].b),
                            Curl_dyn_len(&writebuf[i].b));
      Curl_dyn_free(&writebuf[i].b);
    }
  }
  return result;
}

void Curl_client_cleanup(struct Curl_easy *data)
{
  struct Curl_cwriter *writer = data->req.writer_stack;
  size_t i;

  while(writer) {
    data->req.writer_stack = writer->next;
    writer->cwt->do_close(data, writer);
    free(writer);
    writer = data->req.writer_stack;
  }

  for(i = 0; i < data->state.tempcount; i++) {
    Curl_dyn_free(&data->state.tempwrite[i].b);
  }
  data->state.tempcount = 0;
  data->req.bytecount = 0;
  data->req.headerline = 0;
}

/* Write data using an unencoding writer stack. "nbytes" is not
   allowed to be 0. */
CURLcode Curl_cwriter_write(struct Curl_easy *data,
                             struct Curl_cwriter *writer, int type,
                             const char *buf, size_t nbytes)
{
  if(!writer)
    return CURLE_WRITE_ERROR;
  return writer->cwt->do_write(data, writer, type, buf, nbytes);
}

CURLcode Curl_cwriter_def_init(struct Curl_easy *data,
                               struct Curl_cwriter *writer)
{
  (void)data;
  (void)writer;
  return CURLE_OK;
}

CURLcode Curl_cwriter_def_write(struct Curl_easy *data,
                                struct Curl_cwriter *writer, int type,
                                const char *buf, size_t nbytes)
{
  return Curl_cwriter_write(data, writer->next, type, buf, nbytes);
}

void Curl_cwriter_def_close(struct Curl_easy *data,
                            struct Curl_cwriter *writer)
{
  (void) data;
  (void) writer;
}

/* Real client writer to installed callbacks. */
static CURLcode cw_client_write(struct Curl_easy *data,
                                struct Curl_cwriter *writer, int type,
                                const char *buf, size_t nbytes)
{
  (void)writer;
  if(!nbytes)
    return CURLE_OK;
  return chop_write(data, type, FALSE, (char *)buf, nbytes);
}

static const struct Curl_cwtype cw_client = {
  "client",
  NULL,
  Curl_cwriter_def_init,
  cw_client_write,
  Curl_cwriter_def_close,
  sizeof(struct Curl_cwriter)
};

static size_t get_max_body_write_len(struct Curl_easy *data, curl_off_t limit)
{
  if(limit != -1) {
    /* How much more are we allowed to write? */
    curl_off_t remain_diff;
    remain_diff = limit - data->req.bytecount;
    if(remain_diff < 0) {
      /* already written too much! */
      return 0;
    }
#if SIZEOF_CURL_OFF_T > SIZEOF_SIZE_T
    else if(remain_diff > SSIZE_T_MAX) {
      return SIZE_T_MAX;
    }
#endif
    else {
      return (size_t)remain_diff;
    }
  }
  return SIZE_T_MAX;
}

/* Download client writer in phase CURL_CW_PROTOCOL that
 * sees the "real" download body data. */
static CURLcode cw_download_write(struct Curl_easy *data,
                                  struct Curl_cwriter *writer, int type,
                                  const char *buf, size_t nbytes)
{
  CURLcode result;
  size_t nwrite, excess_len = 0;

  if(!(type & CLIENTWRITE_BODY)) {
    if((type & CLIENTWRITE_CONNECT) && data->set.suppress_connect_headers)
      return CURLE_OK;
    return Curl_cwriter_write(data, writer->next, type, buf, nbytes);
  }

  if(!data->req.bytecount) {
    Curl_pgrsTime(data, TIMER_STARTTRANSFER);
    if(data->req.exp100 > EXP100_SEND_DATA)
      /* set time stamp to compare with when waiting for the 100 */
      data->req.start100 = Curl_now();
  }

  /* Here, we deal with REAL BODY bytes. All filtering and transfer
   * encodings have been applied and only the true content, e.g. BODY,
   * bytes are passed here.
   * This allows us to check sizes, update stats, etc. independent
   * from the protocol in play. */

  if(data->req.no_body && nbytes > 0) {
    /* BODY arrives although we want none, bail out */
    streamclose(data->conn, "ignoring body");
    DEBUGF(infof(data, "did not want a BODY, but seeing %zu bytes",
                 nbytes));
    data->req.download_done = TRUE;
    return CURLE_WEIRD_SERVER_REPLY;
  }

  /* Determine if we see any bytes in excess to what is allowed.
   * We write the allowed bytes and handle excess further below.
   * This gives deterministic BODY writes on varying buffer receive
   * lengths. */
  nwrite = nbytes;
  if(-1 != data->req.maxdownload) {
    size_t wmax = get_max_body_write_len(data, data->req.maxdownload);
    if(nwrite > wmax) {
      excess_len = nbytes - wmax;
      nwrite = wmax;
    }

    if(nwrite == wmax) {
      data->req.download_done = TRUE;
    }
  }

  /* Error on too large filesize is handled below, after writing
   * the permitted bytes */
  if(data->set.max_filesize) {
    size_t wmax = get_max_body_write_len(data, data->set.max_filesize);
    if(nwrite > wmax) {
      nwrite = wmax;
    }
  }

  /* Update stats, write and report progress */
  data->req.bytecount += nwrite;
  ++data->req.bodywrites;
  if(!data->req.ignorebody && nwrite) {
    result = Curl_cwriter_write(data, writer->next, type, buf, nwrite);
    if(result)
      return result;
  }
  result = Curl_pgrsSetDownloadCounter(data, data->req.bytecount);
  if(result)
    return result;

  if(excess_len) {
    if(!data->req.ignorebody) {
      infof(data,
            "Excess found writing body:"
            " excess = %zu"
            ", size = %" CURL_FORMAT_CURL_OFF_T
            ", maxdownload = %" CURL_FORMAT_CURL_OFF_T
            ", bytecount = %" CURL_FORMAT_CURL_OFF_T,
            excess_len, data->req.size, data->req.maxdownload,
            data->req.bytecount);
      connclose(data->conn, "excess found in a read");
    }
  }
  else if(nwrite < nbytes) {
    failf(data, "Exceeded the maximum allowed file size "
          "(%" CURL_FORMAT_CURL_OFF_T ") with %"
          CURL_FORMAT_CURL_OFF_T " bytes",
          data->set.max_filesize, data->req.bytecount);
    return CURLE_FILESIZE_EXCEEDED;
  }

  return CURLE_OK;
}

static const struct Curl_cwtype cw_download = {
  "download",
  NULL,
  Curl_cwriter_def_init,
  cw_download_write,
  Curl_cwriter_def_close,
  sizeof(struct Curl_cwriter)
};

/* RAW client writer in phase CURL_CW_RAW that
 * enabled tracing of raw data. */
static CURLcode cw_raw_write(struct Curl_easy *data,
                             struct Curl_cwriter *writer, int type,
                             const char *buf, size_t nbytes)
{
  if(type & CLIENTWRITE_BODY && data->set.verbose && !data->req.ignorebody) {
    Curl_debug(data, CURLINFO_DATA_IN, (char *)buf, nbytes);
  }
  return Curl_cwriter_write(data, writer->next, type, buf, nbytes);
}

static const struct Curl_cwtype cw_raw = {
  "raw",
  NULL,
  Curl_cwriter_def_init,
  cw_raw_write,
  Curl_cwriter_def_close,
  sizeof(struct Curl_cwriter)
};

/* Create an unencoding writer stage using the given handler. */
CURLcode Curl_cwriter_create(struct Curl_cwriter **pwriter,
                                   struct Curl_easy *data,
                                   const struct Curl_cwtype *cwt,
                                   Curl_cwriter_phase phase)
{
  struct Curl_cwriter *writer;
  CURLcode result = CURLE_OUT_OF_MEMORY;

  DEBUGASSERT(cwt->cwriter_size >= sizeof(struct Curl_cwriter));
  writer = (struct Curl_cwriter *) calloc(1, cwt->cwriter_size);
  if(!writer)
    goto out;

  writer->cwt = cwt;
  writer->phase = phase;
  result = cwt->do_init(data, writer);

out:
  *pwriter = result? NULL : writer;
  if(result)
    free(writer);
  return result;
}

void Curl_cwriter_free(struct Curl_easy *data,
                             struct Curl_cwriter *writer)
{
  if(writer) {
    writer->cwt->do_close(data, writer);
    free(writer);
  }
}

size_t Curl_cwriter_count(struct Curl_easy *data, Curl_cwriter_phase phase)
{
  struct Curl_cwriter *w;
  size_t n = 0;

  for(w = data->req.writer_stack; w; w = w->next) {
    if(w->phase == phase)
      ++n;
  }
  return n;
}

static CURLcode do_init_stack(struct Curl_easy *data)
{
  struct Curl_cwriter *writer;
  CURLcode result;

  DEBUGASSERT(!data->req.writer_stack);
  result = Curl_cwriter_create(&data->req.writer_stack,
                               data, &cw_client, CURL_CW_CLIENT);
  if(result)
    return result;

  result = Curl_cwriter_create(&writer, data, &cw_download, CURL_CW_PROTOCOL);
  if(result)
    return result;
  result = Curl_cwriter_add(data, writer);
  if(result) {
    Curl_cwriter_free(data, writer);
  }

  result = Curl_cwriter_create(&writer, data, &cw_raw, CURL_CW_RAW);
  if(result)
    return result;
  result = Curl_cwriter_add(data, writer);
  if(result) {
    Curl_cwriter_free(data, writer);
  }
  return result;
}

CURLcode Curl_cwriter_add(struct Curl_easy *data,
                          struct Curl_cwriter *writer)
{
  CURLcode result;
  struct Curl_cwriter **anchor = &data->req.writer_stack;

  if(!*anchor) {
    result = do_init_stack(data);
    if(result)
      return result;
  }

  /* Insert the writer as first in its phase.
   * Skip existing writers of lower phases. */
  while(*anchor && (*anchor)->phase < writer->phase)
    anchor = &((*anchor)->next);
  writer->next = *anchor;
  *anchor = writer;
  return CURLE_OK;
}

void Curl_cwriter_remove_by_name(struct Curl_easy *data,
                                 const char *name)
{
  struct Curl_cwriter **anchor = &data->req.writer_stack;

  while(*anchor) {
    if(!strcmp(name, (*anchor)->cwt->name)) {
      struct Curl_cwriter *w = (*anchor);
      *anchor = w->next;
      Curl_cwriter_free(data, w);
      continue;
    }
    anchor = &((*anchor)->next);
  }
}

/*
 * 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 Curl_easy *data,   /* transfer */
                   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 connectdata *conn = data->conn;

  /* 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](data, num, buffertofill, bytesfromsocket, &result);
  if(nread < 0)
    goto out;

  *n += nread;
  result = CURLE_OK;
out:
  return result;
}
