├── .clang-format ├── .github └── workflows │ └── main.yml ├── .gitignore ├── CMakeLists.txt ├── LICENSE ├── README.md ├── base ├── CMakeLists.txt ├── bundle.h ├── exception.cc ├── flex │ ├── flex.cc │ └── flex.h ├── isolate.cc ├── js │ ├── console.js │ ├── flex.js │ └── rasp.js ├── native-function.cc ├── platform.cc ├── request.cc ├── request.h ├── snapshot.cc ├── tests │ └── main.cc ├── thread-pool.h └── timeout-task.cc ├── go ├── CMakeLists.txt ├── PkgConfig.cmake ├── README.md ├── bridge.cc ├── export.h ├── header.h ├── log.cc ├── log.go ├── openrasp-v8.pc.in ├── request-context.cc ├── request-context.go ├── underlying-buffer.go ├── v8.go └── v8_test.go ├── java ├── .gitignore ├── CMakeLists.txt ├── bench │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── org │ │ │ └── sample │ │ │ ├── Context.java │ │ │ ├── Logger.java │ │ │ ├── MyBenchmark.java │ │ │ ├── Params.java │ │ │ └── StackGetter.java │ │ └── resources │ │ └── plugin.js ├── com_baidu_openrasp_v8_Context.cc ├── com_baidu_openrasp_v8_Context.h ├── com_baidu_openrasp_v8_CrashReporter.cc ├── com_baidu_openrasp_v8_CrashReporter.h ├── com_baidu_openrasp_v8_V8.cc ├── com_baidu_openrasp_v8_V8.h ├── fetch_native_libraries.sh ├── header.h ├── pom.xml ├── pool.cc ├── src │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── baidu │ │ │ │ └── openrasp │ │ │ │ ├── nativelib │ │ │ │ ├── BaseJniExtractor.java │ │ │ │ ├── DefaultJniExtractor.java │ │ │ │ ├── JniExtractor.java │ │ │ │ ├── MxSysInfo.java │ │ │ │ ├── NativeLibraryUtil.java │ │ │ │ ├── NativeLoader.java │ │ │ │ └── WebappJniExtractor.java │ │ │ │ └── v8 │ │ │ │ ├── ByteArrayOutputStream.java │ │ │ │ ├── Context.java │ │ │ │ ├── CrashReporter.java │ │ │ │ ├── Loader.java │ │ │ │ ├── Logger.java │ │ │ │ ├── StackGetter.java │ │ │ │ └── V8.java │ │ └── resources │ │ │ └── .gitkeep │ └── test │ │ └── java │ │ └── com │ │ └── baidu │ │ └── openrasp │ │ └── v8 │ │ ├── ContextImpl.java │ │ └── V8Test.java └── utils.cc ├── php ├── CMakeLists.txt ├── PkgConfig.cmake ├── header.h └── openrasp-v8.pc.in ├── prebuilts ├── CMakeLists.txt ├── fetch_php_staticlibs.sh └── fetch_prebuilts.sh ├── scripts ├── linux32.sh ├── linux64.sh ├── linuxmusl64.sh ├── osx64.sh ├── windows32.sh └── windows64.sh └── vendors ├── Catch2 ├── include │ └── catch2 │ │ ├── catch.hpp │ │ ├── catch_reporter_automake.hpp │ │ ├── catch_reporter_tap.hpp │ │ └── catch_reporter_teamcity.hpp └── lib │ └── cmake │ └── Catch2 │ ├── Catch.cmake │ ├── Catch2Config.cmake │ ├── Catch2ConfigVersion.cmake │ ├── Catch2Targets.cmake │ ├── CatchAddTests.cmake │ └── ParseAndAddCatchTests.cmake ├── alpine-env └── Dockerfile ├── build-libv8.sh ├── cmake ├── CodeCoverage.cmake ├── c_flag_overrides.cmake ├── cxx_flag_overrides.cmake └── detect_architecture.cmake ├── cpr ├── .clang-format ├── .gitignore ├── .gitmodules ├── .travis.yml ├── AUTHORS ├── CMakeLists.txt ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── VERSION ├── appveyor.yml ├── cpr-config.cmake ├── cpr │ ├── CMakeLists.txt │ ├── auth.cpp │ ├── cookies.cpp │ ├── cprtypes.cpp │ ├── digest.cpp │ ├── error.cpp │ ├── multipart.cpp │ ├── parameters.cpp │ ├── payload.cpp │ ├── proxies.cpp │ ├── session.cpp │ ├── ssl_options.cpp │ ├── timeout.cpp │ └── util.cpp ├── format-check.sh ├── include │ └── cpr │ │ ├── api.h │ │ ├── auth.h │ │ ├── body.h │ │ ├── connect_timeout.h │ │ ├── cookies.h │ │ ├── cpr.h │ │ ├── cprtypes.h │ │ ├── curlholder.h │ │ ├── defines.h │ │ ├── digest.h │ │ ├── error.h │ │ ├── low_speed.h │ │ ├── max_redirects.h │ │ ├── multipart.h │ │ ├── parameters.h │ │ ├── payload.h │ │ ├── proxies.h │ │ ├── response.h │ │ ├── session.h │ │ ├── ssl_options.h │ │ ├── status_codes.h │ │ ├── timeout.h │ │ ├── user_agent.h │ │ ├── util.h │ │ └── verbose.h ├── opt │ └── CMakeLists.txt └── test │ ├── CMakeLists.txt │ ├── alternating_tests.cpp │ ├── async_tests.cpp │ ├── callback_tests.cpp │ ├── delete_tests.cpp │ ├── error_tests.cpp │ ├── get_tests.cpp │ ├── head_tests.cpp │ ├── options_tests.cpp │ ├── patch_tests.cpp │ ├── post_tests.cpp │ ├── proxy_tests.cpp │ ├── put_tests.cpp │ ├── raw_body_tests.cpp │ ├── server.cpp │ ├── server.h │ ├── session_tests.cpp │ └── util_tests.cpp └── fetch_centos6_sysroot.sh /.clang-format: -------------------------------------------------------------------------------- 1 | BasedOnStyle: Chromium 2 | ColumnLimit: 120 -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | 34 | # Build 35 | [Bb]uild*/ 36 | [Dd]ebug*/ 37 | [Rr]elease*/ 38 | vscodebuild 39 | 40 | .vscode 41 | .DS_Store 42 | *.log 43 | 44 | *.pc 45 | dist 46 | 47 | prebuilts/* 48 | !prebuilts/CMakeLists.txt 49 | !prebuilts/fetch_prebuilts.sh 50 | !prebuilts/fetch_php_staticlibs.sh -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.12.0) 2 | 3 | set(CMAKE_USER_MAKE_RULES_OVERRIDE_CXX ${CMAKE_CURRENT_SOURCE_DIR}/vendors/cmake/cxx_flag_overrides.cmake) 4 | set(CMAKE_CXX_STANDARD 11) 5 | set(CMAKE_POSITION_INDEPENDENT_CODE ON) 6 | 7 | project(openrasp-v8 LANGUAGES CXX) 8 | 9 | option(ENABLE_IAST "enable IAST" OFF) 10 | 11 | enable_testing() 12 | 13 | if (ENABLE_LANGUAGES STREQUAL "all") 14 | set(LANGS php java go) 15 | else() 16 | set(LANGS ${ENABLE_LANGUAGES}) 17 | endif() 18 | 19 | add_subdirectory(prebuilts) 20 | add_subdirectory(base) 21 | foreach(LANG IN LISTS LANGS) 22 | add_subdirectory(${LANG}) 23 | endforeach() -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # openrasp-v8 2 | 3 | ![CI](https://github.com/baidu-security/openrasp-v8/workflows/CI/badge.svg) 4 | 5 | Google V8 JavaScript engine with OpenRASP builtins, and bridges that are used to embed V8 within languages which are supported by [OpenRASP](https://github.com/baidu/openrasp). 6 | 7 | Currently supported languages: 8 | 9 | - PHP 10 | - Java 11 | - Go 12 | 13 | ## Features 14 | 15 | ### OpenRASP attack detect engine in JavaScript 16 | 17 | Full JavaScript runtime context of OpenRASP attack detect engine, with simple C++ interfaces and helpers. 18 | 19 | Integrating openrasp-v8 in other languages only need several lines. 20 | 21 | ### Lexical analyzer 22 | 23 | Flex lexical analyzer is embeded in openrasp-v8 to tokenize sql and command strings. Just call `RASP.sql_tokenize` or `RASP.cmd_tokenize` 24 | 25 | ### HTTP request 26 | 27 | The http request method is `RASP.request`. It accepts a configure object and returns a promise. Just like the axios. 28 | 29 | ### Platform independent 30 | 31 | You can build and use it on different OS types, different OS versions and different OS archs. 32 | 33 | For convenience of build, we have built some third-party libraries to static libraries: 34 | 35 | - Linux x64 36 | - Linux x86 37 | - Linux musl 38 | - OSX x64 39 | - Windows x64 40 | - Windows x86 41 | 42 | For compatibility of Linux, most libraries will be staticly linked into openrasp-v8, even libc++. You can even use centos6 sysroot to force linker to link old version glibc. 43 | 44 | ### Support multiple languages 45 | 46 | We will continuely add more languages to our support list. 47 | 48 | The language support briges are not just some C++ ports, but also the language specified native interfaces. Such as jni fo Java and cgo for Go. 49 | 50 | ## Build 51 | 52 | We use CMake to generate the files needed by your build tool (GNU make, Visual Studio, Ninja, etc.) for building openrasp-v8 and its language ports. 53 | 54 | For example: 55 | 56 | ```shell 57 | mkdir build 58 | cd build 59 | cmake -DENABLE_LANGUAGES=all .. 60 | make 61 | make test 62 | ``` 63 | 64 | The openrasp-v8 specified cmake variables: 65 | 66 | - ENABLE_LANGUAGES 67 | 68 | Cmake list of languages to build, or all for building all (base, php, java, go) 69 | 70 | - BUILD_TESTING 71 | 72 | Boolean option for whether the tests will be built 73 | 74 | - BUILD_COVERAGE 75 | 76 | Boolean option for whether the coverage will be built 77 | -------------------------------------------------------------------------------- /base/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.12.0) 2 | 3 | project(base LANGUAGES CXX) 4 | 5 | aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} BASE_SRCS) 6 | aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/flex FLEX_SRCS) 7 | 8 | add_library(base OBJECT ${BASE_SRCS} ${FLEX_SRCS}) 9 | target_include_directories(base PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/..) 10 | add_dependencies(base prebuilts) 11 | target_link_libraries(base PUBLIC prebuilts) 12 | 13 | set(JS_SRCS console.js flex.js rasp.js) 14 | list(TRANSFORM JS_SRCS PREPEND ${CMAKE_CURRENT_SOURCE_DIR}/js/) 15 | # 使用xxd把文件内容转换为c字符数组 16 | find_program(XXD xxd ${PREBUILTS_PREFIX}/bin) 17 | add_custom_target(builtinjs2cheader 18 | COMMAND rm -rf gen && mkdir gen 19 | COMMAND cat ${JS_SRCS} > gen/builtins 20 | COMMAND ${XXD} -i gen/builtins > gen/builtins.h 21 | WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) 22 | target_include_directories(base PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) 23 | add_dependencies(base builtinjs2cheader) 24 | 25 | # 添加cpr源码一起编译 26 | target_include_directories(base PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../vendors/cpr/include) 27 | aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/../vendors/cpr/cpr CPR_SRCS) 28 | target_sources(base PRIVATE ${CPR_SRCS}) 29 | 30 | # testing # 31 | option(BUILD_TESTING "Build the testing tree." OFF) 32 | option(BUILD_COVERAGE "Enable coverage reporting" OFF) 33 | if(NOT CMAKE_BUILD_TYPE OR CMAKE_BUILD_TYPE STREQUAL "Debug" OR BUILD_TESTING) 34 | set(BUILD_TESTING ON) 35 | find_package(Catch2 REQUIRED PATHS "${CMAKE_CURRENT_SOURCE_DIR}/../vendors/Catch2") 36 | aux_source_directory(tests BASE_TESTS_SRCS) 37 | add_executable(tests ${BASE_TESTS_SRCS}) 38 | target_include_directories(tests PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../vendors/cpr/include) 39 | target_link_libraries(tests base Catch2::Catch2) 40 | 41 | include(CTest) 42 | include(Catch) 43 | catch_discover_tests(tests) 44 | 45 | if(BUILD_COVERAGE) 46 | set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/../vendors/cmake") 47 | include(CodeCoverage) 48 | append_coverage_compiler_flags() 49 | set(COVERAGE_LCOV_EXCLUDES '*tests*' '*flex*' '*lex.yy.c*' '*usr*' '*vendors*' '*prebuilts*') 50 | setup_target_for_coverage_lcov(NAME coverage EXECUTABLE tests DEPENDENCIES tests) 51 | endif() 52 | endif() 53 | -------------------------------------------------------------------------------- /base/exception.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2019 Baidu Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "bundle.h" 18 | 19 | namespace openrasp_v8 { 20 | using namespace std; 21 | Exception::Exception(v8::Isolate* isolate, v8::TryCatch& try_catch) : string() { 22 | string& ref = *this; 23 | if (!try_catch.HasCaught()) { 24 | return; 25 | } 26 | if (try_catch.HasTerminated()) { 27 | ref.append("Terminated\n"); 28 | return; 29 | } 30 | v8::HandleScope handle_scope(isolate); 31 | v8::String::Utf8Value exception(isolate, try_catch.Exception()); 32 | v8::Local message = try_catch.Message(); 33 | if (message.IsEmpty()) { 34 | ref.append(*exception).append("\n"); 35 | } else { 36 | v8::Local context = isolate->GetCurrentContext(); 37 | std::string filename = ""; 38 | int linenum = 0; 39 | if (!message->GetScriptOrigin().ResourceName()->IsUndefined()) { 40 | filename = *v8::String::Utf8Value(isolate, message->GetScriptOrigin().ResourceName()); 41 | linenum = message->GetLineNumber(context).FromMaybe(0); 42 | } 43 | ref.append(filename).append(":").append(to_string(linenum)).append("\n"); 44 | v8::Local line; 45 | if (message->GetSourceLine(context).ToLocal(&line)) { 46 | v8::String::Utf8Value val(isolate, line); 47 | int start = 0, end = val.length(); 48 | if (end > 4 * 1024) { 49 | start = message->GetStartColumn() - 1024; 50 | end = message->GetEndColumn() + 1024; 51 | if (start < 0) { 52 | start = 0; 53 | } 54 | if (end > val.length()) { 55 | end = val.length(); 56 | } 57 | } 58 | ref.append(*val + start, end - start).append("\n"); 59 | } 60 | v8::Local stack_trace_string; 61 | if (try_catch.StackTrace(context).ToLocal(&stack_trace_string) && stack_trace_string->IsString() && 62 | v8::Local::Cast(stack_trace_string)->Length() > 0) { 63 | v8::String::Utf8Value stack_trace(isolate, stack_trace_string); 64 | ref.append(*stack_trace).append("\n"); 65 | } else { 66 | ref.append(*exception).append("\n"); 67 | } 68 | } 69 | } 70 | } // namespace openrasp_v8 -------------------------------------------------------------------------------- /base/flex/flex.h: -------------------------------------------------------------------------------- 1 | #include 2 | typedef struct flex_token_result { 3 | uint32_t * result; 4 | uint32_t result_len; 5 | } flex_token_result; 6 | 7 | flex_token_result flex_lexing(const char *input, uint32_t len, const char *tokenizer_type); 8 | 9 | #define YY_FATAL_ERROR(msg) throw msg 10 | -------------------------------------------------------------------------------- /base/js/flex.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @file flex.js 3 | * 包装native的flex_tokenize方法 4 | */ 5 | 'use strict'; 6 | 7 | global.tokenize = function (query, type) { 8 | const result = [] 9 | const arr = flex_tokenize(query, type) || [] 10 | for (let i = 0; i < arr.length; i += 2) { 11 | const start = arr[i] 12 | const stop = arr[i + 1] 13 | const text = query.substring(start, stop) 14 | result.push({ start, stop, text }) 15 | } 16 | return result 17 | } -------------------------------------------------------------------------------- /base/js/rasp.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @file rasp.js 3 | * RASP类 4 | */ 5 | 'use strict'; 6 | 7 | global.RASP = class { 8 | constructor(name) { 9 | if (typeof (name) !== 'string' || name.length == 0) { 10 | throw new TypeError('Plugin name must be a string'); 11 | } 12 | this.name = name; 13 | RASP.plugins[name] = this; 14 | } 15 | 16 | static check(checkPoint, checkParams, checkContext) { 17 | if (!RASP.checkPoints[checkPoint]) { 18 | return; 19 | } 20 | const results = [] 21 | for (const checkProcess of RASP.checkPoints[checkPoint]) { 22 | const result = checkProcess.plugin.make_result(checkProcess.func(checkParams, checkContext)); 23 | if (result) { 24 | results.push(result); 25 | } 26 | } 27 | return results; 28 | } 29 | 30 | static sql_tokenize(query) { 31 | return tokenize(query, "sql") 32 | } 33 | 34 | static cmd_tokenize(query) { 35 | return tokenize(query, 'bash') 36 | } 37 | 38 | static request(config) { 39 | return request(config) 40 | } 41 | 42 | static request_async(config) { 43 | return request_async(config) 44 | } 45 | 46 | static get_jsengine() { 47 | return 'v8' 48 | } 49 | 50 | static get_version() { 51 | return version 52 | } 53 | 54 | // 注册检测函数 55 | register(checkPoint, checkProcess) { 56 | if (typeof (checkPoint) !== 'string' || checkPoint.length == 0) { 57 | throw new TypeError('Check point name must be a string'); 58 | } 59 | if (Array.isArray(global.checkPoints) && global.checkPoints.indexOf(checkPoint) < 0) { 60 | this.log('Unknown check point name \'' + checkPoint + '\''); 61 | return; 62 | } 63 | if (typeof (checkProcess) !== 'function') { 64 | throw new TypeError('Check process must be a function'); 65 | } 66 | RASP.checkPoints[checkPoint] = RASP.checkPoints[checkPoint] || [] 67 | RASP.checkPoints[checkPoint].push({ 68 | func: checkProcess, 69 | plugin: this 70 | }); 71 | } 72 | 73 | // 加上插件名称前缀 74 | log() { 75 | let len = arguments.length; 76 | let args = Array(len); 77 | for (let key = 0; key < len; key++) { 78 | args[key] = arguments[key]; 79 | } 80 | console.log.apply(console, ['[' + this.name + ']'].concat(args)); 81 | } 82 | 83 | // 规范返回给c++的对象结构 84 | make_result(result) { 85 | // 不拦截和无日志的情况直接返回undefined,减少数据传递 86 | if (typeof result !== 'object' || result.action === 'ignore') { 87 | return; 88 | } 89 | // 非promise和promise两种情况 90 | if (typeof result.then !== 'function') { 91 | result.action = result.action || 'log'; 92 | result.message = result.message || ''; 93 | result.name = result.name || this.name; 94 | result.confidence = result.confidence || 0; 95 | return result; 96 | } else { 97 | // promise对象fullfill后再make_result 98 | return result.then(rst => { 99 | return this.make_result(rst) 100 | }).catch(err => { 101 | return this.make_result({ 102 | action: 'exception', 103 | message: JSON.stringify(err) 104 | }) 105 | }) 106 | } 107 | } 108 | }; 109 | RASP.plugins = {}; 110 | RASP.checkPoints = {}; -------------------------------------------------------------------------------- /base/native-function.cc: -------------------------------------------------------------------------------- 1 | #include "bundle.h" 2 | #include "flex/flex.h" 3 | #include "request.h" 4 | 5 | namespace openrasp_v8 { 6 | 7 | void log_callback(const v8::FunctionCallbackInfo& info) { 8 | Isolate* isolate = reinterpret_cast(info.GetIsolate()); 9 | for (int i = 0; i < info.Length(); i++) { 10 | v8::String::Utf8Value message(isolate, info[i]); 11 | Platform::logger({*message, static_cast(message.length())}); 12 | } 13 | } 14 | 15 | void flex_callback(const v8::FunctionCallbackInfo& info) { 16 | Isolate* isolate = reinterpret_cast(info.GetIsolate()); 17 | auto context = isolate->GetCurrentContext(); 18 | if (info.Length() < 2 || !info[0]->IsString() || !info[1]->IsString()) { 19 | return; 20 | } 21 | v8::String::Utf8Value str(isolate, info[0]); 22 | v8::String::Utf8Value lexer_mode(isolate, info[1]); 23 | 24 | char* input = *str; 25 | int input_len = str.length(); 26 | 27 | flex_token_result token_result = flex_lexing(input, input_len, *lexer_mode); 28 | 29 | size_t len = std::min(uint32_t(input_len), token_result.result_len); 30 | auto arr = v8::Array::New(isolate, len); 31 | for (int i = 0; i < len; i++) { 32 | arr->Set(context, i, v8::Integer::New(isolate, token_result.result[i])).IsJust(); 33 | } 34 | free(token_result.result); 35 | info.GetReturnValue().Set(arr); 36 | } 37 | 38 | void request_callback(const v8::FunctionCallbackInfo& info) { 39 | auto isolate = info.GetIsolate(); 40 | v8::TryCatch try_catch(isolate); 41 | auto context = isolate->GetCurrentContext(); 42 | v8::Local resolver; 43 | if (!v8::Promise::Resolver::New(context).ToLocal(&resolver)) { 44 | try_catch.ReThrow(); 45 | return; 46 | } 47 | info.GetReturnValue().Set(resolver->GetPromise()); 48 | HTTPRequest req(isolate, info[0]); 49 | HTTPResponse res = req.GetResponse(); 50 | auto object = res.ToObject(isolate); 51 | if (res.error) { 52 | resolver->Reject(context, object).IsJust(); 53 | } else { 54 | resolver->Resolve(context, object).IsJust(); 55 | } 56 | } 57 | 58 | void request_async_callback(const v8::FunctionCallbackInfo& info) { 59 | auto isolate = info.GetIsolate(); 60 | AsyncRequest::GetInstance().Submit(std::make_shared(isolate, info[0])); 61 | } 62 | 63 | intptr_t* Snapshot::external_references = new intptr_t[5]{ 64 | reinterpret_cast(log_callback), 65 | reinterpret_cast(flex_callback), 66 | reinterpret_cast(request_callback), 67 | reinterpret_cast(request_async_callback), 68 | 0, 69 | }; 70 | } // namespace openrasp_v8 -------------------------------------------------------------------------------- /base/platform.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2019 Baidu Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "bundle.h" 18 | 19 | namespace openrasp_v8 { 20 | 21 | std::unique_ptr Platform::instance; 22 | Logger Platform::logger = [](const std::string& message) { printf("%s", message.c_str()); }; 23 | // CriticalMemoryPressureCallback Platform::criticalMemoryPressureCallback = nullptr; 24 | 25 | Platform* Platform::New(int thread_pool_size) { 26 | instance.reset(new Platform(thread_pool_size)); 27 | return instance.get(); 28 | } 29 | 30 | Platform* Platform::Get() { 31 | return instance.get(); 32 | } 33 | 34 | void Platform::Startup() { 35 | if (!default_platform) { 36 | default_platform = v8::platform::NewDefaultPlatform(thread_pool_size); 37 | } 38 | } 39 | 40 | void Platform::Shutdown() { 41 | if (default_platform) { 42 | default_platform = nullptr; 43 | } 44 | } 45 | 46 | Platform::Platform(int thread_pool_size) : thread_pool_size(thread_pool_size) { 47 | tracing_controller.reset(new v8::platform::tracing::TracingController()); 48 | tracing_controller->Initialize(nullptr); 49 | Startup(); 50 | } 51 | 52 | Platform::~Platform() { 53 | Shutdown(); 54 | } 55 | 56 | bool Platform::PumpMessageLoop(v8::Isolate* isolate, v8::platform::MessageLoopBehavior behavior) { 57 | return v8::platform::PumpMessageLoop(default_platform.get(), isolate, behavior); 58 | } 59 | // void Platform::RunIdleTasks(v8::Isolate* isolate, double idle_time_in_seconds) { 60 | // return v8::platform::RunIdleTasks(default_platform.get(), isolate, idle_time_in_seconds); 61 | // } 62 | int Platform::NumberOfWorkerThreads() { 63 | return default_platform->NumberOfWorkerThreads(); 64 | } 65 | std::shared_ptr Platform::GetForegroundTaskRunner(v8::Isolate* isolate) { 66 | return default_platform->GetForegroundTaskRunner(isolate); 67 | } 68 | void Platform::CallOnWorkerThread(std::unique_ptr task) { 69 | return default_platform->CallOnWorkerThread(std::move(task)); 70 | } 71 | void Platform::CallDelayedOnWorkerThread(std::unique_ptr task, double delay_in_seconds) { 72 | return default_platform->CallDelayedOnWorkerThread(std::move(task), delay_in_seconds); 73 | } 74 | void Platform::CallOnForegroundThread(v8::Isolate* isolate, v8::Task* task) { 75 | return default_platform->CallOnForegroundThread(isolate, task); 76 | } 77 | void Platform::CallDelayedOnForegroundThread(v8::Isolate* isolate, v8::Task* task, double delay_in_seconds) { 78 | return default_platform->CallDelayedOnForegroundThread(isolate, task, delay_in_seconds); 79 | } 80 | // void Platform::CallIdleOnForegroundThread(v8::Isolate* isolate, v8::IdleTask* task) { 81 | // return default_platform->CallIdleOnForegroundThread(isolate, task); 82 | // } 83 | // bool Platform::IdleTasksEnabled(v8::Isolate* isolate) { 84 | // return default_platform->IdleTasksEnabled(isolate); 85 | // } 86 | double Platform::MonotonicallyIncreasingTime() { 87 | return default_platform->MonotonicallyIncreasingTime(); 88 | } 89 | double Platform::CurrentClockTimeMillis() { 90 | return default_platform->CurrentClockTimeMillis(); 91 | } 92 | v8::TracingController* Platform::GetTracingController() { 93 | // return default_platform->GetTracingController(); 94 | // return our TracingController, to avoid nullptr exception when shutdown platform 95 | return tracing_controller.get(); 96 | } 97 | v8::Platform::StackTracePrinter Platform::GetStackTracePrinter() { 98 | return default_platform->GetStackTracePrinter(); 99 | } 100 | // v8::PageAllocator* Platform::GetPageAllocator() { 101 | // // return default_platform->GetPageAllocator(); 102 | // // if returned nullptr, v8 will create a default PageAllocator as same as the one of default platform 103 | // return nullptr; 104 | // } 105 | // bool Platform::OnCriticalMemoryPressure(size_t length) { 106 | // if (criticalMemoryPressureCallback != nullptr) { 107 | // return criticalMemoryPressureCallback(length); 108 | // } else { 109 | // return false; 110 | // } 111 | // } 112 | 113 | } // namespace openrasp_v8 -------------------------------------------------------------------------------- /base/request.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2019 Baidu Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | #include 19 | #include 20 | 21 | #include 22 | #include 23 | 24 | #include "bundle.h" 25 | 26 | namespace openrasp_v8 { 27 | // HTTP部分基于libcurl的c++接口cpr 28 | class HTTPResponse : public cpr::Response { 29 | public: 30 | HTTPResponse() = default; 31 | HTTPResponse(const cpr::Response& response) : cpr::Response(response) {} 32 | v8::Local ToObject(v8::Isolate* isolate); 33 | }; 34 | 35 | class HTTPRequest : public cpr::Session { 36 | public: 37 | HTTPRequest() = default; 38 | HTTPRequest(v8::Isolate* isolate, v8::Local conf); 39 | void SetMethod(const std::string& method) { this->method = method; } 40 | HTTPResponse GetResponse(); 41 | std::string GetUrl() const; 42 | 43 | private: 44 | std::string method; 45 | std::string url; 46 | std::string error; 47 | }; 48 | 49 | } // namespace openrasp_v8 -------------------------------------------------------------------------------- /base/snapshot.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2019 Baidu Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include "bundle.h" 19 | #include "flex/flex.h" 20 | #include "gen/builtins.h" 21 | 22 | namespace openrasp_v8 { 23 | 24 | Snapshot::Snapshot(const char* data, size_t raw_size, uint64_t timestamp) 25 | : v8::StartupData({data, static_cast(raw_size)}), timestamp(timestamp) {} 26 | Snapshot::Snapshot(const std::string& path, uint64_t timestamp) : v8::StartupData({nullptr, 0}), timestamp(timestamp) { 27 | char* buffer = nullptr; 28 | size_t size = 0; 29 | std::ifstream file(path, std::ios::in | std::ios::binary); 30 | if (file) { 31 | file.seekg(0, std::ios::end); 32 | size = file.tellg(); 33 | file.seekg(0, std::ios::beg); 34 | if (size > 0) { 35 | buffer = new char[size]; 36 | if (!file.read(buffer, size)) { 37 | delete[] buffer; 38 | return; 39 | } 40 | } 41 | } 42 | this->data = buffer; 43 | this->raw_size = size; 44 | } 45 | Snapshot::Snapshot(const std::string& config, 46 | const std::vector& plugin_list, 47 | const std::string& version, 48 | uint64_t timestamp, 49 | void* custom_data) 50 | : v8::StartupData({nullptr, 0}), timestamp(timestamp) { 51 | IsolateData data; 52 | data.custom_data = custom_data; 53 | v8::SnapshotCreator creator(external_references); 54 | Isolate* isolate = reinterpret_cast(creator.GetIsolate()); 55 | isolate->SetData(&data); 56 | { 57 | v8::Isolate::Scope isolate_scope(isolate); 58 | v8::HandleScope handle_scope(isolate); 59 | v8::Local context = v8::Context::New(isolate); 60 | v8::Context::Scope context_scope(context); 61 | v8::TryCatch try_catch(isolate); 62 | v8::Local global = context->Global(); 63 | global->Set(context, NewV8Key(isolate, "version"), NewV8String(isolate, version)).IsJust(); 64 | global->Set(context, NewV8Key(isolate, "global"), global).IsJust(); 65 | global->Set(context, NewV8Key(isolate, "window"), global).IsJust(); 66 | v8::Local v8_stdout = v8::Object::New(isolate); 67 | v8_stdout 68 | ->Set( 69 | context, NewV8Key(isolate, "write"), 70 | v8::Function::New(context, reinterpret_cast(external_references[0])).ToLocalChecked()) 71 | .IsJust(); 72 | global->Set(context, NewV8Key(isolate, "stdout"), v8_stdout).IsJust(); 73 | global->Set(context, NewV8Key(isolate, "stderr"), v8_stdout).IsJust(); 74 | global 75 | ->Set( 76 | context, NewV8Key(isolate, "flex_tokenize"), 77 | v8::Function::New(context, reinterpret_cast(external_references[1])).ToLocalChecked()) 78 | .IsJust(); 79 | global 80 | ->Set( 81 | context, NewV8Key(isolate, "request"), 82 | v8::Function::New(context, reinterpret_cast(external_references[2])).ToLocalChecked()) 83 | .IsJust(); 84 | global 85 | ->Set( 86 | context, NewV8Key(isolate, "request_async"), 87 | v8::Function::New(context, reinterpret_cast(external_references[3])).ToLocalChecked()) 88 | .IsJust(); 89 | if (isolate->ExecScript({reinterpret_cast(gen_builtins), gen_builtins_len}, "builtins.js").IsEmpty()) { 90 | Exception e(isolate, try_catch); 91 | Platform::logger(e); 92 | // no need to continue 93 | return; 94 | } 95 | if (isolate->ExecScript(config, "config.js").IsEmpty()) { 96 | Exception e(isolate, try_catch); 97 | Platform::logger(e); 98 | } 99 | for (auto& plugin_src : plugin_list) { 100 | if (isolate->ExecScript("(function(){\n" + plugin_src.source + "\n})()", plugin_src.filename, -1).IsEmpty()) { 101 | Exception e(isolate, try_catch); 102 | Platform::logger(e); 103 | } 104 | } 105 | creator.SetDefaultContext(context); 106 | } 107 | v8::StartupData snapshot = creator.CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kClear); 108 | this->data = snapshot.data; 109 | this->raw_size = snapshot.raw_size; 110 | } 111 | Snapshot::~Snapshot() { 112 | delete[] data; 113 | } 114 | bool Snapshot::Save(const std::string& path) const { 115 | std::string tmp_path = path + ".tmp"; 116 | std::ofstream file(tmp_path, std::ios::out | std::ios::binary | std::ios::trunc); 117 | if (file) { 118 | file.write(data, raw_size); 119 | file.close(); 120 | if (!static_cast(file)) { 121 | return false; 122 | } 123 | if (std::rename(tmp_path.c_str(), path.c_str())) { 124 | return false; 125 | } 126 | return true; 127 | } 128 | // check errno when return value is false 129 | return false; 130 | } 131 | } // namespace openrasp_v8 -------------------------------------------------------------------------------- /base/thread-pool.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2019 Baidu Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | namespace openrasp_v8 { 26 | class ThreadPool { 27 | public: 28 | typedef std::function Task; 29 | 30 | ThreadPool(size_t thread_size, size_t queue_cap) : queue_cap(queue_cap) { 31 | for (size_t i = 0; i < thread_size; i++) { 32 | threads.emplace_back([this]() { 33 | while (auto task = GetNext()) { 34 | task(); 35 | } 36 | }); 37 | } 38 | } 39 | 40 | ~ThreadPool() { 41 | { 42 | std::lock_guard lock(mtx); 43 | terminated = true; 44 | } 45 | cv.notify_all(); 46 | for (auto& t : threads) { 47 | if (t.joinable()) { 48 | t.join(); 49 | } 50 | } 51 | } 52 | 53 | bool Post(Task&& task) { 54 | { 55 | std::lock_guard lock(mtx); 56 | if (terminated || tasks.size() >= queue_cap) { 57 | return false; 58 | } 59 | tasks.emplace(std::forward(task)); 60 | } 61 | cv.notify_one(); 62 | return true; 63 | } 64 | 65 | Task GetNext() { 66 | std::unique_lock lock(mtx); 67 | for (;;) { 68 | if (terminated) { 69 | return nullptr; 70 | } else if (!tasks.empty()) { 71 | auto task = std::move(tasks.front()); 72 | tasks.pop(); 73 | return task; 74 | } else { 75 | cv.wait(lock); 76 | } 77 | } 78 | } 79 | 80 | size_t GetQueueSize() { 81 | { 82 | std::lock_guard lock(mtx); 83 | return tasks.size(); 84 | } 85 | } 86 | 87 | private: 88 | std::condition_variable cv; 89 | std::mutex mtx; 90 | std::vector threads; 91 | std::queue tasks; 92 | size_t queue_cap; 93 | bool terminated = false; 94 | }; 95 | } // namespace openrasp_v8 -------------------------------------------------------------------------------- /base/timeout-task.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2019 Baidu Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include "bundle.h" 21 | 22 | namespace openrasp_v8 { 23 | TimeoutTask::TimeoutTask(Isolate* isolate, std::future fut, int milliseconds) 24 | : isolate(isolate), 25 | fut(std::move(fut)), 26 | time_point(std::chrono::high_resolution_clock::now() + std::chrono::milliseconds(milliseconds)) {} 27 | 28 | void TimeoutTask::Run() { 29 | if (std::future_status::timeout == fut.wait_until(time_point)) { 30 | isolate->GetData()->is_timeout = true; 31 | isolate->TerminateExecution(); 32 | } 33 | } 34 | } // namespace openrasp_v8 -------------------------------------------------------------------------------- /go/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.12.0) 2 | 3 | project(go LANGUAGES CXX) 4 | 5 | add_library(openrasp_v8_go) 6 | add_dependencies(openrasp_v8_go base prebuilts) 7 | target_link_libraries(openrasp_v8_go PUBLIC base prebuilts) 8 | 9 | add_custom_command(TARGET openrasp_v8_go POST_BUILD 10 | COMMAND ${CMAKE_COMMAND} 11 | -DOPENRASP_V8_PATH=${CMAKE_CURRENT_BINARY_DIR} 12 | -DINCLUDE_DIRECTORIES="$" 13 | -DLINK_LIBRARIES="$" 14 | -DTARGET_FILE="$" 15 | -P ${CMAKE_CURRENT_SOURCE_DIR}/PkgConfig.cmake) 16 | -------------------------------------------------------------------------------- /go/PkgConfig.cmake: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.12.0) 2 | set(PREFIX ${CMAKE_CURRENT_LIST_DIR}) 3 | list(JOIN INCLUDE_DIRECTORIES " -I" CFLAGS) 4 | set(CFLAGS "-I${CFLAGS}") 5 | list(JOIN LINK_LIBRARIES " " LDFLAGS) 6 | set(LDFLAGS "${TARGET_FILE} ${LDFLAGS}") 7 | configure_file(${PREFIX}/openrasp-v8.pc.in ${PREFIX}/openrasp-v8.pc) 8 | -------------------------------------------------------------------------------- /go/README.md: -------------------------------------------------------------------------------- 1 | # openrasp-v8 for go 2 | 3 | ## Build 4 | 5 | Firstly, make sure the git and git-lfs have been installed. 6 | 7 | Clone this project and enter go directory 8 | 9 | ``` 10 | git clone https://github.com/baidu-security/openrasp-v8.git 11 | cd go 12 | ``` 13 | 14 | Build C++ dependencies 15 | 16 | ``` 17 | mkdir build 18 | cmake -S . -B build 19 | cmake --build build 20 | ``` 21 | 22 | Build go package 23 | 24 | ``` 25 | go build 26 | ``` 27 | 28 | Run tests 29 | 30 | ``` 31 | go test 32 | ``` 33 | 34 | ## Install 35 | 36 | Go get without building and installing 37 | 38 | ``` 39 | go get -d github.com/baidu-security/openrasp-v8/go 40 | ``` 41 | 42 | Enter the source directory 43 | 44 | ``` 45 | cd $GOPATH/src/github.com/baidu-security/openrasp-v8/go 46 | ``` 47 | 48 | Follow the build guide above and then, 49 | 50 | Install package 51 | 52 | ``` 53 | go install 54 | ``` 55 | 56 | ## Caveat 57 | 58 | The v8 static library is tracked by git-lfs in this repository, if you can not install the git-lfs, you can download the libv8 mananly, and tell cmake where can find the libv8_monolith.a 59 | 60 | ``` 61 | cmake -S . -B build -DCMAKE_PREFIX_PATH=path-to-libv8 62 | ``` -------------------------------------------------------------------------------- /go/bridge.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2019 Baidu Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "header.h" 18 | 19 | using namespace openrasp_v8; 20 | 21 | Snapshot* snapshot = nullptr; 22 | std::vector plugin_list; 23 | 24 | char Initialize() { 25 | v8::V8::InitializePlatform(Platform::New(0)); 26 | v8::V8::Initialize(); 27 | return true; 28 | } 29 | 30 | char Dispose() { 31 | delete snapshot; 32 | v8::V8::Dispose(); 33 | v8::V8::ShutdownPlatform(); 34 | return true; 35 | } 36 | 37 | char ClearPlugin() { 38 | plugin_list.clear(); 39 | return true; 40 | } 41 | 42 | char AddPlugin(Buffer source, Buffer name) { 43 | plugin_list.emplace_back(std::string{*name, name.length()}, std::string{*source, source.length()}); 44 | return true; 45 | } 46 | 47 | char CreateSnapshot(Buffer config) { 48 | auto duration = std::chrono::system_clock::now().time_since_epoch(); 49 | auto millis = std::chrono::duration_cast(duration).count(); 50 | Snapshot* blob = new Snapshot({*config, config.length()}, plugin_list, millis, nullptr); 51 | if (!blob->IsOk()) { 52 | delete blob; 53 | return false; 54 | } 55 | delete snapshot; 56 | snapshot = blob; 57 | return true; 58 | } 59 | 60 | Buffer Check(Buffer type, Buffer params, int context_index, int timeout) { 61 | Isolate* isolate = GetIsolate(); 62 | if (!isolate) { 63 | return {nullptr, 0}; 64 | } 65 | auto data = isolate->GetData(); 66 | auto custom_data = GetCustomData(data); 67 | custom_data->context_index = context_index; 68 | v8::HandleScope handle_scope(isolate); 69 | auto context = isolate->GetCurrentContext(); 70 | v8::Local tmp_str; 71 | v8::Local request_type; 72 | v8::Local request_params; 73 | v8::Local request_context; 74 | 75 | if (!v8::String::NewFromUtf8(isolate, *type, v8::NewStringType::kNormal, type.length()).ToLocal(&request_type)) { 76 | return {nullptr, 0}; 77 | } 78 | 79 | if (!v8::String::NewFromUtf8(isolate, *params, v8::NewStringType::kNormal, params.length()).ToLocal(&tmp_str)) { 80 | return {nullptr, 0}; 81 | } 82 | if (!v8::JSON::Parse(context, tmp_str).ToLocal(&request_params)) { 83 | return {nullptr, 0}; 84 | } 85 | 86 | if (!data->request_context_templ.Get(isolate)->NewInstance(context).ToLocal(&request_context)) { 87 | return {nullptr, 0}; 88 | } 89 | 90 | auto rst = isolate->Check(request_type, request_params.As(), request_context, timeout); 91 | 92 | if (rst->Length() == 0) { 93 | return {nullptr, 0}; 94 | } 95 | v8::Local json; 96 | if (!v8::JSON::Stringify(context, rst).ToLocal(&json)) { 97 | return {nullptr, 0}; 98 | } 99 | size_t len = json->Utf8Length(isolate); 100 | // no trailing 0 101 | char* str = new char[len]; 102 | json->WriteUtf8(isolate, str, len); 103 | return {str, len}; 104 | } 105 | 106 | Buffer ExecScript(Buffer source, Buffer name) { 107 | Isolate* isolate = GetIsolate(); 108 | if (!isolate) { 109 | return {nullptr, 0}; 110 | } 111 | v8::HandleScope handle_scope(isolate); 112 | v8::TryCatch try_catch(isolate); 113 | auto maybe_rst = isolate->ExecScript({*source, source.length()}, {*name, name.length()}); 114 | v8::Local rst; 115 | v8::Local string; 116 | if (!maybe_rst.ToLocal(&rst) || !v8::JSON::Stringify(isolate->GetCurrentContext(), rst).ToLocal(&string)) { 117 | Exception e(isolate, try_catch); 118 | plugin_info(isolate, e); 119 | return {nullptr, 0}; 120 | } 121 | size_t len = string->Utf8Length(isolate); 122 | // no trailing 0 123 | char* str = new char[len]; 124 | string->WriteUtf8(isolate, str, len); 125 | return {str, len}; 126 | } 127 | -------------------------------------------------------------------------------- /go/export.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2019 Baidu Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | #include 19 | 20 | #ifdef __cplusplus 21 | extern "C" { 22 | #endif 23 | 24 | typedef struct { 25 | const void* data; 26 | size_t raw_size; 27 | #ifdef __cplusplus 28 | const char* operator*() const { return reinterpret_cast(data); } 29 | size_t length() const { return raw_size; } 30 | #endif 31 | } Buffer; 32 | 33 | void* CreateV8String(void* isolate, Buffer buf); 34 | void* CreateV8ArrayBuffer(void* isolate, Buffer buf); 35 | 36 | char Initialize(); 37 | char Dispose(); 38 | char ClearPlugin(); 39 | char AddPlugin(Buffer source, Buffer name); 40 | char CreateSnapshot(Buffer config); 41 | Buffer Check(Buffer type, Buffer params, int context_index, int timeout); 42 | Buffer ExecScript(Buffer source, Buffer name); 43 | 44 | #ifdef __cplusplus 45 | } 46 | #endif 47 | -------------------------------------------------------------------------------- /go/header.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2019 Baidu Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include "_cgo_export.h" 20 | #include "base/bundle.h" 21 | #include "export.h" 22 | 23 | extern openrasp_v8::Snapshot* snapshot; 24 | extern std::vector plugin_list; 25 | class CustomData { 26 | public: 27 | int context_index = 0; 28 | }; 29 | inline CustomData* GetCustomData(openrasp_v8::IsolateData* data) { 30 | return reinterpret_cast(data->custom_data); 31 | } 32 | inline CustomData* GetCustomData(openrasp_v8::Isolate* isolate) { 33 | return GetCustomData(isolate->GetData()); 34 | } 35 | class IsolateDeleter { 36 | public: 37 | void operator()(openrasp_v8::Isolate* isolate) { 38 | delete GetCustomData(isolate); 39 | isolate->Dispose(); 40 | } 41 | }; 42 | typedef std::unique_ptr IsolatePtr; 43 | inline openrasp_v8::Isolate* GetIsolate() { 44 | static thread_local IsolatePtr isolate_ptr; 45 | auto isolate = isolate_ptr.get(); 46 | if (snapshot) { 47 | if (!isolate || isolate->IsExpired(snapshot->timestamp)) { 48 | auto duration = std::chrono::system_clock::now().time_since_epoch(); 49 | auto millis = std::chrono::duration_cast(duration).count(); 50 | isolate = openrasp_v8::Isolate::New(snapshot, millis); 51 | isolate->GetData()->custom_data = new CustomData(); 52 | isolate_ptr.reset(isolate); 53 | } 54 | } 55 | return isolate; 56 | } -------------------------------------------------------------------------------- /go/log.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2019 Baidu Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "base/bundle.h" 18 | #include "header.h" 19 | using namespace openrasp_v8; 20 | 21 | void openrasp_v8::plugin_info(Isolate* isolate, const std::string& message) { 22 | pluginLog({message.c_str(), message.length()}); 23 | } -------------------------------------------------------------------------------- /go/log.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2019 Baidu Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package v8 18 | 19 | /* 20 | #cgo CFLAGS: -std=c11 21 | #cgo CXXFLAGS: -std=c++11 22 | #cgo pkg-config: openrasp-v8.pc 23 | #include "export.h" 24 | #include "stdlib.h" 25 | */ 26 | import "C" 27 | 28 | //PluginLogCB the plugin log callback, any content type, should output directly, should not append trailing '\n' 29 | type PluginLogCB func(str string) 30 | 31 | var pluginLogCB PluginLogCB 32 | 33 | //export pluginLog 34 | func pluginLog(buf C.Buffer) { 35 | if pluginLogCB != nil { 36 | pluginLogCB(C.GoStringN((*C.char)(buf.data), C.int(buf.raw_size))) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /go/openrasp-v8.pc.in: -------------------------------------------------------------------------------- 1 | Name: openrasp-v8 2 | Description: openrasp-v8 3 | Version: x 4 | Cflags: ${CFLAGS} 5 | Libs: ${LDFLAGS} -------------------------------------------------------------------------------- /go/underlying-buffer.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2019 Baidu Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package v8 18 | 19 | /* 20 | #cgo CFLAGS: -std=c11 21 | #cgo CXXFLAGS: -std=c++11 22 | #cgo pkg-config: openrasp-v8.pc 23 | #include "export.h" 24 | #include "stdlib.h" 25 | */ 26 | import "C" 27 | import ( 28 | "reflect" 29 | "unsafe" 30 | ) 31 | 32 | func underlyingString(s string) C.Buffer { 33 | p := (*reflect.StringHeader)(unsafe.Pointer(&s)) 34 | return C.Buffer{data: unsafe.Pointer(p.Data), raw_size: C.size_t(p.Len)} 35 | } 36 | 37 | func underlyingBytes(b []byte) C.Buffer { 38 | p := (*reflect.SliceHeader)(unsafe.Pointer(&b)) 39 | return C.Buffer{data: unsafe.Pointer(p.Data), raw_size: C.size_t(p.Len)} 40 | } 41 | 42 | func underlying(i interface{}) C.Buffer { 43 | switch t := i.(type) { 44 | case string: 45 | return underlyingString(t) 46 | case []byte: 47 | return underlyingBytes(t) 48 | default: 49 | return C.Buffer{nil, 0} 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /go/v8.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2019 Baidu Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package v8 18 | 19 | /* 20 | #cgo CFLAGS: -std=c11 21 | #cgo CXXFLAGS: -std=c++11 22 | #cgo pkg-config: openrasp-v8.pc 23 | #include "export.h" 24 | #include "stdlib.h" 25 | */ 26 | import "C" 27 | import ( 28 | "sync" 29 | "unsafe" 30 | ) 31 | 32 | //Plugin plugin source and filename 33 | type Plugin struct { 34 | Source string 35 | Filename string 36 | } 37 | 38 | var rw sync.RWMutex 39 | 40 | //Initialize initialize V8 41 | func Initialize(cb PluginLogCB) bool { 42 | rw.Lock() 43 | defer rw.Unlock() 44 | pluginLogCB = cb 45 | return C.Initialize() != 0 46 | } 47 | 48 | //Dispose dispose V8, can not reinitialze 49 | func Dispose() bool { 50 | rw.Lock() 51 | defer rw.Unlock() 52 | return C.Dispose() != 0 53 | } 54 | 55 | //CreateSnapshot create snapshot with config and plugins 56 | func CreateSnapshot(config string, plugins []Plugin) bool { 57 | rw.Lock() 58 | defer rw.Unlock() 59 | C.ClearPlugin() 60 | for _, plugin := range plugins { 61 | C.AddPlugin(underlyingString(plugin.Source), underlyingString(plugin.Filename)) 62 | } 63 | return C.CreateSnapshot(underlyingString(config)) != 0 64 | } 65 | 66 | //Check check request 67 | func Check(requestType string, requestParams []byte, requestContext *ContextGetters, timeout int) []byte { 68 | rw.RLock() 69 | defer rw.RUnlock() 70 | contextIndex := RegisterContext(requestContext) 71 | defer UnregisterContext(contextIndex) 72 | buf := C.Check(underlyingString(requestType), underlyingBytes(requestParams), C.int(contextIndex), C.int(timeout)) 73 | defer C.free(unsafe.Pointer(buf.data)) 74 | return C.GoBytes(unsafe.Pointer(buf.data), C.int(buf.raw_size)) 75 | } 76 | 77 | //ExecScript execute any script 78 | func ExecScript(source string, filename string) string { 79 | rw.RLock() 80 | defer rw.RUnlock() 81 | buf := C.ExecScript(underlyingString(source), underlyingString(filename)) 82 | return C.GoStringN((*C.char)(buf.data), C.int(buf.raw_size)) 83 | } 84 | -------------------------------------------------------------------------------- /java/.gitignore: -------------------------------------------------------------------------------- 1 | bin 2 | target 3 | .project 4 | .settings 5 | .classpath 6 | lib 7 | natives 8 | 9 | # idea 10 | .idea 11 | *.iml 12 | -------------------------------------------------------------------------------- /java/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.12.0) 2 | 3 | project(java LANGUAGES CXX) 4 | 5 | find_package(JNI) 6 | aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} SRCS) 7 | add_library(openrasp_v8_java SHARED ${SRCS}) 8 | target_include_directories(openrasp_v8_java PUBLIC ${JNI_INCLUDE_DIRS}) 9 | add_dependencies(openrasp_v8_java base prebuilts) 10 | target_link_libraries(openrasp_v8_java PUBLIC base prebuilts) 11 | 12 | if (CMAKE_SYSTEM_NAME STREQUAL "Linux") 13 | target_link_libraries(openrasp_v8_java PRIVATE "-z noexecstack") 14 | endif() -------------------------------------------------------------------------------- /java/bench/src/main/java/org/sample/Context.java: -------------------------------------------------------------------------------- 1 | package org.sample; 2 | 3 | import java.util.*; 4 | import com.jsoniter.output.JsonStream; 5 | import org.apache.commons.lang3.RandomStringUtils; 6 | import com.baidu.openrasp.v8.ByteArrayOutputStream; 7 | 8 | public class Context extends com.baidu.openrasp.v8.Context { 9 | 10 | public String getString(String key) { 11 | return RandomStringUtils.randomAscii(1, 1024 * 4); 12 | } 13 | 14 | public byte[] getObject(String key) { 15 | HashMap obj = new HashMap(); 16 | obj.put("os", "Linux"); 17 | int rand = new Random().nextInt(10); 18 | for (int i = 0; i < rand; i++) { 19 | obj.put(RandomStringUtils.randomAlphanumeric(2, 10), RandomStringUtils.randomAscii(0, 1024 * 4)); 20 | obj.put(RandomStringUtils.randomAlphanumeric(2, 10), Math.random()); 21 | } 22 | ByteArrayOutputStream data = new ByteArrayOutputStream(); 23 | JsonStream.serialize(obj, data); 24 | data.write(0); 25 | return data.getByteArray(); 26 | } 27 | 28 | public byte[] getBuffer(String key) { 29 | return getObject(key); 30 | } 31 | 32 | } -------------------------------------------------------------------------------- /java/bench/src/main/java/org/sample/Logger.java: -------------------------------------------------------------------------------- 1 | package org.sample; 2 | 3 | public class Logger implements com.baidu.openrasp.v8.Logger { 4 | public void log(String msg) { 5 | if (msg.length() > 1024) { 6 | msg = msg.substring(0, 256) + "..." + msg.substring(msg.length() - 256, msg.length()); 7 | } 8 | System.out.println(msg); 9 | } 10 | } -------------------------------------------------------------------------------- /java/bench/src/main/java/org/sample/MyBenchmark.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | 26 | package org.sample; 27 | 28 | import org.openjdk.jmh.annotations.*; 29 | import org.apache.commons.io.FileUtils; 30 | import java.util.concurrent.TimeUnit; 31 | import java.util.ArrayList; 32 | import com.baidu.openrasp.v8.V8; 33 | import com.baidu.openrasp.v8.ByteArrayOutputStream; 34 | 35 | @Fork(1) 36 | @Threads(1000) 37 | @Warmup(iterations = 1, time = 10, timeUnit = TimeUnit.SECONDS) 38 | @Measurement(iterations = 2000, time = 10, timeUnit = TimeUnit.SECONDS) 39 | @State(Scope.Benchmark) 40 | public class MyBenchmark { 41 | 42 | public static Context context; 43 | 44 | @Setup(Level.Trial) 45 | public void setupTrial() throws Exception { 46 | V8.Load(); 47 | Context.setStringKeys(new String[] { "path", "method", "url", "querystring", "protocol", "remoteAddr", 48 | "appBasePath", "requestId" }); 49 | Context.setObjectKeys(new String[] { "json", "server", "parameter", "header" }); 50 | Context.setBufferKeys(new String[] { "body" }); 51 | V8.SetLogger(new Logger()); 52 | V8.SetStackGetter(new StackGetter()); 53 | V8.Initialize(2); 54 | String plugin = FileUtils.readFileToString(org.openjdk.jmh.util.FileUtils.extractFromResource("/plugin.js"), 55 | "UTF-8"); 56 | ArrayList scripts = new ArrayList(); 57 | scripts.add(new String[] { "test.js", plugin }); 58 | V8.CreateSnapshot("{}", scripts.toArray(), "1.2.3"); 59 | } 60 | 61 | @TearDown(Level.Trial) 62 | public void tearDownTrial() throws Exception { 63 | for (int i = 0; i < 10; i++) { 64 | V8.Check("requestEnd", "{}".getBytes(), 2, context, 100); 65 | } 66 | } 67 | 68 | @Setup(Level.Iteration) 69 | public void setupIteration() throws Exception { 70 | context = new Context(); 71 | V8.Check("request", "{}".getBytes(), 2, context, 100); 72 | } 73 | 74 | @TearDown(Level.Iteration) 75 | public void tearDownIteration() throws Exception { 76 | V8.Check("requestEnd", "{}".getBytes(), 2, context, 100); 77 | } 78 | 79 | @Benchmark 80 | public void testCheck() { 81 | String type = Params.GetType(); 82 | byte[] params = Params.GetParams(type); 83 | V8.Check(type, params, 0, context, 1000); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /java/bench/src/main/java/org/sample/Params.java: -------------------------------------------------------------------------------- 1 | package org.sample; 2 | 3 | import java.util.*; 4 | import com.jsoniter.output.JsonStream; 5 | import org.apache.commons.lang3.RandomStringUtils; 6 | import com.baidu.openrasp.v8.ByteArrayOutputStream; 7 | 8 | public class Params { 9 | 10 | private static Random random = new Random(); 11 | 12 | private static String[] types = { "sql", "command", "readFile", "writeFile", "directory" }; 13 | 14 | public static String GetType() { 15 | return types[random.nextInt(types.length)]; 16 | } 17 | 18 | public static byte[] GetParams(String type) { 19 | HashMap obj = new HashMap(); 20 | if (type.equals("sql")) { 21 | obj.put("query", RandomStringUtils.randomAscii(1, 1024 * 4)); 22 | obj.put("server", "mysql"); 23 | } else if (type.equals("command")) { 24 | obj.put("command", RandomStringUtils.randomAscii(1, 1024 * 1024 * 4)); 25 | } else if (type.equals("readFile") || type.equals("writeFile") || type.equals("directory")) { 26 | obj.put("path", RandomStringUtils.randomAscii(1, 1024 * 4)); 27 | obj.put("realpath", RandomStringUtils.randomAscii(1, 1024 * 4)); 28 | } 29 | ByteArrayOutputStream data = new ByteArrayOutputStream(); 30 | JsonStream.serialize(obj, data); 31 | data.write(0); 32 | return data.getByteArray(); 33 | } 34 | 35 | } -------------------------------------------------------------------------------- /java/bench/src/main/java/org/sample/StackGetter.java: -------------------------------------------------------------------------------- 1 | package org.sample; 2 | 3 | import java.util.*; 4 | import com.jsoniter.output.JsonStream; 5 | import org.apache.commons.lang3.RandomStringUtils; 6 | import com.baidu.openrasp.v8.ByteArrayOutputStream; 7 | 8 | public class StackGetter implements com.baidu.openrasp.v8.StackGetter { 9 | 10 | public byte[] get() { 11 | LinkedList list = new LinkedList(); 12 | for (int i = 0; i < 10; i++) { 13 | list.add(RandomStringUtils.randomAscii(1, 1024 * 4)); 14 | } 15 | ByteArrayOutputStream data = new ByteArrayOutputStream(); 16 | JsonStream.serialize(list, data); 17 | data.write(0); 18 | return data.getByteArray(); 19 | } 20 | 21 | } -------------------------------------------------------------------------------- /java/com_baidu_openrasp_v8_Context.h: -------------------------------------------------------------------------------- 1 | /* DO NOT EDIT THIS FILE - it is machine generated */ 2 | #include 3 | /* Header for class com_baidu_openrasp_v8_Context */ 4 | 5 | #ifndef _Included_com_baidu_openrasp_v8_Context 6 | #define _Included_com_baidu_openrasp_v8_Context 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | /* 11 | * Class: com_baidu_openrasp_v8_Context 12 | * Method: setStringKeys 13 | * Signature: ([Ljava/lang/String;)V 14 | */ 15 | JNIEXPORT void JNICALL Java_com_baidu_openrasp_v8_Context_setStringKeys 16 | (JNIEnv *, jclass, jobjectArray); 17 | 18 | /* 19 | * Class: com_baidu_openrasp_v8_Context 20 | * Method: setObjectKeys 21 | * Signature: ([Ljava/lang/String;)V 22 | */ 23 | JNIEXPORT void JNICALL Java_com_baidu_openrasp_v8_Context_setObjectKeys 24 | (JNIEnv *, jclass, jobjectArray); 25 | 26 | /* 27 | * Class: com_baidu_openrasp_v8_Context 28 | * Method: setBufferKeys 29 | * Signature: ([Ljava/lang/String;)V 30 | */ 31 | JNIEXPORT void JNICALL Java_com_baidu_openrasp_v8_Context_setBufferKeys 32 | (JNIEnv *, jclass, jobjectArray); 33 | 34 | #ifdef __cplusplus 35 | } 36 | #endif 37 | #endif 38 | -------------------------------------------------------------------------------- /java/com_baidu_openrasp_v8_CrashReporter.h: -------------------------------------------------------------------------------- 1 | /* DO NOT EDIT THIS FILE - it is machine generated */ 2 | #include 3 | /* Header for class com_baidu_openrasp_v8_CrashReporter */ 4 | 5 | #ifndef _Included_com_baidu_openrasp_v8_CrashReporter 6 | #define _Included_com_baidu_openrasp_v8_CrashReporter 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | /* 11 | * Class: com_baidu_openrasp_v8_CrashReporter 12 | * Method: install 13 | * Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V 14 | */ 15 | JNIEXPORT void JNICALL Java_com_baidu_openrasp_v8_CrashReporter_install 16 | (JNIEnv *, jclass, jstring, jstring, jstring, jstring); 17 | 18 | #ifdef __cplusplus 19 | } 20 | #endif 21 | #endif 22 | -------------------------------------------------------------------------------- /java/com_baidu_openrasp_v8_V8.h: -------------------------------------------------------------------------------- 1 | /* DO NOT EDIT THIS FILE - it is machine generated */ 2 | #include 3 | /* Header for class com_baidu_openrasp_v8_V8 */ 4 | 5 | #ifndef _Included_com_baidu_openrasp_v8_V8 6 | #define _Included_com_baidu_openrasp_v8_V8 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | /* 11 | * Class: com_baidu_openrasp_v8_V8 12 | * Method: Initialize 13 | * Signature: (III)Z 14 | */ 15 | JNIEXPORT jboolean JNICALL Java_com_baidu_openrasp_v8_V8_Initialize 16 | (JNIEnv *, jclass, jint, jint, jint); 17 | 18 | /* 19 | * Class: com_baidu_openrasp_v8_V8 20 | * Method: Dispose 21 | * Signature: ()Z 22 | */ 23 | JNIEXPORT jboolean JNICALL Java_com_baidu_openrasp_v8_V8_Dispose 24 | (JNIEnv *, jclass); 25 | 26 | /* 27 | * Class: com_baidu_openrasp_v8_V8 28 | * Method: CreateSnapshot 29 | * Signature: (Ljava/lang/String;[Ljava/lang/Object;Ljava/lang/String;)Z 30 | */ 31 | JNIEXPORT jboolean JNICALL Java_com_baidu_openrasp_v8_V8_CreateSnapshot 32 | (JNIEnv *, jclass, jstring, jobjectArray, jstring); 33 | 34 | /* 35 | * Class: com_baidu_openrasp_v8_V8 36 | * Method: Check 37 | * Signature: (Ljava/lang/String;[BILcom/baidu/openrasp/v8/Context;I)[B 38 | */ 39 | JNIEXPORT jbyteArray JNICALL Java_com_baidu_openrasp_v8_V8_Check 40 | (JNIEnv *, jclass, jstring, jbyteArray, jint, jobject, jint); 41 | 42 | /* 43 | * Class: com_baidu_openrasp_v8_V8 44 | * Method: ExecuteScript 45 | * Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; 46 | */ 47 | JNIEXPORT jstring JNICALL Java_com_baidu_openrasp_v8_V8_ExecuteScript 48 | (JNIEnv *, jclass, jstring, jstring); 49 | 50 | #ifdef __cplusplus 51 | } 52 | #endif 53 | #endif 54 | -------------------------------------------------------------------------------- /java/fetch_native_libraries.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ev 4 | ROOT=$(git rev-parse --show-toplevel) 5 | TAG=$(git describe --exact-match --tags || echo snapshot) 6 | if [ $TRAVIS ]; then 7 | DIR=$HOME/cache 8 | mkdir -p $DIR 9 | else 10 | DIR=/tmp 11 | fi 12 | echo $ROOT $TAG $DIR 13 | curl -R -# -k -L -o $DIR/java_natives_$TAG.tar.gz.download -z $DIR/java_natives_$TAG.tar.gz https://github.com/baidu-security/openrasp-v8/releases/download/$TAG/java_natives.tar.gz 14 | [[ -f $DIR/java_natives_$TAG.tar.gz.download ]] && cp -p $DIR/java_natives_$TAG.tar.gz.download $DIR/java_natives_$TAG.tar.gz && rm $DIR/java_natives_$TAG.tar.gz.download 15 | tar zxf $DIR/java_natives_$TAG.tar.gz -C $ROOT/java/src/main/resources 16 | -------------------------------------------------------------------------------- /java/header.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2019 Baidu Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include "base/bundle.h" 27 | 28 | // fix 32 bit jdk's runtime stack 29 | #if defined(__linux__) && defined(__i386__) 30 | #define ALIGN_FUNCTION __attribute__((force_align_arg_pointer)) 31 | #else 32 | #define ALIGN_FUNCTION 33 | #endif 34 | 35 | extern openrasp_v8::Snapshot* snapshot; 36 | extern std::mutex snapshot_mtx; 37 | 38 | void plugin_log(JNIEnv* env, const std::string& message); 39 | void plugin_log(const std::string& message); 40 | std::string Jstring2String(JNIEnv* env, jstring jstr); 41 | jstring String2Jstring(JNIEnv* env, const std::string& str); 42 | v8::MaybeLocal Jstring2V8string(JNIEnv* env, jstring jstr); 43 | jstring V8value2Jstring(JNIEnv* env, v8::Local val); 44 | v8::Local CreateRequestContextTemplate(openrasp_v8::Isolate* isolate); 45 | void GetStack(v8::Local name, const v8::PropertyCallbackInfo& info); 46 | 47 | class V8Class { 48 | public: 49 | V8Class() = default; 50 | V8Class(JNIEnv* env) { 51 | auto ref = env->FindClass("com/baidu/openrasp/v8/V8"); 52 | cls = (jclass)env->NewGlobalRef(ref); 53 | Log = env->GetStaticMethodID(cls, "Log", "(Ljava/lang/String;)V"); 54 | GetStack = env->GetStaticMethodID(cls, "GetStack", "()[B"); 55 | GetFreeMemory = env->GetStaticMethodID(cls, "GetFreeMemory", "()J"); 56 | Gc = env->GetStaticMethodID(cls, "Gc", "()V"); 57 | } 58 | jclass cls; 59 | jmethodID Log; 60 | jmethodID GetStack; 61 | jmethodID GetFreeMemory; 62 | jmethodID Gc; 63 | }; 64 | 65 | class ContextClass { 66 | public: 67 | ContextClass() = default; 68 | ContextClass(JNIEnv* env) { 69 | auto ref = env->FindClass("com/baidu/openrasp/v8/Context"); 70 | cls = (jclass)env->NewGlobalRef(ref); 71 | getString = env->GetMethodID(cls, "getString", "(Ljava/lang/String;)Ljava/lang/String;"); 72 | getObject = env->GetMethodID(cls, "getObject", "(Ljava/lang/String;)[B"); 73 | getBuffer = env->GetMethodID(cls, "getBuffer", "(Ljava/lang/String;)[B"); 74 | } 75 | jclass cls; 76 | jmethodID getString; 77 | jmethodID getObject; 78 | jmethodID getBuffer; 79 | }; 80 | 81 | inline JNIEnv* GetJNIEnv(openrasp_v8::Isolate* isolate) { 82 | return reinterpret_cast(isolate->GetData()->custom_data); 83 | } 84 | 85 | namespace isolate_pool { 86 | extern size_t size; 87 | extern std::shared_ptr GetIsolate(); 88 | } // namespace isolate_pool 89 | 90 | class PerThreadRuntime { 91 | public: 92 | ~PerThreadRuntime() { Dispose(); } 93 | openrasp_v8::Isolate* GetIsolate() { 94 | if (!snapshot) { 95 | return nullptr; 96 | } 97 | if (!isolate || isolate->IsDead() || isolate->IsExpired(snapshot->timestamp)) { 98 | Dispose(); 99 | isolate = isolate_pool::GetIsolate(); 100 | } 101 | return isolate.get(); 102 | } 103 | void Dispose() { 104 | request_context.Reset(); 105 | isolate.reset(); 106 | } 107 | std::shared_ptr isolate; 108 | v8::Persistent request_context; 109 | }; 110 | 111 | class ExternalOneByteStringResource : public v8::String::ExternalOneByteStringResource { 112 | public: 113 | ExternalOneByteStringResource(JNIEnv* env, jbyteArray jbuf, jsize jbuf_size = 0) { 114 | if (jbuf == nullptr) { 115 | return; 116 | } 117 | if (jbuf_size == 0) { 118 | jbuf_size = env->GetArrayLength(jbuf); 119 | } 120 | if (jbuf_size < 0) { 121 | return; 122 | } 123 | if (jbuf_size > openrasp_v8::max_buffer_size) { 124 | jbuf_size = openrasp_v8::max_buffer_size; 125 | } 126 | buf = new char[jbuf_size]; 127 | if (buf == nullptr) { 128 | return; 129 | } 130 | env->GetByteArrayRegion(jbuf, 0, jbuf_size, reinterpret_cast(buf)); 131 | size = strnlen(buf, jbuf_size); 132 | }; 133 | ~ExternalOneByteStringResource() override { delete[] buf; } 134 | const char* data() const override { return buf; } 135 | size_t length() const override { return size; } 136 | 137 | private: 138 | size_t size = 0; 139 | char* buf = nullptr; 140 | }; 141 | 142 | extern JavaVM* jvm; 143 | extern V8Class v8_class; 144 | extern ContextClass ctx_class; 145 | extern bool is_initialized; 146 | extern thread_local PerThreadRuntime per_thread_runtime; 147 | -------------------------------------------------------------------------------- /java/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | com.baidu.openrasp 4 | v8 5 | 1.0-SNAPSHOT 6 | 7 | 8 | junit 9 | junit 10 | 4.12 11 | test 12 | 13 | 14 | com.jsoniter 15 | jsoniter 16 | 0.9.23 17 | test 18 | 19 | 20 | 21 | 1.6 22 | 1.6 23 | UTF-8 24 | UTF-8 25 | 26 | -------------------------------------------------------------------------------- /java/pool.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2019 Baidu Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include "header.h" 22 | 23 | namespace isolate_pool { 24 | 25 | class IsolateDeleter { 26 | public: 27 | ALIGN_FUNCTION void operator()(openrasp_v8::Isolate* isolate) { isolate->Dispose(); } 28 | }; 29 | 30 | size_t size = 1; 31 | static std::list> isolates; 32 | 33 | std::shared_ptr GetIsolate() { 34 | std::lock_guard lock1(snapshot_mtx); 35 | isolates.remove_if([](std::weak_ptr ptr) { 36 | auto p = ptr.lock(); 37 | return !p || p->IsDead() || p->IsExpired(snapshot->timestamp); 38 | }); 39 | isolates.sort([](std::weak_ptr p1, std::weak_ptr p2) { 40 | return p1.use_count() < p2.use_count(); 41 | }); 42 | 43 | if (isolates.size() >= size) { 44 | auto p = isolates.front().lock(); 45 | if (p) { 46 | return p; 47 | } 48 | } 49 | 50 | auto duration = std::chrono::system_clock::now().time_since_epoch(); 51 | auto millis = std::chrono::duration_cast(duration).count(); 52 | auto isolate = openrasp_v8::Isolate::New(snapshot, millis); 53 | v8::Locker lock2(isolate); 54 | v8::Isolate::Scope isolate_scope(isolate); 55 | v8::HandleScope handle_scope(isolate); 56 | isolate->Initialize(); 57 | isolate->GetData()->request_context_templ.Reset(isolate, CreateRequestContextTemplate(isolate)); 58 | 59 | std::shared_ptr ptr(isolate, IsolateDeleter()); 60 | isolates.push_front(ptr); 61 | 62 | return ptr; 63 | } 64 | } // namespace isolate_pool -------------------------------------------------------------------------------- /java/src/main/java/com/baidu/openrasp/nativelib/DefaultJniExtractor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * #%L 3 | * Native library loader for extracting and loading native libraries from Java. 4 | * %% 5 | * Copyright (C) 2010 - 2015 Board of Regents of the University of 6 | * Wisconsin-Madison and Glencoe Software, Inc. 7 | * %% 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions are met: 10 | * 11 | * 1. Redistributions of source code must retain the above copyright notice, 12 | * this list of conditions and the following disclaimer. 13 | * 2. Redistributions in binary form must reproduce the above copyright notice, 14 | * this list of conditions and the following disclaimer in the documentation 15 | * and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE 21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | * POSSIBILITY OF SUCH DAMAGE. 28 | * #L% 29 | */ 30 | 31 | // This code is derived from Richard van der Hoff's mx-native-loader project: 32 | // http://opensource.mxtelecom.com/maven/repo/com/wapmx/native/mx-native-loader/1.7/ 33 | // See NOTICE.txt for details. 34 | 35 | // Copyright 2009 MX Telecom Ltd 36 | 37 | package com.baidu.openrasp.nativelib; 38 | 39 | import java.io.File; 40 | import java.io.IOException; 41 | 42 | /** 43 | * JniExtractor suitable for single application deployments per virtual machine 44 | *

