mirror of
https://github.com/moparisthebest/curl
synced 2025-02-28 09:21:50 -05:00
- 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.
This commit is contained in:
parent
d72efff878
commit
514592b892
6
CHANGES
6
CHANGES
@ -7,6 +7,12 @@
|
|||||||
Changelog
|
Changelog
|
||||||
|
|
||||||
|
|
||||||
|
Daniel Stenberg (9 May 2008)
|
||||||
|
- 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.
|
||||||
|
|
||||||
Yang Tse (9 May 2008)
|
Yang Tse (9 May 2008)
|
||||||
- Internal time differences now use monotonic time source if available.
|
- Internal time differences now use monotonic time source if available.
|
||||||
This also implies the removal of the winmm.lib dependency for WIN32.
|
This also implies the removal of the winmm.lib dependency for WIN32.
|
||||||
|
@ -3,8 +3,8 @@ Curl and libcurl 7.18.2
|
|||||||
Public curl releases: 105
|
Public curl releases: 105
|
||||||
Command line options: 126
|
Command line options: 126
|
||||||
curl_easy_setopt() options: 150
|
curl_easy_setopt() options: 150
|
||||||
Public functions in libcurl: 56
|
Public functions in libcurl: 58
|
||||||
Public web site mirrors: 39
|
Public web site mirrors: 37
|
||||||
Known libcurl bindings: 36
|
Known libcurl bindings: 36
|
||||||
Contributors: 636
|
Contributors: 636
|
||||||
|
|
||||||
@ -14,6 +14,7 @@ This release includes the following changes:
|
|||||||
o CURLOPT_NOBODY is now supported over SFTP
|
o CURLOPT_NOBODY is now supported over SFTP
|
||||||
o curl can now run on Symbian OS
|
o curl can now run on Symbian OS
|
||||||
o curl -w redirect_url and CURLINFO_REDIRECT_URL
|
o curl -w redirect_url and CURLINFO_REDIRECT_URL
|
||||||
|
o added curl_easy_send() and curl_easy_recv()
|
||||||
|
|
||||||
This release includes the following bugfixes:
|
This release includes the following bugfixes:
|
||||||
|
|
||||||
|
@ -4,7 +4,8 @@ check_PROGRAMS = 10-at-a-time anyauthput cookie_interface \
|
|||||||
getinfo getinmemory http-post httpput \
|
getinfo getinmemory http-post httpput \
|
||||||
https multi-app multi-debugcallback multi-double \
|
https multi-app multi-debugcallback multi-double \
|
||||||
multi-post multi-single persistant post-callback \
|
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
|
# These examples require external dependencies that may not be commonly
|
||||||
# available on POSIX systems, so don't bother attempting to compile them here.
|
# available on POSIX systems, so don't bother attempting to compile them here.
|
||||||
|
117
docs/examples/sendrecv.c
Normal file
117
docs/examples/sendrecv.c
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* _ _ ____ _
|
||||||
|
* Project ___| | | | _ \| |
|
||||||
|
* / __| | | | |_) | |
|
||||||
|
* | (__| |_| | _ <| |___
|
||||||
|
* \___|\___/|_| \_\_____|
|
||||||
|
*
|
||||||
|
* An example of curl_easy_send() and curl_easy_recv() usage.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <curl/curl.h>
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
}
|
@ -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 \
|
libcurl-tutorial.3 curl_easy_reset.3 curl_easy_escape.3 \
|
||||||
curl_easy_unescape.3 curl_multi_setopt.3 curl_multi_socket.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_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 \
|
HTMLPAGES = curl_easy_cleanup.html curl_easy_getinfo.html \
|
||||||
curl_easy_init.html curl_easy_perform.html curl_easy_setopt.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_share_strerror.html curl_global_init_mem.html libcurl-tutorial.html \
|
||||||
curl_easy_reset.html curl_easy_escape.html curl_easy_unescape.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_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 \
|
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 \
|
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_share_strerror.pdf curl_global_init_mem.pdf libcurl-tutorial.pdf \
|
||||||
curl_easy_reset.pdf curl_easy_escape.pdf curl_easy_unescape.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_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)
|
CLEANFILES = $(HTMLPAGES) $(PDFPAGES)
|
||||||
|
|
||||||
|
70
docs/libcurl/curl_easy_recv.3
Normal file
70
docs/libcurl/curl_easy_recv.3
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
.\" **************************************************************************
|
||||||
|
.\" * _ _ ____ _
|
||||||
|
.\" * Project ___| | | | _ \| |
|
||||||
|
.\" * / __| | | | |_) | |
|
||||||
|
.\" * | (__| |_| | _ <| |___
|
||||||
|
.\" * \___|\___/|_| \_\_____|
|
||||||
|
.\" *
|
||||||
|
.\" * Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, 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 <curl/easy.h>
|
||||||
|
.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) "
|
65
docs/libcurl/curl_easy_send.3
Normal file
65
docs/libcurl/curl_easy_send.3
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
.\" **************************************************************************
|
||||||
|
.\" * _ _ ____ _
|
||||||
|
.\" * Project ___| | | | _ \| |
|
||||||
|
.\" * / __| | | | |_) | |
|
||||||
|
.\" * | (__| |_| | _ <| |___
|
||||||
|
.\" * \___|\___/|_| \_\_____|
|
||||||
|
.\" *
|
||||||
|
.\" * Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, 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 <curl/easy.h>
|
||||||
|
.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) "
|
@ -24,7 +24,9 @@
|
|||||||
<br><a href="curl_easy_getinfo.html">curl_easy_getinfo</A>
|
<br><a href="curl_easy_getinfo.html">curl_easy_getinfo</A>
|
||||||
<br><a href="curl_easy_init.html">curl_easy_init</A>
|
<br><a href="curl_easy_init.html">curl_easy_init</A>
|
||||||
<br><a href="curl_easy_perform.html">curl_easy_perform</A>
|
<br><a href="curl_easy_perform.html">curl_easy_perform</A>
|
||||||
|
<br><a href="curl_easy_recv.html">curl_easy_recv</A>
|
||||||
<br><a href="curl_easy_reset.html">curl_easy_reset</A>
|
<br><a href="curl_easy_reset.html">curl_easy_reset</A>
|
||||||
|
<br><a href="curl_easy_send.html">curl_easy_send</A>
|
||||||
<br><a href="curl_easy_setopt.html">curl_easy_setopt</A>
|
<br><a href="curl_easy_setopt.html">curl_easy_setopt</A>
|
||||||
<br><a href="curl_easy_strerror.html">curl_easy_strerror</A>
|
<br><a href="curl_easy_strerror.html">curl_easy_strerror</A>
|
||||||
<br><a href="curl_escape.html">curl_escape</A>
|
<br><a href="curl_escape.html">curl_escape</A>
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
.\" * | (__| |_| | _ <| |___
|
.\" * | (__| |_| | _ <| |___
|
||||||
.\" * \___|\___/|_| \_\_____|
|
.\" * \___|\___/|_| \_\_____|
|
||||||
.\" *
|
.\" *
|
||||||
.\" * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
|
.\" * Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
.\" *
|
.\" *
|
||||||
.\" * This software is licensed as described in the file COPYING, which
|
.\" * This software is licensed as described in the file COPYING, which
|
||||||
.\" * you should have received as part of this distribution. The terms
|
.\" * 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
|
An unspecified error occurred during the SSH session
|
||||||
.IP "CURLE_SSL_SHUTDOWN_FAILED (80)"
|
.IP "CURLE_SSL_SHUTDOWN_FAILED (80)"
|
||||||
Failed to shut down the SSL connection
|
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*"
|
.IP "CURLE_OBSOLETE*"
|
||||||
These error codes will never be returned. They used to be used in an old libcurl
|
These error codes will never be returned. They used to be used in an old libcurl
|
||||||
version and are currently unused.
|
version and are currently unused.
|
||||||
|
@ -447,6 +447,8 @@ typedef enum {
|
|||||||
|
|
||||||
CURLE_SSL_SHUTDOWN_FAILED, /* 80 - Failed to shut down the SSL
|
CURLE_SSL_SHUTDOWN_FAILED, /* 80 - Failed to shut down the SSL
|
||||||
connection */
|
connection */
|
||||||
|
CURLE_AGAIN, /* 81 - socket is not ready for send/recv,
|
||||||
|
wait till it's ready and try again */
|
||||||
CURL_LAST /* never use! */
|
CURL_LAST /* never use! */
|
||||||
} CURLcode;
|
} CURLcode;
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@ -74,6 +74,28 @@ CURL_EXTERN CURL* curl_easy_duphandle(CURL *curl);
|
|||||||
*/
|
*/
|
||||||
CURL_EXTERN void curl_easy_reset(CURL *curl);
|
CURL_EXTERN void curl_easy_reset(CURL *curl);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NAME curl_easy_recv()
|
||||||
|
*
|
||||||
|
* DESCRIPTION
|
||||||
|
*
|
||||||
|
* Receives data from the connected socket. Use after successful
|
||||||
|
* curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
|
||||||
|
*/
|
||||||
|
CURL_EXTERN CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen,
|
||||||
|
size_t *n);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NAME curl_easy_send()
|
||||||
|
*
|
||||||
|
* DESCRIPTION
|
||||||
|
*
|
||||||
|
* Sends data over the connected socket. Use after successful
|
||||||
|
* curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
|
||||||
|
*/
|
||||||
|
CURL_EXTERN CURLcode curl_easy_send(CURL *curl, const void *buffer,
|
||||||
|
size_t buflen, size_t *n);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -92,6 +92,7 @@
|
|||||||
#include "sockaddr.h" /* required for Curl_sockaddr_storage */
|
#include "sockaddr.h" /* required for Curl_sockaddr_storage */
|
||||||
#include "inet_ntop.h"
|
#include "inet_ntop.h"
|
||||||
#include "inet_pton.h"
|
#include "inet_pton.h"
|
||||||
|
#include "sslgen.h" /* for Curl_ssl_check_cxn() */
|
||||||
|
|
||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
@ -977,3 +978,46 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
|||||||
|
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Used to extract socket and connectdata struct for the most recent
|
||||||
|
* transfer on the given SessionHandle.
|
||||||
|
*
|
||||||
|
* The socket 'long' will be -1 in case of failure!
|
||||||
|
*/
|
||||||
|
CURLcode Curl_getconnectinfo(struct SessionHandle *data,
|
||||||
|
long *param_longp,
|
||||||
|
struct connectdata **connp)
|
||||||
|
{
|
||||||
|
if((data->state.lastconnect != -1) &&
|
||||||
|
(data->state.connc->connects[data->state.lastconnect] != NULL)) {
|
||||||
|
struct connectdata *c =
|
||||||
|
data->state.connc->connects[data->state.lastconnect];
|
||||||
|
if(connp)
|
||||||
|
/* only store this if the caller cares for it */
|
||||||
|
*connp = c;
|
||||||
|
*param_longp = c->sock[FIRSTSOCKET];
|
||||||
|
/* we have a socket connected, let's determine if the server shut down */
|
||||||
|
/* determine if ssl */
|
||||||
|
if(c->ssl[FIRSTSOCKET].use) {
|
||||||
|
/* use the SSL context */
|
||||||
|
if(!Curl_ssl_check_cxn(c))
|
||||||
|
*param_longp = -1; /* FIN received */
|
||||||
|
}
|
||||||
|
/* Minix 3.1 doesn't support any flags on recv; just assume socket is OK */
|
||||||
|
#ifdef MSG_PEEK
|
||||||
|
else {
|
||||||
|
/* use the socket */
|
||||||
|
char buf;
|
||||||
|
if(recv((RECV_TYPE_ARG1)c->sock[FIRSTSOCKET], (RECV_TYPE_ARG2)&buf,
|
||||||
|
(RECV_TYPE_ARG3)1, (RECV_TYPE_ARG4)MSG_PEEK) == 0) {
|
||||||
|
*param_longp = -1; /* FIN received */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*param_longp = -1;
|
||||||
|
|
||||||
|
return CURLE_OK;
|
||||||
|
}
|
||||||
|
@ -47,4 +47,13 @@ long Curl_timeleft(struct connectdata *conn,
|
|||||||
|
|
||||||
#define DEFAULT_CONNECT_TIMEOUT 300000 /* milliseconds == five minutes */
|
#define DEFAULT_CONNECT_TIMEOUT 300000 /* milliseconds == five minutes */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Used to extract socket and connectdata struct for the most recent
|
||||||
|
* transfer on the given SessionHandle.
|
||||||
|
*
|
||||||
|
* The socket 'long' will be -1 in case of failure!
|
||||||
|
*/
|
||||||
|
CURLcode Curl_getconnectinfo(struct SessionHandle *data,
|
||||||
|
long *param_longp,
|
||||||
|
struct connectdata **connp);
|
||||||
#endif
|
#endif
|
||||||
|
96
lib/easy.c
96
lib/easy.c
@ -83,6 +83,7 @@
|
|||||||
#include "easyif.h"
|
#include "easyif.h"
|
||||||
#include "select.h"
|
#include "select.h"
|
||||||
#include "sendf.h" /* for failf function prototype */
|
#include "sendf.h" /* for failf function prototype */
|
||||||
|
#include "connect.h" /* for Curl_getconnectinfo */
|
||||||
|
|
||||||
#define _MPRINTF_REPLACE /* use our functions only */
|
#define _MPRINTF_REPLACE /* use our functions only */
|
||||||
#include <curl/mprintf.h>
|
#include <curl/mprintf.h>
|
||||||
@ -1056,3 +1057,98 @@ CURLcode Curl_convert_from_utf8(struct SessionHandle *data,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CURL_DOES_CONVERSIONS */
|
#endif /* CURL_DOES_CONVERSIONS */
|
||||||
|
|
||||||
|
static CURLcode easy_connection(struct SessionHandle *data,
|
||||||
|
curl_socket_t *sfd,
|
||||||
|
struct connectdata **connp)
|
||||||
|
{
|
||||||
|
CURLcode ret;
|
||||||
|
long sockfd;
|
||||||
|
|
||||||
|
if(data == NULL)
|
||||||
|
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||||
|
|
||||||
|
/* only allow these to be called on handles with CURLOPT_CONNECT_ONLY */
|
||||||
|
if(!data->set.connect_only) {
|
||||||
|
failf(data, "CONNECT_ONLY is required!");
|
||||||
|
return CURLE_UNSUPPORTED_PROTOCOL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = Curl_getconnectinfo(data, &sockfd, connp);
|
||||||
|
if(ret != CURLE_OK)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if(sockfd == -1) {
|
||||||
|
failf(data, "Failed to get recent socket");
|
||||||
|
return CURLE_UNSUPPORTED_PROTOCOL;
|
||||||
|
}
|
||||||
|
|
||||||
|
*sfd = (curl_socket_t)sockfd; /* we know that this is actually a socket
|
||||||
|
descriptor so the typecast is fine here */
|
||||||
|
|
||||||
|
return CURLE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Receives data from the connected socket. Use after successful
|
||||||
|
* curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
|
||||||
|
* Returns CURLE_OK on success, error code on error.
|
||||||
|
*/
|
||||||
|
CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen, size_t *n)
|
||||||
|
{
|
||||||
|
curl_socket_t sfd;
|
||||||
|
CURLcode ret;
|
||||||
|
int ret1;
|
||||||
|
ssize_t n1;
|
||||||
|
struct connectdata *c;
|
||||||
|
struct SessionHandle *data = (struct SessionHandle *)curl;
|
||||||
|
|
||||||
|
ret = easy_connection(data, &sfd, &c);
|
||||||
|
if(ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
*n = 0;
|
||||||
|
ret1 = Curl_read(c, sfd, buffer, buflen, &n1);
|
||||||
|
|
||||||
|
if(ret1 == -1)
|
||||||
|
return CURLE_AGAIN;
|
||||||
|
|
||||||
|
if(n1 == -1)
|
||||||
|
return CURLE_RECV_ERROR;
|
||||||
|
|
||||||
|
*n = (size_t)n1;
|
||||||
|
|
||||||
|
return CURLE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sends data over the connected socket. Use after successful
|
||||||
|
* curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
|
||||||
|
*/
|
||||||
|
CURLcode curl_easy_send(CURL *curl, const void *buffer, size_t buflen,
|
||||||
|
size_t *n)
|
||||||
|
{
|
||||||
|
curl_socket_t sfd;
|
||||||
|
CURLcode ret;
|
||||||
|
ssize_t n1;
|
||||||
|
struct connectdata *c = NULL;
|
||||||
|
struct SessionHandle *data = (struct SessionHandle *)curl;
|
||||||
|
|
||||||
|
ret = easy_connection(data, &sfd, &c);
|
||||||
|
if(ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
*n = 0;
|
||||||
|
ret = Curl_write(c, sfd, buffer, buflen, &n1);
|
||||||
|
|
||||||
|
if(n1 == -1)
|
||||||
|
return CURLE_SEND_ERROR;
|
||||||
|
|
||||||
|
/* detect EAGAIN */
|
||||||
|
if((CURLE_OK == ret) && (0 == n1))
|
||||||
|
return CURLE_AGAIN;
|
||||||
|
|
||||||
|
*n = (size_t)n1;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "sslgen.h"
|
#include "sslgen.h"
|
||||||
|
#include "connect.h" /* Curl_getconnectinfo() */
|
||||||
|
|
||||||
/* Make this the last #include */
|
/* Make this the last #include */
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
@ -75,9 +76,6 @@ CURLcode Curl_getinfo(struct SessionHandle *data, CURLINFO info, ...)
|
|||||||
double *param_doublep=NULL;
|
double *param_doublep=NULL;
|
||||||
char **param_charp=NULL;
|
char **param_charp=NULL;
|
||||||
struct curl_slist **param_slistp=NULL;
|
struct curl_slist **param_slistp=NULL;
|
||||||
#ifdef MSG_PEEK
|
|
||||||
char buf;
|
|
||||||
#endif
|
|
||||||
int type;
|
int type;
|
||||||
|
|
||||||
if(!data)
|
if(!data)
|
||||||
@ -205,31 +203,7 @@ CURLcode Curl_getinfo(struct SessionHandle *data, CURLINFO info, ...)
|
|||||||
*param_charp = data->state.most_recent_ftp_entrypath;
|
*param_charp = data->state.most_recent_ftp_entrypath;
|
||||||
break;
|
break;
|
||||||
case CURLINFO_LASTSOCKET:
|
case CURLINFO_LASTSOCKET:
|
||||||
if((data->state.lastconnect != -1) &&
|
(void)Curl_getconnectinfo(data, param_longp, NULL);
|
||||||
(data->state.connc->connects[data->state.lastconnect] != NULL)) {
|
|
||||||
struct connectdata *c = data->state.connc->connects
|
|
||||||
[data->state.lastconnect];
|
|
||||||
*param_longp = c->sock[FIRSTSOCKET];
|
|
||||||
/* we have a socket connected, let's determine if the server shut down */
|
|
||||||
/* determine if ssl */
|
|
||||||
if(c->ssl[FIRSTSOCKET].use) {
|
|
||||||
/* use the SSL context */
|
|
||||||
if(!Curl_ssl_check_cxn(c))
|
|
||||||
*param_longp = -1; /* FIN received */
|
|
||||||
}
|
|
||||||
/* Minix 3.1 doesn't support any flags on recv; just assume socket is OK */
|
|
||||||
#ifdef MSG_PEEK
|
|
||||||
else {
|
|
||||||
/* use the socket */
|
|
||||||
if(recv((RECV_TYPE_ARG1)c->sock[FIRSTSOCKET], (RECV_TYPE_ARG2)&buf,
|
|
||||||
(RECV_TYPE_ARG3)1, (RECV_TYPE_ARG4)MSG_PEEK) == 0) {
|
|
||||||
*param_longp = -1; /* FIN received */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else
|
|
||||||
*param_longp = -1;
|
|
||||||
break;
|
break;
|
||||||
case CURLINFO_REDIRECT_URL:
|
case CURLINFO_REDIRECT_URL:
|
||||||
/* Return the URL this request would have been redirected to if that
|
/* Return the URL this request would have been redirected to if that
|
||||||
|
@ -261,6 +261,9 @@ curl_easy_strerror(CURLcode error)
|
|||||||
case CURLE_SSH:
|
case CURLE_SSH:
|
||||||
return "Error in the SSH layer";
|
return "Error in the SSH layer";
|
||||||
|
|
||||||
|
case CURLE_AGAIN:
|
||||||
|
return "Socket not ready for send/recv";
|
||||||
|
|
||||||
/* error codes not used by current libcurl */
|
/* error codes not used by current libcurl */
|
||||||
case CURLE_OBSOLETE4:
|
case CURLE_OBSOLETE4:
|
||||||
case CURLE_OBSOLETE10:
|
case CURLE_OBSOLETE10:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user