Package center.app.common

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

package center.app.common;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
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.TimeoutInputStream;
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.NewTaskInfo;
import center.task.State;
import center.task.TaskException;
import center.task.TypeOfState;
import center.task.prm.IDependentParam;

/**
* Процессор обработки http запросов
*
* @author Vassaev A.V.
* @version 1.1 13/03/2009
*/
public class HTTPResponseProcessor extends AProcessor {

  // private static final int THREADS_AMOUNT = 20;
  // private static final int MAX_THREADS_AMOUNT = 2 * THREADS_AMOUNT;
  // private static final int QUEUE_CAPACITY = 1024;

  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();
    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()); !!!
        // TODO
        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;
        int cl = 0;
        for (Map.Entry<String, List<String>> e : httpExchange
            .getRequestHeaders().entrySet()) {
          List<String> v = e.getValue();
          String k = e.getKey();
          if ("Content-type".equals(k))
            ct = v.toString();
          else if ("Content-length".equals(k))
            cl = Strings.parseInteger(v.get(0));
          setPrms(cp, prms, "hdrs." + k, v.toString());
        }
        InputStream is = httpExchange.getRequestBody();
        Process tprc = executor.occupyOrNew();
        OutputByteBuffer obb = null;
        try {
          long read_wait = Strings.parseIntegerNvl(
              cntx.getPrmByFullName("read_wait"), 10000);// !!!
          TimeoutInputStream tis = new TimeoutInputStream(tprc);
          tis.setTimeout(read_wait);
          tis.setLimitRead(cl);
          tis.setCircleBufferSize(50);
          tis.startReadSource(is);
          obb = (cl <= 0) ? Process.getByteBuffer(8000, tis)
              : Process.getByteBuffer(8000, tis, cl);
        } catch (SysException e) {
          e.printStackTrace();
          tprc.interrupt();
          throw new SysRuntimeException(e);
        } finally {
          executor.free(tprc);
        }
        try {
          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);
            try {
              boolean parse_postquery = cntx.getPrmNvl(
                  "parse_postquery", false);
              if (parse_postquery) {
                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 (SysException e1) {
              // TODO Auto-generated catch block
              e1.printStackTrace();
            }
          }
        } 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";
        }

        // if (https) {
        // HttpsServer srv = (HttpsServer)
        // httpExchange.getHttpContext().getServer();
        // SSLContext ssl = srv.getHttpsConfigurator().getSSLContext();
        // }
        NewTaskInfo nti = getChild();
        Context cntx_child = null;
        try {
          String grp_in = cntx.getPrmString("grp_in");
          if (grp_in == null)
            grp_in = "in";
          String grp_out = cntx.getPrmString("grp_out");
          if (grp_out == null)
            grp_out = "out";

          if (!Strings.parseBooleanNvl(
              cntx.getPrmString("save-in-body"), true)) {
            prms.remove("body");
          }
          cntx_child = nti.createAndReadyTask(cntx.ta, cntx,
              cntx.id_subject, grp_in, prms);
          Object res = null;
          if ((cntx_child == null) || (cntx_child.id_task <= 0)) {
            res = cntx_child
                .getPrmByFullName(((grp_out == null) || (grp_out
                    .length() == 0)) ? "body" : grp_out
                    + "/body");
            if (res == null) {
              Headers hd = httpExchange.getResponseHeaders();
              hd.put("Content-Type",
                  Arrays.asList("text/plain; charset=" + enc));
              httpExchange.sendResponseHeaders(503, 0);
              OutputStream w = httpExchange.getResponseBody();
              w.write("Обработчик не выбран".getBytes(enc));
              w.close();
              return;
            }
          } else {
            Process.currentProcess().regResourceName(
                cntx_child.id_task, "child.id");
            long wait = Strings.parseIntegerNvl(
                cntx.getPrmByFullName("wait"), 30000);// !!!
            cntx.log(false, "Start waiting (", wait, ")");
            cntx_child.ta.waitFinished(cntx_child.id_subject,
                cntx_child.id_task, wait);
            cntx.log(false, "End waiting");
            res = cntx_child
                .getPrmByFullName(((grp_out == null) || (grp_out
                    .length() == 0)) ? "body" : grp_out
                    + "/body");
          }

          if (res != null) {
            Map<String, Object> result = cntx_child
                .getGroupParams(grp_out);
            long l = 0;
            if (res instanceof FileInputStream) {
              is = (FileInputStream) res;
              l = ((FileInputStream) is).getChannel().size();
            } else if (res instanceof Element) {
              Element el = (Element) res;
              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());
              is = new FileInputStream(f.getCanonicalPath());
              l = f.length();
            } else if (res instanceof InputStreamReader) {
              InputStreamReader f = (InputStreamReader) res;
              File x = File.createTempFile("dbms", "clob");
              FileWriter w = new FileWriter(x);
              char[] buf = new char[8 * 1024];
              int len;
              while ((len = f.read(buf)) > 0) {
                w.write(buf, 0, len);
              }
              w.flush();
              w.close();
              is = new FileInputStream(x);
              l = ((FileInputStream) is).getChannel().size();
            } 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.");
            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_child);
                  } 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();
          if (cntx_child != null)
            try {
              cntx_child.ta.setState(cntx_child.id_subject,
                  cntx_child.id_task, State.DONE_ERR);
            } catch (SysException e1) {
              e1.printStackTrace(); // To change body of catch
                          // statement use File |
                          // Settings | File
                          // Templates.
            }
          return;
        } 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.HTTPResponseProcessor$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.