Jen143
Jen143

Reputation: 835

Error in HttpWebRequest stream exceed the Content-Length bytes size

This is adding shipment to Orderhive API and the authentication is AWS4 Signature. This is the full error: Bytes to be written to the stream exceed the Content-Length bytes size specified. Below is the implementation that causes the error.

 var headers = new Dictionary<string, string>
                {
                    {AWS4SignerBase.X_Amz_Content_SHA256, contentHashString},
                    {"content-length", requestBody.Length.ToString()},
                    {"content-type", "application/json"},
                    {"id_token", _credentails.id_token},
                    {"X-Amz-Security-Token",  _credentails.session_token}
                };

public string InvokeHttpRequest(Uri endpointUri,
                                             string httpMethod,
                                             IDictionary<string, string> headers,
                                             string requestBody)
        {
            string responseBody = "";
            try
            {
                var request = ConstructWebRequest(endpointUri, httpMethod, headers);

                if (!string.IsNullOrEmpty(requestBody))
                {
                    var buffer = new byte[8192]; // arbitrary buffer size                        
                    var requestStream = request.GetRequestStream();
                    using (var inputStream = new MemoryStream(Encoding.UTF8.GetBytes(requestBody)))
                    {
                        var bytesRead = 0;
                        while ((bytesRead = inputStream.Read(buffer, 0, buffer.Length)) > 0)
                        {
                            requestStream.Write(buffer, 0, bytesRead);
                        }
                    }
                }

                responseBody = CheckResponse(request);
            }
            catch (WebException ex)
            {
                using (var response = ex.Response as HttpWebResponse)
                {
                    if (response != null)
                    {
                        var errorMsg = ReadResponseBody(response);
                        Console.WriteLine("\n-- HTTP call failed with exception '{0}', status code '{1}'", errorMsg, response.StatusCode);
                    }
                }
            }

            return responseBody;
        }



public HttpWebRequest ConstructWebRequest(Uri endpointUri,
                                                         string httpMethod,
                                                         IDictionary<string, string> headers)
        {
            var request = (HttpWebRequest)WebRequest.Create(endpointUri);
            request.Method = httpMethod;

            foreach (var header in headers.Keys)
            {
                // not all headers can be set via the dictionary
                if (header.Equals("host", StringComparison.OrdinalIgnoreCase))
                    request.Host = headers[header];
                else if (header.Equals("content-length", StringComparison.OrdinalIgnoreCase))
                    request.ContentLength = long.Parse(headers[header]);
                else if (header.Equals("content-type", StringComparison.OrdinalIgnoreCase))
                    request.ContentType = headers[header];
                else
                    request.Headers.Add(header, headers[header]);
            }

            return request;
        }

I can't figure out how can I change the code to fix this. Please help. Thank you.

Upvotes: 0

Views: 2554

Answers (1)

Oguz Ozgul
Oguz Ozgul

Reputation: 7187

It seems that you are specifying a content-length which is incompatible with the number of bytes you write to the upstream.

While you are setting the content length with:

"content-length", requestBody.Length.ToString()

You are sending as content the following:

Encoding.UTF8.GetBytes(requestBody)

The string's Length and the number of bytes in its UTF8 binary representation differs here.

Please try setting the content-length as such:

"content-length", Encoding.UTF8.GetByteCount(requestBody).ToString()

Upvotes: 1

Related Questions