mirror of
https://github.com/Armored-Dragon/overte.git
synced 2025-03-11 16:13:16 +01:00
hook OctreeServer up to embedded-webserver
This commit is contained in:
parent
ffb628edfb
commit
5fdf310a45
12 changed files with 275 additions and 7627 deletions
|
@ -36,8 +36,6 @@ link_hifi_library(voxel-server ${TARGET_NAME} ${ROOT_DIR})
|
|||
link_hifi_library(script-engine ${TARGET_NAME} ${ROOT_DIR})
|
||||
#testing
|
||||
|
||||
include_directories(${ROOT_DIR}/externals/civetweb/include)
|
||||
|
||||
if (UNIX)
|
||||
target_link_libraries(${TARGET_NAME} ${CMAKE_DL_LIBS})
|
||||
endif (UNIX)
|
||||
|
|
|
@ -58,17 +58,6 @@ DomainServer::DomainServer(int argc, char* argv[]) :
|
|||
const char METAVOXEL_CONFIG_OPTION[] = "--metavoxelServerConfig";
|
||||
_metavoxelServerConfig = getCmdOption(argc, (const char**)argv, METAVOXEL_CONFIG_OPTION);
|
||||
|
||||
//
|
||||
// char* documentRoot = new char[documentRootString.size() + 1];
|
||||
// strcpy(documentRoot, documentRootString.toLocal8Bit().constData());
|
||||
//
|
||||
// // list of options. Last element must be NULL.
|
||||
// const char* options[] = {"listening_ports", "8080",
|
||||
// "document_root", documentRoot, NULL};
|
||||
//
|
||||
// callbacks.begin_request = civetwebRequestHandler;
|
||||
// callbacks.upload = civetwebUploadHandler;
|
||||
|
||||
connect(nodeList, SIGNAL(nodeKilled(SharedNodePointer)), this, SLOT(nodeKilled(SharedNodePointer)));
|
||||
|
||||
if (!_staticAssignmentFile.exists() || _voxelServerConfig) {
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
const int MAX_STATIC_ASSIGNMENT_FILE_ASSIGNMENTS = 1000;
|
||||
|
||||
class DomainServer : public QCoreApplication, public HttpRequestHandler {
|
||||
class DomainServer : public QCoreApplication, public HTTPRequestHandler {
|
||||
Q_OBJECT
|
||||
public:
|
||||
DomainServer(int argc, char* argv[]);
|
||||
|
|
98
externals/civetweb/LICENSE.md
vendored
98
externals/civetweb/LICENSE.md
vendored
|
@ -1,98 +0,0 @@
|
|||
ALL LICENSES
|
||||
=====
|
||||
|
||||
This document includes several copyright licenses for different
|
||||
aspects of the software. Not all licenses may apply depending
|
||||
on the features chosen.
|
||||
|
||||
Civetweb License
|
||||
-----
|
||||
|
||||
### Included with all features.
|
||||
|
||||
> Copyright (c) 2004-2013 Sergey Lyubka
|
||||
>
|
||||
> Copyright (c) 2013 No Face Press, LLC (Thomas Davis)
|
||||
>
|
||||
> Copyright (c) 2013 F-Secure Corporation
|
||||
>
|
||||
> Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
> of this software and associated documentation files (the "Software"), to deal
|
||||
> in the Software without restriction, including without limitation the rights
|
||||
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
> copies of the Software, and to permit persons to whom the Software is
|
||||
> furnished to do so, subject to the following conditions:
|
||||
>
|
||||
> The above copyright notice and this permission notice shall be included in
|
||||
> all copies or substantial portions of the Software.
|
||||
>
|
||||
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
> THE SOFTWARE.
|
||||
|
||||
Lua License
|
||||
------
|
||||
|
||||
### Included only if built with Lua support.
|
||||
|
||||
http://www.lua.org/license.html
|
||||
|
||||
> Copyright <20> 1994-2013 Lua.org, PUC-Rio.
|
||||
> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
>
|
||||
> The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
>
|
||||
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
SQLite3 License
|
||||
------
|
||||
|
||||
### Included only if built with Lua support.
|
||||
|
||||
http://www.sqlite.org/copyright.html
|
||||
|
||||
> 2001 September 15
|
||||
>
|
||||
> The author disclaims copyright to this source code. In place of
|
||||
> a legal notice, here is a blessing:
|
||||
>
|
||||
> May you do good and not evil.
|
||||
> May you find forgiveness for yourself and forgive others.
|
||||
> May you share freely, never taking more than you give.
|
||||
|
||||
lsqlite3 License
|
||||
------
|
||||
|
||||
### Included only if built with Lua support.
|
||||
|
||||
> lsqlite3
|
||||
> Copyright (C) 2002-2007 Tiago Dionizio, Doug Currie
|
||||
> All rights reserved.
|
||||
> Author : Tiago Dionizio <tiago.dionizio@ist.utl.pt>
|
||||
> Author : Doug Currie <doug.currie@alum.mit.edu>
|
||||
> Library : lsqlite3 - a SQLite 3 database binding for Lua 5
|
||||
>
|
||||
> Permission is hereby granted, free of charge, to any person obtaining
|
||||
> a copy of this software and associated documentation files (the
|
||||
> "Software"), to deal in the Software without restriction, including
|
||||
> without limitation the rights to use, copy, modify, merge, publish,
|
||||
> distribute, sublicense, and/or sell copies of the Software, and to
|
||||
> permit persons to whom the Software is furnished to do so, subject to
|
||||
> the following conditions:
|
||||
>
|
||||
> The above copyright notice and this permission notice shall be
|
||||
> included in all copies or substantial portions of the Software.
|
||||
>
|
||||
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
> EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
> MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
> IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
> CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
> TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
> SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
488
externals/civetweb/include/civetweb.h
vendored
488
externals/civetweb/include/civetweb.h
vendored
|
@ -1,488 +0,0 @@
|
|||
/* Copyright (c) 2004-2013 Sergey Lyubka
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef CIVETWEB_HEADER_INCLUDED
|
||||
#define CIVETWEB_HEADER_INCLUDED
|
||||
|
||||
#ifndef CIVETWEB_VERSION
|
||||
#define CIVETWEB_VERSION "1.6"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
struct mg_context; /* Handle for the HTTP service itself */
|
||||
struct mg_connection; /* Handle for the individual connection */
|
||||
|
||||
|
||||
/* This structure contains information about the HTTP request. */
|
||||
struct mg_request_info {
|
||||
const char *request_method; /* "GET", "POST", etc */
|
||||
const char *uri; /* URL-decoded URI */
|
||||
const char *http_version; /* E.g. "1.0", "1.1" */
|
||||
const char *query_string; /* URL part after '?', not including '?', or
|
||||
NULL */
|
||||
const char *remote_user; /* Authenticated user, or NULL if no auth
|
||||
used */
|
||||
long remote_ip; /* Client's IP address */
|
||||
int remote_port; /* Client's port */
|
||||
int is_ssl; /* 1 if SSL-ed, 0 if not */
|
||||
void *user_data; /* User data pointer passed to mg_start() */
|
||||
void *conn_data; /* Connection-specific user data */
|
||||
|
||||
int num_headers; /* Number of HTTP headers */
|
||||
struct mg_header {
|
||||
const char *name; /* HTTP header name */
|
||||
const char *value; /* HTTP header value */
|
||||
} http_headers[64]; /* Maximum 64 headers */
|
||||
};
|
||||
|
||||
|
||||
/* This structure needs to be passed to mg_start(), to let civetweb know
|
||||
which callbacks to invoke. For detailed description, see
|
||||
https://github.com/sunsetbrew/civetweb/blob/master/docs/UserManual.md */
|
||||
struct mg_callbacks {
|
||||
/* Called when civetweb has received new HTTP request.
|
||||
If callback returns non-zero,
|
||||
callback must process the request by sending valid HTTP headers and
|
||||
body, and civetweb will not do any further processing.
|
||||
If callback returns 0, civetweb processes the request itself. In this
|
||||
case, callback must not send any data to the client. */
|
||||
int (*begin_request)(struct mg_connection *);
|
||||
|
||||
/* Called when civetweb has finished processing request. */
|
||||
void (*end_request)(const struct mg_connection *, int reply_status_code);
|
||||
|
||||
/* Called when civetweb is about to log a message. If callback returns
|
||||
non-zero, civetweb does not log anything. */
|
||||
int (*log_message)(const struct mg_connection *, const char *message);
|
||||
|
||||
/* Called when civetweb initializes SSL library. */
|
||||
int (*init_ssl)(void *ssl_context, void *user_data);
|
||||
|
||||
/* Called when websocket request is received, before websocket handshake.
|
||||
If callback returns 0, civetweb proceeds with handshake, otherwise
|
||||
cinnection is closed immediately. */
|
||||
int (*websocket_connect)(const struct mg_connection *);
|
||||
|
||||
/* Called when websocket handshake is successfully completed, and
|
||||
connection is ready for data exchange. */
|
||||
void (*websocket_ready)(struct mg_connection *);
|
||||
|
||||
/* Called when data frame has been received from the client.
|
||||
Parameters:
|
||||
bits: first byte of the websocket frame, see websocket RFC at
|
||||
http://tools.ietf.org/html/rfc6455, section 5.2
|
||||
data, data_len: payload, with mask (if any) already applied.
|
||||
Return value:
|
||||
non-0: keep this websocket connection opened.
|
||||
0: close this websocket connection. */
|
||||
int (*websocket_data)(struct mg_connection *, int bits,
|
||||
char *data, size_t data_len);
|
||||
|
||||
/* Called when civetweb is closing a connection. The per-context mutex is
|
||||
locked when this is invoked. This is primarily useful for noting when
|
||||
a websocket is closing and removing it from any application-maintained
|
||||
list of clients. */
|
||||
void (*connection_close)(struct mg_connection *);
|
||||
|
||||
/* Called when civetweb tries to open a file. Used to intercept file open
|
||||
calls, and serve file data from memory instead.
|
||||
Parameters:
|
||||
path: Full path to the file to open.
|
||||
data_len: Placeholder for the file size, if file is served from
|
||||
memory.
|
||||
Return value:
|
||||
NULL: do not serve file from memory, proceed with normal file open.
|
||||
non-NULL: pointer to the file contents in memory. data_len must be
|
||||
initilized with the size of the memory block. */
|
||||
const char * (*open_file)(const struct mg_connection *,
|
||||
const char *path, size_t *data_len);
|
||||
|
||||
/* Called when civetweb is about to serve Lua server page (.lp file), if
|
||||
Lua support is enabled.
|
||||
Parameters:
|
||||
lua_context: "lua_State *" pointer. */
|
||||
void (*init_lua)(struct mg_connection *, void *lua_context);
|
||||
|
||||
/* Called when civetweb has uploaded a file to a temporary directory as a
|
||||
result of mg_upload() call.
|
||||
Parameters:
|
||||
file_file: full path name to the uploaded file. */
|
||||
void (*upload)(struct mg_connection *, const char *file_name);
|
||||
|
||||
/* Called when civetweb is about to send HTTP error to the client.
|
||||
Implementing this callback allows to create custom error pages.
|
||||
Parameters:
|
||||
status: HTTP error status code. */
|
||||
int (*http_error)(struct mg_connection *, int status);
|
||||
};
|
||||
|
||||
/* Start web server.
|
||||
|
||||
Parameters:
|
||||
callbacks: mg_callbacks structure with user-defined callbacks.
|
||||
options: NULL terminated list of option_name, option_value pairs that
|
||||
specify Civetweb configuration parameters.
|
||||
|
||||
Side-effects: on UNIX, ignores SIGCHLD and SIGPIPE signals. If custom
|
||||
processing is required for these, signal handlers must be set up
|
||||
after calling mg_start().
|
||||
|
||||
|
||||
Example:
|
||||
const char *options[] = {
|
||||
"document_root", "/var/www",
|
||||
"listening_ports", "80,443s",
|
||||
NULL
|
||||
};
|
||||
struct mg_context *ctx = mg_start(&my_func, NULL, options);
|
||||
|
||||
Refer to https://github.com/sunsetbrew/civetweb/blob/master/docs/UserManual.md
|
||||
for the list of valid option and their possible values.
|
||||
|
||||
Return:
|
||||
web server context, or NULL on error. */
|
||||
struct mg_context *mg_start(const struct mg_callbacks *callbacks,
|
||||
void *user_data,
|
||||
const char **configuration_options);
|
||||
|
||||
|
||||
/* Stop the web server.
|
||||
|
||||
Must be called last, when an application wants to stop the web server and
|
||||
release all associated resources. This function blocks until all Civetweb
|
||||
threads are stopped. Context pointer becomes invalid. */
|
||||
void mg_stop(struct mg_context *);
|
||||
|
||||
/* mg_request_handler
|
||||
|
||||
Called when a new request comes in. This callback is URI based
|
||||
and configured with mg_set_request_handler().
|
||||
|
||||
Parameters:
|
||||
conn: current connection information.
|
||||
cbdata: the callback data configured with mg_set_request_handler().
|
||||
Returns:
|
||||
0: the handler could not handle the request, so fall through.
|
||||
1: the handler processed the request. */
|
||||
typedef int (* mg_request_handler)(struct mg_connection *conn, void *cbdata);
|
||||
|
||||
/* mg_set_request_handler
|
||||
|
||||
Sets or removes a URI mapping for a request handler.
|
||||
|
||||
URI's are ordered and prefixed URI's are supported. For example,
|
||||
consider two URIs: /a/b and /a
|
||||
/a matches /a
|
||||
/a/b matches /a/b
|
||||
/a/c matches /a
|
||||
|
||||
Parameters:
|
||||
ctx: server context
|
||||
uri: the URI to configure
|
||||
handler: the callback handler to use when the URI is requested.
|
||||
If NULL, the URI will be removed.
|
||||
cbdata: the callback data to give to the handler when it s requested. */
|
||||
void mg_set_request_handler(struct mg_context *ctx, const char *uri, mg_request_handler handler, void *cbdata);
|
||||
|
||||
|
||||
/* Get the value of particular configuration parameter.
|
||||
The value returned is read-only. Civetweb does not allow changing
|
||||
configuration at run time.
|
||||
If given parameter name is not valid, NULL is returned. For valid
|
||||
names, return value is guaranteed to be non-NULL. If parameter is not
|
||||
set, zero-length string is returned. */
|
||||
const char *mg_get_option(const struct mg_context *ctx, const char *name);
|
||||
|
||||
|
||||
/* Return array of strings that represent valid configuration options.
|
||||
For each option, option name and default value is returned, i.e. the
|
||||
number of entries in the array equals to number_of_options x 2.
|
||||
Array is NULL terminated. */
|
||||
const char **mg_get_valid_option_names(void);
|
||||
|
||||
|
||||
/* Add, edit or delete the entry in the passwords file.
|
||||
|
||||
This function allows an application to manipulate .htpasswd files on the
|
||||
fly by adding, deleting and changing user records. This is one of the
|
||||
several ways of implementing authentication on the server side. For another,
|
||||
cookie-based way please refer to the examples/chat in the source tree.
|
||||
|
||||
If password is not NULL, entry is added (or modified if already exists).
|
||||
If password is NULL, entry is deleted.
|
||||
|
||||
Return:
|
||||
1 on success, 0 on error. */
|
||||
int mg_modify_passwords_file(const char *passwords_file_name,
|
||||
const char *domain,
|
||||
const char *user,
|
||||
const char *password);
|
||||
|
||||
|
||||
/* Return information associated with the request. */
|
||||
struct mg_request_info *mg_get_request_info(struct mg_connection *);
|
||||
|
||||
|
||||
/* Send data to the client.
|
||||
Return:
|
||||
0 when the connection has been closed
|
||||
-1 on error
|
||||
>0 number of bytes written on success */
|
||||
int mg_write(struct mg_connection *, const void *buf, size_t len);
|
||||
|
||||
|
||||
/* Send data to a websocket client wrapped in a websocket frame. Uses mg_lock
|
||||
to ensure that the transmission is not interrupted, i.e., when the
|
||||
application is proactively communicating and responding to a request
|
||||
simultaneously.
|
||||
|
||||
Send data to a websocket client wrapped in a websocket frame.
|
||||
This function is available when civetweb is compiled with -DUSE_WEBSOCKET
|
||||
|
||||
Return:
|
||||
0 when the connection has been closed
|
||||
-1 on error
|
||||
>0 number of bytes written on success */
|
||||
int mg_websocket_write(struct mg_connection* conn, int opcode,
|
||||
const char *data, size_t data_len);
|
||||
|
||||
/* Blocks until unique access is obtained to this connection. Intended for use
|
||||
with websockets only.
|
||||
Invoke this before mg_write or mg_printf when communicating with a
|
||||
websocket if your code has server-initiated communication as well as
|
||||
communication in direct response to a message. */
|
||||
void mg_lock(struct mg_connection* conn);
|
||||
void mg_unlock(struct mg_connection* conn);
|
||||
|
||||
/* Opcodes, from http://tools.ietf.org/html/rfc6455 */
|
||||
enum {
|
||||
WEBSOCKET_OPCODE_CONTINUATION = 0x0,
|
||||
WEBSOCKET_OPCODE_TEXT = 0x1,
|
||||
WEBSOCKET_OPCODE_BINARY = 0x2,
|
||||
WEBSOCKET_OPCODE_CONNECTION_CLOSE = 0x8,
|
||||
WEBSOCKET_OPCODE_PING = 0x9,
|
||||
WEBSOCKET_OPCODE_PONG = 0xa
|
||||
};
|
||||
|
||||
|
||||
/* Macros for enabling compiler-specific checks for printf-like arguments. */
|
||||
#undef PRINTF_FORMAT_STRING
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1400
|
||||
#include <sal.h>
|
||||
#if defined(_MSC_VER) && _MSC_VER > 1400
|
||||
#define PRINTF_FORMAT_STRING(s) _Printf_format_string_ s
|
||||
#else
|
||||
#define PRINTF_FORMAT_STRING(s) __format_string s
|
||||
#endif
|
||||
#else
|
||||
#define PRINTF_FORMAT_STRING(s) s
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define PRINTF_ARGS(x, y) __attribute__((format(printf, x, y)))
|
||||
#else
|
||||
#define PRINTF_ARGS(x, y)
|
||||
#endif
|
||||
|
||||
/* Send data to the client using printf() semantics.
|
||||
|
||||
Works exactly like mg_write(), but allows to do message formatting. */
|
||||
int mg_printf(struct mg_connection *,
|
||||
PRINTF_FORMAT_STRING(const char *fmt), ...) PRINTF_ARGS(2, 3);
|
||||
|
||||
|
||||
/* Send contents of the entire file together with HTTP headers. */
|
||||
void mg_send_file(struct mg_connection *conn, const char *path);
|
||||
|
||||
|
||||
/* Read data from the remote end, return number of bytes read.
|
||||
Return:
|
||||
0 connection has been closed by peer. No more data could be read.
|
||||
< 0 read error. No more data could be read from the connection.
|
||||
> 0 number of bytes read into the buffer. */
|
||||
int mg_read(struct mg_connection *, void *buf, size_t len);
|
||||
|
||||
|
||||
/* Get the value of particular HTTP header.
|
||||
|
||||
This is a helper function. It traverses request_info->http_headers array,
|
||||
and if the header is present in the array, returns its value. If it is
|
||||
not present, NULL is returned. */
|
||||
const char *mg_get_header(const struct mg_connection *, const char *name);
|
||||
|
||||
|
||||
/* Get a value of particular form variable.
|
||||
|
||||
Parameters:
|
||||
data: pointer to form-uri-encoded buffer. This could be either POST data,
|
||||
or request_info.query_string.
|
||||
data_len: length of the encoded data.
|
||||
var_name: variable name to decode from the buffer
|
||||
dst: destination buffer for the decoded variable
|
||||
dst_len: length of the destination buffer
|
||||
|
||||
Return:
|
||||
On success, length of the decoded variable.
|
||||
On error:
|
||||
-1 (variable not found).
|
||||
-2 (destination buffer is NULL, zero length or too small to hold the
|
||||
decoded variable).
|
||||
|
||||
Destination buffer is guaranteed to be '\0' - terminated if it is not
|
||||
NULL or zero length. */
|
||||
int mg_get_var(const char *data, size_t data_len,
|
||||
const char *var_name, char *dst, size_t dst_len);
|
||||
|
||||
/* Get a value of particular form variable.
|
||||
|
||||
Parameters:
|
||||
data: pointer to form-uri-encoded buffer. This could be either POST data,
|
||||
or request_info.query_string.
|
||||
data_len: length of the encoded data.
|
||||
var_name: variable name to decode from the buffer
|
||||
dst: destination buffer for the decoded variable
|
||||
dst_len: length of the destination buffer
|
||||
occurrence: which occurrence of the variable, 0 is the first, 1 the
|
||||
second...
|
||||
this makes it possible to parse a query like
|
||||
b=x&a=y&a=z which will have occurrence values b:0, a:0 and a:1
|
||||
|
||||
Return:
|
||||
On success, length of the decoded variable.
|
||||
On error:
|
||||
-1 (variable not found).
|
||||
-2 (destination buffer is NULL, zero length or too small to hold the
|
||||
decoded variable).
|
||||
|
||||
Destination buffer is guaranteed to be '\0' - terminated if it is not
|
||||
NULL or zero length. */
|
||||
int mg_get_var2(const char *data, size_t data_len,
|
||||
const char *var_name, char *dst, size_t dst_len, size_t occurrence);
|
||||
|
||||
/* Fetch value of certain cookie variable into the destination buffer.
|
||||
|
||||
Destination buffer is guaranteed to be '\0' - terminated. In case of
|
||||
failure, dst[0] == '\0'. Note that RFC allows many occurrences of the same
|
||||
parameter. This function returns only first occurrence.
|
||||
|
||||
Return:
|
||||
On success, value length.
|
||||
On error:
|
||||
-1 (either "Cookie:" header is not present at all or the requested
|
||||
parameter is not found).
|
||||
-2 (destination buffer is NULL, zero length or too small to hold the
|
||||
value). */
|
||||
int mg_get_cookie(const char *cookie, const char *var_name,
|
||||
char *buf, size_t buf_len);
|
||||
|
||||
|
||||
/* Download data from the remote web server.
|
||||
host: host name to connect to, e.g. "foo.com", or "10.12.40.1".
|
||||
port: port number, e.g. 80.
|
||||
use_ssl: wether to use SSL connection.
|
||||
error_buffer, error_buffer_size: error message placeholder.
|
||||
request_fmt,...: HTTP request.
|
||||
Return:
|
||||
On success, valid pointer to the new connection, suitable for mg_read().
|
||||
On error, NULL. error_buffer contains error message.
|
||||
Example:
|
||||
char ebuf[100];
|
||||
struct mg_connection *conn;
|
||||
conn = mg_download("google.com", 80, 0, ebuf, sizeof(ebuf),
|
||||
"%s", "GET / HTTP/1.0\r\nHost: google.com\r\n\r\n");
|
||||
*/
|
||||
struct mg_connection *mg_download(const char *host, int port, int use_ssl,
|
||||
char *error_buffer, size_t error_buffer_size,
|
||||
PRINTF_FORMAT_STRING(const char *request_fmt),
|
||||
...) PRINTF_ARGS(6, 7);
|
||||
|
||||
|
||||
/* Close the connection opened by mg_download(). */
|
||||
void mg_close_connection(struct mg_connection *conn);
|
||||
|
||||
|
||||
/* File upload functionality. Each uploaded file gets saved into a temporary
|
||||
file and MG_UPLOAD event is sent.
|
||||
Return number of uploaded files. */
|
||||
int mg_upload(struct mg_connection *conn, const char *destination_dir);
|
||||
|
||||
|
||||
/* Convenience function -- create detached thread.
|
||||
Return: 0 on success, non-0 on error. */
|
||||
typedef void * (*mg_thread_func_t)(void *);
|
||||
int mg_start_thread(mg_thread_func_t f, void *p);
|
||||
|
||||
|
||||
/* Return builtin mime type for the given file name.
|
||||
For unrecognized extensions, "text/plain" is returned. */
|
||||
const char *mg_get_builtin_mime_type(const char *file_name);
|
||||
|
||||
|
||||
/* Return Civetweb version. */
|
||||
const char *mg_version(void);
|
||||
|
||||
/* URL-decode input buffer into destination buffer.
|
||||
0-terminate the destination buffer.
|
||||
form-url-encoded data differs from URI encoding in a way that it
|
||||
uses '+' as character for space, see RFC 1866 section 8.2.1
|
||||
http://ftp.ics.uci.edu/pub/ietf/html/rfc1866.txt
|
||||
Return: length of the decoded data, or -1 if dst buffer is too small. */
|
||||
int mg_url_decode(const char *src, int src_len, char *dst,
|
||||
int dst_len, int is_form_url_encoded);
|
||||
|
||||
/* URL-encode input buffer into destination buffer.
|
||||
returns the length of the resulting buffer or -1
|
||||
is the buffer is too small. */
|
||||
int mg_url_encode(const char *src, char *dst, size_t dst_len);
|
||||
|
||||
/* MD5 hash given strings.
|
||||
Buffer 'buf' must be 33 bytes long. Varargs is a NULL terminated list of
|
||||
ASCIIz strings. When function returns, buf will contain human-readable
|
||||
MD5 hash. Example:
|
||||
char buf[33];
|
||||
mg_md5(buf, "aa", "bb", NULL); */
|
||||
char *mg_md5(char buf[33], ...);
|
||||
|
||||
|
||||
/* Print error message to the opened error log stream.
|
||||
This utilizes the provided logging configuration.
|
||||
conn: connection
|
||||
fmt: format string without the line return
|
||||
...: variable argument list
|
||||
Example:
|
||||
mg_cry(conn,"i like %s", "logging"); */
|
||||
void mg_cry(struct mg_connection *conn,
|
||||
PRINTF_FORMAT_STRING(const char *fmt), ...) PRINTF_ARGS(2, 3);
|
||||
|
||||
/* utility method to compare two buffers, case incensitive. */
|
||||
int mg_strncasecmp(const char *s1, const char *s2, size_t len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* CIVETWEB_HEADER_INCLUDED */
|
461
externals/civetweb/include/md5.inl
vendored
461
externals/civetweb/include/md5.inl
vendored
|
@ -1,461 +0,0 @@
|
|||
/*
|
||||
* This an amalgamation of md5.c and md5.h into a single file
|
||||
* with all static declaration to reduce linker conflicts
|
||||
* in Civetweb.
|
||||
*
|
||||
* The MD5_STATIC declaration was added to facilitate static
|
||||
* inclusion.
|
||||
* No Face Press, LLC
|
||||
*/
|
||||
|
||||
/* $Id: md5.h,v 1.4 2002/04/13 19:20:28 lpd Exp $ */
|
||||
/*
|
||||
Independent implementation of MD5 (RFC 1321).
|
||||
|
||||
This code implements the MD5 Algorithm defined in RFC 1321, whose
|
||||
text is available at
|
||||
http://www.ietf.org/rfc/rfc1321.txt
|
||||
The code is derived from the text of the RFC, including the test suite
|
||||
(section A.5) but excluding the rest of Appendix A. It does not include
|
||||
any code or documentation that is identified in the RFC as being
|
||||
copyrighted.
|
||||
|
||||
The original and principal author of md5.h is L. Peter Deutsch
|
||||
<ghost@aladdin.com>. Other authors are noted in the change history
|
||||
that follows (in reverse chronological order):
|
||||
|
||||
2002-04-13 lpd Removed support for non-ANSI compilers; removed
|
||||
references to Ghostscript; clarified derivation from RFC 1321;
|
||||
now handles byte order either statically or dynamically.
|
||||
1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
|
||||
1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5);
|
||||
added conditionalization for C++ compilation from Martin
|
||||
Purschke <purschke@bnl.gov>.
|
||||
1999-05-03 lpd Original version.
|
||||
*/
|
||||
|
||||
#ifndef md5_INCLUDED
|
||||
# define md5_INCLUDED
|
||||
|
||||
/*
|
||||
* This package supports both compile-time and run-time determination of CPU
|
||||
* byte order. If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be
|
||||
* compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is
|
||||
* defined as non-zero, the code will be compiled to run only on big-endian
|
||||
* CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to
|
||||
* run on either big- or little-endian CPUs, but will run slightly less
|
||||
* efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined.
|
||||
*/
|
||||
|
||||
typedef unsigned char md5_byte_t; /* 8-bit byte */
|
||||
typedef unsigned int md5_word_t; /* 32-bit word */
|
||||
|
||||
/* Define the state of the MD5 Algorithm. */
|
||||
typedef struct md5_state_s {
|
||||
md5_word_t count[2]; /* message length in bits, lsw first */
|
||||
md5_word_t abcd[4]; /* digest buffer */
|
||||
md5_byte_t buf[64]; /* accumulate block */
|
||||
} md5_state_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/* Initialize the algorithm. */
|
||||
MD5_STATIC void md5_init(md5_state_t *pms);
|
||||
|
||||
/* Append a string to the message. */
|
||||
MD5_STATIC void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes);
|
||||
|
||||
/* Finish the message and return the digest. */
|
||||
MD5_STATIC void md5_finish(md5_state_t *pms, md5_byte_t digest[16]);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* end extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* md5_INCLUDED */
|
||||
|
||||
/*
|
||||
Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved.
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
L. Peter Deutsch
|
||||
ghost@aladdin.com
|
||||
|
||||
*/
|
||||
/* $Id: md5.c,v 1.6 2002/04/13 19:20:28 lpd Exp $ */
|
||||
/*
|
||||
Independent implementation of MD5 (RFC 1321).
|
||||
|
||||
This code implements the MD5 Algorithm defined in RFC 1321, whose
|
||||
text is available at
|
||||
http://www.ietf.org/rfc/rfc1321.txt
|
||||
The code is derived from the text of the RFC, including the test suite
|
||||
(section A.5) but excluding the rest of Appendix A. It does not include
|
||||
any code or documentation that is identified in the RFC as being
|
||||
copyrighted.
|
||||
|
||||
The original and principal author of md5.c is L. Peter Deutsch
|
||||
<ghost@aladdin.com>. Other authors are noted in the change history
|
||||
that follows (in reverse chronological order):
|
||||
|
||||
2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order
|
||||
either statically or dynamically; added missing #include <string.h>
|
||||
in library.
|
||||
2002-03-11 lpd Corrected argument list for main(), and added int return
|
||||
type, in test program and T value program.
|
||||
2002-02-21 lpd Added missing #include <stdio.h> in test program.
|
||||
2000-07-03 lpd Patched to eliminate warnings about "constant is
|
||||
unsigned in ANSI C, signed in traditional"; made test program
|
||||
self-checking.
|
||||
1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
|
||||
1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5).
|
||||
1999-05-03 lpd Original version.
|
||||
*/
|
||||
|
||||
#ifndef MD5_STATIC
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */
|
||||
#ifdef ARCH_IS_BIG_ENDIAN
|
||||
# define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1)
|
||||
#else
|
||||
# define BYTE_ORDER 0
|
||||
#endif
|
||||
|
||||
#define T_MASK ((md5_word_t)~0)
|
||||
#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87)
|
||||
#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9)
|
||||
#define T3 0x242070db
|
||||
#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111)
|
||||
#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050)
|
||||
#define T6 0x4787c62a
|
||||
#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec)
|
||||
#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe)
|
||||
#define T9 0x698098d8
|
||||
#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850)
|
||||
#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e)
|
||||
#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841)
|
||||
#define T13 0x6b901122
|
||||
#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c)
|
||||
#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71)
|
||||
#define T16 0x49b40821
|
||||
#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d)
|
||||
#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf)
|
||||
#define T19 0x265e5a51
|
||||
#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855)
|
||||
#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2)
|
||||
#define T22 0x02441453
|
||||
#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e)
|
||||
#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437)
|
||||
#define T25 0x21e1cde6
|
||||
#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829)
|
||||
#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278)
|
||||
#define T28 0x455a14ed
|
||||
#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa)
|
||||
#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07)
|
||||
#define T31 0x676f02d9
|
||||
#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375)
|
||||
#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd)
|
||||
#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e)
|
||||
#define T35 0x6d9d6122
|
||||
#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3)
|
||||
#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb)
|
||||
#define T38 0x4bdecfa9
|
||||
#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f)
|
||||
#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f)
|
||||
#define T41 0x289b7ec6
|
||||
#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805)
|
||||
#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a)
|
||||
#define T44 0x04881d05
|
||||
#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6)
|
||||
#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a)
|
||||
#define T47 0x1fa27cf8
|
||||
#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a)
|
||||
#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb)
|
||||
#define T50 0x432aff97
|
||||
#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58)
|
||||
#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6)
|
||||
#define T53 0x655b59c3
|
||||
#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d)
|
||||
#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82)
|
||||
#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e)
|
||||
#define T57 0x6fa87e4f
|
||||
#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f)
|
||||
#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb)
|
||||
#define T60 0x4e0811a1
|
||||
#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d)
|
||||
#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca)
|
||||
#define T63 0x2ad7d2bb
|
||||
#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e)
|
||||
|
||||
|
||||
static void
|
||||
md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/)
|
||||
{
|
||||
md5_word_t
|
||||
a = pms->abcd[0], b = pms->abcd[1],
|
||||
c = pms->abcd[2], d = pms->abcd[3];
|
||||
md5_word_t t;
|
||||
#if BYTE_ORDER > 0
|
||||
/* Define storage only for big-endian CPUs. */
|
||||
md5_word_t X[16];
|
||||
#else
|
||||
/* Define storage for little-endian or both types of CPUs. */
|
||||
md5_word_t xbuf[16];
|
||||
const md5_word_t *X;
|
||||
#endif
|
||||
|
||||
{
|
||||
#if BYTE_ORDER == 0
|
||||
/*
|
||||
* Determine dynamically whether this is a big-endian or
|
||||
* little-endian machine, since we can use a more efficient
|
||||
* algorithm on the latter.
|
||||
*/
|
||||
static const int w = 1;
|
||||
|
||||
if (*((const md5_byte_t *)&w)) /* dynamic little-endian */
|
||||
#endif
|
||||
#if BYTE_ORDER <= 0 /* little-endian */
|
||||
{
|
||||
/*
|
||||
* On little-endian machines, we can process properly aligned
|
||||
* data without copying it.
|
||||
*/
|
||||
if (!((data - (const md5_byte_t *)0) & 3)) {
|
||||
/* data are properly aligned */
|
||||
X = (const md5_word_t *)data;
|
||||
} else {
|
||||
/* not aligned */
|
||||
memcpy(xbuf, data, 64);
|
||||
X = xbuf;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if BYTE_ORDER == 0
|
||||
else /* dynamic big-endian */
|
||||
#endif
|
||||
#if BYTE_ORDER >= 0 /* big-endian */
|
||||
{
|
||||
/*
|
||||
* On big-endian machines, we must arrange the bytes in the
|
||||
* right order.
|
||||
*/
|
||||
const md5_byte_t *xp = data;
|
||||
int i;
|
||||
|
||||
# if BYTE_ORDER == 0
|
||||
X = xbuf; /* (dynamic only) */
|
||||
# else
|
||||
# define xbuf X /* (static only) */
|
||||
# endif
|
||||
for (i = 0; i < 16; ++i, xp += 4)
|
||||
xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
|
||||
|
||||
/* Round 1. */
|
||||
/* Let [abcd k s i] denote the operation
|
||||
a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
|
||||
#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
|
||||
#define SET(a, b, c, d, k, s, Ti)\
|
||||
t = a + F(b,c,d) + X[k] + Ti;\
|
||||
a = ROTATE_LEFT(t, s) + b
|
||||
/* Do the following 16 operations. */
|
||||
SET(a, b, c, d, 0, 7, T1);
|
||||
SET(d, a, b, c, 1, 12, T2);
|
||||
SET(c, d, a, b, 2, 17, T3);
|
||||
SET(b, c, d, a, 3, 22, T4);
|
||||
SET(a, b, c, d, 4, 7, T5);
|
||||
SET(d, a, b, c, 5, 12, T6);
|
||||
SET(c, d, a, b, 6, 17, T7);
|
||||
SET(b, c, d, a, 7, 22, T8);
|
||||
SET(a, b, c, d, 8, 7, T9);
|
||||
SET(d, a, b, c, 9, 12, T10);
|
||||
SET(c, d, a, b, 10, 17, T11);
|
||||
SET(b, c, d, a, 11, 22, T12);
|
||||
SET(a, b, c, d, 12, 7, T13);
|
||||
SET(d, a, b, c, 13, 12, T14);
|
||||
SET(c, d, a, b, 14, 17, T15);
|
||||
SET(b, c, d, a, 15, 22, T16);
|
||||
#undef SET
|
||||
|
||||
/* Round 2. */
|
||||
/* Let [abcd k s i] denote the operation
|
||||
a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
|
||||
#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
|
||||
#define SET(a, b, c, d, k, s, Ti)\
|
||||
t = a + G(b,c,d) + X[k] + Ti;\
|
||||
a = ROTATE_LEFT(t, s) + b
|
||||
/* Do the following 16 operations. */
|
||||
SET(a, b, c, d, 1, 5, T17);
|
||||
SET(d, a, b, c, 6, 9, T18);
|
||||
SET(c, d, a, b, 11, 14, T19);
|
||||
SET(b, c, d, a, 0, 20, T20);
|
||||
SET(a, b, c, d, 5, 5, T21);
|
||||
SET(d, a, b, c, 10, 9, T22);
|
||||
SET(c, d, a, b, 15, 14, T23);
|
||||
SET(b, c, d, a, 4, 20, T24);
|
||||
SET(a, b, c, d, 9, 5, T25);
|
||||
SET(d, a, b, c, 14, 9, T26);
|
||||
SET(c, d, a, b, 3, 14, T27);
|
||||
SET(b, c, d, a, 8, 20, T28);
|
||||
SET(a, b, c, d, 13, 5, T29);
|
||||
SET(d, a, b, c, 2, 9, T30);
|
||||
SET(c, d, a, b, 7, 14, T31);
|
||||
SET(b, c, d, a, 12, 20, T32);
|
||||
#undef SET
|
||||
|
||||
/* Round 3. */
|
||||
/* Let [abcd k s t] denote the operation
|
||||
a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
|
||||
#define H(x, y, z) ((x) ^ (y) ^ (z))
|
||||
#define SET(a, b, c, d, k, s, Ti)\
|
||||
t = a + H(b,c,d) + X[k] + Ti;\
|
||||
a = ROTATE_LEFT(t, s) + b
|
||||
/* Do the following 16 operations. */
|
||||
SET(a, b, c, d, 5, 4, T33);
|
||||
SET(d, a, b, c, 8, 11, T34);
|
||||
SET(c, d, a, b, 11, 16, T35);
|
||||
SET(b, c, d, a, 14, 23, T36);
|
||||
SET(a, b, c, d, 1, 4, T37);
|
||||
SET(d, a, b, c, 4, 11, T38);
|
||||
SET(c, d, a, b, 7, 16, T39);
|
||||
SET(b, c, d, a, 10, 23, T40);
|
||||
SET(a, b, c, d, 13, 4, T41);
|
||||
SET(d, a, b, c, 0, 11, T42);
|
||||
SET(c, d, a, b, 3, 16, T43);
|
||||
SET(b, c, d, a, 6, 23, T44);
|
||||
SET(a, b, c, d, 9, 4, T45);
|
||||
SET(d, a, b, c, 12, 11, T46);
|
||||
SET(c, d, a, b, 15, 16, T47);
|
||||
SET(b, c, d, a, 2, 23, T48);
|
||||
#undef SET
|
||||
|
||||
/* Round 4. */
|
||||
/* Let [abcd k s t] denote the operation
|
||||
a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
|
||||
#define I(x, y, z) ((y) ^ ((x) | ~(z)))
|
||||
#define SET(a, b, c, d, k, s, Ti)\
|
||||
t = a + I(b,c,d) + X[k] + Ti;\
|
||||
a = ROTATE_LEFT(t, s) + b
|
||||
/* Do the following 16 operations. */
|
||||
SET(a, b, c, d, 0, 6, T49);
|
||||
SET(d, a, b, c, 7, 10, T50);
|
||||
SET(c, d, a, b, 14, 15, T51);
|
||||
SET(b, c, d, a, 5, 21, T52);
|
||||
SET(a, b, c, d, 12, 6, T53);
|
||||
SET(d, a, b, c, 3, 10, T54);
|
||||
SET(c, d, a, b, 10, 15, T55);
|
||||
SET(b, c, d, a, 1, 21, T56);
|
||||
SET(a, b, c, d, 8, 6, T57);
|
||||
SET(d, a, b, c, 15, 10, T58);
|
||||
SET(c, d, a, b, 6, 15, T59);
|
||||
SET(b, c, d, a, 13, 21, T60);
|
||||
SET(a, b, c, d, 4, 6, T61);
|
||||
SET(d, a, b, c, 11, 10, T62);
|
||||
SET(c, d, a, b, 2, 15, T63);
|
||||
SET(b, c, d, a, 9, 21, T64);
|
||||
#undef SET
|
||||
|
||||
/* Then perform the following additions. (That is increment each
|
||||
of the four registers by the value it had before this block
|
||||
was started.) */
|
||||
pms->abcd[0] += a;
|
||||
pms->abcd[1] += b;
|
||||
pms->abcd[2] += c;
|
||||
pms->abcd[3] += d;
|
||||
}
|
||||
|
||||
MD5_STATIC void
|
||||
md5_init(md5_state_t *pms)
|
||||
{
|
||||
pms->count[0] = pms->count[1] = 0;
|
||||
pms->abcd[0] = 0x67452301;
|
||||
pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476;
|
||||
pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301;
|
||||
pms->abcd[3] = 0x10325476;
|
||||
}
|
||||
|
||||
MD5_STATIC void
|
||||
md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes)
|
||||
{
|
||||
const md5_byte_t *p = data;
|
||||
int left = nbytes;
|
||||
int offset = (pms->count[0] >> 3) & 63;
|
||||
md5_word_t nbits = (md5_word_t)(nbytes << 3);
|
||||
|
||||
if (nbytes <= 0)
|
||||
return;
|
||||
|
||||
/* Update the message length. */
|
||||
pms->count[1] += nbytes >> 29;
|
||||
pms->count[0] += nbits;
|
||||
if (pms->count[0] < nbits)
|
||||
pms->count[1]++;
|
||||
|
||||
/* Process an initial partial block. */
|
||||
if (offset) {
|
||||
int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
|
||||
|
||||
memcpy(pms->buf + offset, p, copy);
|
||||
if (offset + copy < 64)
|
||||
return;
|
||||
p += copy;
|
||||
left -= copy;
|
||||
md5_process(pms, pms->buf);
|
||||
}
|
||||
|
||||
/* Process full blocks. */
|
||||
for (; left >= 64; p += 64, left -= 64)
|
||||
md5_process(pms, p);
|
||||
|
||||
/* Process a final partial block. */
|
||||
if (left)
|
||||
memcpy(pms->buf, p, left);
|
||||
}
|
||||
|
||||
MD5_STATIC void
|
||||
md5_finish(md5_state_t *pms, md5_byte_t digest[16])
|
||||
{
|
||||
static const md5_byte_t pad[64] = {
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
md5_byte_t data[8];
|
||||
int i;
|
||||
|
||||
/* Save the length before padding. */
|
||||
for (i = 0; i < 8; ++i)
|
||||
data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
|
||||
/* Pad to 56 bytes mod 64. */
|
||||
md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
|
||||
/* Append the length. */
|
||||
md5_append(pms, data, 8);
|
||||
for (i = 0; i < 16; ++i)
|
||||
digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
|
||||
}
|
6273
externals/civetweb/src/civetweb.c
vendored
6273
externals/civetweb/src/civetweb.c
vendored
File diff suppressed because it is too large
Load diff
|
@ -108,7 +108,7 @@ bool HTTPManager::handleHTTPRequest(HTTPConnection* connection, const QString& p
|
|||
return true;
|
||||
}
|
||||
|
||||
HTTPManager::HTTPManager(quint16 port, const QString& documentRoot, HttpRequestHandler* requestHandler, QObject* parent) :
|
||||
HTTPManager::HTTPManager(quint16 port, const QString& documentRoot, HTTPRequestHandler* requestHandler, QObject* parent) :
|
||||
QTcpServer(parent),
|
||||
_documentRoot(documentRoot),
|
||||
_requestHandler(requestHandler)
|
||||
|
|
|
@ -17,18 +17,18 @@
|
|||
|
||||
class HTTPConnection;
|
||||
|
||||
class HttpRequestHandler {
|
||||
class HTTPRequestHandler {
|
||||
public:
|
||||
/// Handles an HTTP request.
|
||||
virtual bool handleHTTPRequest(HTTPConnection* connection, const QString& path) = 0;
|
||||
};
|
||||
|
||||
/// Handles HTTP connections
|
||||
class HTTPManager : public QTcpServer, public HttpRequestHandler {
|
||||
class HTTPManager : public QTcpServer, public HTTPRequestHandler {
|
||||
Q_OBJECT
|
||||
public:
|
||||
/// Initializes the manager.
|
||||
HTTPManager(quint16 port, const QString& documentRoot, HttpRequestHandler* requestHandler = NULL, QObject* parent = 0);
|
||||
HTTPManager(quint16 port, const QString& documentRoot, HTTPRequestHandler* requestHandler = NULL, QObject* parent = 0);
|
||||
|
||||
bool handleHTTPRequest(HTTPConnection* connection, const QString& path);
|
||||
|
||||
|
@ -37,7 +37,7 @@ protected slots:
|
|||
void acceptConnections();
|
||||
protected:
|
||||
QString _documentRoot;
|
||||
HttpRequestHandler* _requestHandler;
|
||||
HTTPRequestHandler* _requestHandler;
|
||||
};
|
||||
|
||||
#endif /* defined(__hifi__HTTPManager__) */
|
||||
|
|
|
@ -12,13 +12,8 @@ find_package(Qt5Widgets REQUIRED)
|
|||
|
||||
include(${MACRO_DIR}/SetupHifiLibrary.cmake)
|
||||
|
||||
# grab cJSON and civetweb sources to pass as OPTIONAL_SRCS
|
||||
FILE(GLOB OPTIONAL_SRCS ${ROOT_DIR}/externals/civetweb/src/*)
|
||||
|
||||
setup_hifi_library(${TARGET_NAME} ${OPTIONAL_SRCS})
|
||||
|
||||
include_directories(${ROOT_DIR}/externals/civetweb/include)
|
||||
|
||||
qt5_use_modules(${TARGET_NAME} Widgets)
|
||||
|
||||
include(${MACRO_DIR}/IncludeGLM.cmake)
|
||||
|
@ -36,7 +31,5 @@ link_hifi_library(shared ${TARGET_NAME} ${ROOT_DIR})
|
|||
# link in the hifi octree library
|
||||
link_hifi_library(octree ${TARGET_NAME} ${ROOT_DIR})
|
||||
|
||||
# link dl library on UNIX for civetweb
|
||||
if (UNIX AND NOT APPLE)
|
||||
target_link_libraries(${TARGET_NAME} ${CMAKE_DL_LIBS})
|
||||
endif (UNIX AND NOT APPLE)
|
||||
# link the embedded webserver
|
||||
link_hifi_library(embedded-webserver ${TARGET_NAME} ${ROOT_DIR})
|
|
@ -6,25 +6,25 @@
|
|||
// Copyright (c) 2013 HighFidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#include "civetweb.h"
|
||||
|
||||
#include <QtCore/QTimer>
|
||||
#include <QtCore/QUuid>
|
||||
#include <QtNetwork/QNetworkAccessManager>
|
||||
|
||||
#include <time.h>
|
||||
#include <HTTPConnection.h>
|
||||
#include <Logging.h>
|
||||
#include <UUID.h>
|
||||
|
||||
#include "OctreeServer.h"
|
||||
#include "OctreeServerConsts.h"
|
||||
|
||||
OctreeServer* OctreeServer::_instance = NULL;
|
||||
|
||||
void OctreeServer::attachQueryNodeToNode(Node* newNode) {
|
||||
if (newNode->getLinkedData() == NULL) {
|
||||
if (GetInstance()) {
|
||||
OctreeQueryNode* newQueryNodeData = GetInstance()->createOctreeQueryNode(newNode);
|
||||
newQueryNodeData->resetOctreePacket(true); // don't bump sequence
|
||||
newNode->setLinkedData(newQueryNodeData);
|
||||
}
|
||||
OctreeQueryNode* newQueryNodeData = _instance->createOctreeQueryNode(newNode);
|
||||
newQueryNodeData->resetOctreePacket(true); // don't bump sequence
|
||||
newNode->setLinkedData(newQueryNodeData);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -39,30 +39,26 @@ void OctreeServer::nodeKilled(SharedNodePointer node) {
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
OctreeServer* OctreeServer::_theInstance = NULL;
|
||||
|
||||
OctreeServer::OctreeServer(const unsigned char* dataBuffer, int numBytes) :
|
||||
ThreadedAssignment(dataBuffer, numBytes)
|
||||
ThreadedAssignment(dataBuffer, numBytes),
|
||||
_argc(0),
|
||||
_argv(NULL),
|
||||
_parsedArgV(NULL),
|
||||
_httpManager(NULL),
|
||||
_packetsPerClientPerInterval(10),
|
||||
_tree(NULL),
|
||||
_wantPersist(true),
|
||||
_debugSending(false),
|
||||
_debugReceiving(false),
|
||||
_verboseDebug(false),
|
||||
_jurisdiction(NULL),
|
||||
_jurisdictionSender(NULL),
|
||||
_octreeInboundPacketProcessor(NULL),
|
||||
_persistThread(NULL),
|
||||
_started(time(0)),
|
||||
_startedUSecs(usecTimestampNow())
|
||||
{
|
||||
_argc = 0;
|
||||
_argv = NULL;
|
||||
_tree = NULL;
|
||||
_packetsPerClientPerInterval = 10;
|
||||
_wantPersist = true;
|
||||
_debugSending = false;
|
||||
_debugReceiving = false;
|
||||
_verboseDebug = false;
|
||||
_jurisdiction = NULL;
|
||||
_jurisdictionSender = NULL;
|
||||
_octreeInboundPacketProcessor = NULL;
|
||||
_persistThread = NULL;
|
||||
_parsedArgV = NULL;
|
||||
|
||||
_started = time(0);
|
||||
_startedUSecs = usecTimestampNow();
|
||||
|
||||
_theInstance = this;
|
||||
_instance = this;
|
||||
}
|
||||
|
||||
OctreeServer::~OctreeServer() {
|
||||
|
@ -94,235 +90,220 @@ OctreeServer::~OctreeServer() {
|
|||
qDebug() << "OctreeServer::run()... DONE";
|
||||
}
|
||||
|
||||
void OctreeServer::initMongoose(int port) {
|
||||
// setup the mongoose web server
|
||||
struct mg_callbacks callbacks = {};
|
||||
void OctreeServer::initHTTPManager(int port) {
|
||||
// setup the embedded web server
|
||||
|
||||
QString documentRoot = QString("%1/resources/web").arg(QCoreApplication::applicationDirPath());
|
||||
QString listenPort = QString("%1").arg(port);
|
||||
|
||||
|
||||
// list of options. Last element must be NULL.
|
||||
const char* options[] = {
|
||||
"listening_ports", listenPort.toLocal8Bit().constData(),
|
||||
"document_root", documentRoot.toLocal8Bit().constData(),
|
||||
NULL };
|
||||
|
||||
callbacks.begin_request = civetwebRequestHandler;
|
||||
|
||||
// Start the web server.
|
||||
mg_start(&callbacks, NULL, options);
|
||||
// setup an httpManager with us as the request handler and the parent
|
||||
_httpManager = new HTTPManager(port, documentRoot, this, this);
|
||||
}
|
||||
|
||||
int OctreeServer::civetwebRequestHandler(struct mg_connection* connection) {
|
||||
const struct mg_request_info* ri = mg_get_request_info(connection);
|
||||
|
||||
OctreeServer* theServer = GetInstance();
|
||||
|
||||
bool OctreeServer::handleHTTPRequest(HTTPConnection* connection, const QString& path) {
|
||||
|
||||
#ifdef FORCE_CRASH
|
||||
if (strcmp(ri->uri, "/force_crash") == 0 && strcmp(ri->request_method, "GET") == 0) {
|
||||
if (connection->requestOperation() == QNetworkAccessManager::GetOperation
|
||||
&& path == "/force_crash") {
|
||||
|
||||
qDebug() << "About to force a crash!";
|
||||
|
||||
int foo;
|
||||
int* forceCrash = &foo;
|
||||
mg_printf(connection, "%s", "HTTP/1.0 200 OK\r\n\r\n");
|
||||
mg_printf(connection, "%s", "forcing a crash....\r\n");
|
||||
|
||||
QString responseString("forcing a crash...");
|
||||
connection->respond(HTTPConnection::StatusCode200, qPrintable(responseString));
|
||||
|
||||
delete[] forceCrash;
|
||||
mg_printf(connection, "%s", "did it crash....\r\n");
|
||||
return 1;
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
bool showStats = false;
|
||||
if (strcmp(ri->uri, "/") == 0 && strcmp(ri->request_method, "GET") == 0) {
|
||||
showStats = true;
|
||||
|
||||
if (connection->requestOperation() == QNetworkAccessManager::GetOperation) {
|
||||
if (path == "/") {
|
||||
showStats = true;
|
||||
} else if (path == "/resetStats") {
|
||||
_octreeInboundPacketProcessor->resetStats();
|
||||
showStats = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (strcmp(ri->uri, "/resetStats") == 0 && strcmp(ri->request_method, "GET") == 0) {
|
||||
theServer->_octreeInboundPacketProcessor->resetStats();
|
||||
showStats = true;
|
||||
}
|
||||
|
||||
|
||||
if (showStats) {
|
||||
uint64_t checkSum;
|
||||
// return a 200
|
||||
mg_printf(connection, "%s", "HTTP/1.0 200 OK\r\n");
|
||||
mg_printf(connection, "%s", "Content-Type: text/html\r\n\r\n");
|
||||
mg_printf(connection, "%s", "<html><doc>\r\n");
|
||||
mg_printf(connection, "%s", "<pre>\r\n");
|
||||
mg_printf(connection, "<b>Your %s Server is running... <a href='/'>[RELOAD]</a></b>\r\n", theServer->getMyServerName());
|
||||
|
||||
tm* localtm = localtime(&theServer->_started);
|
||||
QString statsString("<html><doc>\r\n<pre>\r\n");
|
||||
statsString += QString("<b>Your %1 Server is running... <a href='/'>[RELOAD]</a></b>\r\n").arg(getMyServerName());
|
||||
|
||||
tm* localtm = localtime(&_started);
|
||||
const int MAX_TIME_LENGTH = 128;
|
||||
char buffer[MAX_TIME_LENGTH];
|
||||
strftime(buffer, MAX_TIME_LENGTH, "%m/%d/%Y %X", localtm);
|
||||
mg_printf(connection, "Running since: %s", buffer);
|
||||
|
||||
statsString += QString("Running since: %1").arg(buffer);
|
||||
|
||||
// Convert now to tm struct for UTC
|
||||
tm* gmtm = gmtime(&theServer->_started);
|
||||
if (gmtm != NULL) {
|
||||
tm* gmtm = gmtime(&_started);
|
||||
if (gmtm) {
|
||||
strftime(buffer, MAX_TIME_LENGTH, "%m/%d/%Y %X", gmtm);
|
||||
mg_printf(connection, " [%s UTM] ", buffer);
|
||||
statsString += (QString(" [%1 UTM] ").arg(buffer));
|
||||
}
|
||||
mg_printf(connection, "%s", "\r\n");
|
||||
|
||||
|
||||
statsString += "\r\n";
|
||||
|
||||
uint64_t now = usecTimestampNow();
|
||||
const int USECS_PER_MSEC = 1000;
|
||||
uint64_t msecsElapsed = (now - theServer->_startedUSecs) / USECS_PER_MSEC;
|
||||
uint64_t msecsElapsed = (now - _startedUSecs) / USECS_PER_MSEC;
|
||||
const int MSECS_PER_SEC = 1000;
|
||||
const int SECS_PER_MIN = 60;
|
||||
const int MIN_PER_HOUR = 60;
|
||||
const int MSECS_PER_MIN = MSECS_PER_SEC * SECS_PER_MIN;
|
||||
|
||||
|
||||
float seconds = (msecsElapsed % MSECS_PER_MIN)/(float)MSECS_PER_SEC;
|
||||
int minutes = (msecsElapsed/(MSECS_PER_MIN)) % MIN_PER_HOUR;
|
||||
int hours = (msecsElapsed/(MSECS_PER_MIN * MIN_PER_HOUR));
|
||||
|
||||
mg_printf(connection, "%s", "Uptime: ");
|
||||
|
||||
statsString += "Uptime: ";
|
||||
|
||||
if (hours > 0) {
|
||||
mg_printf(connection, "%d hour%s ", hours, (hours > 1) ? "s" : "" );
|
||||
statsString += QString("%1 hour%2").arg(hours).arg((hours > 1) ? "s" : "");
|
||||
}
|
||||
if (minutes > 0) {
|
||||
mg_printf(connection, "%d minute%s ", minutes, (minutes > 1) ? "s" : "");
|
||||
statsString += QString("%1 minute%s").arg(minutes).arg((minutes > 1) ? "s" : "");
|
||||
}
|
||||
if (seconds > 0) {
|
||||
mg_printf(connection, "%.3f seconds ", seconds);
|
||||
statsString += QString().sprintf("%.3f seconds", seconds);
|
||||
}
|
||||
mg_printf(connection, "%s", "\r\n");
|
||||
mg_printf(connection, "%s", "\r\n");
|
||||
|
||||
|
||||
statsString += "\r\n\r\n";
|
||||
|
||||
// display voxel file load time
|
||||
if (theServer->isInitialLoadComplete()) {
|
||||
if (theServer->isPersistEnabled()) {
|
||||
mg_printf(connection, "%s File Persist Enabled...\r\n", theServer->getMyServerName());
|
||||
if (isInitialLoadComplete()) {
|
||||
if (isPersistEnabled()) {
|
||||
statsString += QString("%1 File Persist Enabled...\r\n").arg(getMyServerName());
|
||||
} else {
|
||||
mg_printf(connection, "%s File Persist Disabled...\r\n", theServer->getMyServerName());
|
||||
statsString += QString("%1 File Persist Disabled...\r\n").arg(getMyServerName());
|
||||
}
|
||||
mg_printf(connection, "%s", "\r\n");
|
||||
|
||||
uint64_t msecsElapsed = theServer->getLoadElapsedTime() / USECS_PER_MSEC;;
|
||||
|
||||
statsString += "\r\n";
|
||||
|
||||
uint64_t msecsElapsed = getLoadElapsedTime() / USECS_PER_MSEC;;
|
||||
float seconds = (msecsElapsed % MSECS_PER_MIN)/(float)MSECS_PER_SEC;
|
||||
int minutes = (msecsElapsed/(MSECS_PER_MIN)) % MIN_PER_HOUR;
|
||||
int hours = (msecsElapsed/(MSECS_PER_MIN * MIN_PER_HOUR));
|
||||
|
||||
mg_printf(connection, "%s File Load Took: ", theServer->getMyServerName());
|
||||
|
||||
statsString += QString("%1 File Load Took").arg(getMyServerName());
|
||||
if (hours > 0) {
|
||||
mg_printf(connection, "%d hour%s ", hours, (hours > 1) ? "s" : "" );
|
||||
statsString += QString("%1 hour%2").arg(hours).arg((hours > 1) ? "s" : "");
|
||||
}
|
||||
if (minutes > 0) {
|
||||
mg_printf(connection, "%d minute%s ", minutes, (minutes > 1) ? "s" : "");
|
||||
statsString += QString("%1 minute%2").arg(minutes).arg((minutes > 1) ? "s" : "");
|
||||
}
|
||||
if (seconds >= 0) {
|
||||
mg_printf(connection, "%.3f seconds", seconds);
|
||||
statsString += QString().sprintf("%.3f seconds", seconds);
|
||||
}
|
||||
mg_printf(connection, "%s", "\r\n");
|
||||
|
||||
statsString += "\r\n";
|
||||
|
||||
} else {
|
||||
mg_printf(connection, "%s", "Voxels not yet loaded...\r\n");
|
||||
statsString += "Voxels not yet loaded...\r\n";
|
||||
}
|
||||
|
||||
mg_printf(connection, "%s", "\r\n");
|
||||
|
||||
mg_printf(connection, "%s", "\r\n");
|
||||
|
||||
mg_printf(connection, "%s", "<b>Configuration:</b>\r\n");
|
||||
|
||||
for (int i = 1; i < theServer->_argc; i++) {
|
||||
mg_printf(connection, "%s ", theServer->_argv[i]);
|
||||
|
||||
statsString += "\r\n\r\n";
|
||||
statsString += "<b>Configuration:</b>\r\n";
|
||||
|
||||
for (int i = 1; i < _argc; i++) {
|
||||
statsString += _argv[i];
|
||||
}
|
||||
mg_printf(connection, "%s", "\r\n"); // one to end the config line
|
||||
mg_printf(connection, "%s", "\r\n"); // two more for spacing
|
||||
mg_printf(connection, "%s", "\r\n");
|
||||
|
||||
statsString += "\r\n"; //one to end the config line
|
||||
statsString += "\r\n\r\n"; // two more for spacing
|
||||
|
||||
// display scene stats
|
||||
unsigned long nodeCount = OctreeElement::getNodeCount();
|
||||
unsigned long internalNodeCount = OctreeElement::getInternalNodeCount();
|
||||
unsigned long leafNodeCount = OctreeElement::getLeafNodeCount();
|
||||
|
||||
|
||||
QLocale locale(QLocale::English);
|
||||
const float AS_PERCENT = 100.0;
|
||||
mg_printf(connection, "%s", "<b>Current Nodes in scene:</b>\r\n");
|
||||
mg_printf(connection, " Total Nodes: %s nodes\r\n",
|
||||
locale.toString((uint)nodeCount).rightJustified(16, ' ').toLocal8Bit().constData());
|
||||
mg_printf(connection, " Internal Nodes: %s nodes (%5.2f%%)\r\n",
|
||||
locale.toString((uint)internalNodeCount).rightJustified(16, ' ').toLocal8Bit().constData(),
|
||||
((float)internalNodeCount / (float)nodeCount) * AS_PERCENT);
|
||||
mg_printf(connection, " Leaf Nodes: %s nodes (%5.2f%%)\r\n",
|
||||
locale.toString((uint)leafNodeCount).rightJustified(16, ' ').toLocal8Bit().constData(),
|
||||
((float)leafNodeCount / (float)nodeCount) * AS_PERCENT);
|
||||
mg_printf(connection, "%s", "\r\n");
|
||||
mg_printf(connection, "%s", "\r\n");
|
||||
|
||||
|
||||
statsString += "<b>Current Nodes in scene:</b>\r\n";
|
||||
statsString += QString(" Total Nodes: %1 nodes\r\n").arg(locale.toString((uint)nodeCount).rightJustified(16, ' '));
|
||||
statsString += QString().sprintf(" Internal Nodes: %s nodes (%5.2f%%)\r\n",
|
||||
locale.toString((uint)internalNodeCount).rightJustified(16,
|
||||
' ').toLocal8Bit().constData(),
|
||||
((float)internalNodeCount / (float)nodeCount) * AS_PERCENT);
|
||||
statsString += QString().sprintf(" Leaf Nodes: %s nodes (%5.2f%%)\r\n",
|
||||
locale.toString((uint)leafNodeCount).rightJustified(16, ' ').toLocal8Bit().constData(),
|
||||
((float)leafNodeCount / (float)nodeCount) * AS_PERCENT);
|
||||
statsString += "\r\n";
|
||||
statsString += "\r\n";
|
||||
|
||||
// display outbound packet stats
|
||||
mg_printf(connection, "<b>%s Outbound Packet Statistics...</b>\r\n", theServer->getMyServerName());
|
||||
statsString += QString("<b>%1 Outbound Packet Statistics...</b>\r\n").arg(getMyServerName());
|
||||
uint64_t totalOutboundPackets = OctreeSendThread::_totalPackets;
|
||||
uint64_t totalOutboundBytes = OctreeSendThread::_totalBytes;
|
||||
uint64_t totalWastedBytes = OctreeSendThread::_totalWastedBytes;
|
||||
uint64_t totalBytesOfOctalCodes = OctreePacketData::getTotalBytesOfOctalCodes();
|
||||
uint64_t totalBytesOfBitMasks = OctreePacketData::getTotalBytesOfBitMasks();
|
||||
uint64_t totalBytesOfColor = OctreePacketData::getTotalBytesOfColor();
|
||||
|
||||
|
||||
const int COLUMN_WIDTH = 10;
|
||||
mg_printf(connection, " Total Outbound Packets: %s packets\r\n",
|
||||
locale.toString((uint)totalOutboundPackets).rightJustified(COLUMN_WIDTH, ' ').toLocal8Bit().constData());
|
||||
mg_printf(connection, " Total Outbound Bytes: %s bytes\r\n",
|
||||
locale.toString((uint)totalOutboundBytes).rightJustified(COLUMN_WIDTH, ' ').toLocal8Bit().constData());
|
||||
mg_printf(connection, " Total Wasted Bytes: %s bytes\r\n",
|
||||
locale.toString((uint)totalWastedBytes).rightJustified(COLUMN_WIDTH, ' ').toLocal8Bit().constData());
|
||||
mg_printf(connection, " Total OctalCode Bytes: %s bytes (%5.2f%%)\r\n",
|
||||
statsString += QString(" Total Outbound Packets: %1 packets\r\n")
|
||||
.arg(locale.toString((uint)totalOutboundPackets).rightJustified(COLUMN_WIDTH, ' '));
|
||||
statsString += QString(" Total Outbound Bytes: %1 bytes\r\n")
|
||||
.arg(locale.toString((uint)totalOutboundBytes).rightJustified(COLUMN_WIDTH, ' '));
|
||||
statsString += QString(" Total Wasted Bytes: %1 bytes\r\n")
|
||||
.arg(locale.toString((uint)totalWastedBytes).rightJustified(COLUMN_WIDTH, ' '));
|
||||
statsString += QString().sprintf(" Total OctalCode Bytes: %s bytes (%5.2f%%)\r\n",
|
||||
locale.toString((uint)totalBytesOfOctalCodes).rightJustified(COLUMN_WIDTH, ' ').toLocal8Bit().constData(),
|
||||
((float)totalBytesOfOctalCodes / (float)totalOutboundBytes) * AS_PERCENT);
|
||||
mg_printf(connection, " Total BitMasks Bytes: %s bytes (%5.2f%%)\r\n",
|
||||
statsString += QString().sprintf(" Total BitMasks Bytes: %s bytes (%5.2f%%)\r\n",
|
||||
locale.toString((uint)totalBytesOfBitMasks).rightJustified(COLUMN_WIDTH, ' ').toLocal8Bit().constData(),
|
||||
((float)totalBytesOfBitMasks / (float)totalOutboundBytes) * AS_PERCENT);
|
||||
mg_printf(connection, " Total Color Bytes: %s bytes (%5.2f%%)\r\n",
|
||||
statsString += QString().sprintf(" Total Color Bytes: %s bytes (%5.2f%%)\r\n",
|
||||
locale.toString((uint)totalBytesOfColor).rightJustified(COLUMN_WIDTH, ' ').toLocal8Bit().constData(),
|
||||
((float)totalBytesOfColor / (float)totalOutboundBytes) * AS_PERCENT);
|
||||
|
||||
mg_printf(connection, "%s", "\r\n");
|
||||
mg_printf(connection, "%s", "\r\n");
|
||||
|
||||
|
||||
statsString += "\r\n";
|
||||
statsString += "\r\n";
|
||||
|
||||
// display inbound packet stats
|
||||
mg_printf(connection, "<b>%s Edit Statistics... <a href='/resetStats'>[RESET]</a></b>\r\n",
|
||||
theServer->getMyServerName());
|
||||
uint64_t averageTransitTimePerPacket = theServer->_octreeInboundPacketProcessor->getAverageTransitTimePerPacket();
|
||||
uint64_t averageProcessTimePerPacket = theServer->_octreeInboundPacketProcessor->getAverageProcessTimePerPacket();
|
||||
uint64_t averageLockWaitTimePerPacket = theServer->_octreeInboundPacketProcessor->getAverageLockWaitTimePerPacket();
|
||||
uint64_t averageProcessTimePerElement = theServer->_octreeInboundPacketProcessor->getAverageProcessTimePerElement();
|
||||
uint64_t averageLockWaitTimePerElement = theServer->_octreeInboundPacketProcessor->getAverageLockWaitTimePerElement();
|
||||
uint64_t totalElementsProcessed = theServer->_octreeInboundPacketProcessor->getTotalElementsProcessed();
|
||||
uint64_t totalPacketsProcessed = theServer->_octreeInboundPacketProcessor->getTotalPacketsProcessed();
|
||||
|
||||
statsString += QString().sprintf("<b>%s Edit Statistics... <a href='/resetStats'>[RESET]</a></b>\r\n",
|
||||
getMyServerName());
|
||||
uint64_t averageTransitTimePerPacket = _octreeInboundPacketProcessor->getAverageTransitTimePerPacket();
|
||||
uint64_t averageProcessTimePerPacket = _octreeInboundPacketProcessor->getAverageProcessTimePerPacket();
|
||||
uint64_t averageLockWaitTimePerPacket = _octreeInboundPacketProcessor->getAverageLockWaitTimePerPacket();
|
||||
uint64_t averageProcessTimePerElement = _octreeInboundPacketProcessor->getAverageProcessTimePerElement();
|
||||
uint64_t averageLockWaitTimePerElement = _octreeInboundPacketProcessor->getAverageLockWaitTimePerElement();
|
||||
uint64_t totalElementsProcessed = _octreeInboundPacketProcessor->getTotalElementsProcessed();
|
||||
uint64_t totalPacketsProcessed = _octreeInboundPacketProcessor->getTotalPacketsProcessed();
|
||||
|
||||
float averageElementsPerPacket = totalPacketsProcessed == 0 ? 0 : totalElementsProcessed / totalPacketsProcessed;
|
||||
|
||||
mg_printf(connection, " Total Inbound Packets: %s packets\r\n",
|
||||
locale.toString((uint)totalPacketsProcessed).rightJustified(COLUMN_WIDTH, ' ').toLocal8Bit().constData());
|
||||
mg_printf(connection, " Total Inbound Elements: %s elements\r\n",
|
||||
locale.toString((uint)totalElementsProcessed).rightJustified(COLUMN_WIDTH, ' ').toLocal8Bit().constData());
|
||||
mg_printf(connection, " Average Inbound Elements/Packet: %f elements/packet\r\n", averageElementsPerPacket);
|
||||
mg_printf(connection, " Average Transit Time/Packet: %s usecs\r\n",
|
||||
locale.toString((uint)averageTransitTimePerPacket).rightJustified(COLUMN_WIDTH, ' ').toLocal8Bit().constData());
|
||||
mg_printf(connection, " Average Process Time/Packet: %s usecs\r\n",
|
||||
locale.toString((uint)averageProcessTimePerPacket).rightJustified(COLUMN_WIDTH, ' ').toLocal8Bit().constData());
|
||||
mg_printf(connection, " Average Wait Lock Time/Packet: %s usecs\r\n",
|
||||
locale.toString((uint)averageLockWaitTimePerPacket).rightJustified(COLUMN_WIDTH, ' ').toLocal8Bit().constData());
|
||||
mg_printf(connection, " Average Process Time/Element: %s usecs\r\n",
|
||||
locale.toString((uint)averageProcessTimePerElement).rightJustified(COLUMN_WIDTH, ' ').toLocal8Bit().constData());
|
||||
mg_printf(connection, " Average Wait Lock Time/Element: %s usecs\r\n",
|
||||
locale.toString((uint)averageLockWaitTimePerElement).rightJustified(COLUMN_WIDTH, ' ').toLocal8Bit().constData());
|
||||
|
||||
|
||||
|
||||
statsString += QString(" Total Inbound Packets: %1 packets\r\n")
|
||||
.arg(locale.toString((uint)totalPacketsProcessed).rightJustified(COLUMN_WIDTH, ' '));
|
||||
statsString += QString(" Total Inbound Elements: %1 elements\r\n")
|
||||
.arg(locale.toString((uint)totalElementsProcessed).rightJustified(COLUMN_WIDTH, ' '));
|
||||
statsString += QString().sprintf(" Average Inbound Elements/Packet: %f elements/packet\r\n", averageElementsPerPacket);
|
||||
statsString += QString(" Average Transit Time/Packet: %1 usecs\r\n")
|
||||
.arg(locale.toString((uint)averageTransitTimePerPacket).rightJustified(COLUMN_WIDTH, ' '));
|
||||
statsString += QString(" Average Process Time/Packet: %1 usecs\r\n")
|
||||
.arg(locale.toString((uint)averageProcessTimePerPacket).rightJustified(COLUMN_WIDTH, ' '));
|
||||
statsString += QString(" Average Wait Lock Time/Packet: %1 usecs\r\n")
|
||||
.arg(locale.toString((uint)averageLockWaitTimePerPacket).rightJustified(COLUMN_WIDTH, ' '));
|
||||
statsString += QString(" Average Process Time/Element: %1 usecs\r\n")
|
||||
.arg(locale.toString((uint)averageProcessTimePerElement).rightJustified(COLUMN_WIDTH, ' '));
|
||||
statsString += QString(" Average Wait Lock Time/Element: %1 usecs\r\n")
|
||||
.arg(locale.toString((uint)averageLockWaitTimePerElement).rightJustified(COLUMN_WIDTH, ' '));
|
||||
|
||||
|
||||
int senderNumber = 0;
|
||||
NodeToSenderStatsMap& allSenderStats = theServer->_octreeInboundPacketProcessor->getSingleSenderStats();
|
||||
NodeToSenderStatsMap& allSenderStats = _octreeInboundPacketProcessor->getSingleSenderStats();
|
||||
for (NodeToSenderStatsMapIterator i = allSenderStats.begin(); i != allSenderStats.end(); i++) {
|
||||
senderNumber++;
|
||||
QUuid senderID = i->first;
|
||||
SingleSenderStats& senderStats = i->second;
|
||||
|
||||
mg_printf(connection, "\r\n Stats for sender %d uuid: %s\r\n", senderNumber,
|
||||
senderID.toString().toLocal8Bit().constData());
|
||||
|
||||
|
||||
statsString += QString("\r\n Stats for sender %1 uuid: %2\r\n")
|
||||
.arg(senderNumber).arg(senderID.toString());
|
||||
|
||||
averageTransitTimePerPacket = senderStats.getAverageTransitTimePerPacket();
|
||||
averageProcessTimePerPacket = senderStats.getAverageProcessTimePerPacket();
|
||||
averageLockWaitTimePerPacket = senderStats.getAverageLockWaitTimePerPacket();
|
||||
|
@ -330,36 +311,35 @@ int OctreeServer::civetwebRequestHandler(struct mg_connection* connection) {
|
|||
averageLockWaitTimePerElement = senderStats.getAverageLockWaitTimePerElement();
|
||||
totalElementsProcessed = senderStats.getTotalElementsProcessed();
|
||||
totalPacketsProcessed = senderStats.getTotalPacketsProcessed();
|
||||
|
||||
|
||||
averageElementsPerPacket = totalPacketsProcessed == 0 ? 0 : totalElementsProcessed / totalPacketsProcessed;
|
||||
|
||||
mg_printf(connection, " Total Inbound Packets: %s packets\r\n",
|
||||
locale.toString((uint)totalPacketsProcessed).rightJustified(COLUMN_WIDTH, ' ').toLocal8Bit().constData());
|
||||
mg_printf(connection, " Total Inbound Elements: %s elements\r\n",
|
||||
locale.toString((uint)totalElementsProcessed).rightJustified(COLUMN_WIDTH, ' ').toLocal8Bit().constData());
|
||||
mg_printf(connection, " Average Inbound Elements/Packet: %f elements/packet\r\n", averageElementsPerPacket);
|
||||
mg_printf(connection, " Average Transit Time/Packet: %s usecs\r\n",
|
||||
locale.toString((uint)averageTransitTimePerPacket).rightJustified(COLUMN_WIDTH, ' ').toLocal8Bit().constData());
|
||||
mg_printf(connection, " Average Process Time/Packet: %s usecs\r\n",
|
||||
locale.toString((uint)averageProcessTimePerPacket).rightJustified(COLUMN_WIDTH, ' ').toLocal8Bit().constData());
|
||||
mg_printf(connection, " Average Wait Lock Time/Packet: %s usecs\r\n",
|
||||
locale.toString((uint)averageLockWaitTimePerPacket).rightJustified(COLUMN_WIDTH, ' ').toLocal8Bit().constData());
|
||||
mg_printf(connection, " Average Process Time/Element: %s usecs\r\n",
|
||||
locale.toString((uint)averageProcessTimePerElement).rightJustified(COLUMN_WIDTH, ' ').toLocal8Bit().constData());
|
||||
mg_printf(connection, " Average Wait Lock Time/Element: %s usecs\r\n",
|
||||
locale.toString((uint)averageLockWaitTimePerElement).rightJustified(COLUMN_WIDTH, ' ').toLocal8Bit().constData());
|
||||
|
||||
|
||||
statsString += QString(" Total Inbound Packets: %1 packets\r\n")
|
||||
.arg(locale.toString((uint)totalPacketsProcessed).rightJustified(COLUMN_WIDTH, ' '));
|
||||
statsString += QString(" Total Inbound Elements: %1 elements\r\n")
|
||||
.arg(locale.toString((uint)totalElementsProcessed).rightJustified(COLUMN_WIDTH, ' '));
|
||||
statsString += QString().sprintf(" Average Inbound Elements/Packet: %f elements/packet\r\n",
|
||||
averageElementsPerPacket);
|
||||
statsString += QString(" Average Transit Time/Packet: %1 usecs\r\n")
|
||||
.arg(locale.toString((uint)averageTransitTimePerPacket).rightJustified(COLUMN_WIDTH, ' '));
|
||||
statsString += QString(" Average Process Time/Packet: %1 usecs\r\n")
|
||||
.arg(locale.toString((uint)averageProcessTimePerPacket).rightJustified(COLUMN_WIDTH, ' '));
|
||||
statsString += QString(" Average Wait Lock Time/Packet: %1 usecs\r\n")
|
||||
.arg(locale.toString((uint)averageLockWaitTimePerPacket).rightJustified(COLUMN_WIDTH, ' '));
|
||||
statsString += QString(" Average Process Time/Element: %1 usecs\r\n")
|
||||
.arg(locale.toString((uint)averageProcessTimePerElement).rightJustified(COLUMN_WIDTH, ' '));
|
||||
statsString += QString(" Average Wait Lock Time/Element: %1 usecs\r\n")
|
||||
.arg(locale.toString((uint)averageLockWaitTimePerElement).rightJustified(COLUMN_WIDTH, ' '));
|
||||
|
||||
}
|
||||
|
||||
|
||||
mg_printf(connection, "%s", "\r\n");
|
||||
mg_printf(connection, "%s", "\r\n");
|
||||
|
||||
|
||||
statsString += "\r\n\r\n";
|
||||
|
||||
// display memory usage stats
|
||||
mg_printf(connection, "%s", "<b>Current Memory Usage Statistics</b>\r\n");
|
||||
mg_printf(connection, "\r\nOctreeElement size... %ld bytes\r\n", sizeof(OctreeElement));
|
||||
mg_printf(connection, "%s", "\r\n");
|
||||
|
||||
statsString += "<b>Current Memory Usage Statistics</b>\r\n";
|
||||
statsString += QString().sprintf("\r\nOctreeElement size... %ld bytes\r\n", sizeof(OctreeElement));
|
||||
statsString += "\r\n";
|
||||
|
||||
const char* memoryScaleLabel;
|
||||
const float MEGABYTES = 1000000.f;
|
||||
const float GIGABYTES = 1000000000.f;
|
||||
|
@ -371,82 +351,84 @@ int OctreeServer::civetwebRequestHandler(struct mg_connection* connection) {
|
|||
memoryScaleLabel = "GB";
|
||||
memoryScale = GIGABYTES;
|
||||
}
|
||||
|
||||
mg_printf(connection, "Element Node Memory Usage: %8.2f %s\r\n",
|
||||
OctreeElement::getVoxelMemoryUsage() / memoryScale, memoryScaleLabel);
|
||||
mg_printf(connection, "Octcode Memory Usage: %8.2f %s\r\n",
|
||||
OctreeElement::getOctcodeMemoryUsage() / memoryScale, memoryScaleLabel);
|
||||
mg_printf(connection, "External Children Memory Usage: %8.2f %s\r\n",
|
||||
OctreeElement::getExternalChildrenMemoryUsage() / memoryScale, memoryScaleLabel);
|
||||
mg_printf(connection, "%s", " -----------\r\n");
|
||||
mg_printf(connection, " Total: %8.2f %s\r\n",
|
||||
OctreeElement::getTotalMemoryUsage() / memoryScale, memoryScaleLabel);
|
||||
|
||||
mg_printf(connection, "%s", "\r\n");
|
||||
mg_printf(connection, "%s", "OctreeElement Children Population Statistics...\r\n");
|
||||
|
||||
statsString += QString().sprintf("Element Node Memory Usage: %8.2f %s\r\n",
|
||||
OctreeElement::getVoxelMemoryUsage() / memoryScale, memoryScaleLabel);
|
||||
statsString += QString().sprintf("Octcode Memory Usage: %8.2f %s\r\n",
|
||||
OctreeElement::getOctcodeMemoryUsage() / memoryScale, memoryScaleLabel);
|
||||
statsString += QString().sprintf("External Children Memory Usage: %8.2f %s\r\n",
|
||||
OctreeElement::getExternalChildrenMemoryUsage() / memoryScale, memoryScaleLabel);
|
||||
statsString += " -----------\r\n";
|
||||
statsString += QString().sprintf(" Total: %8.2f %s\r\n",
|
||||
OctreeElement::getTotalMemoryUsage() / memoryScale, memoryScaleLabel);
|
||||
statsString += "\r\n";
|
||||
|
||||
statsString += "OctreeElement Children Population Statistics...\r\n";
|
||||
checkSum = 0;
|
||||
for (int i=0; i <= NUMBER_OF_CHILDREN; i++) {
|
||||
checkSum += OctreeElement::getChildrenCount(i);
|
||||
mg_printf(connection, " Nodes with %d children: %s nodes (%5.2f%%)\r\n", i,
|
||||
locale.toString((uint)OctreeElement::getChildrenCount(i)).rightJustified(16, ' ').toLocal8Bit().constData(),
|
||||
((float)OctreeElement::getChildrenCount(i) / (float)nodeCount) * AS_PERCENT);
|
||||
statsString += QString().sprintf(" Nodes with %d children: %s nodes (%5.2f%%)\r\n", i,
|
||||
locale.toString((uint)OctreeElement::getChildrenCount(i)).rightJustified(16, ' ').toLocal8Bit().constData(),
|
||||
((float)OctreeElement::getChildrenCount(i) / (float)nodeCount) * AS_PERCENT);
|
||||
}
|
||||
mg_printf(connection, "%s", " ----------------------\r\n");
|
||||
mg_printf(connection, " Total: %s nodes\r\n",
|
||||
locale.toString((uint)checkSum).rightJustified(16, ' ').toLocal8Bit().constData());
|
||||
|
||||
statsString += " ----------------------\r\n";
|
||||
statsString += QString(" Total: %1 nodes\r\n")
|
||||
.arg(locale.toString((uint)checkSum).rightJustified(16, ' '));
|
||||
|
||||
#ifdef BLENDED_UNION_CHILDREN
|
||||
mg_printf(connection, "%s", "\r\n");
|
||||
mg_printf(connection, "%s", "OctreeElement Children Encoding Statistics...\r\n");
|
||||
|
||||
mg_printf(connection, " Single or No Children: %10.llu nodes (%5.2f%%)\r\n",
|
||||
OctreeElement::getSingleChildrenCount(), ((float)OctreeElement::getSingleChildrenCount() / (float)nodeCount) * AS_PERCENT);
|
||||
mg_printf(connection, " Two Children as Offset: %10.llu nodes (%5.2f%%)\r\n",
|
||||
OctreeElement::getTwoChildrenOffsetCount(),
|
||||
((float)OctreeElement::getTwoChildrenOffsetCount() / (float)nodeCount) * AS_PERCENT);
|
||||
mg_printf(connection, " Two Children as External: %10.llu nodes (%5.2f%%)\r\n",
|
||||
OctreeElement::getTwoChildrenExternalCount(),
|
||||
((float)OctreeElement::getTwoChildrenExternalCount() / (float)nodeCount) * AS_PERCENT);
|
||||
mg_printf(connection, " Three Children as Offset: %10.llu nodes (%5.2f%%)\r\n",
|
||||
OctreeElement::getThreeChildrenOffsetCount(),
|
||||
((float)OctreeElement::getThreeChildrenOffsetCount() / (float)nodeCount) * AS_PERCENT);
|
||||
mg_printf(connection, " Three Children as External: %10.llu nodes (%5.2f%%)\r\n",
|
||||
OctreeElement::getThreeChildrenExternalCount(),
|
||||
((float)OctreeElement::getThreeChildrenExternalCount() / (float)nodeCount) * AS_PERCENT);
|
||||
mg_printf(connection, " Children as External Array: %10.llu nodes (%5.2f%%)\r\n",
|
||||
OctreeElement::getExternalChildrenCount(),
|
||||
((float)OctreeElement::getExternalChildrenCount() / (float)nodeCount) * AS_PERCENT);
|
||||
|
||||
statsString += "\r\n";
|
||||
statsString += "OctreeElement Children Encoding Statistics...\r\n";
|
||||
|
||||
statsString += QString().sprintf(" Single or No Children: %10.llu nodes (%5.2f%%)\r\n",
|
||||
OctreeElement::getSingleChildrenCount(),
|
||||
((float)OctreeElement::getSingleChildrenCount() / (float)nodeCount) * AS_PERCENT));
|
||||
statsString += QString().sprintf(" Two Children as Offset: %10.llu nodes (%5.2f%%)\r\n",
|
||||
OctreeElement::getTwoChildrenOffsetCount(),
|
||||
((float)OctreeElement::getTwoChildrenOffsetCount() / (float)nodeCount) * AS_PERCENT));
|
||||
statsString += QString().sprintf(" Two Children as External: %10.llu nodes (%5.2f%%)\r\n",
|
||||
OctreeElement::getTwoChildrenExternalCount(),
|
||||
((float)OctreeElement::getTwoChildrenExternalCount() / (float)nodeCount) * AS_PERCENT);
|
||||
statsString += QString().sprintf(" Three Children as Offset: %10.llu nodes (%5.2f%%)\r\n",
|
||||
OctreeElement::getThreeChildrenOffsetCount(),
|
||||
((float)OctreeElement::getThreeChildrenOffsetCount() / (float)nodeCount) * AS_PERCENT);
|
||||
statsString += QString().sprintf(" Three Children as External: %10.llu nodes (%5.2f%%)\r\n",
|
||||
OctreeElement::getThreeChildrenExternalCount(),
|
||||
((float)OctreeElement::getThreeChildrenExternalCount() / (float)nodeCount) * AS_PERCENT);
|
||||
statsString += QString().sprintf(" Children as External Array: %10.llu nodes (%5.2f%%)\r\n",
|
||||
OctreeElement::getExternalChildrenCount(),
|
||||
((float)OctreeElement::getExternalChildrenCount() / (float)nodeCount) * AS_PERCENT);
|
||||
|
||||
checkSum = OctreeElement::getSingleChildrenCount() +
|
||||
OctreeElement::getTwoChildrenOffsetCount() + OctreeElement::getTwoChildrenExternalCount() +
|
||||
OctreeElement::getThreeChildrenOffsetCount() + OctreeElement::getThreeChildrenExternalCount() +
|
||||
OctreeElement::getExternalChildrenCount();
|
||||
|
||||
mg_printf(connection, "%s", " ----------------\r\n");
|
||||
mg_printf(connection, " Total: %10.llu nodes\r\n", checkSum);
|
||||
mg_printf(connection, " Expected: %10.lu nodes\r\n", nodeCount);
|
||||
|
||||
mg_printf(connection, "%s", "\r\n");
|
||||
mg_printf(connection, "%s", "In other news....\r\n");
|
||||
mg_printf(connection, "could store 4 children internally: %10.llu nodes\r\n",
|
||||
OctreeElement::getCouldStoreFourChildrenInternally());
|
||||
mg_printf(connection, "could NOT store 4 children internally: %10.llu nodes\r\n",
|
||||
OctreeElement::getCouldNotStoreFourChildrenInternally());
|
||||
OctreeElement::getTwoChildrenOffsetCount() + OctreeElement::getTwoChildrenExternalCount() +
|
||||
OctreeElement::getThreeChildrenOffsetCount() + OctreeElement::getThreeChildrenExternalCount() +
|
||||
OctreeElement::getExternalChildrenCount();
|
||||
|
||||
statsString += " ----------------\r\n";
|
||||
statsString += QString().sprintf(" Total: %10.llu nodes\r\n", checkSum);
|
||||
statsString += QString().sprintf(" Expected: %10.lu nodes\r\n", nodeCount);
|
||||
|
||||
statsString += "\r\n";
|
||||
statsString += "In other news....\r\n";
|
||||
|
||||
statsString += QString().sprintf("could store 4 children internally: %10.llu nodes\r\n",
|
||||
OctreeElement::getCouldStoreFourChildrenInternally());
|
||||
statsString += QString().sprintf("could NOT store 4 children internally: %10.llu nodes\r\n",
|
||||
OctreeElement::getCouldNotStoreFourChildrenInternally());
|
||||
#endif
|
||||
|
||||
mg_printf(connection, "%s", "\r\n");
|
||||
mg_printf(connection, "%s", "\r\n");
|
||||
mg_printf(connection, "%s", "</pre>\r\n");
|
||||
|
||||
mg_printf(connection, "%s", "</doc></html>");
|
||||
|
||||
return 1;
|
||||
|
||||
statsString += "\r\n\r\n";
|
||||
statsString += "</pre>\r\n";
|
||||
statsString += "</doc></html>";
|
||||
|
||||
connection->respond(HTTPConnection::StatusCode200, qPrintable(statsString), "text/html");
|
||||
|
||||
return true;
|
||||
} else {
|
||||
// have mongoose process this request from the document_root
|
||||
return 0;
|
||||
// have HTTPManager attempt to process this request from the document_root
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void OctreeServer::setArguments(int argc, char** argv) {
|
||||
_argc = argc;
|
||||
|
@ -553,7 +535,7 @@ void OctreeServer::run() {
|
|||
const char* statusPort = getCmdOption(_argc, _argv, STATUS_PORT);
|
||||
if (statusPort) {
|
||||
int statusPortNumber = atoi(statusPort);
|
||||
initMongoose(statusPortNumber);
|
||||
initHTTPManager(statusPortNumber);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
#include <QDateTime>
|
||||
#include <QtCore/QCoreApplication>
|
||||
|
||||
#include <HTTPManager.h>
|
||||
|
||||
#include <ThreadedAssignment.h>
|
||||
#include <EnvironmentData.h>
|
||||
|
||||
|
@ -23,7 +25,7 @@
|
|||
#include "OctreeInboundPacketProcessor.h"
|
||||
|
||||
/// Handles assignments of type OctreeServer - sending octrees to various clients.
|
||||
class OctreeServer : public ThreadedAssignment {
|
||||
class OctreeServer : public ThreadedAssignment, public HTTPRequestHandler {
|
||||
Q_OBJECT
|
||||
public:
|
||||
OctreeServer(const unsigned char* dataBuffer, int numBytes);
|
||||
|
@ -40,7 +42,6 @@ public:
|
|||
JurisdictionMap* getJurisdiction() { return _jurisdiction; }
|
||||
|
||||
int getPacketsPerClientPerInterval() const { return _packetsPerClientPerInterval; }
|
||||
static OctreeServer* GetInstance() { return _theInstance; }
|
||||
|
||||
bool isInitialLoadComplete() const { return (_persistThread) ? _persistThread->isInitialLoadComplete() : true; }
|
||||
bool isPersistEnabled() const { return (_persistThread) ? true : false; }
|
||||
|
@ -61,6 +62,8 @@ public:
|
|||
virtual int sendSpecialPacket(Node* node) { return 0; }
|
||||
|
||||
static void attachQueryNodeToNode(Node* newNode);
|
||||
|
||||
bool handleHTTPRequest(HTTPConnection* connection, const QString& path);
|
||||
public slots:
|
||||
/// runs the voxel server assignment
|
||||
void run();
|
||||
|
@ -69,9 +72,14 @@ public slots:
|
|||
void nodeKilled(SharedNodePointer node);
|
||||
|
||||
protected:
|
||||
void parsePayload();
|
||||
void initHTTPManager(int port);
|
||||
|
||||
int _argc;
|
||||
const char** _argv;
|
||||
char** _parsedArgV;
|
||||
|
||||
HTTPManager* _httpManager;
|
||||
|
||||
char _persistFilename[MAX_FILENAME_LENGTH];
|
||||
int _packetsPerClientPerInterval;
|
||||
|
@ -85,12 +93,10 @@ protected:
|
|||
OctreeInboundPacketProcessor* _octreeInboundPacketProcessor;
|
||||
OctreePersistThread* _persistThread;
|
||||
|
||||
void parsePayload();
|
||||
void initMongoose(int port);
|
||||
static int civetwebRequestHandler(struct mg_connection *connection);
|
||||
static OctreeServer* _theInstance;
|
||||
static OctreeServer* _instance;
|
||||
|
||||
time_t _started;
|
||||
uint64_t _startedUSecs;
|
||||
uint64_t _startedUSecs;
|
||||
};
|
||||
|
||||
#endif // __octree_server__OctreeServer__
|
||||
|
|
Loading…
Reference in a new issue