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