Package nginx.clojure.net

Source Code of nginx.clojure.net.SimpleHandler4TestNginxClojureAsynChannel

package nginx.clojure.net;

import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.CharsetEncoder;
import java.util.Map;

import nginx.clojure.ChannelListener;
import nginx.clojure.NginxClojureRT;
import nginx.clojure.NginxHttpServerChannel;
import nginx.clojure.NginxRequest;
import nginx.clojure.java.ArrayMap;
import nginx.clojure.java.NginxJavaRingHandler;
import nginx.clojure.logger.TinyLogService;
import nginx.clojure.logger.TinyLogService.MsgType;
import nginx.clojure.net.NginxClojureAsynChannel.CompletionListener;

public class SimpleHandler4TestNginxClojureAsynChannel implements NginxJavaRingHandler {

  TinyLogService log = new TinyLogService(MsgType.debug, System.err, System.err);
 
  private void handleError(long status, NginxClojureAsynChannel upstream, NginxHttpServerChannel downstream) {
    upstream.close();
    if (downstream.getContext() == "sent") {
      downstream.send("\r\n************Error Happended************\r\n"+upstream.buildError(status), true, true);
      log.warn("error happened: %s", upstream.buildError(status));
    }else {
      downstream.sendResponse(new Object[] {500, ArrayMap.create("Content-Type", "text/html") , upstream.buildError(status)});
    }
  }
 
  private boolean checkDownStreamClosed(NginxClojureAsynChannel upstream, NginxHttpServerChannel downstream) {
    if (downstream.isClosed()) {
      log.info("downstream is closed!");
      upstream.close();
      return true;
    }
    return false;
  }
 
  @Override
  public Object[] invoke(Map<String, Object> request) {
    NginxRequest req = (NginxRequest) request;
    NginxHttpServerChannel downstream = req.handler().hijack(req, true);
    downstream.addListener(downstream, new ChannelListener<NginxHttpServerChannel>() {

      @Override
      public void onClose(NginxHttpServerChannel data) {
        log.info("***downstream closed!");
      }

      @Override
      public void onConnect(long status, NginxHttpServerChannel data) {
      }
    });
    final NginxClojureAsynChannel upstream = new NginxClojureAsynChannel();
    String url = "mirror.bit.edu.cn:80";
    upstream.setTimeout(5000, 20000, 20000);
    upstream.connect(url, downstream, new CompletionListener<NginxHttpServerChannel>() {
      @Override
      public void onError(long code, NginxHttpServerChannel downstream) {
        log.info("connected error : " + code);
        handleError(code, upstream, downstream);
      }
      @Override
      public void onDone(long status, final NginxHttpServerChannel downstream) {
        log.info("connected successfully : " + status);
        if (checkDownStreamClosed(upstream, downstream)) {
          return;
        }
        CharsetEncoder encoder = NginxClojureRT.DEFAULT_ENCODING.newEncoder();
        ByteBuffer getCommand;
        try {
          getCommand = encoder.encode(CharBuffer
              .wrap("GET /apache/httpcomponents/httpclient/RELEASE_NOTES-4.3.x.txt HTTP/1.1\r\n"
                  + "User-Agent: nginx-clojure/0.2.5\r\n"
                  + "Host: mirror.bit.edu.cn\r\nAccept: */*\r\n"
                  + "Connection: close\r\n\r\n"));
          upstream.write(getCommand, upstream, new CompletionListener<NginxClojureAsynChannel>() {
            public void onError(long code, NginxClojureAsynChannel attachment) {
              attachment.close();
              handleError(code, upstream, downstream);
            };
            @Override
            public void onDone(long status, final NginxClojureAsynChannel upstream) {
              log.info("write onDone status : " + status);
              upstream.getAsynSocket().shutdown(NginxClojureAsynSocket.NGX_HTTP_CLOJURE_SOCKET_SHUTDOWN_SOFT_WRITE);
              if (checkDownStreamClosed(upstream, downstream)) {
                return;
              }
              ByteBuffer buffer = ByteBuffer.allocateDirect(1024*4);
              CompletionListener<ByteBuffer> upstreamListener = new CompletionListener<ByteBuffer>() {
                public void onError(long code, ByteBuffer attachment) {
                  handleError(code, upstream, downstream);
                };
                @Override
                public void onDone(long status, ByteBuffer buffer) {
                  log.info("read onDone status : " + status);
                  if (checkDownStreamClosed(upstream, downstream)) {
                    return;
                  }
                  boolean end = buffer.hasRemaining() || status == 0;
                  buffer.flip();
                  downstream.setContext("sent");//have sent something
                  downstream.send(buffer, true, end);
                  buffer.clear();
                  if (!end) {
                    upstream.read(buffer, buffer, this);
                  }else {
                    upstream.close();
                  }
                }
              };
              upstream.read(buffer, buffer, upstreamListener);
            }

          });
        } catch (CharacterCodingException e) {// should not happend!
        }
         
      }
    });
    return null;
  }

}
TOP

Related Classes of nginx.clojure.net.SimpleHandler4TestNginxClojureAsynChannel

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.