Home | History | Annotate | Download | only in lib
      1 /***************************************************************************
      2  *                                  _   _ ____  _
      3  *  Project                     ___| | | |  _ \| |
      4  *                             / __| | | | |_) | |
      5  *                            | (__| |_| |  _ <| |___
      6  *                             \___|\___/|_| \_\_____|
      7  *
      8  * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel (at) haxx.se>, et al.
      9  *
     10  * This software is licensed as described in the file COPYING, which
     11  * you should have received as part of this distribution. The terms
     12  * are also available at https://curl.haxx.se/docs/copyright.html.
     13  *
     14  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
     15  * copies of the Software, and permit persons to whom the Software is
     16  * furnished to do so, under the terms of the COPYING file.
     17  *
     18  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
     19  * KIND, either express or implied.
     20  *
     21  ***************************************************************************/
     22 
     23 #include "curl_setup.h"
     24 
     25 #ifdef HAVE_NETINET_IN_H
     26 #include <netinet/in.h>
     27 #endif
     28 
     29 #ifdef HAVE_LINUX_TCP_H
     30 #include <linux/tcp.h>
     31 #endif
     32 
     33 #include <curl/curl.h>
     34 
     35 #include "urldata.h"
     36 #include "sendf.h"
     37 #include "connect.h"
     38 #include "vtls/vtls.h"
     39 #include "ssh.h"
     40 #include "easyif.h"
     41 #include "multiif.h"
     42 #include "non-ascii.h"
     43 #include "strerror.h"
     44 #include "select.h"
     45 #include "strdup.h"
     46 
     47 /* The last 3 #include files should be in this order */
     48 #include "curl_printf.h"
     49 #include "curl_memory.h"
     50 #include "memdebug.h"
     51 
     52 #ifdef CURL_DO_LINEEND_CONV
     53 /*
     54  * convert_lineends() changes CRLF (\r\n) end-of-line markers to a single LF
     55  * (\n), with special processing for CRLF sequences that are split between two
     56  * blocks of data.  Remaining, bare CRs are changed to LFs.  The possibly new
     57  * size of the data is returned.
     58  */
     59 static size_t convert_lineends(struct Curl_easy *data,
     60                                char *startPtr, size_t size)
     61 {
     62   char *inPtr, *outPtr;
     63 
     64   /* sanity check */
     65   if((startPtr == NULL) || (size < 1)) {
     66     return size;
     67   }
     68 
     69   if(data->state.prev_block_had_trailing_cr) {
     70     /* The previous block of incoming data
     71        had a trailing CR, which was turned into a LF. */
     72     if(*startPtr == '\n') {
     73       /* This block of incoming data starts with the
     74          previous block's LF so get rid of it */
     75       memmove(startPtr, startPtr + 1, size-1);
     76       size--;
     77       /* and it wasn't a bare CR but a CRLF conversion instead */
     78       data->state.crlf_conversions++;
     79     }
     80     data->state.prev_block_had_trailing_cr = FALSE; /* reset the flag */
     81   }
     82 
     83   /* find 1st CR, if any */
     84   inPtr = outPtr = memchr(startPtr, '\r', size);
     85   if(inPtr) {
     86     /* at least one CR, now look for CRLF */
     87     while(inPtr < (startPtr + size-1)) {
     88       /* note that it's size-1, so we'll never look past the last byte */
     89       if(memcmp(inPtr, "\r\n", 2) == 0) {
     90         /* CRLF found, bump past the CR and copy the NL */
     91         inPtr++;
     92         *outPtr = *inPtr;
     93         /* keep track of how many CRLFs we converted */
     94         data->state.crlf_conversions++;
     95       }
     96       else {
     97         if(*inPtr == '\r') {
     98           /* lone CR, move LF instead */
     99           *outPtr = '\n';
    100         }
    101         else {
    102           /* not a CRLF nor a CR, just copy whatever it is */
    103           *outPtr = *inPtr;
    104         }
    105       }
    106       outPtr++;
    107       inPtr++;
    108     } /* end of while loop */
    109 
    110     if(inPtr < startPtr + size) {
    111       /* handle last byte */
    112       if(*inPtr == '\r') {
    113         /* deal with a CR at the end of the buffer */
    114         *outPtr = '\n'; /* copy a NL instead */
    115         /* note that a CRLF might be split across two blocks */
    116         data->state.prev_block_had_trailing_cr = TRUE;
    117       }
    118       else {
    119         /* copy last byte */
    120         *outPtr = *inPtr;
    121       }
    122       outPtr++;
    123     }
    124     if(outPtr < startPtr + size)
    125       /* tidy up by null terminating the now shorter data */
    126       *outPtr = '\0';
    127 
    128     return (outPtr - startPtr);
    129   }
    130   return size;
    131 }
    132 #endif /* CURL_DO_LINEEND_CONV */
    133 
    134 #ifdef USE_RECV_BEFORE_SEND_WORKAROUND
    135 bool Curl_recv_has_postponed_data(struct connectdata *conn, int sockindex)
    136 {
    137   struct postponed_data * const psnd = &(conn->postponed[sockindex]);
    138   return psnd->buffer && psnd->allocated_size &&
    139          psnd->recv_size > psnd->recv_processed;
    140 }
    141 
    142 static void pre_receive_plain(struct connectdata *conn, int num)
    143 {
    144   const curl_socket_t sockfd = conn->sock[num];
    145   struct postponed_data * const psnd = &(conn->postponed[num]);
    146   size_t bytestorecv = psnd->allocated_size - psnd->recv_size;
    147   /* WinSock will destroy unread received data if send() is
    148      failed.
    149      To avoid lossage of received data, recv() must be
    150      performed before every send() if any incoming data is
    151      available. However, skip this, if buffer is already full. */
    152   if((conn->handler->protocol&PROTO_FAMILY_HTTP) != 0 &&
    153      conn->recv[num] == Curl_recv_plain &&
    154      (!psnd->buffer || bytestorecv)) {
    155     const int readymask = Curl_socket_check(sockfd, CURL_SOCKET_BAD,
    156                                             CURL_SOCKET_BAD, 0);
    157     if(readymask != -1 && (readymask & CURL_CSELECT_IN) != 0) {
    158       /* Have some incoming data */
    159       if(!psnd->buffer) {
    160         /* Use buffer double default size for intermediate buffer */
    161         psnd->allocated_size = 2 * conn->data->set.buffer_size;
    162         psnd->buffer = malloc(psnd->allocated_size);
    163         psnd->recv_size = 0;
    164         psnd->recv_processed = 0;
    165 #ifdef DEBUGBUILD
    166         psnd->bindsock = sockfd; /* Used only for DEBUGASSERT */
    167 #endif /* DEBUGBUILD */
    168         bytestorecv = psnd->allocated_size;
    169       }
    170       if(psnd->buffer) {
    171         ssize_t recvedbytes;
    172         DEBUGASSERT(psnd->bindsock == sockfd);
    173         recvedbytes = sread(sockfd, psnd->buffer + psnd->recv_size,
    174                             bytestorecv);
    175         if(recvedbytes > 0)
    176           psnd->recv_size += recvedbytes;
    177       }
    178       else
    179         psnd->allocated_size = 0;
    180     }
    181   }
    182 }
    183 
    184 static ssize_t get_pre_recved(struct connectdata *conn, int num, char *buf,
    185                               size_t len)
    186 {
    187   struct postponed_data * const psnd = &(conn->postponed[num]);
    188   size_t copysize;
    189   if(!psnd->buffer)
    190     return 0;
    191 
    192   DEBUGASSERT(psnd->allocated_size > 0);
    193   DEBUGASSERT(psnd->recv_size <= psnd->allocated_size);
    194   DEBUGASSERT(psnd->recv_processed <= psnd->recv_size);
    195   /* Check and process data that already received and storied in internal
    196      intermediate buffer */
    197   if(psnd->recv_size > psnd->recv_processed) {
    198     DEBUGASSERT(psnd->bindsock == conn->sock[num]);
    199     copysize = CURLMIN(len, psnd->recv_size - psnd->recv_processed);
    200     memcpy(buf, psnd->buffer + psnd->recv_processed, copysize);
    201     psnd->recv_processed += copysize;
    202   }
    203   else
    204     copysize = 0; /* buffer was allocated, but nothing was received */
    205 
    206   /* Free intermediate buffer if it has no unprocessed data */
    207   if(psnd->recv_processed == psnd->recv_size) {
    208     free(psnd->buffer);
    209     psnd->buffer = NULL;
    210     psnd->allocated_size = 0;
    211     psnd->recv_size = 0;
    212     psnd->recv_processed = 0;
    213 #ifdef DEBUGBUILD
    214     psnd->bindsock = CURL_SOCKET_BAD;
    215 #endif /* DEBUGBUILD */
    216   }
    217   return (ssize_t)copysize;
    218 }
    219 #else  /* ! USE_RECV_BEFORE_SEND_WORKAROUND */
    220 /* Use "do-nothing" macros instead of functions when workaround not used */
    221 bool Curl_recv_has_postponed_data(struct connectdata *conn, int sockindex)
    222 {
    223   (void)conn;
    224   (void)sockindex;
    225   return false;
    226 }
    227 #define pre_receive_plain(c,n) do {} WHILE_FALSE
    228 #define get_pre_recved(c,n,b,l) 0
    229 #endif /* ! USE_RECV_BEFORE_SEND_WORKAROUND */
    230 
    231 /* Curl_infof() is for info message along the way */
    232 
    233 void Curl_infof(struct Curl_easy *data, const char *fmt, ...)
    234 {
    235   if(data && data->set.verbose) {
    236     va_list ap;
    237     size_t len;
    238     char print_buffer[2048 + 1];
    239     va_start(ap, fmt);
    240     len = mvsnprintf(print_buffer, sizeof(print_buffer), fmt, ap);
    241     /*
    242      * Indicate truncation of the input by replacing the last 3 characters
    243      * with "...", and transfer the newline over in case the format had one.
    244      */
    245     if(len >= sizeof(print_buffer)) {
    246       len = strlen(fmt);
    247       if(fmt[--len] == '\n')
    248         msnprintf(print_buffer + (sizeof(print_buffer) - 5), 5, "...\n");
    249       else
    250         msnprintf(print_buffer + (sizeof(print_buffer) - 4), 4, "...");
    251     }
    252     va_end(ap);
    253     len = strlen(print_buffer);
    254     Curl_debug(data, CURLINFO_TEXT, print_buffer, len);
    255   }
    256 }
    257 
    258 /* Curl_failf() is for messages stating why we failed.
    259  * The message SHALL NOT include any LF or CR.
    260  */
    261 
    262 void Curl_failf(struct Curl_easy *data, const char *fmt, ...)
    263 {
    264   if(data->set.verbose || data->set.errorbuffer) {
    265     va_list ap;
    266     size_t len;
    267     char error[CURL_ERROR_SIZE + 2];
    268     va_start(ap, fmt);
    269     mvsnprintf(error, CURL_ERROR_SIZE, fmt, ap);
    270     len = strlen(error);
    271 
    272     if(data->set.errorbuffer && !data->state.errorbuf) {
    273       strcpy(data->set.errorbuffer, error);
    274       data->state.errorbuf = TRUE; /* wrote error string */
    275     }
    276     if(data->set.verbose) {
    277       error[len] = '\n';
    278       error[++len] = '\0';
    279       Curl_debug(data, CURLINFO_TEXT, error, len);
    280     }
    281     va_end(ap);
    282   }
    283 }
    284 
    285 /* Curl_sendf() sends formatted data to the server */
    286 CURLcode Curl_sendf(curl_socket_t sockfd, struct connectdata *conn,
    287                     const char *fmt, ...)
    288 {
    289   struct Curl_easy *data = conn->data;
    290   ssize_t bytes_written;
    291   size_t write_len;
    292   CURLcode result = CURLE_OK;
    293   char *s;
    294   char *sptr;
    295   va_list ap;
    296   va_start(ap, fmt);
    297   s = vaprintf(fmt, ap); /* returns an allocated string */
    298   va_end(ap);
    299   if(!s)
    300     return CURLE_OUT_OF_MEMORY; /* failure */
    301 
    302   bytes_written = 0;
    303   write_len = strlen(s);
    304   sptr = s;
    305 
    306   for(;;) {
    307     /* Write the buffer to the socket */
    308     result = Curl_write(conn, sockfd, sptr, write_len, &bytes_written);
    309 
    310     if(result)
    311       break;
    312 
    313     if(data->set.verbose)
    314       Curl_debug(data, CURLINFO_DATA_OUT, sptr, (size_t)bytes_written);
    315 
    316     if((size_t)bytes_written != write_len) {
    317       /* if not all was written at once, we must advance the pointer, decrease
    318          the size left and try again! */
    319       write_len -= bytes_written;
    320       sptr += bytes_written;
    321     }
    322     else
    323       break;
    324   }
    325 
    326   free(s); /* free the output string */
    327 
    328   return result;
    329 }
    330 
    331 /*
    332  * Curl_write() is an internal write function that sends data to the
    333  * server. Works with plain sockets, SCP, SSL or kerberos.
    334  *
    335  * If the write would block (CURLE_AGAIN), we return CURLE_OK and
    336  * (*written == 0). Otherwise we return regular CURLcode value.
    337  */
    338 CURLcode Curl_write(struct connectdata *conn,
    339                     curl_socket_t sockfd,
    340                     const void *mem,
    341                     size_t len,
    342                     ssize_t *written)
    343 {
    344   ssize_t bytes_written;
    345   CURLcode result = CURLE_OK;
    346   int num = (sockfd == conn->sock[SECONDARYSOCKET]);
    347 
    348   bytes_written = conn->send[num](conn, num, mem, len, &result);
    349 
    350   *written = bytes_written;
    351   if(bytes_written >= 0)
    352     /* we completely ignore the curlcode value when subzero is not returned */
    353     return CURLE_OK;
    354 
    355   /* handle CURLE_AGAIN or a send failure */
    356   switch(result) {
    357   case CURLE_AGAIN:
    358     *written = 0;
    359     return CURLE_OK;
    360 
    361   case CURLE_OK:
    362     /* general send failure */
    363     return CURLE_SEND_ERROR;
    364 
    365   default:
    366     /* we got a specific curlcode, forward it */
    367     return result;
    368   }
    369 }
    370 
    371 ssize_t Curl_send_plain(struct connectdata *conn, int num,
    372                         const void *mem, size_t len, CURLcode *code)
    373 {
    374   curl_socket_t sockfd = conn->sock[num];
    375   ssize_t bytes_written;
    376   /* WinSock will destroy unread received data if send() is
    377      failed.
    378      To avoid lossage of received data, recv() must be
    379      performed before every send() if any incoming data is
    380      available. */
    381   pre_receive_plain(conn, num);
    382 
    383 #if defined(MSG_FASTOPEN) && !defined(TCP_FASTOPEN_CONNECT) /* Linux */
    384   if(conn->bits.tcp_fastopen) {
    385     bytes_written = sendto(sockfd, mem, len, MSG_FASTOPEN,
    386                            conn->ip_addr->ai_addr, conn->ip_addr->ai_addrlen);
    387     conn->bits.tcp_fastopen = FALSE;
    388   }
    389   else
    390 #endif
    391     bytes_written = swrite(sockfd, mem, len);
    392 
    393   *code = CURLE_OK;
    394   if(-1 == bytes_written) {
    395     int err = SOCKERRNO;
    396 
    397     if(
    398 #ifdef WSAEWOULDBLOCK
    399       /* This is how Windows does it */
    400       (WSAEWOULDBLOCK == err)
    401 #else
    402       /* errno may be EWOULDBLOCK or on some systems EAGAIN when it returned
    403          due to its inability to send off data without blocking. We therefore
    404          treat both error codes the same here */
    405       (EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err) ||
    406       (EINPROGRESS == err)
    407 #endif
    408       ) {
    409       /* this is just a case of EWOULDBLOCK */
    410       bytes_written = 0;
    411       *code = CURLE_AGAIN;
    412     }
    413     else {
    414       char buffer[STRERROR_LEN];
    415       failf(conn->data, "Send failure: %s",
    416             Curl_strerror(err, buffer, sizeof(buffer)));
    417       conn->data->state.os_errno = err;
    418       *code = CURLE_SEND_ERROR;
    419     }
    420   }
    421   return bytes_written;
    422 }
    423 
    424 /*
    425  * Curl_write_plain() is an internal write function that sends data to the
    426  * server using plain sockets only. Otherwise meant to have the exact same
    427  * proto as Curl_write()
    428  */
    429 CURLcode Curl_write_plain(struct connectdata *conn,
    430                           curl_socket_t sockfd,
    431                           const void *mem,
    432                           size_t len,
    433                           ssize_t *written)
    434 {
    435   ssize_t bytes_written;
    436   CURLcode result;
    437   int num = (sockfd == conn->sock[SECONDARYSOCKET]);
    438 
    439   bytes_written = Curl_send_plain(conn, num, mem, len, &result);
    440 
    441   *written = bytes_written;
    442 
    443   return result;
    444 }
    445 
    446 ssize_t Curl_recv_plain(struct connectdata *conn, int num, char *buf,
    447                         size_t len, CURLcode *code)
    448 {
    449   curl_socket_t sockfd = conn->sock[num];
    450   ssize_t nread;
    451   /* Check and return data that already received and storied in internal
    452      intermediate buffer */
    453   nread = get_pre_recved(conn, num, buf, len);
    454   if(nread > 0) {
    455     *code = CURLE_OK;
    456     return nread;
    457   }
    458 
    459   nread = sread(sockfd, buf, len);
    460 
    461   *code = CURLE_OK;
    462   if(-1 == nread) {
    463     int err = SOCKERRNO;
    464 
    465     if(
    466 #ifdef WSAEWOULDBLOCK
    467       /* This is how Windows does it */
    468       (WSAEWOULDBLOCK == err)
    469 #else
    470       /* errno may be EWOULDBLOCK or on some systems EAGAIN when it returned
    471          due to its inability to send off data without blocking. We therefore
    472          treat both error codes the same here */
    473       (EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err)
    474 #endif
    475       ) {
    476       /* this is just a case of EWOULDBLOCK */
    477       *code = CURLE_AGAIN;
    478     }
    479     else {
    480       char buffer[STRERROR_LEN];
    481       failf(conn->data, "Recv failure: %s",
    482             Curl_strerror(err, buffer, sizeof(buffer)));
    483       conn->data->state.os_errno = err;
    484       *code = CURLE_RECV_ERROR;
    485     }
    486   }
    487   return nread;
    488 }
    489 
    490 static CURLcode pausewrite(struct Curl_easy *data,
    491                            int type, /* what type of data */
    492                            const char *ptr,
    493                            size_t len)
    494 {
    495   /* signalled to pause sending on this connection, but since we have data
    496      we want to send we need to dup it to save a copy for when the sending
    497      is again enabled */
    498   struct SingleRequest *k = &data->req;
    499   struct UrlState *s = &data->state;
    500   char *dupl;
    501   unsigned int i;
    502   bool newtype = TRUE;
    503 
    504   if(s->tempcount) {
    505     for(i = 0; i< s->tempcount; i++) {
    506       if(s->tempwrite[i].type == type) {
    507         /* data for this type exists */
    508         newtype = FALSE;
    509         break;
    510       }
    511     }
    512     DEBUGASSERT(i < 3);
    513   }
    514   else
    515     i = 0;
    516 
    517   if(!newtype) {
    518     /* append new data to old data */
    519 
    520     /* figure out the new size of the data to save */
    521     size_t newlen = len + s->tempwrite[i].len;
    522     /* allocate the new memory area */
    523     char *newptr = realloc(s->tempwrite[i].buf, newlen);
    524     if(!newptr)
    525       return CURLE_OUT_OF_MEMORY;
    526     /* copy the new data to the end of the new area */
    527     memcpy(newptr + s->tempwrite[i].len, ptr, len);
    528 
    529     /* update the pointer and the size */
    530     s->tempwrite[i].buf = newptr;
    531     s->tempwrite[i].len = newlen;
    532   }
    533   else {
    534     dupl = Curl_memdup(ptr, len);
    535     if(!dupl)
    536       return CURLE_OUT_OF_MEMORY;
    537 
    538     /* store this information in the state struct for later use */
    539     s->tempwrite[i].buf = dupl;
    540     s->tempwrite[i].len = len;
    541     s->tempwrite[i].type = type;
    542 
    543     if(newtype)
    544       s->tempcount++;
    545   }
    546 
    547   /* mark the connection as RECV paused */
    548   k->keepon |= KEEP_RECV_PAUSE;
    549 
    550   DEBUGF(infof(data, "Paused %zu bytes in buffer for type %02x\n",
    551                len, type));
    552 
    553   return CURLE_OK;
    554 }
    555 
    556 
    557 /* chop_write() writes chunks of data not larger than CURL_MAX_WRITE_SIZE via
    558  * client write callback(s) and takes care of pause requests from the
    559  * callbacks.
    560  */
    561 static CURLcode chop_write(struct connectdata *conn,
    562                            int type,
    563                            char *optr,
    564                            size_t olen)
    565 {
    566   struct Curl_easy *data = conn->data;
    567   curl_write_callback writeheader = NULL;
    568   curl_write_callback writebody = NULL;
    569   char *ptr = optr;
    570   size_t len = olen;
    571 
    572   if(!len)
    573     return CURLE_OK;
    574 
    575   /* If reading is paused, append this data to the already held data for this
    576      type. */
    577   if(data->req.keepon & KEEP_RECV_PAUSE)
    578     return pausewrite(data, type, ptr, len);
    579 
    580   /* Determine the callback(s) to use. */
    581   if(type & CLIENTWRITE_BODY)
    582     writebody = data->set.fwrite_func;
    583   if((type & CLIENTWRITE_HEADER) &&
    584      (data->set.fwrite_header || data->set.writeheader)) {
    585     /*
    586      * Write headers to the same callback or to the especially setup
    587      * header callback function (added after version 7.7.1).
    588      */
    589     writeheader =
    590       data->set.fwrite_header? data->set.fwrite_header: data->set.fwrite_func;
    591   }
    592 
    593   /* Chop data, write chunks. */
    594   while(len) {
    595     size_t chunklen = len <= CURL_MAX_WRITE_SIZE? len: CURL_MAX_WRITE_SIZE;
    596 
    597     if(writebody) {
    598       size_t wrote = writebody(ptr, 1, chunklen, data->set.out);
    599 
    600       if(CURL_WRITEFUNC_PAUSE == wrote) {
    601         if(conn->handler->flags & PROTOPT_NONETWORK) {
    602           /* Protocols that work without network cannot be paused. This is
    603              actually only FILE:// just now, and it can't pause since the
    604              transfer isn't done using the "normal" procedure. */
    605           failf(data, "Write callback asked for PAUSE when not supported!");
    606           return CURLE_WRITE_ERROR;
    607         }
    608         return pausewrite(data, type, ptr, len);
    609       }
    610       if(wrote != chunklen) {
    611         failf(data, "Failed writing body (%zu != %zu)", wrote, chunklen);
    612         return CURLE_WRITE_ERROR;
    613       }
    614     }
    615 
    616     ptr += chunklen;
    617     len -= chunklen;
    618   }
    619 
    620   if(writeheader) {
    621     size_t wrote;
    622     ptr = optr;
    623     len = olen;
    624     Curl_set_in_callback(data, true);
    625     wrote = writeheader(ptr, 1, len, data->set.writeheader);
    626     Curl_set_in_callback(data, false);
    627 
    628     if(CURL_WRITEFUNC_PAUSE == wrote)
    629       /* here we pass in the HEADER bit only since if this was body as well
    630          then it was passed already and clearly that didn't trigger the
    631          pause, so this is saved for later with the HEADER bit only */
    632       return pausewrite(data, CLIENTWRITE_HEADER, ptr, len);
    633 
    634     if(wrote != len) {
    635       failf(data, "Failed writing header");
    636       return CURLE_WRITE_ERROR;
    637     }
    638   }
    639 
    640   return CURLE_OK;
    641 }
    642 
    643 
    644 /* Curl_client_write() sends data to the write callback(s)
    645 
    646    The bit pattern defines to what "streams" to write to. Body and/or header.
    647    The defines are in sendf.h of course.
    648 
    649    If CURL_DO_LINEEND_CONV is enabled, data is converted IN PLACE to the
    650    local character encoding.  This is a problem and should be changed in
    651    the future to leave the original data alone.
    652  */
    653 CURLcode Curl_client_write(struct connectdata *conn,
    654                            int type,
    655                            char *ptr,
    656                            size_t len)
    657 {
    658   struct Curl_easy *data = conn->data;
    659 
    660   if(0 == len)
    661     len = strlen(ptr);
    662 
    663   DEBUGASSERT(type <= 3);
    664 
    665   /* FTP data may need conversion. */
    666   if((type & CLIENTWRITE_BODY) &&
    667     (conn->handler->protocol & PROTO_FAMILY_FTP) &&
    668     conn->proto.ftpc.transfertype == 'A') {
    669     /* convert from the network encoding */
    670     CURLcode result = Curl_convert_from_network(data, ptr, len);
    671     /* Curl_convert_from_network calls failf if unsuccessful */
    672     if(result)
    673       return result;
    674 
    675 #ifdef CURL_DO_LINEEND_CONV
    676     /* convert end-of-line markers */
    677     len = convert_lineends(data, ptr, len);
    678 #endif /* CURL_DO_LINEEND_CONV */
    679     }
    680 
    681   return chop_write(conn, type, ptr, len);
    682 }
    683 
    684 CURLcode Curl_read_plain(curl_socket_t sockfd,
    685                          char *buf,
    686                          size_t bytesfromsocket,
    687                          ssize_t *n)
    688 {
    689   ssize_t nread = sread(sockfd, buf, bytesfromsocket);
    690 
    691   if(-1 == nread) {
    692     int err = SOCKERRNO;
    693     int return_error;
    694 #ifdef USE_WINSOCK
    695     return_error = WSAEWOULDBLOCK == err;
    696 #else
    697     return_error = EWOULDBLOCK == err || EAGAIN == err || EINTR == err;
    698 #endif
    699     if(return_error)
    700       return CURLE_AGAIN;
    701     return CURLE_RECV_ERROR;
    702   }
    703 
    704   /* we only return number of bytes read when we return OK */
    705   *n = nread;
    706   return CURLE_OK;
    707 }
    708 
    709 /*
    710  * Internal read-from-socket function. This is meant to deal with plain
    711  * sockets, SSL sockets and kerberos sockets.
    712  *
    713  * Returns a regular CURLcode value.
    714  */
    715 CURLcode Curl_read(struct connectdata *conn, /* connection data */
    716                    curl_socket_t sockfd,     /* read from this socket */
    717                    char *buf,                /* store read data here */
    718                    size_t sizerequested,     /* max amount to read */
    719                    ssize_t *n)               /* amount bytes read */
    720 {
    721   CURLcode result = CURLE_RECV_ERROR;
    722   ssize_t nread = 0;
    723   size_t bytesfromsocket = 0;
    724   char *buffertofill = NULL;
    725   struct Curl_easy *data = conn->data;
    726 
    727   /* if HTTP/1 pipelining is both wanted and possible */
    728   bool pipelining = Curl_pipeline_wanted(data->multi, CURLPIPE_HTTP1) &&
    729     (conn->bundle->multiuse == BUNDLE_PIPELINING);
    730 
    731   /* Set 'num' to 0 or 1, depending on which socket that has been sent here.
    732      If it is the second socket, we set num to 1. Otherwise to 0. This lets
    733      us use the correct ssl handle. */
    734   int num = (sockfd == conn->sock[SECONDARYSOCKET]);
    735 
    736   *n = 0; /* reset amount to zero */
    737 
    738   /* If session can pipeline, check connection buffer  */
    739   if(pipelining) {
    740     size_t bytestocopy = CURLMIN(conn->buf_len - conn->read_pos,
    741                                  sizerequested);
    742 
    743     /* Copy from our master buffer first if we have some unread data there*/
    744     if(bytestocopy > 0) {
    745       memcpy(buf, conn->master_buffer + conn->read_pos, bytestocopy);
    746       conn->read_pos += bytestocopy;
    747       conn->bits.stream_was_rewound = FALSE;
    748 
    749       *n = (ssize_t)bytestocopy;
    750       return CURLE_OK;
    751     }
    752     /* If we come here, it means that there is no data to read from the buffer,
    753      * so we read from the socket */
    754     bytesfromsocket = CURLMIN(sizerequested, MASTERBUF_SIZE);
    755     buffertofill = conn->master_buffer;
    756   }
    757   else {
    758     bytesfromsocket = CURLMIN(sizerequested, (size_t)data->set.buffer_size);
    759     buffertofill = buf;
    760   }
    761 
    762   nread = conn->recv[num](conn, num, buffertofill, bytesfromsocket, &result);
    763   if(nread < 0)
    764     return result;
    765 
    766   if(pipelining) {
    767     memcpy(buf, conn->master_buffer, nread);
    768     conn->buf_len = nread;
    769     conn->read_pos = nread;
    770   }
    771 
    772   *n += nread;
    773 
    774   return CURLE_OK;
    775 }
    776 
    777 /* return 0 on success */
    778 int Curl_debug(struct Curl_easy *data, curl_infotype type,
    779                char *ptr, size_t size)
    780 {
    781   static const char s_infotype[CURLINFO_END][3] = {
    782     "* ", "< ", "> ", "{ ", "} ", "{ ", "} " };
    783   int rc = 0;
    784 
    785 #ifdef CURL_DOES_CONVERSIONS
    786   char *buf = NULL;
    787   size_t conv_size = 0;
    788 
    789   switch(type) {
    790   case CURLINFO_HEADER_OUT:
    791     buf = Curl_memdup(ptr, size);
    792     if(!buf)
    793       return 1;
    794     conv_size = size;
    795 
    796     /* Special processing is needed for this block if it
    797      * contains both headers and data (separated by CRLFCRLF).
    798      * We want to convert just the headers, leaving the data as-is.
    799      */
    800     if(size > 4) {
    801       size_t i;
    802       for(i = 0; i < size-4; i++) {
    803         if(memcmp(&buf[i], "\x0d\x0a\x0d\x0a", 4) == 0) {
    804           /* convert everything through this CRLFCRLF but no further */
    805           conv_size = i + 4;
    806           break;
    807         }
    808       }
    809     }
    810 
    811     Curl_convert_from_network(data, buf, conv_size);
    812     /* Curl_convert_from_network calls failf if unsuccessful */
    813     /* we might as well continue even if it fails...   */
    814     ptr = buf; /* switch pointer to use my buffer instead */
    815     break;
    816   default:
    817     /* leave everything else as-is */
    818     break;
    819   }
    820 #endif /* CURL_DOES_CONVERSIONS */
    821 
    822   if(data->set.fdebug) {
    823     Curl_set_in_callback(data, true);
    824     rc = (*data->set.fdebug)(data, type, ptr, size, data->set.debugdata);
    825     Curl_set_in_callback(data, false);
    826   }
    827   else {
    828     switch(type) {
    829     case CURLINFO_TEXT:
    830     case CURLINFO_HEADER_OUT:
    831     case CURLINFO_HEADER_IN:
    832       fwrite(s_infotype[type], 2, 1, data->set.err);
    833       fwrite(ptr, size, 1, data->set.err);
    834 #ifdef CURL_DOES_CONVERSIONS
    835       if(size != conv_size) {
    836         /* we had untranslated data so we need an explicit newline */
    837         fwrite("\n", 1, 1, data->set.err);
    838       }
    839 #endif
    840       break;
    841     default: /* nada */
    842       break;
    843     }
    844   }
    845 #ifdef CURL_DOES_CONVERSIONS
    846   free(buf);
    847 #endif
    848   return rc;
    849 }
    850