예제 #1
0
OGRUKOOAP190Layer::OGRUKOOAP190Layer( const char* pszFilename,
                                      VSILFILE* fpIn ) :
    poSRS(nullptr),
    fp(fpIn),
    bUseEastingNorthingAsGeometry(CPLTestBool(
        CPLGetConfigOption("UKOOAP190_USE_EASTING_NORTHING", "NO"))),
    nYear(0)
{
    nNextFID = 0;
    bEOF = false;

    poFeatureDefn = new OGRFeatureDefn( CPLGetBasename(pszFilename) );
    SetDescription( poFeatureDefn->GetName() );
    poFeatureDefn->Reference();
    poFeatureDefn->SetGeomType( wkbPoint );

    for( int i = 0;
         i < static_cast<int>(sizeof(UKOOAP190Fields) /
                              sizeof(UKOOAP190Fields[0]));
         i++ )
    {
        OGRFieldDefn    oField( UKOOAP190Fields[i].pszName,
                                UKOOAP190Fields[i].eType );
        poFeatureDefn->AddFieldDefn( &oField );
    }

    ParseHeaders();

    poFeatureDefn->GetGeomFieldDefn(0)->SetSpatialRef(poSRS);
}
예제 #2
0
//Parses the request
QTSS_Error HTTPRequest::Parse()
{
    Assert(fRequestHeader.Ptr != NULL);
    StringParser parser(&fRequestHeader);
    
    // Store the request line (used for logging) 
    // (ex: GET /index.html HTTP/1.0)
    StringParser requestLineParser(&fRequestHeader);
    requestLineParser.ConsumeUntil(&fRequestLine, StringParser::sEOLMask);
  
    // Parse request line returns an error if there is an error in the
    // request URI or the formatting of the request line. 
    // If the method or version are not found, they are set
    // to httpIllegalMethod or httpIllegalVersion respectively, 
    // and QTSS_NoErr is returned.
	// 解析第一行
    QTSS_Error err = ParseRequestLine(&parser);
    if (err != QTSS_NoErr)
		return err;
  
    // Parse headers and set values of headers into fFieldValues array
    err = ParseHeaders(&parser);
    if (err != QTSS_NoErr)
            return err;
  
    return QTSS_NoErr;
}
예제 #3
0
OGRUKOOAP190Layer::OGRUKOOAP190Layer( const char* pszFilename,
                                      VSILFILE* fp )

