PageRenderTime 39ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/ps3mediaserver/net/pms/network/HTTPServer.java

http://ps3mediaserver.googlecode.com/
Java | 288 lines | 236 code | 31 blank | 21 comment | 68 complexity | 57a749b2690eaa72971f59b71e1a4280 MD5 | raw file
Possible License(s): GPL-2.0, Apache-2.0, CPL-1.0
  1. /*
  2. * PS3 Media Server, for streaming any medias to your PS3.
  3. * Copyright (C) 2008 A.Brochard
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License
  7. * as published by the Free Software Foundation; version 2
  8. * of the License only.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  18. */
  19. package net.pms.network;
  20. import java.io.IOException;
  21. import java.net.Inet6Address;
  22. import java.net.InetAddress;
  23. import java.net.InetSocketAddress;
  24. import java.net.NetworkInterface;
  25. import java.net.ServerSocket;
  26. import java.net.Socket;
  27. import java.net.SocketException;
  28. import java.net.UnknownHostException;
  29. import java.nio.channels.ClosedByInterruptException;
  30. import java.nio.channels.ServerSocketChannel;
  31. import java.util.ArrayList;
  32. import java.util.Enumeration;
  33. import java.util.List;
  34. import java.util.concurrent.Executors;
  35. import net.pms.PMS;
  36. import net.pms.util.PMSUtil;
  37. import org.apache.commons.lang.StringUtils;
  38. import org.jboss.netty.bootstrap.ServerBootstrap;
  39. import org.jboss.netty.channel.Channel;
  40. import org.jboss.netty.channel.ChannelFactory;
  41. import org.jboss.netty.channel.group.ChannelGroup;
  42. import org.jboss.netty.channel.group.DefaultChannelGroup;
  43. import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
  44. import org.slf4j.Logger;
  45. import org.slf4j.LoggerFactory;
  46. public class HTTPServer implements Runnable {
  47. private static final Logger logger = LoggerFactory.getLogger(HTTPServer.class);
  48. private ArrayList<String> ips;
  49. private int port;
  50. private String hostName;
  51. private ServerSocketChannel serverSocketChannel;
  52. private ServerSocket serverSocket;
  53. private boolean stop;
  54. private Thread runnable;
  55. private InetAddress iafinal = null;
  56. private ChannelFactory factory;
  57. private Channel channel;
  58. private NetworkInterface ni = null;
  59. private ChannelGroup group;
  60. public InetAddress getIafinal() {
  61. return iafinal;
  62. }
  63. public NetworkInterface getNi() {
  64. return ni;
  65. }
  66. public HTTPServer(int port) {
  67. this.port = port;
  68. ips = new ArrayList<String>();
  69. }
  70. public boolean start() throws IOException {
  71. boolean found = false;
  72. String fixedNetworkInterfaceName = PMS.getConfiguration().getNetworkInterface();
  73. NetworkInterface fixedNI = NetworkInterface.getByName(fixedNetworkInterfaceName);
  74. if (fixedNI != null) {
  75. if (checkNetworkInterface(fixedNI)) {
  76. ni = fixedNI;
  77. }
  78. } else {
  79. Enumeration<NetworkInterface> enm = NetworkInterface.getNetworkInterfaces();
  80. while (enm.hasMoreElements()) {
  81. ni = enm.nextElement();
  82. found = checkNetworkInterface(ni);
  83. if (found) {
  84. break;
  85. }
  86. }
  87. }
  88. hostName = PMS.getConfiguration().getServerHostname();
  89. InetSocketAddress address = null;
  90. if (hostName != null && hostName.length() > 0) {
  91. logger.info("Using forced address " + hostName);
  92. InetAddress tempIA = InetAddress.getByName(hostName);
  93. if (tempIA != null && ni != null && ni.equals(NetworkInterface.getByInetAddress(tempIA))) {
  94. address = new InetSocketAddress(tempIA, port);
  95. } else {
  96. address = new InetSocketAddress(hostName, port);
  97. }
  98. } else if (iafinal != null) {
  99. logger.info("Using address " + iafinal + " found on network interface: " + ni.toString().trim().replace('\n', ' '));
  100. address = new InetSocketAddress(iafinal, port);
  101. } else {
  102. logger.info("Using localhost address");
  103. address = new InetSocketAddress(port);
  104. }
  105. logger.info("Created socket: " + address);
  106. if (!PMS.getConfiguration().isHTTPEngineV2()) {
  107. serverSocketChannel = ServerSocketChannel.open();
  108. serverSocket = serverSocketChannel.socket();
  109. serverSocket.setReuseAddress(true);
  110. serverSocket.bind(address);
  111. if (hostName == null && iafinal != null) {
  112. hostName = iafinal.getHostAddress();
  113. } else if (hostName == null) {
  114. hostName = InetAddress.getLocalHost().getHostAddress();
  115. }
  116. runnable = new Thread(this, "HTTP Server");
  117. runnable.setDaemon(false);
  118. runnable.start();
  119. } else {
  120. group = new DefaultChannelGroup("myServer");
  121. factory = new NioServerSocketChannelFactory(
  122. Executors.newCachedThreadPool(),
  123. Executors.newCachedThreadPool());
  124. ServerBootstrap bootstrap = new ServerBootstrap(factory);
  125. HttpServerPipelineFactory pipeline = new HttpServerPipelineFactory(group);
  126. bootstrap.setPipelineFactory(pipeline);
  127. bootstrap.setOption("child.tcpNoDelay", true);
  128. bootstrap.setOption("child.keepAlive", true);
  129. bootstrap.setOption("reuseAddress", true);
  130. bootstrap.setOption("child.reuseAddress", true);
  131. bootstrap.setOption("child.sendBufferSize", 65536);
  132. bootstrap.setOption("child.receiveBufferSize", 65536);
  133. channel = bootstrap.bind(address);
  134. group.add(channel);
  135. if (hostName == null && iafinal != null) {
  136. hostName = iafinal.getHostAddress();
  137. } else if (hostName == null) {
  138. hostName = InetAddress.getLocalHost().getHostAddress();
  139. }
  140. }
  141. return true;
  142. }
  143. private boolean checkNetworkInterface(NetworkInterface net) throws SocketException, UnknownHostException {
  144. InetAddress ia;
  145. boolean found = false;
  146. boolean skip = false;
  147. String name = net.getName();
  148. String displayName = net.getDisplayName();
  149. // Should we skip this particular network interface?
  150. if (PMSUtil.isNetworkInterfaceLoopback(net)) {
  151. skip = true;
  152. } else {
  153. skip = skipNetworkInterface(name, displayName);
  154. }
  155. if (skip) {
  156. logger.info("Skipping network interface " + displayName + " (" + name + ")");
  157. } else {
  158. logger.info("Scanning network interface " + displayName + " (" + name + ")");
  159. Enumeration<InetAddress> addrs = net.getInetAddresses();
  160. while (addrs.hasMoreElements()) {
  161. ia = addrs.nextElement();
  162. if (!(ia instanceof Inet6Address) && !ia.isLoopbackAddress()) {
  163. iafinal = ia;
  164. found = true;
  165. if (StringUtils.isNotEmpty(PMS.getConfiguration().getServerHostname())) {
  166. found = iafinal.equals(InetAddress.getByName(PMS.getConfiguration().getServerHostname()));
  167. }
  168. break;
  169. }
  170. }
  171. }
  172. return found;
  173. }
  174. private boolean skipNetworkInterface(String name, String displayName) {
  175. // Try to match all configured blacklisted network interfaces
  176. List<String> skipNetworkInterfaces = PMS.getConfiguration().getSkipNetworkInterfaces();
  177. for (String current : skipNetworkInterfaces) {
  178. if (name != null && lcontains(name, current)) {
  179. return true;
  180. }
  181. if (displayName != null && lcontains(displayName, current)) {
  182. return true;
  183. }
  184. }
  185. return false;
  186. }
  187. private boolean lcontains(String txt, String substr) {
  188. return txt.toLowerCase().contains(substr);
  189. }
  190. public void stop() {
  191. logger.info("Stopping server on host " + hostName + " and port " + port + "...");
  192. if (!PMS.getConfiguration().isHTTPEngineV2()) {
  193. runnable.interrupt();
  194. runnable = null;
  195. try {
  196. serverSocket.close();
  197. serverSocketChannel.close();
  198. } catch (IOException e) {
  199. }
  200. } else if (channel != null) {
  201. if (group != null) {
  202. group.close().awaitUninterruptibly();
  203. }
  204. if (factory != null) {
  205. factory.releaseExternalResources();
  206. }
  207. }
  208. }
  209. public void run() {
  210. logger.info("Starting DLNA Server on host " + hostName + " and port " + port + "...");
  211. while (!stop) {
  212. try {
  213. Socket socket = serverSocket.accept();
  214. InetAddress inetAddress = socket.getInetAddress();
  215. String ip = inetAddress.getHostAddress();
  216. // basic ipfilter: solntcev at gmail dot com
  217. boolean ignore = false;
  218. if (!PMS.getConfiguration().getIpFiltering().allowed(inetAddress)) {
  219. ignore = true;
  220. socket.close();
  221. logger.trace("Ignoring request from: " + ip);
  222. } else {
  223. logger.trace("Receiving a request from: " + ip);
  224. }
  225. if (!ignore) {
  226. RequestHandler request = new RequestHandler(socket);
  227. Thread thread = new Thread(request, "Request Handler");
  228. thread.start();
  229. }
  230. } catch (ClosedByInterruptException e) {
  231. stop = true;
  232. } catch (IOException e) {
  233. e.printStackTrace();
  234. } finally {
  235. try {
  236. if (stop && serverSocket != null) {
  237. serverSocket.close();
  238. }
  239. if (stop && serverSocketChannel != null) {
  240. serverSocketChannel.close();
  241. }
  242. } catch (IOException e) {
  243. e.printStackTrace();
  244. }
  245. }
  246. }
  247. }
  248. public String getURL() {
  249. return "http://" + hostName + ":" + port;
  250. }
  251. public String getHost() {
  252. return hostName;
  253. }
  254. public int getPort() {
  255. return port;
  256. }
  257. }