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


rc_tagdetect_client
Author(s): Monika Florek-Jasinska , Raphael Schaller
autogenerated on Sat Feb 13 2021 03:42:16