bool HTTP4CLIProtocol::EnqueueForOutbound() { //1. Empty our local buffer _localOutputBuffer.IgnoreAll(); //2. Get the HTTP protocol InboundHTTPProtocol *pHTTP = (InboundHTTPProtocol *) GetFarProtocol(); //3. Prepare the HTTP headers //pHTTP->SetOutboundHeader(HTTP_HEADERS_CONTENT_TYPE, "application/json"); pHTTP->SetOutboundHeader(HTTP_HEADERS_CONTENT_TYPE, "text/plain"); //4. Get the buffer from PT_INBOUND_JSONCLI IOBuffer *pBuffer = GetNearProtocol()->GetOutputBuffer(); if (pBuffer == NULL) return true; //5. Put the data inside the local buffer and empty the buffer from //the PT_INBOUND_JSONCLI _localOutputBuffer.ReadFromBuffer(GETIBPOINTER(*pBuffer), GETAVAILABLEBYTESCOUNT(*pBuffer)); pBuffer->IgnoreAll(); //6. Trigger EnqueueForOutbound down the stack return pHTTP->EnqueueForOutbound(); }
bool HTTP4CLIProtocol::SignalInputData(IOBuffer &buffer) { //1. Get the HTTP protocol. We are sure is a PT_INBOUND_HTTP //because we return true inside AllowFarProtocol only when type == PT_INBOUND_HTTP InboundHTTPProtocol *pHTTP = (InboundHTTPProtocol *) GetFarProtocol(); //2. Get the request headers Variant headers = pHTTP->GetHeaders(); //3. Populate the input buffer for the next protocol in the stack (PT_INBOUND_JSONCLI) //with the data we just found out inside the headers URI uri; string dummy = "http://localhost" + (string) headers[HTTP_FIRST_LINE][HTTP_URL]; FINEST("dummy: %s",STR(dummy)); if (!URI::FromString(dummy, false, uri)) { FATAL("Invalid request"); return false; } string fullCommand=uri.document; fullCommand+=" "; if(uri.parameters.size()!=0){ fullCommand+=unb64(MAP_VAL(uri.parameters.begin())); } fullCommand+="\n"; _localInputBuffer.ReadFromString(fullCommand); //4. Call the next protocol with the new buffer return GetNearProtocol()->SignalInputData(_localInputBuffer); }
bool OutboundRTMPProtocol::PerformHandshake(IOBuffer &buffer) { switch (_rtmpState) { case RTMP_STATE_NOT_INITIALIZED: { _encrypted = (VariantType) _customParameters[CONF_PROTOCOL] == V_STRING && _customParameters[CONF_PROTOCOL] == CONF_PROTOCOL_OUTBOUND_RTMPE; _usedScheme = _encrypted ? 1 : 0; if ((VariantType) _customParameters[CONF_PROTOCOL] == V_STRING && _customParameters[CONF_PROTOCOL] == CONF_PROTOCOL_OUTBOUND_RTMPE) { return PerformHandshakeStage1(true); } else { return PerformHandshakeStage1(false); } } case RTMP_STATE_CLIENT_REQUEST_SENT: { if (GETAVAILABLEBYTESCOUNT(buffer) < 3073) return true; if (!PerformHandshakeStage2(buffer, _encrypted)) { FATAL("Unable to handshake"); return false; } if (_pFarProtocol != NULL) { if (!_pFarProtocol->EnqueueForOutbound()) { FATAL("Unable to signal output data"); return false; } } if (_pKeyIn != NULL && _pKeyOut != NULL) { //insert the RTMPE protocol in the current protocol stack BaseProtocol *pFarProtocol = GetFarProtocol(); RTMPEProtocol *pRTMPE = new RTMPEProtocol(_pKeyIn, _pKeyOut, GETAVAILABLEBYTESCOUNT(_outputBuffer)); ResetFarProtocol(); pFarProtocol->SetNearProtocol(pRTMPE); pRTMPE->SetNearProtocol(this); //FINEST("New protocol chain: %s", STR(*pFarProtocol)); } if (!buffer.Ignore(3073)) { FATAL("Unable to ignore 3073 bytes"); return false; } _handshakeCompleted = true; return true; } default: { FATAL("Invalid RTMP state: %d", _rtmpState); return false; } } }
bool InboundRTMPProtocol::PerformHandshake(IOBuffer &buffer) { switch (_rtmpState) { case RTMP_STATE_NOT_INITIALIZED: { if (GETAVAILABLEBYTESCOUNT(buffer) < 1537) { return true; } uint8_t handshakeType = GETIBPOINTER(buffer)[0]; if (!buffer.Ignore(1)) { FATAL("Unable to ignore one byte"); return false; } _currentFPVersion = ENTOHLP(GETIBPOINTER(buffer) + 4); switch (handshakeType) { case 3: //plain { return PerformHandshake(buffer, false); } case 6: //encrypted { return PerformHandshake(buffer, true); } default: { FATAL("Handshake type not implemented: %hhu", handshakeType); return false; } } } case RTMP_STATE_SERVER_RESPONSE_SENT: { if (GETAVAILABLEBYTESCOUNT(buffer) < 1536) { return true; } else { //ignore the client's last handshake part if (!buffer.Ignore(1536)) { FATAL("Unable to ignore inbound data"); return false; } _handshakeCompleted = true; _rtmpState = RTMP_STATE_DONE; if (_pKeyIn != NULL && _pKeyOut != NULL) { //insert the RTMPE protocol in the current protocol stack BaseProtocol *pFarProtocol = GetFarProtocol(); RTMPEProtocol *pRTMPE = new RTMPEProtocol(_pKeyIn, _pKeyOut); ResetFarProtocol(); pFarProtocol->SetNearProtocol(pRTMPE); pRTMPE->SetNearProtocol(this); FINEST("New protocol chain: %s", STR(*pFarProtocol)); //decrypt the leftovers RC4(_pKeyIn, GETAVAILABLEBYTESCOUNT(buffer), GETIBPOINTER(buffer), GETIBPOINTER(buffer)); } return true; } } default: { FATAL("Invalid RTMP state: %d", _rtmpState); return false; } } }