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