I recently had to sent a HTTP request containing some JSON in UTF-8 format.
However, when I received the text it seemed to be cut short.
This is a simple recreation of my code:
// I already have 3 variables:
// string socketIp, integer socketPort and string json.
// Where "json" contains my json string.
using (var socket = new TcpClient(socketIp, socketPort))
{
var headerContent = new StringBuilder();
headerContent.AppendLine("POST /someUrl/someReceiver.aspx HTTP/1.0");
headerContent.AppendLine("Accept: */*");
headerContent.AppendLine("Host: " + socketIp);
headerContent.AppendLine("Content-Type: application/javascript; charset=utf8");
headerContent.AppendLine("Content-Length: " + json.Length);
headerContent.AppendLine("Connection: Close");
headerContent.AppendLine();
var header = Encoding.UTF8.GetBytes(headerContent.ToString());
var body = Encoding.UTF8.GetBytes(json);
using (var stream = socket.GetStream())
{
stream.Write(header, 0, header.Length);
stream.Write(body, 0, body.Length);
}
}
Now this solution simply would not send the whole body to the recipient server. When I got it, it was always cut short.
I did notice, however, that the more non-english characters i added (such as \\u00c6
, \\u00d8
and \\u00c5
), the less content i would get.
So i thought of the issue of two-byte characters in UTF-8. And found out that i can use the Encoding
class to get the real length of the byte arrrays after being encoded with UTF-8, this is done using the GetByteCount()
method.
I added this calculation result to my stream.Write
length, and my Content-Length
header.
using (var socket = new TcpClient(socketIp, socketPort))
{
var body = Encoding.UTF8.GetBytes(json);
var bodyLength = Encoding.UTF8.GetByteCount(json);
var headerContent = new StringBuilder();
headerContent.AppendLine("POST /someUrl/someReceiver.aspx HTTP/1.0");
headerContent.AppendLine("Accept: */*");
headerContent.AppendLine("Host: " + socketIp);
headerContent.AppendLine("Content-Type: application/javascript; charset=utf-8");
headerContent.AppendLine("Content-Length: " + bodyLength);
headerContent.AppendLine("Connection: Close");
headerContent.AppendLine();
var headerString = headerContent.ToString();
var header = Encoding.UTF8.GetBytes(headerString);
var headerLength = Encoding.UTF8.GetByteCount(headerString);
using (var stream = socket.GetStream())
{
stream.Write(header, 0, headerLength);
stream.Write(body, 0, bodyLength);
}
}
And bingo! It works as expected! The length is now correct and the stream is not cut short.