Imported Upstream version 7.53.1
[platform/upstream/curl.git] / docs / examples / sendrecv.c
index 41e283c..6623234 100644 (file)
@@ -62,10 +62,9 @@ int main(void)
   CURLcode res;
   /* Minimalistic http request */
   const char *request = "GET / HTTP/1.0\r\nHost: example.com\r\n\r\n";
-  curl_socket_t sockfd; /* socket */
-  long sockextr;
-  size_t iolen;
-  curl_off_t nread;
+  size_t request_len = strlen(request);
+  curl_socket_t sockfd;
+  size_t nsent_total = 0;
 
   /* A general note of caution here: if you're using curl_easy_recv() or
      curl_easy_send() to implement HTTP or _any_ other protocol libcurl
@@ -82,54 +81,76 @@ int main(void)
     curl_easy_setopt(curl, CURLOPT_CONNECT_ONLY, 1L);
     res = curl_easy_perform(curl);
 
-    if(CURLE_OK != res) {
-      printf("Error: %s\n", strerror(res));
+    if(res != CURLE_OK) {
+      printf("Error: %s\n", curl_easy_strerror(res));
       return 1;
     }
 
-    /* Extract the socket from the curl handle - we'll need it for waiting.
-     * Note that this API takes a pointer to a 'long' while we use
-     * curl_socket_t for sockets otherwise.
-     */
-    res = curl_easy_getinfo(curl, CURLINFO_LASTSOCKET, &sockextr);
+    /* Extract the socket from the curl handle - we'll need it for waiting. */
+    res = curl_easy_getinfo(curl, CURLINFO_ACTIVESOCKET, &sockfd);
 
-    if(CURLE_OK != res) {
+    if(res != CURLE_OK) {
       printf("Error: %s\n", curl_easy_strerror(res));
       return 1;
     }
 
-    sockfd = (curl_socket_t)sockextr;
+    printf("Sending request.\n");
 
-    /* wait for the socket to become ready for sending */
-    if(!wait_on_socket(sockfd, 0, 60000L)) {
-      printf("Error: timeout.\n");
-      return 1;
-    }
+    do {
+      /* Warning: This example program may loop indefinitely.
+       * A production-quality program must define a timeout and exit this loop
+       * as soon as the timeout has expired. */
+      size_t nsent;
+      do {
+        nsent = 0;
+        res = curl_easy_send(curl, request + nsent_total,
+            request_len - nsent_total, &nsent);
+        nsent_total += nsent;
 
-    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(res == CURLE_AGAIN && !wait_on_socket(sockfd, 0, 60000L)) {
+          printf("Error: timeout.\n");
+          return 1;
+        }
+      } while(res == CURLE_AGAIN);
 
-    if(CURLE_OK != res) {
-      printf("Error: %s\n", curl_easy_strerror(res));
-      return 1;
-    }
-    puts("Reading response.");
+      if(res != CURLE_OK) {
+        printf("Error: %s\n", curl_easy_strerror(res));
+        return 1;
+      }
 
-    /* read the response */
-    for(;;) {
-      char buf[1024];
+      printf("Sent %" CURL_FORMAT_CURL_OFF_T " bytes.\n",
+        (curl_off_t)nsent);
+
+    } while(nsent_total < request_len);
 
-      wait_on_socket(sockfd, 1, 60000L);
-      res = curl_easy_recv(curl, buf, 1024, &iolen);
+    printf("Reading response.\n");
 
-      if(CURLE_OK != res)
+    for(;;) {
+      /* Warning: This example program may loop indefinitely (see above). */
+      char buf[1024];
+      size_t nread;
+      do {
+        nread = 0;
+        res = curl_easy_recv(curl, buf, sizeof(buf), &nread);
+
+        if(res == CURLE_AGAIN && !wait_on_socket(sockfd, 1, 60000L)) {
+          printf("Error: timeout.\n");
+          return 1;
+        }
+      } while(res == CURLE_AGAIN);
+
+      if(res != CURLE_OK) {
+        printf("Error: %s\n", curl_easy_strerror(res));
         break;
+      }
 
-      nread = (curl_off_t)iolen;
+      if(nread == 0) {
+        /* end of the response */
+        break;
+      }
 
-      printf("Received %" CURL_FORMAT_CURL_OFF_T " bytes.\n", nread);
+      printf("Received %" CURL_FORMAT_CURL_OFF_T " bytes.\n",
+        (curl_off_t)nread);
     }
 
     /* always cleanup */