All Downloads are FREE. Search and download functionalities are using the official Maven repository.

gov.nist.javax.sip.stack.NioWebSocketMessageChannel Maven / Gradle / Ivy

There is a newer version: 1.3.0-91
Show newest version
/*
 * Conditions Of Use
 *
 * This software was developed by employees of the National Institute of
 * Standards and Technology (NIST), an agency of the Federal Government.
 * Pursuant to title 15 Untied States Code Section 105, works of NIST
 * employees are not subject to copyright protection in the United States
 * and are considered to be in the public domain.  As a result, a formal
 * license is not needed to use the software.
 *
 * This software is provided by NIST as a service and is expressly
 * provided "AS IS."  NIST MAKES NO WARRANTY OF ANY KIND, EXPRESS, IMPLIED
 * OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT
 * AND DATA ACCURACY.  NIST does not warrant or make any representations
 * regarding the use of the software or the results thereof, including but
 * not limited to the correctness, accuracy, reliability or usefulness of
 * the software.
 *
 * Permission to use this software is contingent upon your acceptance
 * of the terms of this agreement
 *
 * .
 *
 */
package gov.nist.javax.sip.stack;

import gov.nist.core.CommonLogger;
import gov.nist.core.Host;
import gov.nist.core.HostPort;
import gov.nist.core.LogWriter;
import gov.nist.core.StackLogger;
import gov.nist.javax.sip.header.RecordRoute;
import gov.nist.javax.sip.message.SIPMessage;
import gov.nist.javax.sip.message.SIPRequest;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.text.ParseException;
import java.util.concurrent.atomic.AtomicBoolean;

import javax.sip.address.SipURI;
import javax.sip.address.URI;
import javax.sip.header.ContactHeader;
import javax.sip.header.RecordRouteHeader;
import javax.sip.header.ViaHeader;
import javax.sip.message.Request;


public class NioWebSocketMessageChannel extends NioTcpMessageChannel{

	private static StackLogger logger = CommonLogger
			.getLogger(NioWebSocketMessageChannel.class);
	
	private WebSocketCodec codec = new WebSocketCodec(true, true);
	
	boolean readingHttp = true;
	String httpInput = "";
	boolean client;
	AtomicBoolean httpClientRequestSent=new AtomicBoolean(false);
	String httpHostHeader;
	String httpMethod;
	String httpLocation;
	
	public static NioWebSocketMessageChannel create(
			NioWebSocketMessageProcessor nioTcpMessageProcessor,
			SocketChannel socketChannel) throws IOException {
		NioWebSocketMessageChannel retval = (NioWebSocketMessageChannel) channelMap.get(socketChannel);
		if (retval == null) {
			retval = new NioWebSocketMessageChannel(nioTcpMessageProcessor,
					socketChannel);
			channelMap.put(socketChannel, retval);
		}
		return retval;
	}
	
	protected NioWebSocketMessageChannel(NioTcpMessageProcessor nioTcpMessageProcessor,
			SocketChannel socketChannel) throws IOException {
		super(nioTcpMessageProcessor, socketChannel);

		messageProcessor = nioTcpMessageProcessor;
		myClientInputStream = socketChannel.socket().getInputStream();
	}
	
	@Override
	protected void sendMessage(final byte[] msg, final boolean isClient) throws IOException {
		if (logger.isLoggingEnabled(LogWriter.TRACE_DEBUG)) {
			logger.logDebug("sendMessage isClient  = " + isClient + " this = " + this);
		}
		lastActivityTimeStamp = System.currentTimeMillis();
		
		NIOHandler nioHandler = ((NioTcpMessageProcessor) messageProcessor).nioHandler;
		if(this.socketChannel != null && this.socketChannel.isConnected() && this.socketChannel.isOpen()) {
			nioHandler.putSocket(NIOHandler.makeKey(this.peerAddress, this.peerPort), this.socketChannel);
		}
		sendWrapped(msg, this.peerAddress, this.peerPort, isClient);
	}
	
