示例#1
0
std::string headerValue(const Headers& headers, const std::string& name)
{
   Headers::const_iterator it = std::find_if(headers.begin(), 
                                             headers.end(), 
                                             HeaderNamePredicate(name))  ;
   
   if ( it != headers.end() )
      return (*it).value ;
   else
      return std::string() ;
}
示例#2
0
Headers::const_iterator findHeader(const Headers& headers, 
                                   const std::string& name)
{
   return std::find_if(headers.begin(), 
                       headers.end(), 
                       HeaderNamePredicate(name));
}
示例#3
0
bool HttpServerResponse::writeHead(int statusCode,
                                   const QByteArray &reasonPhrase,
                                   const Headers &headers)
{
    if (priv->formattingState != Priv::STATUS_LINE)
        return false;

    if (priv->options.testFlag(HttpServerResponse::HTTP_1_0)) {
        static const char chunk[] = "HTTP/1.0 ";
        priv->device.write(chunk, sizeof(chunk) - 1);
    } else {
        static const char chunk[] = "HTTP/1.1 ";
        priv->device.write(chunk, sizeof(chunk) - 1);
    }

    priv->device.write(QByteArray::number(statusCode));
    priv->device.write(" ", 1);
    priv->device.write(reasonPhrase);
    priv->device.write(CRLF);

    for (Headers::const_iterator i = headers.constBegin()
         ;i != headers.end();++i) {
        priv->device.write(i.key());
        priv->device.write(": ", 2);
        priv->device.write(i.value());
        priv->device.write(CRLF);
    }
    priv->formattingState = Priv::HEADERS;
    return true;
}
示例#4
0
bool HttpServerResponse::addTrailers(const Headers &headers)
{
    if (priv->options.testFlag(HttpServerResponse::HTTP_1_0))
        return false;

    switch (priv->formattingState) {
    case Priv::STATUS_LINE:
    case Priv::END:
    case Priv::HEADERS:
        return false;
    case Priv::MESSAGE_BODY:
        priv->device.write("0\r\n");
        priv->formattingState = Priv::TRAILERS;
    case Priv::TRAILERS:
    {
        for (Headers::const_iterator i = headers.constBegin()
             ;i != headers.end();++i) {
            priv->device.write(i.key());
            priv->device.write(": ", 2);
            priv->device.write(i.value());
            priv->device.write(CRLF);
        }
    }
    } // switch (priv->formattingState)
    return true;
}
示例#5
0
    void assign(const Message& message, const Headers& extraHeaders)
    {
        body_ = message.body_;
        httpVersionMajor_ = message.httpVersionMajor_;
        httpVersionMinor_ = message.httpVersionMinor_;
        headers_ = message.headers_;
        overrideHeader_ = message.overrideHeader_;
        httpVersion_ = message.httpVersion_;

        std::for_each(extraHeaders.begin(), extraHeaders.end(),
                      boost::bind(&Message::setExtraHeader, this, _1));
    }
