From 514592b89207e83d13b5a4e79bc247aa6f74c4b7 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 12 May 2008 21:43:24 +0000 Subject: - Introducing curl_easy_send() and curl_easy_recv(). They can be used to send and receive data over a connection previously setup with curl_easy_perform() and its CURLOPT_CONNECT_ONLY option. The sendrecv.c example was added to show how they can be used. --- docs/examples/Makefile.inc | 3 +- docs/examples/sendrecv.c | 117 ++++++++++++++++++++++++++++++++++++++++++ docs/libcurl/Makefile.am | 8 +-- docs/libcurl/curl_easy_recv.3 | 70 +++++++++++++++++++++++++ docs/libcurl/curl_easy_send.3 | 65 +++++++++++++++++++++++ docs/libcurl/index.html | 2 + docs/libcurl/libcurl-errors.3 | 6 ++- 7 files changed, 266 insertions(+), 5 deletions(-) create mode 100644 docs/examples/sendrecv.c create mode 100644 docs/libcurl/curl_easy_recv.3 create mode 100644 docs/libcurl/curl_easy_send.3 (limited to 'docs') diff --git a/docs/examples/Makefile.inc b/docs/examples/Makefile.inc index 5d0c162a5..840c9bf6c 100644 --- a/docs/examples/Makefile.inc +++ b/docs/examples/Makefile.inc @@ -4,7 +4,8 @@ check_PROGRAMS = 10-at-a-time anyauthput cookie_interface \ getinfo getinmemory http-post httpput \ https multi-app multi-debugcallback multi-double \ multi-post multi-single persistant post-callback \ - postit2 sepheaders simple simplepost simplessl + postit2 sepheaders simple simplepost simplessl \ + sendrecv # These examples require external dependencies that may not be commonly # available on POSIX systems, so don't bother attempting to compile them here. diff --git a/docs/examples/sendrecv.c b/docs/examples/sendrecv.c new file mode 100644 index 000000000..1a37d2862 --- /dev/null +++ b/docs/examples/sendrecv.c @@ -0,0 +1,117 @@ +/***************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * An example of curl_easy_send() and curl_easy_recv() usage. + * + * $Id$ + */ + +#include +#include +#include + +/* Auxiliary function that waits on the socket. */ +static int wait_on_socket(int sockfd, int for_recv, long timeout_ms) +{ + struct timeval tv; + long seconds, usecs; + fd_set infd, outfd, errfd; + int res; + + tv.tv_sec = timeout_ms / 1000; + tv.tv_usec= (timeout_ms % 1000) * 1000; + + FD_ZERO(&infd); + FD_ZERO(&outfd); + FD_ZERO(&errfd); + + FD_SET(sockfd, &errfd); /* always check for error */ + + if(for_recv) + { + FD_SET(sockfd, &infd); + } + else + { + FD_SET(sockfd, &outfd); + } + + /* select() returns the number of signalled sockets or -1 */ + res = select(sockfd + 1, &infd, &outfd, &errfd, &tv); + return res; +} + +int main(void) +{ + CURL *curl; + CURLcode res; + /* Minimalistic http request */ + const char *request = "GET / HTTP/1.0\r\nHost: curl.haxx.se\r\n\r\n"; + int sockfd; /* socket */ + size_t iolen; + + curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "curl.haxx.se"); + /* Do not do the transfer - only connect to host */ + curl_easy_setopt(curl, CURLOPT_CONNECT_ONLY, 1L); + res = curl_easy_perform(curl); + + if(CURLE_OK != res) + { + printf("Error: %s\n", strerror(res)); + return 1; + } + + /* Extract the socket from the curl handle - we'll need it + * for waiting */ + res = curl_easy_getinfo(curl, CURLINFO_LASTSOCKET, &sockfd); + + if(CURLE_OK != res) + { + printf("Error: %s\n", strerror(res)); + return 1; + } + + /* wait for the socket to become ready for sending */ + if(!wait_on_socket(sockfd, 0, 60000L)) + { + printf("Error: timeout.\n"); + return 1; + } + + puts("Sending request."); + /* Send the request. Real applications should check the iolen + * to see if all the request has been sent */ + res = curl_easy_send(curl, request, strlen(request), &iolen); + + if(CURLE_OK != res) + { + printf("Error: %s\n", strerror(res)); + return 1; + } + puts("Reading response."); + + /* read the response */ + for(;;) + { + char buf[1024]; + + wait_on_socket(sockfd, 1, 60000L); + res = curl_easy_recv(curl, buf, 1024, &iolen); + + if(CURLE_OK != res) + break; + + printf("Received %u bytes.\n", iolen); + } + + /* always cleanup */ + curl_easy_cleanup(curl); + } + return 0; +} diff --git a/docs/libcurl/Makefile.am b/docs/libcurl/Makefile.am index 9bf8e99c7..9e562c21e 100644 --- a/docs/libcurl/Makefile.am +++ b/docs/libcurl/Makefile.am @@ -19,7 +19,7 @@ man_MANS = curl_easy_cleanup.3 curl_easy_getinfo.3 curl_easy_init.3 \ libcurl-tutorial.3 curl_easy_reset.3 curl_easy_escape.3 \ curl_easy_unescape.3 curl_multi_setopt.3 curl_multi_socket.3 \ curl_multi_timeout.3 curl_formget.3 curl_multi_assign.3 \ - curl_easy_pause.3 + curl_easy_pause.3 curl_easy_recv.3 curl_easy_send.3 HTMLPAGES = curl_easy_cleanup.html curl_easy_getinfo.html \ curl_easy_init.html curl_easy_perform.html curl_easy_setopt.html \ @@ -37,7 +37,8 @@ HTMLPAGES = curl_easy_cleanup.html curl_easy_getinfo.html \ curl_share_strerror.html curl_global_init_mem.html libcurl-tutorial.html \ curl_easy_reset.html curl_easy_escape.html curl_easy_unescape.html \ curl_multi_setopt.html curl_multi_socket.html curl_multi_timeout.html \ - curl_formget.html curl_multi_assign.html curl_easy_pause.html + curl_formget.html curl_multi_assign.html curl_easy_pause.html \ + curl_easy_recv.html curl_easy_send.html PDFPAGES = curl_easy_cleanup.pdf curl_easy_getinfo.pdf curl_easy_init.pdf \ curl_easy_perform.pdf curl_easy_setopt.pdf curl_easy_duphandle.pdf \ @@ -54,7 +55,8 @@ PDFPAGES = curl_easy_cleanup.pdf curl_easy_getinfo.pdf curl_easy_init.pdf \ curl_share_strerror.pdf curl_global_init_mem.pdf libcurl-tutorial.pdf \ curl_easy_reset.pdf curl_easy_escape.pdf curl_easy_unescape.pdf \ curl_multi_setopt.pdf curl_multi_socket.pdf curl_multi_timeout.pdf \ - curl_formget.pdf curl_multi_assign.pdf curl_easy_pause.pdf + curl_formget.pdf curl_multi_assign.pdf curl_easy_pause.pdf \ + curl_easy_recv.pdf curl_easy_send.pdf CLEANFILES = $(HTMLPAGES) $(PDFPAGES) diff --git a/docs/libcurl/curl_easy_recv.3 b/docs/libcurl/curl_easy_recv.3 new file mode 100644 index 000000000..ea806ff66 --- /dev/null +++ b/docs/libcurl/curl_easy_recv.3 @@ -0,0 +1,70 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2008, Daniel Stenberg, , et al. +.\" * +.\" * This software is licensed as described in the file COPYING, which +.\" * you should have received as part of this distribution. The terms +.\" * are also available at http://curl.haxx.se/docs/copyright.html. +.\" * +.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell +.\" * copies of the Software, and permit persons to whom the Software is +.\" * furnished to do so, under the terms of the COPYING file. +.\" * +.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +.\" * KIND, either express or implied. +.\" * +.\" * $Id$ +.\" ************************************************************************** +.\" +.TH curl_easy_recv 3 "29 April 2008" "libcurl 7.18.2" "libcurl Manual" +.SH NAME +curl_easy_recv - receives raw data on an "easy" connection +.SH SYNOPSIS +.B #include +.sp +.BI "CURLcode curl_easy_recv( CURL *" curl ", void *" buffer "," +.BI "size_t " buflen ", size_t *" n ");" +.ad +.SH DESCRIPTION +This function receives raw data from the established connection. You may use +it together with \fIcurl_easy_send(3)\fP to implement custom protocols using +libcurl. This functionality can be particularly useful if you use proxies +and/or SSL encryption: libcurl will take care of proxy negotiation and +connection set-up. + +\fBbuffer\fP is a pointer to your buffer that will get the received +data. \fBbuflen\fP is the maximum amount of data you can get in that +buffer. The variable \fBn\fP points to will receive the number of received +bytes. + +To establish the connection, set \fBCURLOPT_CONNECT_ONLY\fP option before +calling \fIcurl_easy_perform(3)\fP. Note that \fIcurl_easy_recv(3)\fP does not +work on connections that were created without this option. + +You must ensure that the socket has data to read before calling +\fIcurl_easy_recv(3)\fP, otherwise the call will return \fBCURLE_AGAIN\fP - +the socket is used in non-blocking mode internally. Use +\fIcurl_easy_getinfo(3)\fP with \fBCURLINFO_LASTSOCKET\fP to obtain the +socket; use your operating system facilities like \fIselect(2)\fP to check if +it has any data you can read. +.SH AVAILABILITY +Added in 7.18.2. +.SH RETURN VALUE +On success, returns \fBCURLE_OK\fP, stores the received data into +\fBbuffer\fP, and the number of bytes it actually read into \fB*n\fP. + +On failure, returns the appropriate error code. + +If there is no data to read, the function returns \fBCURLE_AGAIN\fP. Use +your operating system facilities to wait until the data is ready, and retry. +.SH EXAMPLE +See \fBsendrecv.c\fP in \fBdocs/examples\fP directory for usage example. +.SH "SEE ALSO" +.BR curl_easy_setopt "(3), " curl_easy_perform "(3), " +.BR curl_easy_getinfo "(3), " +.BR curl_easy_send "(3) " diff --git a/docs/libcurl/curl_easy_send.3 b/docs/libcurl/curl_easy_send.3 new file mode 100644 index 000000000..60a97b29d --- /dev/null +++ b/docs/libcurl/curl_easy_send.3 @@ -0,0 +1,65 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2008, Daniel Stenberg, , et al. +.\" * +.\" * This software is licensed as described in the file COPYING, which +.\" * you should have received as part of this distribution. The terms +.\" * are also available at http://curl.haxx.se/docs/copyright.html. +.\" * +.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell +.\" * copies of the Software, and permit persons to whom the Software is +.\" * furnished to do so, under the terms of the COPYING file. +.\" * +.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +.\" * KIND, either express or implied. +.\" * +.\" * $Id$ +.\" ************************************************************************** +.\" +.TH curl_easy_send 3 "29 April 2008" "libcurl 7.18.2" "libcurl Manual" +.SH NAME +curl_easy_send - sends raw data over an "easy" connection +.SH SYNOPSIS +.B #include +.sp +.BI "CURLcode curl_easy_send( CURL *" curl ", const void *" buffer "," +.BI " size_t " buflen ", size_t *" n ");" +.ad +.SH DESCRIPTION +This function sends arbitrary data over the established connection. You may +use it together with \fIcurl_easy_recv(3)\fP to implement custom protocols +using libcurl. This functionality can be particularly useful if you use +proxies and/or SSL encryption: libcurl will take care of proxy negotiation and +connection set-up. + +\fBbuffer\fP is a pointer to the data of length \fBbuflen\fP that you want sent. +The variable \fBn\fP points to will receive the number of sent bytes. + +To establish the connection, set \fBCURLOPT_CONNECT_ONLY\fP option before +calling \fIcurl_easy_perform(3)\fP. Note that \fIcurl_easy_send(3)\fP will not +work on connections that were created without this option. + +You must ensure that the socket is writable before calling +\fIcurl_easy_send(3)\fP, otherwise the call will return \fBCURLE_AGAIN\fP - +the socket is used in non-blocking mode internally. Use +\fIcurl_easy_getinfo(3)\fP with \fBCURLINFO_LASTSOCKET\fP to obtain the +socket; use your operating system facilities like \fIselect(2)\fP to check if +it can be written to. +.SH AVAILABILITY +Added in 7.18.2. +.SH RETURN VALUE +On success, returns \fBCURLE_OK\fP and stores the number of bytes actually +sent into \fB*n\fP. Note that this may very well be less than the amount you +wanted to send. + +On failure, returns the appropriate error code. +.SH EXAMPLE +See \fBsendrecv.c\fP in \fBdocs/examples\fP directory for usage example. +.SH "SEE ALSO" +.BR curl_easy_setopt "(3), " curl_easy_perform "(3), " curl_easy_getinfo "(3), " +.BR curl_easy_recv "(3) " diff --git a/docs/libcurl/index.html b/docs/libcurl/index.html index 6b4f10550..287a2dd69 100644 --- a/docs/libcurl/index.html +++ b/docs/libcurl/index.html @@ -24,7 +24,9 @@
curl_easy_getinfo
curl_easy_init
curl_easy_perform +
curl_easy_recv
curl_easy_reset +
curl_easy_send
curl_easy_setopt
curl_easy_strerror
curl_escape diff --git a/docs/libcurl/libcurl-errors.3 b/docs/libcurl/libcurl-errors.3 index a686793f7..28e6f82c9 100644 --- a/docs/libcurl/libcurl-errors.3 +++ b/docs/libcurl/libcurl-errors.3 @@ -5,7 +5,7 @@ .\" * | (__| |_| | _ <| |___ .\" * \___|\___/|_| \_\_____| .\" * -.\" * Copyright (C) 1998 - 2007, Daniel Stenberg, , et al. +.\" * Copyright (C) 1998 - 2008, Daniel Stenberg, , et al. .\" * .\" * This software is licensed as described in the file COPYING, which .\" * you should have received as part of this distribution. The terms @@ -208,6 +208,10 @@ The resource referenced in the URL does not exist An unspecified error occurred during the SSH session .IP "CURLE_SSL_SHUTDOWN_FAILED (80)" Failed to shut down the SSL connection +.IP "CURLE_AGAIN (81)" +Socket is not ready for send/recv wait till it's ready and try again. This +return code is only returned from \fIcurl_easy_recv(3)\fP and +\fIcurl_easy_send(3)\fP (Added in 7.18.2) .IP "CURLE_OBSOLETE*" These error codes will never be returned. They used to be used in an old libcurl version and are currently unused. -- cgit v1.2.3