Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ISC Open Source Projects
Kea
Commits
4c23ca08
Commit
4c23ca08
authored
Jan 16, 2018
by
Tomek Mrugalski
🛰
Browse files
[5451] Various changes after review.
parent
e7fda30c
Changes
6
Hide whitespace changes
Inline
Side-by-side
src/lib/asiolink/tcp_socket.h
View file @
4c23ca08
...
...
@@ -92,7 +92,8 @@ public:
/// \brief Checks if the connection is usable.
///
/// The connection is usable if the peer has closed it.
/// The connection is usable if the socket is open and the peer has not
/// closed its connection.
///
/// \return true if the connection is usable.
bool
isUsable
()
const
{
...
...
src/lib/http/client.cc
View file @
4c23ca08
...
...
@@ -269,7 +269,7 @@ public:
HttpResponsePtr
&
response
,
long
&
request_timeout
,
HttpClient
::
RequestHandler
&
callback
)
{
// Check if the is a queue for this URL. If there is no queue, there
// Check if the
re
is a queue for this URL. If there is no queue, there
// is no request queued either.
auto
it
=
queue_
.
find
(
url
);
if
(
it
!=
queue_
.
end
())
{
...
...
@@ -580,7 +580,7 @@ Connection::sendCallback(const boost::system::error_code& ec, size_t length) {
}
// If there is no more data to be sent, start receiving a response. Otherwise,
// continue
receiv
ing.
// continue
send
ing.
if
(
buf_
.
empty
())
{
doReceive
();
...
...
src/lib/http/tests/response_parser_unittests.cc
View file @
4c23ca08
...
...
@@ -68,6 +68,58 @@ public:
EXPECT_FALSE
(
parser
.
getErrorMessage
().
empty
());
}
/// @brief Tests that the response specified with (header, body) can
/// be parsed properly.
///
/// @param header specifies the header of the response to be parsed
/// @param json specifies the body of the response (JSON in text format) to be parsed
/// @param expect_success whether the parsing is expected to be successful
///
/// @return a parser that parsed the response for further inspection
HttpResponseJson
testResponseWithJson
(
const
std
::
string
&
header
,
const
std
::
string
&
json
,
bool
expect_success
=
true
)
{
std
::
string
http_resp
=
createResponseString
(
header
,
json
);
// Create HTTP response which accepts JSON as a body.
HttpResponseJson
response
;
// Create a parser and make it use the response we created.
HttpResponseParser
parser
(
response
);
EXPECT_NO_THROW
(
parser
.
initModel
());
// Simulate receiving HTTP response in chunks.
const
unsigned
chunk_size
=
10
;
while
(
!
http_resp
.
empty
())
{
size_t
chunk
=
http_resp
.
size
()
%
chunk_size
;
if
(
chunk
==
0
)
{
chunk
=
chunk_size
;
}
parser
.
postBuffer
(
&
http_resp
[
0
],
chunk
);
http_resp
.
erase
(
0
,
chunk
);
parser
.
poll
();
if
(
chunk
<
chunk_size
)
{
EXPECT_TRUE
(
parser
.
needData
());
if
(
!
parser
.
needData
())
{
ADD_FAILURE
()
<<
"Parser completed prematurely"
;
return
(
response
);
}
}
}
if
(
expect_success
)
{
// Parser should have parsed the response and should expect no more data.
EXPECT_FALSE
(
parser
.
needData
());
// Parsing should be successful.
EXPECT_TRUE
(
parser
.
httpParseOk
())
<<
parser
.
getErrorMessage
();
// There should be no error message.
EXPECT_TRUE
(
parser
.
getErrorMessage
().
empty
());
}
return
(
response
);
}
/// @brief Instance of the HttpResponse used by the unit tests.
HttpResponse
response_
;
};
...
...
@@ -79,37 +131,7 @@ TEST_F(HttpResponseParserTest, responseWithJson) {
"Content-Type: application/json
\r\n
"
;
std
::
string
json
=
"{
\"
result
\"
: 0,
\"
text
\"
:
\"
All ok
\"
}"
;
http_resp
=
createResponseString
(
http_resp
,
json
);
// Create HTTP response which accepts JSON as a body.
HttpResponseJson
response
;
// Create a parser and make it use the response we created.
HttpResponseParser
parser
(
response
);
ASSERT_NO_THROW
(
parser
.
initModel
());
// Simulate receiving HTTP response in chunks.
const
unsigned
chunk_size
=
10
;
while
(
!
http_resp
.
empty
())
{
size_t
chunk
=
http_resp
.
size
()
%
chunk_size
;
if
(
chunk
==
0
)
{
chunk
=
chunk_size
;
}
parser
.
postBuffer
(
&
http_resp
[
0
],
chunk
);
http_resp
.
erase
(
0
,
chunk
);
parser
.
poll
();
if
(
chunk
<
chunk_size
)
{
ASSERT_TRUE
(
parser
.
needData
());
}
}
// Parser should have parsed the response and should expect no more data.
ASSERT_FALSE
(
parser
.
needData
());
// Parsing should be successful.
ASSERT_TRUE
(
parser
.
httpParseOk
())
<<
parser
.
getErrorMessage
();
// There should be no error message.
EXPECT_TRUE
(
parser
.
getErrorMessage
().
empty
());
HttpResponseJson
response
=
testResponseWithJson
(
http_resp
,
json
);
// Verify HTTP version, status code and phrase.
EXPECT_EQ
(
1
,
response
.
getHttpVersion
().
major_
);
...
...
@@ -166,8 +188,8 @@ TEST_F(HttpResponseParserTest, extraneousDataInResponse) {
EXPECT_TRUE
(
parser
.
getErrorMessage
().
empty
());
}
// This test verifies that LWS is parsed correctly. The LWS
marks line breaks
// in the HTTP header values.
// This test verifies that LWS is parsed correctly. The LWS
(linear white
//
space) marks line breaks
in the HTTP header values.
TEST_F
(
HttpResponseParserTest
,
getLWS
)
{
// "User-Agent" header contains line breaks with whitespaces in the new
// lines to mark continuation of the header value.
...
...
src/lib/http/tests/server_client_unittests.cc
View file @
4c23ca08
...
...
@@ -1236,7 +1236,7 @@ TEST_F(HttpClientTest, clientRequestTimeout) {
PostHttpRequestJsonPtr
request2
=
createRequest
(
"sequence"
,
1
);
HttpResponseJsonPtr
response2
(
new
HttpResponseJson
());
ASSERT_NO_THROW
(
client
.
asyncSendRequest
(
url
,
request2
,
response2
,
[
this
,
&
cb_num
](
const
boost
::
system
::
error_code
&
ec
,
const
HttpResponsePtr
&
,
[
this
,
&
cb_num
](
const
boost
::
system
::
error_code
&
/*ec*/
,
const
HttpResponsePtr
&
,
const
std
::
string
&
)
{
if
(
++
cb_num
>
1
)
{
io_service_
.
stop
();
...
...
src/lib/http/url.cc
View file @
4c23ca08
// Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2017
-2018
Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
...
...
@@ -80,18 +80,18 @@ Url::parse() {
port_
=
0
;
path_
.
clear
();
std
::
ostringstream
e
;
std
::
ostringstream
e
rror
;
// Retrieve scheme
size_t
p
=
url_
.
find
(
":"
);
if
((
p
==
0
)
||
(
p
==
std
::
string
::
npos
))
{
e
<<
"url "
<<
url_
<<
" lacks http or https scheme"
;
error_message_
=
e
.
str
();
size_t
offset
=
url_
.
find
(
":"
);
if
((
offset
==
0
)
||
(
offset
==
std
::
string
::
npos
))
{
e
rror
<<
"url "
<<
url_
<<
" lacks http or https scheme"
;
error_message_
=
e
rror
.
str
();
return
;
}
// Validate scheme.
std
::
string
scheme
=
url_
.
substr
(
0
,
p
);
std
::
string
scheme
=
url_
.
substr
(
0
,
offset
);
if
(
scheme
==
"http"
)
{
scheme_
=
Url
::
HTTP
;
...
...
@@ -99,87 +99,87 @@ Url::parse() {
scheme_
=
Url
::
HTTPS
;
}
else
{
e
<<
"invalid scheme "
<<
scheme
<<
" in "
<<
url_
;
error_message_
=
e
.
str
();
e
rror
<<
"invalid scheme "
<<
scheme
<<
" in "
<<
url_
;
error_message_
=
e
rror
.
str
();
return
;
}
// Colon and two slashes should follow the scheme
if
(
url_
.
substr
(
p
,
3
)
!=
"://"
)
{
e
<<
"expected :// after scheme in "
<<
url_
;
error_message_
=
e
.
str
();
if
(
url_
.
substr
(
offset
,
3
)
!=
"://"
)
{
e
rror
<<
"expected :// after scheme in "
<<
url_
;
error_message_
=
e
rror
.
str
();
return
;
}
// Move forward to hostname.
p
+=
3
;
if
(
p
>=
url_
.
length
())
{
e
<<
"hostname missing in "
<<
url_
;
error_message_
=
e
.
str
();
offset
+=
3
;
if
(
offset
>=
url_
.
length
())
{
e
rror
<<
"hostname missing in "
<<
url_
;
error_message_
=
e
rror
.
str
();
return
;
}
size_t
h
=
0
;
size_t
offset2
=
0
;
// IPv6 address is specified within [ ].
if
(
url_
.
at
(
p
)
==
'['
)
{
h
=
url_
.
find
(
']'
,
p
);
if
(
h
==
std
::
string
::
npos
)
{
e
<<
"expected ] after IPv6 address in "
<<
url_
;
error_message_
=
e
.
str
();
if
(
url_
.
at
(
offset
)
==
'['
)
{
offset2
=
url_
.
find
(
']'
,
offset
);
if
(
offset2
==
std
::
string
::
npos
)
{
e
rror
<<
"expected ] after IPv6 address in "
<<
url_
;
error_message_
=
e
rror
.
str
();
return
;
}
else
if
(
h
==
p
+
1
)
{
e
<<
"expected IPv6 address within [] in "
<<
url_
;
error_message_
=
e
.
str
();
}
else
if
(
offset2
==
offset
+
1
)
{
e
rror
<<
"expected IPv6 address within [] in "
<<
url_
;
error_message_
=
e
rror
.
str
();
return
;
}
// Move one character beyond the ].
++
h
;
++
offset2
;
}
else
{
// There is a normal hostname or IPv4 address. It is terminated
// by the colon (for port number), a slash (if no port number) or
// goes up to the end of the URL.
h
=
url_
.
find
(
":"
,
p
);
if
(
h
==
std
::
string
::
npos
)
{
h
=
url_
.
find
(
"/"
,
p
);
if
(
h
==
std
::
string
::
npos
)
{
offset2
=
url_
.
find
(
":"
,
offset
);
if
(
offset2
==
std
::
string
::
npos
)
{
offset2
=
url_
.
find
(
"/"
,
offset
);
if
(
offset2
==
std
::
string
::
npos
)
{
// No port number and no slash.
h
=
url_
.
length
();
offset2
=
url_
.
length
();
}
}
}
// Extract the hostname.
hostname_
=
url_
.
substr
(
p
,
h
-
p
);
hostname_
=
url_
.
substr
(
offset
,
offset2
-
offset
);
// If there is no port number and no path, simply return and mark the
// URL as valid.
if
(
h
==
url_
.
length
())
{
if
(
offset2
==
url_
.
length
())
{
valid_
=
true
;
return
;
}
// If there is a port number, we need to read it and convert to
// numeric value.
if
(
url_
.
at
(
h
)
==
':'
)
{
if
(
h
==
url_
.
length
()
-
1
)
{
e
<<
"expected port number after : in "
<<
url_
;
error_message_
=
e
.
str
();
if
(
url_
.
at
(
offset2
)
==
':'
)
{
if
(
offset2
==
url_
.
length
()
-
1
)
{
e
rror
<<
"expected port number after : in "
<<
url_
;
error_message_
=
e
rror
.
str
();
return
;
}
// Move to the port number.
++
h
;
++
offset2
;
// Port number may be terminated by a slash or by the end of URL.
size_t
s
=
url_
.
find
(
'/'
,
h
);
size_t
s
lash_offset
=
url_
.
find
(
'/'
,
offset2
);
std
::
string
port_str
;
if
(
s
==
std
::
string
::
npos
)
{
port_str
=
url_
.
substr
(
h
);
if
(
s
lash_offset
==
std
::
string
::
npos
)
{
port_str
=
url_
.
substr
(
offset2
);
}
else
{
port_str
=
url_
.
substr
(
h
,
s
-
h
);
port_str
=
url_
.
substr
(
offset2
,
slash_offset
-
offset2
);
}
try
{
...
...
@@ -187,18 +187,18 @@ Url::parse() {
port_
=
boost
::
lexical_cast
<
unsigned
>
(
port_str
);
}
catch
(...)
{
e
<<
"invalid port number "
<<
port_str
<<
" in "
<<
url_
;
error_message_
=
e
.
str
();
e
rror
<<
"invalid port number "
<<
port_str
<<
" in "
<<
url_
;
error_message_
=
e
rror
.
str
();
return
;
}
// Go to the end of the port section.
h
=
s
;
offset2
=
slash_offset
;
}
// If there is anything left in the URL, we consider it a path.
if
(
h
!=
std
::
string
::
npos
)
{
path_
=
url_
.
substr
(
h
);
if
(
offset2
!=
std
::
string
::
npos
)
{
path_
=
url_
.
substr
(
offset2
);
}
valid_
=
true
;
...
...
src/lib/http/url.h
View file @
4c23ca08
// Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2017
-2018
Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
...
...
@@ -13,7 +13,7 @@
namespace
isc
{
namespace
http
{
/// @brief Represents URL.
/// @brief Represents
an
URL.
///
/// It parses the provided URL and allows for retrieving the parts
/// of it after parsing.
...
...
@@ -33,6 +33,12 @@ public:
/// @param url URL.
explicit
Url
(
const
std
::
string
&
url
);
/// @brief compares URLs lexically.
///
/// Both URLs are compared as text.
///
/// @param url URL to be compared with
/// @return true if the other operator is larger (in lexical sense)
bool
operator
<
(
const
Url
&
url
)
const
;
/// @brief Checks if the URL is valid.
...
...
Write
Preview
Supports
Markdown
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