add-Sec-WebSocket-Draft-and-protocol-autodetect.patch

Signed-off-by: Andy Green <andy@warmcat.com>
diff --git a/lib/handshake.c b/lib/handshake.c
index 05547b0..2ca7938 100644
--- a/lib/handshake.c
+++ b/lib/handshake.c
@@ -112,6 +112,24 @@
 			/* completed header processing, but missing some bits */
 			goto bail;
 
+		/* are we happy about the draft version client side wants? */
+
+		if (wsi->utf8_token[WSI_TOKEN_DRAFT].token) {
+			wsi->ietf_spec_revision =
+				   atoi(wsi->utf8_token[WSI_TOKEN_DRAFT].token);
+			switch (wsi->ietf_spec_revision) {
+			case 76:
+				break;
+			case 2:
+				break;
+			default:
+				fprintf(stderr, "Rejecting handshake on seeing "
+					"unsupported draft request %d\n",
+						       wsi->ietf_spec_revision);
+				goto bail;
+			}
+		}
+
 		/* Make sure user side is happy about protocol */
 
 		if (wsi->callback)
diff --git a/lib/libwebsockets.c b/lib/libwebsockets.c
index ec5226c..11ab790 100644
--- a/lib/libwebsockets.c
+++ b/lib/libwebsockets.c
@@ -69,7 +69,6 @@
  * libwebsocket_create_server() - Create the listening websockets server
  * @port:	Port to listen on
  * @callback:	The callback in user code to perform actual serving
- * @protocol:	Which version of the websockets protocol (currently 76)
  * @user_area_size:	How much memory to allocate per connection session
  * 			which will be used by the user application to store
  * 			per-session data.  A pointer to this space is given
@@ -99,13 +98,13 @@
  */
 
 int libwebsocket_create_server(int port,
-		int (*callback)(struct libwebsocket *,
-				enum libwebsocket_callback_reasons, 
-				void *, void *, size_t),
-					int protocol, size_t user_area_size,
-				const char * ssl_cert_filepath,
-				const char * ssl_private_key_filepath,
-				int gid, int uid)
+			       int (*callback)(struct libwebsocket *,
+					enum libwebsocket_callback_reasons, 
+					void *, void *, size_t),
+			       size_t user_area_size,
+			       const char * ssl_cert_filepath,
+			       const char * ssl_private_key_filepath,
+			       int gid, int uid)
 {
 	int n;
 	int client;
@@ -186,20 +185,6 @@
 		/* SSL is happy and has a cert it's content with */
 	}
 #endif
-
-	/* sanity check */
-
-	switch (protocol) {
-	case 0:
-	case 2:
-	case 76:
-		fprintf(stderr, " Using protocol v%d\n", protocol);
-		break;
-	default:
-		fprintf(stderr, "protocol %d not supported (try 0 2 or 76)\n",
-								      protocol);
-		return -1;
-	}
 	
 	if (!callback) {
 		fprintf(stderr, "callback is not optional!\n");
@@ -346,7 +331,12 @@
 			}
 
 			wsi[fds_count]->callback = callback;
-			wsi[fds_count]->ietf_spec_revision = protocol;
+			/*
+			 * Default protocol is 76
+			 * After 76, there's a header specified to inform which
+			 * draft the client wants
+			 */
+			wsi[fds_count]->ietf_spec_revision = 76;
 
 			fds[fds_count].events = POLLIN;
 			fds[fds_count++].fd = fd;
diff --git a/lib/libwebsockets.h b/lib/libwebsockets.h
index 02c2397..b1588b1 100644
--- a/lib/libwebsockets.h
+++ b/lib/libwebsockets.h
@@ -44,7 +44,7 @@
 		  int (*callback)(struct libwebsocket *wsi,
 				  enum libwebsocket_callback_reasons reason,
 				  void *user, void *in, size_t len),
-					       int protocol, size_t user_space,
+					       size_t user_space,
 					       const char * ssl_cert_filepath,
 					const char * ssl_private_key_filepath,
 							      int gid, int uid);
diff --git a/lib/parsers.c b/lib/parsers.c
index 430507e..3436baf 100644
--- a/lib/parsers.c
+++ b/lib/parsers.c
@@ -30,6 +30,7 @@
 	{ "Sec-WebSocket-Protocol:", 23 },
 	{ "Upgrade:", 8 },
 	{ "Origin:", 7 },
+	{ "Sec-WebSocket-Draft:", 20 },
 	{ "\x0d\x0a", 2 },
 };
 
@@ -46,6 +47,7 @@
 	case WSI_TOKEN_PROTOCOL:
 	case WSI_TOKEN_UPGRADE:
 	case WSI_TOKEN_ORIGIN:
