I am working with Haproxy and need to read the v2 header from TCP stream, according to spec it is supposed to have first 13 bytes following:
\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A\x02
in byte
{byte[13]}
[0]: 13
[1]: 10
[2]: 13
[3]: 10
[4]: 0
[5]: 13
[6]: 10
[7]: 81
[8]: 85
[9]: 73
[10]: 84
[11]: 10
[12]: 2
however I get
[0]: 13
[1]: 10
[2]: 0
[3]: 13
[4]: 10
[5]: 81
[6]: 85
[7]: 73
[8]: 84
[9]: 10
[10]: 33
[11]: 17
[12]: 0
My read does seem to be missing first two bytes 13 10
from the spec, however ending seems to differ too, I can't seem to figure out why...
What is even more confusing I can't see from
IP address (54.219.177.232) nor to
(45.32.136.69) nowhere in the header they are supposed to be 17th byte onward
Count = 91
[0]: 12
[1]: 180
[2]: 183
[3]: 211
[4]: 173
[5]: 172
[6]: 31
[7]: 23
[8]: 237
[9]: 228
[10]: 70
[11]: 1
[12]: 187
[13]: 22
[14]: 3
[15]: 1
[16]: 0
[17]: 178
[18]: 1
[19]: 0
[20]: 0
[21]: 174
[22]: 3
[23]: 3
[24]: 65
[25]: 71
[26]: 172
[27]: 83
[28]: 43
[29]: 146
[30]: 158
[31]: 30
[32]: 150
[33]: 85
[34]: 84
[35]: 34
[36]: 158
[37]: 111
[38]: 242
[39]: 247
[40]: 173
[41]: 198
[42]: 13
[43]: 133
[44]: 9
[45]: 39
[46]: 111
[47]: 9
[48]: 44
[49]: 64
[50]: 232
[51]: 25
[52]: 14
[53]: 51
[54]: 110
[55]: 76
[56]: 0
[57]: 0
[58]: 32
[59]: 74
[60]: 74
[61]: 192
[62]: 43
[63]: 192
[64]: 47
[65]: 192
[66]: 44
[67]: 192
[68]: 48
[69]: 204
[70]: 169
[71]: 204
[72]: 168
[73]: 204
[74]: 20
[75]: 204
[76]: 19
[77]: 192
[78]: 19
[79]: 192
[80]: 20
[81]: 0
[82]: 156
[83]: 0
[84]: 157
[85]: 0
[86]: 47
[87]: 0
[88]: 53
[89]: 0
[90]: 10`
Code that reads header looks following:
var childSocketThread = new Thread(() =>
{
var getOrPostHttp1Acc = new List<byte>();
var getOrPostHttp1 = new byte[1];
while (getOrPostHttp1[0] != 10)
{
socket.Receive(getOrPostHttp1);
getOrPostHttp1Acc.Add(getOrPostHttp1[0]);
}
bool isGet = Encoding.ASCII.GetString(getOrPostHttp1Acc.ToArray()).ToUpper().Contains("GET");
byte[] proxyv2headerIdentifier = new byte[13];
socket.Receive(proxyv2headerIdentifier);
var proxyv2header = new List<byte>();
var proxyv2HeaderBuffer = new byte[1];
if(proxyv2headerIdentifier.SequenceEqual(proxyv2HeaderStartRequence))//TODO:uncomment this, hardcoded (true) is only for testing
{
while (proxyv2HeaderBuffer[0] != 10)
{
socket.Receive(proxyv2HeaderBuffer);
proxyv2header.Add(proxyv2HeaderBuffer[0]);
}
string headerString = $"proxyv2:{Encoding.ASCII.GetString(proxyv2header.ToArray())}";
byte[] bodyBuff = new byte[0];
byte[] buffer = new byte[1];
int contentLength = 0;
while (!headerString.Contains("\r\n\r\n"))
//at this point header is read into proxyv2header ....
Where am I misreading specification, or doing something wrong?
Ok I have figured this one myself...
mistake was to read the http method first (if it's GET
or POST
) haproxy does not start with that... so removing method read
var getOrPostHttp1Acc = new List<byte>();
var getOrPostHttp1 = new byte[1];
while (getOrPostHttp1[0] != 10)
{
socket.Receive(getOrPostHttp1);
getOrPostHttp1Acc.Add(getOrPostHttp1[0]);
}
bool isGet = Encoding.ASCII.GetString(getOrPostHttp1Acc.ToArray()).ToUpper().Contains("GET");
and reducing start sequence to 12 bytes did it...
In regards to IP, it was hiding in the plain sight all this time...
Hope this saves you some time.