/**
* @brief 
*
* @param headers
* @param payload
* @param statusCode
* @param statusText
*
* @return 
*/
bool RtspConnection::sendResponse( Headers &headers, std::string payload, int statusCode, std::string statusText )
{
    std::string response;

    response = stringtf( "RTSP/1.0 %d %s\r\n", statusCode, statusText.c_str() );

    //headers.insert( Headers::value_type( "Server", "ZoneMinder Streamer V2.0" ) );
    headers.insert( Headers::value_type( "Date", datetimeInet() ) );
    for ( Headers::iterator iter = headers.begin(); iter != headers.end(); iter++ )
    {
        response += iter->first+": "+iter->second+"\r\n";
    }
    response += "\r\n";

    if ( payload.size() )
    {
        response += payload;
    }

    Debug( 2, "Sending RTSP response: %s", response.c_str() );

    if ( mSocket->send( response.c_str(), response.size() ) != (int)response.length() )
    {
        Error( "Unable to send response '%s': %s", response.c_str(), strerror(errno) );
        return( false );
    }

#if 0
    // Not currently used. If RTSP over HTTP ever required then will need to do something like this
    if ( mMethod == RTP_OZ_RTSP_HTTP )
    {
        response = base64Encode( response );
        Debug( 2, "Sending encoded RTSP response: %s", response.c_str() );
        if ( mRtspSocket2.send( response.c_str(), response.size() ) != (int)response.length() )
        {
            Error( "Unable to send response '%s': %s", response.c_str(), strerror(errno) );
            return( false );
        }
    }
    else
    {
        if ( mRtspSocket.send( response.c_str(), response.size() ) != (int)response.length() )
        {
            Error( "Unable to send response '%s': %s", response.c_str(), strerror(errno) );
            return( false );
        }
    }
#endif
    return( true );
}
示例#7
0
void makeNodesHeader(const boost::filesystem::path& output, const Builder& builder, const Headers& headerFileNames)
{
	boost::filesystem::path hpath = output, spath = output;
	hpath /= "nodes.hpp";
	spath /= "nodes.cpp";
	boost::filesystem::ofstream h(hpath.c_str());
	boost::filesystem::ofstream s(spath.c_str());

	h << "/* Automatically generated by ast-gen. DO NOT MODIFY. */\n";
	h << "#pragma once\n";
	for (Headers::const_iterator it = headerFileNames.begin(); it != headerFileNames.end(); it++) {
		h << "#include \"maxwell/ast/nodes/" << *it << "\"\n";
	}
	h << "#include <string>\n";

	s << "/* Automatically generated by ast-gen. DO NOT MODIFY. */\n";
	s << "#include \"maxwell/ast/nodes/nodes.hpp\"\n\n";

	// Generate the node factory class.
	h << "\nnamespace ast {\n\n";
	// h << "class NodeFactory\n{\npublic:\n";
	// h << "\tstatic NodePtr make(const std::string& name);\n";
	// h << "};\n";
	h << "NodePtr makeNode(const std::string& name);\n\n";
	h << "} // namespace ast\n\n";

	// s << "NodePtr NodeFactory::make(const std::string& name) {\n";
	s << "ast::NodePtr ast::makeNode(const std::string& name) {\n";
	s << "\tsize_t size = name.size();\n";
	NodeNames names;
	for (Builder::Nodes::const_iterator it = builder.nodes.begin(); it != builder.nodes.end(); it++) {
		names.insert(it->first);
	}
	generateFactoryBody(s, names, 1);
	s << "\tthrow std::runtime_error(\"Node class name '\" + name + \"' not known to NodeFactory.\");\n";
	s << "}\n";
}
/**
* @brief 
*
* @param request
*
* @return 
*/
bool RtspConnection::handleRequest( const std::string &request )
{
    Debug( 2, "Handling RTSP request: %s (%zd bytes)", request.c_str(), request.size() );

    StringTokenList lines( request, "\r\n" );
    if ( lines.size() <= 0 )
    {
        Error( "Unable to split request '%s' into tokens", request.c_str() );
        return( false );
    }

    StringTokenList parts( lines[0], " " );
    if ( parts.size() != 3 )
    {
        Error( "Unable to split request part '%s' into tokens", lines[0].c_str() );
        return( false );
    }

    std::string requestType = parts[0];
    Debug( 4, "Got request '%s'", requestType.c_str() );
    std::string requestUrl = parts[1];
    Debug( 4, "Got requestUrl '%s'", requestUrl.c_str() );
    std::string requestVer = parts[2];
    Debug( 4, "Got requestVer '%s'", requestVer.c_str() );
    if ( requestVer != "RTSP/1.0" )
    {
        Error( "Unexpected RTSP version '%s'", requestVer.c_str() );
        return( false );
    }

    // Extract headers from request
    Headers requestHeaders;
    for ( int i = 1; i < lines.size(); i++ )
    {
        StringTokenList parts( lines[i], ": " );
        if ( parts.size() != 2 )
        {
            Error( "Unable to split request header '%s' into tokens", lines[i].c_str() );
            return( false );
        }
        Debug( 4, "Got header '%s', value '%s'", parts[0].c_str(), parts[1].c_str() );
        requestHeaders.insert( Headers::value_type( parts[0], parts[1] ) );
    }

    if ( requestHeaders.find("CSeq") == requestHeaders.end() )
    {
        Error( "No CSeq header found" );
        return( false );
    }
    Debug( 4, "Got sequence number %s", requestHeaders["CSeq"].c_str() );

    uint32_t session = 0;
    if ( requestHeaders.find("Session") != requestHeaders.end() )
    {
        Debug( 4, "Got session header, '%s', passing to session", requestHeaders["Session"].c_str() );
        session = strtol( requestHeaders["Session"].c_str(), NULL, 16 );
    }

    Headers responseHeaders;
    responseHeaders.insert( Headers::value_type( "CSeq", requestHeaders["CSeq"] ) );
    if ( requestType == "OPTIONS" )
    {
        responseHeaders.insert( Headers::value_type( "Public", "DESCRIBE, SETUP, PLAY, GET_PARAMETER, TEARDOWN" ) );
        return( sendResponse( responseHeaders ) );
    }
    else if ( requestType == "DESCRIBE" )
    {
        FeedProvider *provider = validateRequestUrl( requestUrl );

        if ( !provider )
        {
            sendResponse( responseHeaders, "", 404, "Not Found" );
            return( false );
        }

        const VideoProvider *videoProvider = dynamic_cast<const VideoProvider *>(provider);

        int codec = AV_CODEC_ID_MPEG4;
        int width = videoProvider->width();
        int height = videoProvider->height();
        FrameRate frameRate = 15;
        //FrameRate frameRate = videoProvider->frameRate();
        int bitRate = 90000;
        int quality = 70;

        std::string sdpFormatString =
            "v=0\r\n"
            "o=- %jd %jd IN IP4 %s\r\n"
            "s=ZoneMinder Stream\r\n"
            "i=Media Streamers\r\n"
            "c=IN IP4 0.0.0.0\r\n"
            "t=0 0\r\n"
            "a=control:*\r\n"
            "a=range:npt=0.000000-\r\n";
        uint64_t now64 = time64();
        char hostname[HOST_NAME_MAX] = "";
        if ( gethostname( hostname, sizeof(hostname) ) < 0 )
            Fatal( "Can't gethostname: %s", strerror(errno) );

        std::string sdpString = stringtf( sdpFormatString, now64, now64, hostname );

        if ( codec == AV_CODEC_ID_H264 )
        {
            if ( provider->cl4ss() == "RawH264Input" )
            {
                std::string encoderKey = H264Relay::getPoolKey( provider->identity(), width, height, frameRate, bitRate, quality );
                if ( !(mEncoder = Encoder::getPooledEncoder( encoderKey )) )
                {
                    H264Relay *h264Relay = NULL;
                    mEncoder = h264Relay = new H264Relay( provider->identity(), width, height, frameRate, bitRate, quality );
                    mEncoder->registerProvider( *provider );
                    Encoder::poolEncoder( mEncoder );
                    h264Relay->start();
                }
                sdpString += mEncoder->sdpString( 1 ); // XXX - Should be variable
                responseHeaders.insert( Headers::value_type( "Content-length", stringtf( "%zd", sdpString.length() ) ) );
            }
            else
            {
                std::string encoderKey = H264Encoder::getPoolKey( provider->identity(), width, height, frameRate, bitRate, quality );
                if ( !(mEncoder = Encoder::getPooledEncoder( encoderKey )) )
                {
                    H264Encoder *h264Encoder = NULL;
                    mEncoder = h264Encoder = new H264Encoder( provider->identity(), width, height, frameRate, bitRate, quality );
                    mEncoder->registerProvider( *provider );
                    Encoder::poolEncoder( mEncoder );
                    h264Encoder->start();
                }
                sdpString += mEncoder->sdpString( 1 ); // XXX - Should be variable
                responseHeaders.insert( Headers::value_type( "Content-length", stringtf( "%zd", sdpString.length() ) ) );
            }
        }
        else if ( codec == AV_CODEC_ID_MPEG4 )
        {
            std::string encoderKey = MpegEncoder::getPoolKey( provider->identity(), width, height, frameRate, bitRate, quality );
            if ( !(mEncoder = Encoder::getPooledEncoder( encoderKey )) )
            {
                MpegEncoder *mpegEncoder = NULL;
                mEncoder = mpegEncoder = new MpegEncoder( provider->identity(), width, height, frameRate, bitRate, quality );
                mEncoder->registerProvider( *provider );
                Encoder::poolEncoder( mEncoder );
                mpegEncoder->start();
            }
            sdpString += mEncoder->sdpString( 1 ); // XXX - Should be variable
            responseHeaders.insert( Headers::value_type( "Content-length", stringtf( "%zd", sdpString.length() ) ) );
        }
        return( sendResponse( responseHeaders, sdpString ) );
    }
    else if ( requestType == "SETUP" )
    {
        // These commands are handled by RTSP session so pass them on and send any required responses
        RtspSession *rtspSession = 0;
        if ( session )
        {
            rtspSession = mRtspController->getSession( session );
        }
        else
        {
            rtspSession = mRtspController->newSession( this, mEncoder );
        }
        if ( rtspSession->recvRequest( requestType, requestUrl, requestHeaders, responseHeaders ) )
            return( sendResponse( responseHeaders ) );
        return( false );
    }
    else if ( requestType == "PLAY" || requestType == "GET_PARAMETER" || requestType == "TEARDOWN" )
    {
        // These commands are handled by RTSP session so pass them on and send any required responses
        RtspSession *rtspSession = 0;
        if ( session )
        {
            rtspSession = mRtspController->getSession( session );
            if ( rtspSession && rtspSession->recvRequest( requestType, requestUrl, requestHeaders, responseHeaders ) )
                return( sendResponse( responseHeaders ) );
        }
        return( sendResponse( responseHeaders, "", 454, "Session Not Found" ) );
    }
    Error( "Unrecognised RTSP command '%s'", requestType.c_str() );
    return( sendResponse( responseHeaders, "", 405, "Method not implemented" ) );
}
示例#9
0
bool containsHeader(const Headers& headers, const std::string& name)
{
   return findHeader(headers, name) != headers.end();
}