Package center.app.common

Source Code of center.app.common.HTTPXResponseProcessor$XMLHttpHandler

package center.app.common;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLParameters;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;

import org.w3c.dom.Element;

import com.sun.net.httpserver.Headers;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
import com.sun.net.httpserver.HttpsConfigurator;
import com.sun.net.httpserver.HttpsParameters;
import com.sun.net.httpserver.HttpsServer;

import ru.vassaev.core.base.Null;
import ru.vassaev.core.container.ApplicationManager;
import ru.vassaev.core.exception.SysException;
import ru.vassaev.core.exception.SysRuntimeException;
import ru.vassaev.core.io.OutputByteBuffer;
import ru.vassaev.core.thread.PoolThread;
import ru.vassaev.core.thread.Process;
import ru.vassaev.core.util.Strings;
import ru.vassaev.core.xml.XMLFileWaiter;
import center.task.AProcessor;
import center.task.CalculateException;
import center.task.Context;
import center.task.State;
import center.task.TaskException;
import center.task.TypeOfState;
import center.task.prm.IDependentParam;

/**
* Процессор обработки http запросов
* @author Vassaev A.V.
* @version 1.0 29/10/2012
*/
public class HTTPXResponseProcessor extends AProcessor {

  private SSLParameters sslp = null;
  private boolean https = false;
  private HttpServer server = null;
  private Integer port;
  private String story_file = null;
  private char[] story_pwd = null;
  private char[] key_pwd = null;
  private String path = null;
  private PoolThread executor = null;

  public void paramsValidateAndPrepare(Context cntx) throws SysException {
    port = Strings.parseInteger(cntx.getPrmString("port"));
    if (port == null)
      throw new SysException("Parameter port isn't set");
    https = Strings.parseBooleanNvl(cntx.getPrmString("https"), false);
    if (https) {
      story_file = cntx.getPrmString("story_file");
      if (story_file == null)
        throw new SysException("Parameter story_file isn't set");
      if (File.separatorChar != '\\')
        story_file = story_file.replace('\\', File.separatorChar);
      if (File.separatorChar != '/')
        story_file = story_file.replace('/', File.separatorChar);
      File sf = new File(story_file);
      try {
        story_file = sf.getCanonicalPath();
      } catch (IOException e) {
        throw new SysException(e);
      }
      String story_pwd = cntx.getPrmString("story_pwd");
      if (story_pwd == null)
        throw new SysException("Parameter story_pwd isn't set");
      this.story_pwd = story_pwd.toCharArray();
      String key_pwd = cntx.getPrmString("key_pwd");
      if (key_pwd == null)
        throw new SysException("Parameter key_pwd isn't set");
      this.key_pwd = key_pwd.toCharArray();
    }
    path = cntx.getPrmString("path");
    if (path == null)
      path = "/";
    String poolProcessName = cntx.getPrmString("process_pool");
    if (Null.equ(poolProcessName))
      throw new SysException("Parameter process_pool isn't set");
    executor = (PoolThread) ApplicationManager.getPoolByName(poolProcessName, Process.class);
  }
  private Thread main_thread;
  public State process(Context cntx) throws TaskException, SysException, InterruptedException {
    paramsValidateAndPrepare(cntx);
    main_thread = Process.currentProcess().getParent();
    try {
      //*
      if (https)
        try {
          server = HttpsServer.create(new InetSocketAddress(port), 0);
          HttpsServer ss = (HttpsServer) server;

          // Получить экземпляр хранилища ключей.
          KeyStore keyStore = KeyStore.getInstance("JKS");
          FileInputStream fis = new FileInputStream(story_file);
          keyStore.load(fis, story_pwd);

          // Получить диспетчеры ключей базовой реализации для заданного хранилища ключей.
          KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
          keyManagerFactory.init(keyStore, key_pwd);
          KeyManager[] keyManagers = keyManagerFactory.getKeyManagers();

          // Получить доверенные диспетчеры базовой реализации.
          TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("SunX509");
          trustManagerFactory.init(keyStore);
          TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
          // Получить защищенное случайное число.
          SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG", "SUN");

          // Создание SSL контекста
          SSLContext sslContext = SSLContext.getInstance("SSLv3");
          sslContext.init(keyManagers, trustManagers, secureRandom);

          sslp = sslContext.getSupportedSSLParameters();
          boolean needClientAuth = Strings.parseBoolean(cntx.getPrmNvl("needClientAuth", "false"));
          sslp.setNeedClientAuth(needClientAuth);
          boolean wantClientAuth = Strings.parseBoolean(cntx.getPrmNvl("wantClientAuth", "false"));
          sslp.setWantClientAuth(wantClientAuth);

          HttpsConfigurator conf = new HttpsConfigurator(sslContext) {
            public void configure(HttpsParameters params) {
              params.setSSLParameters(sslp);
            }
          };

          ss.setHttpsConfigurator(conf);
          System.setProperty("javax.net.ssl.trustStore", story_file);
          System.setProperty("javax.net.ssl.keyStore", story_file);
          String trustStore = System.getProperty("javax.net.ssl.trustStore");
          if (trustStore == null)
            System.out.println("javax.net.ssl.trustStore is not defined");
          else
            System.out.println("javax.net.ssl.trustStore = " + trustStore);
          String keyStore1 = System.getProperty("javax.net.ssl.keyStore");
          if (keyStore1 == null)
            System.out.println("javax.net.ssl.keyStore is not defined");
          else
            System.out.println("javax.net.ssl.keyStore = " + keyStore1);
        } catch (NoSuchProviderException e) {
          throw new TaskException(State.DONE_ERR, e);
        } catch (NoSuchAlgorithmException e) {
          throw new TaskException(State.DONE_ERR, e);
        } catch (KeyManagementException e) {
          throw new TaskException(State.DONE_ERR, e);
        } catch (CertificateException e) {
          throw new TaskException(State.DONE_ERR, e);
        } catch (UnrecoverableKeyException e) {
          throw new TaskException(State.DONE_ERR, e);
        } catch (KeyStoreException e) {
          throw new TaskException(State.DONE_ERR, e);
        }
      else
        server = HttpServer.create(new InetSocketAddress(port), 0);
      server.createContext(path, new XMLHttpHandler(cntx));
      server.setExecutor(executor);
      server.start();

      Process prc = Process.currentProcess();
      while (true) {
        try {
          if (prc.isWillBreak())
            return State.BROKEN;
          State st = cntx.ta.getState(cntx.id_task);
          if (st.getType().equals(TypeOfState.LAST))
            return st;
          if (st.equals(State.BREAKING))
            return State.BROKEN;
        } catch (SysException ex) {
          ex.printStackTrace();
        }
        Thread.sleep(2000);//!!!
      }
    } catch (IOException e) {
      throw new TaskException(State.DONE_ERR, e);
    } catch (InterruptedException e) {
      throw new TaskException(State.DONE_ERR, e);
    } finally {
      if (server != null)
        server.stop(0);
    }
  }

