🌱Light and powerful C++ web framework for highly scalable and resource-efficient web application. It's zero-dependency and easy-portable.

Overview
Oat++ Logo

 

oatpp build status Language grade: C/C++ Join the chat at https://gitter.im/oatpp-framework/Lobby

Oat++

News

  • Hey, meet the new oatpp version 1.2.5! See the changelog for details.
  • Check out the new oatpp ORM - read more here.

Oat++ is a modern Web Framework for C++. It's fully loaded and contains all necessary components for effective production level development. It's also light and has a small memory footprint.

Start

About

Join Our Community

Quick Overview

Shortcuts:

Build Powerful API And Document It With Swagger-UI

See ApiController for more details.

ENDPOINT_INFO(getUserById) {
  info->summary = "Get one User by userId";

  info->addResponse<Object<UserDto>>(Status::CODE_200, "application/json");
  info->addResponse<Object<StatusDto>>(Status::CODE_404, "application/json");
  info->addResponse<Object<StatusDto>>(Status::CODE_500, "application/json");

  info->pathParams["userId"].description = "User Identifier";
}
ENDPOINT("GET", "users/{userId}", getUserById,
         PATH(Int32, userId))
{
  return createDtoResponse(Status::CODE_200, m_userService.getUserById(userId));
}

Access Databases And Keep Your Data Consistent

See Oat++ ORM for more details.

QUERY(createUser,
      "INSERT INTO users (username, email, role) VALUES (:username, :email, :role);",
      PARAM(oatpp::String, username), 
      PARAM(oatpp::String, email), 
      PARAM(oatpp::Enum<UserRoles>::AsString, role))

Frequently Asked Questions

Q: "Oat++" name?

  • "Oat" is something light, organic, and green. It can be easily cooked and consumed with no effort.
  • "++" gives a hint that it is "something" for C++.

Q: What is the main area of Oat++ application?

Oat++ is used for many different purposes, from building REST APIs that run on embedded devices to building microservices and highly-loaded cloud applications.

But the majority of use cases appears to be in IoT and Robotics.

Q: How portable is Oat++?

Theoretically, Oat++ can be easily ported everywhere where you have threads and network stack. With an additional comparably small effort, it can be ported almost everywhere depending on how much you strip it and what would be the final binary size.

See supported platforms for additional info.

Q: What is the size of a minimal Oat++ application?

About 1Mb, depending on C/C++ std-lib and oatpp version.

Q: Which Oat++ API to choose, Simple or Async?

Always choose Simple API wherever possible. Simple API is more developed and makes the code cleaner.

Async API is designed for small, specific tasks that run at high concurrency levels ex.:

  • Serving file downloads to a large number of concurrent users (1K users and more).
  • Streaming to a large number of clients (1K or more).
  • Websocket Chat servers.

For all other purposes use simple API.

Examples

REST-API

  • REST Service - A complete example of a "CRUD" service (UserService) built with Oat++. REST + Swagger-UI + SQLite.
  • REST Client - Example project of how-to use Retrofit-like client wrapper (ApiClient) and how it works.

WebSocket

  • Can Chat - Feature-complete rooms-based chat for tens of thousands users. Client plus Server.
  • WebSocket - Collection of oatpp WebSocket examples.
  • YUV Websocket Stream - Example project how-to create a YUV image stream from a V4L device (i.E. Webcam) using websockets.

Databases

  • SQLite - A complete example of a "CRUD" service. REST + Swagger-UI + SQLite.
  • PostgreSQL - Example of a production-grade entity service storing information in PostgreSQL. With Swagger-UI and configuration profiles.
  • MongoDB - Example project how to work with MongoDB using oatpp-mongo mondule. Project is a web-service with basic CRUD and Swagger-UI.

IoT

  • Example-IoT-Hue - Example project how-to create an Philips Hue compatible REST-API that is discovered and controllable by Hue compatible Smart-Home devices like Amazon Alexa or Google Echo.

Streaming

  • HTTP Live Streaming Server - Example project on how to build an HLS-streaming server using Oat++ asynchronous API.
  • YUV Websocket Stream - Example project how-to create a YUV image stream from a V4L device (i.E. Webcam) using websockets.

TLS

  • TLS With Libressl - Example project how-to setup secure connection and serve via HTTPS.

Microservices

Asynchronous API

  • Async Service - Example project on how to use asynchronous API to handle a large number of simultaneous connections.
