Reputation: 11
Problem: I am trying to send an email using Azure Communication Services Email API, but I keep encountering an EOF (End of File) error in the response.
Details:
The request is being made via a POST method with all necessary headers, including Authorization (HMAC-SHA256 signature), x-ms-date, x-ms-content-sha256, and Content-Type: application/json.
The body contains a valid JSON payload, including sender address, subject, content, and recipients.
Despite setting the headers and request body correctly, the server responds with an EOF error.
What I Tried:
I created a POST request with the Azure Communication Services Email API URL.
I included the necessary headers:
Authorization: Generated using HMAC-SHA256.
x-ms-date: RFC1123 formatted UTC timestamp.
x-ms-content-sha256: Base64-encoded SHA-256 hash of the request body.
Content-Type: Set to "application/json".
I created a JSON body with the required fields: senderAddress, subject, plainText, html, and recipients.
I used Go to make the HTTP request with all the required parameters.
What I Expected to Happen:
I expected the API to successfully send the email and return a response indicating the email was sent or queued for delivery.
What Actually Happened:
The API returned an error message with "EOF", indicating that something went wrong when handling the request. The response contained no additional information or details about the cause of the issue.
Upvotes: 1
Views: 132
Reputation: 1243
The EOF error indicates that the server closed the connection before the client was able to read the full response occurs due to Invalid JSON Payload and Header.
I used this document to send emails with the REST API using Azure Communication Services.
Refer this MSDOC for Azure Communication Services Authentication .
Below is the Go code for sending an email using Azure Communication Services with a PDF in the body .Adjust the body as needed based on the your requirements using above documentation.
package main
import (
"bytes"
"crypto/hmac"
"crypto/sha256"
"encoding/base64"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"time"
)
func main() {
fmt.Println("Azure Communication Services - Sign an HTTP request Tutorial")
resourceEndpoint := "https://AzureCommunicationServiceName.communication.azure.com(or)EndpointOfCommunicationService"
requestURI := fmt.Sprintf("%s/emails:send?api-version=2023-03-31", resourceEndpoint)
body := map[string]interface{}{
"headers": map[string]string{
"ClientCorrelationId": "123",
"ClientCustomHeaderName": "ClientCustomHeaderValue",
},
"senderAddress": "[email protected]",
"content": map[string]interface{}{
"subject": "An exciting offer especially for you!",
"plainText": "This exciting offer was created especially for you, our most loyal customer.",
"html": "<html><head><title>Exciting offer!</title></head><body><h1>This exciting offer was created especially for you, our most loyal customer.</h1></body></html>",
},
"recipients": map[string]interface{}{
"to": []map[string]string{
{"address": "[email protected]", "displayName": "sampath"},
},
"cc": []interface{}{},
"bcc": []interface{}{},
},
"attachments": []map[string]interface{}{
{
"name": "MyAttachment.pdf",
"contentType": "application/pdf",
"contentInBase64": "TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQ=",
},
},
"replyTo": []map[string]string{
{"address": "[email protected]", "displayName": "sampath"},
},
"userEngagementTrackingDisabled": true,
}
serializedBody, err := json.Marshal(body)
if err != nil {
panic(err)
}
date := time.Now().UTC().Format(http.TimeFormat)
fmt.Printf("x-ms-date: %s\n", date)
host := "sampath56ravi.unitedstates.communication.azure.com"
contentHash := computeContentHash(serializedBody)
fmt.Printf("x-ms-content-sha256: %s\n", contentHash)
stringToSign := fmt.Sprintf("POST\n/emails:send?api-version=2023-03-31\n%s;%s;%s", date, host, contentHash)
fmt.Printf("String to Sign: %s\n", stringToSign)
secret := "<AzureCommunicationAccesskey>"
signature := computeSignature(stringToSign, secret)
authorizationHeader := fmt.Sprintf("HMAC-SHA256 SignedHeaders=x-ms-date;host;x-ms-content-sha256&Signature=%s", signature)
fmt.Printf("Authorization Header: %s\n", authorizationHeader)
req, err := http.NewRequest(http.MethodPost, requestURI, bytes.NewBuffer(serializedBody))
if err != nil {
panic(err)
}
req.Header.Add("x-ms-date", date)
req.Header.Add("x-ms-content-sha256", contentHash)
req.Header.Add("Authorization", authorizationHeader)
req.Header.Add("Content-Type", "application/json")
client := &http.Client{}
response, err := client.Do(req)
if err != nil {
panic(err)
}
defer response.Body.Close()
responseBody, err := ioutil.ReadAll(response.Body)
if err != nil {
panic(err)
}
fmt.Printf("Response Status: %s\n", response.Status)
fmt.Printf("Response Body: %s\n", string(responseBody))
}
func computeContentHash(content []byte) string {
hasher := sha256.New()
hasher.Write(content)
hashedBytes := hasher.Sum(nil)
return base64.StdEncoding.EncodeToString(hashedBytes)
}
func computeSignature(stringToSign, secret string) string {
key, _ := base64.StdEncoding.DecodeString(secret)
h := hmac.New(sha256.New, key)
h.Write([]byte(stringToSign))
hashedBytes := h.Sum(nil)
return base64.StdEncoding.EncodeToString(hashedBytes)
}
Output:
Upvotes: 0