Annotation of embedaddon/curl/docs/examples/sendrecv.c, revision 1.1.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>