Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
P
pistache
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Libraries
pistache
Commits
3366df11
Commit
3366df11
authored
Dec 03, 2018
by
hydratim
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added IPv6 support
parent
ca1e564e
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
155 additions
and
38 deletions
+155
-38
include/pistache/http.h
include/pistache/http.h
+1
-8
include/pistache/net.h
include/pistache/net.h
+23
-0
src/common/http_header.cc
src/common/http_header.cc
+24
-9
src/common/net.cc
src/common/net.cc
+106
-20
src/server/listener.cc
src/server/listener.cc
+1
-1
No files found.
include/pistache/http.h
View file @
3366df11
...
...
@@ -815,15 +815,8 @@ namespace helpers
{
inline
Address
httpAddr
(
const
StringView
&
view
)
{
auto
const
str
=
view
.
toString
();
auto
const
pos
=
str
.
find
(
':'
);
if
(
pos
==
std
::
string
::
npos
)
{
return
Address
(
std
::
move
(
str
),
HTTP_STANDARD_PORT
);
return
Address
(
str
);
}
auto
const
host
=
str
.
substr
(
0
,
pos
);
auto
const
port
=
std
::
stoi
(
str
.
substr
(
pos
+
1
));
return
Address
(
std
::
move
(
host
),
port
);
}
}
// namespace helpers
}
// namespace Http
}
// namespace Pistache
include/pistache/net.h
View file @
3366df11
...
...
@@ -53,6 +53,7 @@ public:
static
Ipv4
any
();
std
::
string
toString
()
const
;
void
toNetwork
(
in_addr_t
*
)
const
;
private:
uint8_t
a
;
...
...
@@ -61,6 +62,25 @@ private:
uint8_t
d
;
};
class
Ipv6
{
public:
Ipv6
(
uint16_t
a
,
uint16_t
b
,
uint16_t
c
,
uint16_t
d
,
uint16_t
e
,
uint16_t
f
,
uint16_t
g
,
uint16_t
h
);
static
Ipv6
any
();
std
::
string
toString
()
const
;
void
toNetwork
(
in6_addr
*
)
const
;
private:
uint16_t
a
;
uint16_t
b
;
uint16_t
c
;
uint16_t
d
;
uint16_t
e
;
uint16_t
f
;
uint16_t
g
;
uint16_t
h
;
};
class
Address
{
public:
Address
();
...
...
@@ -68,6 +88,7 @@ public:
Address
(
std
::
string
addr
);
Address
(
const
char
*
addr
);
Address
(
Ipv4
ip
,
Port
port
);
Address
(
Ipv6
ip
,
Port
port
);
Address
(
const
Address
&
other
)
=
default
;
Address
(
Address
&&
other
)
=
default
;
...
...
@@ -79,11 +100,13 @@ public:
std
::
string
host
()
const
;
Port
port
()
const
;
int
family
()
const
;
private:
void
init
(
const
std
::
string
&
addr
);
std
::
string
host_
;
Port
port_
;
int
family_
;
};
class
Error
:
public
std
::
runtime_error
{
...
...
src/common/http_header.cc
View file @
3366df11
...
...
@@ -340,17 +340,32 @@ Host::Host(const std::string& data)
void
Host
::
parse
(
const
std
::
string
&
data
)
{
auto
pos
=
data
.
find
(
':'
);
if
(
pos
!=
std
::
string
::
npos
)
{
std
::
string
h
=
data
.
substr
(
0
,
pos
);
int16_t
p
=
std
::
stoi
(
data
.
substr
(
pos
+
1
));
host_
=
h
;
port_
=
p
;
unsigned
long
pos
=
data
.
find
(
']'
);
unsigned
long
s_pos
=
data
.
find
(
'['
);
if
(
pos
!=
std
::
string
::
npos
&&
s_pos
!=
std
::
string
::
npos
)
{
//IPv6 address
host_
=
data
.
substr
(
s_pos
+
1
,
pos
-
1
);
pos
++
;
}
else
{
host_
=
data
;
port_
=
HTTP_STANDARD_PORT
;
//IPv4 address
pos
=
data
.
find
(
':'
);
if
(
pos
==
std
::
string
::
npos
)
{
host_
=
data
;
port_
=
HTTP_STANDARD_PORT
;
}
host_
=
data
.
substr
(
0
,
pos
);
if
(
host_
==
"*"
)
{
host_
=
"0.0.0.0"
;
}
}
char
*
end
;
const
std
::
string
portPart
=
data
.
substr
(
pos
+
1
);
if
(
portPart
.
empty
())
throw
std
::
invalid_argument
(
"Invalid port"
);
long
port
=
strtol
(
portPart
.
c_str
(),
&
end
,
10
);
if
(
*
end
!=
0
||
port
<
Port
::
min
()
||
port
>
Port
::
max
())
throw
std
::
invalid_argument
(
"Invalid port"
);
port_
=
static_cast
<
uint16_t
>
(
port
);
}
void
...
...
src/common/net.cc
View file @
3366df11
...
...
@@ -52,12 +52,71 @@ Ipv4::any() {
std
::
string
Ipv4
::
toString
()
const
{
static
constexpr
size_t
MaxSize
=
sizeof
(
"255"
)
*
4
+
3
+
1
;
/* 4 * 255 + 3 * dot + \0 */
// Use the built-in ipv4 string length from arpa/inet.h
char
buff
[
INET_ADDRSTRLEN
+
1
];
in_addr_t
addr
;
toNetwork
(
&
addr
);
// Convert the network format address into display format
inet_ntop
(
AF_INET
,
&
addr
,
buff
,
INET_ADDRSTRLEN
);
return
std
::
string
(
buff
);
}
char
buff
[
MaxSize
];
snprintf
(
buff
,
MaxSize
,
"%d.%d.%d.%d"
,
a
,
b
,
c
,
d
);
void
Ipv4
::
toNetwork
(
in_addr_t
*
addr
)
const
{
// Bitshift the bytes into an in_addr_t (a single 32bit unsigned int);
*
addr
=
(
uint32_t
)(
d
<<
24
)
|
(
uint32_t
)(
c
<<
16
)
|
(
uint32_t
)(
b
<<
8
)
|
(
uint32_t
)
a
;
}
return
std
::
string
(
buff
);
Ipv6
::
Ipv6
(
uint16_t
a
,
uint16_t
b
,
uint16_t
c
,
uint16_t
d
,
uint16_t
e
,
uint16_t
f
,
uint16_t
g
,
uint16_t
h
)
:
a
(
a
)
,
b
(
b
)
,
c
(
c
)
,
d
(
d
)
,
e
(
e
)
,
f
(
f
)
,
g
(
g
)
,
h
(
h
)
{
}
Ipv6
Ipv6
::
any
()
{
return
Ipv6
(
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
);
}
std
::
string
Ipv6
::
toString
()
const
{
// Use the built-in ipv6 string length from arpa/inet.h
char
buff6
[
INET6_ADDRSTRLEN
+
1
];
in6_addr
addr
;
toNetwork
(
&
addr
);
inet_ntop
(
AF_INET6
,
&
addr
,
buff6
,
INET6_ADDRSTRLEN
);
return
std
::
string
(
buff6
);
}
void
Ipv6
::
toNetwork
(
in6_addr
*
addr6
)
const
{
uint16_t
temp_ip6
[
8
]
=
{
a
,
b
,
c
,
d
,
e
,
f
,
g
,
h
};
uint16_t
remap_ip6
[
8
]
=
{
0
};
uint16_t
x
,
y
;
// If native endianness is little-endian swap the bytes, otherwise just copy them into the new array
if
(
htonl
(
1
)
!=
1
)
{
for
(
uint16_t
i
=
0
;
i
<
8
;
i
++
)
{
x
=
temp_ip6
[
i
];
y
=
__builtin_bswap16
(
x
);
remap_ip6
[
i
]
=
y
;
}
}
else
{
memcpy
(
remap_ip6
,
temp_ip6
,
16
);
}
// Copy the bytes into the in6_addr struct
memcpy
(
addr6
->
s6_addr16
,
remap_ip6
,
16
);
}
Address
::
Address
()
...
...
@@ -86,16 +145,31 @@ Address::Address(Ipv4 ip, Port port)
,
port_
(
port
)
{
}
Address
::
Address
(
Ipv6
ip
,
Port
port
)
:
host_
(
ip
.
toString
())
,
port_
(
port
)
{
}
Address
Address
::
fromUnix
(
struct
sockaddr
*
addr
)
{
struct
sockaddr_in
*
in_addr
=
reinterpret_cast
<
struct
sockaddr_in
*>
(
addr
);
char
*
host
=
inet_ntoa
(
in_addr
->
sin_addr
);
assert
(
addr
);
int
port
=
ntohs
(
in_addr
->
sin_port
);
if
(
addr
->
sa_family
==
AF_INET
)
{
struct
sockaddr_in
*
in_addr
=
reinterpret_cast
<
struct
sockaddr_in
*>
(
addr
);
char
host
[
INET_ADDRSTRLEN
+
1
];
inet_ntop
(
AF_INET
,
&
(
in_addr
->
sin_addr
),
host
,
INET_ADDRSTRLEN
);
int
port
=
ntohs
(
in_addr
->
sin_port
);
assert
(
addr
);
return
Address
(
host
,
port
);
}
else
if
(
addr
->
sa_family
==
AF_INET6
)
{
struct
sockaddr_in6
*
in_addr
=
reinterpret_cast
<
struct
sockaddr_in6
*>
(
addr
);
char
host
[
INET6_ADDRSTRLEN
+
1
];
inet_ntop
(
AF_INET6
,
&
(
in_addr
->
sin6_addr
),
host
,
INET6_ADDRSTRLEN
);
int
port
=
ntohs
(
in_addr
->
sin6_port
);
assert
(
addr
);
return
Address
(
host
,
port
);
}
throw
Error
(
"Not an IP socket"
);
return
Address
(
host
,
port
);
}
std
::
string
...
...
@@ -108,18 +182,30 @@ Address::port() const {
return
port_
;
}
int
Address
::
family
()
const
{
return
family_
;
}
void
Address
::
init
(
const
std
::
string
&
addr
)
{
const
auto
pos
=
addr
.
find
(
':'
);
if
(
pos
==
std
::
string
::
npos
)
throw
std
::
invalid_argument
(
"Invalid address"
);
host_
=
addr
.
substr
(
0
,
pos
);
if
(
host_
==
"*"
)
{
host_
=
"0.0.0.0"
;
unsigned
long
pos
=
addr
.
find
(
']'
);
unsigned
long
s_pos
=
addr
.
find
(
'['
);
if
(
pos
!=
std
::
string
::
npos
&&
s_pos
!=
std
::
string
::
npos
)
{
//IPv6 address
host_
=
addr
.
substr
(
s_pos
+
1
,
pos
-
1
);
pos
++
;
}
else
{
//IPv4 address
pos
=
addr
.
find
(
':'
);
if
(
pos
==
std
::
string
::
npos
)
throw
std
::
invalid_argument
(
"Invalid address"
);
host_
=
addr
.
substr
(
0
,
pos
);
if
(
host_
==
"*"
)
{
host_
=
"0.0.0.0"
;
}
}
char
*
end
;
const
std
::
string
portPart
=
addr
.
substr
(
pos
+
1
);
if
(
portPart
.
empty
())
...
...
src/server/listener.cc
View file @
3366df11
...
...
@@ -157,7 +157,7 @@ Listener::bind(const Address& address) {
addr_
=
address
;
struct
addrinfo
hints
;
hints
.
ai_family
=
AF_INET
;
hints
.
ai_family
=
address
.
family
()
;
hints
.
ai_socktype
=
SOCK_STREAM
;
hints
.
ai_flags
=
AI_PASSIVE
;
hints
.
ai_protocol
=
0
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment