Esempio n. 1
0
LLIOPipe::EStatus LLHTTPPipe::process_impl(
	const LLChannelDescriptors& channels,
    buffer_ptr_t& buffer,
    bool& eos,
    LLSD& context,
    LLPumpIO* pump)
{
	PUMP_DEBUG;
    lldebugs << "LLSDHTTPServer::process_impl" << llendl;

    // Once we have all the data, We need to read the sd on
    // the the in channel, and respond on  the out channel

    if(!eos) return STATUS_BREAK;
    if(!pump || !buffer) return STATUS_PRECONDITION_NOT_MET;

	PUMP_DEBUG;
	if (mState == STATE_INVOKE)
	{
		PUMP_DEBUG;
		mState = STATE_DELAYED;
			// assume deferred unless mResponse does otherwise
		mResponse = Response::create(this);

		// TODO: Babbage: Parameterize parser?
		LLBufferStream istr(channels, buffer.get());

		static LLTimer timer;
		if (sTimingCallback)
		{
			timer.reset();
		}

		std::string verb = context[CONTEXT_REQUEST]["verb"];
		if(verb == HTTP_VERB_GET)
		{
			mNode.get(LLHTTPNode::ResponsePtr(mResponse), context);
		}
		else if(verb == HTTP_VERB_PUT)
		{
			LLSD input;
			LLSDSerialize::fromXML(input, istr);

			mNode.put(LLHTTPNode::ResponsePtr(mResponse), context, input);
		}
		else if(verb == HTTP_VERB_POST)
		{
			LLSD input;
			LLSDSerialize::fromXML(input, istr);

			mNode.post(LLHTTPNode::ResponsePtr(mResponse), context, input);
		}
		else if(verb == HTTP_VERB_DELETE)
		{
			mNode.del(LLHTTPNode::ResponsePtr(mResponse), context);
		}		
		else 
		{
		    mResponse->methodNotAllowed();
		}

		if (sTimingCallback)
		{
			LLHTTPNode::Description desc;
			mNode.describe(desc);
			LLSD info = desc.getInfo();
			std::string timing_name = info["description"];
			timing_name += " ";
			timing_name += verb;
			F32 delta = timer.getElapsedTimeF32();
			sTimingCallback(timing_name.c_str(), delta, sTimingCallbackData);
		}

		// Log Internal Server Errors
		if(mStatusCode == 500)
		{
			llwarns << "LLHTTPPipe::process_impl:500:Internal Server Error" 
					<< llendl;
		}
	}

	PUMP_DEBUG;
	switch (mState)
	{
		case STATE_DELAYED:
			lockChain(pump);
			mState = STATE_LOCKED;
			return STATUS_BREAK;

		case STATE_LOCKED:
			// should never ever happen!
			return STATUS_ERROR;

		case STATE_GOOD_RESULT:
		{
			context["response"]["contentType"] = "application/xml";
			LLBufferStream ostr(channels, buffer.get());
			LLSDSerialize::toXML(mGoodResult, ostr);

			return STATUS_DONE;
		}

		case STATE_STATUS_RESULT:
		{
			context["response"]["contentType"] = "text/plain";
			context["response"]["statusCode"] = mStatusCode;
			context["response"]["statusMessage"] = mStatusMessage;
			LLBufferStream ostr(channels, buffer.get());
			ostr << mStatusMessage << std::ends;

			return STATUS_DONE;
		}
		default:
			llwarns << "LLHTTPPipe::process_impl: unexpected state "
				<< mState << llendl;

			return STATUS_BREAK;
	}
// 	PUMP_DEBUG; // unreachable
}
Esempio n. 2
0
LLIOPipe::EStatus LLHTTPPipe::process_impl(
	const LLChannelDescriptors& channels,
    buffer_ptr_t& buffer,
    bool& eos,
    LLSD& context,
    LLPumpIO* pump)
{
	PUMP_DEBUG;
    lldebugs << "LLSDHTTPServer::process_impl" << llendl;

    // Once we have all the data, We need to read the sd on
    // the the in channel, and respond on  the out channel

    if(!eos) return STATUS_BREAK;
    if(!pump || !buffer) return STATUS_PRECONDITION_NOT_MET;

	PUMP_DEBUG;
	if (mState == STATE_INVOKE)
	{
		PUMP_DEBUG;
		mState = STATE_DELAYED;
			// assume deferred unless mResponse does otherwise
		mResponse = Response::create(this);

		// *TODO: Babbage: Parameterize parser?
		// *TODO: We should look at content-type and do the right
		// thing. Phoenix 2007-12-31
		LLBufferStream istr(channels, buffer.get());

		static LLTimer timer;
		timer.reset();

		std::string verb = context[CONTEXT_REQUEST][CONTEXT_VERB];
		if(verb == HTTP_VERB_GET)
		{
            LLPerfBlock getblock("http_get");   
			mNode.get(LLHTTPNode::ResponsePtr(mResponse), context);
		}
		else if(verb == HTTP_VERB_PUT)
		{
            LLPerfBlock putblock("http_put");
			LLSD input;
			LLSDSerialize::fromXML(input, istr);
			mNode.put(LLHTTPNode::ResponsePtr(mResponse), context, input);
		}
		else if(verb == HTTP_VERB_POST)
		{
            LLPerfBlock postblock("http_post");
			LLSD input;
			LLSDSerialize::fromXML(input, istr);
			mNode.post(LLHTTPNode::ResponsePtr(mResponse), context, input);
		}
		else if(verb == HTTP_VERB_DELETE)
		{
            LLPerfBlock delblock("http_delete");
			mNode.del(LLHTTPNode::ResponsePtr(mResponse), context);
		}		
		else if(verb == HTTP_VERB_OPTIONS)
		{
			mNode.options(LLHTTPNode::ResponsePtr(mResponse), context);
		}		
		else 
		{
		    mResponse->methodNotAllowed();
		}

		F32 delta = timer.getElapsedTimeF32();
		if (sTimingCallback)
		{
			LLHTTPNode::Description desc;
			mNode.describe(desc);
			LLSD info = desc.getInfo();
			std::string timing_name = info["description"];
			timing_name += " ";
			timing_name += verb;
			sTimingCallback(timing_name.c_str(), delta, sTimingCallbackData);
		}

		// Log all HTTP transactions.
		// TODO: Add a way to log these to their own file instead of indra.log
		// It is just too spammy to be in indra.log.
		lldebugs << verb << " " << context[CONTEXT_REQUEST]["path"].asString()
			<< " " << mStatusCode << " " <<  mStatusMessage << " " << delta
			<< "s" << llendl;

		// Log Internal Server Errors
		//if(mStatusCode == 500)
		//{
		//	llwarns << "LLHTTPPipe::process_impl:500:Internal Server Error" 
		//			<< llendl;
		//}
	}

	PUMP_DEBUG;
	switch (mState)
	{
		case STATE_DELAYED:
			lockChain(pump);
			mState = STATE_LOCKED;
			return STATUS_BREAK;

		case STATE_LOCKED:
			// should never ever happen!
			return STATUS_ERROR;

		case STATE_GOOD_RESULT:
		{
			LLSD headers = mHeaders;
			headers["Content-Type"] = "application/llsd+xml";
			context[CONTEXT_RESPONSE][CONTEXT_HEADERS] = headers;
			LLBufferStream ostr(channels, buffer.get());
			LLSDSerialize::toXML(mGoodResult, ostr);

			return STATUS_DONE;
		}

		case STATE_STATUS_RESULT:
		{
			LLSD headers = mHeaders;
			headers["Content-Type"] = "text/plain";
			context[CONTEXT_RESPONSE][CONTEXT_HEADERS] = headers;
			context[CONTEXT_RESPONSE]["statusCode"] = mStatusCode;
			context[CONTEXT_RESPONSE]["statusMessage"] = mStatusMessage;
			LLBufferStream ostr(channels, buffer.get());
			ostr << mStatusMessage << std::ends;

			return STATUS_DONE;
		}
		default:
			llwarns << "LLHTTPPipe::process_impl: unexpected state "
				<< mState << llendl;

			return STATUS_BREAK;
	}
// 	PUMP_DEBUG; // unreachable
}