Annotation of embedaddon/curl/docs/examples/sendrecv.c, revision 1.1
1.1 ! misho 1: /***************************************************************************
! 2: * _ _ ____ _
! 3: * Project ___| | | | _ \| |
! 4: * / __| | | | |_) | |
! 5: * | (__| |_| | _ <| |___
! 6: * \___|\___/|_| \_\_____|
! 7: *
! 8: * Copyright (C) 1998 - 2019, 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 https://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: /* <DESC>
! 23: * An example of curl_easy_send() and curl_easy_recv() usage.
! 24: * </DESC>
! 25: */
! 26:
! 27: #include <stdio.h>
! 28: #include <string.h>
! 29: #include <curl/curl.h>
! 30:
! 31: /* Auxiliary function that waits on the socket. */
! 32: static int wait_on_socket(curl_socket_t sockfd, int for_recv, long timeout_ms)
! 33: {
! 34: struct timeval tv;
! 35: fd_set infd, outfd, errfd;
! 36: int res;
! 37:
! 38: tv.tv_sec = timeout_ms / 1000;
! 39: tv.tv_usec = (timeout_ms % 1000) * 1000;
! 40:
! 41: FD_ZERO(&infd);
! 42: FD_ZERO(&outfd);
! 43: FD_ZERO(&errfd);
! 44:
! 45: FD_SET(sockfd, &errfd); /* always check for error */
! 46:
! 47: if(for_recv) {
! 48: FD_SET(sockfd, &infd);
! 49: }
! 50: else {
! 51: FD_SET(sockfd, &outfd);
! 52: }
! 53:
! 54: /* select() returns the number of signalled sockets or -1 */
! 55: res = select((int)sockfd + 1, &infd, &outfd, &errfd, &tv);
! 56: return res;
! 57: }
! 58:
! 59: int main(void)
! 60: {
! 61: CURL *curl;
! 62: /* Minimalistic http request */
! 63: const char *request = "GET / HTTP/1.0\r\nHost: example.com\r\n\r\n";
! 64: size_t request_len = strlen(request);
! 65:
! 66: /* A general note of caution here: if you're using curl_easy_recv() or
! 67: curl_easy_send() to implement HTTP or _any_ other protocol libcurl
! 68: supports "natively", you're doing it wrong and you should stop.
! 69:
! 70: This example uses HTTP only to show how to use this API, it does not
! 71: suggest that writing an application doing this is sensible.
! 72: */
! 73:
! 74: curl = curl_easy_init();
! 75: if(curl) {
! 76: CURLcode res;
! 77: curl_socket_t sockfd;
! 78: size_t nsent_total = 0;
! 79:
! 80: curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
! 81: /* Do not do the transfer - only connect to host */
! 82: curl_easy_setopt(curl, CURLOPT_CONNECT_ONLY, 1L);
! 83: res = curl_easy_perform(curl);
! 84:
! 85: if(res != CURLE_OK) {
! 86: printf("Error: %s\n", curl_easy_strerror(res));
! 87: return 1;
! 88: }
! 89:
! 90: /* Extract the socket from the curl handle - we'll need it for waiting. */
! 91: res = curl_easy_getinfo(curl, CURLINFO_ACTIVESOCKET, &sockfd);
! 92:
! 93: if(res != CURLE_OK) {
! 94: printf("Error: %s\n", curl_easy_strerror(res));
! 95: return 1;
! 96: }
! 97:
! 98: printf("Sending request.\n");
! 99:
! 100: do {
! 101: /* Warning: This example program may loop indefinitely.
! 102: * A production-quality program must define a timeout and exit this loop
! 103: * as soon as the timeout has expired. */
! 104: size_t nsent;
! 105: do {
! 106: nsent = 0;
! 107: res = curl_easy_send(curl, request + nsent_total,
! 108: request_len - nsent_total, &nsent);
! 109: nsent_total += nsent;
! 110:
! 111: if(res == CURLE_AGAIN && !wait_on_socket(sockfd, 0, 60000L)) {
! 112: printf("Error: timeout.\n");
! 113: return 1;
! 114: }
! 115: } while(res == CURLE_AGAIN);
! 116:
! 117: if(res != CURLE_OK) {
! 118: printf("Error: %s\n", curl_easy_strerror(res));
! 119: return 1;
! 120: }
! 121:
! 122: printf("Sent %" CURL_FORMAT_CURL_OFF_T " bytes.\n",
! 123: (curl_off_t)nsent);
! 124:
! 125: } while(nsent_total < request_len);
! 126:
! 127: printf("Reading response.\n");
! 128:
! 129: for(;;) {
! 130: /* Warning: This example program may loop indefinitely (see above). */
! 131: char buf[1024];
! 132: size_t nread;
! 133: do {
! 134: nread = 0;
! 135: res = curl_easy_recv(curl, buf, sizeof(buf), &nread);
! 136:
! 137: if(res == CURLE_AGAIN && !wait_on_socket(sockfd, 1, 60000L)) {
! 138: printf("Error: timeout.\n");
! 139: return 1;
! 140: }
! 141: } while(res == CURLE_AGAIN);
! 142:
! 143: if(res != CURLE_OK) {
! 144: printf("Error: %s\n", curl_easy_strerror(res));
! 145: break;
! 146: }
! 147:
! 148: if(nread == 0) {
! 149: /* end of the response */
! 150: break;
! 151: }
! 152:
! 153: printf("Received %" CURL_FORMAT_CURL_OFF_T " bytes.\n",
! 154: (curl_off_t)nread);
! 155: }
! 156:
! 157: /* always cleanup */
! 158: curl_easy_cleanup(curl);
! 159: }
! 160: return 0;
! 161: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>