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#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 */
49static 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
125static 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
167static 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
210void 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
228void 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 */
253CURLcode 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 */
305CURLcode 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
338ssize_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 */
395CURLcode 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
412ssize_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
455static 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 */
489CURLcode 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 */
596CURLcode 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
625CURLcode 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 */
657CURLcode 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 */
721static 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
790int 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