  public final class XMLHttpHandler implements HttpHandler {
    private void setPrms(Process cp, Map<String, Object> prms, String key, Object value) {
      cp.regResourceName(value, "msg." + key);
      prms.put(key, value);
      System.out.println("msg." + key + " = " + value);
    }
    private Context cntx;
    public XMLHttpHandler(Context cntx) {
      this.cntx = cntx;
    }

    public void handle(HttpExchange httpExchange) throws IOException {
      Process.currentProcess().setParent(main_thread);
      try {
        InetSocketAddress ra = httpExchange.getRemoteAddress();
        Process cp = Process.currentProcess();
        Map<String, Object> prms = new HashMap<String, Object>();

        setPrms(cp, prms, "protocol", httpExchange.getProtocol());
        setPrms(cp, prms, "method", httpExchange.getRequestMethod());
        //setPrms(cp, prms, "remote.hostName", ra.getHostName());
        setPrms(cp, prms, "remote.port", ra.getPort());
        setPrms(cp, prms, "remote.ip", ra.getAddress().getHostAddress());
        setPrms(cp, prms, "query.path", httpExchange.getRequestURI().getPath());
        String query = httpExchange.getRequestURI().getQuery();
        if (query != null) {
          String[] eqs = Strings.parseXVSLine(query, '/', '&');
          for (int i = 0; i < eqs.length; i++) {
            String eq = eqs[i];
            int j = eq.indexOf('=');
            if (j >= 0)
              setPrms(cp, prms, "get." + eq.substring(0, j), eq.substring(j + 1));
             
          }
          setPrms(cp, prms, "query", query);
        }
        String ct = null;
        for (Map.Entry<String, List<String>> e : httpExchange.getRequestHeaders().entrySet()) {
          Object v = e.getValue();
          String k = e.getKey();
          if ("Content-type".equals(k))
            ct = v.toString();
          setPrms(cp, prms, "hdrs." + k, v.toString());
        }

        InputStream is = httpExchange.getRequestBody();
        try {
          OutputByteBuffer obb = Process.getByteBuffer(8000, is);
          setPrms(cp, prms, "body", obb);
          if ("POST".equals(httpExchange.getRequestMethod()) &&
              ct != null &&
              ct.indexOf("application/x-www-form-urlencoded") >= 0) {
            String enc;
            try {
              enc = cntx.getPrmNvl("request.encoding", "UTF-8");
              if (enc == null || enc.trim().length() == 0)
                enc = "UTF-8";
            } catch (SysException e2) {
              enc = "UTF-8";
            }
            StringBuffer sb = Strings.getStringBuffer(obb.getIS(), enc);
            setPrms(cp, prms, "postquery", sb);

            String[] eqs = Strings.parseXVSLine(sb.toString(), '/', '&');
            for (String eq : eqs) {
              int j = eq.indexOf('=');
              if (j >= 0)
                setPrms(cp, prms, "post." + eq.substring(0, j), eq.substring(j + 1));
            }
          }
        } catch (IOException e) {
          e.printStackTrace();
          throw new SysRuntimeException(e);
        }

        String enc;
        try {
          enc = cntx.getPrmNvl("response.encoding", "UTF-8");
          if (enc == null || enc.trim().length() == 0)
            enc = "UTF-8";
        } catch (SysException e2) {
          enc = "UTF-8";
        }
        try {
          String grp_in = cntx.getPrmNvl("grp_in", "in");
          String grp_out = cntx.getPrmNvl("grp_out", "out");

          setPrms(cp, prms, "out.result", cntx.getPrmByFullName("update"));
         
          Object res = cntx.getPrmByFullName(cntx.getFullName(grp_out, "body"));
          if (res != null) {
            long l = 0;
            if (res instanceof FileInputStream) {
              FileInputStream f = (FileInputStream) res;
              is = f;
              l = f.getChannel().size();
            } else if (res instanceof Element) {
              Element el = (Element)res;
              OutputByteBuffer obb = new OutputByteBuffer(8000);
              XMLFileWaiter.putStream(el, obb, "utf-8");
              try {
                obb.close();
                l = obb.getLength();
              } catch (IOException e1) {
                e1.printStackTrace();
              }
              is = obb.getIS();
            } else if (res instanceof OutputByteBuffer) {
              is = ((OutputByteBuffer)res).getIS();
              l = ((OutputByteBuffer)res).getLength();
            } else if (res instanceof File) {
              File f = (File)res;
              cntx.log(false, "source file name = ", f.getCanonicalPath());
              try {
                is = new FileInputStream(f.getCanonicalPath());
                l = f.length();
              } catch (Throwable e) {
                System.out.println(e.getMessage());
                e.getStackTrace();
                throw new IOException(e);
              }
            } else {
              byte[] buf = res.toString().getBytes(enc);
              is = new ByteArrayInputStream(buf);
              l = buf.length;
            }

            Headers hd = httpExchange.getResponseHeaders();
            hd.put("Content-Type", Arrays.asList("text/plain; charset=" + enc));
            hd.put("Content-Length", Arrays.asList(Long.toString(l)));
            String h = cntx.getFullName(grp_out, "hdrs.");
            Map<String, Object> result = cntx.getGroupParams(grp_out);
            for (Map.Entry<String, Object> e : result.entrySet()) {
              String k = e.getKey();
              if (k.indexOf(h) == 0) {
                k = k.substring(h.length());
                Object o = e.getValue();
                String v;
                if (o != null && o instanceof IDependentParam) {
                  IDependentParam idp = (IDependentParam)o;
                  try {
                    o = idp.getValue(cntx);
                  } catch (CalculateException e1) {
                    e1.printStackTrace();
                  }
                }
                if (o == null)
                  continue;
                v = Strings.getString(o);
                hd.put(k, Arrays.asList(v));
              }
            }
            httpExchange.sendResponseHeaders(200, l);
            OutputStream w = httpExchange.getResponseBody();
            byte[] buf = new byte[8 * 1024];
            int len;
            while ((len = is.read(buf)) > 0) {
              w.write(buf, 0, len);
            }
            is.close();
            w.close();
          } else {
            httpExchange.sendResponseHeaders(503, 0);
          }
        } catch (SysException e) {
          e.printStackTrace();
        } finally {
          try {
            cntx.getPrmByFullName("finish", 1000);
          } catch (SysException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
          }//!!!
        }
      } finally {
        httpExchange.close();
      }
    }
  }

  @Override
  public Set<String> dependentOn() {
    // TODO Auto-generated method stub
    return null;
  }

  @Override
  public Set<String> loopDependentOn() {
    // TODO Auto-generated method stub
    return null;
  }


}
TOP

Related Classes of center.app.common.HTTPXResponseProcessor$XMLHttpHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.