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>