45 | * WARNING: This extractor can result in UnsatisifiedLinkError if it is used in 46 | * more than one classloader. 47 | * 48 | * @author Richard van der Hoff (richardv@mxtelecom.com) 49 | */ 50 | public class DefaultJniExtractor extends BaseJniExtractor { 51 | 52 | /** 53 | * this is where native dependencies are extracted to (e.g. tmplib/). 54 | */ 55 | private File nativeDir; 56 | 57 | public DefaultJniExtractor(final Class libraryJarClass) throws IOException { 58 | super(libraryJarClass); 59 | 60 | nativeDir = getTempDir(); 61 | // Order of operations is such that we do not error if we are racing with 62 | // another thread to create the directory. 63 | nativeDir.mkdirs(); 64 | if (!nativeDir.isDirectory()) { 65 | throw new IOException("Unable to create native library working directory " + nativeDir); 66 | } 67 | nativeDir.deleteOnExit(); 68 | } 69 | 70 | @Override 71 | public File getJniDir() { 72 | return nativeDir; 73 | } 74 | 75 | @Override 76 | public File getNativeDir() { 77 | return nativeDir; 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /java/src/main/java/com/baidu/openrasp/nativelib/JniExtractor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * #%L 3 | * Native library loader for extracting and loading native libraries from Java. 4 | * %% 5 | * Copyright (C) 2010 - 2015 Board of Regents of the University of 6 | * Wisconsin-Madison and Glencoe Software, Inc. 7 | * %% 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions are met: 10 | * 11 | * 1. Redistributions of source code must retain the above copyright notice, 12 | * this list of conditions and the following disclaimer. 13 | * 2. Redistributions in binary form must reproduce the above copyright notice, 14 | * this list of conditions and the following disclaimer in the documentation 15 | * and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE 21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | * POSSIBILITY OF SUCH DAMAGE. 28 | * #L% 29 | */ 30 | 31 | // This code is derived from Richard van der Hoff's mx-native-loader project: 32 | // http://opensource.mxtelecom.com/maven/repo/com/wapmx/native/mx-native-loader/1.7/ 33 | // See NOTICE.txt for details. 34 | 35 | // Copyright 2006 MX Telecom Ltd 36 | 37 | package com.baidu.openrasp.nativelib; 38 | 39 | import java.io.File; 40 | import java.io.IOException; 41 | 42 | /** 43 | * @author Richard van der Hoff (richardv@mxtelecom.com) 44 | */ 45 | public interface JniExtractor { 46 | 47 | /** 48 | * Extract a JNI library from the classpath to a temporary file. 49 | * 50 | * @param libPath library path 51 | * @param libname System.loadLibrary() compatible library name 52 | * @return the extracted file 53 | * @throws IOException when extracting the desired file failed 54 | */ 55 | public File extractJni(String libPath, String libname) throws IOException, ClassNotFoundException, NoSuchFieldException, IllegalAccessException; 56 | 57 | /** 58 | * Extract all libraries which are registered for auto-extraction to files in 59 | * the temporary directory. 60 | * 61 | * @throws IOException when extracting the desired file failed 62 | */ 63 | public void extractRegistered() throws IOException; 64 | } 65 | -------------------------------------------------------------------------------- /java/src/main/java/com/baidu/openrasp/nativelib/MxSysInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * #%L 3 | * Native library loader for extracting and loading native libraries from Java. 4 | * %% 5 | * Copyright (C) 2010 - 2015 Board of Regents of the University of 6 | * Wisconsin-Madison and Glencoe Software, Inc. 7 | * %% 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions are met: 10 | * 11 | * 1. Redistributions of source code must retain the above copyright notice, 12 | * this list of conditions and the following disclaimer. 13 | * 2. Redistributions in binary form must reproduce the above copyright notice, 14 | * this list of conditions and the following disclaimer in the documentation 15 | * and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE 21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | * POSSIBILITY OF SUCH DAMAGE. 28 | * #L% 29 | */ 30 | 31 | package com.baidu.openrasp.nativelib; 32 | 33 | import java.io.File; 34 | import java.io.IOException; 35 | import java.util.regex.Matcher; 36 | import java.util.regex.Pattern; 37 | 38 | public class MxSysInfo { 39 | 40 | /** 41 | * Find the mx.sysinfo string for the current jvm 42 | *

43 | * Can be overridden by specifying a mx.sysinfo system property 44 | * 45 | * @return the specified mx.sysinfo or a guessed one 46 | */ 47 | public static String getMxSysInfo() { 48 | final String mxSysInfo = System.getProperty("mx.sysinfo"); 49 | return mxSysInfo != null ? mxSysInfo : guessMxSysInfo(); 50 | } 51 | 52 | /** 53 | * Make a spirited attempt at guessing what the mx.sysinfo for the current jvm 54 | * might be. 55 | * 56 | * @return the guessed mx.sysinfo 57 | */ 58 | public static String guessMxSysInfo() { 59 | final String arch = System.getProperty("os.arch"); 60 | final String os = System.getProperty("os.name"); 61 | String extra = "unknown"; 62 | 63 | if ("Linux".equals(os)) { 64 | try { 65 | final String libc_dest = new File("/lib/libc.so.6").getCanonicalPath(); 66 | final Matcher libc_m = Pattern.compile(".*/libc-(\\d+)\\.(\\d+)\\..*").matcher(libc_dest); 67 | if (!libc_m.matches()) 68 | throw new IOException("libc symlink contains unexpected destination: " + libc_dest); 69 | 70 | File libstdcxx_file = new File("/usr/lib/libstdc++.so.6"); 71 | if (!libstdcxx_file.exists()) 72 | libstdcxx_file = new File("/usr/lib/libstdc++.so.5"); 73 | 74 | final String libstdcxx_dest = libstdcxx_file.getCanonicalPath(); 75 | final Matcher libstdcxx_m = Pattern.compile(".*/libstdc\\+\\+\\.so\\.(\\d+)\\.0\\.(\\d+)") 76 | .matcher(libstdcxx_dest); 77 | if (!libstdcxx_m.matches()) 78 | throw new IOException("libstdc++ symlink contains unexpected destination: " + libstdcxx_dest); 79 | String cxxver; 80 | if ("5".equals(libstdcxx_m.group(1))) { 81 | cxxver = "5"; 82 | } else if ("6".equals(libstdcxx_m.group(1))) { 83 | final int minor_ver = Integer.parseInt(libstdcxx_m.group(2)); 84 | if (minor_ver < 9) { 85 | cxxver = "6"; 86 | } else { 87 | cxxver = "6" + libstdcxx_m.group(2); 88 | } 89 | } else { 90 | cxxver = libstdcxx_m.group(1) + libstdcxx_m.group(2); 91 | } 92 | 93 | extra = "c" + libc_m.group(1) + libc_m.group(2) + "cxx" + cxxver; 94 | } catch (final IOException e) { 95 | extra = "unknown"; 96 | } 97 | } 98 | 99 | return arch + "-" + os + "-" + extra; 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /java/src/main/java/com/baidu/openrasp/nativelib/WebappJniExtractor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * #%L 3 | * Native library loader for extracting and loading native libraries from Java. 4 | * %% 5 | * Copyright (C) 2010 - 2015 Board of Regents of the University of 6 | * Wisconsin-Madison and Glencoe Software, Inc. 7 | * %% 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions are met: 10 | * 11 | * 1. Redistributions of source code must retain the above copyright notice, 12 | * this list of conditions and the following disclaimer. 13 | * 2. Redistributions in binary form must reproduce the above copyright notice, 14 | * this list of conditions and the following disclaimer in the documentation 15 | * and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE 21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | * POSSIBILITY OF SUCH DAMAGE. 28 | * #L% 29 | */ 30 | 31 | // This code is derived from Richard van der Hoff's mx-native-loader project: 32 | // http://opensource.mxtelecom.com/maven/repo/com/wapmx/native/mx-native-loader/1.7/ 33 | // See NOTICE.txt for details. 34 | 35 | // Copyright 2009 MX Telecom Ltd 36 | 37 | package com.baidu.openrasp.nativelib; 38 | 39 | import java.io.File; 40 | import java.io.IOException; 41 | 42 | /** 43 | * JniExtractor suitable for multiple application deployments on the same 44 | * virtual machine (such as webapps) 45 | *

46 | * Designed to avoid the restriction that jni library can be loaded by at most 47 | * one classloader at a time. 48 | *

49 | * Works by extracting each library to a different location for each 50 | * classloader. 51 | *

52 | * WARNING: This can expose strange and wonderful bugs in jni code. These bugs 53 | * generally stem from transitive dependencies of the jni library and can be 54 | * solved by linking these dependencies statically to form a single library 55 | * 56 | * @author markjh 57 | */ 58 | public class WebappJniExtractor extends BaseJniExtractor { 59 | 60 | private final File nativeDir; 61 | private final File jniSubDir; 62 | 63 | /** 64 | * @param classloaderName is a friendly name for your classloader which will be 65 | * embedded in the directory name of the 66 | * classloader-specific subdirectory which will be 67 | * created. 68 | */ 69 | public WebappJniExtractor(final String classloaderName) throws IOException { 70 | nativeDir = getTempDir(); 71 | // Order of operations is such thatwe do not error if we are racing with 72 | // another thread to create the directory. 73 | nativeDir.mkdirs(); 74 | if (!nativeDir.isDirectory()) { 75 | throw new IOException("Unable to create native library working directory " + nativeDir); 76 | } 77 | 78 | final long now = System.currentTimeMillis(); 79 | File trialJniSubDir; 80 | int attempt = 0; 81 | while (true) { 82 | trialJniSubDir = new File(nativeDir, classloaderName + "." + now + "." + attempt); 83 | if (trialJniSubDir.mkdir()) 84 | break; 85 | if (trialJniSubDir.exists()) { 86 | attempt++; 87 | continue; 88 | } 89 | throw new IOException("Unable to create native library working directory " + trialJniSubDir); 90 | } 91 | jniSubDir = trialJniSubDir; 92 | jniSubDir.deleteOnExit(); 93 | } 94 | 95 | @Override 96 | protected void finalize() throws Throwable { 97 | super.finalize(); 98 | final File[] files = jniSubDir.listFiles(); 99 | for (final File file : files) { 100 | file.delete(); 101 | } 102 | jniSubDir.delete(); 103 | } 104 | 105 | @Override 106 | public File getJniDir() { 107 | return jniSubDir; 108 | } 109 | 110 | @Override 111 | public File getNativeDir() { 112 | return nativeDir; 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /java/src/main/java/com/baidu/openrasp/v8/ByteArrayOutputStream.java: -------------------------------------------------------------------------------- 1 | package com.baidu.openrasp.v8; 2 | 3 | /** 4 | * This class implements an output stream in which the data is written into a 5 | * byte array. The buffer automatically grows as data is written to it. The data 6 | * can be retrieved using toByteArray() and 7 | * toString(). 8 | *

9 | * Closing a ByteArrayOutputStream has no effect. The methods in this 10 | * class can be called after the stream has been closed without generating an 11 | * IOException. 12 | * 13 | * @author Arthur van Hoff 14 | * @since JDK1.0 15 | */ 16 | 17 | public class ByteArrayOutputStream extends java.io.ByteArrayOutputStream { 18 | /** 19 | * Retuen the underlying byte array buffer. 20 | * 21 | * @return the current contents of this output stream, as a byte array. 22 | * @see java.io.ByteArrayOutputStream#size() 23 | */ 24 | public byte getByteArray()[] { 25 | return buf; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /java/src/main/java/com/baidu/openrasp/v8/Context.java: -------------------------------------------------------------------------------- 1 | package com.baidu.openrasp.v8; 2 | 3 | public abstract class Context { 4 | 5 | public synchronized static native void setStringKeys(String[] keys); 6 | 7 | public synchronized static native void setObjectKeys(String[] keys); 8 | 9 | public synchronized static native void setBufferKeys(String[] keys); 10 | 11 | public abstract String getString(String key); 12 | 13 | public abstract byte[] getObject(String key); 14 | 15 | public abstract byte[] getBuffer(String key); 16 | 17 | } -------------------------------------------------------------------------------- /java/src/main/java/com/baidu/openrasp/v8/CrashReporter.java: -------------------------------------------------------------------------------- 1 | package com.baidu.openrasp.v8; 2 | 3 | public class CrashReporter { 4 | public synchronized static native void install(String url, String appid, String appSecret, String raspid); 5 | } 6 | -------------------------------------------------------------------------------- /java/src/main/java/com/baidu/openrasp/v8/Loader.java: -------------------------------------------------------------------------------- 1 | package com.baidu.openrasp.v8; 2 | 3 | import com.baidu.openrasp.nativelib.NativeLoader; 4 | 5 | public class Loader { 6 | private static boolean isLoad = false; 7 | 8 | public synchronized static void load() throws Exception { 9 | if (isLoad) { 10 | return; 11 | } 12 | NativeLoader.loadLibrary("openrasp_v8_java"); 13 | isLoad = true; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /java/src/main/java/com/baidu/openrasp/v8/Logger.java: -------------------------------------------------------------------------------- 1 | package com.baidu.openrasp.v8; 2 | 3 | public interface Logger { 4 | public void log(String msg); 5 | } -------------------------------------------------------------------------------- /java/src/main/java/com/baidu/openrasp/v8/StackGetter.java: -------------------------------------------------------------------------------- 1 | package com.baidu.openrasp.v8; 2 | 3 | public interface StackGetter { 4 | public byte[] get(); 5 | } -------------------------------------------------------------------------------- /java/src/main/java/com/baidu/openrasp/v8/V8.java: -------------------------------------------------------------------------------- 1 | package com.baidu.openrasp.v8; 2 | 3 | import com.baidu.openrasp.nativelib.NativeLoader; 4 | 5 | public class V8 { 6 | 7 | private static Logger logger = null; 8 | 9 | private static StackGetter stackGetter = null; 10 | 11 | private static boolean isLoad = false; 12 | 13 | public synchronized static native boolean Initialize(int isolate_pool_size, int request_pool_size, 14 | int request_queue_size); 15 | 16 | public synchronized static native boolean Dispose(); 17 | 18 | public synchronized static native boolean CreateSnapshot(String config, Object[] plugins, String version); 19 | 20 | public static native byte[] Check(String type, byte[] params, int params_size, Context context, int timeout); 21 | 22 | public static native String ExecuteScript(String source, String filename) throws Exception; 23 | 24 | @Deprecated 25 | public synchronized static void Load() throws Exception { 26 | if (isLoad) { 27 | return; 28 | } 29 | NativeLoader.loadLibrary("openrasp_v8_java"); 30 | isLoad = true; 31 | } 32 | 33 | public synchronized static boolean Initialize() { 34 | return Initialize(Runtime.getRuntime().availableProcessors(), 4, 1000); 35 | } 36 | 37 | @Deprecated 38 | public static byte[] Check(String type, byte[] params, int params_size, Context context, boolean new_request, 39 | int timeout) { 40 | return Check(type, params, params_size, context, timeout); 41 | } 42 | 43 | public static void Log(String msg) { 44 | if (logger != null) { 45 | logger.log(msg.replaceAll("\n$", "")); 46 | } 47 | } 48 | 49 | public static void SetLogger(Logger logger) { 50 | V8.logger = logger; 51 | } 52 | 53 | public static byte[] GetStack() { 54 | return stackGetter != null ? stackGetter.get() : null; 55 | } 56 | 57 | public static void SetStackGetter(StackGetter stackGetter) { 58 | V8.stackGetter = stackGetter; 59 | } 60 | 61 | public static long GetFreeMemory() { 62 | return Runtime.getRuntime().freeMemory(); 63 | } 64 | 65 | public static void Gc() { 66 | System.gc(); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /java/src/main/resources/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu-security/openrasp-v8/4e1398d9e3de81a581c8f465b117abb8399a014d/java/src/main/resources/.gitkeep -------------------------------------------------------------------------------- /java/src/test/java/com/baidu/openrasp/v8/ContextImpl.java: -------------------------------------------------------------------------------- 1 | package com.baidu.openrasp.v8; 2 | 3 | import java.util.*; 4 | import com.jsoniter.output.JsonStream; 5 | 6 | public class ContextImpl extends Context { 7 | 8 | public String getString(String key) { 9 | if (key.equals("path")) 10 | return getPath(); 11 | if (key.equals("method")) 12 | return getMethod(); 13 | if (key.equals("url")) 14 | return getUrl(); 15 | if (key.equals("querystring")) 16 | return getQuerystring(); 17 | if (key.equals("appBasePath")) 18 | return getAppBasePath(); 19 | if (key.equals("protocol")) 20 | return getProtocol(); 21 | if (key.equals("remoteAddr")) 22 | return getRemoteAddr(); 23 | if (key.equals("requestId")) 24 | return getRequestId(); 25 | return ""; 26 | } 27 | 28 | public byte[] getObject(String key) { 29 | if (key.equals("json")) 30 | return getJson(); 31 | if (key.equals("header")) 32 | return getHeader(); 33 | if (key.equals("parameter")) 34 | return getParameter(); 35 | if (key.equals("server")) 36 | return getServer(); 37 | return "{}".getBytes(); 38 | } 39 | 40 | public byte[] getBuffer(String key) { 41 | if (key.equals("body")) 42 | return getBody(); 43 | return "{}".getBytes(); 44 | } 45 | 46 | public String getPath() { 47 | return "test 中文 & 😊"; 48 | } 49 | 50 | public String getMethod() { 51 | return "test 中文 & 😊"; 52 | } 53 | 54 | public String getUrl() { 55 | return "test 中文 & 😊"; 56 | } 57 | 58 | public String getQuerystring() { 59 | return "test 中文 & 😊"; 60 | } 61 | 62 | public String getAppBasePath() { 63 | return "test 中文 & 😊"; 64 | } 65 | 66 | public String getProtocol() { 67 | return "test 中文 & 😊"; 68 | } 69 | 70 | public String getRemoteAddr() { 71 | return "test 中文 & 😊"; 72 | } 73 | 74 | public String getRequestId() { 75 | return ""; 76 | } 77 | 78 | public byte[] getBody() { 79 | ByteArrayOutputStream data = new ByteArrayOutputStream(); 80 | data.write((byte) 0); 81 | data.write((byte) 1); 82 | data.write((byte) 2); 83 | data.write((byte) 3); 84 | return data.toByteArray(); 85 | } 86 | 87 | public byte[] getJson() { 88 | List list = new ArrayList(); 89 | list.add("test 中文 & 😊"); 90 | ByteArrayOutputStream data = new ByteArrayOutputStream(); 91 | JsonStream.serialize(list, data); 92 | data.write(0); 93 | return data.getByteArray(); 94 | } 95 | 96 | public byte[] getHeader() { 97 | List list = new ArrayList(); 98 | list.add("test 中文 & 😊"); 99 | ByteArrayOutputStream data = new ByteArrayOutputStream(); 100 | JsonStream.serialize(list, data); 101 | data.write(0); 102 | return data.getByteArray(); 103 | } 104 | 105 | public byte[] getParameter() { 106 | List list = new ArrayList(); 107 | list.add("test 中文 & 😊"); 108 | ByteArrayOutputStream data = new ByteArrayOutputStream(); 109 | JsonStream.serialize(list, data); 110 | data.write(0); 111 | return data.getByteArray(); 112 | } 113 | 114 | public byte[] getServer() { 115 | List list = new ArrayList(); 116 | list.add("test 中文 & 😊"); 117 | ByteArrayOutputStream data = new ByteArrayOutputStream(); 118 | JsonStream.serialize(list, data); 119 | data.write(0); 120 | return data.getByteArray(); 121 | } 122 | 123 | } -------------------------------------------------------------------------------- /java/utils.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2019 Baidu Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #include 17 | #include 18 | #include 19 | 20 | #include "header.h" 21 | 22 | using namespace openrasp_v8; 23 | 24 | JavaVM* jvm = nullptr; 25 | V8Class v8_class; 26 | ContextClass ctx_class; 27 | bool is_initialized = false; 28 | Snapshot* snapshot = nullptr; 29 | std::mutex snapshot_mtx; 30 | thread_local PerThreadRuntime per_thread_runtime; 31 | 32 | void plugin_log(JNIEnv* env, const std::string& message) { 33 | auto msg = String2Jstring(env, message); 34 | env->CallStaticVoidMethod(v8_class.cls, v8_class.Log, msg); 35 | } 36 | 37 | void plugin_log(const std::string& message) { 38 | JNIEnv* env; 39 | auto rst = jvm->GetEnv((void**)&env, JNI_VERSION_1_6); 40 | if (rst == JNI_ERR) { 41 | printf("%s", message.c_str()); 42 | return; 43 | } 44 | if (rst == JNI_EDETACHED) { 45 | jvm->AttachCurrentThread((void**)&env, nullptr); 46 | } 47 | plugin_log(env, message); 48 | if (rst == JNI_EDETACHED) { 49 | jvm->DetachCurrentThread(); 50 | } 51 | } 52 | 53 | void GetStack(v8::Local name, const v8::PropertyCallbackInfo& info) { 54 | auto isolate = reinterpret_cast(info.GetIsolate()); 55 | auto env = GetJNIEnv(isolate); 56 | jbyteArray jbuf = reinterpret_cast(env->CallStaticObjectMethod(v8_class.cls, v8_class.GetStack)); 57 | if (jbuf == nullptr) { 58 | return info.GetReturnValue().Set(v8::Array::New(isolate)); 59 | } 60 | auto maybe_string = v8::String::NewExternalOneByte(isolate, new ExternalOneByteStringResource(env, jbuf)); 61 | if (maybe_string.IsEmpty()) { 62 | return info.GetReturnValue().Set(v8::Array::New(isolate)); 63 | } 64 | auto maybe_value = v8::JSON::Parse(isolate->GetCurrentContext(), maybe_string.ToLocalChecked()); 65 | if (maybe_value.IsEmpty()) { 66 | return info.GetReturnValue().Set(v8::Array::New(isolate)); 67 | } 68 | auto value = maybe_value.ToLocalChecked(); 69 | info.GetReturnValue().Set(value); 70 | } 71 | 72 | std::string Jstring2String(JNIEnv* env, jstring str) { 73 | try { 74 | auto size = env->GetStringLength(str); 75 | if (size < 0) { 76 | return {}; 77 | } 78 | if (size > max_buffer_size) { 79 | size = max_buffer_size; 80 | } 81 | std::vector u16(size); 82 | env->GetStringRegion(str, 0, size, reinterpret_cast(u16.data())); 83 | #ifdef _WIN32 84 | return std::wstring_convert, wchar_t>{}.to_bytes( 85 | std::wstring(u16.begin(), u16.end())); 86 | #else 87 | return std::wstring_convert, char16_t>{}.to_bytes(u16.data(), u16.data() + size); 88 | #endif 89 | } catch (std::exception& exception) { 90 | std::string s; 91 | auto utf = env->GetStringUTFChars(str, nullptr); 92 | auto size = env->GetStringUTFLength(str); 93 | if (utf && size > 0) { 94 | s = std::string(utf, size < max_buffer_size ? size : max_buffer_size); 95 | } 96 | env->ReleaseStringUTFChars(str, utf); 97 | return s; 98 | } 99 | } 100 | 101 | jstring String2Jstring(JNIEnv* env, const std::string& str) { 102 | try { 103 | #ifdef _WIN32 104 | std::wstring ws = std::wstring_convert, wchar_t>{}.from_bytes(str); 105 | std::u16string u16(ws.begin(), ws.end()); 106 | #else 107 | std::u16string u16 = std::wstring_convert, char16_t>{}.from_bytes(str); 108 | #endif 109 | return env->NewString(reinterpret_cast(u16.data()), u16.size()); 110 | } catch (std::exception& exception) { 111 | return env->NewStringUTF(str.data()); 112 | } 113 | } 114 | 115 | v8::MaybeLocal Jstring2V8string(JNIEnv* env, jstring jstr) { 116 | auto size = env->GetStringLength(jstr); 117 | if (size < 0) { 118 | return {}; 119 | } 120 | if (size > max_buffer_size) { 121 | size = max_buffer_size; 122 | } 123 | std::vector u16(size); 124 | env->GetStringRegion(jstr, 0, size, u16.data()); 125 | return v8::String::NewFromTwoByte(v8::Isolate::GetCurrent(), u16.data(), v8::NewStringType::kNormal, size); 126 | } 127 | 128 | jstring V8value2Jstring(JNIEnv* env, v8::Local val) { 129 | v8::String::Value str(v8::Isolate::GetCurrent(), val); 130 | return env->NewString(*str, str.length()); 131 | } -------------------------------------------------------------------------------- /php/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.12.0) 2 | 3 | project(php LANGUAGES CXX) 4 | 5 | add_library(openrasp_v8_php STATIC) 6 | add_dependencies(openrasp_v8_php base prebuilts) 7 | target_link_libraries(openrasp_v8_php PUBLIC base prebuilts) 8 | 9 | add_custom_command(TARGET openrasp_v8_php POST_BUILD 10 | COMMAND ${CMAKE_COMMAND} 11 | -DOPENRASP_V8_PATH=${CMAKE_CURRENT_BINARY_DIR} 12 | -DINCLUDE_DIRECTORIES="$" 13 | -DLINK_LIBRARIES="$" 14 | -DCOMPILE_OPTIONS="$" 15 | -DTARGET_FILE="$" 16 | -P ${CMAKE_CURRENT_SOURCE_DIR}/PkgConfig.cmake) -------------------------------------------------------------------------------- /php/PkgConfig.cmake: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.12.0) 2 | 3 | list(TRANSFORM INCLUDE_DIRECTORIES PREPEND "-I") 4 | list(JOIN INCLUDE_DIRECTORIES " " CFLAGS) 5 | set(CFLAGS "${COMPILE_OPTIONS} ${CFLAGS}") 6 | 7 | list(APPEND LINK_LIBRARIES ${TARGET_FILE}) 8 | list(JOIN LINK_LIBRARIES " " LIBS) 9 | 10 | set(PREFIX ${CMAKE_CURRENT_LIST_DIR}) 11 | configure_file(${PREFIX}/openrasp-v8.pc.in ${PREFIX}/openrasp-v8.pc) 12 | -------------------------------------------------------------------------------- /php/header.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017-2019 Baidu Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include "base/bundle.h" 20 | 21 | namespace openrasp { 22 | using openrasp_v8::Initialize; 23 | using openrasp_v8::NewV8String; 24 | using openrasp_v8::Platform; 25 | using openrasp_v8::PluginFile; 26 | using openrasp_v8::Snapshot; 27 | class Isolate : public openrasp_v8::Isolate { 28 | public: 29 | static Isolate* New(Snapshot* snapshot_blob, uint64_t timestamp) { 30 | auto isolate = reinterpret_cast(openrasp_v8::Isolate::New(snapshot_blob, timestamp)); 31 | isolate->Enter(); 32 | v8::HandleScope handle_scope(isolate); 33 | isolate->Initialize(); 34 | isolate->GetData()->context.Get(isolate)->Enter(); 35 | return isolate; 36 | } 37 | void Dispose() { 38 | Exit(); 39 | openrasp_v8::Isolate::Dispose(); 40 | } 41 | }; 42 | } -------------------------------------------------------------------------------- /php/openrasp-v8.pc.in: -------------------------------------------------------------------------------- 1 | Name: openrasp-v8 2 | Description: openrasp-v8 3 | Version: x 4 | Cflags: ${CFLAGS} 5 | Libs: ${LIBS} -------------------------------------------------------------------------------- /prebuilts/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.0.0) 2 | 3 | project(prebuilts LANGUAGES CXX) 4 | 5 | include(${CMAKE_CURRENT_SOURCE_DIR}/../vendors/cmake/detect_architecture.cmake) 6 | 7 | string(TOLOWER ${CMAKE_SYSTEM_NAME} SYSTEM_NAME) 8 | if (${SYSTEM_NAME} STREQUAL "linux") 9 | execute_process(COMMAND bash "-c" "[ $OSTYPE = 'linux-musl' ]" RESULT_VARIABLE ret) 10 | if(ret EQUAL "0") 11 | set(SYSTEM_NAME "linux-musl") 12 | endif() 13 | endif() 14 | set(PREBUILTS_PREFIX ${CMAKE_CURRENT_SOURCE_DIR}/${SYSTEM_NAME}) 15 | set(PREBUILTS_PREFIX ${CMAKE_CURRENT_SOURCE_DIR}/${SYSTEM_NAME} PARENT_SCOPE) 16 | 17 | if(ARCH64) 18 | set(LIBS_PREFIX ${PREBUILTS_PREFIX}/lib64) 19 | else() 20 | set(LIBS_PREFIX ${PREBUILTS_PREFIX}/lib32) 21 | endif() 22 | 23 | if(NOT ${SYSTEM_NAME} STREQUAL "windows") 24 | message(STATUS "Fetch prebuilts") 25 | execute_process(COMMAND bash "-c" "${CMAKE_CURRENT_SOURCE_DIR}/fetch_prebuilts.sh" WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/.. RESULT_VARIABLE ret) 26 | if(NOT ret EQUAL "0") 27 | message(FATAL_ERROR "Failed to to fetch prebuilts") 28 | endif() 29 | endif() 30 | 31 | if(ENABLE_IAST AND ${ENABLE_LANGUAGES} STREQUAL "php") 32 | message(STATUS "Fetch php7 static library") 33 | execute_process(COMMAND bash "-c" "${CMAKE_CURRENT_SOURCE_DIR}/fetch_php_staticlibs.sh" WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/.. RESULT_VARIABLE ret) 34 | if(NOT ret EQUAL "0") 35 | message(FATAL_ERROR "Failed to fetch php7 static library") 36 | endif() 37 | endif() 38 | 39 | file(REMOVE_RECURSE ${PREBUILTS_PREFIX}/include/cpr ${LIBS_PREFIX}/libcpr.a) 40 | 41 | add_library(prebuilts INTERFACE) 42 | target_include_directories(prebuilts INTERFACE ${PREBUILTS_PREFIX}/include) 43 | 44 | file(GLOB LIBS LIST_DIRECTORIES false ${LIBS_PREFIX}/*) 45 | 46 | if(${SYSTEM_NAME} STREQUAL "darwin" OR ${SYSTEM_NAME} STREQUAL "linux-musl") 47 | find_package(CURL) 48 | find_package(ZLIB) 49 | target_link_libraries(prebuilts INTERFACE CURL::libcurl ZLIB::ZLIB) 50 | target_link_libraries(prebuilts INTERFACE ${LIBS}) 51 | endif() 52 | 53 | if(${SYSTEM_NAME} STREQUAL "windows") 54 | target_compile_definitions(prebuilts INTERFACE CURL_STATICLIB) 55 | target_link_libraries(prebuilts INTERFACE ${LIBS}) 56 | target_link_libraries(prebuilts INTERFACE winmm.lib dbghelp.lib shlwapi.lib ws2_32.lib crypt32.lib) 57 | endif() 58 | 59 | if(${SYSTEM_NAME} STREQUAL "linux") 60 | target_include_directories(prebuilts INTERFACE ${PREBUILTS_PREFIX}/include/c++/v1) 61 | target_compile_options(prebuilts INTERFACE -nostdinc++) 62 | list(TRANSFORM LIBS PREPEND "-Wl,") 63 | target_link_libraries(prebuilts INTERFACE -Wl,--start-group ${LIBS} -Wl,--end-group) 64 | target_link_libraries(prebuilts INTERFACE -nodefaultlibs -lm -lc -lrt -lgcc_s -ldl -lpthread) 65 | endif() 66 | -------------------------------------------------------------------------------- /prebuilts/fetch_php_staticlibs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | ROOT=$(git rev-parse --show-toplevel || pwd) 6 | 7 | if [ $TRAVIS ]; then 8 | DIR=$HOME/cache 9 | mkdir -p $DIR 10 | else 11 | DIR=/tmp 12 | fi 13 | FILENAME="static-lib.tar.gz" 14 | curl -# -k -L -o $DIR/$FILENAME.download https://packages.baidu.com/app/openrasp/$FILENAME 15 | [[ -f $DIR/$FILENAME.download ]] && mv $DIR/$FILENAME.download $DIR/$FILENAME 16 | tar zxf $DIR/$FILENAME -C $ROOT/prebuilts/linux 17 | -------------------------------------------------------------------------------- /prebuilts/fetch_prebuilts.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | ROOT=$(git rev-parse --show-toplevel || pwd) 6 | 7 | if [ $TRAVIS ]; then 8 | DIR=$HOME/cache 9 | mkdir -p $DIR 10 | else 11 | DIR=/tmp 12 | fi 13 | 14 | if [[ "$OSTYPE" == "linux-gnu" ]]; then 15 | FILENAME="openrasp-v8-prebuilts-7.8-linux.tar.gz" 16 | elif [[ "$OSTYPE" == "darwin"* ]]; then 17 | FILENAME="openrasp-v8-prebuilts-7.8-darwin.tar.gz" 18 | elif [[ "$OSTYPE" == "msys" ]]; then 19 | FILENAME="openrasp-v8-prebuilts-7.8-windows.tar.gz" 20 | elif [[ "$OSTYPE" == "linux-musl" ]]; then 21 | FILENAME="openrasp-v8-prebuilts-7.8-linux-musl.tar.gz" 22 | else 23 | echo "Unsupported os type" 24 | exit 1 25 | fi 26 | 27 | curl -# -k -L -o $DIR/$FILENAME.download -z $DIR/$FILENAME https://packages.baidu.com/app/openrasp/v8/$FILENAME 28 | [[ -f $DIR/$FILENAME.download ]] && mv $DIR/$FILENAME.download $DIR/$FILENAME 29 | tar zxf $DIR/$FILENAME -C $ROOT/prebuilts 30 | -------------------------------------------------------------------------------- /scripts/linux32.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ev 4 | 5 | pushd `git rev-parse --show-toplevel` 6 | 7 | rm -rf build32 8 | 9 | mkdir -p build32 && pushd $_ 10 | 11 | (if [[ -d /tmp/centos6-sysroot ]]; then source /tmp/centos6-sysroot/setx86.sh; fi; cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DBUILD_TESTING=ON -DENABLE_LANGUAGES=all ..) 12 | 13 | make VERBOSE=1 -j 14 | 15 | ./base/tests -s 16 | 17 | ldd base/tests 18 | 19 | popd 20 | 21 | mkdir -p java/src/main/resources/natives/linux_32 && cp build32/java/libopenrasp_v8_java.so $_ 22 | 23 | # pushd java 24 | 25 | # mvn test -------------------------------------------------------------------------------- /scripts/linux64.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ev 4 | 5 | pushd `git rev-parse --show-toplevel` 6 | 7 | rm -rf build64 8 | 9 | mkdir -p build64 && pushd $_ 10 | 11 | (if [[ -d /tmp/centos6-sysroot ]]; then source /tmp/centos6-sysroot/setx64.sh; fi; cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DBUILD_TESTING=ON -DENABLE_LANGUAGES=all ..) 12 | 13 | make VERBOSE=1 -j 14 | 15 | ./base/tests -s 16 | 17 | ldd base/tests 18 | 19 | popd 20 | 21 | mkdir -p java/src/main/resources/natives/linux_64 && cp build64/java/libopenrasp_v8_java.so $_ 22 | 23 | pushd java 24 | 25 | mvn test -------------------------------------------------------------------------------- /scripts/linuxmusl64.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ev 4 | 5 | pushd `git rev-parse --show-toplevel` 6 | 7 | if [[ ! -f "/etc/alpine-release" ]]; then 8 | pushd vendors/alpine-env 9 | curl -# -k -L -z apache-maven-3.6.3-bin.tar.gz -O https://downloads.apache.org/maven/maven-3/3.6.3/binaries/apache-maven-3.6.3-bin.tar.gz 10 | curl -# -k -L -z cmake-3.17.1-Linux-musl.tar.gz -O https://packages.baidu.com/app/cmake-3.17.1-Linux-musl.tar.gz 11 | docker build -t openrasp-v8-alpine-env . 12 | popd 13 | docker run --rm -v `pwd`:/openrasp-v8 -w /openrasp-v8 openrasp-v8-alpine-env "/openrasp-v8/scripts/linuxmusl64.sh" 14 | exit 0 15 | fi 16 | 17 | rm -rf build64 18 | 19 | mkdir -p build64 && pushd $_ 20 | 21 | cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DBUILD_TESTING=ON -DENABLE_LANGUAGES=all .. 22 | 23 | make VERBOSE=1 -j 24 | 25 | ./base/tests -s 26 | 27 | ldd base/tests 28 | 29 | popd 30 | 31 | mkdir -p java/src/main/resources/natives/linux_musl64 && cp build64/java/libopenrasp_v8_java.so $_ 32 | 33 | pushd java 34 | 35 | mvn test -------------------------------------------------------------------------------- /scripts/osx64.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ev 4 | 5 | pushd `git rev-parse --show-toplevel` 6 | 7 | rm -rf build64 8 | 9 | mkdir -p build64 && pushd $_ 10 | 11 | cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DBUILD_TESTING=ON -DENABLE_LANGUAGES=all .. 12 | 13 | make VERBOSE=1 -j 14 | 15 | ./base/tests -s 16 | 17 | popd 18 | 19 | mkdir -p java/src/main/resources/natives/osx_64 && cp build64/java/libopenrasp_v8_java.dylib $_ 20 | 21 | pushd java 22 | 23 | mvn test 24 | -------------------------------------------------------------------------------- /scripts/windows32.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ev 4 | 5 | pushd `git rev-parse --show-toplevel` 6 | 7 | rm -rf build32 8 | 9 | mkdir -p build32 && pushd $_ 10 | 11 | cmake -DCMAKE_VERBOSE_MAKEFILE=ON -A Win32 -DBUILD_TESTING=ON -DENABLE_LANGUAGES=java .. 12 | 13 | cmake --build . --config RelWithDebInfo 14 | 15 | cmake --build . --config RelWithDebInfo --target RUN_TESTS 16 | 17 | file java/RelWithDebInfo/openrasp_v8_java.dll 18 | 19 | popd 20 | 21 | mkdir -p java/src/main/resources/natives/windows_32 && cp build32/java/RelWithDebInfo/openrasp_v8_java.dll $_ 22 | 23 | # pushd java 24 | 25 | # mvn test 26 | -------------------------------------------------------------------------------- /scripts/windows64.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ev 4 | 5 | pushd `git rev-parse --show-toplevel` 6 | 7 | rm -rf build64 8 | 9 | mkdir -p build64 && pushd $_ 10 | 11 | cmake -DCMAKE_VERBOSE_MAKEFILE=ON -A x64 -DBUILD_TESTING=ON -DENABLE_LANGUAGES=java .. 12 | 13 | cmake --build . --config RelWithDebInfo 14 | 15 | cmake --build . --config RelWithDebInfo --target RUN_TESTS 16 | 17 | file java/RelWithDebInfo/openrasp_v8_java.dll 18 | 19 | popd 20 | 21 | mkdir -p java/src/main/resources/natives/windows_64 && cp build64/java/RelWithDebInfo/openrasp_v8_java.dll $_ 22 | 23 | pushd java 24 | 25 | mvn test 26 | -------------------------------------------------------------------------------- /vendors/Catch2/include/catch2/catch_reporter_automake.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Created by Justin R. Wilson on 2/19/2017. 3 | * Copyright 2017 Justin R. Wilson. All rights reserved. 4 | * 5 | * Distributed under the Boost Software License, Version 1.0. (See accompanying 6 | * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 | */ 8 | #ifndef TWOBLUECUBES_CATCH_REPORTER_AUTOMAKE_HPP_INCLUDED 9 | #define TWOBLUECUBES_CATCH_REPORTER_AUTOMAKE_HPP_INCLUDED 10 | 11 | // Don't #include any Catch headers here - we can assume they are already 12 | // included before this header. 13 | // This is not good practice in general but is necessary in this case so this 14 | // file can be distributed as a single header that works with the main 15 | // Catch single header. 16 | 17 | namespace Catch { 18 | 19 | struct AutomakeReporter : StreamingReporterBase { 20 | AutomakeReporter( ReporterConfig const& _config ) 21 | : StreamingReporterBase( _config ) 22 | {} 23 | 24 | ~AutomakeReporter() override; 25 | 26 | static std::string getDescription() { 27 | return "Reports test results in the format of Automake .trs files"; 28 | } 29 | 30 | void assertionStarting( AssertionInfo const& ) override {} 31 | 32 | bool assertionEnded( AssertionStats const& /*_assertionStats*/ ) override { return true; } 33 | 34 | void testCaseEnded( TestCaseStats const& _testCaseStats ) override { 35 | // Possible values to emit are PASS, XFAIL, SKIP, FAIL, XPASS and ERROR. 36 | stream << ":test-result: "; 37 | if (_testCaseStats.totals.assertions.allPassed()) { 38 | stream << "PASS"; 39 | } else if (_testCaseStats.totals.assertions.allOk()) { 40 | stream << "XFAIL"; 41 | } else { 42 | stream << "FAIL"; 43 | } 44 | stream << ' ' << _testCaseStats.testInfo.name << '\n'; 45 | StreamingReporterBase::testCaseEnded( _testCaseStats ); 46 | } 47 | 48 | void skipTest( TestCaseInfo const& testInfo ) override { 49 | stream << ":test-result: SKIP " << testInfo.name << '\n'; 50 | } 51 | 52 | }; 53 | 54 | #ifdef CATCH_IMPL 55 | AutomakeReporter::~AutomakeReporter() {} 56 | #endif 57 | 58 | CATCH_REGISTER_REPORTER( "automake", AutomakeReporter) 59 | 60 | } // end namespace Catch 61 | 62 | #endif // TWOBLUECUBES_CATCH_REPORTER_AUTOMAKE_HPP_INCLUDED 63 | -------------------------------------------------------------------------------- /vendors/Catch2/lib/cmake/Catch2/Catch2Config.cmake: -------------------------------------------------------------------------------- 1 | 2 | ####### Expanded from @PACKAGE_INIT@ by configure_package_config_file() ####### 3 | ####### Any changes to this file will be overwritten by the next CMake run #### 4 | ####### The input file was Catch2Config.cmake.in ######## 5 | 6 | get_filename_component(PACKAGE_PREFIX_DIR "${CMAKE_CURRENT_LIST_DIR}/../../../" ABSOLUTE) 7 | 8 | macro(set_and_check _var _file) 9 | set(${_var} "${_file}") 10 | if(NOT EXISTS "${_file}") 11 | message(FATAL_ERROR "File or directory ${_file} referenced by variable ${_var} does not exist !") 12 | endif() 13 | endmacro() 14 | 15 | macro(check_required_components _NAME) 16 | foreach(comp ${${_NAME}_FIND_COMPONENTS}) 17 | if(NOT ${_NAME}_${comp}_FOUND) 18 | if(${_NAME}_FIND_REQUIRED_${comp}) 19 | set(${_NAME}_FOUND FALSE) 20 | endif() 21 | endif() 22 | endforeach() 23 | endmacro() 24 | 25 | #################################################################################### 26 | 27 | 28 | # Avoid repeatedly including the targets 29 | if(NOT TARGET Catch2::Catch2) 30 | # Provide path for scripts 31 | list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}") 32 | 33 | include(${CMAKE_CURRENT_LIST_DIR}/Catch2Targets.cmake) 34 | endif() 35 | -------------------------------------------------------------------------------- /vendors/Catch2/lib/cmake/Catch2/Catch2ConfigVersion.cmake: -------------------------------------------------------------------------------- 1 | # This is a basic version file for the Config-mode of find_package(). 2 | # It is used by write_basic_package_version_file() as input file for configure_file() 3 | # to create a version-file which can be installed along a config.cmake file. 4 | # 5 | # The created file sets PACKAGE_VERSION_EXACT if the current version string and 6 | # the requested version string are exactly the same and it sets 7 | # PACKAGE_VERSION_COMPATIBLE if the current version is >= requested version, 8 | # but only if the requested major version is the same as the current one. 9 | # The variable CVF_VERSION must be set before calling configure_file(). 10 | 11 | 12 | set(PACKAGE_VERSION "2.6.1") 13 | 14 | if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION) 15 | set(PACKAGE_VERSION_COMPATIBLE FALSE) 16 | else() 17 | 18 | if("2.6.1" MATCHES "^([0-9]+)\\.") 19 | set(CVF_VERSION_MAJOR "${CMAKE_MATCH_1}") 20 | else() 21 | set(CVF_VERSION_MAJOR "2.6.1") 22 | endif() 23 | 24 | if(PACKAGE_FIND_VERSION_MAJOR STREQUAL CVF_VERSION_MAJOR) 25 | set(PACKAGE_VERSION_COMPATIBLE TRUE) 26 | else() 27 | set(PACKAGE_VERSION_COMPATIBLE FALSE) 28 | endif() 29 | 30 | if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION) 31 | set(PACKAGE_VERSION_EXACT TRUE) 32 | endif() 33 | endif() 34 | 35 | 36 | # if the installed or the using project don't have CMAKE_SIZEOF_VOID_P set, ignore it: 37 | if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "" OR "" STREQUAL "") 38 | return() 39 | endif() 40 | 41 | # check that the installed version has the same 32/64bit-ness as the one which is currently searching: 42 | if(NOT CMAKE_SIZEOF_VOID_P STREQUAL "") 43 | math(EXPR installedBits " * 8") 44 | set(PACKAGE_VERSION "${PACKAGE_VERSION} (${installedBits}bit)") 45 | set(PACKAGE_VERSION_UNSUITABLE TRUE) 46 | endif() 47 | -------------------------------------------------------------------------------- /vendors/Catch2/lib/cmake/Catch2/Catch2Targets.cmake: -------------------------------------------------------------------------------- 1 | # Generated by CMake 2 | 3 | if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" LESS 2.5) 4 | message(FATAL_ERROR "CMake >= 2.6.0 required") 5 | endif() 6 | cmake_policy(PUSH) 7 | cmake_policy(VERSION 2.6) 8 | #---------------------------------------------------------------- 9 | # Generated CMake target import file. 10 | #---------------------------------------------------------------- 11 | 12 | # Commands may need to know the format version. 13 | set(CMAKE_IMPORT_FILE_VERSION 1) 14 | 15 | # Protect against multiple inclusion, which would fail when already imported targets are added once more. 16 | set(_targetsDefined) 17 | set(_targetsNotDefined) 18 | set(_expectedTargets) 19 | foreach(_expectedTarget Catch2::Catch2) 20 | list(APPEND _expectedTargets ${_expectedTarget}) 21 | if(NOT TARGET ${_expectedTarget}) 22 | list(APPEND _targetsNotDefined ${_expectedTarget}) 23 | endif() 24 | if(TARGET ${_expectedTarget}) 25 | list(APPEND _targetsDefined ${_expectedTarget}) 26 | endif() 27 | endforeach() 28 | if("${_targetsDefined}" STREQUAL "${_expectedTargets}") 29 | unset(_targetsDefined) 30 | unset(_targetsNotDefined) 31 | unset(_expectedTargets) 32 | set(CMAKE_IMPORT_FILE_VERSION) 33 | cmake_policy(POP) 34 | return() 35 | endif() 36 | if(NOT "${_targetsDefined}" STREQUAL "") 37 | message(FATAL_ERROR "Some (but not all) targets in this export set were already defined.\nTargets Defined: ${_targetsDefined}\nTargets not yet defined: ${_targetsNotDefined}\n") 38 | endif() 39 | unset(_targetsDefined) 40 | unset(_targetsNotDefined) 41 | unset(_expectedTargets) 42 | 43 | 44 | # Compute the installation prefix relative to this file. 45 | get_filename_component(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH) 46 | get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH) 47 | get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH) 48 | get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH) 49 | if(_IMPORT_PREFIX STREQUAL "/") 50 | set(_IMPORT_PREFIX "") 51 | endif() 52 | 53 | # Create imported target Catch2::Catch2 54 | add_library(Catch2::Catch2 INTERFACE IMPORTED) 55 | 56 | set_target_properties(Catch2::Catch2 PROPERTIES 57 | INTERFACE_COMPILE_FEATURES "cxx_alignas;cxx_alignof;cxx_attributes;cxx_auto_type;cxx_constexpr;cxx_defaulted_functions;cxx_deleted_functions;cxx_final;cxx_lambdas;cxx_noexcept;cxx_override;cxx_range_for;cxx_rvalue_references;cxx_static_assert;cxx_strong_enums;cxx_trailing_return_types;cxx_unicode_literals;cxx_user_literals;cxx_variadic_macros" 58 | INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include" 59 | ) 60 | 61 | if(CMAKE_VERSION VERSION_LESS 3.0.0) 62 | message(FATAL_ERROR "This file relies on consumers using CMake 3.0.0 or greater.") 63 | endif() 64 | 65 | # Load information for each installed configuration. 66 | get_filename_component(_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) 67 | file(GLOB CONFIG_FILES "${_DIR}/Catch2Targets-*.cmake") 68 | foreach(f ${CONFIG_FILES}) 69 | include(${f}) 70 | endforeach() 71 | 72 | # Cleanup temporary variables. 73 | set(_IMPORT_PREFIX) 74 | 75 | # Loop over all imported files and verify that they actually exist 76 | foreach(target ${_IMPORT_CHECK_TARGETS} ) 77 | foreach(file ${_IMPORT_CHECK_FILES_FOR_${target}} ) 78 | if(NOT EXISTS "${file}" ) 79 | message(FATAL_ERROR "The imported target \"${target}\" references the file 80 | \"${file}\" 81 | but this file does not exist. Possible reasons include: 82 | * The file was deleted, renamed, or moved to another location. 83 | * An install or uninstall procedure did not complete successfully. 84 | * The installation package was faulty and contained 85 | \"${CMAKE_CURRENT_LIST_FILE}\" 86 | but not all the files it references. 87 | ") 88 | endif() 89 | endforeach() 90 | unset(_IMPORT_CHECK_FILES_FOR_${target}) 91 | endforeach() 92 | unset(_IMPORT_CHECK_TARGETS) 93 | 94 | # This file does not depend on other imported targets which have 95 | # been exported from the same project but in a separate export set. 96 | 97 | # Commands beyond this point should not need to know the version. 98 | set(CMAKE_IMPORT_FILE_VERSION) 99 | cmake_policy(POP) 100 | -------------------------------------------------------------------------------- /vendors/Catch2/lib/cmake/Catch2/CatchAddTests.cmake: -------------------------------------------------------------------------------- 1 | # Distributed under the OSI-approved BSD 3-Clause License. See accompanying 2 | # file Copyright.txt or https://cmake.org/licensing for details. 3 | 4 | set(prefix "${TEST_PREFIX}") 5 | set(suffix "${TEST_SUFFIX}") 6 | set(spec ${TEST_SPEC}) 7 | set(extra_args ${TEST_EXTRA_ARGS}) 8 | set(properties ${TEST_PROPERTIES}) 9 | set(script) 10 | set(suite) 11 | set(tests) 12 | 13 | function(add_command NAME) 14 | set(_args "") 15 | foreach(_arg ${ARGN}) 16 | if(_arg MATCHES "[^-./:a-zA-Z0-9_]") 17 | set(_args "${_args} [==[${_arg}]==]") # form a bracket_argument 18 | else() 19 | set(_args "${_args} ${_arg}") 20 | endif() 21 | endforeach() 22 | set(script "${script}${NAME}(${_args})\n" PARENT_SCOPE) 23 | endfunction() 24 | 25 | # Run test executable to get list of available tests 26 | if(NOT EXISTS "${TEST_EXECUTABLE}") 27 | message(FATAL_ERROR 28 | "Specified test executable '${TEST_EXECUTABLE}' does not exist" 29 | ) 30 | endif() 31 | execute_process( 32 | COMMAND ${TEST_EXECUTOR} "${TEST_EXECUTABLE}" ${spec} --list-test-names-only 33 | OUTPUT_VARIABLE output 34 | RESULT_VARIABLE result 35 | ) 36 | # Catch --list-test-names-only reports the number of tests, so 0 is... surprising 37 | if(${result} EQUAL 0) 38 | message(WARNING 39 | "Test executable '${TEST_EXECUTABLE}' contains no tests!\n" 40 | ) 41 | elseif(${result} LESS 0) 42 | message(FATAL_ERROR 43 | "Error running test executable '${TEST_EXECUTABLE}':\n" 44 | " Result: ${result}\n" 45 | " Output: ${output}\n" 46 | ) 47 | endif() 48 | 49 | string(REPLACE "\n" ";" output "${output}") 50 | 51 | # Parse output 52 | foreach(line ${output}) 53 | set(test ${line}) 54 | # use escape commas to handle properly test cases with commans inside the name 55 | string(REPLACE "," "\\," test_name ${test}) 56 | # ...and add to script 57 | add_command(add_test 58 | "${prefix}${test}${suffix}" 59 | ${TEST_EXECUTOR} 60 | "${TEST_EXECUTABLE}" 61 | "${test_name}" 62 | ${extra_args} 63 | ) 64 | add_command(set_tests_properties 65 | "${prefix}${test}${suffix}" 66 | PROPERTIES 67 | WORKING_DIRECTORY "${TEST_WORKING_DIR}" 68 | ${properties} 69 | ) 70 | list(APPEND tests "${prefix}${test}${suffix}") 71 | endforeach() 72 | 73 | # Create a list of all discovered tests, which users may use to e.g. set 74 | # properties on the tests 75 | add_command(set ${TEST_LIST} ${tests}) 76 | 77 | # Write CTest script 78 | file(WRITE "${CTEST_FILE}" "${script}") 79 | -------------------------------------------------------------------------------- /vendors/alpine-env/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:3.8 2 | 3 | LABEL maintainer="lanyuhang@baidu.com" 4 | 5 | # RUN echo "http://mirrors.aliyun.com/alpine/v3.8/main" > /etc/apk/repositories \ 6 | # && echo "http://mirrors.aliyun.com/alpine/v3.8/community" >> /etc/apk/repositories 7 | 8 | RUN apk add --no-cache bash curl tar xz vim alpine-sdk openjdk8 curl-dev zlib-dev libexecinfo-dev linux-headers 9 | 10 | ENV JAVA_HOME=/usr/lib/jvm/java-1.8-openjdk 11 | 12 | ADD apache-maven-3.6.3-bin.tar.gz /usr/local 13 | 14 | ADD cmake-3.17.1-Linux-musl.tar.gz /usr/local 15 | 16 | ENV PATH=/usr/local/cmake-3.17.1-Linux-musl/bin:/usr/local/apache-maven-3.6.3/bin:$PATH 17 | 18 | CMD /bin/bash -------------------------------------------------------------------------------- /vendors/build-libv8.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ev 4 | 5 | ### begin conf 6 | all_proxy= 7 | 8 | # commit or branch or tag 9 | v8_commit=6584de6be21c377b55f4f2b923388f1b6b0169cb 10 | 11 | # true or false 12 | skip_v8_sync=true 13 | 14 | # true or false 15 | build_musl=true 16 | ### end conf 17 | 18 | ### v8 sync 19 | if [[ $skip_v8_sync != "true" ]]; then 20 | export all_proxy 21 | 22 | if [[ ! -d depot_tools ]]; then 23 | git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git 24 | fi 25 | 26 | PATH=$PATH:`pwd`/depot_tools 27 | 28 | if [[ ! -d v8 ]]; then 29 | fetch --nohooks v8 30 | fi 31 | 32 | pushd v8 33 | 34 | git checkout $v8_commit 35 | 36 | gclient sync 37 | 38 | popd 39 | 40 | fi 41 | 42 | ### build 43 | pushd v8 44 | 45 | mkdir -p out/monolith.x64 46 | 47 | mkdir -p out/monolith.x86 48 | 49 | cat > out/monolith.x64/args.gn < out/monolith.x86/args.gn <> out/monolith.x64/args.gn <> out/monolith.x86/args.gn <> out/monolith.x64/args.gn < 2 | Andreas Gerstmayr 3 | Anton Lindström 4 | bandzaw 5 | Bob Jansen 6 | Chase Geigle 7 | Danilo Spinella 8 | David E 9 | Don Goodman-Wilson 10 | Eren Okka 11 | Felix Vanorder 12 | Florian Dang 13 | fuchs 14 | Guo Xiao 15 | Himanshu Shekhar 16 | Huu Nguyen 17 | Ivan Smirnov 18 | Josh Leeb-du Toit 19 | Klaus Silveira 20 | Mexus 21 | nabijaczleweli 22 | noh4h_ss 23 | Omer Katz 24 | pravic 25 | Sam Bristow 26 | Sean Chittenden 27 | Shuyu Liang 28 | Simon Ninon 29 | Smiley Barry 30 | Vittorio Romeo 31 | Vladimir Gamalian 32 | xpol 33 | -------------------------------------------------------------------------------- /vendors/cpr/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8.7) 2 | 3 | if(POLICY CMP0048) 4 | # cmake warns if loaded from a min-3.0-required parent dir, so silence the warning: 5 | cmake_policy(SET CMP0048 NEW) 6 | endif() 7 | 8 | # Allow use of project folders for IDEs like Visual Studio, so we 9 | # could organize projects into relevant folders: "cpr", "tests" & "external (libraries)". 10 | set_property(GLOBAL PROPERTY USE_FOLDERS ON) 11 | set_property(GLOBAL PROPERTY PREDEFINED_TARGETS_FOLDER "CMake") 12 | 13 | project(cpr CXX) 14 | 15 | if(NOT ${CMAKE_VERSION} VERSION_LESS 3.2) 16 | set(CMAKE_CXX_STANDARD 11) 17 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 18 | else() 19 | message(STATUS "Checking compiler flags for C++11 support.") 20 | # Set C++11 support flags for various compilers 21 | include(CheckCXXCompilerFlag) 22 | check_cxx_compiler_flag("-std=c++11" COMPILER_SUPPORTS_CXX11) 23 | check_cxx_compiler_flag("-std=c++0x" COMPILER_SUPPORTS_CXX0X) 24 | if(COMPILER_SUPPORTS_CXX11) 25 | message(STATUS "C++11 is supported.") 26 | if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") 27 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -stdlib=libc++") 28 | else() 29 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") 30 | endif() 31 | elseif(COMPILER_SUPPORTS_CXX0X) 32 | message(STATUS "C++0x is supported.") 33 | if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") 34 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x -stdlib=libc++") 35 | else() 36 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") 37 | endif() 38 | else() 39 | message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.") 40 | endif() 41 | endif() 42 | 43 | set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin) 44 | set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/lib) 45 | 46 | set(CPR_LIBRARIES cpr CACHE INTERNAL "") 47 | set(CPR_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/include CACHE INTERNAL "") 48 | 49 | macro(cpr_option OPTION_NAME OPTION_TEXT OPTION_DEFAULT) 50 | option(${OPTION_NAME} ${OPTION_TEXT} ${OPTION_DEFAULT}) 51 | if(DEFINED ENV{${OPTION_NAME}}) 52 | # Allow setting the option through an environment variable 53 | set(${OPTION_NAME} $ENV{${OPTION_NAME}}) 54 | endif() 55 | if(${OPTION_NAME}) 56 | add_definitions(-D${OPTION_NAME}) 57 | endif() 58 | message(STATUS " ${OPTION_NAME}: ${${OPTION_NAME}}") 59 | endmacro() 60 | 61 | message(STATUS "C++ Requests CMake Options") 62 | message(STATUS "=======================================================") 63 | cpr_option(USE_SYSTEM_CURL 64 | "If ON, this project will look in the system paths for an installed curl library" OFF) 65 | cpr_option(BUILD_CPR_TESTS "Set to ON to build cpr tests." ON) 66 | cpr_option(GENERATE_COVERAGE "Set to ON to generate coverage reports." OFF) 67 | cpr_option(CPR_CURL_NOSIGNAL "Set to ON to disable use of signals in libcurl." OFF) 68 | cpr_option(USE_SYSTEM_GTEST 69 | "If ON, this project will look in the system paths for an installed gtest library" OFF) 70 | cpr_option(CMAKE_USE_OPENSSL "Use OpenSSL code. Experimental" ON) 71 | message(STATUS "=======================================================") 72 | 73 | if(BUILD_CPR_TESTS) 74 | enable_testing() 75 | endif() 76 | 77 | add_subdirectory(opt) 78 | add_subdirectory(cpr) 79 | if(BUILD_CPR_TESTS) 80 | add_subdirectory(test) 81 | endif() 82 | 83 | install(DIRECTORY include/cpr DESTINATION include) 84 | -------------------------------------------------------------------------------- /vendors/cpr/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to C++ Requests 2 | 3 | Please fork this repository and contribute back using [pull requests](https://github.com/whoshuu/cpr/pulls). Features can be requested using [issues](https://github.com/whoshuu/cpr/issues). All code, comments, and critiques are greatly appreciated. 4 | 5 | ## Formatting 6 | 7 | To avoid unproductive debates on formatting, this project uses `clang-format` to ensure a consistent style across all source files. Currently, `clang-format` 3.8 is the version of `clang-format` we use. The format file can be found [here](https://github.com/whoshuu/cpr/blob/master/.clang-format). To install `clang-format` on Ubuntu, run this: 8 | 9 | ``` 10 | apt-get install clang-format-3.8 11 | ``` 12 | 13 | To install `clang-format` on OS X, run this: 14 | 15 | ``` 16 | brew install clang-format 17 | ``` 18 | 19 | Note that `brew` might install a later version of `clang-format`, but it should be mostly compatible with what's run on the Travis servers. 20 | 21 | To run `clang-format` on every source file, run this in the root directory: 22 | 23 | ``` 24 | ./format-check.sh 25 | ``` 26 | 27 | This should indicate which files need formatting and also show a diff of the requested changes. More specific usage instructions can be found on the official [LLVM website](http://releases.llvm.org/3.8.0/tools/clang/docs/ClangFormat.html). 28 | -------------------------------------------------------------------------------- /vendors/cpr/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 Huu Nguyen 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /vendors/cpr/README.md: -------------------------------------------------------------------------------- 1 | # C++ Requests: Curl for People 2 | 3 | [![gitter](https://badges.gitter.im/cpp-pm/community.svg)](https://gitter.im/whoshuu/cpr) [![Documentation](https://img.shields.io/badge/documentation-master-brightgreen.svg)](https://whoshuu.github.io/cpr/) 4 | [![Build Status](https://travis-ci.org/whoshuu/cpr.svg?branch=master)](https://travis-ci.org/whoshuu/cpr) [![Build status](https://ci.appveyor.com/api/projects/status/imalkp3a6hblpj5y/branch/master?svg=true)](https://ci.appveyor.com/project/whoshuu/cpr/branch/master) [![Coverage Status](https://coveralls.io/repos/whoshuu/cpr/badge.svg?branch=master&service=github)](https://coveralls.io/github/whoshuu/cpr) 5 | 6 | ## Announcements 7 | 8 | The cpr project will have a new maintainer: [Tim Stack](https://github.com/tstack). He has graciously agreed to donate his time to keep the project healthy and grow it. For those waiting on their PRs and issues to be resolved, I appreciate your patience and know that you will be in good hands moving forward. 9 | 10 | ## TLDR 11 | 12 | C++ Requests is a simple wrapper around [libcurl](http://curl.haxx.se/libcurl) inspired by the excellent [Python Requests](https://github.com/kennethreitz/requests) project. 13 | 14 | Despite its name, libcurl's easy interface is anything but, and making mistakes misusing it is a common source of error and frustration. Using the more expressive language facilities of C++11, this library captures the essence of making network calls into a few concise idioms. 15 | 16 | Here's a quick GET request: 17 | 18 | ```c++ 19 | #include 20 | 21 | int main(int argc, char** argv) { 22 | auto r = cpr::Get(cpr::Url{"https://api.github.com/repos/whoshuu/cpr/contributors"}, 23 | cpr::Authentication{"user", "pass"}, 24 | cpr::Parameters{{"anon", "true"}, {"key", "value"}}); 25 | r.status_code; // 200 26 | r.header["content-type"]; // application/json; charset=utf-8 27 | r.text; // JSON text string 28 | } 29 | ``` 30 | 31 | And here's [less functional, more complicated code, without cpr](https://gist.github.com/whoshuu/2dc858b8730079602044). 32 | 33 | ## Documentation 34 | 35 | You can find the latest documentation [here](https://whoshuu.github.io/cpr). It's a work in progress, but it should give you a better idea of how to use the library than the [tests](https://github.com/whoshuu/cpr/tree/master/test) currently do. 36 | 37 | ## Features 38 | 39 | C++ Requests currently supports: 40 | 41 | * Custom headers 42 | * Url encoded parameters 43 | * Url encoded POST values 44 | * Multipart form POST upload 45 | * File POST upload 46 | * Basic authentication 47 | * Digest authentication 48 | * Connection and request timeout specification 49 | * Timeout for low speed connection 50 | * Asynchronous requests 51 | * :cookie: support! 52 | * Proxy support 53 | * Callback interface 54 | * PUT methods 55 | * DELETE methods 56 | * HEAD methods 57 | * OPTIONS methods 58 | * PATCH methods 59 | 60 | ## Planned 61 | 62 | Support for the following will be forthcoming (in rough order of implementation priority): 63 | 64 | * [Streamed requests](https://github.com/whoshuu/cpr/issues/25) 65 | * [OpenSSL support](https://github.com/whoshuu/cpr/issues/31) 66 | 67 | and much more! 68 | 69 | ## Usage 70 | 71 | For just getting this library up and running, I highly recommend forking the [example project](https://github.com/whoshuu/cpr-example). It's configured with the minimum CMake magic and boilerplate needed to start playing around with networked applications. 72 | 73 | If you already have a project you need to integrate C++ Requests with, the primary way is to use git submodules. Add this repository as a submodule of your root repository: 74 | 75 | ```shell 76 | git submodule add git@github.com:whoshuu/cpr.git 77 | OR 78 | git submodule add https://github.com/whoshuu/cpr.git 79 | 80 | git submodule update --init --recursive 81 | ``` 82 | 83 | Next, add this subdirectory to your CMakeLists.txt before declaring any targets that might use it: 84 | 85 | ```cmake 86 | add_subdirectory(cpr) 87 | ``` 88 | 89 | This will produce two important CMake variables, `CPR_INCLUDE_DIRS` and `CPR_LIBRARIES`, which you'll use in the typical way: 90 | 91 | ```cmake 92 | include_directories(${CPR_INCLUDE_DIRS}) 93 | target_link_libraries(your_target_name ${CPR_LIBRARIES}) 94 | ``` 95 | 96 | and that should do it! Using the submodule method of integrating C++ Requests, there's no need to handle libcurl yourself, all of those dependencies are taken care of for you. 97 | 98 | ## Requirements 99 | 100 | The only explicit requirements are: 101 | 102 | * a C++11 compatible compiler such as Clang or GCC. The minimum required version of GCC is unknown, so if anyone has trouble building this library with a specific version of GCC, do let me know 103 | * curl and its development libraries 104 | -------------------------------------------------------------------------------- /vendors/cpr/VERSION: -------------------------------------------------------------------------------- 1 | 1.3.0 2 | -------------------------------------------------------------------------------- /vendors/cpr/appveyor.yml: -------------------------------------------------------------------------------- 1 | version: '1.1.{build}' 2 | configuration: 3 | - RELEASE 4 | - DEBUG 5 | os: Visual Studio 2015 6 | before_build: 7 | - git submodule update --init --recursive 8 | - set CMAKE_USE_OPENSSL=OFF 9 | - mkdir build 10 | - cd build 11 | - cmake -DCMAKE_BUILD_TYPE=%Configuration% .. -G "Visual Studio 14 2015" 12 | build: 13 | project: C:\projects\cpr\build\cpr.sln 14 | test_script: 15 | - cd C:\projects\cpr\build 16 | - ctest -VV -C %Configuration% 17 | -------------------------------------------------------------------------------- /vendors/cpr/cpr-config.cmake: -------------------------------------------------------------------------------- 1 | # - C++ Requests, Curl for People 2 | # This module is a libcurl wrapper written in modern C++. 3 | # It provides an easy, intuitive, and efficient interface to 4 | # a host of networking methods. 5 | # 6 | # Finding this module will define the following variables: 7 | # CPR_FOUND - True if the core library has been found 8 | # CPR_LIBRARIES - Path to the core library archive 9 | # CPR_INCLUDE_DIRS - Path to the include directories. Gives access 10 | # to cpr.h, which must be included in every 11 | # file that uses this interface 12 | 13 | find_path(CPR_INCLUDE_DIR 14 | NAMES cpr.h) 15 | 16 | find_library(CPR_LIBRARY 17 | NAMES cpr 18 | HINTS ${CPR_LIBRARY_ROOT}) 19 | 20 | include(FindPackageHandleStandardArgs) 21 | find_package_handle_standard_args(CPR REQUIRED_VARS CPR_LIBRARY CPR_INCLUDE_DIR) 22 | 23 | if(CPR_FOUND) 24 | set(CPR_LIBRARIES ${CPR_LIBRARY}) 25 | set(CPR_INCLUDE_DIRS ${CPR_INCLUDE_DIR}) 26 | endif() 27 | -------------------------------------------------------------------------------- /vendors/cpr/cpr/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | message(STATUS "Using CURL_INCLUDE_DIRS: ${CURL_INCLUDE_DIRS}.") 2 | 3 | add_library(${CPR_LIBRARIES} 4 | 5 | # Source files 6 | auth.cpp 7 | cookies.cpp 8 | cprtypes.cpp 9 | digest.cpp 10 | error.cpp 11 | multipart.cpp 12 | parameters.cpp 13 | payload.cpp 14 | proxies.cpp 15 | session.cpp 16 | timeout.cpp 17 | util.cpp 18 | ssl_options.cpp 19 | 20 | # Header files (useful in IDEs) 21 | "${CPR_INCLUDE_DIRS}/cpr/api.h" 22 | "${CPR_INCLUDE_DIRS}/cpr/auth.h" 23 | "${CPR_INCLUDE_DIRS}/cpr/body.h" 24 | "${CPR_INCLUDE_DIRS}/cpr/cookies.h" 25 | "${CPR_INCLUDE_DIRS}/cpr/cpr.h" 26 | "${CPR_INCLUDE_DIRS}/cpr/cprtypes.h" 27 | "${CPR_INCLUDE_DIRS}/cpr/curlholder.h" 28 | "${CPR_INCLUDE_DIRS}/cpr/defines.h" 29 | "${CPR_INCLUDE_DIRS}/cpr/digest.h" 30 | "${CPR_INCLUDE_DIRS}/cpr/error.h" 31 | "${CPR_INCLUDE_DIRS}/cpr/max_redirects.h" 32 | "${CPR_INCLUDE_DIRS}/cpr/multipart.h" 33 | "${CPR_INCLUDE_DIRS}/cpr/parameters.h" 34 | "${CPR_INCLUDE_DIRS}/cpr/payload.h" 35 | "${CPR_INCLUDE_DIRS}/cpr/proxies.h" 36 | "${CPR_INCLUDE_DIRS}/cpr/response.h" 37 | "${CPR_INCLUDE_DIRS}/cpr/session.h" 38 | "${CPR_INCLUDE_DIRS}/cpr/timeout.h" 39 | "${CPR_INCLUDE_DIRS}/cpr/util.h" 40 | "${CPR_INCLUDE_DIRS}/cpr/ssl_options.h" 41 | "${CPR_INCLUDE_DIRS}/cpr/verbose.h") 42 | 43 | message(STATUS "Using CURL_LIBRARIES: ${CURL_LIBRARIES}.") 44 | target_link_libraries(${CPR_LIBRARIES} 45 | ${CURL_LIBRARIES}) 46 | 47 | if(NOT (CMAKE_VERSION VERSION_LESS 3.0)) 48 | target_include_directories(${CPR_LIBRARIES} 49 | PUBLIC 50 | ${CPR_INCLUDE_DIRS} 51 | ${CURL_INCLUDE_DIRS}) 52 | else() 53 | include_directories( 54 | ${CPR_INCLUDE_DIRS} 55 | ${CURL_INCLUDE_DIRS}) 56 | endif() 57 | 58 | install(TARGETS ${CPR_LIBRARIES} 59 | RUNTIME DESTINATION bin 60 | LIBRARY DESTINATION lib 61 | ARCHIVE DESTINATION lib) 62 | -------------------------------------------------------------------------------- /vendors/cpr/cpr/auth.cpp: -------------------------------------------------------------------------------- 1 | #include "cpr/auth.h" 2 | 3 | namespace cpr { 4 | 5 | const char* Authentication::GetAuthString() const noexcept { 6 | return auth_string_.data(); 7 | } 8 | 9 | } // namespace cpr 10 | -------------------------------------------------------------------------------- /vendors/cpr/cpr/cookies.cpp: -------------------------------------------------------------------------------- 1 | #include "cpr/cookies.h" 2 | 3 | #include "cpr/util.h" 4 | 5 | namespace cpr { 6 | 7 | Cookies::Cookies(const std::initializer_list>& pairs) 8 | : map_{pairs} {} 9 | 10 | std::string Cookies::GetEncoded() const { 11 | std::stringstream stream; 12 | for (const auto& item : map_) { 13 | stream << cpr::util::urlEncode(item.first) << "="; 14 | // special case version 1 cookies, which can be distinguished by 15 | // beginning and trailing quotes 16 | if (!item.second.empty() && item.second.front() == '"' && item.second.back() == '"') { 17 | stream << item.second; 18 | } else { 19 | stream << cpr::util::urlEncode(item.second); 20 | } 21 | stream << "; "; 22 | } 23 | return stream.str(); 24 | } 25 | 26 | std::string& Cookies::operator[](const std::string& key) { 27 | return map_[key]; 28 | } 29 | 30 | } // namespace cpr 31 | -------------------------------------------------------------------------------- /vendors/cpr/cpr/cprtypes.cpp: -------------------------------------------------------------------------------- 1 | #include "cpr/cprtypes.h" 2 | 3 | #include 4 | #include 5 | 6 | namespace cpr { 7 | 8 | bool CaseInsensitiveCompare::operator()(const std::string& a, const std::string& b) const noexcept { 9 | return std::lexicographical_compare( 10 | a.begin(), a.end(), b.begin(), b.end(), 11 | [](unsigned char ac, unsigned char bc) { return std::tolower(ac) < std::tolower(bc); }); 12 | } 13 | 14 | } // namespace cpr 15 | -------------------------------------------------------------------------------- /vendors/cpr/cpr/digest.cpp: -------------------------------------------------------------------------------- 1 | #include "cpr/digest.h" 2 | 3 | namespace cpr { 4 | 5 | const char* Digest::GetAuthString() const noexcept { 6 | return Authentication::GetAuthString(); 7 | } 8 | 9 | } // namespace cpr 10 | -------------------------------------------------------------------------------- /vendors/cpr/cpr/error.cpp: -------------------------------------------------------------------------------- 1 | #include "cpr/error.h" 2 | 3 | #include 4 | 5 | namespace cpr { 6 | 7 | ErrorCode Error::getErrorCodeForCurlError(std::int32_t curl_code) { 8 | switch (curl_code) { 9 | case CURLE_OK: 10 | return ErrorCode::OK; 11 | case CURLE_UNSUPPORTED_PROTOCOL: 12 | return ErrorCode::UNSUPPORTED_PROTOCOL; 13 | case CURLE_URL_MALFORMAT: 14 | return ErrorCode::INVALID_URL_FORMAT; 15 | case CURLE_COULDNT_RESOLVE_PROXY: 16 | return ErrorCode::PROXY_RESOLUTION_FAILURE; 17 | case CURLE_COULDNT_RESOLVE_HOST: 18 | return ErrorCode::HOST_RESOLUTION_FAILURE; 19 | case CURLE_COULDNT_CONNECT: 20 | return ErrorCode::CONNECTION_FAILURE; 21 | case CURLE_OPERATION_TIMEDOUT: 22 | return ErrorCode::OPERATION_TIMEDOUT; 23 | case CURLE_SSL_CONNECT_ERROR: 24 | return ErrorCode::SSL_CONNECT_ERROR; 25 | #if LIBCURL_VERSION_NUM < 0x073e00 26 | case CURLE_PEER_FAILED_VERIFICATION: 27 | return ErrorCode::SSL_REMOTE_CERTIFICATE_ERROR; 28 | #endif 29 | case CURLE_GOT_NOTHING: 30 | return ErrorCode::EMPTY_RESPONSE; 31 | case CURLE_SSL_ENGINE_NOTFOUND: 32 | return ErrorCode::GENERIC_SSL_ERROR; 33 | case CURLE_SSL_ENGINE_SETFAILED: 34 | return ErrorCode::GENERIC_SSL_ERROR; 35 | case CURLE_SEND_ERROR: 36 | return ErrorCode::NETWORK_SEND_FAILURE; 37 | case CURLE_RECV_ERROR: 38 | return ErrorCode::NETWORK_RECEIVE_ERROR; 39 | case CURLE_SSL_CERTPROBLEM: 40 | return ErrorCode::SSL_LOCAL_CERTIFICATE_ERROR; 41 | case CURLE_SSL_CIPHER: 42 | return ErrorCode::GENERIC_SSL_ERROR; 43 | #if LIBCURL_VERSION_NUM >= 0x073e00 44 | case CURLE_PEER_FAILED_VERIFICATION: 45 | return ErrorCode::SSL_REMOTE_CERTIFICATE_ERROR; 46 | #else 47 | case CURLE_SSL_CACERT: 48 | return ErrorCode::SSL_CACERT_ERROR; 49 | #endif 50 | case CURLE_USE_SSL_FAILED: 51 | return ErrorCode::GENERIC_SSL_ERROR; 52 | case CURLE_SSL_ENGINE_INITFAILED: 53 | return ErrorCode::GENERIC_SSL_ERROR; 54 | case CURLE_SSL_CACERT_BADFILE: 55 | return ErrorCode::SSL_CACERT_ERROR; 56 | case CURLE_SSL_SHUTDOWN_FAILED: 57 | return ErrorCode::GENERIC_SSL_ERROR; 58 | case CURLE_SSL_CRL_BADFILE: 59 | return ErrorCode::SSL_CACERT_ERROR; 60 | case CURLE_SSL_ISSUER_ERROR: 61 | return ErrorCode::SSL_CACERT_ERROR; 62 | case CURLE_TOO_MANY_REDIRECTS: 63 | return ErrorCode::OK; 64 | default: 65 | return ErrorCode::INTERNAL_ERROR; 66 | } 67 | } 68 | 69 | } // namespace cpr 70 | -------------------------------------------------------------------------------- /vendors/cpr/cpr/multipart.cpp: -------------------------------------------------------------------------------- 1 | #include "cpr/multipart.h" 2 | 3 | namespace cpr { 4 | 5 | Multipart::Multipart(const std::initializer_list& parts) : parts{parts} {} 6 | 7 | } // namespace cpr 8 | -------------------------------------------------------------------------------- /vendors/cpr/cpr/parameters.cpp: -------------------------------------------------------------------------------- 1 | #include "cpr/parameters.h" 2 | 3 | #include 4 | #include 5 | 6 | #include "cpr/util.h" 7 | 8 | namespace cpr { 9 | 10 | Parameters::Parameters(const std::initializer_list& parameters) { 11 | for (const auto& parameter : parameters) { 12 | AddParameter(parameter); 13 | } 14 | } 15 | 16 | void Parameters::AddParameter(const Parameter& parameter) { 17 | if (!content.empty()) { 18 | content += "&"; 19 | } 20 | 21 | auto escapedKey = cpr::util::urlEncode(parameter.key); 22 | if (parameter.value.empty()) { 23 | content += escapedKey; 24 | } else { 25 | auto escapedValue = cpr::util::urlEncode(parameter.value); 26 | content += escapedKey + "=" + escapedValue; 27 | } 28 | } 29 | 30 | } // namespace cpr 31 | -------------------------------------------------------------------------------- /vendors/cpr/cpr/payload.cpp: -------------------------------------------------------------------------------- 1 | #include "cpr/payload.h" 2 | 3 | #include 4 | #include 5 | 6 | #include "cpr/util.h" 7 | 8 | namespace cpr { 9 | 10 | Payload::Payload(const std::initializer_list& pairs) : Payload(begin(pairs), end(pairs)) {} 11 | 12 | void Payload::AddPair(const Pair& pair) { 13 | if (!content.empty()) { 14 | content += "&"; 15 | } 16 | auto escaped = cpr::util::urlEncode(pair.value); 17 | content += pair.key + "=" + escaped; 18 | } 19 | 20 | } // namespace cpr 21 | -------------------------------------------------------------------------------- /vendors/cpr/cpr/proxies.cpp: -------------------------------------------------------------------------------- 1 | #include "cpr/proxies.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | namespace cpr { 9 | 10 | Proxies::Proxies(const std::initializer_list>& hosts) 11 | : hosts_{hosts} {} 12 | 13 | bool Proxies::has(const std::string& protocol) const { 14 | return hosts_.count(protocol) > 0; 15 | } 16 | 17 | const std::string& Proxies::operator[](const std::string& protocol) { 18 | return hosts_[protocol]; 19 | } 20 | 21 | } // namespace cpr 22 | -------------------------------------------------------------------------------- /vendors/cpr/cpr/ssl_options.cpp: -------------------------------------------------------------------------------- 1 | #include "cpr/ssl_options.h" 2 | 3 | namespace cpr { 4 | 5 | VerifySsl::VerifySsl(bool verify) : verify_{verify} {} 6 | 7 | VerifySsl::operator bool() const { 8 | return verify_; 9 | } 10 | 11 | } // namespace cpr 12 | -------------------------------------------------------------------------------- /vendors/cpr/cpr/timeout.cpp: -------------------------------------------------------------------------------- 1 | #include "cpr/timeout.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | namespace cpr { 9 | 10 | long Timeout::Milliseconds() const { 11 | static_assert(std::is_same::value, 12 | "Following casting expects milliseconds."); 13 | 14 | if (ms.count() > std::numeric_limits::max()) { 15 | throw std::overflow_error( 16 | "cpr::Timeout: timeout value overflow: " + std::to_string(ms.count()) + " ms."); 17 | } 18 | if (ms.count() < std::numeric_limits::min()) { 19 | throw std::underflow_error( 20 | "cpr::Timeout: timeout value underflow: " + std::to_string(ms.count()) + " ms."); 21 | } 22 | 23 | return static_cast(ms.count()); 24 | } 25 | 26 | } // namespace cpr 27 | -------------------------------------------------------------------------------- /vendors/cpr/cpr/util.cpp: -------------------------------------------------------------------------------- 1 | #include "cpr/util.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | namespace cpr { 12 | namespace util { 13 | 14 | Header parseHeader(const std::string& headers) { 15 | Header header; 16 | std::vector lines; 17 | std::istringstream stream(headers); 18 | { 19 | std::string line; 20 | while (std::getline(stream, line, '\n')) { 21 | lines.push_back(line); 22 | } 23 | } 24 | 25 | for (auto& line : lines) { 26 | if (line.substr(0, 5) == "HTTP/") { 27 | header.clear(); 28 | } 29 | 30 | if (line.length() > 0) { 31 | auto found = line.find(":"); 32 | if (found != std::string::npos) { 33 | auto value = line.substr(found + 1); 34 | value.erase(0, value.find_first_not_of("\t ")); 35 | value.resize(std::min(value.size(), value.find_last_not_of("\t\n\r ") + 1)); 36 | header[line.substr(0, found)] = value; 37 | } 38 | } 39 | } 40 | 41 | return header; 42 | } 43 | 44 | std::vector split(const std::string& to_split, char delimiter) { 45 | std::vector tokens; 46 | 47 | std::stringstream stream(to_split); 48 | std::string item; 49 | while (std::getline(stream, item, delimiter)) { 50 | tokens.push_back(item); 51 | } 52 | 53 | return tokens; 54 | } 55 | 56 | size_t writeFunction(void* ptr, size_t size, size_t nmemb, std::string* data) { 57 | data->append(static_cast(ptr), size * nmemb); 58 | return size * nmemb; 59 | } 60 | 61 | std::string urlEncode(const std::string& value) { 62 | std::ostringstream escaped; 63 | escaped.fill('0'); 64 | escaped << std::hex; 65 | 66 | for (auto i = value.cbegin(), n = value.cend(); i != n; ++i) { 67 | std::string::value_type c = (*i); 68 | // Keep alphanumeric and other accepted characters intact 69 | if (std::isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~') { 70 | escaped << c; 71 | continue; 72 | } 73 | // Any other characters are percent-encoded 74 | escaped << '%' << std::setw(2) << std::int32_t(static_cast(c)); 75 | } 76 | 77 | return escaped.str(); 78 | } 79 | 80 | } // namespace util 81 | } // namespace cpr 82 | -------------------------------------------------------------------------------- /vendors/cpr/format-check.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | 4 | which clang-format-3.8 5 | if [ $? -eq 0 ] 6 | then 7 | format_command=clang-format-3.8 8 | else 9 | format_command=clang-format 10 | fi 11 | 12 | format_error_exists=0 13 | 14 | for DIRECTORY in include cpr 15 | do 16 | for FILE in $DIRECTORY/*.h $DIRECTORY/*.cpp 17 | do 18 | if [ -e $FILE ] 19 | then 20 | $format_command -style=file -output-replacements-xml $FILE | grep -c "/dev/null 21 | if [ $? -ne 1 ] 22 | then 23 | echo "Please run clang-format on $FILE:" 24 | $format_command -style=file $FILE | diff - $FILE 25 | format_error_exists=1 26 | fi 27 | fi 28 | done 29 | done 30 | 31 | if [ $format_error_exists -ne 0 ] 32 | then 33 | echo "Some files require formatting" 34 | exit 1 35 | fi 36 | 37 | exit 0 38 | -------------------------------------------------------------------------------- /vendors/cpr/include/cpr/auth.h: -------------------------------------------------------------------------------- 1 | #ifndef CPR_AUTH_H 2 | #define CPR_AUTH_H 3 | 4 | #include 5 | 6 | #include "cpr/defines.h" 7 | 8 | namespace cpr { 9 | 10 | class Authentication { 11 | public: 12 | template 13 | Authentication(UserType&& username, PassType&& password) 14 | : username_{CPR_FWD(username)}, password_{CPR_FWD(password)}, 15 | auth_string_{username_ + ":" + password_} {} 16 | 17 | const char* GetAuthString() const noexcept; 18 | 19 | private: 20 | std::string username_; 21 | std::string password_; 22 | std::string auth_string_; 23 | }; 24 | 25 | } // namespace cpr 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /vendors/cpr/include/cpr/body.h: -------------------------------------------------------------------------------- 1 | #ifndef CPR_BODY_H 2 | #define CPR_BODY_H 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | #include "cpr/defines.h" 10 | 11 | namespace cpr { 12 | 13 | class Body : public std::string { 14 | public: 15 | Body() = default; 16 | Body(const Body& rhs) = default; 17 | Body(Body&& rhs) = default; 18 | Body& operator=(const Body& rhs) = default; 19 | Body& operator=(Body&& rhs) = default; 20 | explicit Body(const char* raw_string) : std::string(raw_string) {} 21 | explicit Body(const char* raw_string, size_t length) : std::string(raw_string, length) {} 22 | explicit Body(size_t to_fill, char character) : std::string(to_fill, character) {} 23 | explicit Body(const std::string& std_string) : std::string(std_string) {} 24 | explicit Body(const std::string& std_string, size_t position, size_t length = std::string::npos) 25 | : std::string(std_string, position, length) {} 26 | explicit Body(std::string&& std_string) : std::string(std::move(std_string)) {} 27 | explicit Body(std::initializer_list il) : std::string(il) {} 28 | template 29 | explicit Body(InputIterator first, InputIterator last) 30 | : std::string(first, last) {} 31 | }; 32 | 33 | } // namespace cpr 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /vendors/cpr/include/cpr/connect_timeout.h: -------------------------------------------------------------------------------- 1 | #ifndef CPR_CONNECT_TIMEOUT_H 2 | #define CPR_CONNECT_TIMEOUT_H 3 | 4 | #include "cpr/timeout.h" 5 | 6 | namespace cpr { 7 | 8 | class ConnectTimeout : public Timeout { 9 | public: 10 | ConnectTimeout(const std::chrono::milliseconds& duration) : Timeout{duration} {} 11 | ConnectTimeout(const std::int32_t& milliseconds) : Timeout{milliseconds} {} 12 | }; 13 | 14 | } // namespace cpr 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /vendors/cpr/include/cpr/cookies.h: -------------------------------------------------------------------------------- 1 | #ifndef CPR_COOKIES_H 2 | #define CPR_COOKIES_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | namespace cpr { 10 | 11 | class Cookies { 12 | public: 13 | Cookies() {} 14 | Cookies(const std::initializer_list>& pairs); 15 | Cookies(const std::map& map) : map_{map} {} 16 | 17 | std::string& operator[](const std::string& key); 18 | std::string GetEncoded() const; 19 | 20 | private: 21 | std::map map_; 22 | }; 23 | 24 | } // namespace cpr 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /vendors/cpr/include/cpr/cpr.h: -------------------------------------------------------------------------------- 1 | #ifndef CPR_CPR_H 2 | #define CPR_CPR_H 3 | 4 | #include "cpr/api.h" 5 | #include "cpr/auth.h" 6 | #include "cpr/cprtypes.h" 7 | #include "cpr/response.h" 8 | #include "cpr/session.h" 9 | #include "cpr/status_codes.h" 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /vendors/cpr/include/cpr/cprtypes.h: -------------------------------------------------------------------------------- 1 | #ifndef CPR_CPR_TYPES_H 2 | #define CPR_CPR_TYPES_H 3 | 4 | #include 5 | #include 6 | 7 | namespace cpr { 8 | 9 | struct CaseInsensitiveCompare { 10 | bool operator()(const std::string& a, const std::string& b) const noexcept; 11 | }; 12 | 13 | using Header = std::map; 14 | using Url = std::string; 15 | 16 | } // namespace cpr 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /vendors/cpr/include/cpr/curlholder.h: -------------------------------------------------------------------------------- 1 | #ifndef CPR_CURL_HOLDER_H 2 | #define CPR_CURL_HOLDER_H 3 | 4 | #include 5 | 6 | #include 7 | 8 | namespace cpr { 9 | 10 | struct CurlHolder { 11 | CURL* handle; 12 | struct curl_slist* chunk; 13 | struct curl_httppost* formpost; 14 | char error[CURL_ERROR_SIZE]; 15 | }; 16 | 17 | } // namespace cpr 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /vendors/cpr/include/cpr/defines.h: -------------------------------------------------------------------------------- 1 | #ifndef CPR_DEFINES_H 2 | #define CPR_DEFINES_H 3 | 4 | #include 5 | 6 | #define CPR_FWD(...) ::std::forward(__VA_ARGS__) 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /vendors/cpr/include/cpr/digest.h: -------------------------------------------------------------------------------- 1 | #ifndef CPR_DIGEST_H 2 | #define CPR_DIGEST_H 3 | 4 | #include "cpr/auth.h" 5 | #include "cpr/defines.h" 6 | 7 | namespace cpr { 8 | 9 | class Digest : public Authentication { 10 | public: 11 | template 12 | Digest(UserType&& username, PassType&& password) 13 | : Authentication{CPR_FWD(username), CPR_FWD(password)} {} 14 | 15 | const char* GetAuthString() const noexcept; 16 | }; 17 | 18 | } // namespace cpr 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /vendors/cpr/include/cpr/error.h: -------------------------------------------------------------------------------- 1 | #ifndef CPR_ERROR_H 2 | #define CPR_ERROR_H 3 | 4 | #include 5 | #include 6 | 7 | #include "cpr/cprtypes.h" 8 | #include "cpr/defines.h" 9 | 10 | namespace cpr { 11 | 12 | enum class ErrorCode { 13 | OK = 0, 14 | CONNECTION_FAILURE, 15 | EMPTY_RESPONSE, 16 | HOST_RESOLUTION_FAILURE, 17 | INTERNAL_ERROR, 18 | INVALID_URL_FORMAT, 19 | NETWORK_RECEIVE_ERROR, 20 | NETWORK_SEND_FAILURE, 21 | OPERATION_TIMEDOUT, 22 | PROXY_RESOLUTION_FAILURE, 23 | SSL_CONNECT_ERROR, 24 | SSL_LOCAL_CERTIFICATE_ERROR, 25 | SSL_REMOTE_CERTIFICATE_ERROR, 26 | SSL_CACERT_ERROR, 27 | GENERIC_SSL_ERROR, 28 | UNSUPPORTED_PROTOCOL, 29 | UNKNOWN_ERROR = 1000, 30 | }; 31 | 32 | class Error { 33 | public: 34 | Error() : code{ErrorCode::OK} {} 35 | 36 | template 37 | Error(const std::int32_t& curl_code, TextType&& p_error_message) 38 | : code{getErrorCodeForCurlError(curl_code)}, message{CPR_FWD(p_error_message)} {} 39 | 40 | explicit operator bool() const { 41 | return code != ErrorCode::OK; 42 | } 43 | 44 | ErrorCode code; 45 | std::string message; 46 | 47 | private: 48 | static ErrorCode getErrorCodeForCurlError(std::int32_t curl_code); 49 | }; 50 | 51 | } // namespace cpr 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /vendors/cpr/include/cpr/low_speed.h: -------------------------------------------------------------------------------- 1 | #ifndef CPR_LOW_SPEED_H 2 | #define CPR_LOW_SPEED_H 3 | 4 | #include 5 | 6 | namespace cpr { 7 | 8 | class LowSpeed { 9 | public: 10 | LowSpeed(const std::int32_t limit, const std::int32_t time) : limit(limit), time(time) {} 11 | 12 | std::int32_t limit; 13 | std::int32_t time; 14 | }; 15 | 16 | } // namespace cpr 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /vendors/cpr/include/cpr/max_redirects.h: -------------------------------------------------------------------------------- 1 | #ifndef CPR_MAX_REDIRECTS_H 2 | #define CPR_MAX_REDIRECTS_H 3 | 4 | #include 5 | 6 | namespace cpr { 7 | 8 | class MaxRedirects { 9 | public: 10 | explicit MaxRedirects(const std::int32_t number_of_redirects) 11 | : number_of_redirects(number_of_redirects) {} 12 | 13 | std::int32_t number_of_redirects; 14 | }; 15 | 16 | } // namespace cpr 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /vendors/cpr/include/cpr/multipart.h: -------------------------------------------------------------------------------- 1 | #ifndef CPR_MULTIPART_H 2 | #define CPR_MULTIPART_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "cpr/defines.h" 11 | 12 | namespace cpr { 13 | 14 | struct File { 15 | template 16 | explicit File(StringType&& filepath) 17 | : filepath{CPR_FWD(filepath)} {} 18 | std::string filepath; 19 | }; 20 | 21 | struct Buffer { 22 | typedef const unsigned char* data_t; 23 | 24 | template 25 | explicit Buffer(Iterator begin, Iterator end, StringType&& filename) 26 | : data{reinterpret_cast(&(*begin))}, 27 | datalen{static_cast(std::distance(begin, end))}, 28 | filename{CPR_FWD(filename)} { 29 | is_random_access_iterator(begin, end); 30 | static_assert(sizeof(*begin) == 1, "only byte buffers can be used"); 31 | } 32 | 33 | template 34 | typename std::enable_if::iterator_category, 35 | std::random_access_iterator_tag>::value>::type 36 | is_random_access_iterator(Iterator /* begin */, Iterator /* end */ ) {} 37 | 38 | data_t data; 39 | unsigned long datalen; 40 | std::string filename; 41 | }; 42 | 43 | struct Part { 44 | Part(const std::string& name, const std::string& value, const std::string& content_type = {}) 45 | : name{name}, value{value}, content_type{content_type}, is_file{false}, 46 | is_buffer{false} {} 47 | Part(const std::string& name, const std::int32_t& value, const std::string& content_type = {}) 48 | : name{name}, value{std::to_string(value)}, content_type{content_type}, is_file{false}, 49 | is_buffer{false} {} 50 | Part(const std::string& name, const File& file, const std::string& content_type = {}) 51 | : name{name}, value{file.filepath}, content_type{content_type}, is_file{true}, 52 | is_buffer{false} {} 53 | Part(const std::string& name, const Buffer& buffer, const std::string& content_type = {}) 54 | : name{name}, value{buffer.filename}, content_type{content_type}, data{buffer.data}, 55 | datalen{buffer.datalen}, is_file{false}, is_buffer{true} {} 56 | 57 | std::string name; 58 | std::string value; 59 | std::string content_type; 60 | Buffer::data_t data; 61 | unsigned long datalen; 62 | bool is_file; 63 | bool is_buffer; 64 | }; 65 | 66 | class Multipart { 67 | public: 68 | Multipart(const std::initializer_list& parts); 69 | 70 | std::vector parts; 71 | }; 72 | 73 | } // namespace cpr 74 | 75 | #endif 76 | -------------------------------------------------------------------------------- /vendors/cpr/include/cpr/parameters.h: -------------------------------------------------------------------------------- 1 | #ifndef CPR_PARAMETERS_H 2 | #define CPR_PARAMETERS_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "cpr/defines.h" 9 | 10 | namespace cpr { 11 | 12 | struct Parameter { 13 | template 14 | Parameter(KeyType&& key, ValueType&& value) 15 | : key{CPR_FWD(key)}, value{CPR_FWD(value)} {} 16 | 17 | std::string key; 18 | std::string value; 19 | }; 20 | 21 | class Parameters { 22 | public: 23 | Parameters() = default; 24 | Parameters(const std::initializer_list& parameters); 25 | 26 | void AddParameter(const Parameter& parameter); 27 | 28 | std::string content; 29 | }; 30 | 31 | } // namespace cpr 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /vendors/cpr/include/cpr/payload.h: -------------------------------------------------------------------------------- 1 | #ifndef CPR_PAYLOAD_H 2 | #define CPR_PAYLOAD_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "cpr/defines.h" 10 | 11 | namespace cpr { 12 | 13 | struct Pair { 14 | template ::value, bool>::type = true> 16 | Pair(KeyType&& p_key, ValueType&& p_value) 17 | : key{CPR_FWD(p_key)}, value{CPR_FWD(p_value)} {} 18 | template 19 | Pair(KeyType&& p_key, const std::int32_t& p_value) 20 | : key{CPR_FWD(p_key)}, value{std::to_string(p_value)} {} 21 | 22 | std::string key; 23 | std::string value; 24 | }; 25 | 26 | class Payload { 27 | public: 28 | template 29 | Payload(const It begin, const It end) { 30 | for (It pair = begin; pair != end; ++pair) { 31 | AddPair(*pair); 32 | } 33 | } 34 | Payload(const std::initializer_list& pairs); 35 | 36 | void AddPair(const Pair& pair); 37 | 38 | std::string content; 39 | }; 40 | 41 | } // namespace cpr 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /vendors/cpr/include/cpr/proxies.h: -------------------------------------------------------------------------------- 1 | #ifndef CPR_PROXIES_H 2 | #define CPR_PROXIES_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | namespace cpr { 10 | 11 | class Proxies { 12 | public: 13 | Proxies() {} 14 | Proxies(const std::initializer_list>& hosts); 15 | 16 | bool has(const std::string& protocol) const; 17 | const std::string& operator[](const std::string& protocol); 18 | 19 | private: 20 | std::map hosts_; 21 | }; 22 | 23 | } // namespace cpr 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /vendors/cpr/include/cpr/response.h: -------------------------------------------------------------------------------- 1 | #ifndef CPR_RESPONSE_H 2 | #define CPR_RESPONSE_H 3 | 4 | #include 5 | #include 6 | 7 | #include "cpr/cookies.h" 8 | #include "cpr/cprtypes.h" 9 | #include "cpr/defines.h" 10 | #include "cpr/error.h" 11 | 12 | namespace cpr { 13 | 14 | class Response { 15 | public: 16 | Response() = default; 17 | 18 | template 20 | Response(const std::int32_t& p_status_code, TextType&& p_text, HeaderType&& p_header, UrlType&& p_url, 21 | const double& p_elapsed, CookiesType&& p_cookies = Cookies{}, 22 | ErrorType&& p_error = Error{}) 23 | : status_code{p_status_code}, text{CPR_FWD(p_text)}, header{CPR_FWD(p_header)}, 24 | url{CPR_FWD(p_url)}, elapsed{p_elapsed}, cookies{CPR_FWD(p_cookies)}, 25 | error{CPR_FWD(p_error)} {} 26 | 27 | std::int32_t status_code; 28 | std::string text; 29 | Header header; 30 | Url url; 31 | double elapsed; 32 | Cookies cookies; 33 | Error error; 34 | }; 35 | 36 | } // namespace cpr 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /vendors/cpr/include/cpr/session.h: -------------------------------------------------------------------------------- 1 | #ifndef CPR_SESSION_H 2 | #define CPR_SESSION_H 3 | 4 | #include 5 | #include 6 | 7 | #include "cpr/auth.h" 8 | #include "cpr/body.h" 9 | #include "cpr/cookies.h" 10 | #include "cpr/cprtypes.h" 11 | #include "cpr/digest.h" 12 | #include "cpr/low_speed.h" 13 | #include "cpr/max_redirects.h" 14 | #include "cpr/multipart.h" 15 | #include "cpr/parameters.h" 16 | #include "cpr/payload.h" 17 | #include "cpr/proxies.h" 18 | #include "cpr/response.h" 19 | #include "cpr/timeout.h" 20 | #include "cpr/connect_timeout.h" 21 | #include "cpr/low_speed.h" 22 | #include "cpr/ssl_options.h" 23 | #include "cpr/timeout.h" 24 | #include "cpr/user_agent.h" 25 | #include "cpr/session.h" 26 | #include "cpr/verbose.h" 27 | 28 | namespace cpr { 29 | 30 | class Session { 31 | public: 32 | Session(); 33 | ~Session(); 34 | 35 | void SetUrl(const Url& url); 36 | void SetParameters(const Parameters& parameters); 37 | void SetParameters(Parameters&& parameters); 38 | void SetHeader(const Header& header); 39 | void SetTimeout(const Timeout& timeout); 40 | void SetConnectTimeout(const ConnectTimeout& timeout); 41 | void SetAuth(const Authentication& auth); 42 | void SetDigest(const Digest& auth); 43 | void SetUserAgent(const UserAgent& ua); 44 | void SetPayload(Payload&& payload); 45 | void SetPayload(const Payload& payload); 46 | void SetProxies(Proxies&& proxies); 47 | void SetProxies(const Proxies& proxies); 48 | void SetMultipart(Multipart&& multipart); 49 | void SetMultipart(const Multipart& multipart); 50 | void SetRedirect(const bool& redirect); 51 | void SetMaxRedirects(const MaxRedirects& max_redirects); 52 | void SetCookies(const Cookies& cookies); 53 | void SetBody(Body&& body); 54 | void SetBody(const Body& body); 55 | void SetLowSpeed(const LowSpeed& low_speed); 56 | void SetVerifySsl(const VerifySsl& verify); 57 | 58 | // Used in templated functions 59 | void SetOption(const Url& url); 60 | void SetOption(const Parameters& parameters); 61 | void SetOption(Parameters&& parameters); 62 | void SetOption(const Header& header); 63 | void SetOption(const Timeout& timeout); 64 | void SetOption(const ConnectTimeout& timeout); 65 | void SetOption(const Authentication& auth); 66 | void SetOption(const Digest& auth); 67 | void SetOption(const UserAgent& ua); 68 | void SetOption(Payload&& payload); 69 | void SetOption(const Payload& payload); 70 | void SetOption(Proxies&& proxies); 71 | void SetOption(const Proxies& proxies); 72 | void SetOption(Multipart&& multipart); 73 | void SetOption(const Multipart& multipart); 74 | void SetOption(const bool& redirect); 75 | void SetOption(const MaxRedirects& max_redirects); 76 | void SetOption(const Cookies& cookies); 77 | void SetOption(Body&& body); 78 | void SetOption(const Body& body); 79 | void SetOption(const LowSpeed& low_speed); 80 | void SetOption(const VerifySsl& verify); 81 | void SetOption(const Verbose& verbose); 82 | 83 | Response Delete(); 84 | Response Get(); 85 | Response Head(); 86 | Response Options(); 87 | Response Patch(); 88 | Response Post(); 89 | Response Put(); 90 | 91 | private: 92 | class Impl; 93 | std::unique_ptr pimpl_; 94 | }; 95 | 96 | } // namespace cpr 97 | 98 | #endif 99 | -------------------------------------------------------------------------------- /vendors/cpr/include/cpr/ssl_options.h: -------------------------------------------------------------------------------- 1 | #ifndef CPR_SSLOPTIONS_H 2 | #define CPR_SSLOPTIONS_H 3 | 4 | namespace cpr { 5 | 6 | class VerifySsl { 7 | public: 8 | VerifySsl() {} 9 | VerifySsl(bool verify); 10 | 11 | operator bool() const; 12 | 13 | private: 14 | bool verify_ = true; 15 | }; 16 | 17 | } // namespace cpr 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /vendors/cpr/include/cpr/status_codes.h: -------------------------------------------------------------------------------- 1 | #ifndef _CPR_STATUS_CODES 2 | #define _CPR_STATUS_CODES 3 | #include 4 | namespace cpr { 5 | namespace status { 6 | // Information responses 7 | constexpr std::int32_t HTTP_CONTINUE = 100; 8 | constexpr std::int32_t HTTP_SWITCHING_PROTOCOL = 101; 9 | constexpr std::int32_t HTTP_PROCESSING = 102; 10 | constexpr std::int32_t HTTP_EARLY_HINTS = 103; 11 | // Sucessful responses 12 | constexpr std::int32_t HTTP_OK = 200; 13 | constexpr std::int32_t HTTP_CREATED = 201; 14 | constexpr std::int32_t HTTP_ACCEPTED = 202; 15 | constexpr std::int32_t HTTP_NON_AUTHORITATIVE_INFORMATION = 203; 16 | constexpr std::int32_t HTTP_NO_CONTENT = 204; 17 | constexpr std::int32_t HTTP_RESET_CONTENT = 205; 18 | constexpr std::int32_t HTTP_PARTIAL_CONTENT = 206; 19 | constexpr std::int32_t HTTP_MULTI_STATUS = 207; 20 | constexpr std::int32_t HTTP_ALREADY_REPORTED = 208; 21 | constexpr std::int32_t HTTP_IM_USED = 226; 22 | // Redirection messages 23 | constexpr std::int32_t HTTP_MULTIPLE_CHOICE = 300; 24 | constexpr std::int32_t HTTP_MOVED_PERMANENTLY = 301; 25 | constexpr std::int32_t HTTP_FOUND = 302; 26 | constexpr std::int32_t HTTP_SEE_OTHER = 303; 27 | constexpr std::int32_t HTTP_NOT_MODIFIED = 304; 28 | constexpr std::int32_t HTTP_USE_PROXY = 305; 29 | constexpr std::int32_t HTTP_UNUSED = 306; 30 | constexpr std::int32_t HTTP_TEMPORARY_REDIRECT = 307; 31 | constexpr std::int32_t HTTP_PERMANENT_REDIRECT = 308; 32 | // Client error responses 33 | constexpr std::int32_t HTTP_BAD_REQUEST = 400; 34 | constexpr std::int32_t HTTP_UNAUTHORIZED = 401; 35 | constexpr std::int32_t HTTP_PAYMENT_REQUIRED = 402; 36 | constexpr std::int32_t HTTP_FORBIDDEN = 403; 37 | constexpr std::int32_t HTTP_NOT_FOUND = 404; 38 | constexpr std::int32_t HTTP_METHOD_NOT_ALLOWED = 405; 39 | constexpr std::int32_t HTTP_NOT_ACCEPTABLE = 406; 40 | constexpr std::int32_t HTTP_PROXY_AUTHENTICATION_REQUIRED = 407; 41 | constexpr std::int32_t HTTP_REQUEST_TIMEOUT = 408; 42 | constexpr std::int32_t HTTP_CONFLICT = 409; 43 | constexpr std::int32_t HTTP_GONE = 410; 44 | constexpr std::int32_t HTTP_LENGTH_REQUIRED = 411; 45 | constexpr std::int32_t HTTP_PRECONDITION_FAILED = 412; 46 | constexpr std::int32_t HTTP_PAYLOAD_TOO_LARGE = 413; 47 | constexpr std::int32_t HTTP_URI_TOO_LONG = 414; 48 | constexpr std::int32_t HTTP_UNSUPPORTED_MEDIA_TYPE = 415; 49 | constexpr std::int32_t HTTP_REQUESTED_RANGE_NOT_SATISFIABLE = 416; 50 | constexpr std::int32_t HTTP_EXPECTATION_FAILED = 417; 51 | constexpr std::int32_t HTTP_IM_A_TEAPOT = 418; 52 | constexpr std::int32_t HTTP_MISDIRECTED_REQUEST = 421; 53 | constexpr std::int32_t HTTP_UNPROCESSABLE_ENTITY = 422; 54 | constexpr std::int32_t HTTP_LOCKED = 423; 55 | constexpr std::int32_t HTTP_FAILED_DEPENDENCY = 424; 56 | constexpr std::int32_t HTTP_TOO_EARLY = 425; 57 | constexpr std::int32_t HTTP_UPGRADE_REQUIRED = 426; 58 | constexpr std::int32_t HTTP_PRECONDITION_REQUIRED = 428; 59 | constexpr std::int32_t HTTP_TOO_MANY_REQUESTS = 429; 60 | constexpr std::int32_t HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE = 431; 61 | constexpr std::int32_t HTTP_UNAVAILABLE_FOR_LEGAL_REASONS = 451; 62 | // Server response errors 63 | constexpr std::int32_t HTTP_INTERNAL_SERVER_ERROR = 500; 64 | constexpr std::int32_t HTTP_NOT_IMPLEMENTED = 501; 65 | constexpr std::int32_t HTTP_BAD_GATEWAY = 502; 66 | constexpr std::int32_t HTTP_SERVICE_UNAVAILABLE = 503; 67 | constexpr std::int32_t HTTP_GATEWAY_TIMEOUT = 504; 68 | constexpr std::int32_t HTTP_HTTP_VERSION_NOT_SUPPORTED = 505; 69 | constexpr std::int32_t HTTP_VARIANT_ALSO_NEGOTIATES = 506; 70 | constexpr std::int32_t HTTP_INSUFFICIENT_STORAGE = 507; 71 | constexpr std::int32_t HTTP_LOOP_DETECTED = 508; 72 | constexpr std::int32_t HTTP_NOT_EXTENDED = 510; 73 | constexpr std::int32_t HTTP_NETWORK_AUTHENTICATION_REQUIRED = 511; 74 | 75 | constexpr bool is_informational(const std::int32_t code) { 76 | return (code >= 100 && code < 200); 77 | } 78 | constexpr bool is_success(const std::int32_t code) { 79 | return (code >= 200 && code < 300); 80 | } 81 | constexpr bool is_redirect(const std::int32_t code) { 82 | return (code >= 300 && code < 400); 83 | } 84 | constexpr bool is_client_error(const std::int32_t code) { 85 | return (code >= 400 && code < 500); 86 | } 87 | constexpr bool is_server_error(const std::int32_t code) { 88 | return (code >= 500 && code < 600); 89 | } 90 | 91 | } // namespace status 92 | } // namespace cpr 93 | #endif -------------------------------------------------------------------------------- /vendors/cpr/include/cpr/timeout.h: -------------------------------------------------------------------------------- 1 | #ifndef CPR_TIMEOUT_H 2 | #define CPR_TIMEOUT_H 3 | 4 | #include 5 | #include 6 | 7 | namespace cpr { 8 | 9 | class Timeout { 10 | public: 11 | Timeout(const std::chrono::milliseconds& duration) : ms{duration} {} 12 | Timeout(const std::int32_t& milliseconds) : Timeout{std::chrono::milliseconds(milliseconds)} {} 13 | 14 | long Milliseconds() const; 15 | 16 | std::chrono::milliseconds ms; 17 | }; 18 | 19 | } // namespace cpr 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /vendors/cpr/include/cpr/user_agent.h: -------------------------------------------------------------------------------- 1 | #ifndef CPR_USERAGENT_H 2 | #define CPR_USERAGENT_H 3 | 4 | #include 5 | #include 6 | 7 | namespace cpr { 8 | 9 | class UserAgent : public std::string { 10 | public: 11 | UserAgent() = default; 12 | UserAgent(const UserAgent&) = default; 13 | UserAgent(UserAgent&&) = default; 14 | 15 | explicit UserAgent(const char* raw_string) : std::string(raw_string) {} 16 | explicit UserAgent(const char* raw_string, size_t length) : std::string(raw_string, length) {} 17 | explicit UserAgent(size_t to_fill, char character) : std::string(to_fill, character) {} 18 | explicit UserAgent(const std::string& std_string) : std::string(std_string) {} 19 | explicit UserAgent(const std::string& std_string, size_t position, 20 | size_t length = std::string::npos) 21 | : std::string(std_string, position, length) {} 22 | explicit UserAgent(std::string&& std_string) : std::string(std::move(std_string)) {} 23 | explicit UserAgent(std::initializer_list il) : std::string(il) {} 24 | template 25 | explicit UserAgent(InputIterator first, InputIterator last) : std::string(first, last) {} 26 | 27 | UserAgent& operator=(const UserAgent&) = default; 28 | UserAgent& operator=(UserAgent&&) = default; 29 | }; 30 | 31 | } // namespace cpr 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /vendors/cpr/include/cpr/util.h: -------------------------------------------------------------------------------- 1 | #ifndef CPR_UTIL_H 2 | #define CPR_UTIL_H 3 | 4 | #include 5 | #include 6 | 7 | #include "cpr/cprtypes.h" 8 | 9 | namespace cpr { 10 | namespace util { 11 | 12 | Header parseHeader(const std::string& headers); 13 | size_t writeFunction(void* ptr, size_t size, size_t nmemb, std::string* data); 14 | std::vector split(const std::string& to_split, char delimiter); 15 | std::string urlEncode(const std::string& response); 16 | 17 | } // namespace util 18 | } // namespace cpr 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /vendors/cpr/include/cpr/verbose.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef CPR_VERBOSE_H_ 3 | #define CPR_VERBOSE_H_ 4 | 5 | #include 6 | 7 | namespace cpr { 8 | 9 | class Verbose { 10 | public: 11 | Verbose(const bool verbose) : verbose{verbose} {} 12 | 13 | bool verbose; 14 | }; 15 | 16 | } // namespace cpr 17 | 18 | 19 | 20 | #endif /* CPR_VERBOSE_H_ */ 21 | -------------------------------------------------------------------------------- /vendors/cpr/opt/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | macro(set_cache_variable VAR_NAME VAR_DESCRIPTION) 2 | set(${VAR_NAME} ${${VAR_NAME}} CACHE INTERNAL ${VAR_DESCRIPTION}) 3 | message(STATUS "Set ${VAR_NAME} to ${${VAR_NAME}}.") 4 | endmacro() 5 | 6 | 7 | # Code coverage 8 | 9 | if(BUILD_CPR_TESTS AND GENERATE_COVERAGE) 10 | set(CMAKE_BUILD_TYPE COVERAGE CACHE INTERNAL "Coverage enabled build") 11 | message(STATUS "Enabling gcov support") 12 | if(NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") 13 | set(COVERAGE_FLAG "--coverage") 14 | endif() 15 | set(CMAKE_CXX_FLAGS_COVERAGE 16 | "-g -O0 ${COVERAGE_FLAG} -fprofile-arcs -ftest-coverage" 17 | CACHE STRING "Flags used by the C++ compiler during coverage builds." 18 | FORCE) 19 | set(CMAKE_C_FLAGS_COVERAGE 20 | "-g -O0 ${COVERAGE_FLAG} -fprofile-arcs -ftest-coverage" 21 | CACHE STRING "Flags used by the C compiler during coverage builds." 22 | FORCE) 23 | set(CMAKE_EXE_LINKER_FLAGS_COVERAGE 24 | "" 25 | CACHE STRING "Flags used for linking binaries during coverage builds." 26 | FORCE) 27 | set(CMAKE_SHARED_LINKER_FLAGS_COVERAGE 28 | "" 29 | CACHE STRING "Flags used by the shared libraries linker during coverage builds." 30 | FORCE) 31 | mark_as_advanced( 32 | CMAKE_CXX_FLAGS_COVERAGE 33 | CMAKE_C_FLAGS_COVERAGE 34 | CMAKE_EXE_LINKER_FLAGS_COVERAGE 35 | CMAKE_SHARED_LINKER_FLAGS_COVERAGE) 36 | endif() 37 | 38 | 39 | # Curl configuration 40 | 41 | if(USE_SYSTEM_CURL) 42 | find_package(CURL) 43 | endif() 44 | if(NOT USE_SYSTEM_CURL OR NOT CURL_FOUND) 45 | message(STATUS "Not using system Curl, using built-in curl project instead.") 46 | option(BUILD_TESTING "Set to ON to build cURL tests." OFF) 47 | option(BUILD_CURL_EXE "Set to ON to build cURL executable." OFF) 48 | add_subdirectory(curl EXCLUDE_FROM_ALL) 49 | set(CURL_FOUND TRUE) 50 | set(CURL_LIBRARIES libcurl) 51 | set(CURL_INCLUDE_DIRS 52 | ${CURL_SOURCE_DIR}/include 53 | ${CURL_BINARY_DIR}/include/curl) 54 | 55 | # Group under the "external" project folder in IDEs such as Visual Studio. 56 | if(BUILD_CURL_EXE) 57 | set_property(TARGET curl PROPERTY FOLDER "external") 58 | endif() 59 | 60 | set_property(TARGET libcurl PROPERTY FOLDER "external") 61 | endif() 62 | 63 | set_cache_variable(CURL_FOUND "Set if libcurl is found or built") 64 | set_cache_variable(CURL_LIBRARIES "Location of libcurl") 65 | set_cache_variable(CURL_INCLUDE_DIRS "Location of curl include files") 66 | 67 | 68 | # GTest configuration 69 | 70 | if(BUILD_CPR_TESTS) 71 | if(USE_SYSTEM_GTEST) 72 | find_package(GTest) 73 | endif() 74 | if(NOT USE_SYSTEM_GTEST OR NOT GTEST_FOUND) 75 | message(STATUS "Not using system gtest, using built-in googletest project instead.") 76 | if(MSVC) 77 | # By default, GTest compiles on Windows in CRT static linkage mode. We use this 78 | # variable to force it into using the CRT in dynamic linkage (DLL), just as CPR 79 | # does. 80 | set(gtest_force_shared_crt ON CACHE BOOL "Force gtest to use the shared c runtime") 81 | endif() 82 | add_subdirectory(googletest) 83 | set(GTEST_FOUND TRUE) 84 | set(GTEST_LIBRARIES gtest) 85 | set(GTEST_MAIN_LIBRARIES gtest_main) 86 | set(GTEST_BOTH_LIBRARIES gtest gtest_main) 87 | set(GTEST_INCLUDE_DIRS ${gtest_SOURCE_DIR}/include) 88 | 89 | # Group under the "tests/gtest" project folder in IDEs such as Visual Studio. 90 | set_property(TARGET gtest PROPERTY FOLDER "tests/gtest") 91 | set_property(TARGET gtest_main PROPERTY FOLDER "tests/gtest") 92 | endif() 93 | 94 | set_cache_variable(GTEST_FOUND "Set if libgtest was found or built") 95 | set_cache_variable(GTEST_LIBRARIES "Location of libgtest") 96 | set_cache_variable(GTEST_MAIN_LIBRARIES "Location of libgtest-main") 97 | set_cache_variable(GTEST_BOTH_LIBRARIES "Location of both gtest libraries") 98 | set_cache_variable(GTEST_INCLUDE_DIRS "Location of gtest include files") 99 | endif() 100 | 101 | 102 | # Mongoose configuration 103 | 104 | if(BUILD_CPR_TESTS) 105 | message(STATUS "Building mongoose project for test support.") 106 | add_subdirectory(mongoose) 107 | set(MONGOOSE_FOUND TRUE) 108 | set(MONGOOSE_LIBRARIES mongoose) 109 | set(MONGOOSE_INCLUDE_DIRS ${mongoose_SOURCE_DIR}) 110 | 111 | set_cache_variable(MONGOOSE_FOUND "Set if libmongoose was found or built") 112 | set_cache_variable(MONGOOSE_LIBRARIES "Location of libmongoose") 113 | set_cache_variable(MONGOOSE_INCLUDE_DIRS "Location of mongoose include files") 114 | 115 | # Group under the "external" project folder in IDEs such as Visual Studio. 116 | set_property(TARGET mongoose PROPERTY FOLDER "external") 117 | endif() 118 | -------------------------------------------------------------------------------- /vendors/cpr/test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | find_package(Threads) 2 | set(TEST_SERVER_LIBRARY test_server) 3 | add_library(${TEST_SERVER_LIBRARY} 4 | server.cpp) 5 | target_link_libraries(${TEST_SERVER_LIBRARY} 6 | ${MONGOOSE_LIBRARIES} 7 | ${CMAKE_THREAD_LIBS_INIT}) 8 | 9 | macro(add_cpr_test _TEST_NAME) 10 | add_executable(${_TEST_NAME}_tests 11 | ${_TEST_NAME}_tests.cpp) 12 | target_link_libraries(${_TEST_NAME}_tests 13 | ${TEST_SERVER_LIBRARY} 14 | ${GTEST_LIBRARIES} 15 | ${CPR_LIBRARIES}) 16 | add_test(NAME cpr_${_TEST_NAME}_tests COMMAND ${_TEST_NAME}_tests) 17 | # Group under the "tests" project folder in IDEs such as Visual Studio. 18 | set_property(TARGET ${_TEST_NAME}_tests PROPERTY FOLDER "tests") 19 | if(WIN32) 20 | set(LIBCURL_DLL_NAME "libcurl.dll") 21 | if(CMAKE_BUILD_TYPE STREQUAL "DEBUG") 22 | set(LIBCURL_DLL_NAME "libcurl-d.dll") 23 | endif() 24 | add_custom_command(TARGET ${_TEST_NAME}_tests POST_BUILD 25 | COMMAND ${CMAKE_COMMAND} -E copy 26 | $/${LIBCURL_DLL_NAME} $) 27 | endif() 28 | endmacro() 29 | 30 | include_directories( 31 | ${CURL_INCLUDE_DIRS} 32 | ${CMAKE_CURRENT_SOURCE_DIR} 33 | ${CPR_INCLUDE_DIRS} 34 | ${GTEST_INCLUDE_DIRS} 35 | ${MONGOOSE_INCLUDE_DIRS}) 36 | 37 | add_cpr_test(get) 38 | add_cpr_test(post) 39 | add_cpr_test(session) 40 | add_cpr_test(async) 41 | add_cpr_test(proxy) 42 | add_cpr_test(head) 43 | add_cpr_test(delete) 44 | add_cpr_test(put) 45 | add_cpr_test(callback) 46 | add_cpr_test(raw_body) 47 | add_cpr_test(options) 48 | add_cpr_test(patch) 49 | add_cpr_test(error) 50 | add_cpr_test(alternating) 51 | add_cpr_test(util) 52 | -------------------------------------------------------------------------------- /vendors/cpr/test/alternating_tests.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | #include 6 | 7 | #include "server.h" 8 | 9 | using namespace cpr; 10 | 11 | static Server* server = new Server(); 12 | auto base = server->GetBaseUrl(); 13 | 14 | TEST(AlternatingTests, PutGetTest) { 15 | auto url = Url{base + "/header_reflect.html"}; 16 | Session session; 17 | session.SetUrl(url); 18 | 19 | { 20 | auto payload = Payload{{"x", "5"}}; 21 | auto response = cpr::Put(url, payload); 22 | auto expected_text = std::string{"Header reflect PUT"}; 23 | EXPECT_EQ(expected_text, response.text); 24 | EXPECT_EQ(url, response.url); 25 | EXPECT_EQ(200, response.status_code); 26 | EXPECT_EQ(ErrorCode::OK, response.error.code); 27 | } 28 | 29 | { 30 | auto response = cpr::Get(url); 31 | auto expected_text = std::string{"Header reflect GET"}; 32 | EXPECT_EQ(expected_text, response.text); 33 | EXPECT_EQ(url, response.url); 34 | EXPECT_EQ(200, response.status_code); 35 | EXPECT_EQ(ErrorCode::OK, response.error.code); 36 | } 37 | } 38 | 39 | TEST(AlternatingTests, PutGetPutGetTest) { 40 | auto url = Url{base + "/header_reflect.html"}; 41 | Session session; 42 | session.SetUrl(url); 43 | 44 | { 45 | auto payload = Payload{{"x", "5"}}; 46 | auto response = cpr::Put(url, payload); 47 | auto expected_text = std::string{"Header reflect PUT"}; 48 | EXPECT_EQ(expected_text, response.text); 49 | EXPECT_EQ(url, response.url); 50 | EXPECT_EQ(200, response.status_code); 51 | EXPECT_EQ(ErrorCode::OK, response.error.code); 52 | } 53 | 54 | { 55 | auto response = cpr::Get(url); 56 | auto expected_text = std::string{"Header reflect GET"}; 57 | EXPECT_EQ(expected_text, response.text); 58 | EXPECT_EQ(url, response.url); 59 | EXPECT_EQ(200, response.status_code); 60 | EXPECT_EQ(ErrorCode::OK, response.error.code); 61 | } 62 | 63 | { 64 | auto payload = Payload{{"x", "5"}}; 65 | auto response = cpr::Put(url, payload); 66 | auto expected_text = std::string{"Header reflect PUT"}; 67 | EXPECT_EQ(expected_text, response.text); 68 | EXPECT_EQ(url, response.url); 69 | EXPECT_EQ(200, response.status_code); 70 | EXPECT_EQ(ErrorCode::OK, response.error.code); 71 | } 72 | 73 | { 74 | auto response = cpr::Get(url); 75 | auto expected_text = std::string{"Header reflect GET"}; 76 | EXPECT_EQ(expected_text, response.text); 77 | EXPECT_EQ(url, response.url); 78 | EXPECT_EQ(200, response.status_code); 79 | EXPECT_EQ(ErrorCode::OK, response.error.code); 80 | } 81 | } 82 | 83 | TEST(AlternatingTests, HeadGetTest) { 84 | auto url = Url{base + "/header_reflect.html"}; 85 | Session session; 86 | session.SetUrl(url); 87 | 88 | { 89 | // Head shouldn't return a body 90 | auto response = cpr::Head(url); 91 | auto expected_text = std::string{""}; 92 | EXPECT_EQ(expected_text, response.text); 93 | EXPECT_EQ(url, response.url); 94 | EXPECT_EQ(200, response.status_code); 95 | EXPECT_EQ(ErrorCode::OK, response.error.code); 96 | } 97 | 98 | { 99 | auto response = cpr::Get(url); 100 | auto expected_text = std::string{"Header reflect GET"}; 101 | EXPECT_EQ(expected_text, response.text); 102 | EXPECT_EQ(url, response.url); 103 | EXPECT_EQ(200, response.status_code); 104 | EXPECT_EQ(ErrorCode::OK, response.error.code); 105 | } 106 | } 107 | 108 | TEST(AlternatingTests, PutHeadTest) { 109 | auto url = Url{base + "/header_reflect.html"}; 110 | Session session; 111 | session.SetUrl(url); 112 | 113 | { 114 | auto payload = Payload{{"x", "5"}}; 115 | auto response = cpr::Put(url, payload); 116 | auto expected_text = std::string{"Header reflect PUT"}; 117 | EXPECT_EQ(expected_text, response.text); 118 | EXPECT_EQ(url, response.url); 119 | EXPECT_EQ(200, response.status_code); 120 | EXPECT_EQ(ErrorCode::OK, response.error.code); 121 | } 122 | 123 | { 124 | // Head shouldn't return a body 125 | auto response = cpr::Head(url); 126 | auto expected_text = std::string{""}; 127 | EXPECT_EQ(expected_text, response.text); 128 | EXPECT_EQ(url, response.url); 129 | EXPECT_EQ(200, response.status_code); 130 | EXPECT_EQ(ErrorCode::OK, response.error.code); 131 | } 132 | } 133 | 134 | TEST(AlternatingTests, PutPostTest) { 135 | auto url = Url{base + "/header_reflect.html"}; 136 | Session session; 137 | session.SetUrl(url); 138 | 139 | { 140 | auto payload = Payload{{"x", "5"}}; 141 | auto response = cpr::Put(url, payload); 142 | auto expected_text = std::string{"Header reflect PUT"}; 143 | EXPECT_EQ(expected_text, response.text); 144 | EXPECT_EQ(url, response.url); 145 | EXPECT_EQ(200, response.status_code); 146 | EXPECT_EQ(ErrorCode::OK, response.error.code); 147 | } 148 | 149 | { 150 | auto payload = Payload{{"x", "5"}}; 151 | auto response = cpr::Post(url, payload); 152 | auto expected_text = std::string{"Header reflect POST"}; 153 | EXPECT_EQ(expected_text, response.text); 154 | EXPECT_EQ(url, response.url); 155 | EXPECT_EQ(200, response.status_code); 156 | EXPECT_EQ(ErrorCode::OK, response.error.code); 157 | } 158 | } 159 | 160 | int main(int argc, char** argv) { 161 | ::testing::InitGoogleTest(&argc, argv); 162 | ::testing::AddGlobalTestEnvironment(server); 163 | return RUN_ALL_TESTS(); 164 | } 165 | -------------------------------------------------------------------------------- /vendors/cpr/test/async_tests.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | 8 | #include "server.h" 9 | 10 | 11 | static Server* server = new Server(); 12 | auto base = server->GetBaseUrl(); 13 | 14 | TEST(UrlEncodedPostTests, AsyncGetTest) { 15 | auto url = Url{base + "/hello.html"}; 16 | auto future = cpr::GetAsync(url); 17 | auto expected_text = std::string{"Hello world!"}; 18 | auto response = future.get(); 19 | EXPECT_EQ(expected_text, response.text); 20 | EXPECT_EQ(url, response.url); 21 | EXPECT_EQ(std::string{"text/html"}, response.header["content-type"]); 22 | EXPECT_EQ(200, response.status_code); 23 | } 24 | 25 | TEST(UrlEncodedPostTests, AsyncGetMultipleTest) { 26 | auto url = Url{base + "/hello.html"}; 27 | std::vector responses; 28 | for (int i = 0; i < 10; ++i) { 29 | responses.emplace_back(cpr::GetAsync(url)); 30 | } 31 | for (auto& future : responses) { 32 | auto expected_text = std::string{"Hello world!"}; 33 | auto response = future.get(); 34 | EXPECT_EQ(expected_text, response.text); 35 | EXPECT_EQ(url, response.url); 36 | EXPECT_EQ(std::string{"text/html"}, response.header["content-type"]); 37 | EXPECT_EQ(200, response.status_code); 38 | } 39 | } 40 | 41 | TEST(UrlEncodedPostTests, AsyncGetMultipleReflectTest) { 42 | auto url = Url{base + "/hello.html"}; 43 | std::vector responses; 44 | for (int i = 0; i < 100; ++i) { 45 | auto p = Parameters{{"key", std::to_string(i)}}; 46 | responses.emplace_back(cpr::GetAsync(url, p)); 47 | } 48 | int i = 0; 49 | for (auto& future : responses) { 50 | auto expected_text = std::string{"Hello world!"}; 51 | auto response = future.get(); 52 | EXPECT_EQ(expected_text, response.text); 53 | auto expected_url = Url{url + "?key=" + std::to_string(i)}; 54 | EXPECT_EQ(expected_url, response.url); 55 | EXPECT_EQ(std::string{"text/html"}, response.header["content-type"]); 56 | EXPECT_EQ(200, response.status_code); 57 | ++i; 58 | } 59 | } 60 | 61 | int main(int argc, char** argv) { 62 | ::testing::InitGoogleTest(&argc, argv); 63 | ::testing::AddGlobalTestEnvironment(server); 64 | return RUN_ALL_TESTS(); 65 | } 66 | -------------------------------------------------------------------------------- /vendors/cpr/test/error_tests.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | #include "server.h" 10 | 11 | using namespace cpr; 12 | 13 | static Server* server = new Server(); 14 | auto base = server->GetBaseUrl(); 15 | auto baseSSL = server->GetBaseUrlSSL(); 16 | 17 | TEST(ErrorTests, BasicSSLFailure) { 18 | auto url = Url{baseSSL + "/hello.html"}; 19 | auto response = cpr::Get(url); 20 | EXPECT_EQ(url, response.url); 21 | EXPECT_EQ(0, response.status_code); 22 | auto curl_version = curl_version_info(CURLVERSION_NOW); 23 | auto expected = ErrorCode::UNSUPPORTED_PROTOCOL; 24 | if(curl_version->features & CURL_VERSION_SSL) { 25 | expected = ErrorCode::SSL_CONNECT_ERROR; 26 | } 27 | EXPECT_EQ(expected, response.error.code); 28 | 29 | } 30 | 31 | TEST(ErrorTests, UnsupportedProtocolFailure) { 32 | auto url = Url{"urk://wat.is.this"}; 33 | auto response = cpr::Get(url); 34 | EXPECT_EQ(0, response.status_code); 35 | EXPECT_EQ(ErrorCode::UNSUPPORTED_PROTOCOL, response.error.code); 36 | } 37 | 38 | TEST(ErrorTests, InvalidURLFailure) { 39 | auto url = Url{"???"}; 40 | auto response = cpr::Get(url); 41 | EXPECT_EQ(0, response.status_code); 42 | EXPECT_EQ(ErrorCode::INVALID_URL_FORMAT, response.error.code); 43 | } 44 | 45 | TEST(ErrorTests, TimeoutFailure) { 46 | auto url = Url{base + "/timeout.html"}; 47 | auto response = cpr::Get(url, cpr::Timeout{1}); 48 | EXPECT_EQ(0, response.status_code); 49 | EXPECT_EQ(ErrorCode::OPERATION_TIMEDOUT, response.error.code); 50 | } 51 | 52 | TEST(ErrorTests, ChronoTimeoutFailure) { 53 | auto url = Url{base + "/timeout.html"}; 54 | auto response = cpr::Get(url, cpr::Timeout{std::chrono::milliseconds{1}}); 55 | EXPECT_EQ(0, response.status_code); 56 | EXPECT_EQ(ErrorCode::OPERATION_TIMEDOUT, response.error.code); 57 | } 58 | 59 | TEST(ErrorTests, ConnectTimeoutFailure) { 60 | auto url = Url{"http://localhost:67"}; 61 | auto response = cpr::Get(url, cpr::ConnectTimeout{1}); 62 | EXPECT_EQ(0, response.status_code); 63 | EXPECT_EQ(ErrorCode::OPERATION_TIMEDOUT, response.error.code); 64 | } 65 | 66 | TEST(ErrorTests, ChronoConnectTimeoutFailure) { 67 | auto url = Url{"http://localhost:67"}; 68 | auto response = cpr::Get(url, cpr::ConnectTimeout{std::chrono::milliseconds{1}}); 69 | EXPECT_EQ(0, response.status_code); 70 | EXPECT_EQ(ErrorCode::OPERATION_TIMEDOUT, response.error.code); 71 | } 72 | 73 | TEST(ErrorTests, LowSpeedTimeFailure) { 74 | auto url = Url{base + "/low_speed.html"}; 75 | auto response = cpr::Get(url, cpr::LowSpeed{1000, 1}); 76 | EXPECT_EQ(0, response.status_code); 77 | EXPECT_EQ(ErrorCode::OPERATION_TIMEDOUT, response.error.code); 78 | } 79 | 80 | TEST(ErrorTests, LowSpeedBytesFailure) { 81 | auto url = Url{base + "/low_speed_bytes.html"}; 82 | auto response = cpr::Get(url, cpr::LowSpeed{1000, 1}); 83 | EXPECT_EQ(0, response.status_code); 84 | EXPECT_EQ(ErrorCode::OPERATION_TIMEDOUT, response.error.code); 85 | } 86 | 87 | TEST(ErrorTests, ProxyFailure) { 88 | auto url = Url{base + "/hello.html"}; 89 | auto response = cpr::Get(url, cpr::Proxies{{"http", "http://bad_host/"}}); 90 | EXPECT_EQ(url, response.url); 91 | EXPECT_EQ(0, response.status_code); 92 | EXPECT_EQ(ErrorCode::PROXY_RESOLUTION_FAILURE, response.error.code); 93 | } 94 | 95 | TEST(ErrorTests, BoolFalseTest) { 96 | Error error; 97 | EXPECT_FALSE(error); 98 | } 99 | 100 | TEST(ErrorTests, BoolTrueTest) { 101 | Error error; 102 | error.code = ErrorCode::UNSUPPORTED_PROTOCOL; 103 | EXPECT_TRUE(error); 104 | } 105 | 106 | int main(int argc, char** argv) { 107 | ::testing::InitGoogleTest(&argc, argv); 108 | ::testing::AddGlobalTestEnvironment(server); 109 | return RUN_ALL_TESTS(); 110 | } 111 | -------------------------------------------------------------------------------- /vendors/cpr/test/options_tests.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | #include 6 | 7 | #include "server.h" 8 | 9 | using namespace cpr; 10 | 11 | static Server* server = new Server(); 12 | auto base = server->GetBaseUrl(); 13 | 14 | TEST(OptionsTests, BaseUrlTest) { 15 | auto url = Url{base + "/"}; 16 | auto response = cpr::Options(url); 17 | auto expected_text = std::string{""}; 18 | EXPECT_EQ(expected_text, response.text); 19 | EXPECT_EQ(url, response.url); 20 | EXPECT_EQ(std::string{"GET, POST, PUT, DELETE, PATCH, OPTIONS"}, 21 | response.header["Access-Control-Allow-Methods"]); 22 | EXPECT_EQ(200, response.status_code); 23 | EXPECT_EQ(ErrorCode::OK, response.error.code); 24 | } 25 | 26 | TEST(OptionsTests, SpecificUrlTest) { 27 | auto url = Url{base + "/hello.html"}; 28 | auto response = cpr::Options(url); 29 | auto expected_text = std::string{""}; 30 | EXPECT_EQ(expected_text, response.text); 31 | EXPECT_EQ(url, response.url); 32 | EXPECT_EQ(std::string{"GET, OPTIONS"}, 33 | response.header["Access-Control-Allow-Methods"]); 34 | EXPECT_EQ(200, response.status_code); 35 | EXPECT_EQ(ErrorCode::OK, response.error.code); 36 | } 37 | 38 | TEST(OptionsTests, AsyncBaseUrlTest) { 39 | auto url = Url{base + "/"}; 40 | std::vector responses; 41 | for (int i = 0; i < 10; ++i) { 42 | responses.emplace_back(cpr::OptionsAsync(url)); 43 | } 44 | for (auto& future_response : responses) { 45 | auto response = future_response.get(); 46 | auto expected_text = std::string{""}; 47 | EXPECT_EQ(expected_text, response.text); 48 | EXPECT_EQ(url, response.url); 49 | EXPECT_EQ(std::string{"GET, POST, PUT, DELETE, PATCH, OPTIONS"}, 50 | response.header["Access-Control-Allow-Methods"]); 51 | EXPECT_EQ(200, response.status_code); 52 | EXPECT_EQ(ErrorCode::OK, response.error.code); 53 | } 54 | } 55 | 56 | TEST(OptionsTests, AsyncSpecificUrlTest) { 57 | auto url = Url{base + "/hello.html"}; 58 | std::vector responses; 59 | for (int i = 0; i < 10; ++i) { 60 | responses.emplace_back(cpr::OptionsAsync(url)); 61 | } 62 | for (auto& future_response : responses) { 63 | auto response = future_response.get(); 64 | auto expected_text = std::string{""}; 65 | EXPECT_EQ(expected_text, response.text); 66 | EXPECT_EQ(url, response.url); 67 | EXPECT_EQ(std::string{"GET, OPTIONS"}, 68 | response.header["Access-Control-Allow-Methods"]); 69 | EXPECT_EQ(200, response.status_code); 70 | EXPECT_EQ(ErrorCode::OK, response.error.code); 71 | } 72 | } 73 | 74 | int main(int argc, char** argv) { 75 | ::testing::InitGoogleTest(&argc, argv); 76 | ::testing::AddGlobalTestEnvironment(server); 77 | return RUN_ALL_TESTS(); 78 | } 79 | -------------------------------------------------------------------------------- /vendors/cpr/test/proxy_tests.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | #include 6 | 7 | // TODO: This uses public servers for proxies and endpoints. This should be replaced with a source 8 | // code implementation inside server.cpp 9 | 10 | #define HTTP_PROXY "104.131.214.38:3128" 11 | #define HTTPS_PROXY "104.131.214.38:3128" 12 | 13 | using namespace cpr; 14 | 15 | TEST(ProxyTests, SingleProxyTest) { 16 | auto url = Url{"http://www.httpbin.org/get"}; 17 | auto response = cpr::Get(url, Proxies{{"http", HTTP_PROXY}}); 18 | EXPECT_EQ(url, response.url); 19 | EXPECT_EQ(std::string{"application/json"}, response.header["content-type"]); 20 | EXPECT_EQ(200, response.status_code); 21 | EXPECT_EQ(ErrorCode::OK, response.error.code); 22 | } 23 | 24 | TEST(ProxyTests, MultipleProxyHttpTest) { 25 | auto url = Url{"http://www.httpbin.org/get"}; 26 | auto response = cpr::Get(url, Proxies{{"http", HTTP_PROXY}, 27 | {"https", HTTPS_PROXY}}); 28 | EXPECT_EQ(url, response.url); 29 | EXPECT_EQ(std::string{"application/json"}, response.header["content-type"]); 30 | EXPECT_EQ(200, response.status_code); 31 | EXPECT_EQ(ErrorCode::OK, response.error.code); 32 | } 33 | 34 | // TODO: These should be fixed after a source code implementation of an HTTPS proxy 35 | #if defined(false) 36 | TEST(ProxyTests, ProxyHttpsTest) { 37 | auto url = Url{"https://www.httpbin.org/get"}; 38 | auto response = cpr::Get(url, Proxies{{"https", HTTPS_PROXY}}); 39 | EXPECT_EQ(url, response.url); 40 | EXPECT_EQ(std::string{"application/json"}, response.header["content-type"]); 41 | EXPECT_EQ(200, response.status_code); 42 | EXPECT_EQ(ErrorCode::OK, response.error.code); 43 | } 44 | 45 | TEST(ProxyTests, MultipleProxyHttpsTest) { 46 | auto url = Url{"https://www.httpbin.org/get"}; 47 | auto response = cpr::Get(url, Proxies{{"http", HTTP_PROXY}, 48 | {"https", HTTPS_PROXY}}); 49 | EXPECT_EQ(url, response.url); 50 | EXPECT_EQ(std::string{"application/json"}, response.header["content-type"]); 51 | EXPECT_EQ(200, response.status_code); 52 | EXPECT_EQ(ErrorCode::OK, response.error.code); 53 | } 54 | #endif 55 | 56 | TEST(ProxyTests, CopyProxyTest) { 57 | auto url = Url{"http://www.httpbin.org/get"}; 58 | auto proxies = Proxies{{"http", HTTP_PROXY}}; 59 | auto response = cpr::Get(url, proxies); 60 | EXPECT_EQ(url, response.url); 61 | EXPECT_EQ(std::string{"application/json"}, response.header["content-type"]); 62 | EXPECT_EQ(200, response.status_code); 63 | EXPECT_EQ(ErrorCode::OK, response.error.code); 64 | } 65 | 66 | TEST(ProxyTests, ProxySessionTest) { 67 | auto url = Url{"http://www.httpbin.org/get"}; 68 | Session session; 69 | session.SetUrl(url); 70 | session.SetProxies(Proxies{{"http", HTTP_PROXY}}); 71 | auto response = session.Get(); 72 | EXPECT_EQ(url, response.url); 73 | EXPECT_EQ(std::string{"application/json"}, response.header["content-type"]); 74 | EXPECT_EQ(200, response.status_code); 75 | EXPECT_EQ(ErrorCode::OK, response.error.code); 76 | } 77 | 78 | TEST(ProxyTests, ReferenceProxySessionTest) { 79 | auto url = Url{"http://www.httpbin.org/get"}; 80 | auto proxies = Proxies{{"http", HTTP_PROXY}}; 81 | Session session; 82 | session.SetUrl(url); 83 | session.SetProxies(proxies); 84 | auto response = session.Get(); 85 | EXPECT_EQ(url, response.url); 86 | EXPECT_EQ(std::string{"application/json"}, response.header["content-type"]); 87 | EXPECT_EQ(200, response.status_code); 88 | EXPECT_EQ(ErrorCode::OK, response.error.code); 89 | } 90 | 91 | int main(int argc, char** argv) { 92 | ::testing::InitGoogleTest(&argc, argv); 93 | return RUN_ALL_TESTS(); 94 | } 95 | -------------------------------------------------------------------------------- /vendors/cpr/test/server.h: -------------------------------------------------------------------------------- 1 | #ifndef CPR_TEST_SERVER_H 2 | #define CPR_TEST_SERVER_H 3 | 4 | #include 5 | 6 | #include 7 | 8 | #include 9 | 10 | using namespace cpr; 11 | 12 | class Server: public ::testing::Environment { 13 | public: 14 | virtual void SetUp(); 15 | virtual void TearDown(); 16 | 17 | Url GetBaseUrl(); 18 | Url GetBaseUrlSSL(); 19 | }; 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /vendors/cpr/test/util_tests.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | using namespace cpr; 9 | 10 | TEST(UtilParseHeaderTests, BasicParseTest) { 11 | auto header_string = std::string{ 12 | "HTTP/1.1 200 OK\r\n" 13 | "Server: nginx\r\n" 14 | "Date: Sun, 05 Mar 2017 00:34:54 GMT\r\n" 15 | "Content-Type: application/json\r\n" 16 | "Content-Length: 351\r\n" 17 | "Connection: keep-alive\r\n" 18 | "Access-Control-Allow-Origin: *\r\n" 19 | "Access-Control-Allow-Credentials: true\r\n" 20 | "\r\n"}; 21 | auto header = util::parseHeader(header_string); 22 | EXPECT_EQ(std::string{"nginx"}, header["Server"]); 23 | EXPECT_EQ(std::string{"Sun, 05 Mar 2017 00:34:54 GMT"}, header["Date"]); 24 | EXPECT_EQ(std::string{"application/json"}, header["Content-Type"]); 25 | EXPECT_EQ(std::string{"351"}, header["Content-Length"]); 26 | EXPECT_EQ(std::string{"keep-alive"}, header["Connection"]); 27 | EXPECT_EQ(std::string{"*"}, header["Access-Control-Allow-Origin"]); 28 | EXPECT_EQ(std::string{"true"}, header["Access-Control-Allow-Credentials"]); 29 | } 30 | 31 | TEST(UtilParseHeaderTests, NewlineTest) { 32 | auto header_string = std::string{ 33 | "HTTP/1.1 200 OK\r\n" 34 | "Auth:\n" 35 | "Access-Control-Allow-Credentials: true\r\n" 36 | "\r\n"}; 37 | auto header = util::parseHeader(header_string); 38 | EXPECT_EQ(std::string{""}, header["Server"]); 39 | EXPECT_EQ(std::string{"true"}, header["Access-Control-Allow-Credentials"]); 40 | } 41 | 42 | TEST(UtilParseHeaderTests, SpaceNewlineTest) { 43 | auto header_string = std::string{ 44 | "HTTP/1.1 200 OK\r\n" 45 | "Auth: \n" 46 | "Access-Control-Allow-Credentials: true\r\n" 47 | "\r\n"}; 48 | auto header = util::parseHeader(header_string); 49 | EXPECT_EQ(std::string{""}, header["Server"]); 50 | EXPECT_EQ(std::string{"true"}, header["Access-Control-Allow-Credentials"]); 51 | } 52 | 53 | TEST(UtilParseHeaderTests, CarriageReturnNewlineTest) { 54 | auto header_string = std::string{ 55 | "HTTP/1.1 200 OK\n" 56 | "Auth:\r\n" 57 | "Access-Control-Allow-Credentials: true\r\n" 58 | "\r\n"}; 59 | auto header = util::parseHeader(header_string); 60 | EXPECT_EQ(std::string{""}, header["Server"]); 61 | EXPECT_EQ(std::string{"true"}, header["Access-Control-Allow-Credentials"]); 62 | } 63 | 64 | TEST(UtilParseHeaderTests, SpaceCarriageReturnNewlineTest) { 65 | auto header_string = std::string{ 66 | "HTTP/1.1 200 OK\n" 67 | "Auth: \r\n" 68 | "Access-Control-Allow-Credentials: true\r\n" 69 | "\r\n"}; 70 | auto header = util::parseHeader(header_string); 71 | EXPECT_EQ(std::string{""}, header["Server"]); 72 | EXPECT_EQ(std::string{"true"}, header["Access-Control-Allow-Credentials"]); 73 | } 74 | 75 | int main(int argc, char** argv) { 76 | ::testing::InitGoogleTest(&argc, argv); 77 | return RUN_ALL_TESTS(); 78 | } 79 | -------------------------------------------------------------------------------- /vendors/fetch_centos6_sysroot.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ev 4 | 5 | if [ $TRAVIS ]; then 6 | DIR=$HOME/cache 7 | mkdir -p $DIR 8 | else 9 | DIR=/tmp 10 | fi 11 | 12 | curl -# -k -L -o $DIR/centos6-sysroot.tar.gz.download -z $DIR/centos6-sysroot.tar.gz https://packages.baidu.com/app/openrasp/v8/centos6-sysroot.tar.gz 13 | [[ -f $DIR/centos6-sysroot.tar.gz.download ]] && mv $DIR/centos6-sysroot.tar.gz.download $DIR/centos6-sysroot.tar.gz 14 | tar zxf $DIR/centos6-sysroot.tar.gz -C /tmp/ --------------------------------------------------------------------------------