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