How do I set a timeout on HTTP requests in Java 11?

To set a timeout on HTTP requests in Java 11, you can use the HttpClient provided by the java.net.http module. The HttpClient API allows you to configure timeouts for requests in a convenient and standardized way.

Here’s how you can do it:

  1. Set a Connection Timeout: This controls the timeout when establishing a connection to the target server.
  2. Set a Read Timeout: This sets the timeout for reading data once the connection is established.

Here is an example demonstrating how to configure both:

Code Example

package org.kodejava.net.http;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;

public class HttpTimeoutExample {
   public static void main(String[] args) {
      // Create an HttpClient with a timeout configuration
      HttpClient client = HttpClient.newBuilder()
              .connectTimeout(Duration.ofSeconds(5)) // Set connection timeout
              .build();

      // Create an HttpRequest
      HttpRequest request = HttpRequest.newBuilder()
              .uri(URI.create("https://example.com"))
              .timeout(Duration.ofSeconds(10)) // Set request timeout
              .GET()
              .build();

      try {
         // Send the request and receive the response
         HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
         System.out.println("Response status code: " + response.statusCode());
         System.out.println("Response body: " + response.body());
      } catch (Exception e) {
         System.err.println("Request failed: " + e.getMessage());
      }
   }
}

Explanation

  1. Connection Timeout:
    • Configured on the HttpClient with connectTimeout(Duration).
    • This defines how long the client will wait while attempting to establish a connection with the server.
  2. Request Timeout:
    • Configured on the HttpRequest with timeout(Duration).
    • This defines how long the request will wait for a complete response after connection establishment.
  3. Error Handling:
    • For failed requests (e.g., timeouts), you should catch and handle exceptions like java.net.http.HttpTimeoutException or log a generic failure as shown above.

Notes

  • If either of the timeouts is exceeded, you will get an exception that can be handled to retry, alert, or further process as needed.
  • Both settings are optional. If not configured, the client will use default timeouts per its implementation.

How do I set custom headers in Java 11 HttpRequest?

In Java 11, the java.net.http package introduced the new HttpClient API, which simplifies working with HTTP requests and responses. To set custom headers for an HttpRequest, you can use the headers method or the setHeader method while building your request using the HttpRequest.Builder.

Here’s a step-by-step guide for setting custom headers:

Example Code

package org.kodejava.net.http;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class CustomHeadersExample {

   public static void main(String[] args) throws Exception {
      // Create an HttpClient
      HttpClient client = HttpClient.newHttpClient();

      // Create a request with custom headers
      HttpRequest request = HttpRequest.newBuilder()
              .uri(URI.create("https://example.com"))
              .header("Custom-Header", "HeaderValue") // Set custom single header
              .headers("Another-Header", "AnotherValue", "Yet-Another-Header", "YetAnotherValue") // Multiple headers
              .GET() // Specify HTTP method
              .build();

      // Send the request and print the response
      HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
      System.out.println("Response code: " + response.statusCode());
      System.out.println("Response body: " + response.body());
   }
}

Key Points in the Code

  1. Create HttpClient: The HttpClient is created using HttpClient.newHttpClient().
  2. Building the Request:
    • Use .header(String name, String value) to set a single custom header.
    • Use .headers(String... headers) to set multiple custom headers. Pass alternating key-value pairs as arguments.
    • Specify the URI and the HTTP method (GET, POST, etc.).
  3. Send the Request: The HttpClient sends the request using the .send() method and handles the response.

Notes:

  • Headers get overridden: If you call .header or .headers multiple times on the same HttpRequest.Builder, later calls for the same key will replace previous header values.
  • Thread Safety: The HttpClient instance is immutable and thread-safe, so you can reuse it for multiple requests.
  • Custom Headers: Use custom headers for tasks like authentication (e.g., Authorization headers), caching, or API versioning.

How do I handle HTTP response status codes with Java 11 HttpClient?

