Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <cpprest/http_listener.h>
- #include <cpprest/http_client.h>
- #include <thread>
- #include <Windows.h>
- #include <fstream>
- #include <iostream>
- #include <memory>
- #include <vector>
- #include <map>
- #include <chrono>
- #include <string.h>
- #include <atomic>
- #include <future>
- namespace http = web::http;
- namespace server_listener = http::experimental::listener;
- std::atomic_bool flag{ false };
- enum class TransactionType : uint16_t {
- Debit,
- Credit
- };
- enum class AccountType : uint16_t {
- Savings,
- Current,
- FixedDeposit
- };
- struct DateTime {
- SYSTEMTIME time_of_day;
- uint16_t year;
- uint16_t month;
- uint16_t day;
- };
- void obsfucate( std::string & s )
- {
- for ( auto &t : s ) t = ~t;
- }
- void decode( std::string & s )
- {
- for ( auto &t : s ) t = ~t;
- }
- struct StatementOfAccount {
- uint64_t amount;
- DateTime date_time;
- TransactionType trans_type;
- std::string remarks;
- };
- struct UserInfo {
- struct Header {
- uint16_t transaction_len;
- uint16_t remarks_len;
- uint16_t fullname_len;
- } header;
- unsigned int balance;
- unsigned int pin;
- unsigned int account_number;
- std::string full_name;
- std::vector<StatementOfAccount> transactions;
- };
- #define WRITE(object,mem_function,s) (fwrite( &(object.mem_function), sizeof(s), 1, file ))
- void WriteToFileFromMap( FILE *file, std::map<unsigned int, UserInfo> const & map )
- {
- for ( auto & m : map ) {
- UserInfo info = m.second;
- WRITE( info.header, transaction_len, uint16_t );
- WRITE( info.header, remarks_len, uint16_t );
- WRITE( info.header, fullname_len, uint16_t );
- WRITE( info, balance, unsigned int );
- WRITE( info, pin, unsigned int );
- WRITE( info, account_number, unsigned int );
- obsfucate( info.full_name );
- fwrite( info.full_name.c_str(), info.header.fullname_len, 1, file );
- for ( uint16_t x = 0; x != info.header.transaction_len; ++x ){
- auto &d = info.transactions[ x ];
- WRITE( d, amount, uint64_t );
- DateTime dt = d.date_time;
- WRITE( dt, year, uint16_t );
- WRITE( dt, month, uint16_t );
- WRITE( dt, day, uint16_t );
- WRITE( d, trans_type, uint16_t );
- obsfucate( d.remarks );
- fwrite( d.remarks.c_str(), info.header.remarks_len, 1, file );
- }
- }
- }
- #undef WRITE
- #define READ(object,mem_function,s) (fread(&(object.mem_function), sizeof(s), 1, file ))
- void ReadFromFileToMap( FILE *file, std::map<unsigned int, UserInfo> & map )
- {
- UserInfo info;
- READ( info.header, transaction_len, uint16_t );
- READ( info.header, remarks_len, uint16_t );
- READ( info.header, fullname_len, uint16_t );
- READ( info, balance, unsigned int );
- READ( info, pin, unsigned int );
- READ( info, account_number, unsigned int );
- info.full_name.resize( info.header.fullname_len );
- fread( &info.full_name[ 0 ], info.header.fullname_len, 1, file );
- decode( info.full_name );
- std::vector<StatementOfAccount> statement( info.header.transaction_len, StatementOfAccount() );
- for ( auto & s : statement ){
- READ( s, amount, uint64_t );
- DateTime &dt = s.date_time;
- READ( dt, year, uint16_t );
- READ( dt, month, uint16_t );
- READ( dt, day, uint16_t );
- READ( s, trans_type, uint16_t );
- s.remarks.resize( info.header.remarks_len );
- READ( s, remarks[ 0 ], s.remarks.size() );
- }
- map.emplace( info.account_number, info );
- }
- #undef READ
- void foo( std::map<unsigned int, UserInfo> & m_data )
- {
- std::map<unsigned int, UserInfo> map{};
- FILE *file = NULL;
- auto t = fopen_s( &file, "file.db", "rb" );
- if ( !file ){
- auto c = reinterpret_cast< uintptr_t >( ReadFromFileToMap );
- FILE *file = NULL;
- auto q = fopen_s( &file, "file.db", "wb" );
- if ( file ){
- SYSTEMTIME t;
- GetSystemTime( &t );
- for ( uint16_t i = 0; i != 200; ++i ){
- UserInfo info;
- info.header.transaction_len = i + 1;
- info.header.remarks_len = 26;
- info.header.fullname_len = 6;
- info.pin = rand() % 9999 + 1000;
- info.balance = ( i + 1 ) * ( rand() % 99999 + 1000 );
- info.account_number = c + ( i * 12 );
- info.full_name = "Joshua";
- std::vector<StatementOfAccount> vec_account{};
- for ( int x = 0; x != ( i + 1 ); ++x ){
- vec_account.push_back( StatementOfAccount{
- info.balance + 1000, DateTime{ t, 2016, 06, 10 },
- TransactionType::Debit, "enum class TransactionType"
- } );
- }
- info.transactions = std::move( vec_account );
- map.insert( { info.account_number, info } );
- }
- }
- std::cout << "Done creating...now writing" << std::endl;
- WriteToFileFromMap( file, map );
- fclose( file );
- fopen_s( &file, "file.db", "rb" );
- ReadFromFileToMap( file, m_data );
- }
- else {
- ReadFromFileToMap( file, m_data );
- }
- bool lflag = false;
- while ( !flag.compare_exchange_weak( lflag, true ) );
- std::cout << "Compare exchange weak....done.\n";
- }
- struct ServerThread
- {
- private:
- static std::map<unsigned int, UserInfo> data;
- static std::map<unsigned int, utility::string_t> loggedin_users;
- public:
- static void processGetter( http::http_request request )
- {
- if ( !flag.load() ){
- request.reply( http::status_codes::PartialContent );
- }
- else {
- request.reply( http::status_codes::OK );
- }
- }
- static void processPost( http::http_request request )
- {
- if ( !flag.load() ){
- request.reply( http::status_codes::PartialContent );
- }
- else {
- std::wcout << request.absolute_uri().path() << std::endl;
- if ( request.absolute_uri().path() == U( "/login" ) ){
- std::wcout << L"We are being asked for permission to login\n";
- request.extract_json().then( [ = ] ( pplx::task<web::json::value> jsonValue ){
- web::json::value login_info{};
- int username{};
- utility::string_t password;
- try {
- login_info = jsonValue.get();
- username = login_info[ U( "username" ) ].as_integer();
- password = login_info[ U( "pin" ) ].as_string();
- }
- catch ( http::http_exception except ){
- std::wcerr << "Conversion error: " << except.what() << std::endl;
- }
- catch ( ... ) {
- std::wcerr << "We are unable to identify what went wrong" << std::endl;
- }
- auto search_result = data.find( username );
- if ( search_result == data.end() ){
- web::json::value error{};
- error[ U( "Error" ) ] = web::json::value( U( "User not found." ) );
- std::wcerr << "We are done here\n";
- request.reply( http::status_codes::Unauthorized, error );
- }
- else {
- GUID session_id;
- CoCreateGuid( &session_id );
- web::json::value ack_message{};
- uint32_t guid_array[ 3 ] { session_id.Data1, session_id.Data2, session_id.Data3 };
- auto first_byte = web::json::value( guid_array[ 0 ] ).as_string(),
- second_byte = web::json::value( guid_array[ 1 ] ).as_string(),
- third_byte = web::json::value( guid_array[ 2 ] ).as_string();
- auto guid_session_id = first_byte + second_byte + third_byte;
- loggedin_users.insert( { username, guid_session_id } );
- ack_message[ U( "Status" ) ] = web::json::value( U( "Success" ) );
- ack_message[ U( "session_id" ) ] = web::json::value( guid_session_id );
- ack_message[ U( "More" ) ] = web::json::value( U( "Successfully logged in." ) );
- request.reply( http::status_codes::Accepted, ack_message );
- }
- } ).wait();
- }
- request.reply( http::status_codes::Unauthorized );
- }
- }
- static void processPut( http::http_request request )
- {
- }
- static void processLogin( http::http_request request )
- {
- }
- void operator()()
- {
- std::thread long_computation{ foo, data };
- server_listener::http_listener server{ U( "http://localhost:3000" ) };
- server.support( http::methods::GET, processGetter );
- server.support( http::methods::PUT, processPut );
- server.support( http::methods::POST, processPost ); // for accepting ID/password
- server.support( http::methods::CONNECT, processLogin );
- try {
- server.open()
- .then( [ &long_computation ]
- {
- } ).wait();
- while ( true );
- }
- catch ( std::exception const & error_message ) {
- std::cerr << error_message.what() << "\n";
- }
- }
- };
- std::map<unsigned int, UserInfo> ServerThread::data{};
- std::map<unsigned int, utility::string_t> ServerThread::loggedin_users{};
- int main()
- {
- std::thread server_thread{ ServerThread{} };
- http::client::http_client client{ U( "http://localhost:3000" ) };
- server_thread.detach();
- auto task = client.request( http::methods::GET ).then( [ &client ] ( http::http_response response ){
- if ( response.status_code() != http::status_codes::OK ){
- throw std::runtime_error{ "We don't know what happened but we can't continue" };
- }
- http::uri_builder uri_builder{ U( "login" ) };
- web::json::value login_credentials{};
- login_credentials[ U( "username" ) ] = web::json::value::number( 12345678 );
- login_credentials[ U( "pin" ) ] = web::json::value::string( U( "1490" ) );
- return client.request( http::methods::POST, uri_builder.to_string(), login_credentials );
- } ).then( [ &client ] ( http::http_response response ) {
- if ( response.status_code() != http::status_codes::Accepted ){
- response.extract_json().then( [] ( pplx::task<web::json::value> jsonValue ){
- auto reason = jsonValue.get().as_object()[ U( "Error" ) ].as_string();
- std::wcerr << reason << std::endl;
- } ).wait();
- }
- else {
- auto session_id = std::make_shared<utility::string_t>();
- response.extract_json().then( [ &client, &session_id ] ( pplx::task<web::json::value> jsonValue ){
- web::json::value value{};
- try {
- value = jsonValue.get();
- }
- catch ( http::http_exception error ){
- std::wcerr << error.what() << std::endl;
- }
- auto result = value.as_object();
- std::wcerr << result[ U( "Status" ) ].as_string() << std::endl;
- std::wcerr << result[ U( "More" ) ].as_string() << std::endl;
- *session_id = result[ U( "session_id" ) ].as_string();
- web::uri_builder uri_builder{ U( "/home" ) };
- uri_builder.append_query( U( "username" ), U( "1234" ) );
- uri_builder.append_query( U( "session_id" ), *session_id );
- uri_builder.append_query( U( "utility" ), U( "balance" ) );
- client.request( http::methods::GET, uri_builder.to_string() );
- } ).wait();
- }
- } );
- try {
- task.wait();
- }
- catch ( std::exception const & except ){
- std::cout << "Error: " << except.what() << std::endl;
- }
- std::cout << "I am done jare" << std::endl;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement