b45e43a3235154e26be912ea462116ba9512b945
[platform/upstream/curl.git] / lib / sendf.c
1 /***************************************************************************
2  *                                  _   _ ____  _
3  *  Project                     ___| | | |  _ \| |
4  *                             / __| | | | |_) | |
5  *                            | (__| |_| |  _ <| |___
6  *                             \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 1998 - 2012, 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 http://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 "setup.h"
24
25 #include <curl/curl.h>
26
27 #include "urldata.h"
28 #include "sendf.h"
29 #include "connect.h"
30 #include "sslgen.h"
31 #include "ssh.h"
32 #include "multiif.h"
33 #include "non-ascii.h"
34
35 #define _MPRINTF_REPLACE /* use the internal *printf() functions */
36 #include <curl/mprintf.h>
37
38 /* the krb4 functions only exists for FTP and if krb4 or gssapi is defined */
39 #if !defined(CURL_DISABLE_FTP) && (defined(HAVE_KRB4) || defined(HAVE_GSSAPI))
40 #include "krb4.h"
41 #else
42 #define Curl_sec_send(a,b,c,d) -1
43 #define Curl_sec_read(a,b,c,d) -1
44 #endif
45
46 #include "curl_memory.h"
47 #include "strerror.h"
48
49 /* The last #include file should be: */
50 #include "memdebug.h"
51
52 #ifdef CURL_DO_LINEEND_CONV
53 /*
54  * convert_lineends() changes CRLF (\r\n) end-of-line markers to a single LF
55  * (\n), with special processing for CRLF sequences that are split between two
56  * blocks of data.  Remaining, bare CRs are changed to LFs.  The possibly new
57  * size of the data is returned.
58  */
59 static size_t convert_lineends(struct SessionHandle *data,
60                                char *startPtr, size_t size)
61 {
62   char *inPtr, *outPtr;
63
64   /* sanity check */
65   if((startPtr == NULL) || (size < 1)) {
66     return(size);
67   }
68
69   if(data->state.prev_block_had_trailing_cr) {
70     /* The previous block of incoming data
71        had a trailing CR, which was turned into a LF. */
72     if(*startPtr == '\n') {
73       /* This block of incoming data starts with the
74          previous block's LF so get rid of it */
75       memmove(startPtr, startPtr+1, size-1);
76       size--;
77       /* and it wasn't a bare CR but a CRLF conversion instead */
78       data->state.crlf_conversions++;
79     }
80     data->state.prev_block_had_trailing_cr = FALSE; /* reset the flag */
81   }
82
83   /* find 1st CR, if any */
84   inPtr = outPtr = memchr(startPtr, '\r', size);
85   if(inPtr) {
86     /* at least one CR, now look for CRLF */
87     while(inPtr < (startPtr+size-1)) {
88       /* note that it's size-1, so we'll never look past the last byte */
89       if(memcmp(inPtr, "\r\n", 2) == 0) {
90         /* CRLF found, bump past the CR and copy the NL */
91         inPtr++;
92         *outPtr = *inPtr;
93         /* keep track of how many CRLFs we converted */
94         data->state.crlf_conversions++;
95       }
96       else {
97         if(*inPtr == '\r') {
98           /* lone CR, move LF instead */
99           *outPtr = '\n';
100         }
101         else {
102           /* not a CRLF nor a CR, just copy whatever it is */
103           *outPtr = *inPtr;
104         }
105       }
106       outPtr++;
107       inPtr++;
108     } /* end of while loop */
109
110     if(inPtr < startPtr+size) {
111       /* handle last byte */
112       if(*inPtr == '\r') {
113         /* deal with a CR at the end of the buffer */
114         *outPtr = '\n'; /* copy a NL instead */
115         /* note that a CRLF might be split across two blocks */
116         data->state.prev_block_had_trailing_cr = TRUE;
117       }
118       else {
119         /* copy last byte */
120         *outPtr = *inPtr;
121       }
122       outPtr++;
123     }
124     if(outPtr < startPtr+size)
125       /* tidy up by null terminating the now shorter data */
126       *outPtr = '\0';
127
128     return(outPtr - startPtr);
129   }
130   return(size);
131 }
132 #endif /* CURL_DO_LINEEND_CONV */
133
134 /* Curl_infof() is for info message along the way */
135
136 void Curl_infof(struct SessionHandle *data, const char *fmt, ...)
137 {
138   if(data && data->set.verbose) {
139     va_list ap;
140     size_t len;
141     char print_buffer[2048 + 1];
142     va_start(ap, fmt);
143     vsnprintf(print_buffer, sizeof(print_buffer), fmt, ap);
144     va_end(ap);
145     len = strlen(print_buffer);
146     Curl_debug(data, CURLINFO_TEXT, print_buffer, len, NULL);
147   }
148 }
149
150 /* Curl_failf() is for messages stating why we failed.
151  * The message SHALL NOT include any LF or CR.
152  */
153
154 void Curl_failf(struct SessionHandle *data, const char *fmt, ...)
155 {
156   va_list ap;
157   size_t len;
158   va_start(ap, fmt);
159
160   vsnprintf(data->state.buffer, BUFSIZE, fmt, ap);
161
162   if(data->set.errorbuffer && !data->state.errorbuf) {
163     snprintf(data->set.errorbuffer, CURL_ERROR_SIZE, "%s", data->state.buffer);
164     data->state.errorbuf = TRUE; /* wrote error string */
165   }
166   if(data->set.verbose) {
167     len = strlen(data->state.buffer);
168     if(len < BUFSIZE - 1) {
169       data->state.buffer[len] = '\n';
170       data->state.buffer[++len] = '\0';
171     }
172     Curl_debug(data, CURLINFO_TEXT, data->state.buffer, len, NULL);
173   }
174
175   va_end(ap);
176 }
177
178 /* Curl_sendf() sends formated data to the server */
179 CURLcode Curl_sendf(curl_socket_t sockfd, struct connectdata *conn,
180                     const char *fmt, ...)
181 {
182   struct SessionHandle *data = conn->data;
183   ssize_t bytes_written;
184   size_t write_len;
185   CURLcode res = CURLE_OK;
186   char *s;
187   char *sptr;
188   va_list ap;
189   va_start(ap, fmt);
190   s = vaprintf(fmt, ap); /* returns an allocated string */
191   va_end(ap);
192   if(!s)
193     return CURLE_OUT_OF_MEMORY; /* failure */
194
195   bytes_written=0;
196   write_len = strlen(s);
197   sptr = s;
198
199   for(;;) {
200     /* Write the buffer to the socket */
201     res = Curl_write(conn, sockfd, sptr, write_len, &bytes_written);
202
203     if(CURLE_OK != res)
204       break;
205
206     if(data->set.verbose)
207       Curl_debug(data, CURLINFO_DATA_OUT, sptr, (size_t)bytes_written, conn);
208
209     if((size_t)bytes_written != write_len) {
210       /* if not all was written at once, we must advance the pointer, decrease
211          the size left and try again! */
212       write_len -= bytes_written;
213       sptr += bytes_written;
214     }
215     else
216       break;
217   }
218
219   free(s); /* free the output string */
220
221   return res;
222 }
223
224 /*
225  * Curl_write() is an internal write function that sends data to the
226  * server. Works with plain sockets, SCP, SSL or kerberos.
227  *
228  * If the write would block (CURLE_AGAIN), we return CURLE_OK and
229  * (*written == 0). Otherwise we return regular CURLcode value.
230  */
231 CURLcode Curl_write(struct connectdata *conn,
232                     curl_socket_t sockfd,
233                     const void *mem,
234                     size_t len,
235                     ssize_t *written)
236 {
237   ssize_t bytes_written;
238   CURLcode curlcode = CURLE_OK;
239   int num = (sockfd == conn->sock[SECONDARYSOCKET]);
240
241   bytes_written = conn->send[num](conn, num, mem, len, &curlcode);
242
243   *written = bytes_written;
244   if(bytes_written >= 0)
245     /* we completely ignore the curlcode value when subzero is not returned */
246     return CURLE_OK;
247
248   /* handle CURLE_AGAIN or a send failure */
249   switch(curlcode) {
250   case CURLE_AGAIN:
251     *written = 0;
252     return CURLE_OK;
253
254   case CURLE_OK:
255     /* general send failure */
256     return CURLE_SEND_ERROR;
257
258   default:
259     /* we got a specific curlcode, forward it */
260     return curlcode;
261   }
262 }
263
264 ssize_t Curl_send_plain(struct connectdata *conn, int num,
265                         const void *mem, size_t len, CURLcode *code)
266 {
267   curl_socket_t sockfd = conn->sock[num];
268   ssize_t bytes_written = swrite(sockfd, mem, len);
269
270   *code = CURLE_OK;
271   if(-1 == bytes_written) {
272     int err = SOCKERRNO;
273
274     if(
275 #ifdef WSAEWOULDBLOCK
276       /* This is how Windows does it */
277       (WSAEWOULDBLOCK == err)
278 #else
279       /* errno may be EWOULDBLOCK or on some systems EAGAIN when it returned
280          due to its inability to send off data without blocking. We therefor
281          treat both error codes the same here */
282       (EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err)
283 #endif
284       ) {
285       /* this is just a case of EWOULDBLOCK */
286       bytes_written=0;
287       *code = CURLE_AGAIN;
288     }
289     else {
290       failf(conn->data, "Send failure: %s",
291             Curl_strerror(conn, err));
292       conn->data->state.os_errno = err;
293       *code = CURLE_SEND_ERROR;
294     }
295   }
296   return bytes_written;
297 }
298
299 /*
300  * Curl_write_plain() is an internal write function that sends data to the
301  * server using plain sockets only. Otherwise meant to have the exact same
302  * proto as Curl_write()
303  */
304 CURLcode Curl_write_plain(struct connectdata *conn,
305                           curl_socket_t sockfd,
306                           const void *mem,
307                           size_t len,
308                           ssize_t *written)
309 {
310   ssize_t bytes_written;
311   CURLcode retcode;
312   int num = (sockfd == conn->sock[SECONDARYSOCKET]);
313
314   bytes_written = Curl_send_plain(conn, num, mem, len, &retcode);
315
316   *written = bytes_written;
317
318   return retcode;
319 }
320
321 ssize_t Curl_recv_plain(struct connectdata *conn, int num, char *buf,
322                         size_t len, CURLcode *code)
323 {
324   curl_socket_t sockfd = conn->sock[num];
325   ssize_t nread = sread(sockfd, buf, len);
326
327   *code = CURLE_OK;
328   if(-1 == nread) {
329     int err = SOCKERRNO;
330
331     if(
332 #ifdef WSAEWOULDBLOCK
333       /* This is how Windows does it */
334       (WSAEWOULDBLOCK == err)
335 #else
336       /* errno may be EWOULDBLOCK or on some systems EAGAIN when it returned
337          due to its inability to send off data without blocking. We therefor
338          treat both error codes the same here */
339       (EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err)
340 #endif
341       ) {
342       /* this is just a case of EWOULDBLOCK */
343       *code = CURLE_AGAIN;
344     }
345     else {
346       failf(conn->data, "Recv failure: %s",
347             Curl_strerror(conn, err));
348       conn->data->state.os_errno = err;
349       *code = CURLE_RECV_ERROR;
350     }
351   }
352   return nread;
353 }
354
355 static CURLcode pausewrite(struct SessionHandle *data,
356                            int type, /* what type of data */
357                            const char *ptr,
358                            size_t len)
359 {
360   /* signalled to pause sending on this connection, but since we have data
361      we want to send we need to dup it to save a copy for when the sending
362      is again enabled */
363   struct SingleRequest *k = &data->req;
364   char *dupl = malloc(len);
365   if(!dupl)
366     return CURLE_OUT_OF_MEMORY;
367
368   memcpy(dupl, ptr, len);
369
370   /* store this information in the state struct for later use */
371   data->state.tempwrite = dupl;
372   data->state.tempwritesize = len;
373   data->state.tempwritetype = type;
374
375   /* mark the connection as RECV paused */
376   k->keepon |= KEEP_RECV_PAUSE;
377
378   DEBUGF(infof(data, "Pausing with %zu bytes in buffer for type %02x\n",
379                len, type));
380
381   return CURLE_OK;
382 }
383
384
385 /* Curl_client_write() sends data to the write callback(s)
386
387    The bit pattern defines to what "streams" to write to. Body and/or header.
388    The defines are in sendf.h of course.
389
390    If CURL_DO_LINEEND_CONV is enabled, data is converted IN PLACE to the
391    local character encoding.  This is a problem and should be changed in
392    the future to leave the original data alone.
393  */
394 CURLcode Curl_client_write(struct connectdata *conn,
395                            int type,
396                            char *ptr,
397                            size_t len)
398 {
399   struct SessionHandle *data = conn->data;
400   size_t wrote;
401
402   if(0 == len)
403     len = strlen(ptr);
404
405   /* If reading is actually paused, we're forced to append this chunk of data
406      to the already held data, but only if it is the same type as otherwise it
407      can't work and it'll return error instead. */
408   if(data->req.keepon & KEEP_RECV_PAUSE) {
409     size_t newlen;
410     char *newptr;
411     if(type != data->state.tempwritetype)
412       /* major internal confusion */
413       return CURLE_RECV_ERROR;
414
415     DEBUGASSERT(data->state.tempwrite);
416
417     /* figure out the new size of the data to save */
418     newlen = len + data->state.tempwritesize;
419     /* allocate the new memory area */
420     newptr = realloc(data->state.tempwrite, newlen);
421     if(!newptr)
422       return CURLE_OUT_OF_MEMORY;
423     /* copy the new data to the end of the new area */
424     memcpy(newptr + data->state.tempwritesize, ptr, len);
425     /* update the pointer and the size */
426     data->state.tempwrite = newptr;
427     data->state.tempwritesize = newlen;
428
429     return CURLE_OK;
430   }
431
432   if(type & CLIENTWRITE_BODY) {
433     if((conn->handler->protocol&CURLPROTO_FTP) &&
434        conn->proto.ftpc.transfertype == 'A') {
435       /* convert from the network encoding */
436       CURLcode rc = Curl_convert_from_network(data, ptr, len);
437       /* Curl_convert_from_network calls failf if unsuccessful */
438       if(rc)
439         return rc;
440
441 #ifdef CURL_DO_LINEEND_CONV
442       /* convert end-of-line markers */
443       len = convert_lineends(data, ptr, len);
444 #endif /* CURL_DO_LINEEND_CONV */
445     }
446     /* If the previous block of data ended with CR and this block of data is
447        just a NL, then the length might be zero */
448     if(len) {
449       wrote = data->set.fwrite_func(ptr, 1, len, data->set.out);
450     }
451     else {
452       wrote = len;
453     }
454
455     if(CURL_WRITEFUNC_PAUSE == wrote)
456       return pausewrite(data, type, ptr, len);
457
458     if(wrote != len) {
459       failf(data, "Failed writing body (%zu != %zu)", wrote, len);
460       return CURLE_WRITE_ERROR;
461     }
462   }
463
464   if((type & CLIENTWRITE_HEADER) &&
465      (data->set.fwrite_header || data->set.writeheader) ) {
466     /*
467      * Write headers to the same callback or to the especially setup
468      * header callback function (added after version 7.7.1).
469      */
470     curl_write_callback writeit=
471       data->set.fwrite_header?data->set.fwrite_header:data->set.fwrite_func;
472
473     /* Note: The header is in the host encoding
474        regardless of the ftp transfer mode (ASCII/Image) */
475
476     wrote = writeit(ptr, 1, len, data->set.writeheader);
477     if(CURL_WRITEFUNC_PAUSE == wrote)
478       /* here we pass in the HEADER bit only since if this was body as well
479          then it was passed already and clearly that didn't trigger the pause,
480          so this is saved for later with the HEADER bit only */
481       return pausewrite(data, CLIENTWRITE_HEADER, ptr, len);
482
483     if(wrote != len) {
484       failf (data, "Failed writing header");
485       return CURLE_WRITE_ERROR;
486     }
487   }
488
489   return CURLE_OK;
490 }
491
492 CURLcode Curl_read_plain(curl_socket_t sockfd,
493                          char *buf,
494                          size_t bytesfromsocket,
495                          ssize_t *n)
496 {
497   ssize_t nread = sread(sockfd, buf, bytesfromsocket);
498
499   if(-1 == nread) {
500     int err = SOCKERRNO;
501 #ifdef USE_WINSOCK
502     if(WSAEWOULDBLOCK == err)
503 #else
504     if((EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err))
505 #endif
506       return CURLE_AGAIN;
507     else
508       return CURLE_RECV_ERROR;
509   }
510
511   /* we only return number of bytes read when we return OK */
512   *n = nread;
513   return CURLE_OK;
514 }
515
516 /*
517  * Internal read-from-socket function. This is meant to deal with plain
518  * sockets, SSL sockets and kerberos sockets.
519  *
520  * Returns a regular CURLcode value.
521  */
522 CURLcode Curl_read(struct connectdata *conn, /* connection data */
523                    curl_socket_t sockfd,     /* read from this socket */
524                    char *buf,                /* store read data here */
525                    size_t sizerequested,     /* max amount to read */
526                    ssize_t *n)               /* amount bytes read */
527 {
528   CURLcode curlcode = CURLE_RECV_ERROR;
529   ssize_t nread = 0;
530   size_t bytesfromsocket = 0;
531   char *buffertofill = NULL;
532   bool pipelining = (conn->data->multi &&
533                      Curl_multi_canPipeline(conn->data->multi)) ? TRUE : FALSE;
534
535   /* Set 'num' to 0 or 1, depending on which socket that has been sent here.
536      If it is the second socket, we set num to 1. Otherwise to 0. This lets
537      us use the correct ssl handle. */
538   int num = (sockfd == conn->sock[SECONDARYSOCKET]);
539
540   *n=0; /* reset amount to zero */
541
542   /* If session can pipeline, check connection buffer  */
543   if(pipelining) {
544     size_t bytestocopy = CURLMIN(conn->buf_len - conn->read_pos,
545                                  sizerequested);
546
547     /* Copy from our master buffer first if we have some unread data there*/
548     if(bytestocopy > 0) {
549       memcpy(buf, conn->master_buffer + conn->read_pos, bytestocopy);
550       conn->read_pos += bytestocopy;
551       conn->bits.stream_was_rewound = FALSE;
552
553       *n = (ssize_t)bytestocopy;
554       return CURLE_OK;
555     }
556     /* If we come here, it means that there is no data to read from the buffer,
557      * so we read from the socket */
558     bytesfromsocket = CURLMIN(sizerequested, BUFSIZE * sizeof (char));
559     buffertofill = conn->master_buffer;
560   }
561   else {
562     bytesfromsocket = CURLMIN((long)sizerequested,
563                               conn->data->set.buffer_size ?
564                               conn->data->set.buffer_size : BUFSIZE);
565     buffertofill = buf;
566   }
567
568   nread = conn->recv[num](conn, num, buffertofill, bytesfromsocket, &curlcode);
569   if(nread < 0)
570     return curlcode;
571
572   if(pipelining) {
573     memcpy(buf, conn->master_buffer, nread);
574     conn->buf_len = nread;
575     conn->read_pos = nread;
576   }
577
578   *n += nread;
579
580   return CURLE_OK;
581 }
582
583 /* return 0 on success */
584 static int showit(struct SessionHandle *data, curl_infotype type,
585                   char *ptr, size_t size)
586 {
587   static const char s_infotype[CURLINFO_END][3] = {
588     "* ", "< ", "> ", "{ ", "} ", "{ ", "} " };
589
590 #ifdef CURL_DOES_CONVERSIONS
591   char buf[BUFSIZE+1];
592   size_t conv_size = 0;
593
594   switch(type) {
595   case CURLINFO_HEADER_OUT:
596     /* assume output headers are ASCII */
597     /* copy the data into my buffer so the original is unchanged */
598     if(size > BUFSIZE) {
599       size = BUFSIZE; /* truncate if necessary */
600       buf[BUFSIZE] = '\0';
601     }
602     conv_size = size;
603     memcpy(buf, ptr, size);
604     /* Special processing is needed for this block if it
605      * contains both headers and data (separated by CRLFCRLF).
606      * We want to convert just the headers, leaving the data as-is.
607      */
608     if(size > 4) {
609       size_t i;
610       for(i = 0; i < size-4; i++) {
611         if(memcmp(&buf[i], "\x0d\x0a\x0d\x0a", 4) == 0) {
612           /* convert everything through this CRLFCRLF but no further */
613           conv_size = i + 4;
614           break;
615         }
616       }
617     }
618
619     Curl_convert_from_network(data, buf, conv_size);
620     /* Curl_convert_from_network calls failf if unsuccessful */
621     /* we might as well continue even if it fails...   */
622     ptr = buf; /* switch pointer to use my buffer instead */
623     break;
624   default:
625     /* leave everything else as-is */
626     break;
627   }
628 #endif /* CURL_DOES_CONVERSIONS */
629
630   if(data->set.fdebug)
631     return (*data->set.fdebug)(data, type, ptr, size,
632                                data->set.debugdata);
633
634   switch(type) {
635   case CURLINFO_TEXT:
636   case CURLINFO_HEADER_OUT:
637   case CURLINFO_HEADER_IN:
638     fwrite(s_infotype[type], 2, 1, data->set.err);
639     fwrite(ptr, size, 1, data->set.err);
640 #ifdef CURL_DOES_CONVERSIONS
641     if(size != conv_size) {
642       /* we had untranslated data so we need an explicit newline */
643       fwrite("\n", 1, 1, data->set.err);
644     }
645 #endif
646     break;
647   default: /* nada */
648     break;
649   }
650   return 0;
651 }
652
653 int Curl_debug(struct SessionHandle *data, curl_infotype type,
654                char *ptr, size_t size,
655                struct connectdata *conn)
656 {
657   int rc;
658   if(data->set.printhost && conn && conn->host.dispname) {
659     char buffer[160];
660     const char *t=NULL;
661     const char *w="Data";
662     switch (type) {
663     case CURLINFO_HEADER_IN:
664       w = "Header";
665     case CURLINFO_DATA_IN:
666       t = "from";
667       break;
668     case CURLINFO_HEADER_OUT:
669       w = "Header";
670     case CURLINFO_DATA_OUT:
671       t = "to";
672       break;
673     default:
674       break;
675     }
676
677     if(t) {
678       snprintf(buffer, sizeof(buffer), "[%s %s %s]", w, t,
679                conn->host.dispname);
680       rc = showit(data, CURLINFO_TEXT, buffer, strlen(buffer));
681       if(rc)
682         return rc;
683     }
684   }
685   rc = showit(data, type, ptr, size);
686   return rc;
687 }