package com.linkedin.r2.filter.transport;
import com.linkedin.common.callback.Callback;
import com.linkedin.r2.filter.NextFilter;
import com.linkedin.r2.filter.message.rest.RestFilter;
import com.linkedin.r2.filter.message.stream.StreamFilter;
import com.linkedin.r2.message.Messages;
import com.linkedin.r2.message.QueryTunnelUtil;
import com.linkedin.r2.message.RequestContext;
import com.linkedin.r2.message.rest.RestRequest;
import com.linkedin.r2.message.rest.RestResponse;
import com.linkedin.r2.message.rest.RestStatus;
import com.linkedin.r2.message.stream.StreamRequest;
import com.linkedin.r2.message.stream.StreamResponse;
import javax.mail.MessagingException;
import java.net.URISyntaxException;
import java.util.Map;
/**
* @author Zhenkai Zhu
*/
public class ServerQueryTunnelFilter implements StreamFilter,RestFilter
{
@Override
public void onRestRequest(RestRequest req,
RequestContext requestContext,
Map<String, String> wireAttrs,
NextFilter<RestRequest, RestResponse> nextFilter)
{
final RestRequest newReq;
try
{
newReq = QueryTunnelUtil.decode(req, requestContext);
}
catch (MessagingException ex)
{
RestResponse errorResponse =
RestStatus.responseForStatus(RestStatus.BAD_REQUEST, ex.toString());
nextFilter.onResponse(errorResponse, requestContext, wireAttrs);
return;
}
catch (URISyntaxException ex)
{
RestResponse errorResponse =
RestStatus.responseForStatus(RestStatus.BAD_REQUEST, ex.toString());
nextFilter.onResponse(errorResponse, requestContext, wireAttrs);
return;
}
catch (Exception ex)
{
nextFilter.onError(ex, requestContext, wireAttrs);
return;
}
nextFilter.onRequest(newReq, requestContext, wireAttrs);
}
@Override
public void onStreamRequest(final StreamRequest req,
final RequestContext requestContext,
final Map<String, String> wireAttrs,
final NextFilter<StreamRequest, StreamResponse> nextFilter)
{
Callback<StreamRequest> callback = new Callback<StreamRequest>()
{
@Override
public void onError(Throwable e)
{
if (e instanceof MessagingException || e instanceof URISyntaxException)
{
RestResponse errorResponse =
RestStatus.responseForStatus(RestStatus.BAD_REQUEST, e.toString());
nextFilter.onResponse(Messages.toStreamResponse(errorResponse), requestContext, wireAttrs);
}
else
{
nextFilter.onError(e, requestContext, wireAttrs);
}
}
@Override
public void onSuccess(StreamRequest newReq)
{
nextFilter.onRequest(newReq, requestContext, wireAttrs);
}
};
// the entire request would be buffered in memory if decoding is needed
// this usually is not a problem as request with extremely query parameters is usually get request with no body
QueryTunnelUtil.decode(req, requestContext, callback);
}
}