/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/ProxyConnection.java

https://bitbucket.org/beginnerjyh/jetty.project · Java · 156 lines · 121 code · 18 blank · 17 comment · 4 complexity · 5455bb4d7dd0207dc46c54d199fe98e9 MD5 · raw file

  1. //
  2. // ========================================================================
  3. // Copyright (c) 1995-2013 Mort Bay Consulting Pty. Ltd.
  4. // ------------------------------------------------------------------------
  5. // All rights reserved. This program and the accompanying materials
  6. // are made available under the terms of the Eclipse Public License v1.0
  7. // and Apache License v2.0 which accompanies this distribution.
  8. //
  9. // The Eclipse Public License is available at
  10. // http://www.eclipse.org/legal/epl-v10.html
  11. //
  12. // The Apache License v2.0 is available at
  13. // http://www.opensource.org/licenses/apache2.0.php
  14. //
  15. // You may elect to redistribute this code under either of these licenses.
  16. // ========================================================================
  17. //
  18. package org.eclipse.jetty.proxy;
  19. import java.io.IOException;
  20. import java.nio.ByteBuffer;
  21. import java.util.concurrent.ConcurrentMap;
  22. import java.util.concurrent.Executor;
  23. import org.eclipse.jetty.io.AbstractConnection;
  24. import org.eclipse.jetty.io.ByteBufferPool;
  25. import org.eclipse.jetty.io.Connection;
  26. import org.eclipse.jetty.io.EndPoint;
  27. import org.eclipse.jetty.util.Callback;
  28. import org.eclipse.jetty.util.ForkInvoker;
  29. import org.eclipse.jetty.util.log.Logger;
  30. public abstract class ProxyConnection extends AbstractConnection
  31. {
  32. protected static final Logger LOG = ConnectHandler.LOG;
  33. private final ForkInvoker<Void> invoker = new ProxyForkInvoker();
  34. private final ByteBufferPool bufferPool;
  35. private final ConcurrentMap<String, Object> context;
  36. private Connection connection;
  37. protected ProxyConnection(EndPoint endp, Executor executor, ByteBufferPool bufferPool, ConcurrentMap<String, Object> context)
  38. {
  39. super(endp, executor);
  40. this.bufferPool = bufferPool;
  41. this.context = context;
  42. }
  43. public ByteBufferPool getByteBufferPool()
  44. {
  45. return bufferPool;
  46. }
  47. public ConcurrentMap<String, Object> getContext()
  48. {
  49. return context;
  50. }
  51. public Connection getConnection()
  52. {
  53. return connection;
  54. }
  55. public void setConnection(Connection connection)
  56. {
  57. this.connection = connection;
  58. }
  59. @Override
  60. public void onFillable()
  61. {
  62. final ByteBuffer buffer = getByteBufferPool().acquire(getInputBufferSize(), true);
  63. try
  64. {
  65. final int filled = read(getEndPoint(), buffer);
  66. LOG.debug("{} filled {} bytes", this, filled);
  67. if (filled > 0)
  68. {
  69. write(getConnection().getEndPoint(), buffer, new Callback()
  70. {
  71. @Override
  72. public void succeeded()
  73. {
  74. LOG.debug("{} wrote {} bytes", this, filled);
  75. bufferPool.release(buffer);
  76. invoker.invoke(null);
  77. }
  78. @Override
  79. public void failed(Throwable x)
  80. {
  81. LOG.debug(this + " failed to write " + filled + " bytes", x);
  82. bufferPool.release(buffer);
  83. connection.close();
  84. }
  85. });
  86. }
  87. else if (filled == 0)
  88. {
  89. bufferPool.release(buffer);
  90. fillInterested();
  91. }
  92. else
  93. {
  94. bufferPool.release(buffer);
  95. connection.getEndPoint().shutdownOutput();
  96. }
  97. }
  98. catch (IOException x)
  99. {
  100. LOG.debug(this + " could not fill", x);
  101. bufferPool.release(buffer);
  102. close();
  103. connection.close();
  104. }
  105. }
  106. protected abstract int read(EndPoint endPoint, ByteBuffer buffer) throws IOException;
  107. protected abstract void write(EndPoint endPoint, ByteBuffer buffer, Callback callback);
  108. @Override
  109. public String toString()
  110. {
  111. return String.format("%s[l:%d<=>r:%d]",
  112. super.toString(),
  113. getEndPoint().getLocalAddress().getPort(),
  114. getEndPoint().getRemoteAddress().getPort());
  115. }
  116. private class ProxyForkInvoker extends ForkInvoker<Void> implements Runnable
  117. {
  118. private ProxyForkInvoker()
  119. {
  120. super(4);
  121. }
  122. @Override
  123. public void fork(Void arg)
  124. {
  125. getExecutor().execute(this);
  126. }
  127. @Override
  128. public void run()
  129. {
  130. onFillable();
  131. }
  132. @Override
  133. public void call(Void arg)
  134. {
  135. onFillable();
  136. }
  137. }
  138. }