{
    this->fp = fp;
    nNextFID = 0;
    bEOF = FALSE;
    poSRS = NULL;
    nYear = 0;

    poFeatureDefn = new OGRFeatureDefn( CPLGetBasename(pszFilename) );
    SetDescription( poFeatureDefn->GetName() );
    poFeatureDefn->Reference();
    poFeatureDefn->SetGeomType( wkbPoint );

    for(int i=0;i<(int)(sizeof(UKOOAP190Fields)/sizeof(UKOOAP190Fields[0]));i++)
    {
        OGRFieldDefn    oField( UKOOAP190Fields[i].pszName,
                                UKOOAP190Fields[i].eType );
        poFeatureDefn->AddFieldDefn( &oField );
    }

    bUseEastingNorthingAsGeometry =
        CSLTestBoolean(CPLGetConfigOption("UKOOAP190_USE_EASTING_NORTHING", "NO"));

    ParseHeaders();

    poFeatureDefn->GetGeomFieldDefn(0)->SetSpatialRef(poSRS);
}
예제 #4
0
파일: asf.c 프로젝트: 5sw/stuff
void ParseFile() 
{
	for (;;) {
		uint8_t *objectStart = cursor;
		GUIDType type = ReadGUID();
		uint64_t size = ReadQWord();
		uint8_t *next = objectStart + size;
		printf( "Object size: %llu\n", size );
		switch (type) {
			case GUIDHeader:
				printf( "Header GUID\n" );
				ParseHeaders();
				break;

			case GUIDData:
				printf( "Found Data object\n" );
				return;
				
			case GUIDUnknown:
			default:
				printf( "Unknown GUID\n" );
				break;
				
		}
		cursor = next;
	}
}
예제 #5
0
wxString mHTTP::GetResponseMessage()
{
    if (m_messagereceived.IsEmpty())
    {
        ParseHeaders();
    }
    return m_messagereceived;
};
예제 #6
0
bool BaseHTTPProtocol::SignalInputData(IOBuffer &buffer) {
	DEBUG_HTTP("-------------------");
	DEBUG_HTTP("%s", STR(*this));
	DEBUG_HTTP("_state: %s", (_state == HTTP_STATE_HEADERS) ? "HTTP_STATE_HEADERS" : (_state == HTTP_STATE_PAYLOAD) ? "HTTP_STATE_PAYLOAD" : "UNKNOWN");
	//1. Get the first line and the headers if necessary
	if (_state == HTTP_STATE_HEADERS) {
		DEBUG_HTTP("Parse the headers");
		if (!ParseHeaders(buffer)) {
			FATAL("Unable to read response headers: %s", STR(*this));
			return false;
		}
	}

	DEBUG_HTTP("_continueAfterParseHeaders: %d", _continueAfterParseHeaders);
	if (!_continueAfterParseHeaders)
		return true;

	//2. Are we still in the "get headers state"? If so, wait for more data
	DEBUG_HTTP("new value of _state: %s", (_state == HTTP_STATE_HEADERS) ? "HTTP_STATE_HEADERS" : (_state == HTTP_STATE_PAYLOAD) ? "HTTP_STATE_PAYLOAD" : "UNKNOWN");
	if (_state != HTTP_STATE_PAYLOAD) {
		return true;
	}

	DEBUG_HTTP("_chunkedContent: %d", _chunkedContent);
	//3. Turning point in processing
	if (_chunkedContent) {
		//4. We deal with chunked content
		DEBUG_HTTP("begin chunk content handling");
		if (!HandleChunkedContent(buffer)) {
			FATAL("Unable to handle chunked content: %s", STR(*this));
			return false;
		}
	} else {
		//5. We deal with length-specified type of content
		DEBUG_HTTP("begin fixed length content handling");
		if (!HandleFixedLengthContent(buffer)) {
			FATAL("Unable to handle fixed length content: %s", STR(*this));
			return false;
		}
	}

	//6. Are we in the get headers state? if so, we might have a new request
	//on the pipe.
	DEBUG_HTTP("brand new value of _state: %s", (_state == HTTP_STATE_HEADERS) ? "HTTP_STATE_HEADERS" : (_state == HTTP_STATE_PAYLOAD) ? "HTTP_STATE_PAYLOAD" : "UNKNOWN");
	if (_state == HTTP_STATE_HEADERS) {
		DEBUG_HTTP("Call SignalInputData again");
		//7. So, get to work again...
		return SignalInputData(buffer);
	} else {
		//8 We are done :)
		DEBUG_HTTP("Done");
		return true;
	}
}
예제 #7
0
void WebProcessor::Execute()
{
	m_gzip =false;
	m_userAccess = uaControl;
	m_authInfo[0] = '\0';
	m_authToken[0] = '\0';

	ParseHeaders();

	if (m_httpMethod == hmPost && m_contentLen <= 0)
	{
		error("Invalid-request: content length is 0");
		return;
	}

	if (m_httpMethod == hmOptions)
	{
		SendOptionsResponse();
		return;
	}

	ParseUrl();

	if (!CheckCredentials())
	{
		SendAuthResponse();
		return;
	}

	if (m_httpMethod == hmPost)
	{
		// reading http body (request content)
		m_request.Reserve(m_contentLen);
		m_request[m_contentLen] = '\0';

		if (!m_connection->Recv(m_request, m_contentLen))
		{
			error("Invalid-request: could not read data");
			return;
		}
		debug("Request=%s", *m_request);
	}

	debug("request received from %s", m_connection->GetRemoteAddr());

	Dispatch();
}
예제 #8
0
bool BaseHTTPProtocol::SignalInputData(IOBuffer &buffer) {
	//1. Get the first line and the headers if necessary
	if (_state == HTTP_STATE_HEADERS) {
		if (!ParseHeaders(buffer)) {
			FATAL("Unable to read response headers");
			return false;
		}
	}

	if (!_continueAfterParseHeaders)
		return true;

	//2. Are we still in the "get headers state"? If so, wait for more data
	if (_state != HTTP_STATE_PAYLOAD) {
		return true;
	}

	//3. Turning point in processing
	if (_chunkedContent) {
		//4. We deal with chunked content
		if (!HandleChunkedContent(buffer)) {
			FATAL("Unable to handle chunked content");
			return false;
		}
	} else {
		//5. We deal with length-specified type of content
		if (!HandleFixedLengthContent(buffer)) {
			FATAL("Unable to handle fixed length content");
			return false;
		}
	}

	//6. Are we in the get headers state? if so, we might have a new request
	//on the pipe.
	if (_state == HTTP_STATE_HEADERS) {
		//7. So, get to work again...
		return SignalInputData(buffer);
	} else {
		//8 We are done :)
		return true;
	}
}
void au::SessionTokenTestConnection::ReadHeaders()
{
    auto self(shared_from_this());
    asio::async_read_until(
        request_->ssl_stream,
        request_->read_buffer_,
        "\r\n\r\n",
        [this, self](
                boost::system::error_code ec,
                std::size_t bytes_transferred
            )
        {
            if (ec)
            {
                std::cout << "ReadHeaders: Got error: " << ec.message()
                    << std::endl;
                request_->Fail(HttpStatusCode::bad_request);
                return;
            }

            ParseHeaders( bytes_transferred );
        });
}
예제 #10
0
파일: request.cpp 프로젝트: sippeangelo/web
Request::Request(std::string raw)
{
	std::vector<std::string> lines;
	// Split the raw data in to lines
	// "The escape sequence \R matches any line ending character sequence"
	boost::split_regex(lines, raw, boost::regex("\\R"));

	if (lines.size() > 0)
	{
		// Read the start line
		boost::smatch m;
		bool match = boost::regex_match(lines.at(0), m, boost::regex("^(.*) (.*) (.*)$"));
		if (match)		
			m_StartLine = { m[1].str(), m[2].str(), m[3].str() };
		else
		{
			std::cerr << "Failed to read request start line" << std::endl;
			return;	
		}

		// Parse ALL the headers!
		m_Headers = ParseHeaders(&lines);
	}
}
예제 #11
0
void CHttpClient::Process()
{
    // Do we have a request start and has the request timed out?
    if (m_uiRequestStart > 0 && (SharedUtility::GetTime() - m_uiRequestStart) >= m_uiRequestTimeout)
    {
        // Set the status to none
        m_status = HTTP_STATUS_NONE;

        // Request timed out, set the last error
        m_lastError = HTTP_ERROR_REQUEST_TIMEOUT;

        // Reset the request start
        m_uiRequestStart = 0;

        // Disconnect from the host
        Disconnect();
        return;
    }

    // Are we not in idle status?
    if (m_status != HTTP_STATUS_NONE)
    {
        switch (m_status)
        {
        case HTTP_STATUS_GET_DATA:
        {
            // Prepare a buffer
            char szBuffer[MAX_BUFFER];
            memset(szBuffer, 0, sizeof(szBuffer));

            // Try to read from the socket
            int iBytesRecieved = Read(szBuffer, sizeof(szBuffer));
            int iHeaderSize = 0;

            // Did we get anything?
            if (iBytesRecieved > 0)
            {
                // Are the headers empty?
                if (m_headerMap.empty())
                {
                    // Parse the headers
                    if (!ParseHeaders(szBuffer, iBytesRecieved, iHeaderSize))
                    {
                        // We don't have a header, set the status
                        m_status = HTTP_STATUS_INVALID;

                        // Set the last error
                        m_lastError = HTTP_ERROR_NO_HEADER;

                        // Reset the request start
                        m_uiRequestStart = 0;

                        // Disconnect from the host
                        Disconnect();
                        return;
                    }

                    // Do we not have any data?
                    if (iBytesRecieved == 0)
                        return;
                }

                // Skip the header data if we have any
                char * szData = (iBytesRecieved ? (szBuffer + iHeaderSize) : NULL);

                // Call the receive handler if we have one
                if (m_pfnReceiveHandler)
                {
                    if (m_pfnReceiveHandler(szData, iBytesRecieved, m_pReceiveHandlerUserData))
                        m_strData.Append(szData, iBytesRecieved);
                }
                // Write response data to file if we have one set
                else if (m_fFile != NULL)
                    fwrite(szData, 1, iBytesRecieved, m_fFile);
            }
            else if (iBytesRecieved == 0)
            {
                // We got data, set the status
                m_status = HTTP_STATUS_GOT_DATA;

                // Reset the request start
                m_uiRequestStart = 0;

                // Disconnect from the host
                Disconnect();
            }
        }

        break;
        }
    }
}
예제 #12
0
/* Set up all the necessary jk_* workspace based on the current HTTP request.
 */
