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