ipv6 and uri parking fixes

This commit is contained in:
Peter Thorson
2012-01-11 10:12:57 -06:00
parent aaf5f51c35
commit 0e92bb207a
8 changed files with 199 additions and 20 deletions

View File

@@ -116,8 +116,8 @@ int main(int argc, char* argv[]) {
std::cout << "Starting WebSocket broadcast server on port " << port << std::endl;
e.listen(port);
}
} catch (std::string e) {
//std::cerr << "Exception: " << e.what() << std::endl;
} catch (std::exception& e) {
std::cerr << "Exception: " << e.what() << std::endl;
}

View File

@@ -186,13 +186,21 @@ public:
uri_ptr get_uri(const http::parser::request& request) const {
std::string h = request.header("Host");
size_t found = h.find(":");
if (found == std::string::npos) {
size_t last_colon = h.rfind(":");
size_t last_sbrace = h.rfind("]");
// no : = hostname with no port
// last : before ] = ipv6 literal with no port
// : with no ] = hostname with port
// : after ] = ipv6 literal with port
if (last_colon == std::string::npos ||
(last_sbrace != std::string::npos && last_sbrace > last_colon))
{
return uri_ptr(new uri(m_connection.is_secure(),h,request.uri()));
} else {
return uri_ptr(new uri(m_connection.is_secure(),
h.substr(0,found),
h.substr(found+1),
h.substr(0,last_colon),
h.substr(last_colon+1),
request.uri()));
}

View File

@@ -103,13 +103,21 @@ public:
uri_ptr get_uri(const http::parser::request& request) const {
std::string h = request.header("Host");
size_t found = h.find(":");
if (found == std::string::npos) {
size_t last_colon = h.rfind(":");
size_t last_sbrace = h.rfind("]");
// no : = hostname with no port
// last : before ] = ipv6 literal with no port
// : with no ] = hostname with port
// : after ] = ipv6 literal with port
if (last_colon == std::string::npos ||
(last_sbrace != std::string::npos && last_sbrace > last_colon))
{
return uri_ptr(new uri(m_connection.is_secure(),h,request.uri()));
} else {
return uri_ptr(new uri(m_connection.is_secure(),
h.substr(0,found),
h.substr(found+1),
h.substr(0,last_colon),
h.substr(last_colon+1),
request.uri()));
}

View File

@@ -263,6 +263,8 @@ client<endpoint>::connect(const std::string& u) {
throw "";
}
std::cout << "host: " << location->get_host() << std::endl;
tcp::resolver::query query(location->get_host(),location->get_port_str());
tcp::resolver::iterator iterator = m_resolver.resolve(query);

View File

@@ -177,7 +177,10 @@ public:
server(boost::asio::io_service& m)
: m_ws_endpoint(static_cast< endpoint_type& >(*this)),
m_io_service(m),
m_endpoint(),
// the only way to set an endpoint address family appears to be using
// this constructor, which also requires a port. This port number can be
// ignored, as it is always overwriten later by the listen() member func
m_endpoint(boost::asio::ip::tcp::v6(),9000),
m_acceptor(m),
m_timer(m,boost::posix_time::seconds(0)) {}
@@ -415,15 +418,19 @@ void server<endpoint>::connection<connection_type>::handle_read_request(
// Set URI
std::string h = m_request.header("Host");
size_t found = h.find(":");
if (found == std::string::npos) {
size_t last_colon = h.rfind(":");
size_t last_sbrace = h.rfind("]");
if (last_colon == std::string::npos ||
(last_sbrace != std::string::npos && last_sbrace > last_colon))
{
// TODO: this makes the assumption that WS and HTTP
// default ports are the same.
m_uri.reset(new uri(m_endpoint.is_secure(),h,m_request.uri()));
} else {
m_uri.reset(new uri(m_endpoint.is_secure(),
h.substr(0,found),
h.substr(found+1),
h.substr(0,last_colon),
h.substr(last_colon+1),
m_request.uri()));
}

View File

@@ -28,14 +28,140 @@
#include "uri.hpp"
#include <sstream>
#include <iostream>
#include <boost/regex.hpp>
using websocketpp::uri;
uri::uri(const std::string& uri) {
boost::cmatch matches;
static const boost::regex expression("(ws|wss)://([^/:\\[]+|\\[[0-9:]+\\])(:\\d{1,5})?(/[^#]*)?");
/*enum state {
BEGIN = 0,
HOST_BEGIN = 1,
READ_IPV6_LITERAL = 2,
READ_HOSTNAME = 3,
BEGIN_PORT = 4,
READ_PORT = 5,
READ_RESOURCE = 6,
};
state the_state = BEGIN;
std::string temp;
for (std::string::const_iterator it = uri.begin(); it != uri.end(); it++) {
switch (the_state) {
case BEGIN:
// we are looking for a ws:// or wss://
if (temp.size() < 5) {
temp.append(1,*it);
} else {
throw websocketpp::uri_exception("Scheme is too long");
}
if (temp == "ws://") {
m_secure = false;
the_state = HOST_BEGIN;
temp.clear();
} else if (temp == "wss://") {
m_secure = true;
the_state = HOST_BEGIN;
temp.clear();
}
break;
case HOST_BEGIN:
// if character is [ go into IPv6 literal state
// otherwise go into read hostname state
if (*it == '[') {
the_state = READ_IPV6_LITERAL;
} else {
*it--;
the_state = READ_HOSTNAME;
}
break;
case READ_IPV6_LITERAL:
// read 0-9a-fA-F:. until ] or 45 characters have been read
if (*it == ']') {
the_state = BEGIN_PORT;
break;
}
if (m_host.size() > 45) {
throw websocketpp::uri_exception("IPv6 literal is too long");
}
if (*it == '.' ||
*it == ':' ||
(*it >= '0' && *it <= '9') ||
(*it >= 'a' && *it <= 'f') ||
(*it >= 'A' && *it <= 'F'))
{
m_host.append(1,*it);
}
break;
case READ_HOSTNAME:
//
if (*it == ':') {
it--;
the_state = BEGIN_PORT;
break;
}
if (*it == '/') {
it--;
the_state = BEGIN_PORT;
break;
}
// TODO: max url length?
// TODO: check valid characters?
if (1) {
m_host.append(1,*it);
}
break;
case BEGIN_PORT:
if (*it == ':') {
the_state = READ_PORT;
} else if (*it == '/') {
m_port = get_port_from_string("");
*it--;
the_state = READ_RESOURCE;
} else {
throw websocketpp::uri_exception("Error parsing WebSocket URI");
}
break;
case READ_PORT:
if (*it >= '0' && *it <= '9') {
if (temp.size() < 5) {
temp.append(1,*it);
} else {
throw websocketpp::uri_exception("Port is too long");
}
} else if (*it == '/') {
m_port = get_port_from_string(temp);
temp.clear();
*it--;
the_state = READ_RESOURCE;
} else {
throw websocketpp::uri_exception("Error parsing WebSocket URI");
}
break;
case READ_RESOURCE:
// max length check?
if (*it == '#') {
throw websocketpp::uri_exception("WebSocket URIs cannot have fragments");
} else {
m_resource.append(1,*it);
}
break;
}
}*/
boost::cmatch matches;
static const boost::regex expression("(ws|wss)://([^/:\\[]+|\\[[0-9a-fA-F:]+\\])(:\\d{1,5})?(/[^#]*)?");
// TODO: should this split resource into path/query?
@@ -43,6 +169,10 @@ uri::uri(const std::string& uri) {
m_secure = (matches[1] == "wss");
m_host = matches[2];
if (m_host[0] == '[') {
m_host = m_host.substr(1,m_host.size()-2);
}
std::string port(matches[3]);
if (port != "") {
@@ -168,7 +298,7 @@ uint16_t uri::get_port_from_string(const std::string& port) const {
}
if (t_port == 0) {
throw websocketpp::uri_exception("Error parsing port string");
throw websocketpp::uri_exception("Error parsing port string: "+port);
}
return t_port;

View File

@@ -1,5 +1,5 @@
BOOST_LIB_PATH ?= /Users/zaphoyd/Documents/boost_1_48_0/stage/lib
BOOST_INCLUDE_PATH ?= /Users/zaphoyd/Documents/boost_1_48_0
BOOST_LIB_PATH ?= /usr/local/lib
BOOST_INCLUDE_PATH ?= /usr/local/include
CFLAGS = -O2 -I$(BOOST_INCLUDE_PATH)
LDFLAGS = -L$(BOOST_LIB_PATH)

View File

@@ -230,6 +230,10 @@
B62A5A6F14774CD5005F9EB0 /* uri.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; name = uri.hpp; path = src/uri.hpp; sourceTree = "<group>"; };
B62A5A7014774F08005F9EB0 /* md5.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; name = md5.hpp; path = src/md5/md5.hpp; sourceTree = "<group>"; };
B62A5A71147759EA005F9EB0 /* common.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; name = common.hpp; path = src/common.hpp; sourceTree = "<group>"; };
B64E12D214BDE132006F20F0 /* logging.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = logging.cpp; sourceTree = "<group>"; };
B64E12D314BDE132006F20F0 /* Makefile */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
B64E12D414BDE132006F20F0 /* parsing.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = parsing.cpp; sourceTree = "<group>"; };
B64E12D514BDE132006F20F0 /* tests */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.executable"; path = tests; sourceTree = "<group>"; };
B653A714148A607D004D7BD9 /* hybi_header.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = hybi_header.hpp; sourceTree = "<group>"; };
B653A718148AB555004D7BD9 /* hybi_header.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = hybi_header.cpp; sourceTree = "<group>"; };
B66388451487D71800DDAE13 /* echo_server_tls.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = echo_server_tls.cpp; path = examples/echo_server_tls/echo_server_tls.cpp; sourceTree = "<group>"; };
@@ -496,6 +500,25 @@
path = src/processors;
sourceTree = "<group>";
};
B64E12D014BDE132006F20F0 /* test */ = {
isa = PBXGroup;
children = (
B64E12D114BDE132006F20F0 /* basic */,
);
path = test;
sourceTree = "<group>";
};
B64E12D114BDE132006F20F0 /* basic */ = {
isa = PBXGroup;
children = (
B64E12D214BDE132006F20F0 /* logging.cpp */,
B64E12D314BDE132006F20F0 /* Makefile */,
B64E12D414BDE132006F20F0 /* parsing.cpp */,
B64E12D514BDE132006F20F0 /* tests */,
);
path = basic;
sourceTree = "<group>";
};
B66388431487D70000DDAE13 /* echo_server_tls */ = {
isa = PBXGroup;
children = (
@@ -623,6 +646,7 @@
B6DF1CC61435ED380029A1B1 /* examples */,
B6DF1CC51435ECE40029A1B1 /* libraries */,
B6138791145CA6F700ED9B19 /* Makefile */,
B64E12D014BDE132006F20F0 /* test */,
B6DF1C7F1434ABB70029A1B1 /* src */,
B6DF1C6A1434A7A30029A1B1 /* Products */,
);