introduce LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER
authorAndy Green <andy@warmcat.com>
Tue, 1 Mar 2011 21:06:02 +0000 (21:06 +0000)
committerAndy Green <andy@warmcat.com>
Tue, 1 Mar 2011 21:06:02 +0000 (21:06 +0000)
This adds a callback to protocols[0] which happens when the
Client HTTP handshake packet is being composed.  After all the
headers for the websocket handshake to the server have been
added, the callback is called with a pointer to a char *
that allows extra headers to be added.  See the comments in
libwebsocket.h or the api documentation for example code.

Signed-off-by: Andy Green <andy@warmcat.com>
lib/libwebsockets.c
lib/libwebsockets.h
libwebsockets-api-doc.html

index ba596bf..96d3934 100644 (file)
@@ -900,6 +900,12 @@ libwebsocket_service_fd(struct libwebsocket_context *this,
                        p += sprintf(p, "Sec-WebSocket-Key2: %s\x0d\x0a",
                                                                         key_2);
 
+                       /* give userland a chance to append, eg, cookies */
+
+                       this->protocols[0].callback(this, wsi,
+                                LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER,
+                                       NULL, &p, (pkt + sizeof(pkt)) - p - 12);
+
                        p += sprintf(p, "\x0d\x0a");
 
                        read(this->fd_random, p, 8);
@@ -927,9 +933,17 @@ libwebsocket_service_fd(struct libwebsocket_context *this,
                if (wsi->c_protocol)
                        p += sprintf(p, "Sec-WebSocket-Protocol: %s\x0d\x0a",
                                                               wsi->c_protocol);
-               p += sprintf(p, "Sec-WebSocket-Version: %d\x0d\x0a\x0d\x0a",
+               p += sprintf(p, "Sec-WebSocket-Version: %d\x0d\x0a",
                                                       wsi->ietf_spec_revision);
 
+               /* give userland a chance to append, eg, cookies */
+
+               this->protocols[0].callback(this, wsi,
+                        LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER,
+                                       NULL, &p, (pkt + sizeof(pkt)) - p - 12);
+
+               p += sprintf(p, "\x0d\x0a");
+
                /* prepare the expected server accept response */
 
                strcpy((char *)buf, wsi->key_b64);
index a97de07..5d0f047 100644 (file)
@@ -47,6 +47,7 @@ enum libwebsocket_callback_reasons {
        LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS,
        LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS,
        LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION,
+       LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER,
 
        /* external poll() management support */
        LWS_CALLBACK_ADD_POLL_FD,
@@ -276,6 +277,30 @@ struct libwebsocket_context;
  *             the default callback action of returning 0 allows the client
  *             certificates.
  *
+ *     LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER: this callback happens
+ *             when a client handshake is being compiled.  @user is NULL,
+ *             @in is a char **, it's pointing to a char * which holds the
+ *             next location in the header buffer where you can add
+ *             headers, and @len is the remaining space in the header buffer,
+ *             which is typically some hundreds of bytes.  So, to add a canned
+ *             cookie, your handler code might look similar to:
+ *
+ *             char **p = (char **)in;
+ *
+ *             if (len < 100)
+ *                     return 1;
+ *
+ *             *p += sprintf(*p, "Cookie: a=b\x0d\x0a");
+ *
+ *             return 0;
+ *
+ *             Notice if you add anything, you just have to take care about
+ *             the CRLF on the line you added.  Obviously this callback is
+ *             optional, if you don't handle it everything is fine.
+ *
+ *             Notice the callback is coming to protocols[0] all the time,
+ *             because there is no specific protocol handshook yet.
+ *
  *     The next four reasons are optional and only need taking care of if you
  *     will be integrating libwebsockets sockets into an external polling
  *     array.
index 966df7d..8cc72c4 100644 (file)
@@ -621,6 +621,32 @@ conventions, return 0 to mean the cert is OK or 1 to fail it.
 This also means that if you don't handle this callback then
 the default callback action of returning 0 allows the client
 certificates.
+</blockquote>
+<h3>LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER</h3>
+<blockquote>
+this callback happens
+when a client handshake is being compiled.  <tt><b>user</b></tt> is NULL,
+<tt><b>in</b></tt> is a char **, it's pointing to a char * which holds the
+next location in the header buffer where you can add
+headers, and <tt><b>len</b></tt> is the remaining space in the header buffer,
+which is typically some hundreds of bytes.  So, to add a canned
+cookie, your handler code might look similar to:
+<p>
+char **p = (char **)in;
+<p>
+if (len &lt; 100)
+return 1;
+<p>
+*p += sprintf(*p, "Cookie: a=b\x0d\x0a");
+<p>
+return 0;
+<p>
+Notice if you add anything, you just have to take care about
+the CRLF on the line you added.  Obviously this callback is
+optional, if you don't handle it everything is fine.
+<p>
+Notice the callback is coming to protocols[0] all the time,
+because there is no specific protocol handshook yet.
 <p>
 The next four reasons are optional and only need taking care of if you
 will be integrating libwebsockets sockets into an external polling