void ProcessMessage_ZMQ(const std::string & str_Message, std::string & str_Reply) { OT_ASSERT(NULL != g_pServer); if (str_Message.size() < 1) return; // -------------------- // return value. std::string resultString = ""; // Whatever we put in this string is what will get returned. // First we grab the client's message OTASCIIArmor ascMessage; ascMessage.MemSet(str_Message.data(), str_Message.size()); // ------------------ // // OTPayload thePayload; // thePayload.SetPayloadSize(str_Message.size()); // memcpy((void*)thePayload.GetPayloadPointer(), str_Message.data(), str_Message.size()); // ---------------------------------------------------------------------- // OTLog::vError("Envelope: \n%s\n Size: %ld\n", ascMessage.Get(), ascMessage.GetLength()); OTMessage theMsg, theReply; // we'll need these in a sec... // OTEnvelope theEnvelope(ascMessage); // Now the base64 is decoded and unpacked, and the envelope is in binary form again. OTEnvelope theEnvelope; // Now the base64 is decoded and the envelope is in binary form again. if (theEnvelope.SetAsciiArmoredData(ascMessage)) { OTLog::Output(2, "Successfully retrieved envelope from ZMQ message...\n"); OTString strEnvelopeContents; // OTString strPubkeyPath("TESTPUBKEY.txt"); // g_pServer->GetServerNym().SavePublicKey(strPubkeyPath); // Decrypt the Envelope. if (theEnvelope.Open(g_pServer->GetServerNym(), strEnvelopeContents)) // now strEnvelopeContents contains the decoded message. { // All decrypted--now let's load the results into an OTMessage. // No need to call theMsg.ParseRawFile() after, since // LoadContractFromString handles it. // if (strEnvelopeContents.Exists() && theMsg.LoadContractFromString(strEnvelopeContents)) { // In case you want to see all the incoming messages... // OTLog::vOutput(0, "%s\n\n", strEnvelopeContents.Get()); // By constructing this without a socket, I put it in XmlRpc/http mode, instead of tcp/ssl. OTClientConnection theClient(*g_pServer); // By optionally passing in &theClient, the client Nym's public key will be // set on it whenever verification is complete. (So for the reply, I'll // have the key and thus I'll be able to encrypt reply to the recipient.) if (g_pServer->ProcessUserCommand(theMsg, theReply, &theClient)) { // At this point the reply is ready to go, and theClient has the public key of the recipient... OTLog::vOutput(1, "Successfully processed user command: %s.\n", theMsg.m_strCommand.Get()); // The transaction is now processed, and the server's reply message is in theReply. // Let's seal it up to the recipient's nym (in an envelope) and send back to the user... OTEnvelope theRecipientEnvelope; bool bSealed = theClient.SealMessageForRecipient(theReply, theRecipientEnvelope); if (bSealed) { // OTPayload theReplyPayload; // theReplyPayload.SetEnvelope(theRecipientEnvelope); // // resultString = ascReply.Get(); // resultString.assign(theReplyPayload.GetPayloadPointer(), theReplyPayload.GetPayloadSize()); OTASCIIArmor ascReply; if (theRecipientEnvelope.GetAsciiArmoredData(ascReply)); resultString.assign(ascReply.Get(), ascReply.GetLength()); } else OTLog::Output(0, "Unable to seal envelope in ProcessMessage_ZMQ.\n"); } else OTLog::Output(0, "Unable to process user command in ProcessMessage_ZMQ.\n"); } else OTLog::Error("Error loading message from envelope contents. ProcessMessage_ZMQ.\n"); } else OTLog::Error("Unable to open envelope. ProcessMessage_ZMQ.\n"); } else OTLog::Error("Error retrieving envelope from ProcessMessage_ZMQ.\n"); // ---------------------------------------------------------------------- str_Reply = resultString; }
bool MessageProcessor::processMessage(const std::string& messageString, std::string& reply) { if (messageString.size() < 1) return false; // First we grab the client's message OTASCIIArmor ascMessage; ascMessage.MemSet(messageString.data(), messageString.size()); String messageContents; ascMessage.GetString(messageContents); // All decrypted--now let's load the results into an OTMessage. // No need to call message.ParseRawFile() after, since // LoadContractFromString handles it. Message message; if (!messageContents.Exists() || !message.LoadContractFromString(messageContents)) { Log::vError("Error loading message from message " "contents:\n\n%s\n\n", messageContents.Get()); return true; } Message replyMessage; replyMessage.m_strCommand.Format("%sResponse", message.m_strCommand.Get()); // NymID replyMessage.m_strNymID = message.m_strNymID; // NotaryID, a hash of the server contract replyMessage.m_strNotaryID = message.m_strNotaryID; // The default reply. In fact this is probably superfluous replyMessage.m_bSuccess = false; ClientConnection client; Nym nym(message.m_strNymID); bool processedUserCmd = server_->userCommandProcessor_.ProcessUserCommand( message, replyMessage, &client, &nym); // By optionally passing in &client, the client Nym's public // key will be set on it whenever verification is complete. (So // for the reply, I'll have the key and thus I'll be able to // encrypt reply to the recipient.) if (!processedUserCmd) { String s1(message); Log::vOutput(0, "Unable to process user command: %s\n ********** " "REQUEST:\n\n%s\n\n", message.m_strCommand.Get(), s1.Get()); // NOTE: normally you would even HAVE a true or false if // we're in this block. ProcessUserCommand() // is what tries to process a command and then sets false // if/when it fails. Until that point, you // wouldn't get any server reply. I'm now changing this // slightly, so you still get a reply (defaulted // to success==false.) That way if a client needs to re-sync // his request number, he will get the false // and therefore know to resync the # as his next move, vs // being stuck with no server reply (and thus // stuck with a bad socket.) // We sign the reply here, but not in the else block, since // it's already signed in cases where // ProcessUserCommand() is a success, by the time that call // returns. // Since the process call definitely failed, I'm replyMessage.m_bSuccess = false; // making sure this here is definitely set to // false (even though it probably was already.) replyMessage.SignContract(server_->GetServerNym()); replyMessage.SaveContract(); String s2(replyMessage); Log::vOutput(0, " ********** RESPONSE:\n\n%s\n\n", s2.Get()); } else { // At this point the reply is ready to go, and client // has the public key of the recipient... Log::vOutput(1, "Successfully processed user command: %s.\n", message.m_strCommand.Get()); } String replyString(replyMessage); if (!replyString.Exists()) { Log::vOutput(0, "Failed trying to grab the reply " "in OTString form. " "(No reply message will be sent.)\n"); return true; } OTASCIIArmor ascReply(replyString); if (!ascReply.Exists()) { Log::vOutput(0, "Unable to WriteArmoredString from " "OTASCIIArmor object into OTString object. (No reply " "message will be sent.)\n"); return true; } reply.assign(ascReply.Get(), ascReply.GetLength()); return false; }
// true == YES, DISCONNECT m_pSocket, something must have gone wrong. // false == NO, do NOT disconnect m_pSocket, everything went wonderfully! // bool ProcessMessage_ZMQ(OTServer & theServer, const std::string & str_Message, std::string & str_Reply) { if (str_Message.size() < 1) return false; const char * szFunc = "ProcessMessage_ZMQ"; // -------------------- // return value. std::string resultString = ""; // Whatever we put in this string is what will get returned. // First we grab the client's message OTASCIIArmor ascMessage; ascMessage.MemSet(str_Message.data(), str_Message.size()); // ------------------ // // OTPayload thePayload; // thePayload.SetPayloadSize(str_Message.size()); // memcpy((void*)thePayload.GetPayloadPointer(), str_Message.data(), str_Message.size()); // ---------------------------------------------------------------------- // OTLog::vError("Envelope: \n%s\n Size: %ld\n", ascMessage.Get(), ascMessage.GetLength()); bool bReturnVal = false; // "false" == no, do NOT disconnect. No errors. ("True" means YES, DISCONNECT!) OTMessage theMsg, theReply; // we'll need these in a sec... // OTEnvelope theEnvelope(ascMessage); OTEnvelope theEnvelope; if (false == theEnvelope.SetAsciiArmoredData(ascMessage)) { OTLog::vError("%s: Error retrieving envelope.\n", szFunc); bReturnVal = true; // disconnect the socket! } else { // Now the base64 is decoded and the envelope is in binary form again. OTLog::vOutput(2, "%s: Successfully retrieved envelope from ZMQ message...\n", szFunc); OTString strEnvelopeContents; // OTString strPubkeyPath("TESTPUBKEY.txt"); // theServer.GetServerNym().SavePublicKey(strPubkeyPath); // Decrypt the Envelope. if (false == theEnvelope.Open(theServer.GetServerNym(), strEnvelopeContents)) // now strEnvelopeContents contains the decoded message. { OTLog::vError("%s: Unable to open envelope.\n", szFunc); bReturnVal = true; // disconnect the socket! } else { // All decrypted--now let's load the results into an OTMessage. // No need to call theMsg.ParseRawFile() after, since // LoadContractFromString handles it. // if (strEnvelopeContents.Exists() && theMsg.LoadContractFromString(strEnvelopeContents)) { theReply.m_strCommand.Format("@%s", theMsg.m_strCommand.Get()); theReply.m_strNymID = theMsg.m_strNymID; // UserID theReply.m_strServerID = theMsg.m_strServerID; // ServerID, a hash of the server contract. theReply.m_bSuccess = false; // The default reply. In fact this is probably superfluous. // In case you want to see all the incoming messages... // OTLog::vOutput(0, "%s\n\n", strEnvelopeContents.Get()); // By constructing this without a socket, I put it in ZMQ mode, instead of tcp/ssl. OTClientConnection theClient(theServer); // By optionally passing in &theClient, the client Nym's public key will be // set on it whenever verification is complete. (So for the reply, I'll // have the key and thus I'll be able to encrypt reply to the recipient.) if (false == theServer.ProcessUserCommand(theMsg, theReply, &theClient)) { const OTString s1(theMsg), s2(theReply); OTLog::vOutput(0, "%s: Unable to process user command.\n\n ********** " "REQUEST:\n\n%s\n\n ********** RESPONSE:\n\n%s\n\n", szFunc, s1.Get(), s2.Get()); // NOTE: normally you would even HAVE a true or false if we're in this block. ProcessUserCommand() // is what tries to process a command and then sets false if/when it fails. Until that point, you // wouldn't get any server reply. I'm now changing this slightly, so you still get a reply (defaulted // to success==false.) That way if a client needs to re-sync his request number, he will get the false // and therefore know to resync the # as his next move, vs being stuck with no server reply (and thus // stuck with a bad socket.) // We sign the reply here, but not in the else block, since it's already signed in cases where // ProcessUserCommand() is a success, by the time that call returns. theReply.m_bSuccess = false; // Since the process call definitely failed, I'm making sure this here is definitely set to false (even though it probably was already.) theReply.SignContract(theServer.GetServerNym()); theReply.SaveContract(); } else // At this point the reply is ready to go, and theClient has the public key of the recipient... OTLog::vOutput(1, "%s: Successfully processed user command: %s.\n", szFunc, theMsg.m_strCommand.Get()); // ------------------------------------------------- // The transaction is now processed (or not), and the server's reply message is in theReply. // Let's seal it up to the recipient's nym (in an envelope) and send back to the user... // OTEnvelope theRecipientEnvelope; bool bSealed = theClient.SealMessageForRecipient(theReply, theRecipientEnvelope); if (false == bSealed) { OTLog::vOutput(0, "%s: Unable to seal envelope. (No reply will be sent.)\n", szFunc); bReturnVal = true; // disconnect the socket! } else { // OTPayload theReplyPayload; // theReplyPayload.SetEnvelope(theRecipientEnvelope); // resultString = ascReply.Get(); // resultString.assign(theReplyPayload.GetPayloadPointer(), theReplyPayload.GetPayloadSize()); OTASCIIArmor ascReply; if (theRecipientEnvelope.GetAsciiArmoredData(ascReply)) resultString.assign(ascReply.Get(), ascReply.GetLength()); } } else { OTLog::vError("%s: Error loading message from envelope contents:\n\n%s\n\n", szFunc, strEnvelopeContents.Get()); bReturnVal = true; // disconnect the socket! } } } // ---------------------------------------------------------------------- str_Reply = resultString; return bReturnVal; } // ProcessMessage_ZMQ