diff options
39 files changed, 887 insertions, 335 deletions
diff --git a/.clang-format b/.clang-format index 17d370f05a..113030c683 100644 --- a/.clang-format +++ b/.clang-format @@ -47,12 +47,21 @@ DisableFormat: false ExperimentalAutoDetectBinPacking: false ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ] IncludeCategories: + + - Regex: '^[<"](crow)' + Priority: 5 + - Regex: '^[<"](boost)' + Priority: 6 + - Regex: '^[<"](gtest|gmock)' + Priority: 7 - Regex: '^<.*\.h>' Priority: 1 - - Regex: '^<.*' + - Regex: '^<.*\.hpp>' Priority: 2 - - Regex: '.*' + - Regex: '^<.*' Priority: 3 + - Regex: '.*' + Priority: 4 IndentCaseLabels: true IndentWidth: 2 IndentWrappedFunctionNames: false diff --git a/CMakeLists.txt b/CMakeLists.txt index e80c6c1f6d..1be970a3e7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,21 +8,16 @@ message("${CMAKE_MODULE_PATH}") SET(BUILD_SHARED_LIBRARIES OFF) -#set(HUNTER_ROOT /home/ed/hunter) #SET(HUNTER_STATUS_DEBUG ON) - -#SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fsanitize=address -fno-omit-frame-pointer -fno-optimize-sibling-calls") -#-fsanitize-memory-track-origins=2 -fno-omit-frame-pointer -SET(MSAN_CXX_FLAGS "-fsanitize=memory -stdlib=libc++ -I/home/ed/libcxx_msan/include -I/home/ed/libcxx_msan/include/c++/v1") -SET(MSAN_LINKER_EXE_FLAGS "${MSAN_CXX_FLAGS} -lc++abi -L/home/ed/libcxx_msan/lib -Wl,-rpath,I/home/ed/libcxx_msan/lib") +#SET(MSAN_CXX_FLAGS "-fsanitize=memory -stdlib=libc++ -I/home/ed/libcxx_msan/include -I/home/ed/libcxx_msan/include/c++/v1") +#SET(MSAN_LINKER_EXE_FLAGS "${MSAN_CXX_FLAGS} -lc++abi -L/home/ed/libcxx_msan/lib -Wl,-rpath,I/home/ed/libcxx_msan/lib") #SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${MSAN_CXX_FLAGS}") #SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${MSAN_LINKER_EXE_FLAGS}") - -message("CMAKE_EXE_LINKER_FLAGS=${CMAKE_EXE_LINKER_FLAGS}") -message("MSAN_CXX_FLAGS=${MSAN_CXX_FLAGS}") +# Debug information +SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -fno-omit-frame-pointer") include("cmake/HunterGate.cmake") #HunterGate( @@ -39,8 +34,6 @@ option(BUILD_FOR_EMBEDDED "Build for device target" ON) project(bmc-webserver CXX C) - - set(CMAKE_CXX_STANDARD 14) set(CMAKE_CXX_STANDARD_REQUIRED ON) @@ -67,15 +60,13 @@ add_definitions(-DBOOST_ERROR_CODE_HEADER_ONLY) add_definitions(-DBOOST_SYSTEM_NO_DEPRECATED) add_definitions(-DBOOST_ALL_NO_LIB) set(Boost_USE_STATIC_LIBS ON) -hunter_add_package(Boost) -find_package(Boost) +hunter_add_package(Boost COMPONENTS system) +find_package(Boost COMPONENTS system) #Openssl hunter_add_package(OpenSSL) find_package(OpenSSL REQUIRED) - - #g3 logging # G3logger does some unfortunate compile options, so cheat a little bit and copy/paste set(LOG_SRC ${CMAKE_CURRENT_SOURCE_DIR}/g3log/src) @@ -93,6 +84,7 @@ ENDIF (MSVC OR MINGW) include_directories(${LOG_SRC}) add_library(g3logger ${SRC_FILES}) +# clean up some warnings in files we don't own if(("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") OR ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")) set_source_files_properties(g3log/src/logcapture.cpp PROPERTIES COMPILE_FLAGS -Wno-braced-scalar-init) set_source_files_properties(g3log/src/filesink.cpp PROPERTIES COMPILE_FLAGS -Wno-braced-scalar-init) @@ -113,6 +105,7 @@ set(BUILD_STATIC ON) # Crow +add_definitions(-DCROW_DISABLE_LOGGING) add_definitions(-DCROW_ENABLE_SSL) include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/crow/include) @@ -169,7 +162,7 @@ set(UT_FILES g3log/test_unit/testing_helpers.cpp g3log/test_unit/test_io.cpp g3log/test_unit/test_message.cpp - src/crowtest/crow_unittest.cpp + src/crow_test.cpp src/gtest_main.cpp src/base64_test.cpp src/token_authorization_middleware_test.cpp @@ -177,8 +170,10 @@ set(UT_FILES src/webassets_test.cpp src/crow_getroutes_test.cpp src/ast_jpeg_decoder_test.cpp - + src/kvm_websocket_test.cpp + src/test_utils.cpp src/msan_test.cpp + src/ci_map_tests.cpp ${CMAKE_BINARY_DIR}/generated/blns.hpp ) @@ -216,13 +211,14 @@ add_subdirectory(static) add_executable(bmcweb ${WEBSERVER_MAIN} ${HDR_FILES} ${SRC_FILES}) target_link_libraries(bmcweb pthread) target_link_libraries(bmcweb OpenSSL::SSL OpenSSL::Crypto) +target_link_libraries(bmcweb Boost::system) target_link_libraries(bmcweb g3logger) target_link_libraries(bmcweb ${ZLIB_LIBRARIES}) add_dependencies(bmcweb packagestaticcpp) # udpclient -add_executable(udpclient src/udpclient.cpp) -target_link_libraries(udpclient pthread) +#add_executable(udpclient src/udpclient.cpp) +#target_link_libraries(udpclient pthread) add_executable(getvideo src/getvideo_main.cpp) target_link_libraries(getvideo pthread) diff --git a/crow/include/crow/app.h b/crow/include/crow/app.h index e0e5d84868..4bce60a498 100644 --- a/crow/include/crow/app.h +++ b/crow/include/crow/app.h @@ -1,5 +1,12 @@ #pragma once +#include "crow/http_request.h" +#include "crow/http_server.h" +#include "crow/logging.h" +#include "crow/middleware_context.h" +#include "crow/routing.h" +#include "crow/settings.h" +#include "crow/utility.h" #include <chrono> #include <cstdint> #include <functional> @@ -9,14 +16,6 @@ #include <thread> #include <type_traits> -#include "crow/http_request.h" -#include "crow/http_server.h" -#include "crow/logging.h" -#include "crow/middleware_context.h" -#include "crow/routing.h" -#include "crow/settings.h" -#include "crow/utility.h" - #ifdef CROW_MSVC_WORKAROUND #define CROW_ROUTE(app, url) app.route_dynamic(url) #else @@ -116,9 +115,7 @@ class Crow { router_.debug_print(); } - std::vector<std::string> get_routes() { - return router_.get_routes(); - } + std::vector<std::string> get_routes() { return router_.get_routes(); } #ifdef CROW_ENABLE_SSL self_t& ssl_file(const std::string& crt_filename, diff --git a/crow/include/crow/ci_map.h b/crow/include/crow/ci_map.h index b2021d37aa..bf50fd08a4 100644 --- a/crow/include/crow/ci_map.h +++ b/crow/include/crow/ci_map.h @@ -1,29 +1,31 @@ #pragma once +#include <algorithm> +#include <iostream> #include <boost/algorithm/string/predicate.hpp> +#include <boost/container/flat_map.hpp> #include <boost/functional/hash.hpp> -#include <unordered_map> namespace crow { -struct ci_hash { - size_t operator()(const std::string& key) const { - std::size_t seed = 0; - std::locale locale; - for (auto c : key) { - boost::hash_combine(seed, std::toupper(c, locale)); +struct ci_key_eq { + bool operator()(const std::string& left, const std::string& right) const { + unsigned int lsz = left.size(); + unsigned int rsz = right.size(); + for (unsigned int i = 0; i < std::min(lsz, rsz); ++i) { + auto lchar = tolower(left[i]); + auto rchar = tolower(right[i]); + if (lchar != rchar) { + return lchar < rchar; + } } - return seed; - } -}; - -struct ci_key_eq { - bool operator()(const std::string& l, const std::string& r) const { - return boost::iequals(l, r); + if (rsz != lsz) { + return lsz < rsz; + } + return 0; } }; -using ci_map = - std::unordered_multimap<std::string, std::string, ci_hash, ci_key_eq>; +using ci_map = boost::container::flat_map<std::string, std::string, ci_key_eq>; } diff --git a/crow/include/crow/http_connection.h b/crow/include/crow/http_connection.h index ed669c3e1b..4b10c11574 100644 --- a/crow/include/crow/http_connection.h +++ b/crow/include/crow/http_connection.h @@ -7,6 +7,8 @@ #include <chrono> #include <vector> +#include <boost/container/flat_map.hpp> + #include "crow/http_parser_merged.h" #include "crow/dumb_timer_queue.h" @@ -263,7 +265,7 @@ class Connection { "Keep-Alive")) add_keep_alive_ = true; } - if (!req.headers.count("host")) { + if (!req.headers.count("Host")) { is_invalid_request = true; res = response(400); } @@ -334,7 +336,7 @@ class Connection { return; } - static std::unordered_map<int, std::string> statusCodes = { + static boost::container::flat_map<int, std::string> statusCodes = { {200, "HTTP/1.1 200 OK\r\n"}, {201, "HTTP/1.1 201 Created\r\n"}, {202, "HTTP/1.1 202 Accepted\r\n"}, diff --git a/crow/include/crow/http_response.h b/crow/include/crow/http_response.h index 66d2ee39b6..322147bff8 100644 --- a/crow/include/crow/http_response.h +++ b/crow/include/crow/http_response.h @@ -1,6 +1,5 @@ #pragma once #include <string> -#include <unordered_map> #include "crow/ci_map.h" #include "crow/http_request.h" diff --git a/crow/include/crow/json.h b/crow/include/crow/json.h index f368eb148d..4672a8d9ff 100644 --- a/crow/include/crow/json.h +++ b/crow/include/crow/json.h @@ -3,14 +3,14 @@ //#define CROW_JSON_NO_ERROR_CHECK #include <algorithm> -#include <boost/algorithm/string/predicate.hpp> -#include <boost/lexical_cast.hpp> -#include <boost/operators.hpp> #include <iostream> #include <memory> #include <string> -#include <unordered_map> #include <vector> +#include <boost/algorithm/string/predicate.hpp> +#include <boost/container/flat_map.hpp> +#include <boost/lexical_cast.hpp> +#include <boost/operators.hpp> #include "crow/settings.h" @@ -920,7 +920,7 @@ class wvalue { double d{}; std::string s; std::unique_ptr<std::vector<wvalue>> l; - std::unique_ptr<std::unordered_map<std::string, wvalue>> o; + std::unique_ptr<boost::container::flat_map<std::string, wvalue>> o; public: wvalue() {} @@ -944,8 +944,8 @@ class wvalue { for (auto it = r.begin(); it != r.end(); ++it) l->emplace_back(*it); return; case type::Object: - o = std::unique_ptr<std::unordered_map<std::string, wvalue>>( - new std::unordered_map<std::string, wvalue>{}); + o = std::unique_ptr<boost::container::flat_map<std::string, wvalue>>( + new boost::container::flat_map<std::string, wvalue>{}); for (auto it = r.begin(); it != r.end(); ++it) o->emplace(it->key(), *it); return; @@ -1097,8 +1097,8 @@ class wvalue { if (t_ != type::Object) reset(); t_ = type::Object; if (!o) - o = std::unique_ptr<std::unordered_map<std::string, wvalue>>( - new std::unordered_map<std::string, wvalue>{}); + o = std::unique_ptr<boost::container::flat_map<std::string, wvalue>>( + new boost::container::flat_map<std::string, wvalue>{}); return (*o)[str]; } diff --git a/crow/include/crow/middleware.h b/crow/include/crow/middleware.h index 342f128615..64b9f9882c 100644 --- a/crow/include/crow/middleware.h +++ b/crow/include/crow/middleware.h @@ -1,7 +1,9 @@ #pragma once -#include <boost/algorithm/string/trim.hpp> + #include "crow/http_request.h" #include "crow/http_response.h" +#include <boost/algorithm/string/trim.hpp> +#include <boost/container/flat_map.hpp> namespace crow { // Any middleware requires following 3 members: @@ -33,8 +35,8 @@ namespace crow { struct CookieParser { struct context { - std::unordered_map<std::string, std::string> jar; - std::unordered_map<std::string, std::string> cookies_to_add; + boost::container::flat_map<std::string, std::string> jar; + boost::container::flat_map<std::string, std::string> cookies_to_add; std::string get_cookie(const std::string& key) { if (jar.count(key)) return jar[key]; diff --git a/crow/include/crow/parser.h b/crow/include/crow/parser.h index 8fffcfc8e0..8140d62106 100644 --- a/crow/include/crow/parser.h +++ b/crow/include/crow/parser.h @@ -4,7 +4,6 @@ #include <boost/algorithm/string.hpp> #include <boost/tokenizer.hpp> #include <string> -#include <unordered_map> #include "crow/http_parser_merged.h" #include "crow/http_request.h" diff --git a/crow/include/crow/routing.h b/crow/include/crow/routing.h index d07f09f625..f1f3b32ce3 100644 --- a/crow/include/crow/routing.h +++ b/crow/include/crow/routing.h @@ -4,10 +4,11 @@ #include <cstdint> #include <memory> #include <tuple> -#include <unordered_map> #include <utility> #include <vector> +#include "boost/container/flat_map.hpp" + #include "crow/common.h" #include "crow/http_request.h" #include "crow/http_response.h" @@ -502,7 +503,7 @@ class Trie { struct Node { unsigned rule_index{}; std::array<unsigned, (int)ParamType::MAX> param_childrens{}; - std::unordered_map<std::string, unsigned> children; + boost::container::flat_map<std::string, unsigned> children; bool IsSimpleNode() const { return !rule_index && diff --git a/crow/include/crow/socket_adaptors.h b/crow/include/crow/socket_adaptors.h index a0d8dfa14c..34bf8016a8 100644 --- a/crow/include/crow/socket_adaptors.h +++ b/crow/include/crow/socket_adaptors.h @@ -33,7 +33,6 @@ struct SocketAdaptor { tcp::socket socket_; }; - struct TestSocketAdaptor { using context = void; TestSocketAdaptor(boost::asio::io_service& io_service, context*) @@ -74,9 +73,31 @@ struct SSLAdaptor { tcp::endpoint remote_endpoint() { return raw_socket().remote_endpoint(); } - bool is_open() { return raw_socket().is_open(); } + bool is_open() { + /*TODO(ed) this is a bit of a cheat. + There are cases when running a websocket where ssl_socket_ might have + std::move() called on it (to transfer ownership to websocket::Connection) + and be empty. This (and the check on close()) is a cheat to do something + sane in this scenario. the correct fix would likely involve changing the + http parser to return a specific code meaning "has been upgraded" so that + the do_read function knows not to try to close the connection which would + fail, because the adapter is gone. As is, do_read beleives the parse + failed, because is_open now returns False (which could also mean the client + disconnected during parse) + */ + if (ssl_socket_ != nullptr) { + return ssl_socket_->lowest_layer().is_open(); + } else { + return false; + } + } - void close() { raw_socket().close(); } + void close() { + if (ssl_socket_ == nullptr) { + return; + } + ssl_socket_->lowest_layer().close(); + } boost::asio::io_service& get_io_service() { return raw_socket().get_io_service(); diff --git a/crow/include/crow/websocket.h b/crow/include/crow/websocket.h index c148c3799d..f29f13be1e 100644 --- a/crow/include/crow/websocket.h +++ b/crow/include/crow/websocket.h @@ -138,7 +138,7 @@ class Connection : public connection { "HTTP/1.1 101 Switching Protocols\r\n" "Upgrade: websocket\r\n" "Connection: Upgrade\r\n" - "Sec-WebSocket-Protocol: binary\n" // TODO(ed): this hardcodes binary mode + "Sec-WebSocket-Protocol: binary\r\n" // TODO(ed): this hardcodes binary mode // find a better way "Sec-WebSocket-Accept: "; static std::string crlf = "\r\n"; diff --git a/include/aspeed/JTABLES.H b/include/aspeed/JTABLES.H index 93fec8c0b5..bff39e3aee 100644 --- a/include/aspeed/JTABLES.H +++ b/include/aspeed/JTABLES.H @@ -1,11 +1,11 @@ -
-static unsigned char zigzag[64] = {
+#pragma once
+static const unsigned char zigzag[64] = {
0, 1, 5, 6, 14, 15, 27, 28, 2, 4, 7, 13, 16, 26, 29, 42,
3, 8, 12, 17, 25, 30, 41, 43, 9, 11, 18, 24, 31, 40, 44, 53,
10, 19, 23, 32, 39, 45, 52, 54, 20, 22, 33, 38, 46, 51, 55, 60,
21, 34, 37, 47, 50, 56, 59, 61, 35, 36, 48, 49, 57, 58, 62, 63};
-static unsigned char dezigzag[64 + 15] = {
+static const unsigned char dezigzag[64 + 15] = {
0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12, 19, 26, 33, 40,
48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 35, 42, 49, 56, 57, 50, 43, 36,
29, 22, 15, 23, 30, 37, 44, 51, 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61,
@@ -13,24 +13,24 @@ static unsigned char dezigzag[64 + 15] = { // let corrupt input sample past end
63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63};
-static unsigned char *std_luminance_qt;
-static unsigned char *std_chrominance_qt;
+static const unsigned char *std_luminance_qt;
+static const unsigned char *std_chrominance_qt;
// Standard Huffman tables (cf. JPEG standard section K.3) */
-static unsigned char std_dc_luminance_nrcodes[17] = {0, 0, 1, 5, 1, 1, 1, 1, 1,
+static const unsigned char std_dc_luminance_nrcodes[17] = {0, 0, 1, 5, 1, 1, 1, 1, 1,
1, 0, 0, 0, 0, 0, 0, 0};
-static unsigned char std_dc_luminance_values[12] = {0, 1, 2, 3, 4, 5,
+static const unsigned char std_dc_luminance_values[12] = {0, 1, 2, 3, 4, 5,
6, 7, 8, 9, 10, 11};
-static unsigned char std_dc_chrominance_nrcodes[17] = {
+static const unsigned char std_dc_chrominance_nrcodes[17] = {
0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0};
-static unsigned char std_dc_chrominance_values[12] = {0, 1, 2, 3, 4, 5,
+static const unsigned char std_dc_chrominance_values[12] = {0, 1, 2, 3, 4, 5,
6, 7, 8, 9, 10, 11};
-static unsigned char std_ac_luminance_nrcodes[17] = {
+static const unsigned char std_ac_luminance_nrcodes[17] = {
0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d};
-static unsigned char std_ac_luminance_values[162] = {
+static const unsigned char std_ac_luminance_values[162] = {
0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06,
0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72,
@@ -46,9 +46,9 @@ static unsigned char std_ac_luminance_values[162] = { 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4,
0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa};
-static unsigned char std_ac_chrominance_nrcodes[17] = {
+static const unsigned char std_ac_chrominance_nrcodes[17] = {
0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77};
-static unsigned char std_ac_chrominance_values[162] = {
+static const unsigned char std_ac_chrominance_values[162] = {
0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41,
0x51, 0x07, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, 0x15, 0x62, 0x72, 0xd1,
@@ -64,7 +64,7 @@ static unsigned char std_ac_chrominance_values[162] = { 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4,
0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa};
-unsigned short int DC_LUMINANCE_HUFFMANCODE[13 * 2] = {
+static const unsigned short int DC_LUMINANCE_HUFFMANCODE[13 * 2] = {
/* 0 */ 0x0000, 0,
/* 1 */ 0x4000, 2,
/* 2 */ 0x6000, 3,
@@ -80,7 +80,7 @@ unsigned short int DC_LUMINANCE_HUFFMANCODE[13 * 2] = { /* 12 */ 0xFFFF, 9,
};
-unsigned short int DC_CHROMINANCE_HUFFMANCODE[13 * 2] = {
+static const unsigned short int DC_CHROMINANCE_HUFFMANCODE[13 * 2] = {
/* 0 */ 0x0000, 0,
/* 1 */ 0x4000, 2,
/* 2 */ 0x8000, 2,
@@ -96,7 +96,7 @@ unsigned short int DC_CHROMINANCE_HUFFMANCODE[13 * 2] = { /* 12 */ 0xFFFF, 11,
};
-unsigned short int AC_LUMINANCE_HUFFMANCODE[39 * 2] = {
+static const unsigned short int AC_LUMINANCE_HUFFMANCODE[39 * 2] = {
/* 0 */ 0x0000, 0,
/* 1 */ 0x4000, 2,
/* 2 */ 0x8000, 2,
@@ -138,7 +138,7 @@ unsigned short int AC_LUMINANCE_HUFFMANCODE[39 * 2] = { /* 38 */ 0xFFFF, 16,
};
-unsigned short int AC_CHROMINANCE_HUFFMANCODE[45 * 2] = {
+static const unsigned short int AC_CHROMINANCE_HUFFMANCODE[45 * 2] = {
/* 0 */ 0x0000, 0,
/* 1 */ 0x4000, 2,
/* 2 */ 0x8000, 2,
@@ -187,59 +187,59 @@ unsigned short int AC_CHROMINANCE_HUFFMANCODE[45 * 2] = { };
//[100]=========================
-static unsigned char Tbl_100Y[64] = {
+static const unsigned char Tbl_100Y[64] = {
2, 1, 1, 2, 3, 5, 6, 7, 1, 1, 1, 2, 3, 7, 7, 6,
1, 1, 2, 3, 5, 7, 8, 7, 1, 2, 2, 3, 6, 10, 10, 7,
2, 2, 4, 7, 8, 13, 12, 9, 3, 4, 6, 8, 10, 13, 14, 11,
6, 8, 9, 10, 12, 15, 15, 12, 9, 11, 11, 12, 14, 12, 12, 12};
-static unsigned char Tbl_100UV[64] = {
+static const unsigned char Tbl_100UV[64] = {
3, 3, 4, 8, 18, 18, 18, 18, 3, 3, 4, 12, 18, 18, 18, 18,
4, 4, 10, 18, 18, 18, 18, 18, 8, 12, 18, 18, 18, 18, 18, 18,
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18};
//[086]=========================
-static unsigned char Tbl_086Y[64] = {
+static const unsigned char Tbl_086Y[64] = {
3, 2, 1, 3, 4, 7, 9, 11, 2, 2, 2, 3, 4, 10, 11, 10,
2, 2, 3, 4, 7, 10, 12, 10, 2, 3, 4, 5, 9, 16, 15, 11,
3, 4, 6, 10, 12, 20, 19, 14, 4, 6, 10, 12, 15, 19, 21, 17,
9, 12, 14, 16, 19, 22, 22, 18, 13, 17, 17, 18, 21, 18, 19, 18};
-static unsigned char Tbl_086UV[64] = {
+static const unsigned char Tbl_086UV[64] = {
4, 5, 6, 13, 27, 27, 27, 27, 5, 5, 7, 18, 27, 27, 27, 27,
6, 7, 15, 27, 27, 27, 27, 27, 13, 18, 27, 27, 27, 27, 27, 27,
27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27};
//[071]=========================
-static unsigned char Tbl_071Y[64] = {
+static const unsigned char Tbl_071Y[64] = {
6, 4, 3, 6, 9, 15, 19, 22, 4, 4, 5, 7, 9, 21, 22, 20,
5, 4, 6, 9, 15, 21, 25, 21, 5, 6, 8, 10, 19, 32, 30, 23,
6, 8, 13, 21, 25, 40, 38, 28, 9, 13, 20, 24, 30, 39, 42, 34,
18, 24, 29, 32, 38, 45, 45, 37, 27, 34, 35, 36, 42, 37, 38, 37};
-static unsigned char Tbl_071UV[64] = {
+static const unsigned char Tbl_071UV[64] = {
9, 10, 13, 26, 55, 55, 55, 55, 10, 11, 14, 37, 55, 55, 55, 55,
13, 14, 31, 55, 55, 55, 55, 55, 26, 37, 55, 55, 55, 55, 55, 55,
55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55,
55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55};
//[057]=========================
-static unsigned char Tbl_057Y[64] = {
+static const unsigned char Tbl_057Y[64] = {
9, 6, 5, 9, 13, 22, 28, 34, 6, 6, 7, 10, 14, 32, 33, 30,
7, 7, 9, 13, 22, 32, 38, 31, 7, 9, 12, 16, 28, 48, 45, 34,
10, 12, 20, 31, 38, 61, 57, 43, 13, 19, 30, 36, 45, 58, 63, 51,
27, 36, 43, 48, 57, 68, 67, 56, 40, 51, 53, 55, 63, 56, 57, 55};
-static unsigned char Tbl_057UV[64] = {
+static const unsigned char Tbl_057UV[64] = {
13, 14, 19, 38, 80, 80, 80, 80, 14, 17, 21, 53, 80, 80, 80, 80,
19, 21, 45, 80, 80, 80, 80, 80, 38, 53, 80, 80, 80, 80, 80, 80,
80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80};
//[043]=========================
-static unsigned char Tbl_043Y[64] = {
+static const unsigned char Tbl_043Y[64] = {
11, 7, 7, 11, 17, 28, 36, 43, 8, 8, 10, 13, 18, 41, 43, 39,
10, 9, 11, 17, 28, 40, 49, 40, 10, 12, 15, 20, 36, 62, 57, 44,
12, 15, 26, 40, 48, 78, 74, 55, 17, 25, 39, 46, 58, 74, 81, 66,
35, 46, 56, 62, 74, 86, 86, 72, 51, 66, 68, 70, 80, 71, 74, 71};
-static unsigned char Tbl_043UV[64] = {
+static const unsigned char Tbl_043UV[64] = {
18, 19, 26, 51, 108, 108, 108, 108, 19, 22, 28, 72, 108,
108, 108, 108, 26, 28, 61, 108, 108, 108, 108, 108, 51, 72,
108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108,
@@ -247,12 +247,12 @@ static unsigned char Tbl_043UV[64] = { 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108};
//[029]=========================
-static unsigned char Tbl_029Y[64] = {
+static const unsigned char Tbl_029Y[64] = {
14, 9, 9, 14, 21, 36, 46, 55, 10, 10, 12, 17, 23, 52, 54, 49,
12, 11, 14, 21, 36, 51, 62, 50, 12, 15, 19, 26, 46, 78, 72, 56,
16, 19, 33, 50, 61, 98, 93, 69, 21, 31, 49, 58, 73, 94, 102, 83,
44, 58, 70, 78, 93, 109, 108, 91, 65, 83, 86, 88, 101, 90, 93, 89};
-static unsigned char Tbl_029UV[64] = {
+static const unsigned char Tbl_029UV[64] = {
22, 24, 32, 63, 133, 133, 133, 133, 24, 28, 34, 88, 133,
133, 133, 133, 32, 34, 75, 133, 133, 133, 133, 133, 63, 88,
133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133,
@@ -260,24 +260,24 @@ static unsigned char Tbl_029UV[64] = { 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133};
//[014]=========================
-static unsigned char Tbl_014Y[64] = {
+static const unsigned char Tbl_014Y[64] = {
17, 12, 10, 17, 26, 43, 55, 66, 13, 13, 15, 20, 28, 63, 65, 60,
15, 14, 17, 26, 43, 62, 75, 61, 15, 18, 24, 31, 55, 95, 87, 67,
19, 24, 40, 61, 74, 119, 112, 84, 26, 38, 60, 70, 88, 113, 123, 100,
53, 70, 85, 95, 112, 132, 131, 110, 78, 100, 103, 107, 122, 109, 112, 108};
-static unsigned char Tbl_014UV[64] = {
+static const unsigned char Tbl_014UV[64] = {
27, 29, 39, 76, 160, 160, 160, 160, 29, 34, 42, 107, 160,
160, 160, 160, 39, 42, 91, 160, 160, 160, 160, 160, 76, 107,
160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160,
160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160,
160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160};
//[000]=========================
-static unsigned char Tbl_000Y[64] = {
+static const unsigned char Tbl_000Y[64] = {
20, 13, 12, 20, 30, 50, 63, 76, 15, 15, 17, 23, 32, 72, 75, 68,
17, 16, 20, 30, 50, 71, 86, 70, 17, 21, 27, 36, 63, 108, 100, 77,
22, 27, 46, 70, 85, 136, 128, 96, 30, 43, 68, 80, 101, 130, 141, 115,
61, 80, 97, 108, 128, 151, 150, 126, 90, 115, 118, 122, 140, 125, 128, 123};
-static unsigned char Tbl_000UV[64] = {
+static const unsigned char Tbl_000UV[64] = {
31, 33, 45, 88, 185, 185, 185, 185, 33, 39, 48, 123, 185,
185, 185, 185, 45, 48, 105, 185, 185, 185, 185, 185, 88, 123,
185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185,
diff --git a/include/ast_jpeg_decoder.hpp b/include/ast_jpeg_decoder.hpp index 4036423f3a..6e5a3d4bde 100644 --- a/include/ast_jpeg_decoder.hpp +++ b/include/ast_jpeg_decoder.hpp @@ -73,8 +73,8 @@ class AstJpegDecoder { public: AstJpegDecoder() { // TODO(ed) figure out how to init this in the constructor - YUVBuffer.resize(800 * 600); - OutBuffer.resize(800 * 600); + YUVBuffer.resize(1920 * 1200); + OutBuffer.resize(1920 * 1200); for (auto &r : OutBuffer) { r.R = 0x00; r.G = 0x00; @@ -815,8 +815,9 @@ class AstJpegDecoder { } */ } - void load_Huffman_table(Huffman_table *HT, unsigned char *nrcode, - unsigned char *value, unsigned short int *Huff_code) { + void load_Huffman_table(Huffman_table *HT, const unsigned char *nrcode, + const unsigned char *value, + const unsigned short int *Huff_code) { unsigned char k, j, i; unsigned int code, code_index; @@ -1001,7 +1002,7 @@ class AstJpegDecoder { return 1; } - void set_quant_table(uint8_t *basic_table, uint8_t scale_factor, + void set_quant_table(const uint8_t *basic_table, uint8_t scale_factor, uint8_t *newtable) // Set quantization table and zigzag reorder it { @@ -1307,8 +1308,8 @@ class AstJpegDecoder { std::array<int, 256> m_Y; unsigned long buffer_index; uint32_t codebuf, newbuf, readbuf; - uint8_t *std_luminance_qt; - uint8_t *std_chrominance_qt; + const unsigned char *std_luminance_qt; + const uint8_t *std_chrominance_qt; signed short int DCY, DCCb, DCCr; // Coeficientii DC pentru Y,Cb,Cr signed short int DCT_coeff[384]; diff --git a/include/crow/g3_logger.hpp b/include/crow/g3_logger.hpp index 8980207b05..748328e2ef 100644 --- a/include/crow/g3_logger.hpp +++ b/include/crow/g3_logger.hpp @@ -1,8 +1,10 @@ #pragma once // This file overrides the default crow logging framework to use g3 instead. -// It implements enough of the interfaces of the crow logging framework to work correctly -// but deletes the ILogHandler interface, as usage of that would be counter to the g3 +// It implements enough of the interfaces of the crow logging framework to work +// correctly +// but deletes the ILogHandler interface, as usage of that would be counter to +// the g3 // handler management, and would cause performance issues. #include <cstdio> @@ -45,7 +47,7 @@ class logger { } // - static void setLogLevel(LogLevel level) { } + static void setLogLevel(LogLevel level) {} static LogLevel get_current_log_level() { return get_log_level_ref(); } @@ -61,29 +63,17 @@ class logger { LogLevel level_; }; } +#ifndef CROW_DISABLE_LOGGING +#define CROW_DISABLE_LOGGING false +#endif -#define CROW_LOG_CRITICAL LOG(FATAL) -#define CROW_LOG_ERROR LOG(WARNING) -#define CROW_LOG_WARNING LOG(WARNING) -#define CROW_LOG_INFO LOG(INFO) -#define CROW_LOG_DEBUG LOG(DEBUG) - - - -/* -#define CROW_LOG_CRITICAL \ - if (false) \ - crow::logger("CRITICAL", crow::LogLevel::Critical) -#define CROW_LOG_ERROR \ - if (false) \ - crow::logger("ERROR ", crow::LogLevel::Error) -#define CROW_LOG_WARNING \ - if (false) \ - crow::logger("WARNING ", crow::LogLevel::Warning) -#define CROW_LOG_INFO \ - if (false) \ - crow::logger("INFO ", crow::LogLevel::Info) -#define CROW_LOG_DEBUG \ - if (false) \ - crow::logger("DEBUG ", crow::LogLevel::Debug) -*/
\ No newline at end of file +#define CROW_LOG_CRITICAL \ + if (!CROW_DISABLE_LOGGING) LOG(FATAL) +#define CROW_LOG_ERROR \ + if (!CROW_DISABLE_LOGGING) LOG(WARNING) +#define CROW_LOG_WARNING \ + if (!CROW_DISABLE_LOGGING) LOG(WARNING) +#define CROW_LOG_INFO \ + if (!CROW_DISABLE_LOGGING) LOG(INFO) +#define CROW_LOG_DEBUG \ + if (!CROW_DISABLE_LOGGING) LOG(DEBUG) diff --git a/include/test_utils.hpp b/include/test_utils.hpp new file mode 100644 index 0000000000..eb990d5405 --- /dev/null +++ b/include/test_utils.hpp @@ -0,0 +1,6 @@ +#pragma once + +#include <string> + +bool gzipInflate(const std::string& compressedBytes, + std::string& uncompressedBytes);
\ No newline at end of file diff --git a/include/web_kvm.hpp b/include/web_kvm.hpp index 62be097e50..df0bef5f2e 100644 --- a/include/web_kvm.hpp +++ b/include/web_kvm.hpp @@ -51,6 +51,14 @@ enum class client_to_server_msg_type : uint8_t { client_cut_text = 6 }; +enum class server_to_client_message_type : uint8_t +{ + framebuffer_update = 0, + set_color_map_entries = 1, + bell_message = 2, + server_cut_text = 3 +}; + struct set_pixel_format_msg { boost::endian::big_uint8_t pad1; boost::endian::big_uint8_t pad2; @@ -135,7 +143,7 @@ std::string serialize(const framebuffer_update_msg& msg) { std::string serialized(vector_size, 0); size_t i = 0; - serialized[i++] = 0; // Type + serialized[i++] = static_cast<char>(server_to_client_message_type::framebuffer_update); // Type serialized[i++] = 0; // Pad byte boost::endian::big_uint16_t number_of_rectangles = msg.rectangles.size(); std::memcpy(&serialized[i], &number_of_rectangles, @@ -271,47 +279,47 @@ void request_routes(Crow<Middlewares...>& app) { auto msg = reinterpret_cast<const frame_buffer_update_req*>( data.data() + sizeof(client_to_server_msg_type)); - // Todo(ed) lifecycle of the video puller and decoder - // should be - // with the websocket, not recreated every time - AstVideo::VideoPuller p; - p.initialize(); - auto out = p.read_video(); - AstVideo::AstJpegDecoder d; - d.decode(out.buffer, out.width, out.height, out.mode, - out.y_selector, out.uv_selector); - - framebuffer_update_msg buffer_update_msg; - - // If the viewer is requesting a full update, force write - // of all pixels - - framebuffer_rectangle this_rect; - this_rect.x = msg->x_position; - this_rect.y = msg->y_position; - this_rect.width = out.width; - this_rect.height = out.height; - this_rect.encoding = - static_cast<uint8_t>(encoding_type::raw); - LOG(DEBUG) << "Encoding is " << this_rect.encoding; - this_rect.data.reserve(this_rect.width * - this_rect.height * 4); - LOG(DEBUG) << "Width " << out.width << " Height " - << out.height; - - for (int i = 0; i < out.width * out.height; i++) { - auto& pixel = d.OutBuffer[i]; - this_rect.data.push_back(pixel.B); - this_rect.data.push_back(pixel.G); - this_rect.data.push_back(pixel.R); - this_rect.data.push_back(0); - } - - buffer_update_msg.rectangles.push_back( - std::move(this_rect)); - auto serialized = serialize(buffer_update_msg); - - conn.send_binary(serialized); + // Todo(ed) lifecycle of the video puller and decoder + // should be + // with the websocket, not recreated every time + AstVideo::VideoPuller p; + p.initialize(); + auto out = p.read_video(); + AstVideo::AstJpegDecoder d; + d.decode(out.buffer, out.width, out.height, out.mode, + out.y_selector, out.uv_selector); + + framebuffer_update_msg buffer_update_msg; + + // If the viewer is requesting a full update, force write + // of all pixels + + framebuffer_rectangle this_rect; + this_rect.x = msg->x_position; + this_rect.y = msg->y_position; + this_rect.width = out.width; + this_rect.height = out.height; + this_rect.encoding = + static_cast<uint8_t>(encoding_type::raw); + LOG(DEBUG) << "Encoding is " << this_rect.encoding; + this_rect.data.reserve(this_rect.width * this_rect.height * + 4); + LOG(DEBUG) << "Width " << out.width << " Height " + << out.height; + + for (int i = 0; i < out.width * out.height; i++) { + auto& pixel = d.OutBuffer[i]; + this_rect.data.push_back(pixel.B); + this_rect.data.push_back(pixel.G); + this_rect.data.push_back(pixel.R); + this_rect.data.push_back(0); + } + + buffer_update_msg.rectangles.push_back( + std::move(this_rect)); + auto serialized = serialize(buffer_update_msg); + + conn.send_binary(serialized); } // TODO(Ed) handle error diff --git a/scripts/build_web_assets.py b/scripts/build_web_assets.py index 857880e4ee..264448e609 100755 --- a/scripts/build_web_assets.py +++ b/scripts/build_web_assets.py @@ -87,12 +87,33 @@ def filter_html(sha1_list, file_content): return string_content.encode() -def filter_js(sha1_list, file_content): +def embed_angular_templates(sha1_list, dependency_ordered_file_list, content_dict, file_content): + string_content = file_content.decode() + index = string_content.find("<script") + if index == -1: + raise Exception("Couldn't find first script tag in html?") + preload_string = "" + for full_filepath in dependency_ordered_file_list: + relative_path, _ = get_relative_path(full_filepath) + if re.search("partial-.*\\.html", relative_path): + sha1_path = get_sha1_path_from_relative(relative_path, sha1_list[relative_path]) + + print("full_filepath" + full_filepath) + preload_string += ( + "<script type=\"text/ng-template\" id=\"" + sha1_path + "\">\n" + + open(full_filepath, 'r').read() + + "</script>\n" + ) + for key in content_dict: + print(key) + string_content = string_content[:index] + preload_string + string_content[index:] + return string_content.encode() + +def filter_js(sha1_list, file_content): string_content = file_content.decode() for key, value in sha1_list.items(): replace_name = get_sha1_path_from_relative(key, value) - string_content_new = re.sub(key, replace_name, string_content) if string_content_new != string_content: print(" Replaced {}".format(key)) @@ -163,7 +184,7 @@ def main(): elif ext == ".js" or ext == ".css": match = re.search( - "([\"'](\.\./)*)(" + relative_replacename + ")([\"'\?])", file_content) + "(\.\./)*" + relative_replacename, file_content) if match: depends_on[full_filepath].append(full_replacename) @@ -191,6 +212,8 @@ def main(): if extension == ".html" or relative_path == "/": new_file_content = filter_html(sha1_list, file_content) + if relative_path.endswith("index.html"): + new_file_content = embed_angular_templates(sha1_list, dependency_ordered_file_list, content_dict, new_file_content) elif extension == ".js" or extension == ".css": new_file_content = filter_js(sha1_list, file_content) else: diff --git a/src/JTABLES.cpp b/src/JTABLES.cpp new file mode 100644 index 0000000000..0033c2be68 --- /dev/null +++ b/src/JTABLES.cpp @@ -0,0 +1,286 @@ +#include <aspeed/JTABLES.H> + +static unsigned char zigzag[64] = { + 0, 1, 5, 6, 14, 15, 27, 28, 2, 4, 7, 13, 16, 26, 29, 42, + 3, 8, 12, 17, 25, 30, 41, 43, 9, 11, 18, 24, 31, 40, 44, 53, + 10, 19, 23, 32, 39, 45, 52, 54, 20, 22, 33, 38, 46, 51, 55, 60, + 21, 34, 37, 47, 50, 56, 59, 61, 35, 36, 48, 49, 57, 58, 62, 63}; + +static unsigned char dezigzag[64 + 15] = { + 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12, 19, 26, 33, 40, + 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 35, 42, 49, 56, 57, 50, 43, 36, + 29, 22, 15, 23, 30, 37, 44, 51, 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, + 54, 47, 55, 62, 63, + // let corrupt input sample past end + 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63}; + +static unsigned char *std_luminance_qt; +static unsigned char *std_chrominance_qt; + +// Standard Huffman tables (cf. JPEG standard section K.3) */ + +static unsigned char std_dc_luminance_nrcodes[17] = {0, 0, 1, 5, 1, 1, 1, 1, 1, + 1, 0, 0, 0, 0, 0, 0, 0}; +static unsigned char std_dc_luminance_values[12] = {0, 1, 2, 3, 4, 5, + 6, 7, 8, 9, 10, 11}; + +static unsigned char std_dc_chrominance_nrcodes[17] = { + 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0}; +static unsigned char std_dc_chrominance_values[12] = {0, 1, 2, 3, 4, 5, + 6, 7, 8, 9, 10, 11}; + +static unsigned char std_ac_luminance_nrcodes[17] = { + 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d}; +static unsigned char std_ac_luminance_values[162] = { + 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, + 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, + 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72, + 0x82, 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, + 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, + 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, + 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, + 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, + 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, + 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, + 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, + 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, + 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa}; + +static unsigned char std_ac_chrominance_nrcodes[17] = { + 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77}; +static unsigned char std_ac_chrominance_values[162] = { + 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, + 0x51, 0x07, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, + 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, 0x15, 0x62, 0x72, 0xd1, + 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, + 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, + 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, + 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, + 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, + 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, + 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, + 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4, + 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa}; + +unsigned short int DC_LUMINANCE_HUFFMANCODE[13 * 2] = { + /* 0 */ 0x0000, 0, + /* 1 */ 0x4000, 2, + /* 2 */ 0x6000, 3, + /* 3 */ 0x8000, 3, + /* 4 */ 0xA000, 3, + /* 5 */ 0xC000, 3, + /* 6 */ 0xE000, 3, + /* 7 */ 0xF000, 4, + /* 8 */ 0xF800, 5, + /* 9 */ 0xFC00, 6, + /* 10 */ 0xFE00, 7, + /* 11 */ 0xFF00, 8, + /* 12 */ 0xFFFF, 9, +}; + +unsigned short int DC_CHROMINANCE_HUFFMANCODE[13 * 2] = { + /* 0 */ 0x0000, 0, + /* 1 */ 0x4000, 2, + /* 2 */ 0x8000, 2, + /* 3 */ 0xC000, 2, + /* 4 */ 0xE000, 3, + /* 5 */ 0xF000, 4, + /* 6 */ 0xF800, 5, + /* 7 */ 0xFC00, 6, + /* 8 */ 0xFE00, 7, + /* 9 */ 0xFF00, 8, + /* 10 */ 0xFF80, 9, + /* 11 */ 0xFFC0, 10, + /* 12 */ 0xFFFF, 11, +}; + +unsigned short int AC_LUMINANCE_HUFFMANCODE[39 * 2] = { + /* 0 */ 0x0000, 0, + /* 1 */ 0x4000, 2, + /* 2 */ 0x8000, 2, + /* 3 */ 0xA000, 3, + /* 4 */ 0xB000, 4, + /* 5 */ 0xC000, 4, + /* 6 */ 0xD000, 4, + /* 7 */ 0xD800, 5, + /* 8 */ 0xE000, 5, + /* 9 */ 0xE800, 5, + /* 10 */ 0xEC00, 6, + /* 11 */ 0xF000, 6, + /* 12 */ 0xF200, 7, + /* 13 */ 0xF400, 7, + /* 14 */ 0xF600, 7, + /* 15 */ 0xF800, 7, + /* 16 */ 0xF900, 8, + /* 17 */ 0xFA00, 8, + /* 18 */ 0xFB00, 8, + /* 19 */ 0xFB80, 9, + /* 20 */ 0xFC00, 9, + /* 21 */ 0xFC80, 9, + /* 22 */ 0xFD00, 9, + /* 23 */ 0xFD80, 9, + /* 24 */ 0xFDC0, 10, + /* 25 */ 0xFE00, 10, + /* 26 */ 0xFE40, 10, + /* 27 */ 0xFE80, 10, + /* 28 */ 0xFEC0, 10, + /* 29 */ 0xFEE0, 11, + /* 30 */ 0xFF00, 11, + /* 31 */ 0xFF20, 11, + /* 32 */ 0xFF40, 11, + /* 33 */ 0xFF50, 12, + /* 34 */ 0xFF60, 12, + /* 35 */ 0xFF70, 12, + /* 36 */ 0xFF80, 12, + /* 37 */ 0xFF82, 15, + /* 38 */ 0xFFFF, 16, +}; + +unsigned short int AC_CHROMINANCE_HUFFMANCODE[45 * 2] = { + /* 0 */ 0x0000, 0, + /* 1 */ 0x4000, 2, + /* 2 */ 0x8000, 2, + /* 3 */ 0xA000, 3, + /* 4 */ 0xB000, 4, + /* 5 */ 0xC000, 4, + /* 6 */ 0xC800, 5, + /* 7 */ 0xD000, 5, + /* 8 */ 0xD800, 5, + /* 9 */ 0xE000, 5, + /* 10 */ 0xE400, 6, + /* 11 */ 0xE800, 6, + /* 12 */ 0xEC00, 6, + /* 13 */ 0xF000, 6, + /* 14 */ 0xF200, 7, + /* 15 */ 0xF400, 7, + /* 16 */ 0xF600, 7, + /* 17 */ 0xF700, 8, + /* 18 */ 0xF800, 8, + /* 19 */ 0xF900, 8, + /* 20 */ 0xFA00, 8, + /* 21 */ 0xFA80, 9, + /* 22 */ 0xFB00, 9, + /* 23 */ 0xFB80, 9, + /* 24 */ 0xFC00, 9, + /* 25 */ 0xFC80, 9, + /* 26 */ 0xFD00, 9, + /* 27 */ 0xFD80, 9, + /* 28 */ 0xFDC0, 10, + /* 29 */ 0xFE00, 10, + /* 30 */ 0xFE40, 10, + /* 31 */ 0xFE80, 10, + /* 32 */ 0xFEC0, 10, + /* 33 */ 0xFEE0, 11, + /* 34 */ 0xFF00, 11, + /* 35 */ 0xFF20, 11, + /* 36 */ 0xFF40, 11, + /* 37 */ 0xFF50, 12, + /* 38 */ 0xFF60, 12, + /* 39 */ 0xFF70, 12, + /* 40 */ 0xFF80, 12, + /* 41 */ 0xFF84, 14, + /* 42 */ 0xFF86, 15, + /* 43 */ 0xFF88, 15, + /* 44 */ 0xFFFF, 16, +}; + +//[100]========================= +static unsigned char Tbl_100Y[64] = { + 2, 1, 1, 2, 3, 5, 6, 7, 1, 1, 1, 2, 3, 7, 7, 6, + 1, 1, 2, 3, 5, 7, 8, 7, 1, 2, 2, 3, 6, 10, 10, 7, + 2, 2, 4, 7, 8, 13, 12, 9, 3, 4, 6, 8, 10, 13, 14, 11, + 6, 8, 9, 10, 12, 15, 15, 12, 9, 11, 11, 12, 14, 12, 12, 12}; +static unsigned char Tbl_100UV[64] = { + 3, 3, 4, 8, 18, 18, 18, 18, 3, 3, 4, 12, 18, 18, 18, 18, + 4, 4, 10, 18, 18, 18, 18, 18, 8, 12, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18}; + +//[086]========================= +static unsigned char Tbl_086Y[64] = { + 3, 2, 1, 3, 4, 7, 9, 11, 2, 2, 2, 3, 4, 10, 11, 10, + 2, 2, 3, 4, 7, 10, 12, 10, 2, 3, 4, 5, 9, 16, 15, 11, + 3, 4, 6, 10, 12, 20, 19, 14, 4, 6, 10, 12, 15, 19, 21, 17, + 9, 12, 14, 16, 19, 22, 22, 18, 13, 17, 17, 18, 21, 18, 19, 18}; +static unsigned char Tbl_086UV[64] = { + 4, 5, 6, 13, 27, 27, 27, 27, 5, 5, 7, 18, 27, 27, 27, 27, + 6, 7, 15, 27, 27, 27, 27, 27, 13, 18, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27}; + +//[071]========================= +static unsigned char Tbl_071Y[64] = { + 6, 4, 3, 6, 9, 15, 19, 22, 4, 4, 5, 7, 9, 21, 22, 20, + 5, 4, 6, 9, 15, 21, 25, 21, 5, 6, 8, 10, 19, 32, 30, 23, + 6, 8, 13, 21, 25, 40, 38, 28, 9, 13, 20, 24, 30, 39, 42, 34, + 18, 24, 29, 32, 38, 45, 45, 37, 27, 34, 35, 36, 42, 37, 38, 37}; +static unsigned char Tbl_071UV[64] = { + 9, 10, 13, 26, 55, 55, 55, 55, 10, 11, 14, 37, 55, 55, 55, 55, + 13, 14, 31, 55, 55, 55, 55, 55, 26, 37, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55}; +//[057]========================= +static unsigned char Tbl_057Y[64] = { + 9, 6, 5, 9, 13, 22, 28, 34, 6, 6, 7, 10, 14, 32, 33, 30, + 7, 7, 9, 13, 22, 32, 38, 31, 7, 9, 12, 16, 28, 48, 45, 34, + 10, 12, 20, 31, 38, 61, 57, 43, 13, 19, 30, 36, 45, 58, 63, 51, + 27, 36, 43, 48, 57, 68, 67, 56, 40, 51, 53, 55, 63, 56, 57, 55}; +static unsigned char Tbl_057UV[64] = { + 13, 14, 19, 38, 80, 80, 80, 80, 14, 17, 21, 53, 80, 80, 80, 80, + 19, 21, 45, 80, 80, 80, 80, 80, 38, 53, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80}; + +//[043]========================= +static unsigned char Tbl_043Y[64] = { + 11, 7, 7, 11, 17, 28, 36, 43, 8, 8, 10, 13, 18, 41, 43, 39, + 10, 9, 11, 17, 28, 40, 49, 40, 10, 12, 15, 20, 36, 62, 57, 44, + 12, 15, 26, 40, 48, 78, 74, 55, 17, 25, 39, 46, 58, 74, 81, 66, + 35, 46, 56, 62, 74, 86, 86, 72, 51, 66, 68, 70, 80, 71, 74, 71}; +static unsigned char Tbl_043UV[64] = { + 18, 19, 26, 51, 108, 108, 108, 108, 19, 22, 28, 72, 108, + 108, 108, 108, 26, 28, 61, 108, 108, 108, 108, 108, 51, 72, + 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, + 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, + 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108}; + +//[029]========================= +static unsigned char Tbl_029Y[64] = { + 14, 9, 9, 14, 21, 36, 46, 55, 10, 10, 12, 17, 23, 52, 54, 49, + 12, 11, 14, 21, 36, 51, 62, 50, 12, 15, 19, 26, 46, 78, 72, 56, + 16, 19, 33, 50, 61, 98, 93, 69, 21, 31, 49, 58, 73, 94, 102, 83, + 44, 58, 70, 78, 93, 109, 108, 91, 65, 83, 86, 88, 101, 90, 93, 89}; +static unsigned char Tbl_029UV[64] = { + 22, 24, 32, 63, 133, 133, 133, 133, 24, 28, 34, 88, 133, + 133, 133, 133, 32, 34, 75, 133, 133, 133, 133, 133, 63, 88, + 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, + 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, + 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133}; + +//[014]========================= +static unsigned char Tbl_014Y[64] = { + 17, 12, 10, 17, 26, 43, 55, 66, 13, 13, 15, 20, 28, 63, 65, 60, + 15, 14, 17, 26, 43, 62, 75, 61, 15, 18, 24, 31, 55, 95, 87, 67, + 19, 24, 40, 61, 74, 119, 112, 84, 26, 38, 60, 70, 88, 113, 123, 100, + 53, 70, 85, 95, 112, 132, 131, 110, 78, 100, 103, 107, 122, 109, 112, 108}; +static unsigned char Tbl_014UV[64] = { + 27, 29, 39, 76, 160, 160, 160, 160, 29, 34, 42, 107, 160, + 160, 160, 160, 39, 42, 91, 160, 160, 160, 160, 160, 76, 107, + 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160}; +//[000]========================= +static unsigned char Tbl_000Y[64] = { + 20, 13, 12, 20, 30, 50, 63, 76, 15, 15, 17, 23, 32, 72, 75, 68, + 17, 16, 20, 30, 50, 71, 86, 70, 17, 21, 27, 36, 63, 108, 100, 77, + 22, 27, 46, 70, 85, 136, 128, 96, 30, 43, 68, 80, 101, 130, 141, 115, + 61, 80, 97, 108, 128, 151, 150, 126, 90, 115, 118, 122, 140, 125, 128, 123}; +static unsigned char Tbl_000UV[64] = { + 31, 33, 45, 88, 185, 185, 185, 185, 33, 39, 48, 123, 185, + 185, 185, 185, 45, 48, 105, 185, 185, 185, 185, 185, 88, 123, + 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, + 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, + 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185};
\ No newline at end of file diff --git a/src/ast_jpeg_decoder_test.cpp b/src/ast_jpeg_decoder_test.cpp index 5b9e7693ef..22c9ecfcdc 100644 --- a/src/ast_jpeg_decoder_test.cpp +++ b/src/ast_jpeg_decoder_test.cpp @@ -1,6 +1,6 @@ #include "ast_jpeg_decoder.hpp" -#include "gmock/gmock.h" -#include "gtest/gtest.h" +#include <gmock/gmock.h> +#include <gtest/gtest.h> #ifdef BUILD_CIMG #define cimg_display 0 @@ -85,7 +85,7 @@ TEST(AstJpegDecoder, AllBlack) { } } } -/* + TEST(AstJpegDecoder, TestColors) { AstVideo::RawVideoBuffer out; @@ -110,7 +110,7 @@ TEST(AstJpegDecoder, TestColors) { out.uv_selector); int tolerance = 16; - + /* for (int i = 0; i < out.width * out.height; i++) { AstVideo::RGB &pixel = d.OutBuffer[i]; EXPECT_GT(pixel.R, 0x8E - tolerance); @@ -120,8 +120,9 @@ TEST(AstJpegDecoder, TestColors) { EXPECT_GT(pixel.B, 0xF1 - tolerance); EXPECT_LT(pixel.B, 0xF1 + tolerance); } + */ } -*/ + // Tests the buffers around the screen aren't written to TEST(AstJpegDecoder, BufferLimits) { AstVideo::RawVideoBuffer out; diff --git a/src/ci_map_tests.cpp b/src/ci_map_tests.cpp new file mode 100644 index 0000000000..acaaa6e80c --- /dev/null +++ b/src/ci_map_tests.cpp @@ -0,0 +1,78 @@ +#include "crow/ci_map.h" +#include <gmock/gmock.h> +#include <gtest/gtest.h> + +using namespace testing; + +TEST(CiMap, MapEmpty) { + crow::ci_map map; + EXPECT_TRUE(map.empty()); + EXPECT_EQ(map.size(), 0); + + map.emplace("foo", "bar"); + + map.clear(); + EXPECT_TRUE(map.empty()); +} + +TEST(CiMap, MapBasicInsert) { + crow::ci_map map; + map.emplace("foo", "bar"); + auto x = map.find("foo"); + ASSERT_NE(x, map.end()); + + EXPECT_EQ(map.find("foo")->first, "foo"); + EXPECT_EQ(map.find("foo")->second, "bar"); + EXPECT_EQ(map.find("FOO")->first, "foo"); + EXPECT_EQ(map.find("FOO")->second, "bar"); +} + +TEST(CiMap, MapManyInsert) { + crow::ci_map map; + map.emplace("foo", "car"); + map.emplace("foo", "boo"); + map.emplace("bar", "cat"); + map.emplace("baz", "bat"); + + EXPECT_EQ(map.size(), 3); + ASSERT_NE(map.find("foo"), map.end()); + EXPECT_EQ(map.find("foo")->first, "foo"); + EXPECT_EQ(map.find("foo")->second, "car"); + + ASSERT_NE(map.find("FOO"), map.end()); + EXPECT_EQ(map.find("FOO")->first, "foo"); + EXPECT_EQ(map.find("FOO")->second, "car"); + + ASSERT_NE(map.find("bar"), map.end()); + EXPECT_EQ(map.find("bar")->first, "bar"); + EXPECT_EQ(map.find("bar")->second, "cat"); + + ASSERT_NE(map.find("BAR"), map.end()); + EXPECT_EQ(map.find("BAR")->first, "bar"); + EXPECT_EQ(map.find("BAR")->second, "cat"); + + ASSERT_NE(map.find("baz"), map.end()); + EXPECT_EQ(map.find("baz")->first, "baz"); + EXPECT_EQ(map.find("baz")->second, "bat"); + + ASSERT_NE(map.find("BAZ"), map.end()); + EXPECT_EQ(map.find("BAZ")->first, "baz"); + EXPECT_EQ(map.find("BAZ")->second, "bat"); + + EXPECT_EQ(map.count("foo"), 1); + EXPECT_EQ(map.count("bar"), 1); + EXPECT_EQ(map.count("baz"), 1); + EXPECT_EQ(map.count("FOO"), 1); + EXPECT_EQ(map.count("BAR"), 1); + EXPECT_EQ(map.count("BAZ"), 1); +} + +TEST(CiMap, MapMultiInsert) { + crow::ci_map map; + map.emplace("foo", "bar1"); + map.emplace("foo", "bar2"); + EXPECT_EQ(map.count("foo"), 1); + EXPECT_EQ(map.count("FOO"), 1); + EXPECT_EQ(map.count("fOo"), 1); + EXPECT_EQ(map.count("FOo"), 1); +}
\ No newline at end of file diff --git a/src/crowtest/crow_unittest.cpp b/src/crow_test.cpp index e84c1a5e13..e84c1a5e13 100644 --- a/src/crowtest/crow_unittest.cpp +++ b/src/crow_test.cpp diff --git a/src/crowtest/about.txt b/src/crowtest/about.txt deleted file mode 100644 index bd55fd1b5c..0000000000 --- a/src/crowtest/about.txt +++ /dev/null @@ -1 +0,0 @@ -This folder contains a port of the CROW unit tests, ported to google test to maek them easier to run
\ No newline at end of file diff --git a/src/getvideo_main.cpp b/src/getvideo_main.cpp index cd7f09c4c2..8c92bd3c85 100644 --- a/src/getvideo_main.cpp +++ b/src/getvideo_main.cpp @@ -1,4 +1,3 @@ - #include <fcntl.h> #include <unistd.h> #include <chrono> diff --git a/src/kvm_websocket_test.cpp b/src/kvm_websocket_test.cpp new file mode 100644 index 0000000000..d690305a60 --- /dev/null +++ b/src/kvm_websocket_test.cpp @@ -0,0 +1,102 @@ +#include <iostream> +#include <sstream> +#include <vector> +#include "test_utils.hpp" +#include "web_kvm.hpp" +#include "crow.h" +#include <gmock/gmock.h> +#include <gtest/gtest.h> + +using namespace crow; +using namespace testing; + +// Tests static files are loaded correctly +TEST(Kvm, BasicRfb) { + SimpleApp app; + + crow::kvm::request_routes(app); + app.bindaddr("127.0.0.1").port(45451); + CROW_ROUTE(app, "/")([]() { return 200; }); + auto _ = async(std::launch::async, [&] { app.run(); }); + auto routes = app.get_routes(); + asio::io_service is; + + { + // Retry a couple of times waiting for the server to come up + // TODO(ed) This is really unfortunate, and should use some form of mock + asio::ip::tcp::socket c(is); + for (int i = 0; i < 200; i++) { + try { + c.connect(asio::ip::tcp::endpoint( + asio::ip::address::from_string("127.0.0.1"), 45451)); + c.close(); + break; + } catch (std::exception e) { + // do nothing. We expect this to fail while the server is starting up + } + } + } + + // Get the websocket + std::string sendmsg = + ("GET /kvmws HTTP/1.1\r\n" + "Host: localhost:45451\r\n" + "Connection: Upgrade\r\n" + "Upgrade: websocket\r\n" + "Sec-WebSocket-Version: 13\r\n" + "Sec-WebSocket-Key: aLeGkmLPZmdv5tTyEpJ3jQ==\r\n" + "Sec-WebSocket-Extensions: permessage-deflate; " + "client_max_window_bits\r\n" + "Sec-WebSocket-Protocol: binary\r\n" + "\r\n"); + + asio::ip::tcp::socket socket(is); + socket.connect(asio::ip::tcp::endpoint( + asio::ip::address::from_string("127.0.0.1"), 45451)); + socket.send(asio::buffer(sendmsg)); + + // Read the response status line. The response streambuf will automatically + // grow to accommodate the entire line. The growth may be limited by passing + // a maximum size to the streambuf constructor. + boost::asio::streambuf response; + boost::asio::read_until(socket, response, "\r\n"); + + // Check that response is OK. + std::istream response_stream(&response); + std::string http_response; + std::getline(response_stream, http_response); + + EXPECT_EQ(http_response, "HTTP/1.1 101 Switching Protocols\r"); + + // Read the response headers, which are terminated by a blank line. + boost::asio::read_until(socket, response, "\r\n\r\n"); + + // Process the response headers. + std::string header; + std::vector<std::string> headers; + while (std::getline(response_stream, header) && header != "\r") { + headers.push_back(header); + } + + EXPECT_THAT(headers, Contains("Upgrade: websocket\r")); + EXPECT_THAT(headers, Contains("Connection: Upgrade\r")); + EXPECT_THAT(headers, Contains("Sec-WebSocket-Protocol: binary\r")); + // TODO(ed) This is the result that it gives today. Need to check websocket + // docs and make + // sure that this calclution is actually being done to spec + EXPECT_THAT(headers, + Contains("Sec-WebSocket-Accept: /CnDM3l79rIxniLNyxMryXbtLEU=\r")); + std::array<char, 13> rfb_open_string; + + // + // socket.receive(rfb_open_string.data(), rfb_open_string.size()); + boost::asio::read(socket, boost::asio::buffer(rfb_open_string)); + auto open_string = + std::string(std::begin(rfb_open_string), std::end(rfb_open_string)); + // Todo(ed) find out what the two characters at the end of the websocket + // stream are + open_string = open_string.substr(2); + EXPECT_EQ(open_string, "RFB 003.008"); + + app.stop(); +}
\ No newline at end of file diff --git a/src/msan_test.cpp b/src/msan_test.cpp index 047d3cfa4a..9fcb9d530c 100644 --- a/src/msan_test.cpp +++ b/src/msan_test.cpp @@ -1,5 +1,5 @@ -#include "gtest/gtest.h" #include <string> +#include "gtest/gtest.h" TEST(MemorySanitizer, TestIsWorking) { std::string foo("foo"); diff --git a/src/security_headers_middleware.cpp b/src/security_headers_middleware.cpp index bcaa87dddb..265cda72a7 100644 --- a/src/security_headers_middleware.cpp +++ b/src/security_headers_middleware.cpp @@ -2,19 +2,38 @@ namespace crow { +static const std::string strict_transport_security_key = + "Strict-Transport-Security"; +static const std::string strict_transport_security_value = + "max-age=31536000; includeSubdomains; preload"; + +static const std::string ua_compatability_key = "X-UA-Compatible"; +static const std::string ua_compatability_value = "IE=11"; + +static const std::string xframe_key = "X-Frame-Options"; +static const std::string xframe_value = "DENY"; + +static const std::string xss_key = "X-XSS-Protection"; +static const std::string xss_value = "1; mode=block"; + +static const std::string content_security_key = "X-Content-Security-Policy"; +static const std::string content_security_value = "default-src 'self'"; + void SecurityHeadersMiddleware::before_handle(crow::request& req, response& res, context& ctx) {} void SecurityHeadersMiddleware::after_handle(request& /*req*/, response& res, context& ctx) { - // TODO(ed) these should really check content types. for example, X-UA-Compatible - // header doesn't make sense when retrieving a JSON or javascript file. It doesn't - // hurt anything, it's just ugly. - res.set_header("Strict-Transport-Security", - "max-age=31536000; includeSubdomains; preload"); - res.set_header("X-UA-Compatible", "IE=11"); - res.set_header("X-Frame-Options", "DENY"); - res.set_header("X-XSS-Protection", "1; mode=block"); - res.set_header("X-Content-Security-Policy", "default-src 'self'"); + /* + TODO(ed) these should really check content types. for example, + X-UA-Compatible header doesn't make sense when retrieving a JSON or + javascript file. It doesn't hurt anything, it's just ugly. + */ + res.add_header(strict_transport_security_key, + strict_transport_security_value); + res.add_header(ua_compatability_key, ua_compatability_value); + res.add_header(xframe_key, xframe_value); + res.add_header(xss_key, xss_value); + res.add_header(content_security_key, content_security_value); } } diff --git a/src/security_headers_middleware_test.cpp b/src/security_headers_middleware_test.cpp index fc183e9523..5045215541 100644 --- a/src/security_headers_middleware_test.cpp +++ b/src/security_headers_middleware_test.cpp @@ -1,7 +1,7 @@ +#include <security_headers_middleware.hpp> #include <crow/app.h> +#include <gtest/gtest.h> #include <gmock/gmock.h> -#include <security_headers_middleware.hpp> -#include "gtest/gtest.h" using namespace crow; using namespace std; diff --git a/src/test_utils.cpp b/src/test_utils.cpp new file mode 100644 index 0000000000..65ef7214b0 --- /dev/null +++ b/src/test_utils.cpp @@ -0,0 +1,67 @@ +#include <zlib.h> +#include <test_utils.hpp> +#include <cstring> + +bool gzipInflate(const std::string& compressedBytes, + std::string& uncompressedBytes) { + if (compressedBytes.size() == 0) { + uncompressedBytes = compressedBytes; + return true; + } + + uncompressedBytes.clear(); + + unsigned full_length = compressedBytes.size(); + unsigned half_length = compressedBytes.size() / 2; + + unsigned uncompLength = full_length; + char* uncomp = (char*)calloc(sizeof(char), uncompLength); + + z_stream strm; + strm.next_in = (Bytef*)compressedBytes.c_str(); + strm.avail_in = compressedBytes.size(); + strm.total_out = 0; + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + + bool done = false; + + if (inflateInit2(&strm, (16 + MAX_WBITS)) != Z_OK) { + free(uncomp); + return false; + } + + while (!done) { + // If our output buffer is too small + if (strm.total_out >= uncompLength) { + // Increase size of output buffer + char* uncomp2 = (char*)calloc(sizeof(char), uncompLength + half_length); + std::memcpy(uncomp2, uncomp, uncompLength); + uncompLength += half_length; + free(uncomp); + uncomp = uncomp2; + } + + strm.next_out = (Bytef*)(uncomp + strm.total_out); + strm.avail_out = uncompLength - strm.total_out; + + // Inflate another chunk. + int err = inflate(&strm, Z_SYNC_FLUSH); + if (err == Z_STREAM_END) + done = true; + else if (err != Z_OK) { + break; + } + } + + if (inflateEnd(&strm) != Z_OK) { + free(uncomp); + return false; + } + + for (size_t i = 0; i < strm.total_out; ++i) { + uncompressedBytes += uncomp[i]; + } + free(uncomp); + return true; +}
\ No newline at end of file diff --git a/src/token_authorization_middleware.cpp b/src/token_authorization_middleware.cpp index 4c7a2d4270..8b109e0234 100644 --- a/src/token_authorization_middleware.cpp +++ b/src/token_authorization_middleware.cpp @@ -1,10 +1,10 @@ -#include <boost/algorithm/string/predicate.hpp> #include <random> #include <unordered_map> +#include <boost/algorithm/string/predicate.hpp> -#include <crow/logging.h> #include <base64.hpp> #include <token_authorization_middleware.hpp> +#include <crow/logging.h> namespace crow { @@ -29,7 +29,7 @@ void TokenAuthorizationMiddleware::before_handle(crow::request& req, res.end(); }; - LOG(DEBUG) << "Token Auth Got route " << req.url; + CROW_LOG_DEBUG << "Token Auth Got route " << req.url; if (req.url == "/" || boost::starts_with(req.url, "/static/")) { // TODO this is total hackery to allow the login page to work before the diff --git a/src/token_authorization_middleware_test.cpp b/src/token_authorization_middleware_test.cpp index c01e7f9ade..e82776533e 100644 --- a/src/token_authorization_middleware_test.cpp +++ b/src/token_authorization_middleware_test.cpp @@ -1,7 +1,7 @@ +#include "token_authorization_middleware.hpp" #include <crow/app.h> #include "gmock/gmock.h" #include "gtest/gtest.h" -#include "token_authorization_middleware.hpp" using namespace crow; using namespace std; diff --git a/src/udpclient.cpp b/src/udpclient.cpp index cf9f3d142f..9bebd6e48e 100644 --- a/src/udpclient.cpp +++ b/src/udpclient.cpp @@ -8,9 +8,8 @@ // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #include <array> -#include <boost/array.hpp> -#include <boost/asio.hpp> #include <iostream> +#include <boost/asio.hpp> using boost::asio::ip::udp; @@ -44,7 +43,7 @@ int main(int argc, char* argv[]) { 0x0E + 0x80; // E is defined in spec as this channel // 0x80 is requesting IPMI 2.0 uint8_t byte1 = static_cast<uint8_t>(channel_number | 0x80); - boost::array<uint8_t, 2> payload{byte1, privilege_level}; + std::array<uint8_t, 2> payload{byte1, privilege_level}; int payload_sum = 0; for (auto element : payload) { diff --git a/src/webassets_test.cpp b/src/webassets_test.cpp index 8d0cfefd83..1d02171e84 100644 --- a/src/webassets_test.cpp +++ b/src/webassets_test.cpp @@ -1,85 +1,20 @@ #include <crow/app.h> #include <gmock/gmock.h> -#include <zlib.h> + +#include <test_utils.hpp> +#include <webassets.hpp> +#include <sstream> #include <boost/algorithm/string/predicate.hpp> #include <boost/iostreams/copy.hpp> #include <boost/iostreams/filter/gzip.hpp> #include <boost/iostreams/filtering_streambuf.hpp> #include <boost/lexical_cast.hpp> -#include <sstream> -#include <webassets.hpp> #include "gtest/gtest.h" + using namespace crow; using namespace std; using namespace testing; -bool gzipInflate(const std::string& compressedBytes, - std::string& uncompressedBytes) { - if (compressedBytes.size() == 0) { - uncompressedBytes = compressedBytes; - return true; - } - - uncompressedBytes.clear(); - - unsigned full_length = compressedBytes.size(); - unsigned half_length = compressedBytes.size() / 2; - - unsigned uncompLength = full_length; - char* uncomp = (char*)calloc(sizeof(char), uncompLength); - - z_stream strm; - strm.next_in = (Bytef*)compressedBytes.c_str(); - strm.avail_in = compressedBytes.size(); - strm.total_out = 0; - strm.zalloc = Z_NULL; - strm.zfree = Z_NULL; - - bool done = false; - - if (inflateInit2(&strm, (16 + MAX_WBITS)) != Z_OK) { - free(uncomp); - return false; - } - - while (!done) { - // If our output buffer is too small - if (strm.total_out >= uncompLength) { - // Increase size of output buffer - char* uncomp2 = (char*)calloc(sizeof(char), uncompLength + half_length); - memcpy(uncomp2, uncomp, uncompLength); - uncompLength += half_length; - free(uncomp); - uncomp = uncomp2; - } - - strm.next_out = (Bytef*)(uncomp + strm.total_out); - strm.avail_out = uncompLength - strm.total_out; - - // Inflate another chunk. - int err = inflate(&strm, Z_SYNC_FLUSH); - if (err == Z_STREAM_END) - done = true; - else if (err != Z_OK) { - break; - } - } - - if (inflateEnd(&strm) != Z_OK) { - free(uncomp); - return false; - } - - for (size_t i = 0; i < strm.total_out; ++i) { - uncompressedBytes += uncomp[i]; - } - free(uncomp); - return true; -} - - - - // Tests static files are loaded correctly TEST(Webassets, StaticFilesFixedRoutes) { std::array<char, 2048> buf; @@ -151,8 +86,6 @@ TEST(Webassets, StaticFilesFixedRoutes) { server.stop(); } - - // Tests static files are loaded correctly TEST(Webassets, EtagIsSane) { std::array<char, 2048> buf; diff --git a/src/webserver_main.cpp b/src/webserver_main.cpp index d77d822041..2ec7e370ff 100644 --- a/src/webserver_main.cpp +++ b/src/webserver_main.cpp @@ -21,10 +21,12 @@ #include "crow/websocket.h" #include "color_cout_g3_sink.hpp" -#include "webassets.hpp" - #include "security_headers_middleware.hpp" +#include "ssl_key_handler.hpp" #include "token_authorization_middleware.hpp" +#include "web_kvm.hpp" +#include "webassets.hpp" +#include "webassets.hpp" #include <boost/asio.hpp> #include <boost/endian/arithmetic.hpp> @@ -34,10 +36,6 @@ #include <string> #include <unordered_set> -#include <web_kvm.hpp> -#include <webassets.hpp> -#include "ssl_key_handler.hpp" - int main(int argc, char** argv) { auto worker(g3::LogWorker::createLogWorker()); std::string logger_name("bmcweb"); @@ -117,6 +115,8 @@ int main(int argc, char** argv) { }); auto ssl_context = ensuressl::get_ssl_context(ssl_pem_file); - app.port(18080).ssl(std::move(ssl_context)).run(); + app.port(18080) + //.ssl(std::move(ssl_context)) + //.concurrency(4) + .run(); } - diff --git a/static/css/font-awesome.css b/static/css/font-awesome.css index a67a32340b..d7de40795c 100644 --- a/static/css/font-awesome.css +++ b/static/css/font-awesome.css @@ -6,7 +6,7 @@ * -------------------------- */ @font-face { font-family: 'FontAwesome'; - /* WARNING: This line is modified from stock FA, to make cachign work*/ + /* WARNING: This line is modified from stock FA, to make caching work*/ src: url('../../static/fonts/fontawesome-webfont.woff') format('woff'); font-weight: normal; font-style: normal; diff --git a/static/css/intel.css b/static/css/intel.css index 5080c77847..5ce5e38946 100644 --- a/static/css/intel.css +++ b/static/css/intel.css @@ -561,3 +561,10 @@ li.L1,li.L3,li.L5,li.L7,li.L9 { } .table-striped-invert > tbody > tr:nth-child(2n+1) > td, .table-striped > tbody > tr:nth-child(2n+1) > th { background-color: #ffffff; } + + +.div-fake-hidden { + width:0px; + height:0px; + overflow:hidden; +}
\ No newline at end of file diff --git a/static/index.html b/static/index.html index f0f4148c5d..687aa6418b 100644 --- a/static/index.html +++ b/static/index.html @@ -3,74 +3,75 @@ <head> <meta charset="utf-8" /> - <meta http-equiv="X-UA-Compatible" content="IE=edge"> - <meta name="viewport" content="width=device-width, initial-scale=1"> + <meta http-equiv="X-UA-Compatible" content="IE=edge" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> <title>Integrated BMC Console</title> - <link href="static/css/bootstrap.css" rel="stylesheet"> - <link href="static/css/font-awesome.css" rel="stylesheet" > - <link href="static/css/intel.css" rel="stylesheet"> + <link href="static/css/bootstrap.css" rel="stylesheet" /> + <link href="static/css/font-awesome.css" rel="stylesheet" /> + <link href="static/css/intel.css" rel="stylesheet" /> <link rel="icon" href="static/favicon.ico" type="image/x-icon" /> - <script type="text/javascript" src="static/js/angular.js"></script> - <script type="text/javascript" src="static/js/angular-animate.js"></script> - <script type="text/javascript" src="static/js/angular-sanitize.js"></script> - <script type="text/javascript" src="static/js/angular-cookies.js"></script> - <script type="text/javascript" src="static/js/angular-resource.js"></script> - <script type="text/javascript" src="static/js/angular-ui-router.js"></script> - <script type="text/javascript" src="static/js/angular-websocket.js"></script> - <script type="text/javascript" src="static/js/lodash.core.js"></script> - - <script type="text/javascript" src="static/js/ui-bootstrap-tpls-2.1.3.js"></script> - - <script type="text/javascript" src="static/js/bmcApp.js"></script> - <script type="text/javascript" src="static/js/base64.js"></script> - <script type="text/javascript" src="static/js/versionController.js"></script> - <script type="text/javascript" src="static/js/selController.js"></script> - <script type="text/javascript" src="static/js/loginController.js"></script> - <script type="text/javascript" src="static/js/kvmController.js"></script> - <script type="text/javascript" src="static/js/ipmiController.js"></script> - - <script type="text/javascript" src="static/noVNC/core/util.js"></script> - <script type="text/javascript" src="static/noVNC/app/webutil.js"></script> - - <script type="text/javascript" src="static/noVNC/core/base64.js"></script> - <script type="text/javascript" src="static/noVNC/core/websock.js"></script> - <script type="text/javascript" src="static/noVNC/core/des.js"></script> - <script type="text/javascript" src="static/noVNC/core/input/keysymdef.js"></script> - <script type="text/javascript" src="static/noVNC/core/input/xtscancodes.js"></script> - <script type="text/javascript" src="static/noVNC/core/input/util.js"></script> - <script type="text/javascript" src="static/noVNC/core/input/devices.js"></script> - <script type="text/javascript" src="static/noVNC/core/display.js"></script> - <script type="text/javascript" src="static/noVNC/core/inflator.js"></script> - <script type="text/javascript" src="static/noVNC/core/rfb.js"></script> - <script type="text/javascript" src="static/noVNC/core/input/keysym.js"></script> + <script type="text/javascript" src="static/js/angular.js" defer></script> + <script type="text/javascript" src="static/js/angular-animate.js" defer></script> + <script type="text/javascript" src="static/js/angular-sanitize.js" defer></script> + <script type="text/javascript" src="static/js/angular-cookies.js" defer></script> + <script type="text/javascript" src="static/js/angular-resource.js" defer></script> + <script type="text/javascript" src="static/js/angular-ui-router.js" defer></script> + <script type="text/javascript" src="static/js/angular-websocket.js" defer></script> + <script type="text/javascript" src="static/js/lodash.core.js" defer></script> + + <script type="text/javascript" src="static/js/ui-bootstrap-tpls-2.1.3.js" defer></script> + + <script type="text/javascript" src="static/js/bmcApp.js" defer></script> + <script type="text/javascript" src="static/js/base64.js" defer></script> + <script type="text/javascript" src="static/js/versionController.js" defer></script> + <script type="text/javascript" src="static/js/selController.js" defer></script> + <script type="text/javascript" src="static/js/loginController.js" defer></script> + <script type="text/javascript" src="static/js/kvmController.js" defer></script> + <script type="text/javascript" src="static/js/ipmiController.js" defer></script> + + <script type="text/javascript" src="static/noVNC/core/util.js" defer></script> + <script type="text/javascript" src="static/noVNC/app/webutil.js" defer></script> + + <script type="text/javascript" src="static/noVNC/core/base64.js" defer></script> + <script type="text/javascript" src="static/noVNC/core/websock.js" defer></script> + <script type="text/javascript" src="static/noVNC/core/des.js" defer></script> + <script type="text/javascript" src="static/noVNC/core/input/keysymdef.js" defer></script> + <script type="text/javascript" src="static/noVNC/core/input/xtscancodes.js" defer></script> + <script type="text/javascript" src="static/noVNC/core/input/util.js" defer></script> + <script type="text/javascript" src="static/noVNC/core/input/devices.js" defer></script> + <script type="text/javascript" src="static/noVNC/core/display.js" defer></script> + <script type="text/javascript" src="static/noVNC/core/inflator.js" defer></script> + <script type="text/javascript" src="static/noVNC/core/rfb.js" defer></script> + <script type="text/javascript" src="static/noVNC/core/input/keysym.js" defer></script> </head> <body> + <div class="div-fake-hidden"><i class="fa fa-square-o fa-3x"></i></div> <div ng-controller="MainCtrl"> - <nav class="navbar navbar-inverse"> + <div class="container-fluid"> <!-- Brand and toggle get grouped for better mobile display --> <div class="navbar-header navbar-left"> + <a class="navbar-brand" href="#"><img style="max-width:100%; max-height:100%;" src="static/img/logo.png" /></a> <button type="button" class="navbar-toggle" ng-init="navCollapsed = true" ng-click="navCollapsed = !navCollapsed" /> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> - </button> - <a class="navbar-brand" href="#"><img style="max-width:100%; max-height:100%; height:50; width:73" src="static/img/logo.png" /></a> </div> <!-- Collect the nav links, forms, and other content for toggling --> <div class="collapse navbar-collapse" uib-collapse="navCollapsed"> <ul class="nav navbar-nav navbar-left"> + <li class="dropdown" uib-dropdown dropdown-append-to-body> <a href="#" class="dropdown-toggle" uib-dropdown-toggle role="button" aria-haspopup="true" aria-expanded="false">System <span class="caret"></span></a> <ul class="dropdown-menu" uib-dropdown-menu role="menu" aria-labelledby="systemlink"> @@ -104,7 +105,7 @@ <li><a href="#">Firmware Update</a></li> </ul> </li> - <li class="dropdown"uib-dropdown dropdown-append-to-body> + <li class="dropdown" uib-dropdown dropdown-append-to-body> <a href="#" class="dropdown-toggle" uib-dropdown-toggle role="button" aria-haspopup="true" aria-expanded="false">Remote Control <span class="caret"></span></a> <ul class="dropdown-menu" uib-dropdown-menu role="menu"> <li><a ui-sref="kvm">KVM Redirection</a></li> diff --git a/static/js/bmcApp.js b/static/js/bmcApp.js index 7d31cc2071..2678ac0a56 100644 --- a/static/js/bmcApp.js +++ b/static/js/bmcApp.js @@ -10,6 +10,8 @@ var app = angular.module('bmcApp', [ 'ngResource' ]); + + app.controller('MainCtrl', ['$scope', function($scope) { }]); @@ -72,9 +74,14 @@ app.directive('windowSize', ['$window', function ($window) { app.run(['$rootScope', '$cookieStore', '$state', '$resource', 'AuthenticationService', '$http', '$templateCache', function($rootScope, $cookieStore, $state, $resource, AuthenticationService, $http, $templateCache) { + + $http.get('static/partial-login.html', {cache:$templateCache}); + $http.get('static/partial-kvm.html', {cache: $templateCache}); + if ($rootScope.globals == undefined){ $rootScope.globals = {}; } + // keep user logged in after page refresh AuthenticationService.RestoreCredientials(); @@ -90,8 +97,7 @@ app.run(['$rootScope', '$cookieStore', '$state', '$resource', 'AuthenticationSer $state.go('login'); } }); - - $http.get('static/partial-kvm.html', { cache: $templateCache }); + } ]); diff --git a/static/partial-login.html b/static/partial-login.html index 247ad1e828..bee698ec71 100644 --- a/static/partial-login.html +++ b/static/partial-login.html @@ -14,6 +14,5 @@ </div> <div class="form-actions"> <button type="submit" ng-disabled="form.$invalid || dataLoading" class="btn btn-danger">Login</button> - <img ng-if="dataLoading" src="data:image/gif;base64,R0lGODlhEAAQAPIAAP///wAAAMLCwkJCQgAAAGJiYoKCgpKSkiH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCgAAACwAAAAAEAAQAAADMwi63P4wyklrE2MIOggZnAdOmGYJRbExwroUmcG2LmDEwnHQLVsYOd2mBzkYDAdKa+dIAAAh+QQJCgAAACwAAAAAEAAQAAADNAi63P5OjCEgG4QMu7DmikRxQlFUYDEZIGBMRVsaqHwctXXf7WEYB4Ag1xjihkMZsiUkKhIAIfkECQoAAAAsAAAAABAAEAAAAzYIujIjK8pByJDMlFYvBoVjHA70GU7xSUJhmKtwHPAKzLO9HMaoKwJZ7Rf8AYPDDzKpZBqfvwQAIfkECQoAAAAsAAAAABAAEAAAAzMIumIlK8oyhpHsnFZfhYumCYUhDAQxRIdhHBGqRoKw0R8DYlJd8z0fMDgsGo/IpHI5TAAAIfkECQoAAAAsAAAAABAAEAAAAzIIunInK0rnZBTwGPNMgQwmdsNgXGJUlIWEuR5oWUIpz8pAEAMe6TwfwyYsGo/IpFKSAAAh+QQJCgAAACwAAAAAEAAQAAADMwi6IMKQORfjdOe82p4wGccc4CEuQradylesojEMBgsUc2G7sDX3lQGBMLAJibufbSlKAAAh+QQJCgAAACwAAAAAEAAQAAADMgi63P7wCRHZnFVdmgHu2nFwlWCI3WGc3TSWhUFGxTAUkGCbtgENBMJAEJsxgMLWzpEAACH5BAkKAAAALAAAAAAQABAAAAMyCLrc/jDKSatlQtScKdceCAjDII7HcQ4EMTCpyrCuUBjCYRgHVtqlAiB1YhiCnlsRkAAAOwAAAAAAAAAAAA=="/> </div> </form>
\ No newline at end of file |