|  | @@ -1136,15 +1136,14 @@ mg_static_assert((sizeof(config_options) / sizeof(config_options[0]))
 | 
											
												
													
														|  |                       == (NUM_OPTIONS + 1),
 |  |                       == (NUM_OPTIONS + 1),
 | 
											
												
													
														|  |                   "config_options and enum not sync");
 |  |                   "config_options and enum not sync");
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -enum { REQUEST_HANDLER, WEBSOCKET_HANDLER, AUTH_HANDLER, NUM_HANDLERS };
 |  | 
 | 
											
												
													
														|  | 
 |  | +enum { REQUEST_HANDLER, WEBSOCKET_HANDLER, AUTH_HANDLER };
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -struct mg_request_handler_info {
 |  | 
 | 
											
												
													
														|  | 
 |  | +struct mg_handler_info {
 | 
											
												
													
														|  |  	/* Name/Pattern of the URI. */
 |  |  	/* Name/Pattern of the URI. */
 | 
											
												
													
														|  |  	char *uri;
 |  |  	char *uri;
 | 
											
												
													
														|  |  	size_t uri_len;
 |  |  	size_t uri_len;
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -	/* handler type: ws/wss (websocket) or http/https (web page) or
 |  | 
 | 
											
												
													
														|  | -	 * authorization. */
 |  | 
 | 
											
												
													
														|  | 
 |  | +	/* handler type */
 | 
											
												
													
														|  |  	int handler_type;
 |  |  	int handler_type;
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  	/* Handler for http/https or authorization requests. */
 |  |  	/* Handler for http/https or authorization requests. */
 | 
											
										
											
												
													
														|  | @@ -1156,11 +1155,14 @@ struct mg_request_handler_info {
 | 
											
												
													
														|  |  	mg_websocket_data_handler data_handler;
 |  |  	mg_websocket_data_handler data_handler;
 | 
											
												
													
														|  |  	mg_websocket_close_handler close_handler;
 |  |  	mg_websocket_close_handler close_handler;
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +	/* Handler for authorization requests */
 | 
											
												
													
														|  | 
 |  | +	mg_authorization_handler auth_handler;
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  |  	/* User supplied argument for the handler function. */
 |  |  	/* User supplied argument for the handler function. */
 | 
											
												
													
														|  |  	void *cbdata;
 |  |  	void *cbdata;
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -	/* next request handler in a linked list */
 |  | 
 | 
											
												
													
														|  | -	struct mg_request_handler_info *next;
 |  | 
 | 
											
												
													
														|  | 
 |  | +	/* next handler in a linked list */
 | 
											
												
													
														|  | 
 |  | +	struct mg_handler_info *next;
 | 
											
												
													
														|  |  };
 |  |  };
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  struct mg_context {
 |  |  struct mg_context {
 | 
											
										
											
												
													
														|  | @@ -1198,7 +1200,7 @@ struct mg_context {
 | 
											
												
													
														|  |  	char *systemName; /* What operating system is running */
 |  |  	char *systemName; /* What operating system is running */
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  	/* linked list of uri handlers */
 |  |  	/* linked list of uri handlers */
 | 
											
												
													
														|  | -	struct mg_request_handler_info *request_handlers;
 |  | 
 | 
											
												
													
														|  | 
 |  | +	struct mg_handler_info *handlers;
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  #if defined(USE_LUA) && defined(USE_WEBSOCKET)
 |  |  #if defined(USE_LUA) && defined(USE_WEBSOCKET)
 | 
											
												
													
														|  |  	/* linked list of shared lua websockets */
 |  |  	/* linked list of shared lua websockets */
 | 
											
										
											
												
													
														|  | @@ -9032,27 +9034,28 @@ redirect_to_https_port(struct mg_connection *conn, int ssl_index)
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  static void
 |  |  static void
 | 
											
												
													
														|  | -mg_set_request_handler_type(struct mg_context *ctx,
 |  | 
 | 
											
												
													
														|  | -                            const char *uri,
 |  | 
 | 
											
												
													
														|  | -                            int handler_type,
 |  | 
 | 
											
												
													
														|  | -                            int is_delete_request,
 |  | 
 | 
											
												
													
														|  | -                            mg_request_handler handler,
 |  | 
 | 
											
												
													
														|  | -                            mg_websocket_connect_handler connect_handler,
 |  | 
 | 
											
												
													
														|  | -                            mg_websocket_ready_handler ready_handler,
 |  | 
 | 
											
												
													
														|  | -                            mg_websocket_data_handler data_handler,
 |  | 
 | 
											
												
													
														|  | -                            mg_websocket_close_handler close_handler,
 |  | 
 | 
											
												
													
														|  | -                            void *cbdata)
 |  | 
 | 
											
												
													
														|  | -{
 |  | 
 | 
											
												
													
														|  | -	struct mg_request_handler_info *tmp_rh, **lastref;
 |  | 
 | 
											
												
													
														|  | 
 |  | +mg_set_handler_type(struct mg_context *ctx,
 | 
											
												
													
														|  | 
 |  | +                    const char *uri,
 | 
											
												
													
														|  | 
 |  | +                    int handler_type,
 | 
											
												
													
														|  | 
 |  | +                    int is_delete_request,
 | 
											
												
													
														|  | 
 |  | +                    mg_request_handler handler,
 | 
											
												
													
														|  | 
 |  | +                    mg_websocket_connect_handler connect_handler,
 | 
											
												
													
														|  | 
 |  | +                    mg_websocket_ready_handler ready_handler,
 | 
											
												
													
														|  | 
 |  | +                    mg_websocket_data_handler data_handler,
 | 
											
												
													
														|  | 
 |  | +                    mg_websocket_close_handler close_handler,
 | 
											
												
													
														|  | 
 |  | +                    mg_authorization_handler auth_handler,
 | 
											
												
													
														|  | 
 |  | +                    void *cbdata)
 | 
											
												
													
														|  | 
 |  | +{
 | 
											
												
													
														|  | 
 |  | +	struct mg_handler_info *tmp_rh, **lastref;
 | 
											
												
													
														|  |  	size_t urilen = strlen(uri);
 |  |  	size_t urilen = strlen(uri);
 | 
											
												
													
														|  | -	int is_websocket_handler = (handler_type == WEBSOCKET_HANDLER);
 |  | 
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -	if (is_websocket_handler) {
 |  | 
 | 
											
												
													
														|  | 
 |  | +	if (handler_type == WEBSOCKET_HANDLER) {
 | 
											
												
													
														|  |  		/* assert(handler == NULL); */
 |  |  		/* assert(handler == NULL); */
 | 
											
												
													
														|  |  		/* assert(is_delete_request || connect_handler!=NULL ||
 |  |  		/* assert(is_delete_request || connect_handler!=NULL ||
 | 
											
												
													
														|  |  		 *        ready_handler!=NULL || data_handler!=NULL ||
 |  |  		 *        ready_handler!=NULL || data_handler!=NULL ||
 | 
											
												
													
														|  |  		 *        close_handler!=NULL);
 |  |  		 *        close_handler!=NULL);
 | 
											
												
													
														|  |  		 */
 |  |  		 */
 | 
											
												
													
														|  | 
 |  | +		/* assert(auth_handler == NULL); */
 | 
											
												
													
														|  |  		if (handler != NULL) {
 |  |  		if (handler != NULL) {
 | 
											
												
													
														|  |  			return;
 |  |  			return;
 | 
											
												
													
														|  |  		}
 |  |  		}
 | 
											
										
											
												
													
														|  | @@ -9062,11 +9065,15 @@ mg_set_request_handler_type(struct mg_context *ctx,
 | 
											
												
													
														|  |  		    && close_handler == NULL) {
 |  |  		    && close_handler == NULL) {
 | 
											
												
													
														|  |  			return;
 |  |  			return;
 | 
											
												
													
														|  |  		}
 |  |  		}
 | 
											
												
													
														|  | -	} else {
 |  | 
 | 
											
												
													
														|  | 
 |  | +		if (auth_handler != NULL) {
 | 
											
												
													
														|  | 
 |  | +			return;
 | 
											
												
													
														|  | 
 |  | +		}
 | 
											
												
													
														|  | 
 |  | +	} else if (handler_type == REQUEST_HANDLER) {
 | 
											
												
													
														|  |  		/* assert(connect_handler==NULL && ready_handler==NULL &&
 |  |  		/* assert(connect_handler==NULL && ready_handler==NULL &&
 | 
											
												
													
														|  |  		 *        data_handler==NULL && close_handler==NULL); */
 |  |  		 *        data_handler==NULL && close_handler==NULL); */
 | 
											
												
													
														|  |  		/* assert(is_delete_request || (handler!=NULL));
 |  |  		/* assert(is_delete_request || (handler!=NULL));
 | 
											
												
													
														|  |  		 */
 |  |  		 */
 | 
											
												
													
														|  | 
 |  | +		/* assert(auth_handler == NULL); */
 | 
											
												
													
														|  |  		if (connect_handler != NULL || ready_handler != NULL
 |  |  		if (connect_handler != NULL || ready_handler != NULL
 | 
											
												
													
														|  |  		    || data_handler != NULL
 |  |  		    || data_handler != NULL
 | 
											
												
													
														|  |  		    || close_handler != NULL) {
 |  |  		    || close_handler != NULL) {
 | 
											
										
											
												
													
														|  | @@ -9075,6 +9082,25 @@ mg_set_request_handler_type(struct mg_context *ctx,
 | 
											
												
													
														|  |  		if (!is_delete_request && (handler == NULL)) {
 |  |  		if (!is_delete_request && (handler == NULL)) {
 | 
											
												
													
														|  |  			return;
 |  |  			return;
 | 
											
												
													
														|  |  		}
 |  |  		}
 | 
											
												
													
														|  | 
 |  | +		if (auth_handler != NULL) {
 | 
											
												
													
														|  | 
 |  | +			return;
 | 
											
												
													
														|  | 
 |  | +		}
 | 
											
												
													
														|  | 
 |  | +	} else { /* AUTH_HANDLER */
 | 
											
												
													
														|  | 
 |  | +		     /* assert(handler == NULL); */
 | 
											
												
													
														|  | 
 |  | +		     /* assert(connect_handler==NULL && ready_handler==NULL &&
 | 
											
												
													
														|  | 
 |  | +		      *        data_handler==NULL && close_handler==NULL); */
 | 
											
												
													
														|  | 
 |  | +		/* assert(auth_handler != NULL); */
 | 
											
												
													
														|  | 
 |  | +		if (handler != NULL) {
 | 
											
												
													
														|  | 
 |  | +			return;
 | 
											
												
													
														|  | 
 |  | +		}
 | 
											
												
													
														|  | 
 |  | +		if (connect_handler != NULL || ready_handler != NULL
 | 
											
												
													
														|  | 
 |  | +		    || data_handler != NULL
 | 
											
												
													
														|  | 
 |  | +		    || close_handler != NULL) {
 | 
											
												
													
														|  | 
 |  | +			return;
 | 
											
												
													
														|  | 
 |  | +		}
 | 
											
												
													
														|  | 
 |  | +		if (!is_delete_request && (auth_handler == NULL)) {
 | 
											
												
													
														|  | 
 |  | +			return;
 | 
											
												
													
														|  | 
 |  | +		}
 | 
											
												
													
														|  |  	}
 |  |  	}
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  	if (!ctx) {
 |  |  	if (!ctx) {
 | 
											
										
											
												
													
														|  | @@ -9084,20 +9110,21 @@ mg_set_request_handler_type(struct mg_context *ctx,
 | 
											
												
													
														|  |  	mg_lock_context(ctx);
 |  |  	mg_lock_context(ctx);
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  	/* first try to find an existing handler */
 |  |  	/* first try to find an existing handler */
 | 
											
												
													
														|  | -	lastref = &(ctx->request_handlers);
 |  | 
 | 
											
												
													
														|  | -	for (tmp_rh = ctx->request_handlers; tmp_rh != NULL;
 |  | 
 | 
											
												
													
														|  | -	     tmp_rh = tmp_rh->next) {
 |  | 
 | 
											
												
													
														|  | 
 |  | +	lastref = &(ctx->handlers);
 | 
											
												
													
														|  | 
 |  | +	for (tmp_rh = ctx->handlers; tmp_rh != NULL; tmp_rh = tmp_rh->next) {
 | 
											
												
													
														|  |  		if (tmp_rh->handler_type == handler_type) {
 |  |  		if (tmp_rh->handler_type == handler_type) {
 | 
											
												
													
														|  |  			if (urilen == tmp_rh->uri_len && !strcmp(tmp_rh->uri, uri)) {
 |  |  			if (urilen == tmp_rh->uri_len && !strcmp(tmp_rh->uri, uri)) {
 | 
											
												
													
														|  |  				if (!is_delete_request) {
 |  |  				if (!is_delete_request) {
 | 
											
												
													
														|  |  					/* update existing handler */
 |  |  					/* update existing handler */
 | 
											
												
													
														|  | -					if (!is_websocket_handler) {
 |  | 
 | 
											
												
													
														|  | 
 |  | +					if (handler_type == REQUEST_HANDLER) {
 | 
											
												
													
														|  |  						tmp_rh->handler = handler;
 |  |  						tmp_rh->handler = handler;
 | 
											
												
													
														|  | -					} else {
 |  | 
 | 
											
												
													
														|  | 
 |  | +					} else if (handler_type == WEBSOCKET_HANDLER) {
 | 
											
												
													
														|  |  						tmp_rh->connect_handler = connect_handler;
 |  |  						tmp_rh->connect_handler = connect_handler;
 | 
											
												
													
														|  |  						tmp_rh->ready_handler = ready_handler;
 |  |  						tmp_rh->ready_handler = ready_handler;
 | 
											
												
													
														|  |  						tmp_rh->data_handler = data_handler;
 |  |  						tmp_rh->data_handler = data_handler;
 | 
											
												
													
														|  |  						tmp_rh->close_handler = close_handler;
 |  |  						tmp_rh->close_handler = close_handler;
 | 
											
												
													
														|  | 
 |  | +					} else { /* AUTH_HANDLER */
 | 
											
												
													
														|  | 
 |  | +						tmp_rh->auth_handler = auth_handler;
 | 
											
												
													
														|  |  					}
 |  |  					}
 | 
											
												
													
														|  |  					tmp_rh->cbdata = cbdata;
 |  |  					tmp_rh->cbdata = cbdata;
 | 
											
												
													
														|  |  				} else {
 |  |  				} else {
 | 
											
										
											
												
													
														|  | @@ -9120,8 +9147,8 @@ mg_set_request_handler_type(struct mg_context *ctx,
 | 
											
												
													
														|  |  		return;
 |  |  		return;
 | 
											
												
													
														|  |  	}
 |  |  	}
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -	tmp_rh = (struct mg_request_handler_info *)
 |  | 
 | 
											
												
													
														|  | -	    mg_calloc(sizeof(struct mg_request_handler_info), 1);
 |  | 
 | 
											
												
													
														|  | 
 |  | +	tmp_rh =
 | 
											
												
													
														|  | 
 |  | +	    (struct mg_handler_info *)mg_calloc(sizeof(struct mg_handler_info), 1);
 | 
											
												
													
														|  |  	if (tmp_rh == NULL) {
 |  |  	if (tmp_rh == NULL) {
 | 
											
												
													
														|  |  		mg_unlock_context(ctx);
 |  |  		mg_unlock_context(ctx);
 | 
											
												
													
														|  |  		mg_cry(fc(ctx), "%s", "Cannot create new request handler struct, OOM");
 |  |  		mg_cry(fc(ctx), "%s", "Cannot create new request handler struct, OOM");
 | 
											
										
											
												
													
														|  | @@ -9135,13 +9162,15 @@ mg_set_request_handler_type(struct mg_context *ctx,
 | 
											
												
													
														|  |  		return;
 |  |  		return;
 | 
											
												
													
														|  |  	}
 |  |  	}
 | 
											
												
													
														|  |  	tmp_rh->uri_len = urilen;
 |  |  	tmp_rh->uri_len = urilen;
 | 
											
												
													
														|  | -	if (!is_websocket_handler) {
 |  | 
 | 
											
												
													
														|  | 
 |  | +	if (handler_type == REQUEST_HANDLER) {
 | 
											
												
													
														|  |  		tmp_rh->handler = handler;
 |  |  		tmp_rh->handler = handler;
 | 
											
												
													
														|  | -	} else {
 |  | 
 | 
											
												
													
														|  | 
 |  | +	} else if (handler_type == WEBSOCKET_HANDLER) {
 | 
											
												
													
														|  |  		tmp_rh->connect_handler = connect_handler;
 |  |  		tmp_rh->connect_handler = connect_handler;
 | 
											
												
													
														|  |  		tmp_rh->ready_handler = ready_handler;
 |  |  		tmp_rh->ready_handler = ready_handler;
 | 
											
												
													
														|  |  		tmp_rh->data_handler = data_handler;
 |  |  		tmp_rh->data_handler = data_handler;
 | 
											
												
													
														|  |  		tmp_rh->close_handler = close_handler;
 |  |  		tmp_rh->close_handler = close_handler;
 | 
											
												
													
														|  | 
 |  | +	} else { /* AUTH_HANDLER */
 | 
											
												
													
														|  | 
 |  | +		tmp_rh->auth_handler = auth_handler;
 | 
											
												
													
														|  |  	}
 |  |  	}
 | 
											
												
													
														|  |  	tmp_rh->cbdata = cbdata;
 |  |  	tmp_rh->cbdata = cbdata;
 | 
											
												
													
														|  |  	tmp_rh->handler_type = handler_type;
 |  |  	tmp_rh->handler_type = handler_type;
 | 
											
										
											
												
													
														|  | @@ -9158,16 +9187,17 @@ mg_set_request_handler(struct mg_context *ctx,
 | 
											
												
													
														|  |                         mg_request_handler handler,
 |  |                         mg_request_handler handler,
 | 
											
												
													
														|  |                         void *cbdata)
 |  |                         void *cbdata)
 | 
											
												
													
														|  |  {
 |  |  {
 | 
											
												
													
														|  | -	mg_set_request_handler_type(ctx,
 |  | 
 | 
											
												
													
														|  | -	                            uri,
 |  | 
 | 
											
												
													
														|  | -	                            REQUEST_HANDLER,
 |  | 
 | 
											
												
													
														|  | -	                            handler == NULL,
 |  | 
 | 
											
												
													
														|  | -	                            handler,
 |  | 
 | 
											
												
													
														|  | -	                            NULL,
 |  | 
 | 
											
												
													
														|  | -	                            NULL,
 |  | 
 | 
											
												
													
														|  | -	                            NULL,
 |  | 
 | 
											
												
													
														|  | -	                            NULL,
 |  | 
 | 
											
												
													
														|  | -	                            cbdata);
 |  | 
 | 
											
												
													
														|  | 
 |  | +	mg_set_handler_type(ctx,
 | 
											
												
													
														|  | 
 |  | +	                    uri,
 | 
											
												
													
														|  | 
 |  | +	                    REQUEST_HANDLER,
 | 
											
												
													
														|  | 
 |  | +	                    handler == NULL,
 | 
											
												
													
														|  | 
 |  | +	                    handler,
 | 
											
												
													
														|  | 
 |  | +	                    NULL,
 | 
											
												
													
														|  | 
 |  | +	                    NULL,
 | 
											
												
													
														|  | 
 |  | +	                    NULL,
 | 
											
												
													
														|  | 
 |  | +	                    NULL,
 | 
											
												
													
														|  | 
 |  | +	                    NULL,
 | 
											
												
													
														|  | 
 |  | +	                    cbdata);
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  
 |  |  
 | 
											
										
											
												
													
														|  | @@ -9183,16 +9213,17 @@ mg_set_websocket_handler(struct mg_context *ctx,
 | 
											
												
													
														|  |  	int is_delete_request = (connect_handler == NULL) && (ready_handler == NULL)
 |  |  	int is_delete_request = (connect_handler == NULL) && (ready_handler == NULL)
 | 
											
												
													
														|  |  	                        && (data_handler == NULL)
 |  |  	                        && (data_handler == NULL)
 | 
											
												
													
														|  |  	                        && (close_handler == NULL);
 |  |  	                        && (close_handler == NULL);
 | 
											
												
													
														|  | -	mg_set_request_handler_type(ctx,
 |  | 
 | 
											
												
													
														|  | -	                            uri,
 |  | 
 | 
											
												
													
														|  | -	                            WEBSOCKET_HANDLER,
 |  | 
 | 
											
												
													
														|  | -	                            is_delete_request,
 |  | 
 | 
											
												
													
														|  | -	                            NULL,
 |  | 
 | 
											
												
													
														|  | -	                            connect_handler,
 |  | 
 | 
											
												
													
														|  | -	                            ready_handler,
 |  | 
 | 
											
												
													
														|  | -	                            data_handler,
 |  | 
 | 
											
												
													
														|  | -	                            close_handler,
 |  | 
 | 
											
												
													
														|  | -	                            cbdata);
 |  | 
 | 
											
												
													
														|  | 
 |  | +	mg_set_handler_type(ctx,
 | 
											
												
													
														|  | 
 |  | +	                    uri,
 | 
											
												
													
														|  | 
 |  | +	                    WEBSOCKET_HANDLER,
 | 
											
												
													
														|  | 
 |  | +	                    is_delete_request,
 | 
											
												
													
														|  | 
 |  | +	                    NULL,
 | 
											
												
													
														|  | 
 |  | +	                    connect_handler,
 | 
											
												
													
														|  | 
 |  | +	                    ready_handler,
 | 
											
												
													
														|  | 
 |  | +	                    data_handler,
 | 
											
												
													
														|  | 
 |  | +	                    close_handler,
 | 
											
												
													
														|  | 
 |  | +	                    NULL,
 | 
											
												
													
														|  | 
 |  | +	                    cbdata);
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  void
 |  |  void
 | 
											
										
											
												
													
														|  | @@ -9201,16 +9232,17 @@ mg_set_auth_handler(struct mg_context *ctx,
 | 
											
												
													
														|  |                      mg_request_handler handler,
 |  |                      mg_request_handler handler,
 | 
											
												
													
														|  |                      void *cbdata)
 |  |                      void *cbdata)
 | 
											
												
													
														|  |  {
 |  |  {
 | 
											
												
													
														|  | -	mg_set_request_handler_type(ctx,
 |  | 
 | 
											
												
													
														|  | -	                            uri,
 |  | 
 | 
											
												
													
														|  | -	                            AUTH_HANDLER,
 |  | 
 | 
											
												
													
														|  | -	                            handler == NULL,
 |  | 
 | 
											
												
													
														|  | -	                            handler,
 |  | 
 | 
											
												
													
														|  | -	                            NULL,
 |  | 
 | 
											
												
													
														|  | -	                            NULL,
 |  | 
 | 
											
												
													
														|  | -	                            NULL,
 |  | 
 | 
											
												
													
														|  | -	                            NULL,
 |  | 
 | 
											
												
													
														|  | -	                            cbdata);
 |  | 
 | 
											
												
													
														|  | 
 |  | +	mg_set_handler_type(ctx,
 | 
											
												
													
														|  | 
 |  | +	                    uri,
 | 
											
												
													
														|  | 
 |  | +	                    AUTH_HANDLER,
 | 
											
												
													
														|  | 
 |  | +	                    handler == NULL,
 | 
											
												
													
														|  | 
 |  | +	                    NULL,
 | 
											
												
													
														|  | 
 |  | +	                    NULL,
 | 
											
												
													
														|  | 
 |  | +	                    NULL,
 | 
											
												
													
														|  | 
 |  | +	                    NULL,
 | 
											
												
													
														|  | 
 |  | +	                    NULL,
 | 
											
												
													
														|  | 
 |  | +	                    handler,
 | 
											
												
													
														|  | 
 |  | +	                    cbdata);
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  static int
 |  |  static int
 | 
											
										
											
												
													
														|  | @@ -9221,14 +9253,14 @@ get_request_handler(struct mg_connection *conn,
 | 
											
												
													
														|  |                      mg_websocket_ready_handler *ready_handler,
 |  |                      mg_websocket_ready_handler *ready_handler,
 | 
											
												
													
														|  |                      mg_websocket_data_handler *data_handler,
 |  |                      mg_websocket_data_handler *data_handler,
 | 
											
												
													
														|  |                      mg_websocket_close_handler *close_handler,
 |  |                      mg_websocket_close_handler *close_handler,
 | 
											
												
													
														|  | 
 |  | +                    mg_authorization_handler *auth_handler,
 | 
											
												
													
														|  |                      void **cbdata)
 |  |                      void **cbdata)
 | 
											
												
													
														|  |  {
 |  |  {
 | 
											
												
													
														|  |  	const struct mg_request_info *request_info = mg_get_request_info(conn);
 |  |  	const struct mg_request_info *request_info = mg_get_request_info(conn);
 | 
											
												
													
														|  |  	if (request_info) {
 |  |  	if (request_info) {
 | 
											
												
													
														|  |  		const char *uri = request_info->local_uri;
 |  |  		const char *uri = request_info->local_uri;
 | 
											
												
													
														|  |  		size_t urilen = strlen(uri);
 |  |  		size_t urilen = strlen(uri);
 | 
											
												
													
														|  | -		struct mg_request_handler_info *tmp_rh;
 |  | 
 | 
											
												
													
														|  | -		int is_websocket_request = (handler_type == WEBSOCKET_HANDLER);
 |  | 
 | 
											
												
													
														|  | 
 |  | +		struct mg_handler_info *tmp_rh;
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  		if (!conn || !conn->ctx) {
 |  |  		if (!conn || !conn->ctx) {
 | 
											
												
													
														|  |  			return 0;
 |  |  			return 0;
 | 
											
										
											
												
													
														|  | @@ -9237,17 +9269,19 @@ get_request_handler(struct mg_connection *conn,
 | 
											
												
													
														|  |  		mg_lock_context(conn->ctx);
 |  |  		mg_lock_context(conn->ctx);
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  		/* first try for an exact match */
 |  |  		/* first try for an exact match */
 | 
											
												
													
														|  | -		for (tmp_rh = conn->ctx->request_handlers; tmp_rh != NULL;
 |  | 
 | 
											
												
													
														|  | 
 |  | +		for (tmp_rh = conn->ctx->handlers; tmp_rh != NULL;
 | 
											
												
													
														|  |  		     tmp_rh = tmp_rh->next) {
 |  |  		     tmp_rh = tmp_rh->next) {
 | 
											
												
													
														|  |  			if (tmp_rh->handler_type == handler_type) {
 |  |  			if (tmp_rh->handler_type == handler_type) {
 | 
											
												
													
														|  |  				if (urilen == tmp_rh->uri_len && !strcmp(tmp_rh->uri, uri)) {
 |  |  				if (urilen == tmp_rh->uri_len && !strcmp(tmp_rh->uri, uri)) {
 | 
											
												
													
														|  | -					if (is_websocket_request) {
 |  | 
 | 
											
												
													
														|  | 
 |  | +					if (handler_type == WEBSOCKET_HANDLER) {
 | 
											
												
													
														|  |  						*connect_handler = tmp_rh->connect_handler;
 |  |  						*connect_handler = tmp_rh->connect_handler;
 | 
											
												
													
														|  |  						*ready_handler = tmp_rh->ready_handler;
 |  |  						*ready_handler = tmp_rh->ready_handler;
 | 
											
												
													
														|  |  						*data_handler = tmp_rh->data_handler;
 |  |  						*data_handler = tmp_rh->data_handler;
 | 
											
												
													
														|  |  						*close_handler = tmp_rh->close_handler;
 |  |  						*close_handler = tmp_rh->close_handler;
 | 
											
												
													
														|  | -					} else {
 |  | 
 | 
											
												
													
														|  | 
 |  | +					} else if (handler_type == REQUEST_HANDLER) {
 | 
											
												
													
														|  |  						*handler = tmp_rh->handler;
 |  |  						*handler = tmp_rh->handler;
 | 
											
												
													
														|  | 
 |  | +					} else { /* AUTH_HANDLER */
 | 
											
												
													
														|  | 
 |  | +						*auth_handler = tmp_rh->auth_handler;
 | 
											
												
													
														|  |  					}
 |  |  					}
 | 
											
												
													
														|  |  					*cbdata = tmp_rh->cbdata;
 |  |  					*cbdata = tmp_rh->cbdata;
 | 
											
												
													
														|  |  					mg_unlock_context(conn->ctx);
 |  |  					mg_unlock_context(conn->ctx);
 | 
											
										
											
												
													
														|  | @@ -9257,18 +9291,20 @@ get_request_handler(struct mg_connection *conn,
 | 
											
												
													
														|  |  		}
 |  |  		}
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  		/* next try for a partial match, we will accept uri/something */
 |  |  		/* next try for a partial match, we will accept uri/something */
 | 
											
												
													
														|  | -		for (tmp_rh = conn->ctx->request_handlers; tmp_rh != NULL;
 |  | 
 | 
											
												
													
														|  | 
 |  | +		for (tmp_rh = conn->ctx->handlers; tmp_rh != NULL;
 | 
											
												
													
														|  |  		     tmp_rh = tmp_rh->next) {
 |  |  		     tmp_rh = tmp_rh->next) {
 | 
											
												
													
														|  |  			if (tmp_rh->handler_type == handler_type) {
 |  |  			if (tmp_rh->handler_type == handler_type) {
 | 
											
												
													
														|  |  				if (tmp_rh->uri_len < urilen && uri[tmp_rh->uri_len] == '/'
 |  |  				if (tmp_rh->uri_len < urilen && uri[tmp_rh->uri_len] == '/'
 | 
											
												
													
														|  |  				    && memcmp(tmp_rh->uri, uri, tmp_rh->uri_len) == 0) {
 |  |  				    && memcmp(tmp_rh->uri, uri, tmp_rh->uri_len) == 0) {
 | 
											
												
													
														|  | -					if (is_websocket_request) {
 |  | 
 | 
											
												
													
														|  | 
 |  | +					if (handler_type == WEBSOCKET_HANDLER) {
 | 
											
												
													
														|  |  						*connect_handler = tmp_rh->connect_handler;
 |  |  						*connect_handler = tmp_rh->connect_handler;
 | 
											
												
													
														|  |  						*ready_handler = tmp_rh->ready_handler;
 |  |  						*ready_handler = tmp_rh->ready_handler;
 | 
											
												
													
														|  |  						*data_handler = tmp_rh->data_handler;
 |  |  						*data_handler = tmp_rh->data_handler;
 | 
											
												
													
														|  |  						*close_handler = tmp_rh->close_handler;
 |  |  						*close_handler = tmp_rh->close_handler;
 | 
											
												
													
														|  | -					} else {
 |  | 
 | 
											
												
													
														|  | 
 |  | +					} else if (handler_type == REQUEST_HANDLER) {
 | 
											
												
													
														|  |  						*handler = tmp_rh->handler;
 |  |  						*handler = tmp_rh->handler;
 | 
											
												
													
														|  | 
 |  | +					} else { /* AUTH_HANDLER */
 | 
											
												
													
														|  | 
 |  | +						*auth_handler = tmp_rh->auth_handler;
 | 
											
												
													
														|  |  					}
 |  |  					}
 | 
											
												
													
														|  |  					*cbdata = tmp_rh->cbdata;
 |  |  					*cbdata = tmp_rh->cbdata;
 | 
											
												
													
														|  |  					mg_unlock_context(conn->ctx);
 |  |  					mg_unlock_context(conn->ctx);
 | 
											
										
											
												
													
														|  | @@ -9278,17 +9314,19 @@ get_request_handler(struct mg_connection *conn,
 | 
											
												
													
														|  |  		}
 |  |  		}
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  		/* finally try for pattern match */
 |  |  		/* finally try for pattern match */
 | 
											
												
													
														|  | -		for (tmp_rh = conn->ctx->request_handlers; tmp_rh != NULL;
 |  | 
 | 
											
												
													
														|  | 
 |  | +		for (tmp_rh = conn->ctx->handlers; tmp_rh != NULL;
 | 
											
												
													
														|  |  		     tmp_rh = tmp_rh->next) {
 |  |  		     tmp_rh = tmp_rh->next) {
 | 
											
												
													
														|  |  			if (tmp_rh->handler_type == handler_type) {
 |  |  			if (tmp_rh->handler_type == handler_type) {
 | 
											
												
													
														|  |  				if (match_prefix(tmp_rh->uri, tmp_rh->uri_len, uri) > 0) {
 |  |  				if (match_prefix(tmp_rh->uri, tmp_rh->uri_len, uri) > 0) {
 | 
											
												
													
														|  | -					if (is_websocket_request) {
 |  | 
 | 
											
												
													
														|  | 
 |  | +					if (handler_type == WEBSOCKET_HANDLER) {
 | 
											
												
													
														|  |  						*connect_handler = tmp_rh->connect_handler;
 |  |  						*connect_handler = tmp_rh->connect_handler;
 | 
											
												
													
														|  |  						*ready_handler = tmp_rh->ready_handler;
 |  |  						*ready_handler = tmp_rh->ready_handler;
 | 
											
												
													
														|  |  						*data_handler = tmp_rh->data_handler;
 |  |  						*data_handler = tmp_rh->data_handler;
 | 
											
												
													
														|  |  						*close_handler = tmp_rh->close_handler;
 |  |  						*close_handler = tmp_rh->close_handler;
 | 
											
												
													
														|  | -					} else {
 |  | 
 | 
											
												
													
														|  | 
 |  | +					} else if (handler_type == REQUEST_HANDLER) {
 | 
											
												
													
														|  |  						*handler = tmp_rh->handler;
 |  |  						*handler = tmp_rh->handler;
 | 
											
												
													
														|  | 
 |  | +					} else { /* AUTH_HANDLER */
 | 
											
												
													
														|  | 
 |  | +						*auth_handler = tmp_rh->auth_handler;
 | 
											
												
													
														|  |  					}
 |  |  					}
 | 
											
												
													
														|  |  					*cbdata = tmp_rh->cbdata;
 |  |  					*cbdata = tmp_rh->cbdata;
 | 
											
												
													
														|  |  					mg_unlock_context(conn->ctx);
 |  |  					mg_unlock_context(conn->ctx);
 | 
											
										
											
												
													
														|  | @@ -9365,7 +9403,7 @@ handle_request(struct mg_connection *conn)
 | 
											
												
													
														|  |  		mg_websocket_data_handler ws_data_handler = NULL;
 |  |  		mg_websocket_data_handler ws_data_handler = NULL;
 | 
											
												
													
														|  |  		mg_websocket_close_handler ws_close_handler = NULL;
 |  |  		mg_websocket_close_handler ws_close_handler = NULL;
 | 
											
												
													
														|  |  		void *callback_data = NULL;
 |  |  		void *callback_data = NULL;
 | 
											
												
													
														|  | -		mg_request_handler auth_handler = NULL;
 |  | 
 | 
											
												
													
														|  | 
 |  | +		mg_authorization_handler auth_handler = NULL;
 | 
											
												
													
														|  |  		void *auth_callback_data = NULL;
 |  |  		void *auth_callback_data = NULL;
 | 
											
												
													
														|  |  #if !defined(NO_FILES)
 |  |  #if !defined(NO_FILES)
 | 
											
												
													
														|  |  		time_t curtime = time(NULL);
 |  |  		time_t curtime = time(NULL);
 | 
											
										
											
												
													
														|  | @@ -9457,6 +9495,7 @@ handle_request(struct mg_connection *conn)
 | 
											
												
													
														|  |  		                        &ws_ready_handler,
 |  |  		                        &ws_ready_handler,
 | 
											
												
													
														|  |  		                        &ws_data_handler,
 |  |  		                        &ws_data_handler,
 | 
											
												
													
														|  |  		                        &ws_close_handler,
 |  |  		                        &ws_close_handler,
 | 
											
												
													
														|  | 
 |  | +		                        NULL,
 | 
											
												
													
														|  |  		                        &callback_data)) {
 |  |  		                        &callback_data)) {
 | 
											
												
													
														|  |  			/* 5.2.1. A callback will handle this request. All requests handled
 |  |  			/* 5.2.1. A callback will handle this request. All requests handled
 | 
											
												
													
														|  |  			 * by a callback have to be considered as requests to a script
 |  |  			 * by a callback have to be considered as requests to a script
 | 
											
										
											
												
													
														|  | @@ -9484,11 +9523,12 @@ handle_request(struct mg_connection *conn)
 | 
											
												
													
														|  |  		/* 6.1. a custom authorization handler is installed */
 |  |  		/* 6.1. a custom authorization handler is installed */
 | 
											
												
													
														|  |  		if (get_request_handler(conn,
 |  |  		if (get_request_handler(conn,
 | 
											
												
													
														|  |  		                        AUTH_HANDLER,
 |  |  		                        AUTH_HANDLER,
 | 
											
												
													
														|  | -		                        &auth_handler,
 |  | 
 | 
											
												
													
														|  |  		                        NULL,
 |  |  		                        NULL,
 | 
											
												
													
														|  |  		                        NULL,
 |  |  		                        NULL,
 | 
											
												
													
														|  |  		                        NULL,
 |  |  		                        NULL,
 | 
											
												
													
														|  |  		                        NULL,
 |  |  		                        NULL,
 | 
											
												
													
														|  | 
 |  | +		                        NULL,
 | 
											
												
													
														|  | 
 |  | +		                        &auth_handler,
 | 
											
												
													
														|  |  		                        &auth_callback_data)) {
 |  |  		                        &auth_callback_data)) {
 | 
											
												
													
														|  |  			if (!auth_handler(conn, auth_callback_data)) {
 |  |  			if (!auth_handler(conn, auth_callback_data)) {
 | 
											
												
													
														|  |  				return;
 |  |  				return;
 | 
											
										
											
												
													
														|  | @@ -12047,7 +12087,7 @@ static void
 | 
											
												
													
														|  |  free_context(struct mg_context *ctx)
 |  |  free_context(struct mg_context *ctx)
 | 
											
												
													
														|  |  {
 |  |  {
 | 
											
												
													
														|  |  	int i;
 |  |  	int i;
 | 
											
												
													
														|  | -	struct mg_request_handler_info *tmp_rh;
 |  | 
 | 
											
												
													
														|  | 
 |  | +	struct mg_handler_info *tmp_rh;
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  	if (ctx == NULL) {
 |  |  	if (ctx == NULL) {
 | 
											
												
													
														|  |  		return;
 |  |  		return;
 | 
											
										
											
												
													
														|  | @@ -12082,9 +12122,9 @@ free_context(struct mg_context *ctx)
 | 
											
												
													
														|  |  	}
 |  |  	}
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  	/* Deallocate request handlers */
 |  |  	/* Deallocate request handlers */
 | 
											
												
													
														|  | -	while (ctx->request_handlers) {
 |  | 
 | 
											
												
													
														|  | -		tmp_rh = ctx->request_handlers;
 |  | 
 | 
											
												
													
														|  | -		ctx->request_handlers = tmp_rh->next;
 |  | 
 | 
											
												
													
														|  | 
 |  | +	while (ctx->handlers) {
 | 
											
												
													
														|  | 
 |  | +		tmp_rh = ctx->handlers;
 | 
											
												
													
														|  | 
 |  | +		ctx->handlers = tmp_rh->next;
 | 
											
												
													
														|  |  		mg_free(tmp_rh->uri);
 |  |  		mg_free(tmp_rh->uri);
 | 
											
												
													
														|  |  		mg_free(tmp_rh);
 |  |  		mg_free(tmp_rh);
 | 
											
												
													
														|  |  	}
 |  |  	}
 | 
											
										
											
												
													
														|  | @@ -12278,7 +12318,7 @@ mg_start(const struct mg_callbacks *callbacks,
 | 
											
												
													
														|  |  		ctx->callbacks.exit_context = 0;
 |  |  		ctx->callbacks.exit_context = 0;
 | 
											
												
													
														|  |  	}
 |  |  	}
 | 
											
												
													
														|  |  	ctx->user_data = user_data;
 |  |  	ctx->user_data = user_data;
 | 
											
												
													
														|  | -	ctx->request_handlers = NULL;
 |  | 
 | 
											
												
													
														|  | 
 |  | +	ctx->handlers = NULL;
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  #if defined(USE_LUA) && defined(USE_WEBSOCKET)
 |  |  #if defined(USE_LUA) && defined(USE_WEBSOCKET)
 | 
											
												
													
														|  |  	ctx->shared_lua_websockets = 0;
 |  |  	ctx->shared_lua_websockets = 0;
 |