mirror of
https://git.gnunet.org/libmicrohttpd.git
synced 2026-09-27 04:09:31 +03:00
sketching support for upgrade handling
This commit is contained in:
@@ -1,3 +1,7 @@
|
||||
Sat Aug 27 20:07:53 CEST 2016
|
||||
Adding completely *untested* logic for HTTP "Upgrade"
|
||||
handling. -CG
|
||||
|
||||
Sat Aug 27 18:20:38 CEST 2016
|
||||
Releasing libmicrohttpd 0.9.51. -CG
|
||||
|
||||
|
||||
@@ -126,7 +126,7 @@ typedef intptr_t ssize_t;
|
||||
* Current version of the library.
|
||||
* 0x01093001 = 1.9.30-1.
|
||||
*/
|
||||
#define MHD_VERSION 0x00095100
|
||||
#define MHD_VERSION 0x00095101
|
||||
|
||||
/**
|
||||
* MHD-internal return code for "YES".
|
||||
@@ -2221,7 +2221,6 @@ MHD_create_response_from_fd_at_offset64 (uint64_t size,
|
||||
uint64_t offset);
|
||||
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* Enumeration for actions MHD should perform on the underlying socket
|
||||
* of the upgrade. This API is not finalized, and in particular
|
||||
@@ -2334,7 +2333,7 @@ typedef void
|
||||
struct MHD_Connection *connection,
|
||||
const char *extra_in,
|
||||
size_t extra_in_size,
|
||||
MHD_SOCKET sock,
|
||||
MHD_socket sock,
|
||||
struct MHD_UpgradeResponseHandle *urh);
|
||||
|
||||
|
||||
@@ -2370,7 +2369,7 @@ typedef void
|
||||
_MHD_EXTERN struct MHD_Response *
|
||||
MHD_create_response_for_upgrade (MHD_UpgradeHandler upgrade_handler,
|
||||
void *upgrade_handler_cls);
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Destroy a response object and associated resources. Note that
|
||||
|
||||
@@ -736,7 +736,8 @@ keepalive_possible (struct MHD_Connection *connection)
|
||||
if (NULL == end)
|
||||
return MHD_YES;
|
||||
if ( (MHD_str_equal_caseless_ (end, "close")) ||
|
||||
(MHD_str_equal_caseless_ (end, "upgrade")) )
|
||||
( (MHD_str_equal_caseless_ (end, "upgrade")) &&
|
||||
(NULL == connection->response->upgrade_handler) ) )
|
||||
return MHD_NO;
|
||||
return MHD_YES;
|
||||
}
|
||||
@@ -2222,6 +2223,9 @@ MHD_connection_handle_read (struct MHD_Connection *connection)
|
||||
break;
|
||||
case MHD_CONNECTION_CLOSED:
|
||||
return MHD_YES;
|
||||
case MHD_CONNECTION_UPGRADE:
|
||||
EXTRA_CHECK (0);
|
||||
break;
|
||||
default:
|
||||
/* shrink read buffer to how much is actually used */
|
||||
MHD_pool_reallocate (connection->pool,
|
||||
@@ -2305,7 +2309,8 @@ MHD_connection_handle_write (struct MHD_Connection *connection)
|
||||
do_write (connection);
|
||||
if (connection->state != MHD_CONNECTION_HEADERS_SENDING)
|
||||
break;
|
||||
check_write_done (connection, MHD_CONNECTION_HEADERS_SENT);
|
||||
check_write_done (connection,
|
||||
MHD_CONNECTION_HEADERS_SENT);
|
||||
break;
|
||||
case MHD_CONNECTION_HEADERS_SENT:
|
||||
EXTRA_CHECK (0);
|
||||
@@ -2395,6 +2400,9 @@ MHD_connection_handle_write (struct MHD_Connection *connection)
|
||||
case MHD_TLS_CONNECTION_INIT:
|
||||
EXTRA_CHECK (0);
|
||||
break;
|
||||
case MHD_CONNECTION_UPGRADE:
|
||||
EXTRA_CHECK (0);
|
||||
break;
|
||||
default:
|
||||
EXTRA_CHECK (0);
|
||||
CONNECTION_CLOSE_ERROR (connection,
|
||||
@@ -2586,9 +2594,9 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
|
||||
}
|
||||
if ( (NULL != connection->response) &&
|
||||
( (MHD_str_equal_caseless_ (connection->method,
|
||||
MHD_HTTP_METHOD_POST)) ||
|
||||
MHD_HTTP_METHOD_POST)) ||
|
||||
(MHD_str_equal_caseless_ (connection->method,
|
||||
MHD_HTTP_METHOD_PUT))) )
|
||||
MHD_HTTP_METHOD_PUT))) )
|
||||
{
|
||||
/* we refused (no upload allowed!) */
|
||||
connection->remaining_upload_size = 0;
|
||||
@@ -2722,6 +2730,21 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
|
||||
}
|
||||
else
|
||||
socket_start_normal_buffering (connection);
|
||||
if (NULL != connection->response->upgrade_handler)
|
||||
{
|
||||
/* This connection is "upgraded". Pass socket to application. */
|
||||
if (MHD_YES !=
|
||||
MHD_response_execute_upgrade_ (connection->response,
|
||||
connection))
|
||||
{
|
||||
/* upgrade failed, fail hard */
|
||||
CONNECTION_CLOSE_ERROR (connection,
|
||||
NULL);
|
||||
continue;
|
||||
}
|
||||
connection->state = MHD_CONNECTION_UPGRADE;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (connection->have_chunked_upload)
|
||||
connection->state = MHD_CONNECTION_CHUNKED_BODY_UNREADY;
|
||||
@@ -2882,6 +2905,8 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
|
||||
case MHD_CONNECTION_CLOSED:
|
||||
cleanup_connection (connection);
|
||||
return MHD_NO;
|
||||
case MHD_CONNECTION_UPGRADE:
|
||||
return MHD_YES; /* keep open */
|
||||
default:
|
||||
EXTRA_CHECK (0);
|
||||
break;
|
||||
|
||||
@@ -274,7 +274,6 @@ struct MHD_Response
|
||||
*/
|
||||
MHD_ContentReaderFreeCallback crfc;
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* Application function to call once we are done sending the headers
|
||||
* of the response; NULL unless this is a response created with
|
||||
@@ -286,7 +285,6 @@ struct MHD_Response
|
||||
* Closure for @e uh.
|
||||
*/
|
||||
void *upgrade_handler_cls;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Mutex to synchronize access to @e data, @e size and
|
||||
@@ -476,7 +474,13 @@ enum MHD_CONNECTION_STATE
|
||||
* Handshake messages will be processed in this state & while
|
||||
* in the #MHD_TLS_HELLO_REQUEST state
|
||||
*/
|
||||
MHD_TLS_CONNECTION_INIT = MHD_CONNECTION_IN_CLEANUP + 1
|
||||
MHD_TLS_CONNECTION_INIT = MHD_CONNECTION_IN_CLEANUP + 1,
|
||||
|
||||
/**
|
||||
* Connection was "upgraded" and socket is now under the
|
||||
* control of the application.
|
||||
*/
|
||||
MHD_CONNECTION_UPGRADE = MHD_TLS_CONNECTION_INIT + 1
|
||||
|
||||
};
|
||||
|
||||
|
||||
+14
-17
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
This file is part of libmicrohttpd
|
||||
Copyright (C) 2007, 2009, 2010 Daniel Pittman and Christian Grothoff
|
||||
Copyright (C) 2007, 2009, 2010, 2016 Daniel Pittman and Christian Grothoff
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
@@ -29,6 +29,9 @@
|
||||
#include "internal.h"
|
||||
#include "response.h"
|
||||
#include "mhd_limits.h"
|
||||
#include "mhd_sockets.h"
|
||||
#include "mhd_itc.h"
|
||||
#include "connection.h"
|
||||
|
||||
#if defined(_WIN32) && defined(MHD_W32_MUTEX_)
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
@@ -577,7 +580,6 @@ MHD_create_response_from_buffer (size_t size,
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* Handle given to the application to manage special
|
||||
* actions relating to MHD responses that "upgrade"
|
||||
@@ -596,13 +598,13 @@ struct MHD_UpgradeResponseHandle
|
||||
/**
|
||||
* The socket we gave to the application (r/w).
|
||||
*/
|
||||
MHD_SOCKET app_sock;
|
||||
MHD_socket app_socket;
|
||||
|
||||
/**
|
||||
* If @a app_sock was a socketpair, our end of it, otherwise
|
||||
* #MHD_INVALID_SOCKET; (r/w).
|
||||
*/
|
||||
MHD_SOCKET mhd_sock;
|
||||
MHD_socket mhd_socket;
|
||||
|
||||
};
|
||||
|
||||
@@ -629,12 +631,12 @@ MHD_upgrade_action (struct MHD_UpgradeResponseHandle *urh,
|
||||
case MHD_UPGRADE_ACTION_CLOSE:
|
||||
/* Application is done with this connection, tear it down! */
|
||||
if ( (MHD_INVALID_SOCKET != urh->app_socket) &&
|
||||
(0 != MHD_socket_close (urh->app_socket)) )
|
||||
(0 != MHD_socket_close_ (urh->app_socket)) )
|
||||
MHD_PANIC ("close failed\n");
|
||||
if ( (MHD_INVALID_SOCKET != urh->mhd_socket) &&
|
||||
(0 != MHD_socket_close (urh->mhd_socket)) )
|
||||
(0 != MHD_socket_close_ (urh->mhd_socket)) )
|
||||
MHD_PANIC ("close failed\n");
|
||||
MHD_connection_resume (urh->connection);
|
||||
MHD_resume_connection (urh->connection);
|
||||
MHD_connection_close_ (urh->connection,
|
||||
MHD_REQUEST_TERMINATED_COMPLETED_OK);
|
||||
free (urh);
|
||||
@@ -659,9 +661,6 @@ MHD_upgrade_action (struct MHD_UpgradeResponseHandle *urh,
|
||||
* @return #MHD_YES on success, #MHD_NO on failure (will cause
|
||||
* connection to be closed)
|
||||
*/
|
||||
// FIXME: This function will need to be called at the right place(s)
|
||||
// in the connection processing (just after we are done sending the header)
|
||||
// (for responses that have the 'upgrade_header' callback set).
|
||||
int
|
||||
MHD_response_execute_upgrade_ (struct MHD_Response *response,
|
||||
struct MHD_Connection *connection)
|
||||
@@ -674,7 +673,7 @@ MHD_response_execute_upgrade_ (struct MHD_Response *response,
|
||||
if (NULL == urh)
|
||||
return MHD_NO;
|
||||
#if HTTPS_SUPPORT
|
||||
if (0 != (connection->daemon->flags & MHD_USE_SSL) )
|
||||
if (0 != (connection->daemon->options & MHD_USE_SSL) )
|
||||
{
|
||||
/* FIXME: this is non-portable for now; W32 port pending... */
|
||||
if (0 != socketpair (AF_UNIX,
|
||||
@@ -694,12 +693,12 @@ MHD_response_execute_upgrade_ (struct MHD_Response *response,
|
||||
connection,
|
||||
connection->read_buffer,
|
||||
rbo,
|
||||
urh->app_sock,
|
||||
urh->app_socket,
|
||||
urh);
|
||||
/* As far as MHD is concerned, this connection is
|
||||
suspended; it will be resumed once we are done
|
||||
in the #MHD_upgrade_action() function */
|
||||
MHD_connection_suspend (connection);
|
||||
MHD_suspend_connection (connection);
|
||||
/* FIXME: also need to start some processing logic in _all_ MHD
|
||||
event loops for the sv traffic! (NOT IMPLEMENTED!!!) */
|
||||
return MHD_YES;
|
||||
@@ -718,7 +717,7 @@ MHD_response_execute_upgrade_ (struct MHD_Response *response,
|
||||
/* As far as MHD is concerned, this connection is
|
||||
suspended; it will be resumed once we are done
|
||||
in the #MHD_upgrade_action() function */
|
||||
MHD_connection_suspend (connection);
|
||||
MHD_suspend_connection (connection);
|
||||
return MHD_YES;
|
||||
}
|
||||
|
||||
@@ -758,7 +757,7 @@ MHD_create_response_for_upgrade (MHD_UpgradeHandler upgrade_handler,
|
||||
{
|
||||
struct MHD_Response *response;
|
||||
|
||||
if (NULL == upgrade_header)
|
||||
if (NULL == upgrade_handler)
|
||||
return NULL; /* invalid request */
|
||||
response = malloc (sizeof (struct MHD_Response));
|
||||
if (NULL == response)
|
||||
@@ -769,14 +768,12 @@ MHD_create_response_for_upgrade (MHD_UpgradeHandler upgrade_handler,
|
||||
free (response);
|
||||
return NULL;
|
||||
}
|
||||
urh->response = response;
|
||||
response->upgrade_handler = upgrade_handler;
|
||||
response->upgrade_handler_cls = upgrade_handler_cls;
|
||||
response->total_size = MHD_SIZE_UNKNOWN;
|
||||
response->reference_count = 1;
|
||||
return response;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -36,4 +36,22 @@ void
|
||||
MHD_increment_response_rc (struct MHD_Response *response);
|
||||
|
||||
|
||||
/**
|
||||
* We are done sending the header of a given response
|
||||
* to the client. Now it is time to perform the upgrade
|
||||
* and hand over the connection to the application.
|
||||
*
|
||||
* @param response the response that was created for an upgrade
|
||||
* @param connection the specific connection we are upgrading
|
||||
* @return #MHD_YES on success, #MHD_NO on failure (will cause
|
||||
* connection to be closed)
|
||||
*/
|
||||
// FIXME: This function will need to be called at the right place(s)
|
||||
// in the connection processing (just after we are done sending the header)
|
||||
// (for responses that have the 'upgrade_header' callback set).
|
||||
int
|
||||
MHD_response_execute_upgrade_ (struct MHD_Response *response,
|
||||
struct MHD_Connection *connection);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user