package com.wangyin.ak47.pipes.http;
import com.wangyin.ak47.common.Logger;
import com.wangyin.ak47.core.Pipe;
import com.wangyin.ak47.core.Request;
import com.wangyin.ak47.core.Response;
import com.wangyin.ak47.core.Buffer;
/**
* 抽象HttpPipe基类,
* 基于ApcheComponent-HttpCore —— httpcore内核设计太糟糕了,放弃。
*
* 现用自制SimpleHttpParser,不支持pipeline方式。
*
* @author wyhubingyin
*
* @param <Q> Request POJO
* @param <R> Response POJO
*/
public abstract class AbstractHttpPipe<Q, R> extends Pipe<Q, R>{
private static final Logger log = new Logger(AbstractHttpPipe.class);
@Override
public void decodeRequest(Buffer buf, Request<Q> request) throws Exception {
SimpleHttpRequest httpreq = SimpleHttpParser.parseRequest(buf);
if( null == httpreq ){
log.debug("parseHttpRequest fail.");
}else{
decodeHttpRequest(httpreq, request);
}
}
/**
* HttpRequest →→→ POJO
*
* @param httpreq HTTP Request object that offer simple API
* @param request Request with POJO
* @throws Exception in any case
*/
public abstract void decodeHttpRequest(SimpleHttpRequest httpreq,
Request<Q> request) throws Exception;
@Override
public void encodeRequest(Request<Q> request, Buffer buf) throws Exception {
SimpleHttpRequest httpreq = new SimpleHttpRequest();
encodeHttpRequest(request, httpreq);
if( httpreq.getContent() != null &&
httpreq.getHeaderFirst("content-length") == null ){
int contentLength = httpreq.getContent().length;
httpreq.setOrAddFirstHeader("content-length",
String.valueOf(contentLength));
}
buf.writeBytes(httpreq.buildFullBytes());
}
/**
* POJO →→→ HttpRequest
*
* @param request Request with POJO
* @param httpreq HTTP Request object that offer simple API
* @throws Exception in any case
*/
public abstract void encodeHttpRequest(Request<Q> request,
SimpleHttpRequest httpreq) throws Exception;
@Override
public void decodeResponse(Buffer buf, Response<R> response) throws Exception {
SimpleHttpResponse httpRes = SimpleHttpParser.parseResponse(buf);
if( null == httpRes ){
log.debug("parseHttpResponse fail.");
}else{
decodeHttpResponse(httpRes, response);
}
// int readableBytes = buf.readableBytes();
// if( readableBytes > 0 ){
// int readerIndex = buf.readerIndex();
// byte[] bytes = new byte[readableBytes];
// buf.readBytes(bytes);
// SimpleHttpResponse httpRes = SimpleHttpParser.parseResponse(bytes);
//
//// ////FIXME
//// int readerIndex = buf.readerIndex();
//// buf.readerIndex(readerIndex+readableBytes);
//// SimpleHttpResponse httpRes = new SimpleHttpResponse();
//// httpRes.setContent("It works!".getBytes());
//// ////FIXME
//
//
// if( null == httpRes ){
// log.debug("parseHttpResponse fail, rollback.");
// buf.readerIndex(readerIndex);
// }else{
// decodeHttpResponse(httpRes, response);
// }
// }else{
// log.warn("NOTHING to read.");
// }
}
/**
* HttpResponse →→→ POJO
*
* @param httpres HTTP Response object that offer simple API
* @param response Response with POJO
* @throws Exception In any case
*/
public abstract void decodeHttpResponse(SimpleHttpResponse httpres,
Response<R> response) throws Exception;
@Override
public void encodeResponse(Response<R> response, Buffer buf) throws Exception {
SimpleHttpResponse httpRes = new SimpleHttpResponse();
encodeHttpResponse(response, httpRes);
if( httpRes.getContent() != null &&
httpRes.getHeaderFirst("content-length") == null ){
int contentLength = httpRes.getContent().length;
httpRes.setOrAddFirstHeader("content-length",
String.valueOf(contentLength));
}
if( httpRes.getHeaderFirst("connection") == null ){
httpRes.setOrAddFirstHeader("connection", "keep-alive");
}
buf.writeBytes(httpRes.buildFullBytes());
}
/**
* POJO →→→ HttpRequest
*
* @param response Response with POJO
* @param httpres HTTP Response object that offer simple API
* @throws Exception In any case
*/
public abstract void encodeHttpResponse(Response<R> response,
SimpleHttpResponse httpres) throws Exception;
}