void ConnectionHandler::incoming(AMQFrame& frame) { if (getState() == CLOSED) { throw Exception("Received frame on closed connection"); } if (rcvTimeoutTask) { // Received frame on connection so delay timeout rcvTimeoutTask->restart(); } AMQBody* body = frame.getBody(); try { if (frame.getChannel() != 0 || !invoke(static_cast<ConnectionOperations&>(*this), *body)) { switch(getState()) { case OPEN: in(frame); break; case CLOSING: QPID_LOG(warning, "Ignoring frame while closing connection: " << frame); break; default: throw Exception("Cannot receive frames on non-zero channel until connection is established."); } } }catch(std::exception& e){ QPID_LOG(warning, "Closing connection due to " << e.what()); setState(CLOSING); errorCode = CLOSE_CODE_FRAMING_ERROR; errorText = e.what(); proxy.close(501, e.what()); } }
void SslConnector::handle(AMQFrame& frame) { bool notifyWrite = false; { Mutex::ScopedLock l(lock); frames.push_back(frame); //only ask to write if this is the end of a frameset or if we //already have a buffers worth of data currentSize += frame.encodedSize(); if (frame.getEof()) { lastEof = frames.size(); notifyWrite = true; } else { notifyWrite = (currentSize >= maxFrameSize); } /* NOTE: Moving the following line into this mutex block is a workaround for BZ 570168, in which the test testConcurrentSenders causes a hang about 1.5% of the time. ( To see the hang much more frequently leave this line out of the mutex block, and put a small usleep just before it.) TODO mgoulish - fix the underlying cause and then move this call back outside the mutex. */ if (notifyWrite && !closed) aio->notifyPendingWrite(); } }
void MessageTransfer::decodeHeader(framing::Buffer& buffer) { AMQFrame method; method.decode(buffer); frames.append(method); AMQFrame header; header.decode(buffer); frames.append(header); }
void SessionHandler::handleIn(AMQFrame& f) { // Note on channel states: a channel is attached if session != 0 AMQMethodBody* m = f.getBody()->getMethod(); try { // Ignore all but detach controls while awaiting detach if (awaitingDetached) { if (!isSessionControl(m)) return; if (m->amqpMethodId() != SESSION_DETACH_METHOD_ID && m->amqpMethodId() != SESSION_DETACHED_METHOD_ID) return; } if (isSessionControl(m)) { invoke(*m); } else { // Drop frames if we are detached. if (!getState()) return; if (!receiveReady) throw IllegalStateException(QPID_MSG(getState()->getId() << ": Not ready to receive data")); if (!getState()->receiverRecord(f)) return; // Ignore duplicates. if (getState()->receiverNeedKnownCompleted()) sendCompletion(); getInHandler()->handle(f); } } catch(const SessionException& e) { executionException(e.code, e.what()); framing::AMQP_AllProxy::Execution execution(channel); AMQMethodBody* m = f.getMethod(); SequenceNumber commandId; if (getState()) commandId = getState()->receiverGetCurrent(); execution.exception(e.code, commandId, m ? m->amqpClassId() : 0, m ? m->amqpMethodId() : 0, 0, e.what(), FieldTable()); detaching(); sendDetach(); } catch(const ChannelException& e){ channelException(e.code, e.what()); peer.detached(name, e.code); } catch(const ConnectionException& e) { connectionException(e.code, e.getMessage()); } catch(const std::exception& e) { connectionException(connection::CLOSE_CODE_FRAMING_ERROR, e.what()); } }
size_t SslConnector::decode(const char* buffer, size_t size) { framing::Buffer in(const_cast<char*>(buffer), size); try { if (checkProtocolHeader(in, version)) { AMQFrame frame; while(frame.decode(in)){ QPID_LOG(trace, "RECV [" << identifier << "]: " << frame); input->received(frame); } } } catch (const ProtocolVersionError& e) { QPID_LOG(info, "Closing connection due to " << e.what()); close(); } return size - in.available(); }
void SessionImpl::handleIn(AMQFrame& frame) // network thread { try { if (invoke(static_cast<SessionHandler&>(*this), *frame.getBody())) { ; } else if (invoke(static_cast<ExecutionHandler&>(*this), *frame.getBody())) { //make sure the command id sequence and completion //tracking takes account of execution commands Lock l(state); completedIn.add(nextIn++); } else { //if not handled by this class, its for the application: deliver(frame); } } catch (const SessionException& e) { setException(createSessionException(e.code, e.getMessage())); } catch (const ChannelException& e) { setException(createChannelException(e.code, e.getMessage())); } }
void operator()(const AMQFrame& f) { AMQFrame copy = f; if (redelivered || ttl || annotations.size()) { copy.cloneBody(); if (annotations.size()) { MessageProperties* props = copy.castBody<AMQHeaderBody>()->get<MessageProperties>(true); for (qpid::types::Variant::Map::const_iterator i = annotations.begin(); i != annotations.end(); ++i) { props->getApplicationHeaders().set(i->first, qpid::amqp_0_10::translate(i->second)); } } if (redelivered || ttl) { DeliveryProperties* dp = copy.castBody<AMQHeaderBody>()->get<DeliveryProperties>(true); if (ttl) dp->setTtl(ttl); if (redelivered) dp->setRedelivered(redelivered); } } handler.handle(copy); }
string getData(const AMQFrame& frame) { const AMQContentBody* content = dynamic_cast<const AMQContentBody*>(frame.getBody()); BOOST_CHECK(content); return content->getData(); }
void SessionImpl::sendFrame(AMQFrame& frame, bool canBlock) { connection->expand(frame.encodedSize(), canBlock); channel.handle(frame); }
bool isContentFrame(AMQFrame& frame) { AMQBody* body = frame.getBody(); uint8_t type = body->type(); return type == HEADER_BODY || type == CONTENT_BODY || isMessageMethod(body); }