Comments
  • Integrate into existing application which uses libevent epoll

    Integrate into existing application which uses libevent epoll

    Hi All,

    We are looking to integrate a reset server into our existing application. I am looking for some pointers on the same. Please note we are already running our libevent epoll and want to handle with the same. Is this possible?

    rgds Balaji

    Help Wanted 
    opened by bkannadassan 36
  • Missing Atomic library

    Missing Atomic library

    Hello,

    I was able to cross-compile a simple API for Clang ARM. But when I run the executable I get the following error: ./{executable}: error while loading shared libraries: libatomic.so.1: cannot open shared object file: No such file or directory

    The GNU Atomic library is not supported for my target devices (compatibility problems with libraries delivered by chip manfacturer).

    I'm not sure but I think Atomic is only used for a spinlock in Oat++, correct me if I'm wrong. Would there be a sollution where I wouldn't have to use Atomic?

    Portability 
    opened by br4m11 30
  • HttpRequest readBodyToString empty

    HttpRequest readBodyToString empty

    Hello

    I cannot get the bodystring of my HttpRequestExecutor response. it is always empty. (getStatusCode and getStatusDescription are working so I know that the request have been well executed) when I use oatpp::url it works fine but when I use HttpRequestExecutor it's empty.

    can you please help me find what am i doing wrong?

    I am expecting a json response from the called API.

    here my oattp HttpRequestExecutor declaration:

     std::shared_ptr<oatpp::web::client::RequestExecutor> createOatppExecutor() {
       auto config = oatpp::libressl::Config::createShared();
       tls_config_insecure_noverifycert(config->getTLSConfig());
       tls_config_insecure_noverifyname(config->getTLSConfig());
       auto connectionProvider = oatpp::libressl::client::ConnectionProvider::createShared(config, "monurl", 443);
       return oatpp::web::client::HttpRequestExecutor::createShared(connectionProvider);
     }
    

    my instanciation:

     auto objectMapper = oatpp::parser::json::mapping::ObjectMapper::createShared();
     //auto requestExecutor = createCurlExecutor();
     auto requestExecutor = createOatppExecutor();
     auto client = ApiClient::createShared(requestExecutor, objectMapper);
    

    my ApiClient function:

    API_CALL("GET", "mypath?myparameter={parameter}", doGettokeninfoheader,HEADER(String, myHeader1, "Content-type"),HEADER(String, myHeader2, "Accept"), PATH(String, parameter))
    

    and my call

    auto data3 = client->doGettokeninfoheader("application/x-www-form-urlencoded","application/json","PHOkrUhrhE-kz-ljWw5ci2SExSg");
    OATPP_LOGD("Api call", "string='%s'", data3->readBodyToString()->c_str());  --> empty when HttpRequestExecutor :-( 
    

    thanks for your help

    Bug 
    opened by nicolaslopez15 21
  • oatpp::base::memory::MemoryPool::freeByEntryHeader()]: Invalid EntryHeader

    oatpp::base::memory::MemoryPool::freeByEntryHeader()]: Invalid EntryHeader

    Hi!

    I observe this exception when I'm stopping the application with OATPP:

    terminate called after throwing an instance of 'std::runtime_error'
      what():  [oatpp::base::memory::MemoryPool::freeByEntryHeader()]: Invalid EntryHeader
    

    I was able to get some more logs of it:

    2020-09-16T13:31:24.530436Z DBG 322058:src/log/oatpp_logger.hpp:20 [oatpp::base::memory::MemoryPool::freeByEntryHeader()]:Error. Invalid EntryHeader. Expected poolId=9803840, entry poolId=-1610486112
    

    Backtrace:

    (gdb) bt
    #0  0x00007f775e5e370f in raise () from /lib64/libc.so.6
    #1  0x00007f775e5cdb25 in abort () from /lib64/libc.so.6
    #2  0x00007f770a4fd06b in __gnu_cxx::__verbose_terminate_handler() [clone .cold.1] () from /lib64/libstdc++.so.6
    #3  0x00007f770a50350c in __cxxabiv1::__terminate(void (*)()) () from /lib64/libstdc++.so.6
    #4  0x00007f770a502529 in __cxa_call_terminate () from /lib64/libstdc++.so.6
    #5  0x00007f770a502ea8 in __gxx_personality_v0 () from /lib64/libstdc++.so.6
    #6  0x00007f770a265ad3 in _Unwind_RaiseException_Phase2 () from /lib64/libgcc_s.so.1
    #7  0x00007f770a266041 in _Unwind_RaiseException () from /lib64/libgcc_s.so.1
    #8  0x00007f770a5037bb in __cxa_throw () from /lib64/libstdc++.so.6
    #9  0x00007f770a985b5e in oatpp::base::memory::MemoryPool::freeByEntryHeader(oatpp::base::memory::MemoryPool::EntryHeader*) [clone .cold.96] () 
    #10 0x00007f770ab09aea in std::_Sp_counted_ptr_inplace<oatpp::collection::LinkedList<std::shared_ptr<oatpp::web::url::mapping::Pattern::Part> >, oatpp::base::memory::PoolSharedObjectAllocator<oatpp::collection::LinkedList<std::shared_ptr<oatpp::web::url::mapping::Pattern::Part> > >, (__gnu_cxx::_Lock_policy)2>::_M_dispose() ()
    #11 0x00007f770ab09ebf in oatpp::web::url::mapping::Pattern::~Pattern() ()
    #12 0x00007f770aaff249 in oatpp::web::url::mapping::Router<oatpp::web::server::HttpRequestHandler>::~Router() ()
    #13 0x00007f770aaff04e in oatpp::web::server::HttpRouter::~HttpRouter() ()
    #14 0x00007f770aa7e979 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release (this=0x236b650) at /usr/include/c++/8/bits/shared_ptr_base.h:148
    #15 std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release (this=0x236b650) at /usr/include/c++/8/bits/shared_ptr_base.h:148
    #16 std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count (this=0x23a32c0, __in_chrg=<optimized out>) at /usr/include/c++/8/bits/shared_ptr_base.h:728
    #17 std::__shared_ptr<oatpp::web::server::HttpRouter, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr (this=0x23a32b8, __in_chrg=<optimized out>) at /usr/include/c++/8/bits/shared_ptr_base.h:1167
    #18 std::shared_ptr<oatpp::web::server::HttpRouter>::~shared_ptr (this=0x23a32b8, __in_chrg=<optimized out>) at /usr/include/c++/8/bits/shared_ptr.h:103
    #19 oatpp::base::Environment::Component<std::shared_ptr<oatpp::web::server::HttpRouter> >::~Component (this=0x23a3278, __in_chrg=<optimized out>)
        at /root/.conan/data/oatpp/1.1.0/_/_/package/56e0cf6d16ee57367a0661ab743f4e43b29223f8/include/oatpp-1.1.0/oatpp/oatpp/core/base/Environment.hpp:242
    #20 zroute::ServiceComponent::~ServiceComponent (this=0x23a3170, __in_chrg=<optimized out>)
    #21 std::default_delete<zroute::ServiceComponent>::operator() (this=0x23a4020, __ptr=0x23a3170) at /usr/include/c++/8/bits/unique_ptr.h:81
    #22 std::unique_ptr<zroute::ServiceComponent, std::default_delete<zroute::ServiceComponent> >::~unique_ptr (this=0x23a4020, __in_chrg=<optimized out>) at /usr/include/c++/8/bits/unique_ptr.h:269
    #23 zroute::HttpServer::~HttpServer (this=0x23a3f90, __in_chrg=<optimized out>)
    #24 0x00007f770a9ac001 in std::default_delete<zroute::HttpServer>::operator() (this=0x7f770e5299c0, __ptr=0x23a3f90) at /usr/include/c++/8/bits/unique_ptr.h:342
    #25 std::unique_ptr<zroute::HttpServer, std::default_delete<zroute::HttpServer> >::~unique_ptr (this=0x7f770e5299c0, __in_chrg=<optimized out>) at /usr/include/c++/8/bits/unique_ptr.h:269
    #26 zroute::core::~core (this=0x7f770e529910, __in_chrg=<optimized out>)
    #27 core_cleanup ()
    #28 0x00007f770a9a2eff in destroy () at inroute_mod.c:137
    #29 0x0000000000582a18 in destroy_modules () at core/sr_module.c:746
    #30 0x000000000041d53d in cleanup (show_status=1) at main.c:563
    #31 0x000000000041ed12 in shutdown_children (sig=15, show_status=1) at main.c:706
    #32 0x000000000041f800 in handle_sigs () at main.c:737
    #33 0x000000000042b465 in main_loop () at main.c:1817
    #34 0x0000000000433137 in main (argc=13, argv=0x7ffd84f9ea78) at main.c:2856
    

    The issue started to occur after I added 2nd controller. There was no such issue with single controller.

    OATPP version is 1.1.0

    After I disabled pool allocation the issue doesn't reproduce anymore:

    --- a/CMakeLists.txt
    +++ b/CMakeLists.txt
    @@ -26,7 +26,7 @@ option(OATPP_BUILD_TESTS "Create test target for oat++" ON)
     ###################################################################################################
    .
     option(OATPP_DISABLE_ENV_OBJECT_COUNTERS "Disable object counting for Release builds for better performance" OFF)
    -option(OATPP_DISABLE_POOL_ALLOCATIONS "This will make oatpp::base::memory::MemoryPool, method obtain and free call new and delete directly" OFF)
    +option(OATPP_DISABLE_POOL_ALLOCATIONS "This will make oatpp::base::memory::MemoryPool, method obtain and free call new and delete directly" ON)
    .
     set(OATPP_THREAD_HARDWARE_CONCURRENCY "AUTO" CACHE STRING "Predefined value for function oatpp::concurrency::Thread::getHardwareConcurrency()")
     set(OATPP_THREAD_DISTRIBUTED_MEM_POOL_SHARDS_COUNT "10" CACHE STRING "Number of shards of ThreadDistributedMemoryPool")
    

    Looks to be connected with https://github.com/oatpp/oatpp/issues/173

    Is this a bug at OATPP custom pool memory allocator?

    Thanks in advance.

    opened by pcapdump 20
  • The process hung up when trying to stop server

    The process hung up when trying to stop server

    I create a sub thread to run my server like this:

    thread_ptr_ = std::make_shared<std::thread>(&WebServer::StartService, this);
    

    This is my function to start server:

    WebServer::StartService() {
        Config& config = Config::GetInstance();
        std::string port;
        Status status;
    
        status = config.GetServerConfigWebPort(port);
        AppComponent components = AppComponent(std::stoi(port));
        SwaggerComponent swaggerComponent("192.168.1.57", std::stoi(port));
    
        /* create ApiControllers and add endpoints to router */
        auto router = components.http_router_.getObject();
    
        auto doc_endpoints = oatpp::swagger::AsyncController::Endpoints::createShared();
    
        auto user_controller = WebController::createShared();
        user_controller->addEndpointsToRouter(router);
    
        doc_endpoints->pushBackAll(user_controller->getEndpoints());
    
        auto swaggerController = oatpp::swagger::AsyncController::createShared(doc_endpoints);
        swaggerController->addEndpointsToRouter(router);
    
        /* create server */
        server_ptr_ = std::make_unique<oatpp::network::server::Server>(components.server_connection_provider_.getObject(),
                                                                       components.server_connection_handler_.getObject());
    
        // start synchronously
        server_ptr_->run();
    
        return Status::OK();
    }
    

    I try to stop my web server just to call Stop() like this:

    if (server_ptr_ != nullptr) {
            server_ptr_->stop();  // cStop server
        }
    
        if (thread_ptr_ != nullptr) {
            thread_ptr_->join();
            thread_ptr_ = nullptr;
        }
    

    I join web thread, and wait it finishing but the process hung up. How I protect it from hanging up?

    I use async endpoint, and my server connection provider is an object of SimpleTCPConnectionProvider

    Question 
    opened by BossZou 18
  • Won't build for iOS 8 or older

    Won't build for iOS 8 or older

    Hi @lganzzzo,

    I'm working on the iOS app version of the Android app that @dmcamens-legrand discussed with you recently. The oat++ library is working well on Android now, and I'm trying to make it work on iOS as well.

    Sadly, the even though the thread_local keyword was added to Xcode 8, it won't compile to devices running iOS 8 or earlier, even in the current version (Xcode 10).

    Do you have any ideas for how to use this library without using the thread_local storage functionality from C++11?

    Thank you!

    Enhancement Help Wanted 
    opened by david-novak-legrand 18
  • Question about streaming possibility

    Question about streaming possibility

    Hello,

    I'm investigating this library and can't find the way how to implement file streaming with it.

    Let's assume huge file is stored in another storage, so I want to use own implementation of file stream, that implements (open/seek/read/write), which then can be used by a framework to get/send chunks of bytes to requestor of this file.

    Is this possible with the current state?

    Question 
    opened by elgatito 16
  • Linker errors in Visual Studio 2019

    Linker errors in Visual Studio 2019

    Hello, I've successfully compiled and installed the library on my Windows platform.

    I am trying to get it working in VS2019. I've added additional libraries in Configuration Properties->C/C++->Additional Include Directories. I added .lib directory to Configuration Properties->Linker->General->Additional Library Directories and I added individual .lib to Input->Additional Dependencies. But, I get the "unresolved external symbol" errors still.

    What am I missing?

    Question 
    opened by ourobor05 15
  • Implementing Issue #408

    Implementing Issue #408

    I gave it a shot at implementing issue #408.

    I wasn't sure if the timeout parameter should be added to the get-function of core::provider::Provider or core::provider::PoolTemplate. I settled for the latter.

    I think I found a bug while writing the test: PoolTemplate::createShared calls PoolTemplate::startCleanupTask, which takes a parameter. Apperantly this function PoolTemplate::createShared was never called and since PoolTemplate is a template no compiler errors occurred. I fixed it by passing ptr to PoolTemplate::startCleanupTask.

    opened by MHaselmaier 14
  • Why does httpServer crash when it exits?

    Why does httpServer crash when it exits?

    std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release shared_ptr_base.h:155
    std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count shared_ptr_base.h:728
    std::__shared_ptr<oatpp::base::StrBuffer, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr shared_ptr_base.h:1167
    std::shared_ptr<oatpp::base::StrBuffer>::~shared_ptr shared_ptr.h:103
    oatpp::data::mapping::type::ObjectWrapper<oatpp::base::StrBuffer, oatpp::data::mapping::type::__class::String>::~ObjectWrapper Type.hpp:97
    oatpp::data::mapping::type::String::~String Primitive.hpp:62
    oatpp::parser::json::mapping::Serializer::Config::~Config Serializer.hpp:49
    __gnu_cxx::new_allocator<oatpp::parser::json::mapping::Serializer::Config>::destroy<oatpp::parser::json::mapping::Serializer::Config> new_allocator.h:140
    std::allocator_traits<std::allocator<oatpp::parser::json::mapping::Serializer::Config> >::destroy<oatpp::parser::json::mapping::Serializer::Config> alloc_traits.h:487
    std::_Sp_counted_ptr_inplace<oatpp::parser::json::mapping::Serializer::Config, std::allocator<oatpp::parser::json::mapping::Serializer::Config>, (__gnu_cxx::_Lock_policy)2>::_M_dispose shared_ptr_base.h:554
    std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release shared_ptr_base.h:155
    std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count shared_ptr_base.h:728
    std::__shared_ptr<oatpp::parser::json::mapping::Serializer::Config, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr shared_ptr_base.h:1167
    std::shared_ptr<oatpp::parser::json::mapping::Serializer::Config>::~shared_ptr shared_ptr.h:103
    oatpp::parser::json::mapping::Serializer::~Serializer Serializer.hpp:38
    __gnu_cxx::new_allocator<oatpp::parser::json::mapping::Serializer>::destroy<oatpp::parser::json::mapping::Serializer> new_allocator.h:140
    std::allocator_traits<std::allocator<oatpp::parser::json::mapping::Serializer> >::destroy<oatpp::parser::json::mapping::Serializer> alloc_traits.h:487
    std::_Sp_counted_ptr_inplace<oatpp::parser::json::mapping::Serializer, std::allocator<oatpp::parser::json::mapping::Serializer>, (__gnu_cxx::_Lock_policy)2>::_M_dispose shared_ptr_base.h:554
    std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release shared_ptr_base.h:155
    std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count shared_ptr_base.h:728
    std::__shared_ptr<oatpp::parser::json::mapping::Serializer, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr shared_ptr_base.h:1167
    std::shared_ptr<oatpp::parser::json::mapping::Serializer>::~shared_ptr shared_ptr.h:103
    oatpp::parser::json::mapping::ObjectMapper::~ObjectMapper ObjectMapper.hpp:40
    __gnu_cxx::new_allocator<oatpp::parser::json::mapping::ObjectMapper>::destroy<oatpp::parser::json::mapping::ObjectMapper> new_allocator.h:140
    std::allocator_traits<std::allocator<oatpp::parser::json::mapping::ObjectMapper> >::destroy<oatpp::parser::json::mapping::ObjectMapper> alloc_traits.h:487
    std::_Sp_counted_ptr_inplace<oatpp::parser::json::mapping::ObjectMapper, std::allocator<oatpp::parser::json::mapping::ObjectMapper>, (__gnu_cxx::_Lock_policy)2>::_M_dispose shared_ptr_base.h:554
    std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release shared_ptr_base.h:155
    std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count shared_ptr_base.h:728
    std::__shared_ptr<oatpp::parser::json::mapping::ObjectMapper, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr shared_ptr_base.h:1167
    std::shared_ptr<oatpp::parser::json::mapping::ObjectMapper>::~shared_ptr shared_ptr.h:103
    ...............
    __run_exit_handlers 0x00007f66df1d6d8c
    __GI_exit 0x00007f66df1d6eba
    __libc_start_main 0x00007f66df1c10a2
    _start 0x000000000084ecaa
    
    Question 
    opened by NickPak 13
  • BufferOutputStream::reserveBytesUpfront() is inefficient

    BufferOutputStream::reserveBytesUpfront() is inefficient

    I tried to upload a moderate volume of data via POST requests to an oatpp-based web service. The volume is: ~114MBytes/minute, it's ~20 requests/minute each ~5.7MBytes. However, oatpp in this case loads almost 100% of a Ryzen 7 PRO 3700 CPU with 16 logical cores. Profiling shows the following: oatpp_BufferOutputStream_reserveBytesUpfront The version of oatpp used is 1.0.0 . Is there a workaround for this bug, e.g. can I somehow make Request::readBodyToString() to allocate a large buffer at once so to eliminate the need for reallocation (e.g. make the buffer size equal to the size of the unencoded POST body)? Or maybe is there a way to increase the growth rate for the BufferOutputStream used?

    Duplicate 
    opened by srogatch 13
  • Crash when calling oatpp::data::mapping::ObjectMapper::writeToString

    Crash when calling oatpp::data::mapping::ObjectMapper::writeToString

    Oatpp Version : 1.2.5

    #0  0x0000000000000000 in ?? ()
    #1  0x000000000107ab58 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release (this=0x7f25b00058c0) at /opt/rh/devtoolset-8/root/usr/include/    c++/8/bits/shared_ptr_base.h:155
    #2  0x000000000106ebf7 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count (this=0x7f266a6da638, __in_chrg=<optimized out>) at /opt/rh/    devtoolset-8/root/usr/include/c++/8/bits/shared_ptr_base.h:728
    #3  0x000000000103d124 in std::__shared_ptr<void, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr (this=0x7f266a6da630, __in_chrg=<optimized out>) at /opt/rh/    devtoolset-8/root/usr/include/c++/8/bits/shared_ptr_base.h:1167
    #4  0x000000000103d166 in std::shared_ptr<void>::~shared_ptr (this=0x7f266a6da630, __in_chrg=<optimized out>) at /opt/rh/devtoolset-8/root/usr/include/    c++/8/bits/shared_ptr.h:103
    #5  0x0000000001055bc8 in oatpp::data::mapping::type::ObjectWrapper<void, oatpp::data::mapping::type::__class::Void>::~ObjectWrapper (    this=0x7f266a6da630, __in_chrg=<optimized out>) at /usr/local/include/oatpp-1.2.5/oatpp/oatpp/core/data/mapping/type/Type.hpp:99
    #6  0x0000000002802f48 in oatpp::parser::json::mapping::Serializer::serializeObject(oatpp::parser::json::mapping::Serializer*,     oatpp::data::stream::ConsistentOutputStream*, oatpp::data::mapping::type::ObjectWrapper<void, oatpp::data::mapping::type::__class::Void> const&) ()
    #7  0x000000000280301d in oatpp::parser::json::mapping::Serializer::serialize(oatpp::data::stream::ConsistentOutputStream*,     oatpp::data::mapping::type::ObjectWrapper<void, oatpp::data::mapping::type::__class::Void> const&) ()
    #8  0x0000000002803b96 in void oatpp::parser::json::mapping::Serializer::serializeList<oatpp::data::mapping::type::ListObjectWrapper<    oatpp::data::mapping::type::ObjectWrapper<void, oatpp::data::mapping::type::__class::Void>, oatpp::data::mapping::type::__class::AbstractList>     >(oatpp::parser::json::mapping::Serializer*, oatpp::data::stream::ConsistentOutputStream*, oatpp::data::mapping::type::ObjectWrapper<void,     oatpp::data::mapping::type::__class::Void> const&) ()
    #9  0x000000000280301d in oatpp::parser::json::mapping::Serializer::serialize(oatpp::data::stream::ConsistentOutputStream*,     oatpp::data::mapping::type::ObjectWrapper<void, oatpp::data::mapping::type::__class::Void> const&) ()
    #10 0x0000000002802f3c in oatpp::parser::json::mapping::Serializer::serializeObject(oatpp::parser::json::mapping::Serializer*,     oatpp::data::stream::ConsistentOutputStream*, oatpp::data::mapping::type::ObjectWrapper<void, oatpp::data::mapping::type::__class::Void> const&) ()
    #11 0x000000000280301d in oatpp::parser::json::mapping::Serializer::serialize(oatpp::data::stream::ConsistentOutputStream*,     oatpp::data::mapping::type::ObjectWrapper<void, oatpp::data::mapping::type::__class::Void> const&) ()
    #12 0x00000000028032af in oatpp::parser::json::mapping::Serializer::serializeToStream(oatpp::data::stream::ConsistentOutputStream*,     oatpp::data::mapping::type::ObjectWrapper<void, oatpp::data::mapping::type::__class::Void> const&) ()
    #13 0x0000000002800d00 in oatpp::parser::json::mapping::ObjectMapper::write(oatpp::data::stream::ConsistentOutputStream*,     oatpp::data::mapping::type::ObjectWrapper<void, oatpp::data::mapping::type::__class::Void> const&) const ()
    #14 0x00000000027da01c in oatpp::data::mapping::ObjectMapper::writeToString(oatpp::data::mapping::type::ObjectWrapper<void,     oatpp::data::mapping::type::__class::Void> const&) const ()
    .....
    .....
    

    Have you encountered the similar problems and what‘s the possible reason? Thanks.

    opened by harlanc 2
  • Why does oatpp::Client response give me a 404 (not found) when the equivalent curl command gives me a 200?

    Why does oatpp::Client response give me a 404 (not found) when the equivalent curl command gives me a 200?

    I'm stumped by this one. I built a REST API client, for a coding challenge, that was supposed to GET a simple body response. This is the path:

    https://candidate.<company>.com/candidateTest/v3/problem/dataset?userKey=<mumbo-jumbo string>

    This is how I built the request executor:

    std::shared_ptr<oatpp::web::client::RequestExecutor> createOatppExecutor() {
      OATPP_LOGD("App", "Using Oat++ native HttpRequestExecutor.");
    
      auto config = oatpp::openssl::Config::createDefaultClientConfigShared();
      auto connectionProvider = oatpp::openssl::client::ConnectionProvider::createShared(config, { "candidate.<company>.com", 443});
      auto requestExecutor = oatpp::web::client::HttpRequestExecutor::createShared(connectionProvider);
    
      return requestExecutor;
    }
    

    And here is the definition of my API_CALL method, for my client class:

    API_CALL("GET", "/candidateTest/v3/problem/dataset?userKey=<mumbo-jumbo string>", doGetEvents);

    No matter how I tried, this code always gave me back a 404 status code:

    void CompanyApi::getEvents(const shared_ptr<CompanyApiClient>& client)
    {
       auto response = client->doGetEvents();
       auto data = response->getStatusCode();
    
       OATPP_LOGD(TAG, "[doGetEvents] Status Code='%d'", data);
       OATPP_LOGD(TAG, "[doGetEvents] Status Description='%s'", response->getStatusDescription()->c_str());
    
       if (response->getStatusCode() == 200) {
       }
    }
    

    However, the following curl command, gave me the expected 200 response, with the data correctly contained in the body:

    curl -v "https://candidate.<company>.com/candidateTest/v3/problem/dataset?userKey=<mumbo-jumbo string>"

    ... < HTTP/1.1 200 OK < Date: Tue, 13 Sep 2022 00:25:31 GMT < Content-Type: application/json;charset=utf-8 < Transfer-Encoding: chunked < Connection: keep-alive < X-Trace: 2B6EF4E05F1255775E4BD58A80E1501ABF241399B1873D9BCC1743B3B601 < Vary: Accept-Encoding ...

    Can somebody please help me understand what am I missing here?

    opened by paulofsarli 1
  • curl: (1) Received HTTP/0.9 when not allowed

    curl: (1) Received HTTP/0.9 when not allowed

    I'm going to upload some files with the following codes:

      ENDPOINT_ASYNC("POST", "test/multipart-all", MultipartUpload) {
    
        ENDPOINT_ASYNC_INIT(MultipartUpload)
        std::shared_ptr<multipart::PartList> m_multipart;
    
        Action act() override {
          m_multipart = std::make_shared<multipart::PartList>(request->getHeaders());
          auto multipartReader = std::make_shared<multipart::AsyncReader>(m_multipart);
    
          multipartReader->setDefaultPartReader(multipart::createAsyncInMemoryPartReader(16*1024*1024 /* max-data-size */));
    
          return request->transferBodyAsync(multipartReader).next(yieldTo(&MultipartUpload::onUploaded));
    
        }
    
        Action onUploaded() {
          OATPP_LOGD("Multipart", "parts_count=%d", m_multipart->count());
    
          auto parts = m_multipart->getAllParts();
          while(!parts.empty()){
    	auto part = parts.front();
    	std::string name = part->getName();
    	std::string filename = part->getFilename();
    	std::string content = part->getPayload()->getInMemoryData();
            OATPP_LOGD("part", "parts=%d %s %s %d", parts.size(), name.c_str(), filename.c_str(), content.size());
          	OATPP_ASSERT_HTTP(part, Status::CODE_400, name + "/" + filename + " is empty");
    
    	parts.pop_front();
          }
          OATPP_LOGD("finished", "parts_count=%d", m_multipart->count());
          return _return(controller->createResponse(Status::CODE_200, "OK"));
        }
      };
    

    My server shows the following messages:

     D |2022-09-08 02:56:39 1662605799607835| Server:Running on port 9000...
     D |2022-09-08 03:00:38 1662606038772396| Multipart:parts_count=2
     D |2022-09-08 03:00:38 1662606038772705| part:parts=2 part1 MyController.cpp 52
     D |2022-09-08 03:00:38 1662606038772827| part:parts=1 part2 MyController.hpp 4529
     D |2022-09-08 03:00:38 1662606038772894| finished:parts_count=2
    

    All things should be good, however my curl shows "* Received HTTP/0.9 when not allowed".

    # curl -v -F [email protected] -F [email protected]  http://localhost:9000/test/multipart-all
    *   Trying 127.0.0.1:9000...
    * TCP_NODELAY set
    * Connected to localhost (127.0.0.1) port 9000 (#0)
    > POST /test/multipart-all HTTP/1.1
    > Host: localhost:9000
    > User-Agent: curl/7.68.0
    > Accept: */*
    > Content-Length: 4953
    > Content-Type: multipart/form-data; boundary=------------------------0162ec68c46f5497
    > Expect: 100-continue
    > 
    * Mark bundle as not supporting multiuse
    < HTTP/1.1 100 Continue
    * Done waiting for 100-continue
    * We are completely uploaded and fine
    < HTTP/1.1 200 OK
    < Content-Length: 2
    < Connection: keep-alive
    < Server: oatpp/1.3.0
    * Received HTTP/0.9 when not allowed
    
    * Closing connection 0
    curl: (1) Received HTTP/0.9 when not allowed
    

    What's wrong? How to solve this problem?

    opened by mochechan 0
  • how to stop the server with oatpp dynamic library

    how to stop the server with oatpp dynamic library

    i code a server similar to example-crud, but when the method (server.run())begin to loop, when a signal ocurred ,there seems no api to stop server provided by oatpp dynamic library.

    opened by flyfish123-sudo 0
  • Suggestion: Create a general purpose Resources class based on oatpp::swagger::Resources

    Suggestion: Create a general purpose Resources class based on oatpp::swagger::Resources

    Hi,

    Recently, I faced an issue with streaming the custom resource files using Oat++ and it looks very simple, but I haven't found any general purpose class that will help to simplify it, especially when you need to stream a lot of different resource files.

    However, the oatpp-swagger module contains such class - oatpp::swagger::Resources, but it's specialized for Swagger resources and cannot used for general case since the Resources::cacheResource() method is private and expect const char*.

    I think this class can be redesigned and moved into the main module with the following changes:

    • make Resources::cacheResource() public;
    • replace const char* with const oatpp::String &;
    • add the validation of the input filename inside the Resources::cacheResource();
    • remove Swagger-related parts.

    Maybe this class can also wrap this code

        if(m_resources->isStreaming()) {
          auto body = std::make_shared<oatpp::web::protocol::http::outgoing::StreamingBody>(
            m_resources->getResourceStream(filename));
          return OutgoingResponse::createShared(Status::CODE_200, body);
        }
        return createResponse(Status::CODE_200, m_resources->getResource(filename));
    

    into a separate method to simplify response handling.

    Fo Swagger resources, there still can be oatpp::swagger::Resources, but it can be inherited from this new Resources class and extended with Swagger-related logic.

    Generally, I already did it for my case. But I would like to hear your opinion. Also, I can prepare PR with these changes, if you think that my suggestion is reasonable.

    opened by EDDragonWolf 2
Releases(1.3.0)
  • 1.3.0(Nov 19, 2021)

  • 1.2.5(Feb 16, 2021)

  • 1.2.0(Oct 27, 2020)

  • 1.1.0(May 25, 2020)

  • 1.0.0(Jan 28, 2020)

    • Configurable object mapping - now user can create own types and add support for these types in ApiController, ApiClient, json::mapping::ObjectMapper.
    • Predefined mapping-enabled unsigned integer types are added.
    • Full support for automatic content compression/decompression based on Accept-Encoding / Content-Encoding headers.
    • CMake. Options added to disable logs. OATPP_DISABLE_LOGV, OATPP_DISABLE_LOGD, OATPP_DISABLE_LOGI, OATPP_DISABLE_LOGW, OATPP_DISABLE_LOGE
    Source code(tar.gz)
    Source code(zip)
  • 0.19.12(Jan 12, 2020)

    Refactoring and Stabilization Release.

    Features and Bug-Fixes

    • Introduce oatpp::data::buffer::Processor and oatpp::data::buffer::ProcessingPipeline for stream chunk-by-chunk processing.
    • Fix server stop() when using oatpp::network::server:: SimpleTCPConnectionProvider. Now server can be properly stopped without additional workarounds.
    • Fix tests inconsistency.
    • Fix a bunch of IO bugs (mostly for Windows).

    Architecture Changes

    • Move IODefinitions.hpp to the root. Move v_io_size, v_io_handle and IOError to the oatpp namespace.
    • Upgrade streams interfaces (to provide nesting and pipelining of any complexity):
      • InputStream now extends ReadCallback
      • OutputStream now extends WriteCallback
      • read/write methods now extended with additional parameter async::Action&.
      • suggestInputStreamAsyncAction / suggestOutputStreamAsyncAction removed.

    Changes Exposed to End-User

    • Rename oatpp::data::v_io_size to oatpp::v_io_size.
    • Rename oatpp::data::v_io_handle to oatpp::v_io_handle.
    • Rename oatpp::data::IOError to oatpp::IOError.
    • Use writeSimple instead of write for ConsistentOutputStreams - ChunkedBuffer and BufferOutputStream.
    • Server stop(). Now additional call to client::ConnectionProvider::getConnection() method is not needed in order to unblock accept and stop the server.
    Source code(tar.gz)
    Source code(zip)
  • 0.19.11(Dec 18, 2019)

    oatpp

    • ApiClient. Introduce retries and RetryPolicy.
    • oatpp::network::virtual_::Interface. Introduce ListenerLock to acquire an interface for listening (analog to bind on a port).
    • oatpp::parser::json::mapping::Serializer. Remove extra space char.
    • oatpp::parser::json::mapping::Serializer. Introduce Beautifier and Beautifier config.
    • Introduce v_buff_size for buffer sizes, as an integer capable of storing a pointer.
    • Introduce oatpp::data::stream::Context to store aditional data about the stream.
    • oatpp::network::server::SimpleTCPConnectionProvider. Add feature to obtain peer IP and port available through the connection stream context.

    oatpp-libressl

    • Better portability.
    • Windows compatibility.
    • Support TLS over custom transport.
    • Require LibreSSL minimum version 3.0.0.

    oatpp-mbedtls

    • Fix acceptor-thread blocking by handshake. TLS Handshake is moved to the stream context initialization.
    Source code(tar.gz)
    Source code(zip)
  • 0.19.10(Nov 3, 2019)

    • ApiController. Add router prefix.
    • Introduce LazyStringMap to store headers and query parameters.
    • Introduce ConnectionPool.
    • Refactor. Rename ADDCORS --> ADD_CORS macro.
    • Optimization. Use BufferOutputStream in RequestHeadersReader.
    • Fix thread sanitizer warnings.
    • Fix some compiler warnings.
    Source code(tar.gz)
    Source code(zip)
  • 0.19.9(Oct 7, 2019)

    • ApiController. Introduced AUTHORIZATION macro.
    • ApiController. Introduced ADDCORS macro.
    • ApiController. Introduced ENDPOINT_INTERCEPTOR macro.
    • Better error handling for simple and async APIs.
    • Support HTTP-pipelining on server-side.
    • Performance optimization. Remove double-buffering while sending the response.
    • Minor bug-fixes.
    Source code(tar.gz)
    Source code(zip)
  • 0.19.8(Aug 20, 2019)

  • 0.19.7(Aug 8, 2019)

    • Better stream processing API.
    • Introduced stream read/write callbacks.
    • Introduced BufferInputStream, FileStream
    • Feature - Multipart support - server/client, simple/async APIs.
    • Revived IOWorker for Async APIs compatibility with future Windows build.
    Source code(tar.gz)
    Source code(zip)
  • 0.19.6(Jun 25, 2019)

    • Additional parameters in server::ConnectionHandler::handleConnection method. - For parameterized connection upgrades.
    • Introduced oatpp::async::Lock - for Coroutine/Thread synchronization
    • Introduced -DOATPP_COMPAT_BUILD_NO_THREAD_LOCAL build flag. - For compatibility with compilers which do not support thread_local feature. See https://github.com/oatpp/oatpp/issues/81.
    • Introduced oatpp default Logger.
    • Fixed memory leak in kqueue based implementation of async IOEventWorker.
    Source code(tar.gz)
    Source code(zip)
  • 0.19.4(May 5, 2019)

    • New oatpp::async::Executor with scheduling and event based IO.
    • First 2-Million concurrent WebSocket connections benchmark https://oatpp.io/benchmark/websocket/2-million/
    • Extended oatpp::data::stream::InputStream and oatpp::data::stream::OutputStream interfaces.
    • Introduced oatpp::data::stream::ConsistentOutputStream interface.
    • oatpp::concurrency::SpinLock now meets C++ Lockable requirements.
    Source code(tar.gz)
    Source code(zip)
  • 0.19.1-2(Feb 12, 2019)

  • 0.19.1(Jan 30, 2019)

  • v0.18.12-alpha(Dec 16, 2018)

  • v0.18.9-alpha(Oct 30, 2018)

Owner
Oat++
🌱Light and powerful C++ web framework for highly scalable and resource-efficient web applications development. It's zero-dependency and easy-portable.
Oat++
Tntnet is a web application server for web applications written in C++.

Tntnet is a web application server for web applications written in C++.

Tommi Mäkitalo 72 Aug 1, 2022
Drogon: A C++14/17 based HTTP web application framework running on Linux/macOS/Unix/Windows

English | 简体中文 | 繁體中文 Overview Drogon is a C++14/17-based HTTP application framework. Drogon can be used to easily build various types of web applicat

An Tao 8k Sep 16, 2022
Your high performance web application C framework

facil.io is a C micro-framework for web applications. facil.io includes: A fast HTTP/1.1 and Websocket static file + application server. Support for c

Bo 1.6k Sep 13, 2022
Crow is very fast and easy to use C++ micro web framework (inspired by Python Flask)

Crow is C++ microframework for web. (inspired by Python Flask) #include "crow.h" int main() { crow::SimpleApp app; CROW_ROUTE(app, "/")([]()

Jaeseung Ha 7k Sep 24, 2022
A C++ Web Framework built on top of Qt, using the simple approach of Catalyst (Perl) framework.

Cutelyst - The Qt Web Framework A Web Framework built on top of Qt, using the simple and elegant approach of Catalyst (Perl) framework. Qt's meta obje

Cutelyst 788 Sep 20, 2022
Experimental, scalable, high performance HTTP server

Lwan Web Server Lwan is a high-performance & scalable web server. The project web site contains more details. Build status OS Arch Release Debug Stati

Leandro A. F. Pereira 5.7k Sep 15, 2022
C++ application development framework, to help developers create and deploy applications quickly and simply

ULib - C++ library Travis CI: Coverity Scan: ULib is a highly optimized class framework for writing C++ applications. I wrote this framework as my too

stefano casazza 948 Sep 17, 2022
The application framework for developer module of EdgeGallery platform

crane-framework crane-framework将可复用的计算和软件功能抽象成插件,APP开发者面向使用插件进行MEC APP开发。这样屏蔽了和MEC平台交互的细节,实现MCE APP和MEC平台的松耦合。而且插件框架基础能力可裁剪,按需提供最小的APP系统。 特性介绍 为了方便开发者

EdgeGallery 21 Aug 30, 2021
This is a proof-of-concept of a modern C web-framework that compiles to WASM and is used for building user interfaces.

DanCing Web ?? ?? (DCW) Getting Started Dancing Web is now distributed with the Tarantella Package Manager — a tool I've made to simplify setup of pro

Danilo Chiarlone 3 Sep 11, 2021
QDjango, a Qt-based C++ web framework

QDjango - a Qt-based C++ web framework Copyright (c) 2010-2015 Jeremy Lainé About QDjango is a web framework written in C++ and built on top of the Qt

Jeremy Lainé 246 Sep 18, 2022
CppCMS - High Performance C++ Web Framework

CppCMS - High Performance C++ Web Framework What is CppCMS? CppCMS is a Free High Performance Web Development Framework (not a CMS) aimed at Rapid Web

Artyom Beilis 367 Sep 3, 2022
A high performance, middleware oriented C++14 http web framework please use matt-42/lithium instead

A high performance, middleware oriented C++14 http web framework please use matt-42/lithium instead

Matthieu Garrigues 1.7k Aug 26, 2022
C library to create simple HTTP servers and Web Applications.

Onion http server library Travis status Coverity status Onion is a C library to create simple HTTP servers and Web Applications. master the developmen

David Moreno Montero 1.9k Sep 13, 2022
cserv is an event-driven and non-blocking web server

cserv is an event-driven and non-blocking web server. It ideally has one worker process per cpu or processor core, and each one is capable of handling thousands of incoming network connections per worker. There is no need to create new threads or processes for each connection.

null 42 Sep 14, 2022
Embedded C/C++ web server

CivetWeb The official home of CivetWeb is https://github.com/civetweb/civetweb Continuous integration for Linux and macOS (Travis CI): Continuous inte

null 2.2k Sep 23, 2022
A C++11 RESTful web server library

Served Overview Served is a C++ library for building high performance RESTful web servers. Served builds upon Boost.ASIO to provide a simple API for d

Meltwater 694 Aug 26, 2022
Pistache is a modern and elegant HTTP and REST framework for C++

Pistache is a modern and elegant HTTP and REST framework for C++. It is entirely written in pure-C++17* and provides a clear and pleasant API.

null 2.8k Sep 21, 2022
Corvusoft's Restbed framework brings asynchronous RESTful functionality to C++14 applications.

Restbed Restbed is a comprehensive and consistent programming model for building applications that require seamless and secure communication over HTTP

Corvusoft 1.7k Sep 18, 2022