Since March 10, 2003 - Version 2
hypothetic.org

MSN Messenger Protocol

General - HTTP Connections

Back To Normal Layout

What is HTTP?

The HyperText Transfer Protocol (HTTP) is the application protocol used by the web. This section assumes you have a basic understanding of HTTP version 1.1, as defined in RFC 2616. There is no standard way of using HTTP for interactive applications - the method described here is just the way Microsoft chose to do it. The method described here has nothing to do with the HTTP "CONNECT" method.

How does HTTP work with MSN?

Microsoft use gateway.messenger.hotmail.com, port 80, as their dispatch server for HTTP connections. Unlike messenger.hotmail.com this server has never been seen to transfer clients to another notification server. However, there is a transfer-like function in MSN's HTTP method.

Though HTTP is most often used for transferring HTML documents (hence the name), it's entirely capable of transferring any kind of data. In HTTP, there is no way for the server to send a message to the client without the client requesting it first. MSN Messenger clients send commands in the body of HTTP an request, and the server queues commands to send in the body of a response. When the client has no commands to send for a few seconds, it should "poll" the server for new messages. The official client polls the server once every two seconds.

Once a client has sent an HTTP request, it must wait for the response to come back before sending another request. For example, if you poll the server then send a command without waiting for the response to the poll, you will receive an HTTP 400 error (bad request).

Normally, a single connection to the server is kept alive throughout an MSN Messenger session, but the protocol seems to support a connection being broken and re-established without the session being affected. This has not yet been tested in practice, though.

In MSNP8, the profile you receive when logging in has "ClientPort" set to 0.

HTTP Issues in the Official Client

Most of the testing for this page was done with version 5 of the official client, which has fairly poor support for HTTP connections, including several bugs and design flaws. Version 5 is the first even to make the option easily available, so it has presumably not been thoroughly tested. Hopefully, this will be improved in future versions.

The official client misbehaves badly when using HTTP proxies operating on a port other than 80. It doesn't always obey the "one request at a time" rule, so it occasionally gets kicked off with a 400 error. The configuration menu confusingly associates "using an HTTP proxy server" with "using a SOCKS proxy server". The proxy server in an HTTP session performs a completely different function to that in a SOCKS connection, and is most likely not required by the protocol. More seriously, some HTTP proxies are intercept and proxy HTTP connections without the client's knowledge. The official client can't handle these "transparent proxies" at all. Finally, if you specify an HTTP proxy server, the official client will ignore the setting to enable or disable its use. Instead, it will try to connect directly to MSN Messenger first, then through HTTP if that fails.

Protocol Description

In an HTTP connection, commands are sent to MSN Messenger with POST requests to a CGI script, and received in responses to those commands. The initial request opens a new notification or switchboard server session, and (for a notification server session) should be sent to gateway.messenger.hotmail.com or (for a switchboard server session) the IP address given in an XFR. Commands you wish to send are contained in the entity-body, one per request (including one in the initial request). When there are no messages to send for a few seconds (two seconds in the official client), the client should poll the server for queued commands.

Server responses contain an "X-MSN-Messenger" header, which includes an IP address to send the next request to and a session ID to send with the next request. If the session is being closed, this header will also include a "Session=close" value. The session ID seems always to be a long number (which remains constant across a session), followed by a dot, then a short number (which changes with each response). Don't rely on this observation - treat it as an arbitrary string.

The official client tries to keep a single connection open throughout a session, though the session ID is presumably included in case a proxy server along the way closes the connection in the middle of a session. Assuming the server doesn't terminate your session when a connection is closed, you must send OUT to close your connection (or wait for a time-out on the server).

The script is /gateway/gateway.dll, and it takes the following arguments:

Action
Either "open" (to open a new session) or "poll" (to receive queued commands without sending any commands). Non-empty requests after the first don't include an "Action" parameter.
Server
Used with "Action=open" to specify the type of server to open. The value can be either "NS" (to open a Notification Server session) or "SB" (to open a switchboard session).
IP
Used with "Action=open" to specify the IP address or domain name of the server.
SessionID
Sent with every request after the first in a session, this is the string given in the previous response.

The official client sends "Proxy-Connection: Keep-Alive" and "Pragma: No-Cache" headers, which are HTTP/1.0 headers that have been replaced by "Connection: Keep-Alive" in HTTP/1.1. Presumably, these are included incase requests pass through old or buggy proxies on the way to the server. The official client also sends "User-Agent: MSMSGS", though the server doesn't discriminate based on the user-agent.

Examples Requests and Responses

Because the URLs in the HTTP examples are so large, having them on this page caused horizontal scrolling which caused difficulties in reading the information above. You may see the examples in this page.

Copyright ©2002-2003 to Mike Mintz.
<http://www.mikemintz.com/>