1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
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.
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.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 ***************************************************************************/
25 #include <curl/curl.h>
33 #include "non-ascii.h"
35 #define _MPRINTF_REPLACE /* use the internal *printf() functions */
36 #include <curl/mprintf.h>
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))
42 #define Curl_sec_send(a,b,c,d) -1
43 #define Curl_sec_read(a,b,c,d) -1
46 #include "curl_memory.h"
49 /* The last #include file should be: */
52 #ifdef CURL_DO_LINEEND_CONV
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.
59 static size_t convert_lineends(struct SessionHandle *data,
60 char *startPtr, size_t size)
65 if((startPtr == NULL) || (size < 1)) {
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);
77 /* and it wasn't a bare CR but a CRLF conversion instead */
78 data->state.crlf_conversions++;
80 data->state.prev_block_had_trailing_cr = FALSE; /* reset the flag */
83 /* find 1st CR, if any */
84 inPtr = outPtr = memchr(startPtr, '\r', size);
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 */
93 /* keep track of how many CRLFs we converted */
94 data->state.crlf_conversions++;
98 /* lone CR, move LF instead */
102 /* not a CRLF nor a CR, just copy whatever it is */
108 } /* end of while loop */
110 if(inPtr < startPtr+size) {
111 /* handle last byte */
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;
124 if(outPtr < startPtr+size)
125 /* tidy up by null terminating the now shorter data */
128 return(outPtr - startPtr);
132 #endif /* CURL_DO_LINEEND_CONV */
134 /* Curl_infof() is for info message along the way */
136 void Curl_infof(struct SessionHandle *data, const char *fmt, ...)
138 if(data && data->set.verbose) {
141 char print_buffer[2048 + 1];
143 vsnprintf(print_buffer, sizeof(print_buffer), fmt, ap);
145 len = strlen(print_buffer);
146 Curl_debug(data, CURLINFO_TEXT, print_buffer, len, NULL);
150 /* Curl_failf() is for messages stating why we failed.
151 * The message SHALL NOT include any LF or CR.
154 void Curl_failf(struct SessionHandle *data, const char *fmt, ...)
160 vsnprintf(data->state.buffer, BUFSIZE, fmt, ap);
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 */
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';
172 Curl_debug(data, CURLINFO_TEXT, data->state.buffer, len, NULL);
178 /* Curl_sendf() sends formated data to the server */
179 CURLcode Curl_sendf(curl_socket_t sockfd, struct connectdata *conn,
180 const char *fmt, ...)
182 struct SessionHandle *data = conn->data;
183 ssize_t bytes_written;
185 CURLcode res = CURLE_OK;
190 s = vaprintf(fmt, ap); /* returns an allocated string */
193 return CURLE_OUT_OF_MEMORY; /* failure */
196 write_len = strlen(s);
200 /* Write the buffer to the socket */
201 res = Curl_write(conn, sockfd, sptr, write_len, &bytes_written);
206 if(data->set.verbose)
207 Curl_debug(data, CURLINFO_DATA_OUT, sptr, (size_t)bytes_written, conn);
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;
219 free(s); /* free the output string */
225 * Curl_write() is an internal write function that sends data to the
226 * server. Works with plain sockets, SCP, SSL or kerberos.
228 * If the write would block (CURLE_AGAIN), we return CURLE_OK and
229 * (*written == 0). Otherwise we return regular CURLcode value.
231 CURLcode Curl_write(struct connectdata *conn,
232 curl_socket_t sockfd,
237 ssize_t bytes_written;
238 CURLcode curlcode = CURLE_OK;
239 int num = (sockfd == conn->sock[SECONDARYSOCKET]);
241 bytes_written = conn->send[num](conn, num, mem, len, &curlcode);
243 *written = bytes_written;
244 if(bytes_written >= 0)
245 /* we completely ignore the curlcode value when subzero is not returned */
248 /* handle CURLE_AGAIN or a send failure */
255 /* general send failure */
256 return CURLE_SEND_ERROR;
259 /* we got a specific curlcode, forward it */
264 ssize_t Curl_send_plain(struct connectdata *conn, int num,
265 const void *mem, size_t len, CURLcode *code)
267 curl_socket_t sockfd = conn->sock[num];
268 ssize_t bytes_written = swrite(sockfd, mem, len);
271 if(-1 == bytes_written) {
275 #ifdef WSAEWOULDBLOCK
276 /* This is how Windows does it */
277 (WSAEWOULDBLOCK == err)
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)
285 /* this is just a case of EWOULDBLOCK */
290 failf(conn->data, "Send failure: %s",
291 Curl_strerror(conn, err));
292 conn->data->state.os_errno = err;
293 *code = CURLE_SEND_ERROR;
296 return bytes_written;
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()
304 CURLcode Curl_write_plain(struct connectdata *conn,
305 curl_socket_t sockfd,
310 ssize_t bytes_written;
312 int num = (sockfd == conn->sock[SECONDARYSOCKET]);
314 bytes_written = Curl_send_plain(conn, num, mem, len, &retcode);
316 *written = bytes_written;
321 ssize_t Curl_recv_plain(struct connectdata *conn, int num, char *buf,
322 size_t len, CURLcode *code)
324 curl_socket_t sockfd = conn->sock[num];
325 ssize_t nread = sread(sockfd, buf, len);
332 #ifdef WSAEWOULDBLOCK
333 /* This is how Windows does it */
334 (WSAEWOULDBLOCK == err)
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)
342 /* this is just a case of EWOULDBLOCK */
346 failf(conn->data, "Recv failure: %s",
347 Curl_strerror(conn, err));
348 conn->data->state.os_errno = err;
349 *code = CURLE_RECV_ERROR;
355 static CURLcode pausewrite(struct SessionHandle *data,
356 int type, /* what type of data */
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
363 struct SingleRequest *k = &data->req;
364 char *dupl = malloc(len);
366 return CURLE_OUT_OF_MEMORY;
368 memcpy(dupl, ptr, len);
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;
375 /* mark the connection as RECV paused */
376 k->keepon |= KEEP_RECV_PAUSE;
378 DEBUGF(infof(data, "Pausing with %zu bytes in buffer for type %02x\n",
385 /* Curl_client_write() sends data to the write callback(s)
387 The bit pattern defines to what "streams" to write to. Body and/or header.
388 The defines are in sendf.h of course.
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.
394 CURLcode Curl_client_write(struct connectdata *conn,
399 struct SessionHandle *data = conn->data;
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) {
411 if(type != data->state.tempwritetype)
412 /* major internal confusion */
413 return CURLE_RECV_ERROR;
415 DEBUGASSERT(data->state.tempwrite);
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);
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;
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 */
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 */
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 */
449 wrote = data->set.fwrite_func(ptr, 1, len, data->set.out);
455 if(CURL_WRITEFUNC_PAUSE == wrote)
456 return pausewrite(data, type, ptr, len);
459 failf(data, "Failed writing body (%zu != %zu)", wrote, len);
460 return CURLE_WRITE_ERROR;
464 if((type & CLIENTWRITE_HEADER) &&
465 (data->set.fwrite_header || data->set.writeheader) ) {
467 * Write headers to the same callback or to the especially setup
468 * header callback function (added after version 7.7.1).
470 curl_write_callback writeit=
471 data->set.fwrite_header?data->set.fwrite_header:data->set.fwrite_func;
473 /* Note: The header is in the host encoding
474 regardless of the ftp transfer mode (ASCII/Image) */
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);
484 failf (data, "Failed writing header");
485 return CURLE_WRITE_ERROR;
492 CURLcode Curl_read_plain(curl_socket_t sockfd,
494 size_t bytesfromsocket,
497 ssize_t nread = sread(sockfd, buf, bytesfromsocket);
502 if(WSAEWOULDBLOCK == err)
504 if((EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err))
508 return CURLE_RECV_ERROR;
511 /* we only return number of bytes read when we return OK */
517 * Internal read-from-socket function. This is meant to deal with plain
518 * sockets, SSL sockets and kerberos sockets.
520 * Returns a regular CURLcode value.
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 */
528 CURLcode curlcode = CURLE_RECV_ERROR;
530 size_t bytesfromsocket = 0;
531 char *buffertofill = NULL;
532 bool pipelining = (conn->data->multi &&
533 Curl_multi_canPipeline(conn->data->multi)) ? TRUE : FALSE;
535 /* Set 'num' to 0 or 1, depending on which socket that has been sent here.
536 If it is the second socket, we set num to 1. Otherwise to 0. This lets
537 us use the correct ssl handle. */
538 int num = (sockfd == conn->sock[SECONDARYSOCKET]);
540 *n=0; /* reset amount to zero */
542 /* If session can pipeline, check connection buffer */
544 size_t bytestocopy = CURLMIN(conn->buf_len - conn->read_pos,
547 /* Copy from our master buffer first if we have some unread data there*/
548 if(bytestocopy > 0) {
549 memcpy(buf, conn->master_buffer + conn->read_pos, bytestocopy);
550 conn->read_pos += bytestocopy;
551 conn->bits.stream_was_rewound = FALSE;
553 *n = (ssize_t)bytestocopy;
556 /* If we come here, it means that there is no data to read from the buffer,
557 * so we read from the socket */
558 bytesfromsocket = CURLMIN(sizerequested, BUFSIZE * sizeof (char));
559 buffertofill = conn->master_buffer;
562 bytesfromsocket = CURLMIN((long)sizerequested,
563 conn->data->set.buffer_size ?
564 conn->data->set.buffer_size : BUFSIZE);
568 nread = conn->recv[num](conn, num, buffertofill, bytesfromsocket, &curlcode);
573 memcpy(buf, conn->master_buffer, nread);
574 conn->buf_len = nread;
575 conn->read_pos = nread;
583 /* return 0 on success */
584 static int showit(struct SessionHandle *data, curl_infotype type,
585 char *ptr, size_t size)
587 static const char s_infotype[CURLINFO_END][3] = {
588 "* ", "< ", "> ", "{ ", "} ", "{ ", "} " };
590 #ifdef CURL_DOES_CONVERSIONS
592 size_t conv_size = 0;
595 case CURLINFO_HEADER_OUT:
596 /* assume output headers are ASCII */
597 /* copy the data into my buffer so the original is unchanged */
599 size = BUFSIZE; /* truncate if necessary */
603 memcpy(buf, ptr, size);
604 /* Special processing is needed for this block if it
605 * contains both headers and data (separated by CRLFCRLF).
606 * We want to convert just the headers, leaving the data as-is.
610 for(i = 0; i < size-4; i++) {
611 if(memcmp(&buf[i], "\x0d\x0a\x0d\x0a", 4) == 0) {
612 /* convert everything through this CRLFCRLF but no further */
619 Curl_convert_from_network(data, buf, conv_size);
620 /* Curl_convert_from_network calls failf if unsuccessful */
621 /* we might as well continue even if it fails... */
622 ptr = buf; /* switch pointer to use my buffer instead */
625 /* leave everything else as-is */
628 #endif /* CURL_DOES_CONVERSIONS */
631 return (*data->set.fdebug)(data, type, ptr, size,
632 data->set.debugdata);
636 case CURLINFO_HEADER_OUT:
637 case CURLINFO_HEADER_IN:
638 fwrite(s_infotype[type], 2, 1, data->set.err);
639 fwrite(ptr, size, 1, data->set.err);
640 #ifdef CURL_DOES_CONVERSIONS
641 if(size != conv_size) {
642 /* we had untranslated data so we need an explicit newline */
643 fwrite("\n", 1, 1, data->set.err);
653 int Curl_debug(struct SessionHandle *data, curl_infotype type,
654 char *ptr, size_t size,
655 struct connectdata *conn)
658 if(data->set.printhost && conn && conn->host.dispname) {
661 const char *w="Data";
663 case CURLINFO_HEADER_IN:
665 case CURLINFO_DATA_IN:
668 case CURLINFO_HEADER_OUT:
670 case CURLINFO_DATA_OUT:
678 snprintf(buffer, sizeof(buffer), "[%s %s %s]", w, t,
679 conn->host.dispname);
680 rc = showit(data, CURLINFO_TEXT, buffer, strlen(buffer));
685 rc = showit(data, type, ptr, size);