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