convert service from Bound to Started
Add Origin check for JSOIN-RPC Server
This commit is contained in:
parent
1fd463ce31
commit
1a81061679
|
@ -0,0 +1,144 @@
|
|||
package org.ethereum.android.jsonrpc;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.JSONRPC2Request;
|
||||
import com.thetransactioncompany.jsonrpc2.JSONRPC2Response;
|
||||
import com.thetransactioncompany.jsonrpc2.server.Dispatcher;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelFutureListener;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.SimpleChannelInboundHandler;
|
||||
import io.netty.handler.codec.http.DefaultFullHttpResponse;
|
||||
import io.netty.handler.codec.http.FullHttpResponse;
|
||||
import io.netty.handler.codec.http.HttpContent;
|
||||
import io.netty.handler.codec.http.HttpHeaders;
|
||||
import io.netty.handler.codec.http.HttpMethod;
|
||||
import io.netty.handler.codec.http.HttpObject;
|
||||
import io.netty.handler.codec.http.HttpRequest;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import io.netty.handler.codec.http.HttpVersion;
|
||||
import io.netty.handler.codec.http.LastHttpContent;
|
||||
import io.netty.handler.codec.http.multipart.DefaultHttpDataFactory;
|
||||
import io.netty.handler.codec.http.multipart.HttpPostStandardRequestDecoder;
|
||||
import io.netty.util.CharsetUtil;
|
||||
|
||||
import static io.netty.handler.codec.http.HttpHeaders.Names.ACCESS_CONTROL_ALLOW_HEADERS;
|
||||
import static io.netty.handler.codec.http.HttpHeaders.Names.ACCESS_CONTROL_ALLOW_ORIGIN;
|
||||
import static io.netty.handler.codec.http.HttpHeaders.Names.ACCESS_CONTROL_REQUEST_METHOD;
|
||||
import static io.netty.handler.codec.http.HttpHeaders.Names.CONNECTION;
|
||||
import static io.netty.handler.codec.http.HttpHeaders.Names.CONTENT_LENGTH;
|
||||
import static io.netty.handler.codec.http.HttpHeaders.Names.CONTENT_TYPE;
|
||||
import static io.netty.handler.codec.http.HttpHeaders.Names.VARY;
|
||||
|
||||
public class JsonRpcServerHandler extends SimpleChannelInboundHandler<HttpObject> {
|
||||
|
||||
private HttpRequest request;
|
||||
private final StringBuilder responseContent = new StringBuilder();
|
||||
private HttpPostStandardRequestDecoder decoder;
|
||||
private String postData;
|
||||
private boolean isOptions = false;
|
||||
private Dispatcher dispatcher;
|
||||
|
||||
public JsonRpcServerHandler(Dispatcher dispatcher) {
|
||||
super();
|
||||
this.dispatcher = dispatcher;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
|
||||
if (decoder != null) {
|
||||
decoder.destroy();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception {
|
||||
if (msg instanceof HttpRequest) {
|
||||
HttpRequest req = this.request = (HttpRequest) msg;
|
||||
if (request.getMethod().equals(HttpMethod.OPTIONS)) {
|
||||
isOptions = true;
|
||||
return;
|
||||
} else if (!req.getUri().equals("/") || !request.getMethod().equals(HttpMethod.POST)) {
|
||||
responseContent.append("Hi, how are you?!!");
|
||||
return;
|
||||
} else {
|
||||
decoder = new HttpPostStandardRequestDecoder(new DefaultHttpDataFactory(false), req);
|
||||
postData = "";
|
||||
}
|
||||
}
|
||||
|
||||
if (decoder != null) {
|
||||
if (msg instanceof HttpContent) {
|
||||
HttpContent chunk = (HttpContent) msg;
|
||||
decoder.offer(chunk);
|
||||
postData += chunk.content().toString(0, chunk.content().capacity(), CharsetUtil.UTF_8);
|
||||
|
||||
if (chunk instanceof LastHttpContent) {
|
||||
JSONRPC2Request req = JSONRPC2Request.parse(postData);
|
||||
JSONRPC2Response resp = dispatcher.process(req, null);
|
||||
responseContent.append(resp);
|
||||
writeResponse(ctx);
|
||||
request = null;
|
||||
decoder.destroy();
|
||||
decoder = null;
|
||||
}
|
||||
}
|
||||
} else if (isOptions) {
|
||||
writeOptionsResponse(ctx);
|
||||
isOptions = false;
|
||||
} else {
|
||||
writeResponse(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeResponse(ChannelHandlerContext ctx) {
|
||||
ByteBuf buf = Unpooled.copiedBuffer(responseContent.toString(), CharsetUtil.UTF_8);
|
||||
responseContent.setLength(0);
|
||||
|
||||
boolean close = HttpHeaders.Values.CLOSE.equalsIgnoreCase(request.headers().get(CONNECTION))
|
||||
|| request.getProtocolVersion().equals(HttpVersion.HTTP_1_0)
|
||||
&& !HttpHeaders.Values.KEEP_ALIVE.equalsIgnoreCase(request.headers().get(CONNECTION));
|
||||
FullHttpResponse response = new DefaultFullHttpResponse(
|
||||
HttpVersion.HTTP_1_1, HttpResponseStatus.OK, buf);
|
||||
response.headers().set(CONTENT_TYPE, "text/plain; charset=UTF-8");
|
||||
response.headers().set(ACCESS_CONTROL_ALLOW_ORIGIN, "*");
|
||||
|
||||
if (!close) {
|
||||
response.headers().set(CONTENT_LENGTH, buf.readableBytes());
|
||||
}
|
||||
|
||||
ChannelFuture future = ctx.writeAndFlush(response);
|
||||
if (close) {
|
||||
future.addListener(ChannelFutureListener.CLOSE);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeOptionsResponse(ChannelHandlerContext ctx) {
|
||||
boolean close = HttpHeaders.Values.CLOSE.equalsIgnoreCase(request.headers().get(CONNECTION))
|
||||
|| request.getProtocolVersion().equals(HttpVersion.HTTP_1_0)
|
||||
&& !HttpHeaders.Values.KEEP_ALIVE.equalsIgnoreCase(request.headers().get(CONNECTION));
|
||||
FullHttpResponse response = new DefaultFullHttpResponse(
|
||||
HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
|
||||
response.headers().set(CONTENT_TYPE, "text/plain; charset=UTF-8");
|
||||
response.headers().set(ACCESS_CONTROL_ALLOW_HEADERS, "Content-Type");
|
||||
response.headers().set(ACCESS_CONTROL_REQUEST_METHOD, "POST");
|
||||
response.headers().set(ACCESS_CONTROL_ALLOW_ORIGIN, "*");
|
||||
response.headers().set(VARY, "Origin");
|
||||
|
||||
if (!close) {
|
||||
response.headers().set(CONTENT_LENGTH, 0);
|
||||
}
|
||||
|
||||
ChannelFuture future = ctx.writeAndFlush(response);
|
||||
if (close) {
|
||||
future.addListener(ChannelFutureListener.CLOSE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
|
||||
cause.printStackTrace();
|
||||
ctx.close();
|
||||
}
|
||||
}
|
|
@ -10,34 +10,15 @@ import io.netty.channel.ChannelInitializer;
|
|||
import io.netty.channel.ChannelPipeline;
|
||||
import io.netty.channel.socket.SocketChannel;
|
||||
import io.netty.handler.codec.http.HttpServerCodec;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.ChannelFutureListener;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.http.DefaultFullHttpResponse;
|
||||
import io.netty.handler.codec.http.FullHttpResponse;
|
||||
import io.netty.handler.codec.http.HttpRequest;
|
||||
import io.netty.handler.codec.http.multipart.HttpPostStandardRequestDecoder;
|
||||
import io.netty.handler.codec.http.multipart.DefaultHttpDataFactory;
|
||||
import io.netty.handler.codec.http.HttpObject;
|
||||
import io.netty.channel.SimpleChannelInboundHandler;
|
||||
import io.netty.handler.codec.http.HttpMethod;
|
||||
import io.netty.handler.codec.http.HttpContent;
|
||||
import io.netty.handler.codec.http.LastHttpContent;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.util.CharsetUtil;
|
||||
import io.netty.handler.codec.http.HttpVersion;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import org.ethereum.android.jsonrpc.full.filter.FilterManager;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import io.netty.handler.codec.http.HttpHeaders;
|
||||
import static io.netty.handler.codec.http.HttpHeaders.Names.*;
|
||||
import org.ethereum.android.jsonrpc.full.method.*;
|
||||
|
||||
import java.net.InetAddress;
|
||||
|
||||
import org.ethereum.android.jsonrpc.*;
|
||||
|
||||
|
||||
public final class JsonRpcServer extends org.ethereum.android.jsonrpc.JsonRpcServer{
|
||||
|
||||
|
@ -146,82 +127,7 @@ public final class JsonRpcServer extends org.ethereum.android.jsonrpc.JsonRpcSer
|
|||
public void initChannel(SocketChannel ch) {
|
||||
ChannelPipeline p = ch.pipeline();
|
||||
p.addLast(new HttpServerCodec());
|
||||
p.addLast(new JsonRpcServerHandler());
|
||||
}
|
||||
}
|
||||
|
||||
class JsonRpcServerHandler extends SimpleChannelInboundHandler<HttpObject> {
|
||||
|
||||
private HttpRequest request;
|
||||
private final StringBuilder responseContent = new StringBuilder();
|
||||
private HttpPostStandardRequestDecoder decoder;
|
||||
private String postData;
|
||||
|
||||
@Override
|
||||
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
|
||||
if (decoder != null) {
|
||||
decoder.destroy();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception {
|
||||
if (msg instanceof HttpRequest) {
|
||||
HttpRequest req = this.request = (HttpRequest) msg;
|
||||
if (!req.getUri().equals("/") || !request.getMethod().equals(HttpMethod.POST)) {
|
||||
responseContent.append("Hi, how are you?!!");
|
||||
return;
|
||||
} else {
|
||||
decoder = new HttpPostStandardRequestDecoder(new DefaultHttpDataFactory(false), req);
|
||||
postData = "";
|
||||
}
|
||||
}
|
||||
|
||||
if (decoder != null) {
|
||||
if (msg instanceof HttpContent) {
|
||||
HttpContent chunk = (HttpContent) msg;
|
||||
decoder.offer(chunk);
|
||||
postData += chunk.content().toString(0, chunk.content().capacity(), CharsetUtil.UTF_8);
|
||||
|
||||
if (chunk instanceof LastHttpContent) {
|
||||
JSONRPC2Request req = JSONRPC2Request.parse(postData);
|
||||
JSONRPC2Response resp = dispatcher.process(req, null);
|
||||
responseContent.append(resp);
|
||||
writeResponse(ctx);
|
||||
request = null;
|
||||
decoder.destroy();
|
||||
decoder = null;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
writeResponse(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeResponse(ChannelHandlerContext ctx) {
|
||||
ByteBuf buf = Unpooled.copiedBuffer(responseContent.toString(), CharsetUtil.UTF_8);
|
||||
responseContent.setLength(0);
|
||||
|
||||
boolean close = HttpHeaders.Values.CLOSE.equalsIgnoreCase(request.headers().get(CONNECTION))
|
||||
|| request.getProtocolVersion().equals(HttpVersion.HTTP_1_0)
|
||||
&& !HttpHeaders.Values.KEEP_ALIVE.equalsIgnoreCase(request.headers().get(CONNECTION));
|
||||
FullHttpResponse response = new DefaultFullHttpResponse(
|
||||
HttpVersion.HTTP_1_1, HttpResponseStatus.OK, buf);
|
||||
response.headers().set(CONTENT_TYPE, "text/plain; charset=UTF-8");
|
||||
|
||||
if (!close) {
|
||||
response.headers().set(CONTENT_LENGTH, buf.readableBytes());
|
||||
}
|
||||
|
||||
ChannelFuture future = ctx.writeAndFlush(response);
|
||||
if (close) {
|
||||
future.addListener(ChannelFutureListener.CLOSE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
|
||||
cause.printStackTrace();
|
||||
ctx.close();
|
||||
p.addLast(new JsonRpcServerHandler(dispatcher));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -10,36 +10,16 @@ import io.netty.channel.ChannelInitializer;
|
|||
import io.netty.channel.ChannelPipeline;
|
||||
import io.netty.channel.socket.SocketChannel;
|
||||
import io.netty.handler.codec.http.HttpServerCodec;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.ChannelFutureListener;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.http.DefaultFullHttpResponse;
|
||||
import io.netty.handler.codec.http.FullHttpResponse;
|
||||
import io.netty.handler.codec.http.HttpRequest;
|
||||
import io.netty.handler.codec.http.multipart.HttpPostStandardRequestDecoder;
|
||||
import io.netty.handler.codec.http.multipart.DefaultHttpDataFactory;
|
||||
import io.netty.handler.codec.http.HttpObject;
|
||||
import io.netty.channel.SimpleChannelInboundHandler;
|
||||
import io.netty.handler.codec.http.HttpMethod;
|
||||
import io.netty.handler.codec.http.HttpContent;
|
||||
import io.netty.handler.codec.http.LastHttpContent;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.util.CharsetUtil;
|
||||
import io.netty.handler.codec.http.HttpVersion;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import org.ethereum.android.jsonrpc.light.whisper.FilterManager;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import io.netty.handler.codec.http.HttpHeaders;
|
||||
import static io.netty.handler.codec.http.HttpHeaders.Names.*;
|
||||
import org.ethereum.android.jsonrpc.light.method.*;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.ethereum.android.jsonrpc.*;
|
||||
|
||||
|
||||
public final class JsonRpcServer extends org.ethereum.android.jsonrpc.JsonRpcServer{
|
||||
|
||||
|
@ -123,82 +103,7 @@ public final class JsonRpcServer extends org.ethereum.android.jsonrpc.JsonRpcSer
|
|||
public void initChannel(SocketChannel ch) {
|
||||
ChannelPipeline p = ch.pipeline();
|
||||
p.addLast(new HttpServerCodec());
|
||||
p.addLast(new JsonRpcServerHandler());
|
||||
}
|
||||
}
|
||||
|
||||
class JsonRpcServerHandler extends SimpleChannelInboundHandler<HttpObject> {
|
||||
|
||||
private HttpRequest request;
|
||||
private final StringBuilder responseContent = new StringBuilder();
|
||||
private HttpPostStandardRequestDecoder decoder;
|
||||
private String postData;
|
||||
|
||||
@Override
|
||||
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
|
||||
if (decoder != null) {
|
||||
decoder.destroy();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception {
|
||||
if (msg instanceof HttpRequest) {
|
||||
HttpRequest req = this.request = (HttpRequest) msg;
|
||||
if (!req.getUri().equals("/") || !request.getMethod().equals(HttpMethod.POST)) {
|
||||
responseContent.append("Hi, how are you?!!");
|
||||
return;
|
||||
} else {
|
||||
decoder = new HttpPostStandardRequestDecoder(new DefaultHttpDataFactory(false), req);
|
||||
postData = "";
|
||||
}
|
||||
}
|
||||
|
||||
if (decoder != null) {
|
||||
if (msg instanceof HttpContent) {
|
||||
HttpContent chunk = (HttpContent) msg;
|
||||
decoder.offer(chunk);
|
||||
postData += chunk.content().toString(0, chunk.content().capacity(), CharsetUtil.UTF_8);
|
||||
|
||||
if (chunk instanceof LastHttpContent) {
|
||||
JSONRPC2Request req = JSONRPC2Request.parse(postData);
|
||||
JSONRPC2Response resp = dispatcher.process(req, null);
|
||||
responseContent.append(resp);
|
||||
writeResponse(ctx);
|
||||
request = null;
|
||||
decoder.destroy();
|
||||
decoder = null;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
writeResponse(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeResponse(ChannelHandlerContext ctx) {
|
||||
ByteBuf buf = Unpooled.copiedBuffer(responseContent.toString(), CharsetUtil.UTF_8);
|
||||
responseContent.setLength(0);
|
||||
|
||||
boolean close = HttpHeaders.Values.CLOSE.equalsIgnoreCase(request.headers().get(CONNECTION))
|
||||
|| request.getProtocolVersion().equals(HttpVersion.HTTP_1_0)
|
||||
&& !HttpHeaders.Values.KEEP_ALIVE.equalsIgnoreCase(request.headers().get(CONNECTION));
|
||||
FullHttpResponse response = new DefaultFullHttpResponse(
|
||||
HttpVersion.HTTP_1_1, HttpResponseStatus.OK, buf);
|
||||
response.headers().set(CONTENT_TYPE, "text/plain; charset=UTF-8");
|
||||
|
||||
if (!close) {
|
||||
response.headers().set(CONTENT_LENGTH, buf.readableBytes());
|
||||
}
|
||||
|
||||
ChannelFuture future = ctx.writeAndFlush(response);
|
||||
if (close) {
|
||||
future.addListener(ChannelFutureListener.CLOSE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
|
||||
cause.printStackTrace();
|
||||
ctx.close();
|
||||
p.addLast(new JsonRpcServerHandler(dispatcher));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -104,8 +104,7 @@ public abstract class JsonRpcServerMethod implements RequestHandler {
|
|||
to = jsToAddress((String) obj.get("to"));
|
||||
}
|
||||
|
||||
// default - from ethereumj-studio
|
||||
BigInteger gasPrice = SZABO.value().multiply(BigInteger.TEN);
|
||||
BigInteger gasPrice = getGasPrice();
|
||||
if (obj.containsKey("gasPrice") && !((String)obj.get("gasPrice")).equals("")) {
|
||||
gasPrice = jsToBigInteger((String) obj.get("gasPrice"));
|
||||
}
|
||||
|
@ -188,7 +187,7 @@ public abstract class JsonRpcServerMethod implements RequestHandler {
|
|||
return BigInteger.ZERO;
|
||||
} else {
|
||||
JSONObject block = (JSONObject)res.getResult();
|
||||
return jsToBigInteger((String)block.get("gasLimit")).add(jsToBigInteger((String)block.get("gasUsed")).negate());
|
||||
return jsToBigInteger((String)block.get("gasLimit")).add(jsToBigInteger((String) block.get("gasUsed")).negate());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -205,4 +204,15 @@ public abstract class JsonRpcServerMethod implements RequestHandler {
|
|||
}
|
||||
}
|
||||
|
||||
protected BigInteger getGasPrice() {
|
||||
ArrayList<Object> params = new ArrayList<Object>();
|
||||
JSONRPC2Request req = new JSONRPC2Request("eth_gasPrice", params, 1000);
|
||||
JSONRPC2Response res = getRemoteData(req);
|
||||
if (res == null || !res.indicatesSuccess()) {
|
||||
return BigInteger.ZERO;
|
||||
} else {
|
||||
return jsToBigInteger(res.getResult().toString());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -117,6 +117,7 @@ public class ServiceConnector {
|
|||
|
||||
if (serviceConnection != null) {
|
||||
Intent intent = new Intent(context, serviceClass);
|
||||
context.getApplicationContext().startService(intent);
|
||||
return context.getApplicationContext().bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
|
||||
} else {
|
||||
return false;
|
||||
|
@ -129,6 +130,10 @@ public class ServiceConnector {
|
|||
if (isBound && serviceConnection != null) {
|
||||
context.getApplicationContext().unbindService(serviceConnection);
|
||||
isBound = false;
|
||||
/*
|
||||
Intent intent = new Intent(context, serviceClass);
|
||||
context.getApplicationContext().stopService(intent);
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue