Return to sendrecv.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / curl / docs / examples |
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: }