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