ProfileInfo ProfileClient::uploadChange(ProfileInfo newValue) { auto url = baseUserUrl() + "/profile/" + newValue.key + "?lastModified=" + std::to_string(newValue.lastModified); Json::Value jsonBody(Json::objectValue); jsonBody["value"] = newValue.value; sendRequest(Http::Request( Http::HttpMethod::Put, url, makeHeaders(Authenticated::True)), jsonBody); auto json = parseJsonBody(); try { auto result = parseJsonKeyLastModified(json); if (result.key != newValue.key) { throw ProtocolError("Server sent the wrong record"); } result.value = newValue.value; return result; } catch (ConversionException) { std::throw_with_nested(ProtocolError("Failed to parse body")); } }
IdLastModified MessagesClient::modifyMeta( const IdLastModified &idlm, const std::vector<unsigned char> &meta) { auto url = baseUserUrl() + "/messages/" + std::to_string(idlm.id) + "?lastModified=" + std::to_string(idlm.lastModified); Json::Value jsonBody(Json::objectValue); jsonBody["meta"] = Base64::encode(meta); sendRequest(Http::Request( Http::HttpMethod::Patch, url, makeHeaders(Authenticated::True)), jsonBody); auto json = parseJsonBody(); try { return parseJsonIdLastModified(json); } catch (ConversionException) { std::throw_with_nested(ProtocolError("Failed to parse idLastModified")); } }
void* VRDeviceClient::streamReceiveThreadMethod(void) { while(true) { /* Wait for next packet reply message: */ VRDevicePipe::MessageIdType message=pipe.readMessage(); if(message==VRDevicePipe::PACKET_REPLY) { /* Read server's state: */ { Threads::Mutex::Lock stateLock(stateMutex); state.read(pipe); } /* Signal packet reception: */ packetSignalCond.broadcast(); /* Invoke packet notification callback: */ { Threads::Mutex::Lock packetNotificationLock(packetNotificationMutex); if(packetNotificationCB!=0) packetNotificationCB(this,packetNotificationCBData); } } else if(message==VRDevicePipe::STOPSTREAM_REPLY) break; else throw ProtocolError("VRDeviceClient: Mismatching message while waiting for PACKET_REPLY"); } return 0; }
ProteinClient::ProteinClient(const char* serverName,int serverPort) :pipe(new ClientServerPipe(TCPSocket(serverName,serverPort))) { /* Send connect request message: */ pipe->writeMessage(ClientServerPipe::CONNECT_REQUEST); /* Wait for connect reply message: */ if(!pipe->getSocket().waitForData(10,0,false)) throw ProtocolError("ProteinClient: Server timed out during connection initialization"); ClientServerPipe::MessageIdType reply=pipe->readMessage(); if(reply==ClientServerPipe::NACK) throw ProtocolWarning("ProteinClient: Server refused connection"); else if(reply!=ClientServerPipe::CONNECT_REPLY) throw ProtocolError("ProteinClient: Mismatching message during connection initialization"); }
void VRDeviceClient::getPacket(void) { if(active) { if(streaming) { /* Wait for arrival of next packet: */ packetSignalCond.wait(); } else { /* Send packet request message: */ pipe.writeMessage(VRDevicePipe::PACKET_REQUEST); pipe.flush(); /* Wait for packet reply message: */ pipe.waitForData(10,0); // Throw exception if reply does not arrive in time if(pipe.readMessage()!=VRDevicePipe::PACKET_REPLY) throw ProtocolError("VRDeviceClient: Mismatching message while waiting for PACKET_REPLY"); /* Read server's state: */ { Threads::Mutex::Lock stateLock(stateMutex); state.read(pipe); } /* Invoke packet notification callback: */ { Threads::Mutex::Lock packetNotificationLock(packetNotificationMutex); if(packetNotificationCB!=0) packetNotificationCB(this,packetNotificationCBData); } } } }
MessagesClient::GetMessagesResult MessagesClient::getMessages( lastModified_type modifiedAfter) { auto url = baseUserUrl() + "/messages?modifiedAfter=" + std::to_string(modifiedAfter) + "&includeData=true"; sendRequest(Http::Request( Http::HttpMethod::Get, url, makeHeaders(Authenticated::True))); auto json = parseJsonBody(); if (!json.isObject()) { throw ProtocolError("Malformed JSON document (object expected)"); } auto resultsTotal = CheckedConverter::toUint32(json["resultsTotal"]); auto resultsReturned = CheckedConverter::toUint32(json["resultsReturned"]); auto data = json["data"]; if (!data.isArray()) { throw ProtocolError("Malformed JSON document (array expected)"); } auto messages = std::vector<Message>(); messages.reserve(data.size()); for (const auto &msgJson : data) { try { messages.push_back(parseJsonMessage(msgJson)); } catch (ConversionException) { std::throw_with_nested(ProtocolError("Failed to parse messages array")); } } GetMessagesResult result; result.messages = std::move(messages); result.countReturned = resultsReturned; result.countLeft = resultsTotal; return result; }
void ProteinClient::getConfigurationById(unsigned int configId,MD::Protein* protein) { /* Send get configuration request message: */ pipe->writeMessage(ClientServerPipe::GETCONFIGBYID_REQUEST); pipe->writeConfigId(configId); /* Wait for reply message: */ ClientServerPipe::MessageIdType reply=pipe->readMessage(); if(reply==ClientServerPipe::NACK) throw ProtocolWarning("ProteinClient: Server refused to send configuration"); else if(reply!=ClientServerPipe::GETCONFIGBYID_REPLY) throw ProtocolError("ProteinClient: Mismatching message while retrieving configuration"); /* Read configuration: */ if(!pipe->readConfiguration(protein)) throw ProtocolError("ProteinClient: Mismatching protein size while retrieving configuration"); }
void VRDeviceClient::initClient(void) { /* Initiate connection: */ pipe.writeMessage(VRDevicePipe::CONNECT_REQUEST); pipe.write<unsigned int>(VRDevicePipe::protocolVersionNumber); pipe.flush(); /* Wait for server's reply: */ if(!pipe.waitForData(30,0,false)) throw ProtocolError("VRDeviceClient: Timeout while waiting for CONNECT_REPLY"); if(pipe.readMessage()!=VRDevicePipe::CONNECT_REPLY) throw ProtocolError("VRDeviceClient: Mismatching message while waiting for CONNECT_REPLY"); unsigned int serverProtocolVersionNumber=pipe.read<unsigned int>(); /* Check server version number or something... */ /* Read server's layout and initialize current state: */ state.readLayout(pipe); }
IdLastModified MessagesClient::parseJsonIdLastModified(const Json::Value &json) { if (!json.isObject()) { throw ProtocolError("Malformed JSON document (object expected)"); } IdLastModified idlm; idlm.id = CheckedConverter::toUint32(json["id"]); idlm.lastModified = CheckedConverter::toUint64(json["lastModified"]); return idlm; }
ProfileInfo ProfileClient::parseJsonKeyLastModified(const Json::Value &json) { if (!json.isObject()) { throw ProtocolError("Malformed JSON document (object expected)"); } ProfileInfo result; result.key = CheckedConverter::toString(json["key"]); result.lastModified = CheckedConverter::toUint64(json["lastModified"]); return result; }
MessageSent MessagesClient::parseJsonMessageSent(const Json::Value &json) { if (!json.isObject()) { throw ProtocolError("Malformed JSON document (object expected)"); } auto dateReceived = CheckedConverter::toDateTime(json["dateReceived"]); MessageSent msgSent{dateReceived}; msgSent.id = CheckedConverter::toUint32(json["id"]); msgSent.lastModified = CheckedConverter::toUint64(json["lastModified"]); return msgSent; }
void ProteinClient::unlockServerQueue(void) { /* Send unlock queue request message: */ pipe->writeMessage(ClientServerPipe::UNLOCKQUEUE_REQUEST); /* Wait for reply message: */ ClientServerPipe::MessageIdType reply=pipe->readMessage(); if(reply==ClientServerPipe::NACK) throw ProtocolWarning("ProteinClient: Server refused request to unlock queue"); else if(reply!=ClientServerPipe::UNLOCKQUEUE_REPLY) throw ProtocolError("ProteinClient: Mismatching message while unlocking server queue"); }
void ProteinClient::getOptimizationTree(const char* fileName) { /* Send get optimization tree request message: */ pipe->writeMessage(ClientServerPipe::GETOPTIMIZATIONTREE_REQUEST); /* Wait for reply message: */ ClientServerPipe::MessageIdType reply=pipe->readMessage(); if(reply==ClientServerPipe::NACK) throw ProtocolWarning("ProteinClient: Server refused to send optimization tree"); else if(reply!=ClientServerPipe::GETOPTIMIZATIONTREE_REPLY) throw ProtocolError("ProteinClient: Mismatching message while retrieving optimization tree"); /* Retrieve optimization tree: */ int numTreeNodes=pipe->readNumOptimizationTreeNodes(); ClientServerPipe::OptimizationTreeNode* treeNodes=new ClientServerPipe::OptimizationTreeNode[numTreeNodes]; pipe->readOptimizationTreeNodes(numTreeNodes,treeNodes); /* Open tree file: */ FILE* file=fopen(fileName,"w"); if(file==0) { delete[] treeNodes; throw std::runtime_error(std::string("ProteinClient: Unable to open optimization tree file ")+std::string(fileName)); } /* Write tree to file: */ #if 1 for(int i=0;i<numTreeNodes;++i) fprintf(file,"%d %d %d %g %d\n",treeNodes[i].id,treeNodes[i].parentId,treeNodes[i].manipulated,treeNodes[i].energy,treeNodes[i].status); #else fprintf(file,"graph G {\n"); static char* nodeColors[4]={"1.0 0.0 0.0","0.0 1.0 0.0","0.0 0.0 1.0","0.5 0.5 0.5"}; for(int i=0;i<numTreeNodes;++i) { char label[80]; sprintf(label,"%u | %12.4g",treeNodes[i].id,treeNodes[i].energy); fprintf(file,"\tcfg%u [label=\"%s\",color=\"%s\"];\n",treeNodes[i].id,label,nodeColors[treeNodes[i].status]); if(treeNodes[i].parentId!=0) { if(treeNodes[i].manipulated) fprintf(file,"\tcfg%u -> cfg%u [color=\"1.0 0.0 0.0\"];\n",treeNodes[i].parentId,treeNodes[i].id); else fprintf(file,"\tcfg%u -> cfg%u;\n",treeNodes[i].parentId,treeNodes[i].id); } } fprintf(file,"}\n"); #endif /* Clean up: */ fclose(file); delete[] treeNodes; }
void ProteinClient::removeConfigurationById(unsigned int configId) { /* Send remove configuration request message: */ pipe->writeMessage(ClientServerPipe::REMOVECONFIGBYID_REQUEST); pipe->writeConfigId(configId); /* Wait for reply message: */ ClientServerPipe::MessageIdType reply=pipe->readMessage(); if(reply==ClientServerPipe::NACK) throw ProtocolWarning("ProteinClient: Server refused to remove configuration"); else if(reply!=ClientServerPipe::REMOVECONFIGBYID_REPLY) throw ProtocolError("ProteinClient: Mismatching message while removing configuration"); }
std::vector<ProfileInfo> ProfileClient::downloadChanges( lastModified_type modifiedAfter) { sendRequest(Http::Request( Http::HttpMethod::Get, baseUserUrl() + "/profile?modifiedAfter=" + std::to_string(modifiedAfter), makeHeaders(Authenticated::True))); auto json = parseJsonBody(); if (!json.isObject()) { throw ProtocolError("Malformed JSON document (object expected)"); } auto data = json["data"]; if (!data.isArray()) { throw ProtocolError("Malformed JSON document (array expected)"); } auto result = std::vector<ProfileInfo>(); result.reserve(data.size()); for (const auto &profileInfoJson : data) { try { result.push_back(parseJsonProfileInfo(profileInfoJson)); } catch (ConversionException) { std::throw_with_nested( ProtocolError("Failed to parse profile info array")); } } return result; }
int ProteinClient::getNumConfigurations(void) { /* Send get number of configurations request message: */ pipe->writeMessage(ClientServerPipe::GETNUMCONFIGS_REQUEST); /* Wait for reply message: */ ClientServerPipe::MessageIdType reply=pipe->readMessage(); if(reply==ClientServerPipe::NACK) throw ProtocolWarning("ProteinClient: Server refused to send number of configurations"); else if(reply!=ClientServerPipe::GETNUMCONFIGS_REPLY) throw ProtocolError("ProteinClient: Mismatching message while querying number of configurations"); /* Return number of configurations: */ int numConfigs=pipe->readNumConfigs(); return numConfigs; }
MessagesClient::SendMessageResult MessagesClient::doSendMessage( const KulloAddress *recipient, const SendableMessage &message, const std::vector<unsigned char> &meta, const boost::optional<ProgressHandler> &onProgress) { bool toSelf = !recipient; kulloAssert((!toSelf && meta.empty()) || (toSelf && !meta.empty())); auto auth = (toSelf) ? Authenticated::True : Authenticated::False; Util::MimeMultipart multipart; multipart.addPart("keySafe", message.keySafe); multipart.addPart("content", message.content); if (!meta.empty()) multipart.addPart("meta", meta); multipart.addPart("attachments", message.attachments); auto contentType = std::string("multipart/form-data; boundary=\"") + multipart.boundary() + "\""; auto body = multipart.toString(); sendRequest(Http::Request( Http::HttpMethod::Post, baseUserUrl(recipient) + "/messages", makeHeaders(auth, contentType, body.size())), body, onProgress); SendMessageResult result; if (toSelf) { auto json = parseJsonBody(); try { result.messageSent = parseJsonMessageSent(json); result.messageSent->size = body.size(); result.requestBodySize = body.size(); } catch (ConversionException) { std::throw_with_nested( ProtocolError("Failed to parse message sent data")); } } return result; }
void ControlImpl::SendReply(ReplyCode code, bool part, const std::string& message) { if (singleLineReplies && part) return; std::ostringstream reply; if (code != NoCode) reply << std::setw(3) << code << (part ? "-" : " "); reply << message; logs::Debug(reply.str()); reply << "\r\n"; const std::string& str = reply.str(); Write(str.c_str(), str.length()); if (lastCode != code && lastCode != CodeNotSet && code != ftp::NoCode) throw ProtocolError("Invalid reply code sequence."); if (code != ftp::NoCode) lastCode = code; }
unsigned int ProteinClient::addConfiguration(unsigned int parentId,const MD::Protein* protein) { /* Send add configuration request message: */ pipe->writeMessage(ClientServerPipe::ADDCONFIG_REQUEST); /* Write configuration: */ pipe->writeConfigId(parentId); pipe->writeConfiguration(protein); /* Wait for reply message: */ ClientServerPipe::MessageIdType reply=pipe->readMessage(); if(reply==ClientServerPipe::NACK) throw ProtocolWarning("ProteinClient: Server refused to add configuration"); else if(reply!=ClientServerPipe::ADDCONFIG_REPLY) throw ProtocolError("ProteinClient: Mismatching message while adding configuration"); return pipe->readConfigId(); }
Message MessagesClient::parseJsonMessage(const Json::Value &json) { if (!json.isObject()) { throw ProtocolError("Malformed JSON document (object expected)"); } Message msg; msg.id = CheckedConverter::toUint32(json["id"]); msg.lastModified = CheckedConverter::toUint64(json["lastModified"]); msg.deleted = CheckedConverter::toBool(json["deleted"]); if (!msg.deleted) { msg.dateReceived = CheckedConverter::toDateTime(json["dateReceived"]); msg.keySafe = CheckedConverter::toVector(json["keySafe"]); msg.content = CheckedConverter::toVector(json["content"]); } msg.meta = CheckedConverter::toVector(json["meta"], AllowEmpty::True); msg.hasAttachments = CheckedConverter::toBool(json["hasAttachments"]); return msg; }
IdLastModified MessagesClient::deleteMessage( const IdLastModified &idlm) { auto url = baseUserUrl() + "/messages/" + std::to_string(idlm.id) + "?lastModified=" + std::to_string(idlm.lastModified); sendRequest(Http::Request( Http::HttpMethod::Delete, url, makeHeaders(Authenticated::True))); auto json = parseJsonBody(); try { return parseJsonIdLastModified(json); } catch (ConversionException) { std::throw_with_nested(ProtocolError("Failed to parse idLastModified")); } }
void RemoteNode::handle_response_(WorkItem& work) { const vfsprotocol::ResponseType rsp_type = work.future.get(); switch (rsp_type) { case vfsprotocol::ResponseType::Ok: // all is well break; case vfsprotocol::ResponseType::ObjectNotRunningHere: LOG_INFO(node_id() << ": volume not present on that node"); throw vd::VolManager::VolumeDoesNotExistException("volume not present on node", work.request_desc); break; case vfsprotocol::ResponseType::UnknownRequest: LOG_WARN(node_id() << ": got an UnknownRequest response status in response to " << work.request_desc); // handle differently once we need to take care of backward compatibility. throw ProtocolError("Remote sent UnknownRequest response status", work.request_desc); break; case vfsprotocol::ResponseType::Timeout: LOG_ERROR(node_id() << ": got a Timeout response status in response to " << work.request_desc); throw RemoteTimeoutException("Remote sent timeout status", work.request_desc); break; default: LOG_ERROR(node_id() << ": " << work.request_desc << " failed, remote returned status " << vfsprotocol::response_type_to_string(rsp_type) << " (" << static_cast<uint32_t>(rsp_type) << ")"); throw fungi::IOException("Remote operation failed", work.request_desc); break; } }
void ClientConnection::handleCommand(const std::string& line) { if (boost::iequals(line, "RETRIEVE TASKS")) { auto& query = findTasksForLoginQ(); query.execute(_userId); std::unique_ptr<ClientTask> task; while (query.next(task)) { _stream.writeLine(concatln("TASK ", task->_id, " TITLE ", quoteString(task->_title), " SPENT ", toSeconds(task->_timeSpent))); for (const auto& line : task->_description) { _stream.writeLine(concatln(line)); } _stream.writeLine("\n"); } _stream.writeLine("END TASKS\n"); } else if (boost::iequals(line, "LOG UPLOAD")) { auto& lastEntryTimeQ = findLastLogEntryTimeForClientQ(); lastEntryTimeQ.execute(_clientId); boost::optional<Timestamp> lastEntryTime; bool res = lastEntryTimeQ.next(lastEntryTime); assert(res); assert(! lastEntryTimeQ.next(lastEntryTime)); if (lastEntryTime) { _stream.writeLine(concatln("LAST ENTRY AT ", formatTimestamp(*lastEntryTime))); } else { _stream.writeLine("NO ENTRYS\n"); } int taskId; std::set<std::string> employeeIds; bool loop = true; while (loop) { auto line = _stream.readLine(); LogEntry entry; if (parse(line, TimestampToken(entry._timestamp), " ", BareStringToken(entry._userId), " LOGIN")) { entry._type = LogEntryType_LOGIN; } else if (parse(line, TimestampToken(entry._timestamp), " ", BareStringToken(entry._userId), " LOGOUT")) { entry._type = LogEntryType_LOGOUT; } else if (parse(line, TimestampToken(entry._timestamp), " ", BareStringToken(entry._userId), " TASK ", IntToken(taskId), " START")) { entry._type = LogEntryType_TASK_START; entry._taskId = taskId; } else if (parse(line, TimestampToken(entry._timestamp), " ", BareStringToken(entry._userId), " TASK ", IntToken(taskId), " PAUSE")) { entry._type = LogEntryType_TASK_PAUSE; entry._taskId = taskId; } else if (parse(line, TimestampToken(entry._timestamp), " ", BareStringToken(entry._userId), " TASK ", IntToken(taskId), " FINISH")) { entry._type = LogEntryType_TASK_FINISH; entry._taskId = taskId; } else if (boost::iequals(line, "END LOG")) { loop = false; } else { throw ProtocolError("Invalid log entry", line); } if (loop) { employeeIds.insert(entry._userId); insertLogEntry(entry); } } for (const auto& employeeId : employeeIds) { processLogs(employeeId); } emit tasksStatusChanged(); } else { throw ProtocolError("Invalid command", line); } }
void RemoteMinerClient::Run(const std::string &server, const std::string &port, const std::string &password, const std::string &address, const int threadcount) { int64 lastrequestedwork=GetTimeMillis(); //debug int64 starttime=0; int64 hashcount=0; int64 lastdisplay=0; std::cout << "Client will start " << threadcount << " miner threads" << std::endl; while(true) { if(IsConnected()==false) { m_minerthreads.Stop(); std::cout << "Attempting to connect to " << server << ":" << port << std::endl; Sleep(1000); if(Connect(server,port)) { m_minerthreads.Start(new threadtype); m_gotserverhello=false; std::cout << "Connected to " << server << ":" << port << std::endl; SendClientHello(password,address); lastrequestedwork=GetTimeMillis(); //debug starttime=GetTimeMillis(); } } else { Update(); while(MessageReady() && !ProtocolError()) { RemoteMinerMessage message; if(ReceiveMessage(message)) { if(message.GetValue().type()==json_spirit::obj_type) { HandleMessage(message); } else { std::cout << "Unexpected json type sent by server. Disconnecting." << std::endl; Disconnect(); } } } if(ProtocolError()) { std::cout << "Protocol error. Disconnecting." << std::endl; Disconnect(); } if(m_minerthreads.RunningThreadCount()<threadcount) { m_minerthreads.Start(new threadtype); } if(m_minerthreads.HaveFoundHash()) { std::cout << "Found Hash!" << std::endl; RemoteMinerThread::foundhash fhash; m_minerthreads.GetFoundHash(fhash); SendFoundHash(fhash.m_blockid,fhash.m_nonce); SendWorkRequest(); } while(m_minerthreads.HaveHashResult()) { RemoteMinerThread::hashresult hresult; m_minerthreads.GetHashResult(hresult); SendMetaHash(hresult.m_blockid,hresult.m_metahashstartnonce,hresult.m_metahashdigest,hresult.m_besthash,hresult.m_besthashnonce); //debug //std::cout << "sent result " << hresult.m_blockid << " " << hresult.m_metahashstartnonce << " " << hresult.m_besthashnonce << std::endl; hashcount+=m_metahashsize; if(hresult.m_metahashstartnonce>4000000000 && (lastrequestedwork+5000)<GetTimeMillis()) { std::cout << "Requesting a new block " << GetTimeMillis() << std::endl; SendWorkRequest(); lastrequestedwork=GetTimeMillis(); } } if(m_minerthreads.NeedWork()) { if((lastrequestedwork+6000)<GetTimeMillis()) { std::cout << "Requesting a new block " << GetTimeMillis() << std::endl; SendWorkRequest(); lastrequestedwork=GetTimeMillis(); } } //debug if(lastdisplay+10000<=GetTimeMillis()) { if(((GetTimeMillis()-starttime)/1000)>0) { //std::cout << hashcount/((GetTimeMillis()-starttime)/1000) << std::endl; //std::cout << "sendsize=" << m_sendbuffer.size() << std::endl; lastdisplay=GetTimeMillis(); } } } } }
void visit(const msg::Update&) override { throw ProtocolError(fs("Can't handle message type Update on state: " << static_cast<unsigned>(m_state))); }
void visit(const msg::InternalSendStart&) override { throw ProtocolError(fs("Can't handle message type InternalSendStart on state: " << static_cast<unsigned>(m_state))); }
void visit(const msg::FileModified&) override { throw ProtocolError(fs("Can't handle message type Unknown on state: " << static_cast<unsigned>(m_state))); }
void visit(const msg::KeysAcknowledgment&) override { throw ProtocolError(fs("Can't handle message type Unknown on state: " << static_cast<unsigned>(m_state))); }