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