diff --git a/changelog b/changelog
index 0c1a7e46f73e6aff6aa6e8bbf679d39ce17754b0..e2d085d87fdc50b7c2144d2d4b0ffe96e0165e20 100644
--- a/changelog
+++ b/changelog
@@ -127,6 +127,14 @@ To convert, search-replace
  - libwebsockets_/lws_
  - libwebsocket_/lws_
  - struct\ libwebsocket/struct\ lws
+ 
+4) context parameter removed from user callback.
+
+Since almost all apis no longer need the context as a parameter, it's no longer
+provided at the user callback directly.
+
+However if you need it, for ALL callbacks wsi is valid and has a valid context
+pointer you can recover using lws_get_ctx(wsi).
 
 
 v1.5-chrome47-firefox41
diff --git a/lib/client-parser.c b/lib/client-parser.c
index f55c29fbaef0e82e40b551d6642a901f3b8feba9..ecbbb662ff5406f3ac6d0e0ab9410d2fa354ad50 100644
--- a/lib/client-parser.c
+++ b/lib/client-parser.c
@@ -403,8 +403,8 @@ ping_drop:
 		if (callback_action == LWS_CALLBACK_CLIENT_RECEIVE_PONG)
 			lwsl_info("Client doing pong callback\n");
 
-		m = wsi->protocol->callback(lws_get_ctx(wsi),
-			wsi, (enum lws_callback_reasons)callback_action,
+		m = wsi->protocol->callback(wsi,
+			(enum lws_callback_reasons)callback_action,
 			wsi->user_space, eff_buf.token, eff_buf.token_len);
 
 		/* if user code wants to close, let caller know */
diff --git a/lib/client.c b/lib/client.c
index 1c771c8ce66788db0638fdfcb64de8025af48161..4cf5acce2567cb8df31d1794540ce015ce7ad08b 100644
--- a/lib/client.c
+++ b/lib/client.c
@@ -718,7 +718,7 @@ check_accept:
 	 * we seem to be good to go, give client last chance to check
 	 * headers and OK it
 	 */
-	wsi->protocol->callback(context, wsi,
+	wsi->protocol->callback(wsi,
 				LWS_CALLBACK_CLIENT_FILTER_PRE_ESTABLISH,
 				wsi->user_space, NULL, 0);
 
@@ -762,7 +762,7 @@ check_accept:
 
 	/* call him back to inform him he is up */
 
-	wsi->protocol->callback(context, wsi, LWS_CALLBACK_CLIENT_ESTABLISHED,
+	wsi->protocol->callback(wsi, LWS_CALLBACK_CLIENT_ESTABLISHED,
 				wsi->user_space, NULL, 0);
 #ifndef LWS_NO_EXTENSIONS
 	/*
@@ -793,12 +793,12 @@ bail3:
 bail2:
 	if (wsi->protocol) {
 		if (isErrorCodeReceived && p) {
-			wsi->protocol->callback(context, wsi,
+			wsi->protocol->callback(wsi,
 				LWS_CALLBACK_CLIENT_CONNECTION_ERROR,
 						wsi->user_space, p,
 						(unsigned int)strlen(p));
 		} else {
-			wsi->protocol->callback(context, wsi,
+			wsi->protocol->callback(wsi,
 				LWS_CALLBACK_CLIENT_CONNECTION_ERROR,
 						wsi->user_space, NULL, 0);
 		}
@@ -902,7 +902,7 @@ lws_generate_client_handshake(struct lws *wsi, char *pkt)
 			continue;
 		}
 
-		n = context->protocols[0].callback(context, wsi,
+		n = context->protocols[0].callback(wsi,
 			LWS_CALLBACK_CLIENT_CONFIRM_EXTENSION_SUPPORTED,
 				wsi->user_space, (char *)ext->name, 0);
 
@@ -936,7 +936,7 @@ lws_generate_client_handshake(struct lws *wsi, char *pkt)
 
 	/* give userland a chance to append, eg, cookies */
 
-	context->protocols[0].callback(context, wsi,
+	context->protocols[0].callback(wsi,
 				       LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER,
 				       NULL, &p,
 				       (pkt + sizeof(context->service_buffer)) - p - 12);
diff --git a/lib/context.c b/lib/context.c
index f194ec226c89339db5c5ced6debdeefdf76f99f8..0dcb0eefcbfdb651d1a95abba7e48b60fcd544e3 100644
--- a/lib/context.c
+++ b/lib/context.c
@@ -75,6 +75,7 @@ LWS_VISIBLE struct lws_context *
 lws_create_context(struct lws_context_creation_info *info)
 {
 	struct lws_context *context = NULL;
+	struct lws wsi;
 #ifndef LWS_NO_DAEMONIZE
 	int pid_daemon = get_daemonize_pid();
 #endif
@@ -129,6 +130,9 @@ lws_create_context(struct lws_context_creation_info *info)
 	context->ka_interval = info->ka_interval;
 	context->ka_probes = info->ka_probes;
 
+	memset(&wsi, 0, sizeof(wsi));
+	wsi.context = context;
+
 	if (!info->ka_interval && info->ka_time > 0) {
 		lwsl_err("info->ka_interval can't be 0 if ka_time used\n");
 		return NULL;
@@ -209,10 +213,13 @@ lws_create_context(struct lws_context_creation_info *info)
 	     context->count_protocols++)
 		/*
 		 * inform all the protocols that they are doing their one-time
-		 * initialization if they want to
+		 * initialization if they want to.
+		 *
+		 * NOTE the wsi is all zeros except for the context pointer
+		 * so lws_get_ctx(wsi) can work in the callback.
 		 */
-		info->protocols[context->count_protocols].callback(context,
-			       NULL, LWS_CALLBACK_PROTOCOL_INIT, NULL, NULL, 0);
+		info->protocols[context->count_protocols].callback(&wsi,
+				LWS_CALLBACK_PROTOCOL_INIT, NULL, NULL, 0);
 
 	/*
 	 * give all extensions a chance to create any per-context
@@ -285,7 +292,7 @@ lws_context_destroy(struct lws_context *context)
 	protocol = context->protocols;
 	if (protocol) {
 		while (protocol->callback) {
-			protocol->callback(context, NULL,
+			protocol->callback(NULL,
 					   LWS_CALLBACK_PROTOCOL_DESTROY,
 					   NULL, NULL, 0);
 			protocol++;
diff --git a/lib/handshake.c b/lib/handshake.c
index eee3bc67fc177e43fb44a33ef3d79f6f2054871c..274c27b7e59fb525d1f0d2395d5e924ce987cfff 100644
--- a/lib/handshake.c
+++ b/lib/handshake.c
@@ -147,8 +147,7 @@ http_postbody:
 			wsi->u.http.content_remain -= body_chunk_len;
 			len -= body_chunk_len;
 
-			n = wsi->protocol->callback(
-				lws_get_ctx(wsi), wsi,
+			n = wsi->protocol->callback(wsi,
 				LWS_CALLBACK_HTTP_BODY, wsi->user_space,
 				buf, body_chunk_len);
 			if (n)
@@ -164,8 +163,7 @@ http_postbody:
 			/* he sent all the content in time */
 postbody_completion:
 			lws_set_timeout(wsi, NO_PENDING_TIMEOUT, 0);
-			n = wsi->protocol->callback(
-				lws_get_ctx(wsi), wsi,
+			n = wsi->protocol->callback(wsi,
 				LWS_CALLBACK_HTTP_BODY_COMPLETION,
 				wsi->user_space, NULL, 0);
 			if (n)
diff --git a/lib/libwebsockets.c b/lib/libwebsockets.c
index b494dfb96ecec2b760b1066a996983d35e16442c..7b3dde7164ce72530892fa9072e260b867acc47d 100644
--- a/lib/libwebsockets.c
+++ b/lib/libwebsockets.c
@@ -75,8 +75,8 @@ lws_close_free_wsi(struct lws *wsi, enum lws_close_status reason)
 		lwsl_debug("closing http file\n");
 		lws_plat_file_close(wsi, wsi->u.http.fd);
 		wsi->u.http.fd = LWS_INVALID_FILE;
-		context->protocols[0].callback(context, wsi,
-			LWS_CALLBACK_CLOSED_HTTP, wsi->user_space, NULL, 0);
+		context->protocols[0].callback(wsi, LWS_CALLBACK_CLOSED_HTTP,
+					       wsi->user_space, NULL, 0);
 	}
 	if (wsi->socket_is_permanently_unusable ||
 	    reason == LWS_CLOSE_STATUS_NOSTATUS_CONTEXT_DESTROY)
@@ -114,8 +114,8 @@ lws_close_free_wsi(struct lws *wsi, enum lws_close_status reason)
 		goto just_kill_connection;
 
 	if (wsi->mode == LWS_CONNMODE_HTTP_SERVING)
-		context->protocols[0].callback(context, wsi,
-			LWS_CALLBACK_CLOSED_HTTP, wsi->user_space, NULL, 0);
+		context->protocols[0].callback(wsi, LWS_CALLBACK_CLOSED_HTTP,
+					       wsi->user_space, NULL, 0);
 
 	/*
 	 * are his extensions okay with him closing?  Eg he might be a mux
@@ -252,16 +252,16 @@ just_kill_connection:
 	    (old_state == WSI_STATE_AWAITING_CLOSE_ACK) ||
 	    (old_state == WSI_STATE_FLUSHING_STORED_SEND_BEFORE_CLOSE))) {
 		lwsl_debug("calling back CLOSED\n");
-		wsi->protocol->callback(context, wsi, LWS_CALLBACK_CLOSED,
+		wsi->protocol->callback(wsi, LWS_CALLBACK_CLOSED,
 					wsi->user_space, NULL, 0);
 	} else if (wsi->mode == LWS_CONNMODE_HTTP_SERVING_ACCEPTED) {
 		lwsl_debug("calling back CLOSED_HTTP\n");
-		context->protocols[0].callback(context, wsi,
-			LWS_CALLBACK_CLOSED_HTTP, wsi->user_space, NULL, 0 );
+		context->protocols[0].callback(wsi, LWS_CALLBACK_CLOSED_HTTP,
+					       wsi->user_space, NULL, 0 );
 	} else if (wsi->mode == LWS_CONNMODE_WS_CLIENT_WAITING_SERVER_REPLY ||
 		   wsi->mode == LWS_CONNMODE_WS_CLIENT_WAITING_CONNECT) {
 		lwsl_debug("Connection closed before server reply\n");
-		context->protocols[0].callback(context, wsi,
+		context->protocols[0].callback(wsi,
 					LWS_CALLBACK_CLIENT_CONNECTION_ERROR,
 					wsi->user_space, NULL, 0);
 	} else
@@ -302,7 +302,7 @@ just_kill_connection:
 	}
 
 	/* outermost destroy notification for wsi (user_space still intact) */
-	context->protocols[0].callback(context, wsi, LWS_CALLBACK_WSI_DESTROY,
+	context->protocols[0].callback(wsi, LWS_CALLBACK_WSI_DESTROY,
 				       wsi->user_space, NULL, 0);
 
 	lws_free_wsi(wsi);
@@ -491,8 +491,7 @@ lws_callback_all_protocol(struct lws_context *context,
 		if (!wsi)
 			continue;
 		if (wsi->protocol == protocol)
-			protocol->callback(context, wsi,
-					   reason, wsi->user_space, NULL, 0);
+			protocol->callback(wsi, reason, wsi->user_space, NULL, 0);
 	}
 
 	return 0;
@@ -647,13 +646,13 @@ lws_canonical_hostname(struct lws_context *context)
 }
 
 int user_callback_handle_rxflow(callback_function callback_function,
-				struct lws_context *context, struct lws *wsi,
+				struct lws *wsi,
 				enum lws_callback_reasons reason, void *user,
 				void *in, size_t len)
 {
 	int n;
 
-	n = callback_function(context, wsi, reason, user, in, len);
+	n = callback_function(wsi, reason, user, in, len);
 	if (!n)
 		n = _lws_rx_flow_control(wsi);
 
diff --git a/lib/libwebsockets.h b/lib/libwebsockets.h
index 4188d2c96c1d45062abcd410466118c2982899b1..4c168d771cc9afa4d4813290a32b5bdbf56c9e13 100644
--- a/lib/libwebsockets.h
+++ b/lib/libwebsockets.h
@@ -105,15 +105,16 @@ extern "C" {
 #include "lws_config.h"
 
 #if defined(WIN32) || defined(_WIN32)
-#if (WINVER < 0x0501)
+#if (WINVER < 0x0600)
 #undef WINVER
 #undef _WIN32_WINNT
-#define WINVER 0x0501
+#define WINVER 0x0600
 #define _WIN32_WINNT WINVER
 #endif
 #ifndef WIN32_LEAN_AND_MEAN
 #define WIN32_LEAN_AND_MEAN
 #endif
+
 #include <winsock2.h>
 #include <ws2tcpip.h>
 #include <stddef.h>
@@ -344,9 +345,6 @@ struct lws_pollfd {
     SHORT events;
     SHORT revents;
 };
-#if (_WIN32_WINNT < 0x0600)
-WINSOCK_API_LINKAGE int WSAAPI WSAPoll(struct lws_pollfd fdArray[], ULONG fds, INT timeout);
-#endif
 #else
 
 #if defined(MBED_OPERATORS)
@@ -1053,11 +1051,10 @@ struct lws_extension;
  *		duration of wsi dereference from the other thread context.
  */
 LWS_VISIBLE LWS_EXTERN int
-callback(const struct lws_context *context, const struct lws *wsi,
-	 enum lws_callback_reasons reason, void *user, void *in, size_t len);
+callback(const struct lws *wsi, enum lws_callback_reasons reason, void *user,
+	 void *in, size_t len);
 
-typedef int (callback_function)(struct lws_context *context,
-				struct lws *wsi,
+typedef int (callback_function)(struct lws *wsi,
 				enum lws_callback_reasons reason, void *user,
 				void *in, size_t len);
 
diff --git a/lib/lws-plat-unix.c b/lib/lws-plat-unix.c
index ca9becb2cb76a9311fb4301bf10ece3ee13c2888..2ac4a0028e4d271d93561e0e051c807aba740361 100644
--- a/lib/lws-plat-unix.c
+++ b/lib/lws-plat-unix.c
@@ -111,7 +111,7 @@ lws_plat_service(struct lws_context *context, int timeout_ms)
 
 	lws_libev_run(context);
 
-	context->service_tid = context->protocols[0].callback(context, NULL,
+	context->service_tid = context->protocols[0].callback(NULL,
 				     LWS_CALLBACK_GET_THREAD_ID, NULL, NULL, 0);
 
 #ifdef LWS_OPENSSL_SUPPORT
diff --git a/lib/lws-plat-win.c b/lib/lws-plat-win.c
index 87ccf275e7b25409469f526d06e25017787569cd..b713e7925797338143dd46ac1677f0c831800b1f 100644
--- a/lib/lws-plat-win.c
+++ b/lib/lws-plat-win.c
@@ -149,7 +149,7 @@ lws_plat_service(struct lws_context *context, int timeout_ms)
 	if (context == NULL)
 		return 1;
 
-	context->service_tid = context->protocols[0].callback(context, NULL,
+	context->service_tid = context->protocols[0].callback(NULL,
 				     LWS_CALLBACK_GET_THREAD_ID, NULL, NULL, 0);
 
 	for (i = 0; i < context->fds_count; ++i) {
diff --git a/lib/output.c b/lib/output.c
index 2e46e7abba660ad8e7bdc0381f8ff3d498f0b56d..183b7aec6a0db45337091bdc1c272c7803850ad0 100644
--- a/lib/output.c
+++ b/lib/output.c
@@ -562,7 +562,7 @@ all_sent:
 			if (wsi->protocol->callback)
 				/* ignore callback returned value */
 				user_callback_handle_rxflow(
-					wsi->protocol->callback, context, wsi,
+					wsi->protocol->callback, wsi,
 					LWS_CALLBACK_HTTP_FILE_COMPLETION,
 					wsi->user_space, NULL, 0);
 			return 1;  /* >0 indicates completed */
diff --git a/lib/parsers.c b/lib/parsers.c
index c80b29ad1a34977576b9830bf2aa4fcdd31762b0..0a57c452b4a5862a35e5eb02087c88e12d64d637 100644
--- a/lib/parsers.c
+++ b/lib/parsers.c
@@ -1023,7 +1023,6 @@ ping_drop:
 
 				ret = user_callback_handle_rxflow(
 						wsi->protocol->callback,
-						lws_get_ctx(wsi),
 						wsi,
 						(enum lws_callback_reasons)callback_action,
 						wsi->user_space,
diff --git a/lib/pollfd.c b/lib/pollfd.c
index d41e8340371df0d9343f7017455dcf375d3bfcc9..be6ff70588a338b5312a4d01eac600e83ffd1e26 100644
--- a/lib/pollfd.c
+++ b/lib/pollfd.c
@@ -46,8 +46,8 @@ insert_wsi_socket_into_fds(struct lws_context *context,
 //	lwsl_info("insert_wsi_socket_into_fds: wsi=%p, sock=%d, fds pos=%d\n",
 //					    wsi, wsi->sock, context->fds_count);
 
-	if (context->protocols[0].callback(context, wsi,
-	    LWS_CALLBACK_LOCK_POLL, wsi->user_space, (void *) &pa, 1))
+	if (context->protocols[0].callback(wsi, LWS_CALLBACK_LOCK_POLL,
+					   wsi->user_space, (void *) &pa, 1))
 		return -1;
 
 	insert_wsi(context, wsi);
@@ -58,12 +58,12 @@ insert_wsi_socket_into_fds(struct lws_context *context,
 	lws_plat_insert_socket_into_fds(context, wsi);
 
 	/* external POLL support via protocol 0 */
-	if (context->protocols[0].callback(context, wsi,
-	    LWS_CALLBACK_ADD_POLL_FD, wsi->user_space, (void *) &pa, 0))
+	if (context->protocols[0].callback(wsi, LWS_CALLBACK_ADD_POLL_FD,
+					   wsi->user_space, (void *) &pa, 0))
 		return -1;
 
-	if (context->protocols[0].callback(context, wsi,
-	    LWS_CALLBACK_UNLOCK_POLL, wsi->user_space, (void *)&pa, 1))
+	if (context->protocols[0].callback(wsi, LWS_CALLBACK_UNLOCK_POLL,
+					   wsi->user_space, (void *)&pa, 1))
 		return -1;
 
 	return 0;
@@ -91,8 +91,8 @@ remove_wsi_socket_from_fds(struct lws *wsi)
 	lwsl_info("%s: wsi=%p, sock=%d, fds pos=%d\n", __func__,
 				    wsi, wsi->sock, wsi->position_in_fds_table);
 
-	if (context->protocols[0].callback(context, wsi,
-	    LWS_CALLBACK_LOCK_POLL, wsi->user_space, (void *)&pa, 1))
+	if (context->protocols[0].callback(wsi, LWS_CALLBACK_LOCK_POLL,
+					   wsi->user_space, (void *)&pa, 1))
 		return -1;
 
 	m = wsi->position_in_fds_table; /* replace the contents for this */
@@ -116,14 +116,13 @@ remove_wsi_socket_from_fds(struct lws *wsi)
 
 	/* remove also from external POLL support via protocol 0 */
 	if (lws_socket_is_valid(wsi->sock)) {
-		if (context->protocols[0].callback(context, wsi,
+		if (context->protocols[0].callback(wsi,
 		    LWS_CALLBACK_DEL_POLL_FD, wsi->user_space,
 		    (void *) &pa, 0))
 			return -1;
 	}
-	if (context->protocols[0].callback(context, wsi,
-				       LWS_CALLBACK_UNLOCK_POLL,
-				       wsi->user_space, (void *) &pa, 1))
+	if (context->protocols[0].callback(wsi, LWS_CALLBACK_UNLOCK_POLL,
+					   wsi->user_space, (void *) &pa, 1))
 		return -1;
 
 	return 0;
@@ -149,16 +148,15 @@ lws_change_pollfd(struct lws *wsi, int _and, int _or)
 	pfd = &context->fds[wsi->position_in_fds_table];
 	pa.fd = wsi->sock;
 
-	if (context->protocols[0].callback(context, wsi,
-	    LWS_CALLBACK_LOCK_POLL, wsi->user_space,  (void *) &pa, 0))
+	if (context->protocols[0].callback(wsi, LWS_CALLBACK_LOCK_POLL,
+					   wsi->user_space,  (void *) &pa, 0))
 		return -1;
 
 	pa.prev_events = pfd->events;
 	pa.events = pfd->events = (pfd->events & ~_and) | _or;
 
-	if (context->protocols[0].callback(context, wsi,
-			LWS_CALLBACK_CHANGE_MODE_POLL_FD,
-				wsi->user_space, (void *) &pa, 0))
+	if (context->protocols[0].callback(wsi, LWS_CALLBACK_CHANGE_MODE_POLL_FD,
+					   wsi->user_space, (void *) &pa, 0))
 		return -1;
 
 	/*
@@ -169,10 +167,9 @@ lws_change_pollfd(struct lws *wsi, int _and, int _or)
 	 *         then cancel it to force a restart with our changed events
 	 */
 #if LWS_POSIX
-	pa_events = (pa.prev_events != pa.events);
+	pa_events = pa.prev_events != pa.events;
 #endif
-	if (pa_events)
-	{
+	if (pa_events) {
 
 		if (lws_plat_change_pollfd(context, wsi, pfd)) {
 			lwsl_info("%s failed\n", __func__);
@@ -181,7 +178,7 @@ lws_change_pollfd(struct lws *wsi, int _and, int _or)
 
 		sampled_tid = context->service_tid;
 		if (sampled_tid) {
-			tid = context->protocols[0].callback(context, NULL,
+			tid = context->protocols[0].callback(NULL,
 				     LWS_CALLBACK_GET_THREAD_ID, NULL, NULL, 0);
 			if (tid == -1)
 				return -1;
@@ -190,8 +187,8 @@ lws_change_pollfd(struct lws *wsi, int _and, int _or)
 		}
 	}
 
-	if (context->protocols[0].callback(context, wsi,
-	    LWS_CALLBACK_UNLOCK_POLL, wsi->user_space, (void *) &pa, 0))
+	if (context->protocols[0].callback(wsi, LWS_CALLBACK_UNLOCK_POLL,
+					   wsi->user_space, (void *) &pa, 0))
 		return -1;
 
 	return 0;
@@ -232,7 +229,8 @@ lws_callback_on_writable(struct lws *wsi)
 		 * Delay waiting for our POLLOUT until peer indicates he has
 		 * space for more using tx window command in http2 layer
 		 */
-		lwsl_info("%s: %p: waiting_tx_credit (%d)\n", __func__, wsi, wsi->u.http2.tx_credit);
+		lwsl_info("%s: %p: waiting_tx_credit (%d)\n", __func__, wsi,
+			  wsi->u.http2.tx_credit);
 		wsi->u.http2.waiting_tx_credit = 1;
 		return 0;
 	}
diff --git a/lib/private-libwebsockets.h b/lib/private-libwebsockets.h
index 795c2773884d79f5c4873b8600114924dae5995f..a30fd5856a396e6bb49b1c64ad6a18e94754d65a 100644
--- a/lib/private-libwebsockets.h
+++ b/lib/private-libwebsockets.h
@@ -1035,9 +1035,9 @@ LWS_EXTERN void
 lws_union_transition(struct lws *wsi, enum connection_mode mode);
 
 LWS_EXTERN int
-user_callback_handle_rxflow(callback_function, struct lws_context *context,
-			struct lws *wsi, enum lws_callback_reasons reason,
-			void *user, void *in, size_t len);
+user_callback_handle_rxflow(callback_function, struct lws *wsi,
+			    enum lws_callback_reasons reason, void *user,
+			    void *in, size_t len);
 #ifdef LWS_USE_HTTP2
 LWS_EXTERN struct lws *lws_http2_get_network_wsi(struct lws *wsi);
 struct lws * lws_http2_get_nth_child(struct lws *wsi, int n);
diff --git a/lib/server-handshake.c b/lib/server-handshake.c
index 9fd8cb2f73d4d465b36959bdc2e523ec2ecabb79..17b4d3690621649bac50d8e7bcaa5e69ee388bb6 100644
--- a/lib/server-handshake.c
+++ b/lib/server-handshake.c
@@ -90,12 +90,9 @@ lws_extension_server_handshake(struct lws *wsi, char **p)
 			 * particular connection + protocol
 			 */
 
-			n = lws_get_ctx(wsi)->
-				protocols[0].callback(
-					lws_get_ctx(wsi),
-					wsi,
-				  LWS_CALLBACK_CONFIRM_EXTENSION_OKAY,
-					  wsi->user_space, ext_name, 0);
+			n = lws_get_ctx(wsi)->protocols[0].callback(wsi,
+				LWS_CALLBACK_CONFIRM_EXTENSION_OKAY,
+				wsi->user_space, ext_name, 0);
 
 			/*
 			 * zero return from callback means go ahead and allow
@@ -259,8 +256,7 @@ handshake_0405(struct lws_context *context, struct lws *wsi)
 	/* notify user code that we're ready to roll */
 
 	if (wsi->protocol->callback)
-		wsi->protocol->callback(lws_get_ctx(wsi),
-				wsi, LWS_CALLBACK_ESTABLISHED,
+		wsi->protocol->callback(wsi, LWS_CALLBACK_ESTABLISHED,
 					  wsi->user_space,
 #ifdef LWS_OPENSSL_SUPPORT
 					  wsi->ssl,
diff --git a/lib/server.c b/lib/server.c
index f60da78607e4e2fdb2ee8f88cc63a973974fed57..1836d84cefb91b697799c218f0e7bea2a11847ef 100644
--- a/lib/server.c
+++ b/lib/server.c
@@ -186,7 +186,6 @@ _lws_rx_flow_control(struct lws *wsi)
 
 int lws_http_action(struct lws *wsi)
 {
-	struct lws_context *context = wsi->context;
 	enum http_connection_type connection_type;
 	enum http_version request_version;
 	char content_length_str[32];
@@ -291,8 +290,7 @@ int lws_http_action(struct lws *wsi)
 	}
 	wsi->u.http.connection_type = connection_type;
 
-	n = wsi->protocol->callback(context, wsi,
-				    LWS_CALLBACK_FILTER_HTTP_CONNECTION,
+	n = wsi->protocol->callback(wsi, LWS_CALLBACK_FILTER_HTTP_CONNECTION,
 				    wsi->user_space, uri_ptr, uri_len);
 
 	if (!n) {
@@ -303,8 +301,8 @@ int lws_http_action(struct lws *wsi)
 		lws_set_timeout(wsi, PENDING_TIMEOUT_HTTP_CONTENT,
 				AWAITING_TIMEOUT);
 
-		n = wsi->protocol->callback(context, wsi, LWS_CALLBACK_HTTP,
-			    wsi->user_space, uri_ptr, uri_len);
+		n = wsi->protocol->callback(wsi, LWS_CALLBACK_HTTP,
+					    wsi->user_space, uri_ptr, uri_len);
 	}
 
 	/* now drop the header info we kept a pointer to */
@@ -523,7 +521,7 @@ upgrade_ws:
 		 * have the opportunity to deny it
 		 */
 
-		if ((wsi->protocol->callback)(lws_get_ctx(wsi), wsi,
+		if ((wsi->protocol->callback)(wsi,
 				LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION,
 				wsi->user_space,
 			      lws_hdr_simple_ptr(wsi, WSI_TOKEN_PROTOCOL), 0)) {
@@ -637,8 +635,8 @@ lws_create_new_server_wsi(struct lws_context *context)
 	 * outermost create notification for wsi
 	 * no user_space because no protocol selection
 	 */
-	context->protocols[0].callback(context, new_wsi,
-			LWS_CALLBACK_WSI_CREATE, NULL, NULL, 0);
+	context->protocols[0].callback(new_wsi, LWS_CALLBACK_WSI_CREATE, NULL,
+				       NULL, 0);
 
 	return new_wsi;
 }
@@ -768,11 +766,8 @@ try_pollout:
 		if (wsi->state != WSI_STATE_HTTP_ISSUING_FILE) {
 			n = user_callback_handle_rxflow(
 					wsi->protocol->callback,
-					lws_get_ctx(wsi),
 					wsi, LWS_CALLBACK_HTTP_WRITEABLE,
-					wsi->user_space,
-					NULL,
-					0);
+					wsi->user_space, NULL, 0);
 			if (n < 0)
 				goto fail;
 			break;
@@ -822,7 +817,7 @@ try_pollout:
 		 * yet so we issue this to protocols[0]
 		 */
 
-		if ((context->protocols[0].callback)(context, wsi,
+		if ((context->protocols[0].callback)(wsi,
 				LWS_CALLBACK_FILTER_NETWORK_CONNECTION,
 					   NULL, (void *)(long)accept_fd, 0)) {
 			lwsl_debug("Callback denied network connection\n");
@@ -851,7 +846,7 @@ try_pollout:
 		 * set properties of the newly created wsi. There's no protocol
 		 * selected yet so we issue this to protocols[0]
 		 */
-		(context->protocols[0].callback)(context, new_wsi,
+		(context->protocols[0].callback)(new_wsi,
 			LWS_CALLBACK_SERVER_NEW_CLIENT_INSTANTIATED,
 			NULL, NULL, 0);
 
diff --git a/lib/service.c b/lib/service.c
index e924c6d38d97054a0e132c42eae70cdaf83846f9..2fc05af8bef2f1180fcd4e351cf809ff5bbca0cb 100644
--- a/lib/service.c
+++ b/lib/service.c
@@ -22,7 +22,7 @@
 #include "private-libwebsockets.h"
 
 static int
-lws_calllback_as_writeable(struct lws_context *context, struct lws *wsi)
+lws_calllback_as_writeable(struct lws *wsi)
 {
 	int n;
 
@@ -38,7 +38,7 @@ lws_calllback_as_writeable(struct lws_context *context, struct lws *wsi)
 		break;
 	}
 	lwsl_info("%s: %p (user=%p)\n", __func__, wsi, wsi->user_space);
-	return user_callback_handle_rxflow(wsi->protocol->callback, context,
+	return user_callback_handle_rxflow(wsi->protocol->callback,
 					   wsi, (enum lws_callback_reasons) n,
 					   wsi->user_space, NULL, 0);
 }
@@ -46,7 +46,6 @@ lws_calllback_as_writeable(struct lws_context *context, struct lws *wsi)
 int
 lws_handle_POLLOUT_event(struct lws *wsi, struct lws_pollfd *pollfd)
 {
-	struct lws_context *context = wsi->context;
 	int write_type = LWS_WRITE_PONG;
 	struct lws_tokens eff_buf;
 #ifdef LWS_USE_HTTP2
@@ -76,7 +75,7 @@ lws_handle_POLLOUT_event(struct lws *wsi, struct lws_pollfd *pollfd)
 		switch (wsi->pps) {
 		case LWS_PPS_HTTP2_MY_SETTINGS:
 		case LWS_PPS_HTTP2_ACK_SETTINGS:
-			lws_http2_do_pps_send(context, wsi);
+			lws_http2_do_pps_send(lws_get_ctx(wsi), wsi);
 			break;
 		default:
 			break;
@@ -255,7 +254,7 @@ user_service:
 		if (!wsi2->u.http2.requested_POLLOUT)
 			continue;
 		wsi2->u.http2.requested_POLLOUT = 0;
-		if (lws_calllback_as_writeable(context, wsi2)) {
+		if (lws_calllback_as_writeable(wsi2)) {
 			lwsl_debug("Closing POLLOUT child\n");
 			lws_close_free_wsi(wsi2, LWS_CLOSE_STATUS_NOSTATUS);
 		}
@@ -267,11 +266,9 @@ user_service:
 	return 0;
 notify:
 #endif
-	return lws_calllback_as_writeable(context, wsi);
+	return lws_calllback_as_writeable(wsi);
 }
 
-
-
 int
 lws_service_timeout_check(struct lws *wsi, unsigned int sec)
 {
diff --git a/lib/ssl.c b/lib/ssl.c
index 638c5b9353f7a52fb9a99af8834e918c63888e6d..6a7008527b91af5e5d1be46d25350bd0cf45f8e0 100644
--- a/lib/ssl.c
+++ b/lib/ssl.c
@@ -60,6 +60,7 @@ OpenSSL_verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx)
 	SSL *ssl;
 	int n;
 	struct lws_context *context;
+	struct lws wsi;
 
 	ssl = X509_STORE_CTX_get_ex_data(x509_ctx,
 		SSL_get_ex_data_X509_STORE_CTX_idx());
@@ -70,9 +71,16 @@ OpenSSL_verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx)
 	 */
 	context = SSL_get_ex_data(ssl, openssl_websocket_private_data_index);
 
-	n = context->protocols[0].callback(NULL, NULL,
-		LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION,
-						   x509_ctx, ssl, preverify_ok);
+	/*
+	 * give him a fake wsi with context set, so he can use lws_get_ctx()
+	 * in the callback
+	 */
+	memset(&wsi, 0, sizeof(wsi));
+	wsi.context = context;
+
+	n = context->protocols[0].callback(&wsi,
+			LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION,
+					   x509_ctx, ssl, preverify_ok);
 
 	/* convert return code from 0 = OK to 1 = OK */
 	return !n;
@@ -83,6 +91,7 @@ lws_context_init_server_ssl(struct lws_context_creation_info *info,
 		     struct lws_context *context)
 {
 	SSL_METHOD *method;
+	struct lws wsi;
 	int error;
 	int n;
 
@@ -109,6 +118,13 @@ lws_context_init_server_ssl(struct lws_context_creation_info *info,
 			lwsl_notice(" Using non-SSL mode\n");
 	}
 
+	/*
+	 * give him a fake wsi with context set, so he can use
+	 * lws_get_ctx() in the callback
+	 */
+	memset(&wsi, 0, sizeof(wsi));
+	wsi.context = context;
+
 	/* basic openssl init */
 
 	SSL_library_init();
@@ -159,7 +175,6 @@ lws_context_init_server_ssl(struct lws_context_creation_info *info,
 
 	if (info->options &
 			LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT) {
-
 		int verify_options = SSL_VERIFY_PEER;
 
 		if (!(info->options & LWS_SERVER_OPTION_PEER_CERT_NOT_REQUIRED))
@@ -178,9 +193,9 @@ lws_context_init_server_ssl(struct lws_context_creation_info *info,
 		 * allowing it to verify incoming client certs
 		 */
 
-		context->protocols[0].callback(context, NULL,
+		context->protocols[0].callback(&wsi,
 			LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS,
-						     context->ssl_ctx, NULL, 0);
+					       context->ssl_ctx, NULL, 0);
 	}
 
 	if (info->options & LWS_SERVER_OPTION_ALLOW_NON_SSL_ON_SSL_PORT) {
@@ -213,18 +228,18 @@ lws_context_init_server_ssl(struct lws_context_creation_info *info,
 						       SSL_FILETYPE_PEM) != 1) {
 				error = ERR_get_error();
 				lwsl_err("ssl problem getting key '%s' %lu: %s\n",
-					info->ssl_private_key_filepath,
-						error,
-						ERR_error_string(error,
-						      (char *)context->service_buffer));
+					 info->ssl_private_key_filepath, error,
+					 ERR_error_string(error,
+					      (char *)context->service_buffer));
 				return 1;
 			}
 		}
 		else {
-			if (context->protocols[0].callback(context, NULL,
+			if (context->protocols[0].callback(&wsi,
 				LWS_CALLBACK_OPENSSL_CONTEXT_REQUIRES_PRIVATE_KEY,
 						context->ssl_ctx, NULL, 0)) {
 				lwsl_err("ssl private key not set\n");
+
 				return 1;
 			}
 		}
@@ -285,6 +300,7 @@ int lws_context_init_client_ssl(struct lws_context_creation_info *info,
 	int error;
 	int n;
 	SSL_METHOD *method;
+	struct lws wsi;
 
 	if (info->provided_client_ssl_ctx) {
 		/* use the provided OpenSSL context if given one */
@@ -366,9 +382,8 @@ int lws_context_init_client_ssl(struct lws_context_creation_info *info,
 
 	/* support for client-side certificate authentication */
 	if (info->ssl_cert_filepath) {
-		n = SSL_CTX_use_certificate_chain_file(
-			context->ssl_client_ctx,
-					info->ssl_cert_filepath);
+		n = SSL_CTX_use_certificate_chain_file(context->ssl_client_ctx,
+						       info->ssl_cert_filepath);
 		if (n != 1) {
 			lwsl_err("problem getting cert '%s' %lu: %s\n",
 				info->ssl_cert_filepath,
@@ -392,16 +407,22 @@ int lws_context_init_client_ssl(struct lws_context_creation_info *info,
 		}
 
 		/* verify private key */
-		if (!SSL_CTX_check_private_key(
-					context->ssl_client_ctx)) {
+		if (!SSL_CTX_check_private_key(context->ssl_client_ctx)) {
 			lwsl_err("Private SSL key doesn't match cert\n");
 			return 1;
 		}
 	}
 
-	context->protocols[0].callback(context, NULL,
-		LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS,
-		context->ssl_client_ctx, NULL, 0);
+	/*
+	 * give him a fake wsi with context set, so he can use
+	 * lws_get_ctx() in the callback
+	 */
+	memset(&wsi, 0, sizeof(wsi));
+	wsi.context = context;
+
+	context->protocols[0].callback(&wsi,
+			LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS,
+				       context->ssl_client_ctx, NULL, 0);
 
 	return 0;
 }
diff --git a/test-server/test-client.c b/test-server/test-client.c
index 77be4120dad9401ad1fb1850fc15dbb51cf447b1..55ed584019727d7d19fc1ca916caa1aeef67c618 100644
--- a/test-server/test-client.c
+++ b/test-server/test-client.c
@@ -72,9 +72,7 @@ enum demo_protocols {
  */
 
 static int
-callback_dumb_increment(struct lws_context *context,
-			struct lws *wsi,
-			enum lws_callback_reasons reason,
+callback_dumb_increment(struct lws *wsi, enum lws_callback_reasons reason,
 			void *user, void *in, size_t len)
 {
 	switch (reason) {
@@ -133,9 +131,7 @@ callback_dumb_increment(struct lws_context *context,
 
 
 static int
-callback_lws_mirror(struct lws_context *context,
-		    struct lws *wsi,
-		    enum lws_callback_reasons reason,
+callback_lws_mirror(struct lws *wsi, enum lws_callback_reasons reason,
 		    void *user, void *in, size_t len)
 {
 	unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + 4096 +
@@ -149,7 +145,7 @@ callback_lws_mirror(struct lws_context *context,
 
 		lwsl_notice("mirror: LWS_CALLBACK_CLIENT_ESTABLISHED\n");
 
-		lws_get_random(context, rands, sizeof(rands[0]));
+		lws_get_random(lws_get_ctx(wsi), rands, sizeof(rands[0]));
 		mirror_lifetime = 16384 + (rands[0] & 65535);
 		/* useful to test single connection stability */
 		if (longlived)
@@ -177,7 +173,7 @@ callback_lws_mirror(struct lws_context *context,
 
 	case LWS_CALLBACK_CLIENT_WRITEABLE:
 		for (n = 0; n < 1; n++) {
-			lws_get_random(context, rands, sizeof(rands));
+			lws_get_random(lws_get_ctx(wsi), rands, sizeof(rands));
 			l += sprintf((char *)&buf[LWS_SEND_BUFFER_PRE_PADDING + l],
 					"c #%06X %d %d %d;",
 					(int)rands[0] & 0xffffff,
diff --git a/test-server/test-echo.c b/test-server/test-echo.c
index a850ec224ca8e769bbfc46c9bab72e3ea78188be..a13f3e109e96056fe0af7cfa1a5ab89a65fb397d 100644
--- a/test-server/test-echo.c
+++ b/test-server/test-echo.c
@@ -53,10 +53,8 @@ struct per_session_data__echo {
 };
 
 static int
-callback_echo(struct lws_context *context,
-		struct lws *wsi,
-		enum lws_callback_reasons reason, void *user,
-							   void *in, size_t len)
+callback_echo(struct lws *wsi, enum lws_callback_reasons reason, void *user,
+	      void *in, size_t len)
 {
 	struct per_session_data__echo *pss = (struct per_session_data__echo *)user;
 	int n;
diff --git a/test-server/test-fraggle.c b/test-server/test-fraggle.c
index 4a1bf39d8b717da73709d3840c6278b8a91c8b3a..b68abd6048a3a49aa8a2df3d2915aa67d660ec15 100644
--- a/test-server/test-fraggle.c
+++ b/test-server/test-fraggle.c
@@ -53,14 +53,12 @@ struct per_session_data__fraggle {
 };
 
 static int
-callback_fraggle(struct lws_context *context,
-			struct lws *wsi,
-			enum lws_callback_reasons reason,
-					       void *user, void *in, size_t len)
+callback_fraggle(struct lws *wsi, enum lws_callback_reasons reason,
+		 void *user, void *in, size_t len)
 {
 	int n;
 	unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + 8000 +
-						  LWS_SEND_BUFFER_POST_PADDING];
+			  LWS_SEND_BUFFER_POST_PADDING];
 	struct per_session_data__fraggle *psf = user;
 	int chunk;
 	int write_mode = LWS_WRITE_CONTINUATION;
@@ -136,7 +134,7 @@ callback_fraggle(struct lws_context *context,
 		switch (psf->state) {
 
 		case FRAGSTATE_START_MESSAGE:
-			lws_get_random(context, &ran, sizeof(ran));
+			lws_get_random(lws_get_ctx(wsi), &ran, sizeof(ran));
 			psf->packets_left = (ran % 1024) + 1;
 			fprintf(stderr, "Spamming %d random fragments\n",
 							     psf->packets_left);
@@ -155,11 +153,11 @@ callback_fraggle(struct lws_context *context,
 			 * code for rx spill because the rx buffer is full
 			 */
 
-			lws_get_random(context, &ran, sizeof(ran));
+			lws_get_random(lws_get_ctx(wsi), &ran, sizeof(ran));
 			chunk = (ran % 8000) + 1;
 			psf->total_message += chunk;
 
-			lws_get_random(context, bp, chunk);
+			lws_get_random(lws_get_ctx(wsi), bp, chunk);
 			for (n = 0; n < chunk; n++)
 				psf->sum += bp[n];
 
diff --git a/test-server/test-ping.c b/test-server/test-ping.c
index 2dd284e1026309589b3a7d65b66f960b9f774ac1..ebc62c005a8e95361a5dd0907f98fa19f7066891 100644
--- a/test-server/test-ping.c
+++ b/test-server/test-ping.c
@@ -100,10 +100,8 @@ enum demo_protocols {
 
 
 static int
-callback_lws_mirror(struct lws_context * this,
-			struct lws *wsi,
-			enum lws_callback_reasons reason,
-					       void *user, void *in, size_t len)
+callback_lws_mirror(struct lws *wsi, enum lws_callback_reasons reason,
+		    void *user, void *in, size_t len)
 {
 	struct timeval tv;
 	unsigned char *p;
diff --git a/test-server/test-server-dumb-increment.c b/test-server/test-server-dumb-increment.c
index b8cba7a1e6829ac5270622748f0fb593fe3d5c27..d06d32316a15f9c5666ce81bc2b3dca3d74e7b04 100644
--- a/test-server/test-server-dumb-increment.c
+++ b/test-server/test-server-dumb-increment.c
@@ -23,9 +23,7 @@
 /* dumb_increment protocol */
 
 int
-callback_dumb_increment(struct lws_context *context,
-			struct lws *wsi,
-			enum lws_callback_reasons reason,
+callback_dumb_increment(struct lws *wsi, enum lws_callback_reasons reason,
 			void *user, void *in, size_t len)
 {
 	unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + 512 +
diff --git a/test-server/test-server-http.c b/test-server/test-server-http.c
index 6f7e4d157cc32605a18e4cf8629db5e029aa4d15..16a49b0a1e105fe07cfc34bc9cb004c788ccc822 100644
--- a/test-server/test-server-http.c
+++ b/test-server/test-server-http.c
@@ -110,8 +110,7 @@ const char * get_mimetype(const char *file)
  * here on the first protocol server.
  */
 
-int callback_http(struct lws_context *context, struct lws *wsi,
-		  enum lws_callback_reasons reason, void *user,
+int callback_http(struct lws *wsi, enum lws_callback_reasons reason, void *user,
 		  void *in, size_t len)
 {
 	struct per_session_data__http *pss =
diff --git a/test-server/test-server-mirror.c b/test-server/test-server-mirror.c
index dfe16d9fbf96fbdfd0b45f873cc63f5fd960c043..923d99670ca28a3b2c582fcf59d1251b979bdfb6 100644
--- a/test-server/test-server-mirror.c
+++ b/test-server/test-server-mirror.c
@@ -33,9 +33,7 @@ static struct a_message ringbuffer[MAX_MESSAGE_QUEUE];
 static int ringbuffer_head;
 
 int
-callback_lws_mirror(struct lws_context *context,
-		    struct lws *wsi,
-		    enum lws_callback_reasons reason,
+callback_lws_mirror(struct lws *wsi, enum lws_callback_reasons reason,
 		    void *user, void *in, size_t len)
 {
 	struct per_session_data__lws_mirror *pss =
@@ -82,7 +80,7 @@ callback_lws_mirror(struct lws_context *context,
 
 			if (((ringbuffer_head - pss->ringbuffer_tail) &
 				  (MAX_MESSAGE_QUEUE - 1)) == (MAX_MESSAGE_QUEUE - 15))
-				lws_rx_flow_allow_all_protocol(context,
+				lws_rx_flow_allow_all_protocol(lws_get_ctx(wsi),
 					       lws_get_protocol(wsi));
 
 			if (lws_partial_buffered(wsi) || lws_send_pipe_choked(wsi)) {
@@ -122,7 +120,7 @@ choke:
 		lws_rx_flow_control(wsi, 0);
 
 done:
-		lws_callback_on_writable_all_protocol(context,
+		lws_callback_on_writable_all_protocol(lws_get_ctx(wsi),
 					       lws_get_protocol(wsi));
 		break;
 
diff --git a/test-server/test-server.h b/test-server/test-server.h
index 457f6aa53fb96124bb05a04bad0386f3a1e209d7..30bc634f7d66246778a69756f62aeb223fa1853e 100644
--- a/test-server/test-server.h
+++ b/test-server/test-server.h
@@ -64,17 +64,14 @@ struct per_session_data__lws_mirror {
 };
 
 extern int
-callback_http(struct lws_context *context, struct lws *wsi,
-	      enum lws_callback_reasons reason, void *user, void *in,
-	      size_t len);
+callback_http(struct lws *wsi, enum lws_callback_reasons reason, void *user,
+	      void *in, size_t len);
 extern int
-callback_lws_mirror(struct lws_context *context, struct lws *wsi,
-		    enum lws_callback_reasons reason, void *user, void *in,
-		    size_t len);
+callback_lws_mirror(struct lws *wsi, enum lws_callback_reasons reason,
+		    void *user, void *in, size_t len);
 extern int
-callback_dumb_increment(struct lws_context *context, struct lws *wsi,
-			enum lws_callback_reasons reason, void *user, void *in,
-			size_t len);
+callback_dumb_increment(struct lws *wsi, enum lws_callback_reasons reason,
+			void *user, void *in, size_t len);
 
 extern void
 dump_handshake_info(struct lws *wsi);