summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2016-08-27 18:08:00 +0000
committerChristian Grothoff <christian@grothoff.org>2016-08-27 18:08:00 +0000
commite0a43cb194fd22ceaed6905d964f2fcd829b933d (patch)
treee4ec639adcbc441535cdd6e92a5ac3e5ea0be5b9
parent63eb4c75a31654c0b74e2985a0b7861ddaa8d5b3 (diff)
sketching support for upgrade handling
-rw-r--r--ChangeLog4
-rw-r--r--src/include/microhttpd.h7
-rw-r--r--src/microhttpd/connection.c33
-rw-r--r--src/microhttpd/internal.h10
-rw-r--r--src/microhttpd/response.c31
-rw-r--r--src/microhttpd/response.h18
6 files changed, 75 insertions, 28 deletions
diff --git a/ChangeLog b/ChangeLog
index 7d61213c..2033ed4a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h
index ff292280..0a7e4711 100644
--- a/src/include/microhttpd.h
+++ b/src/include/microhttpd.h
@@ -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
diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c
index ff7f663f..b1b34cef 100644
--- a/src/microhttpd/connection.c
+++ b/src/microhttpd/connection.c
@@ -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;
diff --git a/src/microhttpd/internal.h b/src/microhttpd/internal.h
index d6f1177c..a810d319 100644
--- a/src/microhttpd/internal.h
+++ b/src/microhttpd/internal.h
@@ -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
};
diff --git a/src/microhttpd/response.c b/src/microhttpd/response.c
index f0ebf5c6..66a1650d 100644
--- a/src/microhttpd/response.c
+++ b/src/microhttpd/response.c
@@ -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
/**
diff --git a/src/microhttpd/response.h b/src/microhttpd/response.h
index a13683d1..ce7e131c 100644
--- a/src/microhttpd/response.h
+++ b/src/microhttpd/response.h
@@ -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