thomescai http://blog.csdn.net/thomescai(转载请保留)
本文主要浅析:http的解码的过程,因为编码的过程我还没细看。。。似乎代码量不多。
实现:
1.SingleHttpSessionIoHandler中添加了4个Filter:ProtocolCodecFilter,
ContextConverter,RequestPipelineAdapter,ServiceFilterAdapter。
2.HttpCodecFactory实现了ProtocolCodecFactory中的getEncoder和getDecoder
通过编码和解码,对http协议进行解析和生成。
package org.apache.asyncweb.server.transport.mina;
public class SingleHttpSessionIoHandler implements SingleSessionIoHandler
{
/** the default idle time */
private static final int DEFAULT_IDLE_TIME = 30000;
/** out default pipeline */
private static final int DEFAULT_PIPELINE = 100;
/** the HttpService container **/
private final ServiceContainer container;
/** the session bound to this single session handler */
protected final IoSession session;
/** the request pipeline */
private final RequestPipeline pipeline;
/** the current context being processed */
private DefaultHttpServiceContext currentContext;
public SingleHttpSessionIoHandler( ServiceContainer container, IoSession session )
{
this.container = container;
this.session = session;
this.pipeline = new StandardRequestPipeline( DEFAULT_PIPELINE );
session.getConfig().setIdleTime( IdleStatus.READER_IDLE, readIdleTime );
session.getFilterChain().addLast( "codec", new ProtocolCodecFilter( new HttpCodecFactory() ) );
session.getFilterChain().addLast( "converter", new ContextConverter() );
session.getFilterChain().addLast( "pipeline", new RequestPipelineAdapter( pipeline ) );
int i = 0;
for ( HttpServiceFilter serviceFilter : container.getServiceFilters() )
{
session.getFilterChain().addLast( "serviceFilter." + i++, new ServiceFilterAdapter( serviceFilter ) );
}
}
package org.apache.asyncweb.common.codec;
public class HttpCodecFactory implements ProtocolCodecFactory
{
public ProtocolEncoder getEncoder( IoSession session ) throws Exception
{
if ( session.getService() instanceof IoAcceptor )
{
return new HttpResponseEncoder();
}
else
{
return new HttpRequestEncoder();
}
}
public ProtocolDecoder getDecoder( IoSession session ) throws Exception
{
if ( session.getService() instanceof IoAcceptor )
{
return new HttpRequestDecoder();
}
else
{
return new HttpResponseDecoder();
}
}
}
类图:
http的解码:
http的解码过程不复杂,但很长。。。
package org.apache.asyncweb.common.codec;
abstract class HttpRequestDecodingStateMachine extends DecodingStateMachine {
private MutableHttpRequest request;
@Override
protected DecodingState init() throws Exception {
request = new DefaultHttpRequest();
return SKIP_EMPTY_LINES;
}
@Override
protected void destroy() throws Exception {
request = null;
}
private final DecodingState SKIP_EMPTY_LINES = new CrLfDecodingState() {
@Override
protected DecodingState finishDecode(boolean foundCRLF,
ProtocolDecoderOutput out) throws Exception {
}
};
private final DecodingState READ_REQUEST_LINE = new HttpRequestLineDecodingState() {
@Override
protected DecodingState finishDecode(List<Object> childProducts,
ProtocolDecoderOutput out) throws Exception {
URI requestUri = (URI) childProducts.get(1);
request.setMethod((HttpMethod) childProducts.get(0));
request.setRequestUri(requestUri);
request.setProtocolVersion((HttpVersion) childProducts.get(2));
request.setParameters(requestUri.getRawQuery());
return READ_HEADERS;
}
};
private final DecodingState READ_HEADERS = new HttpHeaderDecodingState() {
@Override
@SuppressWarnings("unchecked")
protected DecodingState finishDecode(List<Object> childProducts,
ProtocolDecoderOutput out) throws Exception {
}
};
}
所有的解析方法都实现了DecodingState接口,IoBuffer为入口,ProtocolDecoderOutput为出口
public abstract interface DecodingState
{
public abstract DecodingState decode(IoBuffer paramIoBuffer, ProtocolDecoderOutput paramProtocolDecoderOutput)
throws Exception;
public abstract DecodingState finishDecode(ProtocolDecoderOutput paramProtocolDecoderOutput)
throws Exception;
}
decoder时序图:
在init()中 初始化了MutableHttpRequest的实现对象request,解析过程为:SKIP_EMPTY_LINES——》READ_REQUEST_LINE——》READ_HEADERS。
再通过out.write(request),将request返回到HttpRequestDecodingStateMachine
的finishDecode()中。
结束语:
可以顺着解析顺序,查看具体代码。从中了解http的协议。
下期预告:《AsyncWeb原理分析(五)——request的封装》