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