	protected void sendNonWebSocketMessage(byte[] msg, boolean isClient) throws IOException {

		if (logger.isLoggingEnabled(LogWriter.TRACE_DEBUG)) {
			logger.logDebug("sendMessage isClient  = " + isClient + " this = " + this);
		}
		lastActivityTimeStamp = System.currentTimeMillis();
		
		NIOHandler nioHandler = ((NioTcpMessageProcessor) messageProcessor).nioHandler;
		if(this.socketChannel != null && this.socketChannel.isConnected() && this.socketChannel.isOpen()) {
			nioHandler.putSocket(NIOHandler.makeKey(this.peerAddress, this.peerPort), this.socketChannel);
		}
		super.sendTCPMessage(msg, this.peerAddress, this.peerPort, isClient);
	}

	
	public static byte[] wrapBufferIntoWebSocketFrame(byte[] buffer, boolean client) {
		try {
			return WebSocketCodec.encode(buffer, 0, true, client);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	public void sendWrapped(byte message[], InetAddress receiverAddress,
			int receiverPort, boolean retry) throws IOException {
		
		if(client && readingHttp && httpClientRequestSent.compareAndSet(false, true)) {
			String http = "null null HTTP/1.1\r\n" + 
					"Host: null \r\n" + 
					"Upgrade: websocket\r\n" + 
					"Connection: Upgrade\r\n" + 
					"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" + 
					"Sec-WebSocket-Protocol: sip\r\n" + 
					"Sec-WebSocket-Version: 13\r\n\r\n";
			
			super.sendTCPMessage(http.getBytes(), receiverAddress, receiverPort, false);
			try {
				Thread.sleep(150);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
		message = wrapBufferIntoWebSocketFrame(message, client);
		super.sendTCPMessage(message, receiverAddress, receiverPort, retry);
	}
	
	@Override
	public void sendMessage(final byte message[], final InetAddress receiverAddress,
			final int receiverPort, final boolean retry) throws IOException {
		sendWrapped(message, receiverAddress, receiverPort, retry);
	}

	@Override
	public void sendMessage(SIPMessage sipMessage, InetAddress receiverAddress, int receiverPort)
            throws IOException {
		if(sipMessage instanceof SIPRequest) {
			if(client && httpClientRequestSent.compareAndSet(false, true)) {
				SIPRequest request = (SIPRequest) sipMessage;
				SipURI requestUri = (SipURI) request.getRequestURI();
				this.httpHostHeader = requestUri.getHeader("Host");
				this.httpLocation = requestUri.getHeader("Location");
				this.httpMethod = requestUri.getMethodParam();
				String http = this.httpMethod + " " + this.httpLocation + " HTTP/1.1\r\n" + 
						"Host: " + this.httpHostHeader + "\r\n" + 
						"Upgrade: websocket\r\n" + 
						"Connection: Upgrade\r\n" + 
						"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" + 
						"Sec-WebSocket-Protocol: sip\r\n" + 
						"Sec-WebSocket-Version: 13\r\n\r\n";
				super.sendTCPMessage(http.getBytes(), receiverAddress, receiverPort, false);
				try {
					Thread.sleep(150);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		super.sendMessage(sipMessage, receiverAddress, receiverPort);
    }
	
	public NioWebSocketMessageChannel(InetAddress inetAddress, int port,
			SIPTransactionStack sipStack,
			NioTcpMessageProcessor nioTcpMessageProcessor) throws IOException {
		super(inetAddress, port, sipStack, nioTcpMessageProcessor);
		client = true;
		this.codec = new WebSocketCodec(false, true);
	}
	
	@Override
	protected void addBytes(byte[] bytes) throws Exception {
		String s = new String(bytes);
		
		if(readingHttp) {
			byte[] remaining = null;
			for(int q=0;q




© 2015 - 2024 Weber Informatics LLC | Privacy Policy