Access HTTP headers used in the establishment of a TLS connection using Websockets

I am running a TLS-enabled Server. Most of the Python libraries seem to abstract away all the socket level bind/listen/accept/upgrade to TLS parts of the initial handshake process. I have a need to capture an “ORIGIN” header that is sent by my Client to my Server in the middle of this process - I think in the Upgrade request portion of accepting the connection. Does anyone have any examples or instructions to help me obtain this? I cannot seem to find a way! :slight_smile:

There are no header to establish TLS.

In https: you start out by connecting over a TLS session then send the HTTP header over that.

But maybe you mean when you start with http: and that redirects you to https:?

This could also be a reference to Server Name Indication (SNI) which is part of the TLS negotiation. It’s not a header as those are part of HTTP, but it is part of the connection setup.

1 Like

I have added Websockets to the question title as it was probably misleading just to talk about TLS in isolation.

I think that when a client starts a Websockets conversation, it sends a HTTP request to upgrade to WS. It then exchanges Certs and negotiates the handshake via HTTP before both sides agree to start talking WS.

In all the lovely Python encapsulation of this handshake, I haven’t found a way to see these interim HTTP headers. Node.js Websockets library makes data available in an “info” attribute but I haven’t found any equivalent in python. That’s my question, has anyone seen anything in this context.

Please update the subject of the topic too, that will help others who may find it interesting.

Which package(s) are you using for the basic HTTP server functionality in your application now?

FYI if you have not read it this is the websocket RFC RFC 6455: The WebSocket Protocol

That is not the order things happen in.
This is the sequence I expect to happen.

  1. TLS to host - exchange certs etc as defined for TLS protocol
  2. exchange headers using HTTP protocol to switch to websocket
  3. send whatever is defined for your protocol

Which header are you after?
Something from the TLS exchange?
Something from the Websocket HTTP exchange?

Thanks for this. In your referenced RFC on page 5, you’ll see the various headers sent by the client to the server during the upgrade from HTTP to TLS handshake. I’m trying to access in the server code - for example - the “Origin” header sent by the client. The standard library “ssl” facility to “accept” a connection wraps all the various work involved in processing these headers but I don’t think if I use that convenient library, that I seem to be able to see the header content once it’s done it’s thing processing them all into an accepted socket - Hopefully I am wrong!

import socket
import ssl

context = ssl._create_unverified_context(ssl.PROTOCOL_TLS_SERVER)
context.load_cert_chain(certfile=‘…’,keyfile=‘…’)
context.check_hostname = False
with socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) as sock:
 sock.bind((‘’, 8001))
 print (“socket bound to %s” %(8001))
 sock.listen(5)
 print (“socket is listening”)

 while True:
  with context.wrap_socket(sock, server_side=True) as ssock:
   connection, addr = ssock.accept()
   print (‘Got connection from’, addr )

   ##### Do stuff dependent on the ORIGIN header #####

   connection.close()

   break

This module doesn’t do anything with websockets. Instead, look on pypi for a module like, well, websockets and see what it can do for you. I’m not sure what you need the headers for but it should be in there somewhere.

Thankyou Chris. The standard SSL library doe snot seem to be as rich as the one that you suggested. For others I did made a little progress with the standard library’s “unsupported”:

context._msg_callback = ...

But as Chris suggested I think that a move to this Websockets instead might help me. So I’ll give that a go - thanks!

This isn’t what happens; the connection is already TLS when the Upgrade header is presented and the upgrade to Websocket happens. That existing connection is then converted from passing HTTP requests and responses to passing Websocket protocol messages. Quoting that page of the RFC:

   Once the client and server have both sent their handshakes, and if
   the handshake was successful, then the data transfer part starts.
   This is a two-way communication channel where each side can,
   independently from the other, send data at will.

If your goal is obtain the value of a header which was present in the request that contained the Upgrade header, then TLS is not involved at all and focusing on it will likely lead you in the wrong direction.

If you are in control of the server which is receiving the HTTP request from the client, then before ti sends its answer in the handshake sequence you should be able to inspect the headers in the request.

That’s because websockets aren’t its job :slight_smile: The standard SSL library does … SSL. (Or TLS if you want to be technical.) That’s the encryption layer - the difference between http:// and https://, or between ws:// and wss:// - and the only part you might be looking at there is the server’s certificate. HTTP is built on top of SSL, and websockets are built on top of HTTP.

1 Like