All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.apexes.wsonrpc.server.nano.NanoJsonRpcServer Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (C) 2016, apexes.net. All rights reserved.
 * 
 *        http://www.apexes.net
 * 
 */
package net.apexes.wsonrpc.server.nano;

import net.apexes.wsonrpc.core.JsonRpcEngine;
import net.apexes.wsonrpc.core.JsonRpcLogger;
import net.apexes.wsonrpc.core.ServiceRegistry;
import net.apexes.wsonrpc.core.Transport;
import net.apexes.wsonrpc.json.JsonImplementor;
import net.apexes.wsonrpc.json.support.gson.GsonImplementor;
import net.apexes.wsonrpc.server.PathAcceptor;
import net.apexes.wsonrpc.server.PathAcceptors;
import net.apexes.wsonrpc.server.http.HttpRequestValidator;
import net.apexes.wsonrpc.server.nano.http.IHTTPSession;
import net.apexes.wsonrpc.server.nano.http.NanoHTTPD;
import net.apexes.wsonrpc.server.nano.http.request.Method;
import net.apexes.wsonrpc.server.nano.http.response.Response;
import net.apexes.wsonrpc.server.nano.http.response.Status;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Locale;

/**
 * 
 * @author HeDYn
 *
 */
public class NanoJsonRpcServer extends NanoHTTPD {

    private final PathAcceptor pathAcceptor;
    private final JsonRpcEngine jsonRpcEngine;
    private HttpRequestValidator requestValidator;

    public NanoJsonRpcServer(int port) {
        this(port, PathAcceptors.anyPath());
    }
    
    public NanoJsonRpcServer(int port, PathAcceptor pathAcceptor) {
        this(port, pathAcceptor, GsonImplementor.DEFAULT);
    }

    public NanoJsonRpcServer(int port, PathAcceptor pathAcceptor, JsonImplementor jsonImpl) {
        super(port);
        this.pathAcceptor = pathAcceptor;
        this.jsonRpcEngine = new JsonRpcEngine(jsonImpl);
    }
    
    public ServiceRegistry getServiceRegistry() {
        return jsonRpcEngine.getServiceRegistry();
    }

    public JsonRpcLogger getJsonRpcLogger() {
        return jsonRpcEngine.getJsonRpcLogger();
    }

    public void setJsonRpcLogger(JsonRpcLogger jsonRpcLogger) {
        jsonRpcEngine.setJsonRpcLogger(jsonRpcLogger);
    }

    public HttpRequestValidator getRequestValidator() {
        return requestValidator;
    }

    public void setRequestValidator(HttpRequestValidator requestValidator) {
        this.requestValidator = requestValidator;
    }

    @Override
    public Response serve(IHTTPSession session) {
        if (pathAcceptor.accept(session.getUri())) {
            Method method = session.getMethod();
            if (Method.POST.equals(method)) {
                try {
                    ByteArrayOutputStream out = new ByteArrayOutputStream();
                    session.handleBody(out);
                    byte[] bodyBytes = out.toByteArray();

                    HttpRequestValidator validator = requestValidator;
                    if (validator != null && !validator.validate(key -> getHeader(session, key), bodyBytes)) {
                        return responseStatue(Status.FORBIDDEN);
                    }

                    TransportImpl transport = new TransportImpl();
                    jsonRpcEngine.receiveRequest(bodyBytes, transport, session.getRemoteIpAddress());
                    return Response.newFixedLengthResponse(transport.json);
                } catch (Exception e) {
                    return responseStatue(Status.INTERNAL_ERROR, e.toString());
                }
            }
        }
        return responseStatue(Status.NOT_FOUND);
    }

    private static String getHeader(IHTTPSession session, String key) {
        return session.getHeaders().get(key.toLowerCase(Locale.US));
    }

    /**
     * 
     * @author HeDYn
     *
     */
    private static class TransportImpl implements Transport {

        private String json;

        @Override
        public void sendBinary(byte[] bytes) throws IOException {
            this.json = new String(bytes, StandardCharsets.UTF_8);
        }

    }

    private static Response responseStatue(Status status) {
        return responseStatue(status, status.getDescription());
    }

    private static Response responseStatue(Status status, String message) {
        return Response.newFixedLengthResponse(status, NanoHTTPD.MIME_PLAINTEXT, message);
    }
    
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy