d5bf17282311375527be807d19d8e2e130f1c02f
[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 "curl_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 = Curl_multi_pipeline_enabled(conn->data->multi);
533
534   /* Set 'num' to 0 or 1, depending on which socket that has been sent here.
535      If it is the second socket, we set num to 1. Otherwise to 0. This lets
536      us use the correct ssl handle. */
537   int num = (sockfd == conn->sock[SECONDARYSOCKET]);
538
539   *n=0; /* reset amount to zero */
540
541   /* If session can pipeline, check connection buffer  */
542   if(pipelining) {
543     size_t bytestocopy = CURLMIN(conn->buf_len - conn->read_pos,
544                                  sizerequested);
545
546     /* Copy from our master buffer first if we have some unread data there*/
547     if(bytestocopy > 0) {
548       memcpy(buf, conn->master_buffer + conn->read_pos, bytestocopy);
549       conn->read_pos += bytestocopy;
550       conn->bits.stream_was_rewound = FALSE;
551
552       *n = (ssize_t)bytestocopy;
553       return CURLE_OK;
554     }
555     /* If we come here, it means that there is no data to read from the buffer,
556      * so we read from the socket */
557     bytesfromsocket = CURLMIN(sizerequested, BUFSIZE * sizeof (char));
558     buffertofill = conn->master_buffer;
559   }
560   else {
561     bytesfromsocket = CURLMIN((long)sizerequested,
562                               conn->data->set.buffer_size ?
563                               conn->data->set.buffer_size : BUFSIZE);
564     buffertofill = buf;
565   }
566
567   nread = conn->recv[num](conn, num, buffertofill, bytesfromsocket, &curlcode);
568   if(nread < 0)
569     return curlcode;
570
571   if(pipelining) {
572     memcpy(buf, conn->master_buffer, nread);
573     conn->buf_len = nread;
574     conn->read_pos = nread;
575   }
576
577   *n += nread;
578
579   return CURLE_OK;
580 }
581
582 /* return 0 on success */
583 static int showit(struct SessionHandle *data, curl_infotype type,
584                   char *ptr, size_t size)
585 {
586   static const char s_infotype[CURLINFO_END][3] = {
587     "* ", "< ", "> ", "{ ", "} ", "{ ", "} " };
588
589 #ifdef CURL_DOES_CONVERSIONS
590   char buf[BUFSIZE+1];
591   size_t conv_size = 0;
592
593   switch(type) {
594   case CURLINFO_HEADER_OUT:
595     /* assume output headers are ASCII */
596     /* copy the data into my buffer so the original is unchanged */
597     if(size > BUFSIZE) {
598       size = BUFSIZE; /* truncate if necessary */
599       buf[BUFSIZE] = '\0';
600     }
601     conv_size = size;
602     memcpy(buf, ptr, size);
603     /* Special processing is needed for this block if it
604      * contains both headers and data (separated by CRLFCRLF).
605      * We want to convert just the headers, leaving the data as-is.
606      */
607     if(size > 4) {
608       size_t i;
609       for(i = 0; i < size-4; i++) {
610         if(memcmp(&buf[i], "\x0d\x0a\x0d\x0a", 4) == 0) {
611           /* convert everything through this CRLFCRLF but no further */
612           conv_size = i + 4;
613           break;
614         }
615       }
616     }
617
618     Curl_convert_from_network(data, buf, conv_size);
619     /* Curl_convert_from_network calls failf if unsuccessful */
620     /* we might as well continue even if it fails...   */
621     ptr = buf; /* switch pointer to use my buffer instead */
622     break;
623   default:
624     /* leave everything else as-is */
625     break;
626   }
627 #endif /* CURL_DOES_CONVERSIONS */
628
629   if(data->set.fdebug)
630     return (*data->set.fdebug)(data, type, ptr, size,
631                                data->set.debugdata);
632
633   switch(type) {
634   case CURLINFO_TEXT:
635   case CURLINFO_HEADER_OUT:
636   case CURLINFO_HEADER_IN:
637     fwrite(s_infotype[type], 2, 1, data->set.err);
638     fwrite(ptr, size, 1, data->set.err);
639 #ifdef CURL_DOES_CONVERSIONS
640     if(size != conv_size) {
641       /* we had untranslated data so we need an explicit newline */
642       fwrite("\n", 1, 1, data->set.err);
643     }
644 #endif
645     break;
646   default: /* nada */
647     break;
648   }
649   return 0;
650 }
651
652 int Curl_debug(struct SessionHandle *data, curl_infotype type,
653                char *ptr, size_t size,
654                struct connectdata *conn)
655 {
656   int rc;
657   if(data->set.printhost && conn && conn->host.dispname) {
658     char buffer[160];
659     const char *t=NULL;
660     const char *w="Data";
661     switch (type) {
662     case CURLINFO_HEADER_IN:
663       w = "Header";
664     case CURLINFO_DATA_IN:
665       t = "from";
666       break;
667     case CURLINFO_HEADER_OUT:
668       w = "Header";
669     case CURLINFO_DATA_OUT:
670       t = "to";
671       break;
672     default:
673       break;
674     }
675
676     if(t) {
677       snprintf(buffer, sizeof(buffer), "[%s %s %s]", w, t,
678                conn->host.dispname);
679       rc = showit(data, CURLINFO_TEXT, buffer, strlen(buffer));
680       if(rc)
681         return rc;
682     }
683   }
684   rc = showit(data, type, ptr, size);
685   return rc;
686 }