diff options
-rw-r--r-- | CMakeLists.txt | 7 | ||||
-rw-r--r-- | docs/profile.md | 6 | ||||
-rw-r--r-- | include/token_authorization_middleware.hpp | 8 | ||||
-rw-r--r-- | include/web_kvm.hpp | 83 | ||||
-rw-r--r-- | include/webassets.hpp | 1 | ||||
-rwxr-xr-x | scripts/build_web_assets.py | 162 | ||||
-rw-r--r-- | src/getvideo_main.cpp | 100 | ||||
-rw-r--r-- | src/webserver_main.cpp | 27 | ||||
-rw-r--r-- | static/index.html | 63 | ||||
-rw-r--r-- | static/js/bmcApp.js | 7 | ||||
-rw-r--r-- | static/js/kvmController.js | 3 |
11 files changed, 320 insertions, 147 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 31f672baab..9035ee71da 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -115,6 +115,13 @@ set(GENERATED_SRC_FILES set_source_files_properties(${GENERATED_SRC_FILES} PROPERTIES GENERATED TRUE) +if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") + if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0) + set_source_files_properties(${CMAKE_BINARY_DIR}/generated/webassets.cpp PROPERTIES COMPILE_FLAGS -Wno-narrowing) + endif(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0) +endif() + + set(SRC_FILES src/token_authorization_middleware.cpp src/base64.cpp diff --git a/docs/profile.md b/docs/profile.md index fffc400b17..3a2156e453 100644 --- a/docs/profile.md +++ b/docs/profile.md @@ -1,4 +1,8 @@ LD_LIBRARY_PATH=/tmp LD_PRELOAD=libprofiler.so CPUPROFILE=/tmp/profile ./bmcweb scp ed@hades.jf.intel.com:/home/ed/webserver/buildarm/bmcweb /tmp -scp ed@hades.jf.intel.com:/home/ed/gperftools/.libs/libprofiler.so /tmp
\ No newline at end of file +scp ed@hades.jf.intel.com:/home/ed/webserver/buildarm/getvideo /tmp -i /nv/.ssh/id_rsa +scp ed@hades.jf.intel.com:/home/ed/gperftools/.libs/libprofiler.so /tmp + +echo 1 >> /sys/module/video_drv/parameters/debug +echo 8 > /proc/sys/kernel/printk
\ No newline at end of file diff --git a/include/token_authorization_middleware.hpp b/include/token_authorization_middleware.hpp index 61c8385fb4..160265610c 100644 --- a/include/token_authorization_middleware.hpp +++ b/include/token_authorization_middleware.hpp @@ -4,7 +4,15 @@ #include <crow/http_response.h> namespace crow { + +struct User { + +}; + struct TokenAuthorizationMiddleware { + // TODO(ed) auth_token shouldn't really be passed to the context + // it opens the possibility of exposure by and endpoint. + // instead we should only pass some kind of "user" struct struct context { std::string auth_token; }; diff --git a/include/web_kvm.hpp b/include/web_kvm.hpp index cecd09f750..24544fc6d7 100644 --- a/include/web_kvm.hpp +++ b/include/web_kvm.hpp @@ -1,5 +1,13 @@ +#include <boost/endian/arithmetic.hpp> +#include <string> + +#include "app_type.hpp" + +#include <video.h> + namespace crow { namespace kvm { + static const std::string rfb_3_3_version_string = "RFB 003.003\n"; static const std::string rfb_3_7_version_string = "RFB 003.007\n"; static const std::string rfb_3_8_version_string = "RFB 003.008\n"; @@ -26,14 +34,14 @@ struct pixel_format_struct { boost::endian::big_uint8_t pad3; }; -struct server_initialization_message { +struct server_initialization_msg { boost::endian::big_uint16_t framebuffer_width; boost::endian::big_uint16_t framebuffer_height; pixel_format_struct pixel_format; boost::endian::big_uint32_t name_length; }; -enum class client_to_server_message_type : uint8_t { +enum class client_to_server_msg_type : uint8_t { set_pixel_format = 0, fix_color_map_entries = 1, set_encodings = 2, @@ -43,14 +51,14 @@ enum class client_to_server_message_type : uint8_t { client_cut_text = 6 }; -struct set_pixel_format_message { +struct set_pixel_format_msg { boost::endian::big_uint8_t pad1; boost::endian::big_uint8_t pad2; boost::endian::big_uint8_t pad3; pixel_format_struct pixel_format; }; -struct frame_buffer_update_request_message { +struct frame_buffer_update_req { boost::endian::big_uint8_t incremental; boost::endian::big_uint16_t x_position; boost::endian::big_uint16_t y_position; @@ -58,20 +66,20 @@ struct frame_buffer_update_request_message { boost::endian::big_uint16_t height; }; -struct key_event_message { +struct key_event_msg { boost::endian::big_uint8_t down_flag; boost::endian::big_uint8_t pad1; boost::endian::big_uint8_t pad2; boost::endian::big_uint32_t key; }; -struct pointer_event_message { +struct pointer_event_msg { boost::endian::big_uint8_t button_mask; boost::endian::big_uint16_t x_position; boost::endian::big_uint16_t y_position; }; -struct client_cut_text_message { +struct client_cut_text_msg { std::vector<uint8_t> data; }; @@ -112,12 +120,12 @@ struct framebuffer_rectangle { std::vector<uint8_t> data; }; -struct framebuffer_update_message { +struct framebuffer_update_msg { boost::endian::big_uint8_t message_type; std::vector<framebuffer_rectangle> rectangles; }; -std::string serialize(const framebuffer_update_message& msg) { +std::string serialize(const framebuffer_update_msg& msg) { // calculate the size of the needed vector for serialization size_t vector_size = 4; for (const auto& rect : msg.rectangles) { @@ -152,13 +160,13 @@ enum class VncState { UNSTARTED, AWAITING_CLIENT_VERSION, AWAITING_CLIENT_AUTH_METHOD, - AWAITING_CLIENT_INIT_MESSAGE, + AWAITING_CLIENT_INIT_msg, MAIN_LOOP }; class connection_metadata { public: - connection_metadata(void) : vnc_state(VncState::AWAITING_CLIENT_VERSION){}; + connection_metadata(void) : vnc_state(VncState::UNSTARTED){}; VncState vnc_state; }; @@ -172,8 +180,13 @@ void request_routes(BmcAppType& app) { CROW_ROUTE(app, "/kvmws") .websocket() .onopen([&](crow::websocket::connection& conn) { - meta.vnc_state = VncState::AWAITING_CLIENT_VERSION; - conn.send_binary(rfb_3_8_version_string); + if (meta.vnc_state == VncState::UNSTARTED) { + meta.vnc_state = VncState::AWAITING_CLIENT_VERSION; + conn.send_binary(rfb_3_8_version_string); + } else { + conn.close(); + } + }) .onclose( [&](crow::websocket::connection& conn, const std::string& reason) { @@ -203,7 +216,7 @@ void request_routes(BmcAppType& app) { case VncState::AWAITING_CLIENT_AUTH_METHOD: { std::string security_result{{0, 0, 0, 0}}; if (data[0] == (uint8_t)RfbAuthScheme::no_authentication) { - meta.vnc_state = VncState::AWAITING_CLIENT_INIT_MESSAGE; + meta.vnc_state = VncState::AWAITING_CLIENT_INIT_msg; } else { // Mark auth as failed security_result[3] = 1; @@ -211,9 +224,9 @@ void request_routes(BmcAppType& app) { } conn.send_binary(security_result); } break; - case VncState::AWAITING_CLIENT_INIT_MESSAGE: { + case VncState::AWAITING_CLIENT_INIT_msg: { // Now send the server initialization - server_initialization_message server_init_msg; + server_initialization_msg server_init_msg; server_init_msg.framebuffer_width = 640; server_init_msg.framebuffer_height = 480; server_init_msg.pixel_format.bits_per_pixel = 32; @@ -237,30 +250,28 @@ void request_routes(BmcAppType& app) { meta.vnc_state = VncState::MAIN_LOOP; } break; case VncState::MAIN_LOOP: { - if (data.size() >= sizeof(client_to_server_message_type)) { - auto type = static_cast<client_to_server_message_type>(data[0]); - LOG(DEBUG) << "Got type " << (uint32_t)type << "\n"; + if (data.size() >= sizeof(client_to_server_msg_type)) { + auto type = static_cast<client_to_server_msg_type>(data[0]); + LOG(DEBUG) << "Received client message type " << (uint32_t)type + << "\n"; switch (type) { - case client_to_server_message_type::set_pixel_format: { + case client_to_server_msg_type::set_pixel_format: { } break; - case client_to_server_message_type::fix_color_map_entries: { + case client_to_server_msg_type::fix_color_map_entries: { } break; - case client_to_server_message_type::set_encodings: { + case client_to_server_msg_type::set_encodings: { } break; - case client_to_server_message_type:: - framebuffer_update_request: { + case client_to_server_msg_type::framebuffer_update_request: { // Make sure the buffer is long enough to handle what we're // about to do - if (data.size() >= - sizeof(frame_buffer_update_request_message) + - sizeof(client_to_server_message_type)) { - auto msg = reinterpret_cast< - const frame_buffer_update_request_message*>( - data.data() + sizeof(client_to_server_message_type)); + if (data.size() >= sizeof(frame_buffer_update_req) + + sizeof(client_to_server_msg_type)) { + auto msg = reinterpret_cast<const frame_buffer_update_req*>( + data.data() + sizeof(client_to_server_msg_type)); if (!msg->incremental) { - framebuffer_update_message buffer_update_message; + framebuffer_update_msg buffer_update_msg; // If the viewer is requesting a full update, force write // of all pixels @@ -291,9 +302,9 @@ void request_routes(BmcAppType& app) { } } - buffer_update_message.rectangles.push_back( + buffer_update_msg.rectangles.push_back( std::move(this_rect)); - auto serialized = serialize(buffer_update_message); + auto serialized = serialize(buffer_update_msg); conn.send_binary(serialized); } @@ -303,13 +314,13 @@ void request_routes(BmcAppType& app) { break; - case client_to_server_message_type::key_event: { + case client_to_server_msg_type::key_event: { } break; - case client_to_server_message_type::pointer_event: { + case client_to_server_msg_type::pointer_event: { } break; - case client_to_server_message_type::client_cut_text: { + case client_to_server_msg_type::client_cut_text: { } break; default: diff --git a/include/webassets.hpp b/include/webassets.hpp index 924b1d50d5..b5431bc033 100644 --- a/include/webassets.hpp +++ b/include/webassets.hpp @@ -9,6 +9,7 @@ #include <crow/routing.h> #include <app_type.hpp> + namespace crow { namespace webassets { void request_routes(BmcAppType& app); diff --git a/scripts/build_web_assets.py b/scripts/build_web_assets.py index 58a9b94879..8268787092 100755 --- a/scripts/build_web_assets.py +++ b/scripts/build_web_assets.py @@ -30,8 +30,14 @@ ROUTE_DECLARATION = """ void crow::webassets::request_routes(BmcAppType& app){ """ -CPP_MIDDLE_CACHING_HANDLER = """ - res.add_header("Cache-Control", "public, max-age=31556926"); +CACHE_FOREVER_HEADER = """ + res.add_header("Cache-Control", "public, max-age=31556926"); +""" + +CPP_MIDDLE_BUFFER = """ + CROW_ROUTE(app, "{relative_path_sha1}")([](const crow::request& req, crow::response& res) {{ + {CACHE_FOREVER_HEADER} + res.add_header("ETag", "{sha1}"); if (req.headers.count("If-None-Match") == 1) {{ if (req.get_header_value("If-None-Match") == "{sha1}"){{ @@ -40,12 +46,7 @@ CPP_MIDDLE_CACHING_HANDLER = """ return; }} }} -""" - -CPP_MIDDLE_BUFFER = """ - CROW_ROUTE(app, "{relative_path_sha1}")([](const crow::request& req, crow::response& res) {{ - {CPP_MIDDLE_CACHING_HANDLER} res.code = 200; // TODO, if you have a browser from the dark ages that doesn't support gzip, // unzip it before sending based on Accept-Encoding header @@ -75,11 +76,12 @@ CPP_END_BUFFER2 = """const static std::string {relative_path_escaped}{{{file_byt def get_relative_path(full_filepath): pathsplit = full_filepath.split(os.path.sep) relative_path = os.path.sep.join(pathsplit[pathsplit.index("static") + 1:]) + relative_path_escaped = relative_path for character in ['/', '.', '-']: relative_path_escaped = relative_path_escaped.replace(character, "_") - relative_path = "/static/" + relative_path + relative_path = "static/" + relative_path return relative_path, relative_path_escaped @@ -93,12 +95,60 @@ def get_sha1_path_from_relative(relative_path, sha1): def filter_html(sha1_list, file_content): string_content = file_content.decode() for key, value in sha1_list.items(): - key = key.lstrip("/") replace_name = get_sha1_path_from_relative(key, value) - key = re.escape(key) - string_content = re.sub("((src|href)=[\"'])(" + key + ")([\"'])", "\\1" + replace_name + "\\4", string_content) + string_content_new = re.sub("((src|href)=[\"'])(" + re.escape(key) + ")([\"'])", "\\1" + replace_name + "\\4", string_content) + if string_content_new != string_content: + print(" Replaced {}".format(key)) + print(" With {}".format(replace_name)) + string_content = string_content_new + + 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)) + print(" With {}".format(replace_name)) + string_content = string_content_new return string_content.encode() +def compute_sha1_and_update_dict(sha1_list, file_content, relative_path): + sha = hashlib.sha1() + sha.update(file_content) + sha_bytes = sha.digest() + + sha_text = "".join("{:02x}".format(x) for x in sha_bytes) + sha1_list[relative_path] = sha_text + +FILE_PRECIDENCE = ['.woff', '.png' ,'.css', '.js', '.html'] +def sort_order(full_filepath): + # sort list based on users + path, ext = os.path.splitext(full_filepath) + if ext in FILE_PRECIDENCE: + return FILE_PRECIDENCE.index(ext) + 1 + else: + return 0 + + +def get_dependencies(dependency_list, full_filepath): + r = [] + my_dependencies = dependency_list[full_filepath] + r.extend(my_dependencies) + sub_deps = [] + for dependency in my_dependencies: + sub_deps += get_dependencies(dependency_list, dependency) + r.extend(sub_deps) + return r + +def remove_duplicates_preserve_order(seq): + seen = set() + seen_add = seen.add + return [x for x in seq if not (x in seen or seen_add(x))] def main(): """ Main Function """ @@ -114,25 +164,44 @@ def main(): file_list = [os.path.realpath(f) for f in file_list] sha1_list = {} - if not args.debug: - # TODO(ed) most html and woff cacheable - excluded_types = [".html", ".woff"] - # sha1 hash everthing - for full_filepath in file_list: - if os.path.splitext(full_filepath)[1] not in excluded_types: - with open(full_filepath, 'rb') as input_file: - file_content = input_file.read() - sha = hashlib.sha1() - sha.update(file_content) - - sha_text = "".join("{:02x}".format(x) for x in sha.digest()) - relative_path, relative_path_escaped = get_relative_path(full_filepath) - sha1_list[relative_path] = sha_text + + file_list.sort(key=sort_order) + from collections import defaultdict + depends_on = {} + + for full_filepath in file_list: + relative_path, relative_path_escaped = get_relative_path(full_filepath) + text_file_types = ['.css', '.js', '.html'] + ext = os.path.splitext(relative_path)[1] + depends_on[full_filepath] = [] + if ext in text_file_types: + with open(full_filepath, 'r') as input_file: + file_content = input_file.read() + for full_replacename in file_list: + relative_replacename, _ = get_relative_path(full_replacename) + if ext == ".html": + match = re.search("((src|href)=[\"'])(" + relative_replacename + ")([\"'])", file_content) + if match: + depends_on[full_filepath].append(full_replacename) + + elif ext == ".js": + match = re.search("([\"'])(" + relative_replacename + ")([\"'])", file_content) + if match: + depends_on[full_filepath].append(full_replacename) + + dependency_ordered_file_list = [] + for full_filepath in file_list: + relative_path, relative_path_escaped = get_relative_path(full_filepath) + deps = get_dependencies(depends_on, full_filepath) + dependency_ordered_file_list.extend(deps) + dependency_ordered_file_list.append(full_filepath) + + dependency_ordered_file_list = remove_duplicates_preserve_order(dependency_ordered_file_list) with open(args.output, 'w') as cpp_output: cpp_output.write(CPP_BEGIN_BUFFER) - for full_filepath in file_list: + for full_filepath in dependency_ordered_file_list: # make sure none of the files are hidden with open(full_filepath, 'rb') as input_file: file_content = input_file.read() @@ -141,14 +210,20 @@ def main(): print("Including {:<40} size {:>7}".format(relative_path, len(file_content))) if relative_path.endswith(".html") or relative_path == "/": - print("Fixing {}".format(relative_path)) - file_content = filter_html(sha1_list, file_content) + new_file_content = filter_html(sha1_list, file_content) + elif relative_path.endswith(".js"): + new_file_content = filter_js(sha1_list, file_content) + else: + new_file_content = file_content + + file_content = new_file_content if not args.debug: file_content = gzip.compress(file_content) #file_content = file_content[:10] # compute the 2s complement. If you don't, you get narrowing warnings from gcc/clang - + + compute_sha1_and_update_dict(sha1_list, file_content, relative_path) array_binary_text = ', '.join(str(twos_comp(x, 8)) for x in file_content) cpp_output.write( @@ -161,8 +236,7 @@ def main(): cpp_output.write(ROUTE_DECLARATION) - - for full_filepath in file_list: + for full_filepath in dependency_ordered_file_list: relative_path, relative_path_escaped = get_relative_path(full_filepath) sha1 = sha1_list.get(relative_path, '') @@ -171,10 +245,15 @@ def main(): print("unknown content type for {}".format(relative_path)) # handle the default routes - if relative_path == "/static/index.html": + if relative_path == "static/index.html": relative_path = "/" - - relative_path_sha1 = get_sha1_path_from_relative(relative_path, sha1) + relative_path_sha1 = "/" + # TODO(ed), handle woff files better. They are referenced in CSS, which at this + # point isn't scrubbed with a find and replace algorithm + elif relative_path.endswith(".woff"): + relative_path_sha1 = relative_path + else: + relative_path_sha1 = "/" + get_sha1_path_from_relative(relative_path, sha1) content_encoding = 'none' if args.debug else 'gzip' @@ -185,15 +264,14 @@ def main(): 'sha1': sha1, 'sha1_short': sha1[:20], 'content_type': content_type, - 'ENABLE_CACHING': str(ENABLE_CACHING).lower(), - 'content_encoding': '' + 'content_encoding': content_encoding } - if ENABLE_CACHING and sha1 != "": - environment["CPP_MIDDLE_CACHING_HANDLER"] = CPP_MIDDLE_CACHING_HANDLER.format( - **environment - ) - else: - environment["CPP_MIDDLE_CACHING_HANDLER"] = "" + environment["CACHE_FOREVER_HEADER"] = "" + if ENABLE_CACHING: + # if we have a valid sha1, and we have a unique path to the resource + # it can be safely cached forever + if sha1 != "" and relative_path != relative_path_sha1: + environment["CACHE_FOREVER_HEADER"] = CACHE_FOREVER_HEADER content = CPP_MIDDLE_BUFFER.format( **environment diff --git a/src/getvideo_main.cpp b/src/getvideo_main.cpp index f73ee30e78..2259b8c8bc 100644 --- a/src/getvideo_main.cpp +++ b/src/getvideo_main.cpp @@ -1,7 +1,14 @@ #include <video.h> -#include <fstream> -#include <iostream> + #include <iomanip> +#include <iostream> +#include <chrono> +#include <thread> +#include <vector> +#include <fstream> +#include <fcntl.h> +#include <unistd.h> + namespace AstVideo { class VideoPuller { @@ -10,40 +17,91 @@ class VideoPuller { void initialize() { std::cout << "Opening /dev/video\n"; - file.open("/dev/video", std::ios::out | std::ios::in | std::ios::binary); - if (!file.is_open()) { + video_fd = open("/dev/video", O_RDWR); + if (!video_fd) { std::cout << "Failed to open /dev/video\n"; + } else { + std::cout << "Opened successfully\n"; } - IMAGE_INFO image_info{}; - file.write(reinterpret_cast<char*>(&image_info), sizeof(image_info)); + std::vector<unsigned char> buffer(1024 * 1024, 0); - file.read(reinterpret_cast<char*>(&image_info), sizeof(image_info)); + IMAGE_INFO image_info{}; + image_info.do_image_refresh = 1; // full frame refresh + image_info.qc_valid = 0; // quick cursor disabled + image_info.parameter.features.w = 800; + image_info.parameter.features.h = 600; + image_info.parameter.features.chrom_tbl = 0; // level + image_info.parameter.features.lumin_tbl = 0; + image_info.parameter.features.jpg_fmt = 1; + image_info.parameter.features.buf = buffer.data(); + image_info.crypttype = -1; + std::cout << "Writing\n"; - if (file){ - std::cout << "Read succeeded\n"; + int status; + /* + status = write(video_fd, reinterpret_cast<char*>(&image_info), + sizeof(image_info)); + if (status != 0) { + std::cout << "Write failed. Return: " << status <<"\n"; + perror("perror output:"); } + */ + std::cout << "Write done\n"; + //std::this_thread::sleep_for(std::chrono::milliseconds(2000)); + std::cout << "Reading\n"; + status = read(video_fd, reinterpret_cast<char*>(&image_info), sizeof(image_info)); + std::cout << "Reading\n"; + + if (status != 0) { + std::cout << "Read failed with status " << status << "\n"; + } + auto pt = reinterpret_cast<char*>(&image_info); - for(int i=0; i<sizeof(image_info); i++){ - std::cout << std::hex << std::setfill('0') << std::setw(2) << int(*(pt + i)) << " "; + for (int i = 0; i < sizeof(image_info); i++) { + std::cout << std::hex << std::setfill('0') << std::setw(2) + << int(*(pt + i)) << " "; + } + std::cout << "\n"; + /* + for(int i = 0; i < 1024; i++){ + if (i % 16 == 0){ + std::cout << "\n"; + } + std::cout << std::hex << std::setfill('0') << std::setw(2) + << int(buffer[i]) << " "; } + */ + buffer.resize(image_info.len); + std::ofstream f("/tmp/screen.jpg",std::ios::out | std::ios::binary); + + f.write(reinterpret_cast<char*>(buffer.data()), buffer.size()); + std::cout << "\n"; std::cout << "typedef struct _video_features {\n"; - std::cout << "short jpg_fmt: " << image_info.parameter.features.jpg_fmt << "\n"; - std::cout << "short lumin_tbl;" << image_info.parameter.features.lumin_tbl << "\n"; - std::cout << "short chrom_tbl;" << image_info.parameter.features.chrom_tbl << "\n"; - std::cout << "short tolerance_noise;" << image_info.parameter.features.tolerance_noise << "\n"; - std::cout << "int w;" << image_info.parameter.features.w << "\n"; - std::cout << "int h;" << image_info.parameter.features.h << "\n"; - //std::cout << "unsigned char *buf;" << image_info.parameter.features.buf << "\n"; + std::cout << "short jpg_fmt: " << image_info.parameter.features.jpg_fmt + << "\n"; + std::cout << "short lumin_tbl;" << image_info.parameter.features.lumin_tbl + << "\n"; + std::cout << "short chrom_tbl;" << image_info.parameter.features.chrom_tbl + << "\n"; + std::cout << "short tolerance_noise;" + << image_info.parameter.features.tolerance_noise << "\n"; + std::cout << "int w; 0X" << image_info.parameter.features.w << "\n"; + std::cout << "int h; 0X" << image_info.parameter.features.h << "\n"; + + std::cout << "void* buf; 0X" << static_cast<void*>(image_info.parameter.features.buf) << "\n"; + // std::cout << "unsigned char *buf;" << image_info.parameter.features.buf + // << "\n"; std::cout << "} FEATURES_TAG;\n"; std::cout << "typedef struct _image_info {"; - std::cout << "short do_image_refresh;" << image_info.do_image_refresh << "\n"; + std::cout << "short do_image_refresh;" << image_info.do_image_refresh + << "\n"; std::cout << "char qc_valid;" << image_info.qc_valid << "\n"; std::cout << "unsigned int len;" << image_info.len << "\n"; std::cout << "int crypttype;" << image_info.crypttype << "\n"; @@ -54,8 +112,10 @@ class VideoPuller { std::cout << "} parameter;\n"; std::cout << "} IMAGE_INFO;\n"; std::cout << std::endl; + + close(video_fd); } - std::fstream file; + int video_fd; }; } diff --git a/src/webserver_main.cpp b/src/webserver_main.cpp index 58483df89e..80354fbe63 100644 --- a/src/webserver_main.cpp +++ b/src/webserver_main.cpp @@ -1,3 +1,9 @@ +#include <webassets.hpp> +#include <web_kvm.hpp> +#include "ssl_key_handler.hpp" + +#include "app_type.hpp" + #include "crow/app.h" #include "crow/ci_map.h" #include "crow/common.h" @@ -20,25 +26,20 @@ #include "crow/utility.h" #include "crow/websocket.h" -#include "app_type.hpp" #include "color_cout_g3_sink.hpp" #include "token_authorization_middleware.hpp" #include "webassets.hpp" -#include <iostream> -#include <memory> -#include <string> -#include "ssl_key_handler.hpp" +#include <boost/asio.hpp> #include <boost/endian/arithmetic.hpp> -#include <boost/asio.hpp> +#include <iostream> +#include <memory> +#include <string> #include <unordered_set> -#include <webassets.hpp> - -#include <web_kvm.hpp> int main(int argc, char** argv) { auto worker(g3::LogWorker::createLogWorker()); @@ -53,6 +54,7 @@ int main(int argc, char** argv) { ensuressl::ensure_openssl_key_present_and_valid(ssl_pem_file); BmcAppType app; + crow::webassets::request_routes(app); crow::kvm::request_routes(app); @@ -68,16 +70,19 @@ int main(int argc, char** argv) { CROW_ROUTE(app, "/login") .methods("POST"_method)([&](const crow::request& req) { + crow::json::wvalue x; auto auth_token = app.get_context<crow::TokenAuthorizationMiddleware>(req).auth_token; - crow::json::wvalue x; + x["token"] = auth_token; return x; }); CROW_ROUTE(app, "/logout") - .methods("GET"_method, "POST"_method)([]() { + .methods("GET"_method, "POST"_method)([&](const crow::request& req) { + + app.get_context<crow::TokenAuthorizationMiddleware>(req).auth_token = ""; // Do nothing. Credentials have already been cleared by middleware. return 200; }); diff --git a/static/index.html b/static/index.html index 9f08b3778d..391bf939b7 100644 --- a/static/index.html +++ b/static/index.html @@ -13,43 +13,40 @@ <link rel="icon" href="static/favicon.ico" type="image/x-icon" /> - <script src="static/js/angular.js"></script> - <script src="static/js/angular-animate.js"></script> - <script src="static/js/angular-sanitize.js"></script> - <script src="static/js/angular-cookies.js"></script> - <script src="static/js/angular-resource.js"></script> - <script src="static/js/angular-ui-router.js"></script> - <script src="static/js/angular-websocket.js"></script> - <script src="static/js/lodash.core.js"></script> + <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 src="static/js/ui-bootstrap-tpls-2.1.3.js"></script> + <script type="text/javascript" src="static/js/ui-bootstrap-tpls-2.1.3.js"></script> - <script src="static/js/bmcApp.js"></script> - <script src="static/js/base64.js"></script> - <script src="static/js/versionController.js"></script> - <script src="static/js/selController.js"></script> - <script src="static/js/loginController.js"></script> - <script src="static/js/kvmController.js"></script> - <script src="static/js/ipmiController.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 src="static/noVNC/core/util.js"></script> - <script src="static/noVNC/app/webutil.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 src="static/noVNC/core/base64.js"></script> - <script src="static/noVNC/core/websock.js"></script> - <script src="static/noVNC/core/des.js"></script> - <script src="static/noVNC/core/input/keysymdef.js"></script> - <script src="static/noVNC/core/input/xtscancodes.js"></script> - <script src="static/noVNC/core/input/util.js"></script> - <script src="static/noVNC/core/input/devices.js"></script> - <script src="static/noVNC/core/display.js"></script> - <script src="static/noVNC/core/inflator.js"></script> - <script src="static/noVNC/core/rfb.js"></script> - <script src="static/noVNC/core/input/keysym.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"> - var INCLUDE_URI= "static/noVNC/include/"; - </script> </head> <body> @@ -67,7 +64,7 @@ <span class="icon-bar"></span> <span class="icon-bar"></span> </button> - <a class="navbar-brand" href="#"><img style="max-width:100%; max-height:100%" src="static/img/logo.png" /></a> + <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 --> diff --git a/static/js/bmcApp.js b/static/js/bmcApp.js index d4282ba0d6..7d31cc2071 100644 --- a/static/js/bmcApp.js +++ b/static/js/bmcApp.js @@ -10,7 +10,6 @@ var app = angular.module('bmcApp', [ 'ngResource' ]); - app.controller('MainCtrl', ['$scope', function($scope) { }]); @@ -71,8 +70,8 @@ app.directive('windowSize', ['$window', function ($window) { } }]); -app.run(['$rootScope', '$cookieStore', '$state', '$resource', 'AuthenticationService', - function($rootScope, $cookieStore, $state, $resource, AuthenticationService) { +app.run(['$rootScope', '$cookieStore', '$state', '$resource', 'AuthenticationService', '$http', '$templateCache', + function($rootScope, $cookieStore, $state, $resource, AuthenticationService, $http, $templateCache) { if ($rootScope.globals == undefined){ $rootScope.globals = {}; } @@ -91,6 +90,8 @@ app.run(['$rootScope', '$cookieStore', '$state', '$resource', 'AuthenticationSer $state.go('login'); } }); + + $http.get('static/partial-kvm.html', { cache: $templateCache }); } ]); diff --git a/static/js/kvmController.js b/static/js/kvmController.js index d10a223e93..e3dcb1465f 100644 --- a/static/js/kvmController.js +++ b/static/js/kvmController.js @@ -24,7 +24,8 @@ function($scope, $location, $window) { 'onUpdateState': updateState, //'onXvpInit': xvpInit, 'onFBUComplete': FBUComplete, - 'onDesktopName': updateDesktopName + 'onDesktopName': updateDesktopName, + 'foobar': 1 }); rfb.connect(host, port, password, path); } catch (exc) { |