+	case WSI_TOKEN_DRAFT:
 	case WSI_TOKEN_CHALLENGE:
 	
 		debug("WSI_TOKEN_(%d) '%c'\n", wsi->parser_state, c);
diff --git a/lib/private-libwebsockets.h b/lib/private-libwebsockets.h
index bf05758..27f495a 100644
--- a/lib/private-libwebsockets.h
+++ b/lib/private-libwebsockets.h
@@ -85,6 +85,7 @@
 	WSI_TOKEN_PROTOCOL,
 	WSI_TOKEN_UPGRADE,
 	WSI_TOKEN_ORIGIN,
+	WSI_TOKEN_DRAFT,
 	WSI_TOKEN_CHALLENGE,
 	
 	/* always last real token index*/
diff --git a/libwebsockets-api-doc.html b/libwebsockets-api-doc.html
index 7581b27..5471d3a 100644
--- a/libwebsockets-api-doc.html
+++ b/libwebsockets-api-doc.html
@@ -2,8 +2,7 @@
 <i>int</i>
 <b>libwebsocket_create_server</b>
 (<i>int</i> <b>port</b>,
-<i>int (*</i><b>callback</b>) <i>(struct libwebsocket *, 				enum libwebsocket_callback_reasons,  				void *, void *, size_t)</i>,
-<i>int</i> <b>protocol</b>,
+<i>int (*</i><b>callback</b>) <i>(struct libwebsocket *, 					enum libwebsocket_callback_reasons,  					void *, void *, size_t)</i>,
 <i>size_t</i> <b>user_area_size</b>,
 <i>const char *</i> <b>ssl_cert_filepath</b>,
 <i>const char *</i> <b>ssl_private_key_filepath</b>,
@@ -15,8 +14,6 @@
 <dd>Port to listen on
 <dt><b>callback</b>
 <dd>The callback in user code to perform actual serving
-<dt><b>protocol</b>
-<dd>Which version of the websockets protocol (currently 76)
 <dt><b>user_area_size</b>
 <dd>How much memory to allocate per connection session
 which will be used by the user application to store
@@ -52,39 +49,6 @@
 one place; they're all handled in the user callback.
 </blockquote>
 <hr>
-<h2>libwebsocket_get_uri - Return the URI path being requested</h2>
-<i>const char *</i>
-<b>libwebsocket_get_uri</b>
-(<i>struct libwebsocket *</i> <b>wsi</b>)
-<h3>Arguments</h3>
-<dl>
-<dt><b>wsi</b>
-<dd>Websocket instance
-</dl>
-<h3>Description</h3>
-<blockquote>
-The user code can find out the local path being opened from this
-call, it's valid on HTTP or established websocket connections.
-If the client opened the connection with "http://127.0.0.1/xyz/abc.d"
-then this call will return a pointer to "/xyz/abc.d"
-</blockquote>
-<hr>
-<h2>libwebsocket_get_protocol - Return the list of protocols being requested</h2>
-<i>const char *</i>
-<b>libwebsocket_get_protocol</b>
-(<i>struct libwebsocket *</i> <b>wsi</b>)
-<h3>Arguments</h3>
-<dl>
-<dt><b>wsi</b>
-<dd>Websocket instance
-</dl>
-<h3>Description</h3>
-<blockquote>
-The user code can find out which protocols the client is asking to
-work with by calling this.  It may return NULL if there was no
-protocol header specified.
-</blockquote>
-<hr>
 <h2>libwebsocket_write - Apply protocol then write data to client</h2>
 <i>int</i>
 <b>libwebsocket_write</b>
diff --git a/test-server/test-server.c b/test-server/test-server.c
index bfc3c85..1a1cfb6 100644
--- a/test-server/test-server.c
+++ b/test-server/test-server.c
@@ -29,7 +29,6 @@
 
 #define LOCAL_RESOURCE_PATH "/usr/share/libwebsockets-test-server"
 static int port = 7681;
-static int ws_protocol = 76;
 static int use_ssl = 0;
 
 struct per_session_data {
@@ -207,9 +206,6 @@
 		case 'p':
 			port = atoi(optarg);
 			break;
-		case 'r':
-			ws_protocol = atoi(optarg);
-			break;
 		case 'h':
 			fprintf(stderr, "Usage: test-server "
 					     "[--port=<p>] [--protocol=<v>]\n");
@@ -220,7 +216,7 @@
 	if (!use_ssl)
 		cert_path = key_path = NULL;
 	
-	if (libwebsocket_create_server(port, websocket_callback, ws_protocol,
+	if (libwebsocket_create_server(port, websocket_callback,
 					 sizeof(struct per_session_data),
 					     cert_path, key_path, -1, -1) < 0) {
 		fprintf(stderr, "libwebsocket init failed\n");