0

I have written a basic HTTP server in C++ that supports regular websites, but am now trying to extend it to support websockets. All of the networking and parsing is done by my own code, so no libraries -- except I copied and pasted some code for computing SHA1 and converting to base64.

I am reading several guides that describe how to handshake an incoming websocket connection, such as this: http://www.altdev.co/2012/01/23/writing-your-own-websocket-server/ and http://enterprisewebbook.com/ch8_websockets.html

I am stuck on the part where the server needs to take the key from the client's header and append the magic string onto it, then hash it with SHA1, encode it in base64, and send the result back as part of the accept header.

The specific part giving me trouble is the '==' in the key, and the '=' in the resulting string sent back by the server. I can't find any information stating what to do with these -- do I drop the == from the key before appending the magic string to it, or do I keep them on? Also, I can't figure out where the '=' at the end of the final server answer comes from -- and why the server's answer only has a single '=' and the client's key has two '='

Lastly, I am confused about why the magic string the server uses is in base16, but the key sent by the client's browser is already base64 -- do I need to convert the server string to base 64 before appending it, or does it not matter?

And when I convert to base 64, am I converting it as if each ascii symbol is the digit (so 'A' in the string would be 10), or am I converting the binary representation of the entire string to a string representing the original binary but with digits of base64?

Sorry if this is a stupid question, but I don't do much web programming so it's confusing to me when the articles assume the reader knows something about a part of the information.

Matt Swarthout
  • 167
  • 2
  • 10

1 Answers1

2

Pseudo code:

key_decoded = base64_decode(key64)
magic = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
response = SHA1(append(key_decoded, magic))
response_encoded = base64_encode(response)

The '=' at the end of base64 encoded data is there to pad the data to the required length. You don't have to do anything with it. (See here: Why does a base64 encoded string have an = sign at the end) Different lengths of input data may require different amounts of padding, hence the two encoded values have different amounts of padding in your example.

When you convert to base64, you don't assume anything about the input data, it is just input bytes. Do not convert 'a' to 10 (you seem to be thinking the ascii characters are supposed to be representing hexadecimal digits, which is unrelated)

Community
  • 1
  • 1
Lee Adams
  • 311
  • 1
  • 7