static int InitService(private_ws_t *ws, jk_ws_service_t *s)
{
	/* This is the only fixed size buffer left. It won't be overflowed
	 * because the Domino API that reads into the buffer accepts a length
	 * constraint, and it's unlikely ever to be exhausted because the
	 * strings being will typically be short, but it's still aesthetically
	 * troublesome.
	 */
	char workBuf[16 * 1024];
	FilterRequest fr;
	char *hdrs, *qp;
	int hdrsz;
	int errID;
	int hdrCount;
	int rc /*, dummy*/;

	static char *methodName[] = { "", "HEAD", "GET", "POST", "PUT", "DELETE" };

	rc = ws->context->GetRequest(ws->context, &fr, &errID);

	s->jvm_route		= NULL;
	s->start_response	= StartResponse;
	s->read				= Read;
	s->write			= Write;

	s->req_uri = jk_pool_strdup(&ws->p, fr.URL);
	s->query_string = NULL;
	if (qp = strchr(s->req_uri, '?'), qp != NULL)
	{
		*qp++ = '\0';
		if (strlen(qp))
			s->query_string = qp;
	}

	GETVARIABLE("AUTH_TYPE", &s->auth_type, "");
	GETVARIABLE("REMOTE_USER", &s->remote_user, "");
	GETVARIABLE("SERVER_PROTOCOL", &s->protocol, "");
	GETVARIABLE("REMOTE_HOST", &s->remote_host, "");
	GETVARIABLE("REMOTE_ADDR", &s->remote_addr, "");
	GETVARIABLE("SERVER_NAME", &s->server_name, "");
	GETVARIABLEINT("SERVER_PORT", &s->server_port, 80);
	GETVARIABLE("SERVER_SOFTWARE", &s->server_software, SERVERDFLT);
	GETVARIABLEINT("CONTENT_LENGTH", &s->content_length, 0);

	/* SSL Support
	 */
	GETVARIABLEBOOL("HTTPS", &s->is_ssl, 0);


	if (ws->reqData->requestMethod < 0 ||

		ws->reqData->requestMethod >= sizeof(methodName) / sizeof(methodName[0]))

		return JK_FALSE;



	s->method = methodName[ws->reqData->requestMethod];



	s->headers_names	= NULL;

	s->headers_values	= NULL;

	s->num_headers		= 0;


	s->ssl_cert_len	= fr.clientCertLen;
	s->ssl_cert		= fr.clientCert;
	s->ssl_cipher	= NULL;		/* required by Servlet 2.3 Api */
	s->ssl_session	= NULL;


#if defined(JK_VERSION) && JK_VERSION >= MAKEVERSION(1, 2, 0, 1)
	s->ssl_key_size = -1;       /* required by Servlet 2.3 Api, added in jtc */
#endif

	if (s->is_ssl)
	{
		int dummy;

#if 0

		char *sslNames[] =
		{
			"CERT_ISSUER", "CERT_SUBJECT", "CERT_COOKIE", "CERT_FLAGS", "CERT_SERIALNUMBER",
			"HTTPS_SERVER_SUBJECT", "HTTPS_SECRETKEYSIZE", "HTTPS_SERVER_ISSUER", "HTTPS_KEYSIZE"
		};

		char *sslValues[] =
		{
			NULL, NULL, NULL, NULL, NULL,
			NULL, NULL, NULL, NULL
		};

		unsigned i, varCount = 0;
#endif

		DEBUG(("SSL request\n"));

#if defined(JK_VERSION) && JK_VERSION >= MAKEVERSION(1, 2, 0, 1)
		/* Read the variable into a dummy variable: we do this for the side effect of
		 * reading it into workBuf.
		 */
		GETVARIABLEINT("HTTPS_KEYSIZE", &dummy, 0);
		if (workBuf[0] == '[')
			s->ssl_key_size = atoi(workBuf+1);
#else
		(void) dummy;
#endif

#if 0
		for (i = 0; i < sizeof(sslNames)/sizeof(sslNames[0]); i++)
		{
			GETVARIABLE(sslNames[i], &sslValues[i], NULL);
			if (sslValues[i]) varCount++;
		}

		/* Andy, some SSL vars must be mapped directly in  s->ssl_cipher,
         * ssl->session and s->ssl_key_size
		 * ie:
		 * Cipher could be "RC4-MD5"
		 * KeySize 128 (bits)
	     * SessionID a string containing the UniqID used in SSL dialogue
         */
		if (varCount > 0)
		{
			unsigned j;

			s->attributes_names = jk_pool_alloc(&ws->p, varCount * sizeof (char *));
			s->attributes_values = jk_pool_alloc(&ws->p, varCount * sizeof (char *));

			j = 0;
			for (i = 0; i < sizeof(sslNames)/sizeof(sslNames[0]); i++)
			{
				if (sslValues[i])
				{
					s->attributes_names[j] = sslNames[i];
					s->attributes_values[j] = sslValues[i];
					j++;
				}
			}
			s->num_attributes = varCount;
		}
#endif

	}

	/* Duplicate all the headers now */

	hdrsz = ws->reqData->GetAllHeaders(ws->context, &hdrs, &errID);
	DEBUG(("\nGot headers (length %d)\n--------\n%s\n--------\n\n", hdrsz, hdrs));

	s->headers_names =
	s->headers_values = NULL;
	hdrCount = ParseHeaders(ws, hdrs, hdrsz, s);
	DEBUG(("Found %d headers\n", hdrCount));
	s->num_headers = hdrCount;
	s->headers_names	= jk_pool_alloc(&ws->p, hdrCount * sizeof(char *));
	s->headers_values	= jk_pool_alloc(&ws->p, hdrCount * sizeof(char *));
	hdrCount = ParseHeaders(ws, hdrs, hdrsz, s);

	return JK_TRUE;
}
예제 #13
0
// nsIStreamListener implementation
NS_IMETHODIMP
nsMultiMixedConv::OnDataAvailable(nsIRequest *request, nsISupports *context,
                                  nsIInputStream *inStr, uint64_t sourceOffset,
                                  uint32_t count) {
    nsresult rv = NS_OK;
    AutoFree buffer(nullptr);
    uint32_t bufLen = 0, read = 0;

    NS_ASSERTION(request, "multimixed converter needs a request");

    nsCOMPtr<nsIChannel> channel = do_QueryInterface(request, &rv);
    if (NS_FAILED(rv)) return rv;

    // fill buffer
    {
        bufLen = count + mBufLen;
        NS_ENSURE_TRUE((bufLen >= count) && (bufLen >= mBufLen),
                       NS_ERROR_FAILURE);
        buffer = (char *) malloc(bufLen);
        if (!buffer)
            return NS_ERROR_OUT_OF_MEMORY;

        if (mBufLen) {
            // incorporate any buffered data into the parsing
            memcpy(buffer, mBuffer, mBufLen);
            free(mBuffer);
            mBuffer = 0;
            mBufLen = 0;
        }
        
        rv = inStr->Read(buffer + (bufLen - count), count, &read);

        if (NS_FAILED(rv) || read == 0) return rv;
        NS_ASSERTION(read == count, "poor data size assumption");
    }

    char *cursor = buffer;

    if (mFirstOnData) {
        // this is the first OnData() for this request. some servers
        // don't bother sending a token in the first "part." This is
        // illegal, but we'll handle the case anyway by shoving the
        // boundary token in for the server.
        mFirstOnData = false;
        NS_ASSERTION(!mBufLen, "this is our first time through, we can't have buffered data");
        const char * token = mToken.get();

        PushOverLine(cursor, bufLen);

        bool needMoreChars = bufLen < mTokenLen + 2;
        nsAutoCString firstBuffer(buffer, bufLen);
        int32_t posCR = firstBuffer.Find("\r");

        if (needMoreChars || (posCR == kNotFound)) {
            // we don't have enough data yet to make this comparison.
            // skip this check, and try again the next time OnData()
            // is called.
            mFirstOnData = true;
        } else if (mPackagedApp) {
            // We need to check the line starts with --
            if (!StringBeginsWith(firstBuffer, NS_LITERAL_CSTRING("--"))) {
                return NS_ERROR_FAILURE;
            }

            // If the boundary was set in the header,
            // we need to check it matches with the one in the file.
            if (mTokenLen &&
                !StringBeginsWith(Substring(firstBuffer, 2), mToken)) {
                return NS_ERROR_FAILURE;
            }

            // Save the token.
            if (!mTokenLen) {
                mToken = nsCString(Substring(firstBuffer, 2).BeginReading(),
                                   posCR - 2);
                mTokenLen = mToken.Length();
            }

            cursor = buffer;
        } else if (!PL_strnstr(cursor, token, mTokenLen + 2)) {
            char *newBuffer = (char *) realloc(buffer, bufLen + mTokenLen + 1);
            if (!newBuffer)
                return NS_ERROR_OUT_OF_MEMORY;
            buffer = newBuffer;

            memmove(buffer + mTokenLen + 1, buffer, bufLen);
            memcpy(buffer, token, mTokenLen);
            buffer[mTokenLen] = '\n';

            bufLen += (mTokenLen + 1);

            // need to reset cursor to the buffer again (bug 100595)
            cursor = buffer;
        }
    }

    char *token = nullptr;

    // This may get initialized by ParseHeaders and the resulting
    // HttpResponseHead will be passed to nsPartChannel by SendStart

    if (mProcessingHeaders) {
        // we were not able to process all the headers
        // for this "part" given the previous buffer given to 
        // us in the previous OnDataAvailable callback.
        bool done = false;
        rv = ParseHeaders(channel, cursor, bufLen, &done);
        if (NS_FAILED(rv)) return rv;

        if (done) {
            mProcessingHeaders = false;
            rv = SendStart(channel);
            if (NS_FAILED(rv)) return rv;
        }
    }

    int32_t tokenLinefeed = 1;
    while ( (token = FindToken(cursor, bufLen)) ) {

        if (((token + mTokenLen) < (cursor + bufLen)) &&
            (*(token + mTokenLen + 1) == '-')) {
            // This was the last delimiter so we can stop processing
            rv = SendData(cursor, LengthToToken(cursor, token));
            if (NS_FAILED(rv)) return rv;
            if (mPartChannel) {
                mPartChannel->SetIsLastPart();
            }
            return SendStop(NS_OK);
        }

        if (!mNewPart && token > cursor) {
            // headers are processed, we're pushing data now.
            NS_ASSERTION(!mProcessingHeaders, "we should be pushing raw data");
            rv = SendData(cursor, LengthToToken(cursor, token));
            bufLen -= token - cursor;
            if (NS_FAILED(rv)) return rv;
        }
        // XXX else NS_ASSERTION(token == cursor, "?");
        token += mTokenLen;
        bufLen -= mTokenLen;
        tokenLinefeed = PushOverLine(token, bufLen);

        if (mNewPart) {
            // parse headers
            mNewPart = false;
            cursor = token;
            bool done = false; 
            rv = ParseHeaders(channel, cursor, bufLen, &done);
            if (NS_FAILED(rv)) return rv;
            if (done) {
                rv = SendStart(channel);
                if (NS_FAILED(rv)) return rv;
            }
            else {
                // we haven't finished processing header info.
                // we'll break out and try to process later.
                mProcessingHeaders = true;
                break;
            }
        }
        else {
            mNewPart = true;
            // Reset state so we don't carry it over from part to part
            mContentType.Truncate();
            mContentLength = UINT64_MAX;
            mContentDisposition.Truncate();
            mIsByteRangeRequest = false;
            mByteRangeStart = 0;
            mByteRangeEnd = 0;
            
            rv = SendStop(NS_OK);
            if (NS_FAILED(rv)) return rv;
            // reset the token to front. this allows us to treat
            // the token as a starting token.
            token -= mTokenLen + tokenLinefeed;
            bufLen += mTokenLen + tokenLinefeed;
            cursor = token;
        }
    }

    // at this point, we want to buffer up whatever amount (bufLen)
    // we have leftover. However, we *always* want to ensure that
    // we buffer enough data to handle a broken token.

    // carry over
    uint32_t bufAmt = 0;
    if (mProcessingHeaders)
        bufAmt = bufLen;
    else if (bufLen) {
        // if the data ends in a linefeed, and we're in the middle
        // of a "part" (ie. mPartChannel exists) don't bother
        // buffering, go ahead and send the data we have. Otherwise
        // if we don't have a channel already, then we don't even
        // have enough info to start a part, go ahead and buffer
        // enough to collect a boundary token.
        if (!mPartChannel || !(cursor[bufLen-1] == nsCRT::LF) )
            bufAmt = std::min(mTokenLen - 1, bufLen);
    }

    if (bufAmt) {
        rv = BufferData(cursor + (bufLen - bufAmt), bufAmt);
        if (NS_FAILED(rv)) return rv;
        bufLen -= bufAmt;
    }

    if (bufLen) {
        rv = SendData(cursor, bufLen);
        if (NS_FAILED(rv)) return rv;
    }

    return rv;
}
예제 #14
0
파일: flac.c 프로젝트: chouquette/vlc
/*****************************************************************************
 * Open: initializes ES structures
 *****************************************************************************/
