View Javadoc
1   package com.ericsson.research.transport.ws.spi;
2   
3   /*
4    * ##_BEGIN_LICENSE_##
5    * Transport Abstraction Package (trap)
6    * ----------
7    * Copyright (C) 2014 Ericsson AB
8    * ----------
9    * Redistribution and use in source and binary forms, with or without modification,
10   * are permitted provided that the following conditions are met:
11   * 
12   * 1. Redistributions of source code must retain the above copyright notice, this
13   *    list of conditions and the following disclaimer.
14   * 
15   * 2. Redistributions in binary form must reproduce the above copyright notice,
16   *    this list of conditions and the following disclaimer in the documentation
17   *    and/or other materials provided with the distribution.
18   * 
19   * 3. Neither the name of the Ericsson AB nor the names of its contributors
20   *    may be used to endorse or promote products derived from this software without
21   *    specific prior written permission.
22   * 
23   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
24   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25   * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26   * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
27   * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28   * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29   * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30   * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
31   * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
32   * OF THE POSSIBILITY OF SUCH DAMAGE.
33   * ##_END_LICENSE_##
34   */
35  
36  import java.io.IOException;
37  import java.net.InetAddress;
38  import java.net.InetSocketAddress;
39  import java.net.ServerSocket;
40  import java.net.Socket;
41  
42  import com.ericsson.research.transport.ws.WSAcceptListener;
43  import com.ericsson.research.transport.ws.WSSecurityContext;
44  import com.ericsson.research.transport.ws.WSServer;
45  import com.ericsson.research.transport.ws.WSURI;
46  
47  public class WSServerImpl implements WSServer {
48  
49  	private String host;
50  	private int	port;
51  	private WSAcceptListener serverListener;
52  	private WSSecurityContext securityContext;
53  	private ServerSocket acceptSocket;
54  	private boolean closing;
55  	
56  	public WSServerImpl(String host, int port, WSAcceptListener serverListener, WSSecurityContext securityContext) throws IOException {
57  		this.host = host;
58  		this.port = port;
59  		this.serverListener = serverListener;
60  		this.securityContext = securityContext;
61  		bind();
62  	}
63  
64  	private void bind() throws IOException {
65  		closing = false;
66  		for(int i=0;i<=65000;i++) {
67  			try {
68  				if (securityContext == null)
69  					acceptSocket = new ServerSocket(port, 0, InetAddress.getByName(host));
70  				else
71  					throw new UnsupportedOperationException();
72  					//acceptSocket = WSSecureSocketFactory.getSecureServerSocket(securityContext);
73  				new Thread() {
74  					public void run() {
75  						for(;!closing;) {
76  							try {
77  								Socket socket = acceptSocket.accept();
78  								serverListener.notifyAccept(new WSSocketEndpoint(socket, new WSPrefetcher(securityContext), null));
79  							} catch(IOException e) {
80  								if(serverListener!=null)
81  									serverListener.notifyError(e);
82  							}
83  						}
84  					}
85  				}.start();
86  				serverListener.notifyReady(this);
87  				break;
88  			} catch(IOException e) {
89  				if(port > 65000)
90  					throw e;
91  				else
92  					port++;
93  			}
94  		}
95  	}
96  	
97  	public WSURI getURI() {
98  		String scheme = (securityContext==null ? "ws" : "wss");
99  
100 		InetSocketAddress inetAddress = getAddress();
101 		String host = inetAddress.getAddress().getHostAddress();
102 		int port = inetAddress.getPort();
103 		String resource = "ws";
104 		
105 		byte[] address = inetAddress.getAddress().getAddress();
106 		boolean isv6 = address.length > 4;
107 		
108 		if (isv6)
109 			host = "[" + host + "]";
110 
111 		try {
112 			return new WSURI(scheme + "://" + host + ":" + port + "/" + resource);
113 		} catch (IllegalArgumentException e) {
114 			// Should never happen
115 			if(serverListener!=null)
116 				serverListener.notifyError(e);
117 			return null;
118 		}
119 	}
120 
121 	public InetSocketAddress getAddress() {
122 		return (InetSocketAddress)acceptSocket.getLocalSocketAddress();
123 	}
124 
125 	public void close() {
126 		closing = true;
127 		try {
128 			acceptSocket.close();
129 		} catch(IOException e) {
130 			if(serverListener!=null)
131 				serverListener.notifyError(e);
132 		}
133 	}
134 
135 }