Beispiel #1
0
WebSocketImpl* WebSocket::completeHandshake(HTTPClientSession& cs, HTTPResponse& response, const std::string& key)
{
	std::string connection = response.get("Connection", "");
	if (Poco::icompare(connection, "Upgrade") != 0) 
		throw WebSocketException("No Connection: Upgrade header in handshake response", WS_ERR_NO_HANDSHAKE);
	std::string upgrade = response.get("Upgrade", "");
	if (Poco::icompare(upgrade, "websocket") != 0)
		throw WebSocketException("No Upgrade: websocket header in handshake response", WS_ERR_NO_HANDSHAKE);
	std::string accept = response.get("Sec-WebSocket-Accept", "");
	if (accept != computeAccept(key))
		throw WebSocketException("Invalid or missing Sec-WebSocket-Accept header in handshake response", WS_ERR_NO_HANDSHAKE);
	return new WebSocketImpl(static_cast<StreamSocketImpl*>(cs.socket().impl()), true);
}
std::string WebSocketClientHeaderIETF_HYBI17::generateResponse(unsigned short port, const char *webSocketServerProtocolName)
{
	bool secureFlag = false;
	std::string::size_type pos;
	std::string message;
	auto secWebSocketKeyIterator = fields.find("Sec-WebSocket-Key");

	if(secWebSocketKeyIterator == fields.end())
	{
		throw WebSocketException("No `Sec-WebSocket-Key` header found");
	}

	std::string secWebSocketAccept = (*secWebSocketKeyIterator).second + std::string("258EAFA5-E914-47DA-95CA-C5AB0DC85B11");
	secWebSocketAccept = StringUtil::SHA1(secWebSocketAccept);
	secWebSocketAccept = StringUtil::base64Encode(secWebSocketAccept);

	message.append("HTTP/1.1 101 Switching Protocols\r\n");
	message.append("Upgrade: WebSocket\r\n");
	message.append("Connection: Upgrade\r\n");
	message.append(std::string("Sec-WebSocket-Accept: ") + secWebSocketAccept + std::string("\r\n"));

	message.append((webSocketServerProtocolName ? (std::string("Sec-WebSocket-Protocol: ") + std::string(webSocketServerProtocolName) + std::string("\r\n")) : ""));
	message.append("\r\n");

	return message;

}
void WebSocketClientHeaderIETF_HYBI17::read(std::string &packet)
{
	std::string line;
	std::string::size_type startPos = 0, crlfPos;

	line = WebSocketClientHeader::getLine(packet, startPos, crlfPos);

	readFirstLine(line);

	//Read all of the fields. Field ending is denoted by a pair of CRLF.

	startPos = crlfPos + 2;

	do {
		
		line = WebSocketClientHeader::getLine(packet, startPos, crlfPos);

		readFieldLine(line);

		startPos = crlfPos + 2;

		if( (startPos + 2) > packet.size() ) {

			throw WebSocketException(INVALID_HEADER_EXCEPTION_MESSAGE);
		}

	} while(packet[startPos] != '\r' && packet[startPos + 1] != '\n');

	//Skip over the last crlf.
	startPos += 2;

	packet.erase(0, startPos);
}
Beispiel #4
0
WebSocketImpl* WebSocket::connect(HTTPClientSession& cs, HTTPRequest& request, HTTPResponse& response, HTTPCredentials& credentials)
{
	if (!cs.getProxyHost().empty() && !cs.secure())
	{
		cs.proxyTunnel();
	}
	std::string key = createKey();
	request.set("Connection", "Upgrade");
	request.set("Upgrade", "websocket");
	request.set("Sec-WebSocket-Version", WEBSOCKET_VERSION);
	request.set("Sec-WebSocket-Key", key);
	request.setChunkedTransferEncoding(false);
	cs.setKeepAlive(true);
	cs.sendRequest(request);
	std::istream& istr = cs.receiveResponse(response);
	if (response.getStatus() == HTTPResponse::HTTP_SWITCHING_PROTOCOLS)
	{
		return completeHandshake(cs, response, key);
	}
	else if (response.getStatus() == HTTPResponse::HTTP_UNAUTHORIZED)
	{
		Poco::NullOutputStream null;
		Poco::StreamCopier::copyStream(istr, null);
		credentials.authenticate(request, response);
		if (!cs.getProxyHost().empty() && !cs.secure())
		{
			cs.reset();
			cs.proxyTunnel();
		}
		cs.sendRequest(request);
		cs.receiveResponse(response);
		if (response.getStatus() == HTTPResponse::HTTP_SWITCHING_PROTOCOLS)
		{
			return completeHandshake(cs, response, key);
		}
		else if (response.getStatus() == HTTPResponse::HTTP_UNAUTHORIZED)
		{
			throw WebSocketException("Not authorized", WS_ERR_UNAUTHORIZED);
		}
	}
	throw WebSocketException("Cannot upgrade to WebSocket connection", response.getReason(), WS_ERR_NO_HANDSHAKE);
}
Beispiel #5
0
WebSocketImpl* WebSocket::accept(HTTPServerRequest& request, HTTPServerResponse& response)
{
	if (icompare(request.get("Connection", ""), "Upgrade") == 0 &&
	    icompare(request.get("Upgrade", ""), "websocket") == 0)
	{
		std::string version = request.get("Sec-WebSocket-Version", "");
		if (version.empty()) throw WebSocketException("Missing Sec-WebSocket-Version in handshake request", WS_ERR_HANDSHAKE_NO_VERSION);
		if (version != WEBSOCKET_VERSION) throw WebSocketException("Unsupported WebSocket version requested", version, WS_ERR_HANDSHAKE_UNSUPPORTED_VERSION);
		std::string key = request.get("Sec-WebSocket-Key", "");
		Poco::trimInPlace(key);
		if (key.empty()) throw WebSocketException("Missing Sec-WebSocket-Key in handshake request", WS_ERR_HANDSHAKE_NO_KEY);
		
		response.setStatusAndReason(HTTPResponse::HTTP_SWITCHING_PROTOCOLS);
		response.set("Upgrade", "websocket");
		response.set("Connection", "Upgrade");
		response.set("Sec-WebSocket-Accept", computeAccept(key));
		response.setContentLength(0);
		response.send().flush();
		return new WebSocketImpl(static_cast<StreamSocketImpl*>(static_cast<HTTPServerRequestImpl&>(request).detachSocket().impl()), false);
	}
	else throw WebSocketException("No WebSocket handshake", WS_ERR_NO_HANDSHAKE);
}