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