static int Open( vlc_object_t * p_this )
{
    demux_t     *p_demux = (demux_t*)p_this;
    demux_sys_t *p_sys;
    const uint8_t *p_peek;
    es_format_t fmt;

    /* Have a peep at the show. */
    if( vlc_stream_Peek( p_demux->s, &p_peek, 4 ) < 4 ) return VLC_EGENERIC;

    if( p_peek[0]!='f' || p_peek[1]!='L' || p_peek[2]!='a' || p_peek[3]!='C' )
    {
        if( !p_demux->obj.force
         && !demux_IsContentType( p_demux, "audio/flac" ) )
            return VLC_EGENERIC;

        /* User forced */
        msg_Err( p_demux, "this doesn't look like a flac stream, "
                 "continuing anyway" );
    }

    p_sys = malloc( sizeof( demux_sys_t ) );
    if( unlikely(p_sys == NULL) )
        return VLC_ENOMEM;

    p_demux->pf_demux   = Demux;
    p_demux->pf_control = Control;
    p_demux->p_sys      = p_sys;
    p_sys->b_start = true;
    p_sys->i_next_block_flags = 0;
    p_sys->p_packetizer = NULL;
    p_sys->p_meta = NULL;
    p_sys->i_length = 0;
    p_sys->i_pts = VLC_TS_INVALID;
    p_sys->p_es = NULL;
    p_sys->p_current_block = NULL;
    TAB_INIT( p_sys->i_seekpoint, p_sys->seekpoint );
    TAB_INIT( p_sys->i_attachments, p_sys->attachments);
    TAB_INIT( p_sys->i_title_seekpoints, p_sys->pp_title_seekpoints );
    p_sys->i_cover_idx = 0;
    p_sys->i_cover_score = 0;

    es_format_Init( &fmt, AUDIO_ES, VLC_CODEC_FLAC );

    /* We need to read and store the STREAMINFO metadata into fmt extra */
    if( ParseHeaders( p_demux, &fmt ) )
        goto error;

    /* Load the FLAC packetizer */
    p_sys->p_packetizer = demux_PacketizerNew( p_demux, &fmt, "flac" );
    if( !p_sys->p_packetizer )
        goto error;

    if( p_sys->i_cover_idx < p_sys->i_attachments )
    {
        char psz_url[128];
        if( !p_sys->p_meta )
            p_sys->p_meta = vlc_meta_New();
        snprintf( psz_url, sizeof(psz_url), "attachment://%s",
                  p_sys->attachments[p_sys->i_cover_idx]->psz_name );
        vlc_meta_Set( p_sys->p_meta, vlc_meta_ArtworkURL, psz_url );
    }

    p_sys->p_es = es_out_Add( p_demux->out, &p_sys->p_packetizer->fmt_in );
    if( !p_sys->p_es )
        goto error;

    return VLC_SUCCESS;
error:
    Close( p_this );
    return VLC_EGENERIC;
}
예제 #15
0
// Extract HTTP headers via temporary file with -D switch.
// HTTP status code is extracted from curl output (-w switches).
// Redirects are handled recursively. TODO(AlexZ): avoid infinite redirects loop.
bool HttpClient::RunHttpRequest()
{
  ScopedRemoveFile headers_deleter(GetTmpFileName());
  ScopedRemoveFile body_deleter;
  ScopedRemoveFile received_file_deleter;

  string cmd = "curl -s -w '%{http_code}' -X " + m_httpMethod + " -D '" + headers_deleter.m_fileName + "' ";

  for (auto const & header : m_headers)
  {
    cmd += "-H '" + header.first + ": " + header.second + "' ";
  }

  if (!m_cookies.empty())
    cmd += "-b '" + m_cookies + "' ";

  if (!m_bodyData.empty())
  {
    body_deleter.m_fileName = GetTmpFileName();
    // POST body through tmp file to avoid breaking command line.
    if (!WriteToFile(body_deleter.m_fileName, m_bodyData))
      return false;

    // TODO(AlexZ): Correctly clean up this internal var to avoid client confusion.
    m_inputFile = body_deleter.m_fileName;
  }
  // Content-Length is added automatically by curl.
  if (!m_inputFile.empty())
    cmd += "--data-binary '@" + m_inputFile + "' ";

  // Use temporary file to receive data from server.
  // If user has specified file name to save data, it is not temporary and is not deleted automatically.
  string rfile = m_outputFile;
  if (rfile.empty())
  {
    rfile = GetTmpFileName();
    received_file_deleter.m_fileName = rfile;
  }

  cmd += "-o " + rfile + strings::to_string(" ") + "'" + m_urlRequested + "'";

  LOG(LDEBUG, ("Executing", cmd));

  try
  {
    m_errorCode = stoi(RunCurl(cmd));
  }
  catch (RootException const & ex)
  {
    LOG(LERROR, (ex.Msg()));
    return false;
  }

  m_headers.clear();
  Headers const headers = ParseHeaders(ReadFileAsString(headers_deleter.m_fileName));
  string serverCookies;
  string headerKey;
  for (auto const & header : headers)
  {
    if (header.first == "Set-Cookie")
    {
      serverCookies += header.second + ", ";
    }
    else
    {
      if (header.first == "Location")
        m_urlReceived = header.second;

      if (m_loadHeaders)
      {
        headerKey = header.first;
        strings::AsciiToLower(headerKey);
        m_headers.emplace(headerKey, header.second);
      }
    }
  }
  m_headers.emplace("Set-Cookie", NormalizeServerCookies(move(serverCookies)));

  if (m_urlReceived.empty())
  {
    m_urlReceived = m_urlRequested;
    // Load body contents in final request only (skip redirects).
    // Sometimes server can reply with empty body, and it's ok.
    if (m_outputFile.empty())
      m_serverResponse = ReadFileAsString(rfile);
  }
  else
  {
    // Handle HTTP redirect.
    // TODO(AlexZ): Should we check HTTP redirect code here?
    LOG(LDEBUG, ("HTTP redirect", m_errorCode, "to", m_urlReceived));

    HttpClient redirect(m_urlReceived);
    redirect.SetCookies(CombinedCookies());

    if (!redirect.RunHttpRequest())
    {
      m_errorCode = -1;
      return false;
    }

    m_errorCode = redirect.ErrorCode();
    m_urlReceived = redirect.UrlReceived();
    m_headers = move(redirect.m_headers);
    m_serverResponse = move(redirect.m_serverResponse);
  }

  return true;
}
예제 #16
0
// --------------------------------------------------------------------------
//
// Function
//		Name:    HTTPRequest::Receive(IOStreamGetLine &, int)
//		Purpose: Read the request from an IOStreamGetLine (and
//			 attached stream).
//			 Returns false if there was no valid request,
//			 probably due to a kept-alive connection closing.
//		Created: 26/3/04
//
// --------------------------------------------------------------------------
bool HTTPRequest::Receive(IOStreamGetLine &rGetLine, int Timeout)
{
	// Check caller's logic
	if(mMethod != Method_UNINITIALISED)
	{
		THROW_EXCEPTION(HTTPException, RequestAlreadyBeenRead);
	}

	// Read the first line, which is of a different format to the rest of the lines
	std::string requestLine;
	if(!rGetLine.GetLine(requestLine, false /* no preprocessing */, Timeout))
	{
		// Didn't get the request line, probably end of connection which had been kept alive
		return false;
	}
	BOX_TRACE("Request line: " << requestLine);

	// Check the method
	size_t p = 0;	// current position in string
	p = requestLine.find(' '); // end of first word

	if(p == std::string::npos)
	{
		// No terminating space, looks bad
		p = requestLine.size();
	}
	else
	{
		mHttpVerb = requestLine.substr(0, p);
		if (mHttpVerb == "GET")
		{
			mMethod = Method_GET;
		}
		else if (mHttpVerb == "HEAD")
		{
			mMethod = Method_HEAD;
		}
		else if (mHttpVerb == "POST")
		{
			mMethod = Method_POST;
		}
		else if (mHttpVerb == "PUT")
		{
			mMethod = Method_PUT;
		}
		else
		{
			mMethod = Method_UNKNOWN;
		}
	}

	// Skip spaces to find URI
	const char *requestLinePtr = requestLine.c_str();
	while(requestLinePtr[p] != '\0' && requestLinePtr[p] == ' ')
	{
		++p;
	}

	// Check there's a URI following...
	if(requestLinePtr[p] == '\0')
	{
		// Didn't get the request line, probably end of connection which had been kept alive
		return false;
	}

	// Read the URI, unescaping any %XX hex codes
	while(requestLinePtr[p] != ' ' && requestLinePtr[p] != '\0')
	{
		// End of URI, on to query string?
		if(requestLinePtr[p] == '?')
		{
			// Put the rest into the query string, without escaping anything
			++p;
			while(requestLinePtr[p] != ' ' && requestLinePtr[p] != '\0')
			{
				mQueryString += requestLinePtr[p];
				++p;
			}
			break;
		}
		// Needs unescaping?
		else if(requestLinePtr[p] == '+')
		{
			mRequestURI += ' ';
		}
		else if(requestLinePtr[p] == '%')
		{
			// Be tolerant about this... bad things are silently accepted,
			// rather than throwing an error.
			char code[4] = {0,0,0,0};
			code[0] = requestLinePtr[++p];
			if(code[0] != '\0')
			{
				code[1] = requestLinePtr[++p];
			}

			// Convert into a char code
			long c = ::strtol(code, NULL, 16);

			// Accept it?
			if(c > 0 && c <= 255)
			{
				mRequestURI += (char)c;
			}
		}
		else
		{
			// Simple copy of character
			mRequestURI += requestLinePtr[p];
		}

		++p;
	}

	// End of URL?
	if(requestLinePtr[p] == '\0')
	{
		// Assume HTTP 0.9
		mHTTPVersion = HTTPVersion_0_9;
	}
	else
	{
		// Skip any more spaces
		while(requestLinePtr[p] != '\0' && requestLinePtr[p] == ' ')
		{
			++p;
		}

		// Check to see if there's the right string next...
		if(::strncmp(requestLinePtr + p, "HTTP/", 5) == 0)
		{
			// Find the version numbers
			int major, minor;
			if(::sscanf(requestLinePtr + p + 5, "%d.%d", &major, &minor) != 2)
			{
				THROW_EXCEPTION_MESSAGE(HTTPException, BadRequest,
					"Unable to parse HTTP version number: " <<
					requestLinePtr);
			}

			// Store version
			mHTTPVersion = (major * HTTPVersion__MajorMultiplier) + minor;
		}
		else
		{
			// Not good -- wrong string found
			THROW_EXCEPTION_MESSAGE(HTTPException, BadRequest,
				"Unable to parse HTTP request line: " <<
				requestLinePtr);
		}
	}

	BOX_TRACE("HTTPRequest: method=" << mMethod << ", uri=" <<
		mRequestURI << ", version=" << mHTTPVersion);

	// If HTTP 1.1 or greater, assume keep-alive
	if(mHTTPVersion >= HTTPVersion_1_1)
	{
		mClientKeepAliveRequested = true;
	}

	// Decode query string?
	if((mMethod == Method_GET || mMethod == Method_HEAD) && !mQueryString.empty())
	{
		HTTPQueryDecoder decoder(mQuery);
		decoder.DecodeChunk(mQueryString.c_str(), mQueryString.size());
		decoder.Finish();
	}

	// Now parse the headers
	ParseHeaders(rGetLine, Timeout);

	std::string expected;
	if(GetHeader("Expect", &expected))
	{
		if(expected == "100-continue")
		{
			mExpectContinue = true;
		}
	}

	// Parse form data?
	if(mMethod == Method_POST && mContentLength >= 0)
	{
		// Too long? Don't allow people to be nasty by sending lots of data
		if(mContentLength > MAX_CONTENT_SIZE)
		{
			THROW_EXCEPTION(HTTPException, POSTContentTooLong);
		}

		// Some data in the request to follow, parsing it bit by bit
		HTTPQueryDecoder decoder(mQuery);
		// Don't forget any data left in the GetLine object
		int fromBuffer = rGetLine.GetSizeOfBufferedData();
		if(fromBuffer > mContentLength) fromBuffer = mContentLength;
		if(fromBuffer > 0)
		{
			BOX_TRACE("Decoding " << fromBuffer << " bytes of "
				"data from getline buffer");
			decoder.DecodeChunk((const char *)rGetLine.GetBufferedData(), fromBuffer);
			// And tell the getline object to ignore the data we just used
			rGetLine.IgnoreBufferedData(fromBuffer);
		}
		// Then read any more data, as required
		int bytesToGo = mContentLength - fromBuffer;
		while(bytesToGo > 0)
		{
			char buf[4096];
			int toRead = sizeof(buf);
			if(toRead > bytesToGo) toRead = bytesToGo;
			IOStream &rstream(rGetLine.GetUnderlyingStream());
			int r = rstream.Read(buf, toRead, Timeout);
			if(r == 0)
			{
				// Timeout, just error
				THROW_EXCEPTION_MESSAGE(HTTPException, RequestReadFailed,
					"Failed to read complete request with the timeout");
			}
			decoder.DecodeChunk(buf, r);
			bytesToGo -= r;
		}
		// Finish off
		decoder.Finish();
	}
	else if (mContentLength > 0)
	{
		IOStream::pos_type bytesToCopy = rGetLine.GetSizeOfBufferedData();
		if (bytesToCopy > mContentLength)
		{
			bytesToCopy = mContentLength;
		}
		Write(rGetLine.GetBufferedData(), bytesToCopy);
		SetForReading();
		mpStreamToReadFrom = &(rGetLine.GetUnderlyingStream());
	}

	return true;
}