Repository: incubator-impala Updated Branches: refs/heads/master a485d44fd -> 585ee48dc
http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/0b7ae6e4/be/src/thirdparty/squeasel/squeasel.h ---------------------------------------------------------------------- diff --git a/be/src/thirdparty/squeasel/squeasel.h b/be/src/thirdparty/squeasel/squeasel.h new file mode 100644 index 0000000..a17f9ef --- /dev/null +++ b/be/src/thirdparty/squeasel/squeasel.h @@ -0,0 +1,432 @@ +// Some portions Copyright (c) 2004-2012 Sergey Lyubka +// Some portions Copyright (c) 2013 Cloudera Inc. +// +// 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 MONGOOSE_HEADER_INCLUDED +#define MONGOOSE_HEADER_INCLUDED + +#include <stdio.h> +#include <stddef.h> + +// Define this when compiling to add shims for Mongoose APIs to the +// renamed squeasel APIs +#ifdef MONGOOSE_COMPATIBLE +#define mg_callbacks sq_callbacks +#define mg_close_connection sq_close_connection +#define mg_connection sq_connection +#define mg_context sq_context +#define mg_download sq_download +#define mg_get_bound_addresses sq_get_bound_addresses +#define mg_get_builtin_mime_type sq_get_builtin_mime_type +#define mg_get_cookie sq_get_cookie +#define mg_get_header sq_get_header +#define mg_get_option sq_get_option +#define mg_get_request_info sq_get_request_info +#define mg_get_valid_option_names sq_get_valid_option_names +#define mg_get_var sq_get_var +#define mg_header sq_header +#define mg_md5 sq_md5 +#define mg_modify_passwords_file sq_modify_passwords_file +#define mg_printf sq_printf +#define mg_read sq_read +#define mg_request_info sq_request_info +#define mg_send_file sq_send_file +#define mg_start sq_start +#define mg_start_thread sq_start_thread +#define mg_stop sq_stop +#define mg_thread_func_t sq_thread_func_t +#define mg_upload sq_upload +#define mg_url_decode sq_url_decode +#define mg_version sq_version +#define mg_websocket_write sq_websocket_write +#define mg_write sq_write +#endif + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +struct sq_context; // Handle for the HTTP service itself +struct sq_connection; // Handle for the individual connection + +struct sockaddr_in; + +// This structure contains information about the HTTP request. +struct sq_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 sq_start() + void *conn_data; // Connection-specific user data + + int num_headers; // Number of HTTP headers + struct sq_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 sq_start(), to let squeasel know +// which callbacks to invoke. For detailed description, see +// https://github.mtv.cloudera.com/CDH/squeasel/blob/master/UserManual.md +struct sq_callbacks { + // Called when squeasel has received new HTTP request. + // If callback returns non-zero, + // callback must process the request by sending valid HTTP headers and body, + // and squeasel will not do any further processing. + // If callback returns 0, squeasel processes the request itself. In this case, + // callback must not send any data to the client. + int (*begin_request)(struct sq_connection *); + + // Called when squeasel has finished processing request. + void (*end_request)(const struct sq_connection *, int reply_status_code); + + // Called when squeasel is about to log a message. If callback returns + // non-zero, squeasel does not log anything. + int (*log_message)(const struct sq_connection *, const char *message); + + // Called when squeasel 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, squeasel proceeds with handshake, otherwise + // cinnection is closed immediately. + int (*websocket_connect)(const struct sq_connection *); + + // Called when websocket handshake is successfully completed, and + // connection is ready for data exchange. + void (*websocket_ready)(struct sq_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 sq_connection *, int bits, + char *data, size_t data_len); + + // Called when squeasel 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 sq_connection *, + const char *path, size_t *data_len); + + // Called when squeasel is about to serve Lua server page (.lp file), if + // Lua support is enabled. + // Parameters: + // lua_context: "lua_State *" pointer. + void (*init_lua)(struct sq_connection *, void *lua_context); + + // Called when squeasel has uploaded a file to a temporary directory as a + // result of sq_upload() call. + // Parameters: + // file_file: full path name to the uploaded file. + void (*upload)(struct sq_connection *, const char *file_name); + + // Called when squeasel 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 sq_connection *, int status); +}; + +// Start web server. +// +// Parameters: +// callbacks: sq_callbacks structure with user-defined callbacks. +// options: NULL terminated list of option_name, option_value pairs that +// specify Squeasel 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 sq_start(). +// +// +// Example: +// const char *options[] = { +// "document_root", "/var/www", +// "listening_ports", "80,443s", +// NULL +// }; +// struct sq_context *ctx = sq_start(&my_func, NULL, options); +// +// Refer to https://github.mtv.cloudera.com/CDH/squeasel/blob/master/UserManual.md +// for the list of valid option and their possible values. +// +// Return: +// web server context, or NULL on error. +struct sq_context *sq_start(const struct sq_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 Squeasel +// threads are stopped. Context pointer becomes invalid. +void sq_stop(struct sq_context *); + + +// Get the value of particular configuration parameter. +// The value returned is read-only. Squeasel 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 *sq_get_option(const struct sq_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 **sq_get_valid_option_names(void); + + +// Return the addresses that the given context is bound to. *addrs is allocated +// using malloc to be an array of sockaddr*, each of which is itself malloced. +// *num_addrs is set to the number of returned addresses. +// The user is responsible for calling free() on each address as well as the +// 'addrs' array itself, unless an error occurs. +// +// Returns 0 on success, non-zero if an error occurred. +int sq_get_bound_addresses(const struct sq_context *ctx, struct sockaddr_in ***addrs, + int *num_addrs); + +// 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.c 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 sq_modify_passwords_file(const char *passwords_file_name, + const char *domain, + const char *user, + const char *password); + + +// Return information associated with the request. +struct sq_request_info *sq_get_request_info(struct sq_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 sq_write(struct sq_connection *, const void *buf, size_t len); + + +// Send data to a websocket client wrapped in a websocket frame. +// It is unsafe to read/write to this connection from another thread. +// This function is available when squeasel is compiled with -DUSE_WEBSOCKET +// +// Return: +// 0 when the connection has been closed +// -1 on error +// >0 number of bytes written on success +int sq_websocket_write(struct sq_connection* conn, int opcode, + const char *data, size_t data_len); + +// 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 sq_write(), but allows to do message formatting. +int sq_printf(struct sq_connection *, + PRINTF_FORMAT_STRING(const char *fmt), ...) PRINTF_ARGS(2, 3); + + +// Send contents of the entire file together with HTTP headers. +void sq_send_file(struct sq_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 sq_read(struct sq_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 *sq_get_header(const struct sq_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 sq_get_var(const char *data, size_t data_len, + const char *var_name, char *dst, size_t dst_len); + +// 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 sq_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 sq_read(). +// On error, NULL. error_buffer contains error message. +// Example: +// char ebuf[100]; +// struct sq_connection *conn; +// conn = sq_download("google.com", 80, 0, ebuf, sizeof(ebuf), +// "%s", "GET / HTTP/1.0\r\nHost: google.com\r\n\r\n"); +struct sq_connection *sq_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 sq_download(). +void sq_close_connection(struct sq_connection *conn); + + +// File upload functionality. Each uploaded file gets saved into a temporary +// file and SQ_UPLOAD event is sent. +// Return number of uploaded files. +int sq_upload(struct sq_connection *conn, const char *destination_dir); + + +// Convenience function -- create detached thread. +// Return: 0 on success, non-0 on error. +typedef void * (*sq_thread_func_t)(void *); +int sq_start_thread(sq_thread_func_t f, void *p); + + +// Return builtin mime type for the given file name. +// For unrecognized extensions, "text/plain" is returned. +const char *sq_get_builtin_mime_type(const char *file_name); + + +// Return Squeasel version. +const char *sq_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 sq_url_decode(const char *src, int src_len, char *dst, + int dst_len, int is_form_url_encoded); + +// 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]; +// sq_md5(buf, "aa", "bb", NULL); +char *sq_md5(char buf[33], ...); + + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // MONGOOSE_HEADER_INCLUDED http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/0b7ae6e4/be/src/util/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/be/src/util/CMakeLists.txt b/be/src/util/CMakeLists.txt index d286f11..ed1fdfd 100644 --- a/be/src/util/CMakeLists.txt +++ b/be/src/util/CMakeLists.txt @@ -12,6 +12,9 @@ # See the License for the specific language governing permissions and # limitations under the License. +set(SQUEASEL_SRC_DIR "${CMAKE_SOURCE_DIR}/be/src/thirdparty/squeasel") +set(MUSTACHE_SRC_DIR "${CMAKE_SOURCE_DIR}/be/src/thirdparty/mustache") + # Without this option Squeasel looks up the SSL library at run-time # and may not guess the correct name on some distributions SET_SOURCE_FILES_PROPERTIES(${SQUEASEL_SRC_DIR}/squeasel.c PROPERTIES http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/0b7ae6e4/be/src/util/webserver.cc ---------------------------------------------------------------------- diff --git a/be/src/util/webserver.cc b/be/src/util/webserver.cc index b1ff7f6..318a189 100644 --- a/be/src/util/webserver.cc +++ b/be/src/util/webserver.cc @@ -20,18 +20,19 @@ #include <boost/lexical_cast.hpp> #include <boost/mem_fn.hpp> #include <boost/thread/locks.hpp> +#include <fstream> #include <gutil/strings/substitute.h> #include <map> -#include <fstream> #include <stdio.h> #include <signal.h> #include <string> -#include <mustache/mustache.h> #include <rapidjson/stringbuffer.h> #include <rapidjson/prettywriter.h> -#include "util/asan.h" #include "common/logging.h" +#include "rpc/thrift-util.h" +#include "thirdparty/mustache/mustache.h" +#include "util/asan.h" #include "util/cpu-info.h" #include "util/disk-info.h" #include "util/mem-info.h" @@ -42,7 +43,6 @@ #include "util/debug-util.h" #include "util/pretty-printer.h" #include "util/stopwatch.h" -#include "rpc/thrift-util.h" #include "common/names.h" http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/0b7ae6e4/be/src/util/webserver.h ---------------------------------------------------------------------- diff --git a/be/src/util/webserver.h b/be/src/util/webserver.h index 551088c..347fd94 100644 --- a/be/src/util/webserver.h +++ b/be/src/util/webserver.h @@ -16,14 +16,14 @@ #ifndef IMPALA_UTIL_WEBSERVER_H #define IMPALA_UTIL_WEBSERVER_H -#include <squeasel/squeasel.h> -#include <string> -#include <map> #include <boost/function.hpp> #include <boost/thread/shared_mutex.hpp> +#include <map> #include <rapidjson/document.h> +#include <string> #include "common/status.h" +#include "thirdparty/squeasel/squeasel.h" #include "util/network-util.h" namespace impala { http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/0b7ae6e4/cmake_modules/FindMustache.cmake ---------------------------------------------------------------------- diff --git a/cmake_modules/FindMustache.cmake b/cmake_modules/FindMustache.cmake deleted file mode 100644 index 3a9dc6d..0000000 --- a/cmake_modules/FindMustache.cmake +++ /dev/null @@ -1,26 +0,0 @@ -# - Find Mustache (mustache.h and mustache.c) -# This module defines -# MUSTACHE_INCLUDE_DIR, directory containing headers -# MUSTACHE_SRC_DIR, directory containing source -# MUSTACHE_FOUND, whether the Mustache library has been located - -find_path(MUSTACHE_INCLUDE_DIR mustache/mustache.h HINTS $ENV{IMPALA_HOME}/thirdparty) -find_path(MUSTACHE_SRC_DIR mustache.cc HINTS $ENV{IMPALA_HOME}/thirdparty/mustache) - -if (MUSTACHE_INCLUDE_DIR) - set(MUSTACHE_FOUND TRUE) -else () - set(MUSTACHE_FOUND FALSE) -endif () - -if (MUSTACHE_FOUND) - if (NOT MUSTACHE_FIND_QUIETLY) - message(STATUS "Mustache template library found in ${MUSTACHE_INCLUDE_DIR}") - endif () -else () - message(STATUS "Mustache template library includes NOT found. ") -endif () - -mark_as_advanced( - MUSTACHE_INCLUDE_DIR -) http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/0b7ae6e4/cmake_modules/FindSqueasel.cmake ---------------------------------------------------------------------- diff --git a/cmake_modules/FindSqueasel.cmake b/cmake_modules/FindSqueasel.cmake deleted file mode 100644 index ea738e6..0000000 --- a/cmake_modules/FindSqueasel.cmake +++ /dev/null @@ -1,25 +0,0 @@ -# - Find Squeasel (squeasel.h and squeasel.c) -# This module defines -# SQUEASEL_INCLUDE_DIR, directory containing headers -# SQUEASEL_SRC_DIR, directory containing source - -find_path(SQUEASEL_INCLUDE_DIR squeasel/squeasel.h HINTS $ENV{IMPALA_HOME}/thirdparty) -find_path(SQUEASEL_SRC_DIR squeasel.c HINTS $ENV{IMPALA_HOME}/thirdparty/squeasel) - -if (SQUEASEL_INCLUDE_DIR) - set(SQUEASEL_FOUND TRUE) -else () - set(SQUEASEL_FOUND FALSE) -endif () - -if (SQUEASEL_FOUND) - if (NOT SQUEASEL_FIND_QUIETLY) - message(STATUS "Squeasel web server library found in ${SQUEASEL_INCLUDE_DIR}") - endif () -else () - message(FATAL_ERROR "Squeasel web server library includes NOT found. ") -endif () - -mark_as_advanced( - SQUEASEL_INCLUDE_DIR -)
