From 385e7ad0344f740ef4edb1790827096df96d5583 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Tue, 1 Mar 2011 21:06:02 +0000 Subject: [PATCH] introduce LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER 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 --- lib/libwebsockets.c | 16 +++++++++++++++- lib/libwebsockets.h | 25 +++++++++++++++++++++++++ libwebsockets-api-doc.html | 26 ++++++++++++++++++++++++++ 3 files changed, 66 insertions(+), 1 deletion(-) diff --git a/lib/libwebsockets.c b/lib/libwebsockets.c index ba596bf..96d3934 100644 --- a/lib/libwebsockets.c +++ b/lib/libwebsockets.c @@ -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); diff --git a/lib/libwebsockets.h b/lib/libwebsockets.h index a97de07..5d0f047 100644 --- a/lib/libwebsockets.h +++ b/lib/libwebsockets.h @@ -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. diff --git a/libwebsockets-api-doc.html b/libwebsockets-api-doc.html index 966df7d..8cc72c4 100644 --- a/libwebsockets-api-doc.html +++ b/libwebsockets-api-doc.html @@ -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. + +

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 -- 2.7.4