Blog Post

Apps on Azure Blog
3 MIN READ

How to use OpenSSL to Send HTTP(S) Requests

KevinLi's avatar
KevinLi
Icon for Microsoft rankMicrosoft
May 22, 2025

OpenSSL is a powerful tool for working with SSL/TLS, but it can also be used to send custom HTTP requests, which is very useful for debugging and learning how HTTP(S) works at a low level.

 

1. How It Works

Normally, tools like curl or your browser handle everything behind the scenes: they perform the TLS handshake and build the HTTP request. With OpenSSL, you manually create the HTTP request, and OpenSSL only handles the encrypted connection.

  • TLS Handshake: OpenSSL’s s_client command establishes a secure (TLS) connection with the server.
  • Send Request: You pipe (or redirect) a raw HTTP request into s_client. The server processes it and sends a response over the secure channel.

 

2. Sending a GET Request

Here’s how you send a simple GET request to www.bing.com:

(
  printf "GET / HTTP/1.1\r\n"
  printf "Host: www.bing.com\r\n"
  printf "Connection: close\r\n"
  printf "\r\n"
) | openssl s_client -connect www.bing.com:443 -servername www.bing.com -quiet

 

Key points:

  • Each line ends with \r\n.
  • Host header is required for HTTP/1.1.
  • The empty line at the end separates headers from the body (no body in GET).
  • -servername ensures the correct certificate (SNI).
  • -quiet hides handshake details and shows just the HTTP response. It adds -ign_eof automatically
  • -ign_eof wait until get response from server

 

3. Sending a POST Request

POST requests have a body. For example, sending JSON to httpbin.org:

echo -n '{"name": "Kevin"}' > body.json
BODYLEN=$(wc -c < body.json)
(
  printf "POST /post HTTP/1.1\r\n"
  printf "Host: httpbin.org\r\n"
  printf "Content-Type: application/json\r\n"
  printf "Content-Length: %d\r\n" "$BODYLEN"
  printf "Connection: close\r\n"
  printf "\r\n"
  cat body.json
) | openssl s_client -connect httpbin.org:443 -servername httpbin.org -quiet

Key points:

  • Set Content-Type and Content-Length correctly.
  • Use cat to add the POST body.

Note: it may throw error "unexpected eof while reading:../ssl/record/rec_layer_s3.c:317:", it appears due to server closed the connection immediately, normally it can be ignored.

4. Uploading a File (PUT Example)

You can upload files (e.g., to Azure Blob Storage) with PUT. Suppose you have a file /tmp/test.txt and an Azure SAS URL:

FILE="test.txt"
ACCOUNT="youraccount"
CONTAINER="yourcontainer"
BLOB="test.txt"
SAS="your-sas-token"
LENGTH=$(wc -c < "$FILE")
(
  printf "PUT /%s/%s?%s HTTP/1.1\r\n" "$CONTAINER" "$BLOB" "$SAS"
  printf "Host: %s.blob.core.windows.net\r\n" "$ACCOUNT"
  printf "x-ms-blob-type: BlockBlob\r\n"
  printf "Content-Length: %d\r\n" "$LENGTH"
  printf "Connection: close\r\n"
  printf "\r\n"
  cat "$FILE"
) | openssl s_client -connect "$ACCOUNT.blob.core.windows.net:443" -servername "$ACCOUNT.blob.core.windows.net" -quiet

5. Common Pitfalls & Tips

  • Always end headers with \r\n, and include an empty line before the body.
  • Content-Length must exactly match the body size (in bytes).
  • Use the correct Host and -servername for TLS/SNI.
  • If you get 400 Bad Request, check header formatting and line endings.
  • Use -quiet or -ign_eof to see the HTTP response clearly.

 

Summary:

OpenSSL lets you see and control every detail of your HTTPS requests. It’s great for learning, debugging, and troubleshooting complex HTTP or SSL/TLS issues. Start simple—try GET and POST—then experiment with more advanced requests!

 

Published May 22, 2025
Version 1.0
No CommentsBe the first to comment