PageRenderTime 44ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/jboss-as-7.1.1.Final/web/src/main/java/org/jboss/as/web/WebConnectorService.java

#
Java | 417 lines | 321 code | 45 blank | 51 comment | 65 complexity | 4501a307f690f345cd6d7ba4eaeff85f MD5 | raw file
Possible License(s): LGPL-2.1, Apache-2.0
  1. /*
  2. * JBoss, Home of Professional Open Source
  3. * Copyright 2010, Red Hat Inc., and individual contributors as indicated
  4. * by the @authors tag. See the copyright.txt in the distribution for a
  5. * full listing of individual contributors.
  6. *
  7. * This is free software; you can redistribute it and/or modify it
  8. * under the terms of the GNU Lesser General Public License as
  9. * published by the Free Software Foundation; either version 2.1 of
  10. * the License, or (at your option) any later version.
  11. *
  12. * This software is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with this software; if not, write to the Free
  19. * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  20. * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  21. */
  22. package org.jboss.as.web;
  23. import static org.jboss.as.web.WebMessages.MESSAGES;
  24. import java.io.IOException;
  25. import java.lang.reflect.Method;
  26. import java.net.InetAddress;
  27. import java.net.InetSocketAddress;
  28. import java.util.HashSet;
  29. import java.util.concurrent.Executor;
  30. import org.apache.catalina.connector.Connector;
  31. import org.apache.coyote.ajp.AjpAprProtocol;
  32. import org.apache.coyote.ajp.AjpProtocol;
  33. import org.apache.coyote.http11.Http11AprProtocol;
  34. import org.jboss.as.network.ManagedBinding;
  35. import org.jboss.as.network.SocketBinding;
  36. import org.jboss.dmr.ModelNode;
  37. import org.jboss.msc.service.Service;
  38. import org.jboss.msc.service.StartContext;
  39. import org.jboss.msc.service.StartException;
  40. import org.jboss.msc.service.StopContext;
  41. import org.jboss.msc.value.InjectedValue;
  42. /**
  43. * Service creating and starting a web connector.
  44. *
  45. * @author Emanuel Muckenhuber
  46. */
  47. class WebConnectorService implements Service<Connector> {
  48. private volatile String protocol = "HTTP/1.1";
  49. private volatile String scheme = "http";
  50. private Boolean enableLookups = null;
  51. private String proxyName = null;
  52. private Integer proxyPort = null;
  53. private Integer redirectPort = null;
  54. private Boolean secure = null;
  55. private Integer maxPostSize = null;
  56. private Integer maxSavePostSize = null;
  57. private Integer maxConnections = null;
  58. private ModelNode ssl;
  59. private ModelNode virtualServers;
  60. private Connector connector;
  61. private final InjectedValue<Executor> executor = new InjectedValue<Executor>();
  62. private final InjectedValue<SocketBinding> binding = new InjectedValue<SocketBinding>();
  63. private final InjectedValue<WebServer> server = new InjectedValue<WebServer>();
  64. public WebConnectorService(String protocol, String scheme) {
  65. if(protocol != null) this.protocol = protocol;
  66. if(scheme != null) this.scheme = scheme;
  67. }
  68. /**
  69. * Start, register and bind the web connector.
  70. *
  71. * @param context the start context
  72. * @throws StartException if the connector cannot be started
  73. */
  74. public synchronized void start(StartContext context) throws StartException {
  75. final SocketBinding binding = this.binding.getValue();
  76. final InetSocketAddress address = binding.getSocketAddress();
  77. final Executor executor = this.executor.getOptionalValue();
  78. try {
  79. // Create connector
  80. final Connector connector = new Connector(protocol);
  81. connector.setPort(address.getPort());
  82. connector.setScheme(scheme);
  83. if(enableLookups != null) connector.setEnableLookups(enableLookups);
  84. if(maxPostSize != null) connector.setMaxPostSize(maxPostSize);
  85. if(maxSavePostSize != null) connector.setMaxSavePostSize(maxSavePostSize);
  86. if(proxyName != null) connector.setProxyName(proxyName);
  87. if(proxyPort != null) connector.setProxyPort(proxyPort);
  88. if(redirectPort != null) connector.setRedirectPort(redirectPort);
  89. if(secure != null) connector.setSecure(secure);
  90. boolean nativeProtocolHandler = false;
  91. if (connector.getProtocolHandler() instanceof Http11AprProtocol
  92. || connector.getProtocolHandler() instanceof AjpAprProtocol) {
  93. nativeProtocolHandler = true;
  94. }
  95. if (executor != null) {
  96. Method m = connector.getProtocolHandler().getClass().getMethod("setExecutor", Executor.class);
  97. m.invoke(connector.getProtocolHandler(), executor);
  98. }
  99. if (address != null && address.getAddress() != null) {
  100. Method m = connector.getProtocolHandler().getClass().getMethod("setAddress", InetAddress.class);
  101. m.invoke(connector.getProtocolHandler(), address.getAddress());
  102. }
  103. if (maxConnections != null) {
  104. try {
  105. Method m = connector.getProtocolHandler().getClass().getMethod("setPollerSize", Integer.TYPE);
  106. m.invoke(connector.getProtocolHandler(), maxConnections);
  107. } catch (NoSuchMethodException e) {
  108. // Not all connectors will have this
  109. }
  110. if (nativeProtocolHandler) {
  111. try {
  112. Method m = connector.getProtocolHandler().getClass().getMethod("setSendfileSize", Integer.TYPE);
  113. m.invoke(connector.getProtocolHandler(), maxConnections);
  114. } catch (NoSuchMethodException e) {
  115. // Not all connectors will have this
  116. }
  117. } else {
  118. Method m = connector.getProtocolHandler().getClass().getMethod("setMaxThreads", Integer.TYPE);
  119. m.invoke(connector.getProtocolHandler(), maxConnections);
  120. }
  121. }
  122. if (virtualServers != null) {
  123. HashSet<String> virtualServersList = new HashSet<String>();
  124. for (final ModelNode virtualServer : virtualServers.asList()) {
  125. virtualServersList.add(virtualServer.asString());
  126. }
  127. connector.setAllowedHosts(virtualServersList);
  128. }
  129. if (ssl != null) {
  130. boolean nativeSSL = false;
  131. if (connector.getProtocolHandler() instanceof Http11AprProtocol) {
  132. nativeSSL = true;
  133. } else if ((connector.getProtocolHandler() instanceof AjpProtocol) || (connector.getProtocolHandler() instanceof AjpAprProtocol)) {
  134. throw new StartException(MESSAGES.noSSLWithNonHTTPConnectors());
  135. }
  136. // Enable SSL
  137. try {
  138. Method m = connector.getProtocolHandler().getClass().getMethod("setSSLEnabled", Boolean.TYPE);
  139. m.invoke(connector.getProtocolHandler(), true);
  140. } catch (NoSuchMethodException e) {
  141. // No SSL support
  142. throw new StartException(MESSAGES.failedSSLConfiguration(), e);
  143. }
  144. if (nativeSSL) {
  145. // OpenSSL configuration
  146. try {
  147. if (ssl.hasDefined(Constants.PASSWORD)) {
  148. Method m = connector.getProtocolHandler().getClass().getMethod("setSSLPassword", String.class);
  149. m.invoke(connector.getProtocolHandler(), ssl.get(Constants.PASSWORD).asString());
  150. }
  151. if (ssl.hasDefined(Constants.CERTIFICATE_KEY_FILE)) {
  152. Method m = connector.getProtocolHandler().getClass().getMethod("setSSLCertificateKeyFile", String.class);
  153. m.invoke(connector.getProtocolHandler(), ssl.get(Constants.CERTIFICATE_KEY_FILE).asString());
  154. }
  155. if (ssl.hasDefined(Constants.CIPHER_SUITE)) {
  156. Method m = connector.getProtocolHandler().getClass().getMethod("setSSLCipherSuite", String.class);
  157. m.invoke(connector.getProtocolHandler(), ssl.get(Constants.CIPHER_SUITE).asString());
  158. }
  159. if (ssl.hasDefined(Constants.PROTOCOL)) {
  160. Method m = connector.getProtocolHandler().getClass().getMethod("setSSLProtocol", String.class);
  161. m.invoke(connector.getProtocolHandler(), ssl.get(Constants.PROTOCOL).asString());
  162. }
  163. if (ssl.hasDefined(Constants.VERIFY_CLIENT)) {
  164. Method m = connector.getProtocolHandler().getClass().getMethod("setSSLVerifyClient", String.class);
  165. m.invoke(connector.getProtocolHandler(), ssl.get(Constants.VERIFY_CLIENT).asString());
  166. }
  167. if (ssl.hasDefined(Constants.VERIFY_DEPTH)) {
  168. Method m = connector.getProtocolHandler().getClass().getMethod("setSSLVerifyDepth", Integer.TYPE);
  169. m.invoke(connector.getProtocolHandler(), ssl.get(Constants.VERIFY_DEPTH).asInt());
  170. }
  171. if (ssl.hasDefined(Constants.CERTIFICATE_FILE)) {
  172. Method m = connector.getProtocolHandler().getClass().getMethod("setSSLCertificateFile", String.class);
  173. m.invoke(connector.getProtocolHandler(), ssl.get(Constants.CERTIFICATE_FILE).asString());
  174. }
  175. if (ssl.hasDefined(Constants.CA_CERTIFICATE_FILE)) {
  176. Method m = connector.getProtocolHandler().getClass().getMethod("setSSLCACertificateFile", String.class);
  177. m.invoke(connector.getProtocolHandler(), ssl.get(Constants.CA_CERTIFICATE_FILE).asString());
  178. }
  179. if (ssl.hasDefined(Constants.CA_REVOCATION_URL)) {
  180. Method m = connector.getProtocolHandler().getClass().getMethod("setSSLCARevocationFile", String.class);
  181. m.invoke(connector.getProtocolHandler(), ssl.get(Constants.CA_REVOCATION_URL).asString());
  182. }
  183. } catch (NoSuchMethodException e) {
  184. throw new StartException(MESSAGES.failedSSLConfiguration(), e);
  185. }
  186. } else {
  187. // JSSE configuration
  188. try {
  189. if (ssl.hasDefined(Constants.KEY_ALIAS)) {
  190. Method m = connector.getProtocolHandler().getClass().getMethod("setKeyAlias", String.class);
  191. m.invoke(connector.getProtocolHandler(), ssl.get(Constants.KEY_ALIAS).asString());
  192. }
  193. if (ssl.hasDefined(Constants.PASSWORD)) {
  194. Method m = connector.getProtocolHandler().getClass().getMethod("setKeypass", String.class);
  195. m.invoke(connector.getProtocolHandler(), ssl.get(Constants.PASSWORD).asString());
  196. }
  197. if (ssl.hasDefined(Constants.CERTIFICATE_KEY_FILE)) {
  198. Method m = connector.getProtocolHandler().getClass().getMethod("setKeystore", String.class);
  199. m.invoke(connector.getProtocolHandler(), ssl.get(Constants.CERTIFICATE_KEY_FILE).asString());
  200. }
  201. if (ssl.hasDefined(Constants.CIPHER_SUITE)) {
  202. Method m = connector.getProtocolHandler().getClass().getMethod("setCiphers", String.class);
  203. m.invoke(connector.getProtocolHandler(), ssl.get(Constants.CIPHER_SUITE).asString());
  204. }
  205. if (ssl.hasDefined(Constants.PROTOCOL)) {
  206. Method m = connector.getProtocolHandler().getClass().getMethod("setProtocols", String.class);
  207. m.invoke(connector.getProtocolHandler(), ssl.get(Constants.PROTOCOL).asString());
  208. }
  209. if (ssl.hasDefined(Constants.VERIFY_CLIENT)) {
  210. Method m = connector.getProtocolHandler().getClass().getMethod("setClientauth", String.class);
  211. m.invoke(connector.getProtocolHandler(), ssl.get(Constants.VERIFY_CLIENT).asString());
  212. }
  213. if (ssl.hasDefined(Constants.SESSION_CACHE_SIZE)) {
  214. Method m = connector.getProtocolHandler().getClass().getMethod("setAttribute", String.class, Object.class);
  215. m.invoke(connector.getProtocolHandler(), "sessionCacheSize", ssl.get(Constants.SESSION_CACHE_SIZE).asString());
  216. }
  217. if (ssl.hasDefined(Constants.SESSION_TIMEOUT)) {
  218. Method m = connector.getProtocolHandler().getClass().getMethod("setAttribute", String.class, Object.class);
  219. m.invoke(connector.getProtocolHandler(), "sessionCacheTimeout", ssl.get(Constants.SESSION_TIMEOUT).asString());
  220. }
  221. /* possible attributes that apply to ssl socket factory
  222. keystoreType -> PKCS12
  223. keystore -> path/to/keystore.p12
  224. keypass -> key password
  225. truststorePass -> trustPassword
  226. truststoreFile -> path/to/truststore.jks
  227. truststoreType -> JKS
  228. */
  229. if (ssl.hasDefined(Constants.CA_CERTIFICATE_FILE)) {
  230. Method m = connector.getProtocolHandler().getClass().getMethod("setAttribute", String.class, Object.class);
  231. m.invoke(connector.getProtocolHandler(), "truststoreFile", ssl.get(Constants.CA_CERTIFICATE_FILE).asString());
  232. }
  233. if (ssl.hasDefined(Constants.CA_CERTIFICATE_PASSWORD)) {
  234. Method m = connector.getProtocolHandler().getClass().getMethod("setAttribute", String.class, Object.class);
  235. m.invoke(connector.getProtocolHandler(), "truststorePass",ssl.get(Constants.CA_CERTIFICATE_PASSWORD).asString());
  236. }
  237. if (ssl.hasDefined(Constants.TRUSTSTORE_TYPE)) {
  238. Method m = connector.getProtocolHandler().getClass().getMethod("setAttribute", String.class, Object.class);
  239. m.invoke(connector.getProtocolHandler(), "truststoreType",ssl.get(Constants.TRUSTSTORE_TYPE).asString());
  240. }
  241. if (ssl.hasDefined(Constants.KEYSTORE_TYPE)) {
  242. Method m = connector.getProtocolHandler().getClass().getMethod("setKeytype", String.class);
  243. m.invoke(connector.getProtocolHandler(), ssl.get(Constants.KEYSTORE_TYPE).asString());
  244. }
  245. if (ssl.hasDefined(Constants.CA_REVOCATION_URL)) {
  246. Method m = connector.getProtocolHandler().getClass().getMethod("setAttribute", String.class, Object.class);
  247. m.invoke(connector.getProtocolHandler(), "crlFile", ssl.get(Constants.CA_REVOCATION_URL).asString());
  248. }
  249. } catch (NoSuchMethodException e) {
  250. throw new StartException(MESSAGES.failedSSLConfiguration(), e);
  251. }
  252. }
  253. }
  254. getWebServer().addConnector(connector);
  255. connector.init();
  256. connector.start();
  257. this.connector = connector;
  258. } catch (Exception e) {
  259. throw new StartException(MESSAGES.connectorStartError(), e);
  260. }
  261. // Register the binding after the connector is started
  262. binding.getSocketBindings().getNamedRegistry().registerBinding(new ConnectorBinding(binding));
  263. }
  264. /** {@inheritDoc} */
  265. public synchronized void stop(StopContext context) {
  266. final SocketBinding binding = this.binding.getValue();
  267. binding.getSocketBindings().getNamedRegistry().unregisterBinding(binding.getName());
  268. final Connector connector = this.connector;
  269. try {
  270. connector.pause();
  271. } catch (Exception e) {
  272. }
  273. try {
  274. connector.stop();
  275. } catch (Exception e) {
  276. }
  277. getWebServer().removeConnector(connector);
  278. this.connector = null;
  279. }
  280. /** {@inheritDoc} */
  281. public synchronized Connector getValue() throws IllegalStateException {
  282. final Connector connector = this.connector;
  283. if (connector == null) {
  284. throw MESSAGES.nullValue();
  285. }
  286. return connector;
  287. }
  288. void setSsl(final ModelNode ssl) {
  289. this.ssl = ssl;
  290. }
  291. void setVirtualServers(ModelNode virtualServers) {
  292. this.virtualServers = virtualServers;
  293. }
  294. protected boolean isEnableLookups() {
  295. return enableLookups;
  296. }
  297. protected void setEnableLookups(boolean enableLookups) {
  298. this.enableLookups = enableLookups;
  299. }
  300. protected String getProxyName() {
  301. return proxyName;
  302. }
  303. protected void setProxyName(String proxyName) {
  304. this.proxyName = proxyName;
  305. }
  306. protected int getProxyPort() {
  307. return proxyPort;
  308. }
  309. protected void setProxyPort(int proxyPort) {
  310. this.proxyPort = proxyPort;
  311. }
  312. protected int getRedirectPort() {
  313. return redirectPort;
  314. }
  315. protected void setRedirectPort(int redirectPort) {
  316. this.redirectPort = redirectPort;
  317. }
  318. protected boolean isSecure() {
  319. return secure;
  320. }
  321. protected void setSecure(boolean secure) {
  322. this.secure = secure;
  323. }
  324. protected int getMaxPostSize() {
  325. return maxPostSize;
  326. }
  327. protected void setMaxPostSize(int maxPostSize) {
  328. this.maxPostSize = maxPostSize;
  329. }
  330. protected int getMaxSavePostSize() {
  331. return maxSavePostSize;
  332. }
  333. protected void setMaxSavePostSize(int maxSavePostSize) {
  334. this.maxSavePostSize = maxSavePostSize;
  335. }
  336. protected int getMaxConnections() {
  337. return maxConnections;
  338. }
  339. protected void setMaxConnections(int maxConnections) {
  340. this.maxConnections = maxConnections;
  341. }
  342. InjectedValue<Executor> getExecutor() {
  343. return executor;
  344. }
  345. InjectedValue<SocketBinding> getBinding() {
  346. return binding;
  347. }
  348. InjectedValue<WebServer> getServer() {
  349. return server;
  350. }
  351. private WebServer getWebServer() {
  352. return server.getValue();
  353. }
  354. static class ConnectorBinding implements ManagedBinding {
  355. private final SocketBinding binding;
  356. private ConnectorBinding(final SocketBinding binding) {
  357. this.binding = binding;
  358. }
  359. @Override
  360. public String getSocketBindingName() {
  361. return binding.getName();
  362. }
  363. @Override
  364. public InetSocketAddress getBindAddress() {
  365. return binding.getSocketAddress();
  366. }
  367. @Override
  368. public void close() throws IOException {
  369. // TODO should this do something?
  370. }
  371. }
  372. }