Handling HTTP response status codes with Java 11’s HttpClient API involves making a request, receiving a response, and then checking the status code returned in the response.

Here’s how you can do this:

Steps to Handle HTTP Response Status Codes

  1. Create the HttpClient: Build an instance of HttpClient.
  2. Build the Request: Define the HTTP request (e.g., GET, POST, etc.) with the target URI.
  3. Send the Request: Use HttpClient to send the request and receive an HttpResponse.
  4. Handle the Response: Extract and handle the HTTP response status code from the HttpResponse.

Here’s sample code to demonstrate these steps:

package org.kodejava.net.http;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class HttpClientExample {
    public static void main(String[] args) {
        // Step 1: Create an HttpClient
        HttpClient client = HttpClient.newHttpClient();

        // Step 2: Build the Request
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("https://jsonplaceholder.typicode.com/posts/1")) // Replace with your endpoint
                .GET()
                .build();

        try {
            // Step 3: Send the Request and Receive the Response
            HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

            // Step 4: Handle the Response Status Code
            int statusCode = response.statusCode();
            if (statusCode >= 200 && statusCode < 300) {
                // Handle successful responses (e.g., HTTP 200 OK)
                System.out.println("Response: " + response.body());
            } else if (statusCode >= 400 && statusCode < 500) {
                // Handle client errors (e.g., HTTP 404 Not Found)
                System.err.println("Client error: " + statusCode);
            } else if (statusCode >= 500) {
                // Handle server errors (e.g., HTTP 500 Internal Server Error)
                System.err.println("Server error: " + statusCode);
            } else {
                // Handle unexpected status codes
                System.err.println("Unexpected response: " + statusCode);
            }
        } catch (Exception e) {
            // Handle Exceptions
            e.printStackTrace();
        }
    }
}

Explanation

  1. HttpClient: The HttpClient is created using HttpClient.newHttpClient().
  2. HttpRequest: Use HttpRequest.Builder to create and configure an HTTP request.
  3. HttpResponse: The client.send() method sends the request and blocks until the response is received.
  4. Status Code Check: The response provides a status code via response.statusCode(). Different ranges of status codes are handled using conditional blocks.

Common HTTP Status Code Ranges

  • 2xx (Success): The request was successfully processed.
  • 3xx (Redirection): The requested resource has been moved.
  • 4xx (Client Errors): The client made an invalid request or the resource was not found.
    • Example: 404 (Not Found), 401 (Unauthorized)
  • 5xx (Server Errors): The server encountered an error while processing the request.
    • Example: 500 (Internal Server Error), 503 (Service Unavailable)

Advanced Handling

Advanced use cases might involve handling:

  • Headers: Access response or set request headers.
  • Timeouts: Set timeouts for requests.
  • Asynchronous Requests: Use HttpClient.sendAsync() for non-blocking requests.

This approach is the standard way to interact with HTTP codes in Java 11+ using the HttpClient API.

How do I send a POST request with JSON data using Java 11 HttpClient?

In Java 11, the HttpClient API was introduced as part of JEP 321, providing a standardized way to perform HTTP operations. To send a POST request with JSON data, you can use the HttpClient along with its HttpRequest object. Here’s a step-by-step guide and example:

Steps to Send POST Request with JSON Data in Java 11

  1. Create an instance of HttpClient:
    HttpClient is used to send HTTP requests and receive responses.

  2. Build the HttpRequest:
    Use the HttpRequest class to set the URI, HTTP method (POST), and add the JSON payload as the request body.

  3. Set the Content Type Header:
    Use the Content-Type header to specify that the content type of the request body is JSON.

  4. Send the request and handle the response:
    Use the HttpClient‘s send or sendAsync method to execute the request and retrieve the response.

Java Example: Sending a POST Request with JSON Data

package org.kodejava.net.http;

import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class PostRequestExample {

   public static void main(String[] args) {
      // 1. Create HttpClient instance
      try (HttpClient httpClient = HttpClient.newHttpClient()) {

         // 2. JSON data to send in the POST request
         String json = """
                 {
                     "title": "nesciunt quas odio",
                     "body": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
                     "userId": 1
                 }
                 """;

         // 3. Create HttpRequest and set headers
         HttpRequest request = HttpRequest.newBuilder()
                 .uri(URI.create("https://jsonplaceholder.typicode.com/posts/")) // Replace with your API endpoint
                 .header("Content-Type", "application/json")       // Set content type to JSON
                 .POST(HttpRequest.BodyPublishers.ofString(json))  // Set the JSON as body
                 .build();

         try {
            // 4. Send the request and get HttpResponse
            HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());

            // 5. Process the response
            if (response.statusCode() == 200 || response.statusCode() == 201) {
               System.out.println("Response: " + response.body());
            } else {
               System.err.println("Failed with HTTP error code: " + response.statusCode());
            }
         } catch (IOException | InterruptedException e) {
            e.printStackTrace();
         }
      }
   }
}

Breakdown of the Example:

  1. Create HttpClient:

    HttpClient httpClient = HttpClient.newHttpClient();
    

    This creates a new instance of the HttpClient, which will be used to send/receive requests.

  2. JSON Payload:
    A JSON string is created using Java’s multi-line string feature ("""), available starting from Java 13. Alternatively, you can concatenate strings or use external libraries like Jackson to generate the JSON.

  3. Build HttpRequest:

    HttpRequest request = HttpRequest.newBuilder()
           .uri(URI.create("https://jsonplaceholder.typicode.com/posts/"))
           .header("Content-Type", "application/json")
           .POST(HttpRequest.BodyPublishers.ofString(json))
           .build();
    
    • .uri(URI): Specifies the URI (endpoint) for the request.
    • .header("Content-Type", "application/json"): Adds a header specifying the content type.
    • .POST(HttpRequest.BodyPublishers.ofString(json)): Sets the request method to POST and attaches the JSON string as the body.
  4. Send Request and Receive Response:
    HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
    
    • httpClient.send: Performs the HTTP request.
    • HttpResponse.BodyHandlers.ofString(): Specifies that the response body should be treated as a String.
  5. Handle the Response:
    The response status code and body are processed accordingly (response.statusCode() and response.body()).

Sample Output

If the request is successful, you might see output like:

Response: {
  "title": "nesciunt quas odio",
  "body": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
  "userId": 1,
  "id": 101
}

Notes:

  1. Replace the URL (`https://jsonplaceholder.typicode.com/posts/`) with the actual endpoint you want to call.
  2. Add error handling and retries as needed for production environments.
  3. If advanced JSON manipulation is required, consider using libraries like Jackson or Gson to build the JSON payload programmatically.

Dependencies

No external dependencies are required; this is achievable with core Java 11+ classes.

How do I send a simple GET request using Java 11 HttpClient?

In Java 11, you can use the HttpClient to send HTTP requests easily. Here’s how you can send a simple GET request using HttpClient:

Full Example:

package org.kodejava.net.http;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class SimpleGetRequestExample {

   public static void main(String[] args) {
      try {
         // Create an HttpClient instance
         HttpClient httpClient = HttpClient.newHttpClient();

         // Create the GET request
         HttpRequest request = HttpRequest.newBuilder()
                 .uri(URI.create("https://jsonplaceholder.typicode.com/posts/1")) // Replace with your URL
                 .GET() // Optional since GET is the default
                 .build();

         // Send the request and get the response
         HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());

         // Print the response status and body
         System.out.println("Status code: " + response.statusCode());
         System.out.println("Response body: " + response.body());

      } catch (Exception e) {
         e.printStackTrace();
      }
   }
}

Explanation:

  1. HttpClient Instance:
    • Use HttpClient.newHttpClient() to create a new HttpClient. You can also customize the client for specific timeouts, authentication, or proxy configurations.
  2. HttpRequest Object:
    • Use HttpRequest.newBuilder() to create a request.
    • Use .uri(URI.create("URL")) to set the target URI.
    • Specify the HTTP method using .GET() (which is the default for HttpRequest).
  3. Send the HTTP Request:
    • Use the httpClient.send(request, HttpResponse.BodyHandlers.ofString()) method.
    • HttpResponse.BodyHandlers.ofString() specifies how the response body should be handled (in this case, as a string).
  4. Process the Response:
    • Access the HTTP response status code using response.statusCode().
    • Access the body using response.body().

Output for the Example:

If the request is successful, you would see the HTTP status code (e.g., 200) and the response body for the given URL printed in the console.

Status code: 200
Response body: {
  "userId": 1,
  "id": 1,
  "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
  "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
}

Alternative: Using Asynchronous Request

If you want to send the request asynchronously:

package org.kodejava.net.http;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.concurrent.CompletableFuture;

public class AsyncGetRequestExample {

   public static void main(String[] args) {
      HttpClient httpClient = HttpClient.newHttpClient();

      HttpRequest request = HttpRequest.newBuilder()
              .uri(URI.create("https://jsonplaceholder.typicode.com/posts/1"))
              .GET()
              .build();

      CompletableFuture<HttpResponse<String>> responseFuture = httpClient.sendAsync(request, HttpResponse.BodyHandlers.ofString());

      responseFuture.thenAccept(response -> {
         System.out.println("Status code: " + response.statusCode());
         System.out.println("Response body: " + response.body());
      }).join(); // Waits for the asynchronous computation to complete
   }
}

Benefits of Using HttpClient in Java 11:

  • Built-in support for HTTP/1.1 and HTTP/2.
  • Synchronous (send) and asynchronous (sendAsync) request capabilities.
  • Configurable features like timeouts and proxy settings.

By following these examples, you can handle simple GET requests in Java 11 effectively!

What is the purpose of String.strip() method of Java 11?

The purpose of the String.strip() method in Java 11 is to remove whitespaces from both the beginning and end of a string. This is very similar to the String.trim() method available in earlier versions of Java, but there is a key difference between them.

Here’s the difference:

  • String.strip(): Introduced in Java 11, strip() uses the unicode definition of whitespace. It removes not only space characters but also all other types of unicode-defined spaces, such as the thin space \u2009, etc.
  • String.trim(): Available from Java 1.0, trim() is more limited. It considers a whitespace to be any character whose ASCII value is less than or equal to 32 (a space, tab, newline, and a few other control characters).

Here are examples of how they work:

package org.kodejava.lang;

public class StringStripExample {
    public static void main(String[] args) {
        // String.strip()
        String first = " \u2009Hello  ";
        System.out.println(first.strip()); // Outputs "Hello"

        // String.trim()
        String second = " \u2009Hello  ";
        System.out.println(second.trim()); // Outputs "\u2009Hello"
    }
}

Output:

Hello
 Hello

Thus, strip() method is more comprehensive in removing different types of whitespace defined in Unicode, while trim() only removes ASCII control characters and spaces.

There are also String.stripLeading() and String.stripTrailing() methods that were introduced in Java 11, and they are similar to the strip() method, but they only remove the whitespace characters from either the beginning or the end of the string, respectively.

Here is what they do:

  • String.stripLeading(): This method removes any leading whitespace from the string. “Leading” in this context means any whitespace characters at the beginning of the string.
  • String.stripTrailing(): This method removes any trailing whitespace from the string. “Trailing” in this context means any whitespace characters at the end of the string.

Both stripLeading() and stripTrailing() use the Unicode definition of whitespace, the same as strip() method.

Here are examples of how they work:

package org.kodejava.lang;

public class StringStripLeadingTrailingExample {
    public static void main(String[] args) {
        // Strip leading whitespace
        String first = " \u2009Hello World  ";
        System.out.println(first.stripLeading());  // Outputs "Hello World  "

        // Strip trailing whitespace
        String second = " \u2009Hello World  ";
        System.out.println(second.stripTrailing()); // Outputs " \u2009Hello World"
    }
}

Output:

Hello World  
  Hello World

As demonstrated, stripLeading() removed the whitespace characters from the front of the string, and stripTrailing() removed the whitespace characters from the end of the string.

While \u00A0 is technically a type of whitespace (specifically, a non-breaking space or NBSP), it isn’t considered as such by the strip(), stripLeading(), and stripTrailing() methods, which follow the Character.isWhitespace(char) method’s definition of what constitutes a whitespace character.

According to the Java documentation, the Character.isWhitespace(char) method, which the strip() methods use, considers the following characters as whitespace:

  • ‘\t’ U+0009 HORIZONTAL TABULATION
  • ‘\n’ U+000A LINE FEED
  • ‘\u000B’ U+000B VERTICAL TABULATION
  • ‘\f’ U+000C FORM FEED
  • ‘\r’ U+000D CARRIAGE RETURN
  • ‘\u001C’ U+001C FILE SEPARATOR
  • ‘\u001D’ U+001D GROUP SEPARATOR
  • ‘\u001E’ U+001E RECORD SEPARATOR
  • ‘\u001F’ U+001F UNIT SEPARATOR
  • SPACE_SEPARATOR category types

The \u2009 (thin space) and \u0020 (space) are part of SPACE_SEPARATOR category according to Unicode standard and will be correctly stripped.

The \u00A0 (non-breaking space) is actually part of a different category called the NO-BREAK_SPACE and is not considered whitespace by Character.isWhitespace(char), so it won’t be stripped.

How do I create a string of repeated characters?

The following code demonstrates how to create a string of repeated characters. We use the String.repeat(int count) method introduced in Java 11. This method takes one parameter of type int which is the number of times to repeat the string. The count must be a positive number, a negative number will cause this method to throw java.lang.IllegalArgumentException.

In the snippet below, we use the method to repeat characters and draw some triangles. We combine the repeat() method with a for loop to draw the triangles.

package org.kodejava.basic;

public class StringRepeatDemo {
    public static void main(String[] args) {
        String star = "*";
        String fiveStars = star.repeat(5);
        System.out.println("fiveStars = " + fiveStars);

        String arrow = "-->";
        String arrows = arrow.repeat(10);
        System.out.println("arrows    = " + arrows);
    }
}

The outputs of the code snippet above are:

fiveStars = *****
arrows    = -->-->-->-->-->-->-->-->-->-->
package org.kodejava.basic;

public class StringRepeatDemo {
    public static void main(String[] args) {
        String asterisk = "#";
        for (int i = 1; i <= 10; i++) {
            System.out.println(asterisk.repeat(i));
        }
}

The outputs of the code snippet above are:

#
##
###
####
#####
######
#######
########
#########
##########
package org.kodejava.basic;

public class StringRepeatDemo {
    public static void main(String[] args) {
        int height = 10;
        for (int i = 1, j = 1; i <= height; i++, j += 2) {
            System.out.println(" ".repeat(height - i) + "*".repeat(j));
        }
    }
}

The outputs of the code snippet above are:

         *
        ***
       *****
      *******
     *********
    ***********
   *************
  ***************
 *****************
*******************

How do I get HTTP headers using HttpClient HEAD request?

The HTTP HEAD method is used for reading the headers information of a resource returned when accessing it using the HTTP GET method. Such request can be done before deciding to download a large resource to save bandwidth. The response to a HEAD method should not have a body, in the code below we use the HttpResponse.BodyHandlers.discarding(), which is a response body handler that discards the response body.

In the code snippet below we start by creating an instance of HttpClient, in this example we use the HttpClient.newBuilder().build() method. After creating the HttpClient we create the HttpRequest object. We set the HTTP method to HEAD by calling the method method() and pass a string “HEAD” as the method name and HttpRequest.BodyPublishers.noBody() a request body publisher which sends no request body.

The next step in the code below is to send the request and get the response headers from the HttpResponse object using the headers() method. The map() method of the HttpHeaders object give us a key-values of the headers returned by the server.

package org.kodejava.httpclient;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpHeaders;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class HeadRequestExample {
    public static void main(String[] args) throws Exception {
        HttpClient client = HttpClient.newBuilder().build();

        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("https://google.com"))
                .method("HEAD", HttpRequest.BodyPublishers.noBody())
                .build();

        HttpResponse<Void> response = client.send(request,
                HttpResponse.BodyHandlers.discarding());

        // Returns an unmodifiable multi-map view of this HttpHeaders.
        // The map contains key of string, with list of strings as
        // its value.
        HttpHeaders headers = response.headers();
        headers.map().forEach((key, values) ->
                System.out.printf("%s = %s%n", key, values));
    }
}

Here are the HTTP headers we got and printed out to the console screen:

:status = [301]
alt-svc = [quic=":443"; ma=2592000; v="46,43",h3-Q050=":443"; ma=2592000,h3-Q049=":443"; ma=2592000,h3-Q048=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,h3-T050=":443"; ma=2592000]
cache-control = [public, max-age=2592000]
content-length = [220]
content-type = [text/html; charset=UTF-8]
date = [Wed, 22 Apr 2020 14:41:49 GMT]
expires = [Fri, 22 May 2020 14:41:49 GMT]
location = [https://www.google.com/]
server = [gws]
x-frame-options = [SAMEORIGIN]
x-xss-protection = [0]

How do I read website content using HttpClient?

The HTTP Client API can be used to request HTTP resources over the network. This new API was introduced as a new API in Java 11. It supports HTTP/1.1 and HTTP/2 and also support both synchronous and asynchronous programming models. The code snippet below show you how to use the new API to read the content of a website page.

In the code below we start by creating a new instance of HttpClient using the newHttpClient() static method. This is equivalent to calling newBuilder().build(). This give us an instance of HttpClient with default settings like using the “GET” request method the as the default. Then we create an HttpRequest object using the newBuilder() method, set the request URI and call the build() method to build the HttpRequest object.

Next we send the request by calling the send() method of the HttpClient object. This will sends the given request, blocking if necessary to get the response. The returned HttpResponse object contains the response status, headers, and body as handled by given response body handler.

package org.kodejava.httpclient;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;

public class ReadWebsiteContent {
    public static void main(String[] args) throws Exception {
        // Creates HttpClient object with default configuration.
        HttpClient httpClient = HttpClient.newHttpClient();

        // Creates HttpRequest object and set the URI to be requested, 
        // when not defined the default request method is the GET request.
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("https://httpie.org/hello"))
                .GET()
                .build();

        // Sends the request and print out the returned response.
        HttpResponse<String> response = httpClient.send(request,
                HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8));

        System.out.println("Status Code: " + response.statusCode());
        System.out.println("Headers    : " + response.headers().toString());
        System.out.println("Body       : " + response.body());
    }
}

Here is the content of the website that we read using the code snippet above:

Status Code: 200
Headers    : java.net.http.HttpHeaders@2d299ad6 { {:status=[200], cf-cache-status=[DYNAMIC], cf-ray=[5875b78d5df2eb00-LAX], cf-request-id=[023d710c5b0000eb00b738f200000001], content-length=[116], content-type=[text/x-rst;charset=utf-8], date=[Tue, 21 Apr 2020 08:25:53 GMT], etag=["234b9a1fe19f125356a5396c8cc72d54493a2eef"], expect-ct=[max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"], server=[cloudflare], set-cookie=[__cfduid=d5bdb6d828be3bb85d0f1f4c2ff81041c1587457553; expires=Thu, 21-May-20 08:25:53 GMT; path=/; domain=.httpie.org; HttpOnly; SameSite=Lax]} }
Body       : 

Hello, World! 👋
~~~~~~~~~~~~~~~~

Thank you for trying out HTTPie 🥳

I hope this will become a friendship.