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
0d0d82fd
Commit
0d0d82fd
authored
Nov 02, 2015
by
octal
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Refactored a little bit the API. Peer is not a reference anymore but
instead is a shared_ptr
parent
2603f15f
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
233 additions
and
136 deletions
+233
-136
main.cc
main.cc
+11
-11
src/http.cc
src/http.cc
+118
-59
src/http.h
src/http.h
+87
-50
src/listener.cc
src/listener.cc
+12
-11
src/listener.h
src/listener.h
+5
-5
No files found.
main.cc
View file @
0d0d82fd
...
@@ -8,28 +8,28 @@
...
@@ -8,28 +8,28 @@
using
namespace
std
;
using
namespace
std
;
class
MyHandler
:
public
Net
::
Http
::
Handler
{
class
MyHandler
:
public
Net
::
Http
::
Handler
{
void
onRequest
(
const
Net
::
Http
::
Request
&
req
,
Net
::
Tcp
::
Peer
&
peer
)
{
void
onRequest
(
const
Net
::
Http
::
Request
&
req
,
Net
::
Http
::
Response
response
)
{
if
(
req
.
resource
==
"/ping"
)
{
if
(
req
.
resource
()
==
"/ping"
)
{
if
(
req
.
method
==
Net
::
Http
::
Method
::
Get
)
{
if
(
req
.
method
()
==
Net
::
Http
::
Method
::
Get
)
{
using
namespace
Net
::
Http
;
using
namespace
Net
::
Http
;
Net
::
Http
::
Response
response
(
Net
::
Http
::
Code
::
Ok
,
"PONG"
);
response
.
headers
()
response
.
headers
.
add
(
std
::
make_shared
<
Header
::
Server
>
(
"lys"
))
.
add
(
std
::
make_shared
<
Header
::
Server
>
(
"lys"
))
.
add
(
std
::
make_shared
<
Header
::
ContentType
>
(
MIME
(
Text
,
Plain
)));
.
add
(
std
::
make_shared
<
Header
::
ContentType
>
(
MIME
(
Text
,
Plain
)));
response
.
writeTo
(
peer
);
response
.
send
(
Net
::
Http
::
Code
::
Ok
,
"PONG"
);
}
}
}
}
else
if
(
req
.
resource
==
"/echo"
)
{
else
if
(
req
.
resource
()
==
"/echo"
)
{
if
(
req
.
method
==
Net
::
Http
::
Method
::
Post
)
{
if
(
req
.
method
()
==
Net
::
Http
::
Method
::
Post
)
{
Net
::
Http
::
Response
response
(
Net
::
Http
::
Code
::
Ok
,
req
.
body
);
response
.
send
(
Net
::
Http
::
Code
::
Ok
,
req
.
body
());
response
.
writeTo
(
peer
);
}
}
}
}
else
if
(
req
.
resource
()
==
"/exception"
)
{
throw
std
::
runtime_error
(
"Exception thrown in the handler"
);
}
}
}
};
};
...
...
src/http.cc
View file @
0d0d82fd
...
@@ -32,12 +32,12 @@ static constexpr const char* ParserData = "__Parser";
...
@@ -32,12 +32,12 @@ static constexpr const char* ParserData = "__Parser";
namespace
Private
{
namespace
Private
{
void
void
Parser
::
Step
::
raise
(
const
char
*
msg
,
Code
code
/* = Code::Bad_Request */
)
{
Step
::
raise
(
const
char
*
msg
,
Code
code
/* = Code::Bad_Request */
)
{
throw
HttpError
(
code
,
msg
);
throw
HttpError
(
code
,
msg
);
}
}
Parser
::
State
State
Parser
::
RequestLineStep
::
apply
(
StreamCursor
&
cursor
)
{
RequestLineStep
::
apply
(
StreamCursor
&
cursor
)
{
StreamCursor
::
Revert
revert
(
cursor
);
StreamCursor
::
Revert
revert
(
cursor
);
// Method
// Method
...
@@ -59,7 +59,7 @@ namespace Private {
...
@@ -59,7 +59,7 @@ namespace Private {
bool
found
=
false
;
bool
found
=
false
;
for
(
const
auto
&
method
:
Methods
)
{
for
(
const
auto
&
method
:
Methods
)
{
if
(
match_raw
(
method
.
str
,
method
.
len
,
cursor
))
{
if
(
match_raw
(
method
.
str
,
method
.
len
,
cursor
))
{
request
->
method
=
method
.
repr
;
request
->
method
_
=
method
.
repr
;
found
=
true
;
found
=
true
;
break
;
break
;
}
}
...
@@ -83,7 +83,7 @@ namespace Private {
...
@@ -83,7 +83,7 @@ namespace Private {
if
(
!
cursor
.
advance
(
1
))
return
State
::
Again
;
if
(
!
cursor
.
advance
(
1
))
return
State
::
Again
;
}
}
request
->
resource
=
std
::
string
(
cursor
.
offset
(
start
),
cursor
.
diff
(
start
)
+
1
);
request
->
resource
_
=
std
::
string
(
cursor
.
offset
(
start
),
cursor
.
diff
(
start
)
+
1
);
if
((
n
=
cursor
.
next
())
==
StreamCursor
::
Eof
)
return
State
::
Again
;
if
((
n
=
cursor
.
next
())
==
StreamCursor
::
Eof
)
return
State
::
Again
;
if
(
n
!=
' '
)
if
(
n
!=
' '
)
...
@@ -100,10 +100,10 @@ namespace Private {
...
@@ -100,10 +100,10 @@ namespace Private {
const
size_t
diff
=
cursor
.
diff
(
start
);
const
size_t
diff
=
cursor
.
diff
(
start
);
if
(
strncmp
(
cursor
.
offset
(
start
),
"HTTP/1.0"
,
diff
)
==
0
)
{
if
(
strncmp
(
cursor
.
offset
(
start
),
"HTTP/1.0"
,
diff
)
==
0
)
{
request
->
version
=
Version
::
Http10
;
request
->
version
_
=
Version
::
Http10
;
}
}
else
if
(
strncmp
(
cursor
.
offset
(
start
),
"HTTP/1.1"
,
diff
)
==
0
)
{
else
if
(
strncmp
(
cursor
.
offset
(
start
),
"HTTP/1.1"
,
diff
)
==
0
)
{
request
->
version
=
Version
::
Http11
;
request
->
version
_
=
Version
::
Http11
;
}
}
else
{
else
{
raise
(
"Encountered invalid HTTP version"
);
raise
(
"Encountered invalid HTTP version"
);
...
@@ -116,8 +116,8 @@ namespace Private {
...
@@ -116,8 +116,8 @@ namespace Private {
}
}
Parser
::
State
State
Parser
::
HeadersStep
::
apply
(
StreamCursor
&
cursor
)
{
HeadersStep
::
apply
(
StreamCursor
&
cursor
)
{
StreamCursor
::
Revert
revert
(
cursor
);
StreamCursor
::
Revert
revert
(
cursor
);
while
(
!
cursor
.
eol
())
{
while
(
!
cursor
.
eol
())
{
...
@@ -147,11 +147,11 @@ namespace Private {
...
@@ -147,11 +147,11 @@ namespace Private {
if
(
Header
::
Registry
::
isRegistered
(
name
))
{
if
(
Header
::
Registry
::
isRegistered
(
name
))
{
std
::
shared_ptr
<
Header
::
Header
>
header
=
Header
::
Registry
::
makeHeader
(
name
);
std
::
shared_ptr
<
Header
::
Header
>
header
=
Header
::
Registry
::
makeHeader
(
name
);
header
->
parseRaw
(
cursor
.
offset
(
start
),
cursor
.
diff
(
start
));
header
->
parseRaw
(
cursor
.
offset
(
start
),
cursor
.
diff
(
start
));
request
->
headers
.
add
(
header
);
request
->
headers
_
.
add
(
header
);
}
}
else
{
else
{
std
::
string
value
(
cursor
.
offset
(
start
),
cursor
.
diff
(
start
));
std
::
string
value
(
cursor
.
offset
(
start
),
cursor
.
diff
(
start
));
request
->
headers
.
addRaw
(
Header
::
Raw
(
std
::
move
(
name
),
std
::
move
(
value
)));
request
->
headers
_
.
addRaw
(
Header
::
Raw
(
std
::
move
(
name
),
std
::
move
(
value
)));
}
}
// CRLF
// CRLF
...
@@ -161,13 +161,13 @@ namespace Private {
...
@@ -161,13 +161,13 @@ namespace Private {
}
}
revert
.
ignore
();
revert
.
ignore
();
return
Parser
::
State
::
Next
;
return
State
::
Next
;
}
}
Parser
::
State
State
Parser
::
BodyStep
::
apply
(
StreamCursor
&
cursor
)
{
BodyStep
::
apply
(
StreamCursor
&
cursor
)
{
auto
cl
=
request
->
headers
.
tryGet
<
Header
::
ContentLength
>
();
auto
cl
=
request
->
headers
_
.
tryGet
<
Header
::
ContentLength
>
();
if
(
!
cl
)
return
Parser
::
State
::
Done
;
if
(
!
cl
)
return
State
::
Done
;
auto
contentLength
=
cl
->
value
();
auto
contentLength
=
cl
->
value
();
// We already started to read some bytes but we got an incomplete payload
// We already started to read some bytes but we got an incomplete payload
...
@@ -181,14 +181,14 @@ namespace Private {
...
@@ -181,14 +181,14 @@ namespace Private {
if
(
!
cursor
.
advance
(
remaining
))
{
if
(
!
cursor
.
advance
(
remaining
))
{
const
size_t
available
=
cursor
.
remaining
();
const
size_t
available
=
cursor
.
remaining
();
request
->
body
.
append
(
cursor
.
offset
(
start
),
available
);
request
->
body
_
.
append
(
cursor
.
offset
(
start
),
available
);
bytesRead
+=
available
;
bytesRead
+=
available
;
cursor
.
advance
(
available
);
cursor
.
advance
(
available
);
return
State
::
Again
;
return
State
::
Again
;
}
}
else
{
else
{
request
->
body
.
append
(
cursor
.
offset
(),
remaining
);
request
->
body
_
.
append
(
cursor
.
offset
(),
remaining
);
}
}
}
}
...
@@ -196,7 +196,7 @@ namespace Private {
...
@@ -196,7 +196,7 @@ namespace Private {
else
{
else
{
if
(
!
cursor
.
advance
(
2
))
return
State
::
Again
;
if
(
!
cursor
.
advance
(
2
))
return
State
::
Again
;
request
->
body
.
reserve
(
contentLength
);
request
->
body
_
.
reserve
(
contentLength
);
auto
start
=
cursor
;
auto
start
=
cursor
;
...
@@ -204,21 +204,21 @@ namespace Private {
...
@@ -204,21 +204,21 @@ namespace Private {
if
(
!
cursor
.
advance
(
contentLength
))
{
if
(
!
cursor
.
advance
(
contentLength
))
{
const
size_t
available
=
cursor
.
remaining
();
const
size_t
available
=
cursor
.
remaining
();
request
->
body
.
append
(
cursor
.
offset
(
start
),
available
);
request
->
body
_
.
append
(
cursor
.
offset
(
start
),
available
);
bytesRead
+=
available
;
bytesRead
+=
available
;
cursor
.
advance
(
available
);
cursor
.
advance
(
available
);
return
State
::
Again
;
return
State
::
Again
;
}
}
request
->
body
.
append
(
cursor
.
offset
(
start
),
contentLength
);
request
->
body
_
.
append
(
cursor
.
offset
(
start
),
contentLength
);
}
}
bytesRead
=
0
;
bytesRead
=
0
;
return
Parser
::
State
::
Done
;
return
State
::
Done
;
}
}
Parser
::
State
State
Parser
::
parse
()
{
Parser
::
parse
()
{
State
state
=
State
::
Again
;
State
state
=
State
::
Again
;
do
{
do
{
...
@@ -245,88 +245,147 @@ namespace Private {
...
@@ -245,88 +245,147 @@ namespace Private {
currentStep
=
0
;
currentStep
=
0
;
request
.
headers
.
clear
();
request
.
headers
_
.
clear
();
request
.
body
.
clear
();
request
.
body
_
.
clear
();
request
.
resource
.
clear
();
request
.
resource
_
.
clear
();
}
}
}
// namespace Private
}
// namespace Private
Message
::
Message
()
Message
::
Message
()
:
version
(
Version
::
Http11
)
:
version
_
(
Version
::
Http11
)
{
}
{
}
Request
::
Request
()
Request
::
Request
()
:
Message
()
:
Message
()
{
}
{
}
Response
::
Response
(
int
code
,
std
::
string
body
)
Version
{
Request
::
version
()
const
{
this
->
body
=
std
::
move
(
body
);
return
version_
;
code_
=
code
;
}
Method
Request
::
method
()
const
{
return
method_
;
}
std
::
string
Request
::
resource
()
const
{
return
resource_
;
}
std
::
string
Request
::
body
()
const
{
return
body_
;
}
}
Response
::
Response
(
Code
code
,
std
::
string
body
)
const
Header
::
Collection
&
Request
::
headers
()
const
{
return
headers_
;
}
Response
::
Response
()
:
Message
()
:
Message
()
{
}
void
Response
::
associatePeer
(
const
std
::
shared_ptr
<
Tcp
::
Peer
>&
peer
)
{
{
this
->
body
=
std
::
move
(
body
);
if
(
peer_
.
use_count
()
>
0
)
code_
=
static_cast
<
int
>
(
code
);
throw
std
::
runtime_error
(
"A peer was already associated to the response"
);
peer_
=
peer
;
}
}
void
ssize_t
Response
::
writeTo
(
Tcp
::
Peer
&
peer
)
Response
::
send
(
Code
code
)
{
return
send
(
code
,
""
);
}
ssize_t
Response
::
send
(
Code
code
,
const
std
::
string
&
body
,
const
Mime
::
MediaType
&
mime
)
{
{
int
fd
=
peer
.
fd
();
int
fd
=
peer
()
->
fd
();
char
buffer
[
Const
::
MaxBuffer
];
char
buffer
[
Const
::
MaxBuffer
];
Io
::
OutArrayBuf
obuf
(
buffer
,
Io
::
Init
::
ZeroOut
);
Io
::
OutArrayBuf
obuf
(
buffer
,
Io
::
Init
::
ZeroOut
);
std
::
ostream
stream
(
&
obuf
);
std
::
ostream
stream
(
&
obuf
);
stream
<<
"HTTP/1.1 "
;
stream
<<
"HTTP/1.1 "
;
stream
<<
code_
;
stream
<<
static_cast
<
int
>
(
code
)
;
stream
<<
' '
;
stream
<<
' '
;
stream
<<
static_cast
<
Code
>
(
code_
)
;
stream
<<
code
;
stream
<<
crlf
;
stream
<<
crlf
;
for
(
const
auto
&
header
:
headers
.
list
())
{
for
(
const
auto
&
header
:
headers
_
.
list
())
{
stream
<<
header
->
name
()
<<
": "
;
stream
<<
header
->
name
()
<<
": "
;
header
->
write
(
stream
);
header
->
write
(
stream
);
stream
<<
crlf
;
stream
<<
crlf
;
}
}
stream
<<
"Content-Length: "
<<
body
.
size
()
<<
crlf
;
if
(
!
body
.
empty
())
{
stream
<<
crlf
;
stream
<<
"Content-Length: "
<<
body
.
size
()
<<
crlf
;
stream
<<
crlf
;
stream
<<
body
;
}
ssize_t
bytes
=
::
send
(
fd
,
buffer
,
obuf
.
len
(),
0
);
return
bytes
;
}
void
Response
::
setMime
(
const
Mime
::
MediaType
&
mime
)
{
headers_
.
add
(
std
::
make_shared
<
Header
::
ContentType
>
(
mime
));
}
Header
::
Collection
&
Response
::
headers
()
{
return
headers_
;
}
const
Header
::
Collection
&
Response
::
headers
()
const
{
return
headers_
;
}
stream
<<
body
;
std
::
shared_ptr
<
Tcp
::
Peer
>
Response
::
peer
()
const
{
if
(
peer_
.
expired
())
{
throw
std
::
runtime_error
(
"Broken pipe"
);
}
ssize_t
bytes
=
send
(
fd
,
buffer
,
obuf
.
len
(),
0
);
return
peer_
.
lock
(
);
}
}
void
void
Handler
::
onInput
(
const
char
*
buffer
,
size_t
len
,
Tcp
::
Peer
&
peer
)
{
Handler
::
onInput
(
const
char
*
buffer
,
size_t
len
,
const
std
::
shared_ptr
<
Tcp
::
Peer
>
&
peer
)
{
try
{
try
{
auto
&
parser
=
getParser
(
peer
);
auto
&
parser
=
getParser
(
peer
);
// scope (failure), {
// parser.reset();
// };
if
(
!
parser
.
feed
(
buffer
,
len
))
{
if
(
!
parser
.
feed
(
buffer
,
len
))
{
parser
.
reset
();
parser
.
reset
();
throw
HttpError
(
Code
::
Request_Entity_Too_Large
,
"Request exceeded maximum buffer size"
);
throw
HttpError
(
Code
::
Request_Entity_Too_Large
,
"Request exceeded maximum buffer size"
);
}
}
auto
state
=
parser
.
parse
();
auto
state
=
parser
.
parse
();
if
(
state
==
Private
::
Parser
::
State
::
Done
)
{
if
(
state
==
Private
::
State
::
Done
)
{
onRequest
(
parser
.
request
,
peer
);
Response
response
;
response
.
associatePeer
(
peer
);
onRequest
(
parser
.
request
,
std
::
move
(
response
));
parser
.
reset
();
parser
.
reset
();
}
}
}
catch
(
const
HttpError
&
err
)
{
}
catch
(
const
HttpError
&
err
)
{
Response
response
(
err
.
code
(),
err
.
reason
());
Response
response
;
response
.
writeTo
(
peer
);
response
.
associatePeer
(
peer
);
response
.
send
(
static_cast
<
Code
>
(
err
.
code
()),
err
.
reason
());
getParser
(
peer
).
reset
();
getParser
(
peer
).
reset
();
}
}
catch
(
const
std
::
exception
&
e
)
{
catch
(
const
std
::
exception
&
e
)
{
Response
response
(
Code
::
Internal_Server_Error
,
e
.
what
());
Response
response
;
response
.
writeTo
(
peer
);
response
.
associatePeer
(
peer
);
response
.
send
(
Code
::
Internal_Server_Error
,
e
.
what
());
getParser
(
peer
).
reset
();
getParser
(
peer
).
reset
();
}
}
}
}
...
@@ -336,17 +395,17 @@ Handler::onOutput() {
...
@@ -336,17 +395,17 @@ Handler::onOutput() {
}
}
void
void
Handler
::
onConnection
(
Tcp
::
Peer
&
peer
)
{
Handler
::
onConnection
(
const
std
::
shared_ptr
<
Tcp
::
Peer
>
&
peer
)
{
peer
.
putData
(
ParserData
,
std
::
make_shared
<
Private
::
Parser
>
());
peer
->
putData
(
ParserData
,
std
::
make_shared
<
Private
::
Parser
>
());
}
}
void
void
Handler
::
onDisconnection
(
Tcp
::
Peer
&
peer
)
{
Handler
::
onDisconnection
(
const
shared_ptr
<
Tcp
::
Peer
>
&
peer
)
{
}
}
Private
::
Parser
&
Private
::
Parser
&
Handler
::
getParser
(
Tcp
::
Peer
&
peer
)
const
{
Handler
::
getParser
(
const
std
::
shared_ptr
<
Tcp
::
Peer
>
&
peer
)
const
{
return
*
peer
.
getData
<
Private
::
Parser
>
(
ParserData
);
return
*
peer
->
getData
<
Private
::
Parser
>
(
ParserData
);
}
}
Endpoint
::
Endpoint
()
Endpoint
::
Endpoint
()
...
...
src/http.h
View file @
0d0d82fd
...
@@ -14,88 +14,127 @@
...
@@ -14,88 +14,127 @@
#include "http_headers.h"
#include "http_headers.h"
#include "http_defs.h"
#include "http_defs.h"
#include "stream.h"
#include "stream.h"
#include "mime.h"
namespace
Net
{
namespace
Net
{
namespace
Http
{
namespace
Http
{
namespace
Private
{
class
Parser
;
class
RequestLineStep
;
class
HeadersStep
;
class
BodyStep
;
}
// 4. HTTP Message
// 4. HTTP Message
class
Message
{
class
Message
{
public:
public:
Message
();
Message
();
Version
version
;
Version
version
_
;
Header
::
Collection
headers
;
Header
::
Collection
headers
_
;
std
::
string
body
;
std
::
string
body
_
;
};
};
// 5. Request
// 5. Request
class
Request
:
p
ublic
Message
{
class
Request
:
p
rivate
Message
{
public:
public:
friend
class
Private
::
RequestLineStep
;
friend
class
Private
::
HeadersStep
;
friend
class
Private
::
BodyStep
;
friend
class
Private
::
Parser
;
Request
();
Request
();
Method
method
;
Version
version
()
const
;
std
::
string
resource
;
Method
method
()
const
;
std
::
string
resource
()
const
;
std
::
string
body
()
const
;
const
Header
::
Collection
&
headers
()
const
;
private:
Method
method_
;
std
::
string
resource_
;
};
};
class
Handler
;
// 6. Response
// 6. Response
class
Response
:
p
ublic
Message
{
class
Response
:
p
rivate
Message
{
public:
public:
Response
(
int
code
,
std
::
string
body
);
friend
class
Handler
;
Response
(
Code
code
,
std
::
string
body
);
Response
(
const
Response
&
other
)
=
delete
;
Response
&
operator
=
(
const
Response
&
other
)
=
delete
;
Response
(
Response
&&
other
)
=
default
;
Response
&
operator
=
(
Response
&&
other
)
=
default
;
void
writeTo
(
Tcp
::
Peer
&
peer
);
Header
::
Collection
&
headers
();
std
::
string
mimeType
;
const
Header
::
Collection
&
headers
()
const
;
void
setMime
(
const
Mime
::
MediaType
&
mime
);
ssize_t
send
(
Code
code
);
ssize_t
send
(
Code
code
,
const
std
::
string
&
body
,
const
Mime
::
MediaType
&
mime
=
Mime
::
MediaType
());
private:
private:
int
code_
;
Response
();
std
::
shared_ptr
<
Tcp
::
Peer
>
peer
()
const
;
void
associatePeer
(
const
std
::
shared_ptr
<
Tcp
::
Peer
>&
peer
);
std
::
weak_ptr
<
Tcp
::
Peer
>
peer_
;
};
};
namespace
Private
{
namespace
Private
{
struct
Parser
{
enum
class
State
{
Again
,
Next
,
Done
};
enum
class
State
{
Again
,
Next
,
Done
};
struct
Step
{
Step
(
Request
*
request
)
:
request
(
request
)
{
}
struct
Step
{
virtual
State
apply
(
StreamCursor
&
cursor
)
=
0
;
Step
(
Request
*
request
)
:
request
(
request
)
{
}
virtual
State
apply
(
StreamCursor
&
cursor
)
=
0
;
void
raise
(
const
char
*
msg
,
Code
code
=
Code
::
Bad_Request
)
;
void
raise
(
const
char
*
msg
,
Code
code
=
Code
::
Bad_Request
);
Request
*
request
;
};
Request
*
request
;
struct
RequestLineStep
:
public
Step
{
};
RequestLineStep
(
Request
*
request
)
:
Step
(
request
)
{
}
struct
RequestLineStep
:
public
Step
{
State
apply
(
StreamCursor
&
cursor
);
RequestLineStep
(
Request
*
request
)
};
:
Step
(
request
)
{
}
State
apply
(
StreamCursor
&
cursor
);
struct
HeadersStep
:
public
Step
{
};
HeadersStep
(
Request
*
request
)
:
Step
(
request
)
{
}
struct
HeadersStep
:
public
Step
{
State
apply
(
StreamCursor
&
cursor
);
HeadersStep
(
Request
*
request
)
};
:
Step
(
request
)
{
}
State
apply
(
StreamCursor
&
cursor
);
struct
BodyStep
:
public
Step
{
};
BodyStep
(
Request
*
request
)
:
Step
(
request
)
,
bytesRead
(
0
)
{
}
struct
BodyStep
:
public
Step
{
State
apply
(
StreamCursor
&
cursor
);
BodyStep
(
Request
*
request
)
:
Step
(
request
)
,
bytesRead
(
0
)
{
}
State
apply
(
StreamCursor
&
cursor
);
private:
size_t
bytesRead
;
};
private:
struct
Parser
{
size_t
bytesRead
;
};
Parser
()
Parser
()
:
contentLength
(
-
1
)
:
contentLength
(
-
1
)
...
@@ -127,8 +166,6 @@ namespace Private {
...
@@ -127,8 +166,6 @@ namespace Private {
State
parse
();
State
parse
();
// Buffer buffer;
// Cursor cursor;
ArrayStreamBuf
<
Const
::
MaxBuffer
>
buffer
;
ArrayStreamBuf
<
Const
::
MaxBuffer
>
buffer
;
StreamCursor
cursor
;
StreamCursor
cursor
;
...
@@ -147,16 +184,16 @@ namespace Private {
...
@@ -147,16 +184,16 @@ namespace Private {
class
Handler
:
public
Net
::
Tcp
::
Handler
{
class
Handler
:
public
Net
::
Tcp
::
Handler
{
public:
public:
void
onInput
(
const
char
*
buffer
,
size_t
len
,
Tcp
::
Peer
&
peer
);
void
onInput
(
const
char
*
buffer
,
size_t
len
,
const
std
::
shared_ptr
<
Tcp
::
Peer
>
&
peer
);
void
onOutput
();
void
onOutput
();
void
onConnection
(
Tcp
::
Peer
&
peer
);
void
onConnection
(
const
std
::
shared_ptr
<
Tcp
::
Peer
>
&
peer
);
void
onDisconnection
(
Tcp
::
Peer
&
peer
);
void
onDisconnection
(
const
std
::
shared_ptr
<
Tcp
::
Peer
>
&
peer
);
virtual
void
onRequest
(
const
Request
&
request
,
Tcp
::
Peer
&
peer
)
=
0
;
virtual
void
onRequest
(
const
Request
&
request
,
Response
response
)
=
0
;
private:
private:
Private
::
Parser
&
getParser
(
Tcp
::
Peer
&
peer
)
const
;
Private
::
Parser
&
getParser
(
const
std
::
shared_ptr
<
Tcp
::
Peer
>
&
peer
)
const
;
};
};
class
Endpoint
{
class
Endpoint
{
...
...
src/listener.cc
View file @
0d0d82fd
...
@@ -118,8 +118,8 @@ IoWorker::pin(const CpuSet& set) {
...
@@ -118,8 +118,8 @@ IoWorker::pin(const CpuSet& set) {
}
}
}
}
std
::
shared_ptr
<
Peer
>
std
::
shared_ptr
<
Peer
>
&
IoWorker
::
getPeer
(
Fd
fd
)
const
IoWorker
::
getPeer
(
Fd
fd
)
{
{
std
::
unique_lock
<
std
::
mutex
>
guard
(
peersMutex
);
std
::
unique_lock
<
std
::
mutex
>
guard
(
peersMutex
);
auto
it
=
peers
.
find
(
fd
);
auto
it
=
peers
.
find
(
fd
);
...
@@ -130,8 +130,8 @@ IoWorker::getPeer(Fd fd) const
...
@@ -130,8 +130,8 @@ IoWorker::getPeer(Fd fd) const
return
it
->
second
;
return
it
->
second
;
}
}
std
::
shared_ptr
<
Peer
>
std
::
shared_ptr
<
Peer
>
&
IoWorker
::
getPeer
(
Polling
::
Tag
tag
)
const
IoWorker
::
getPeer
(
Polling
::
Tag
tag
)
{
{
return
getPeer
(
tag
.
value
());
return
getPeer
(
tag
.
value
());
}
}
...
@@ -153,11 +153,11 @@ IoWorker::handleIncoming(const std::shared_ptr<Peer>& peer) {
...
@@ -153,11 +153,11 @@ IoWorker::handleIncoming(const std::shared_ptr<Peer>& peer) {
if
(
bytes
==
-
1
)
{
if
(
bytes
==
-
1
)
{
if
(
errno
==
EAGAIN
||
errno
==
EWOULDBLOCK
)
{
if
(
errno
==
EAGAIN
||
errno
==
EWOULDBLOCK
)
{
if
(
totalBytes
>
0
)
{
if
(
totalBytes
>
0
)
{
handler_
->
onInput
(
buffer
,
totalBytes
,
*
peer
);
handler_
->
onInput
(
buffer
,
totalBytes
,
peer
);
}
}
}
else
{
}
else
{
if
(
errno
==
ECONNRESET
)
{
if
(
errno
==
ECONNRESET
)
{
handler_
->
onDisconnection
(
*
peer
);
handler_
->
onDisconnection
(
peer
);
close
(
fd
);
close
(
fd
);
}
}
else
{
else
{
...
@@ -167,7 +167,7 @@ IoWorker::handleIncoming(const std::shared_ptr<Peer>& peer) {
...
@@ -167,7 +167,7 @@ IoWorker::handleIncoming(const std::shared_ptr<Peer>& peer) {
break
;
break
;
}
}
else
if
(
bytes
==
0
)
{
else
if
(
bytes
==
0
)
{
handler_
->
onDisconnection
(
*
peer
);
handler_
->
onDisconnection
(
peer
);
close
(
fd
);
close
(
fd
);
break
;
break
;
}
}
...
@@ -192,7 +192,7 @@ IoWorker::handleNewPeer(const std::shared_ptr<Peer>& peer)
...
@@ -192,7 +192,7 @@ IoWorker::handleNewPeer(const std::shared_ptr<Peer>& peer)
peers
.
insert
(
std
::
make_pair
(
fd
,
peer
));
peers
.
insert
(
std
::
make_pair
(
fd
,
peer
));
}
}
handler_
->
onConnection
(
*
peer
);
handler_
->
onConnection
(
peer
);
poller
.
addFd
(
fd
,
NotifyOn
::
Read
,
Polling
::
Tag
(
fd
),
Polling
::
Mode
::
Edge
);
poller
.
addFd
(
fd
,
NotifyOn
::
Read
,
Polling
::
Tag
(
fd
),
Polling
::
Mode
::
Edge
);
}
}
...
@@ -226,7 +226,8 @@ IoWorker::run() {
...
@@ -226,7 +226,8 @@ IoWorker::run() {
}
}
}
else
{
}
else
{
if
(
event
.
flags
.
hasFlag
(
NotifyOn
::
Read
))
{
if
(
event
.
flags
.
hasFlag
(
NotifyOn
::
Read
))
{
handleIncoming
(
getPeer
(
event
.
tag
));
auto
&
peer
=
getPeer
(
event
.
tag
);
handleIncoming
(
peer
);
}
}
}
}
}
}
...
@@ -247,11 +248,11 @@ Handler::~Handler()
...
@@ -247,11 +248,11 @@ Handler::~Handler()
{
}
{
}
void
void
Handler
::
onConnection
(
Tcp
::
Peer
&
peer
)
{
Handler
::
onConnection
(
const
std
::
shared_ptr
<
Tcp
::
Peer
>
&
peer
)
{
}
}
void
void
Handler
::
onDisconnection
(
Tcp
::
Peer
&
peer
)
{
Handler
::
onDisconnection
(
const
std
::
shared_ptr
<
Tcp
::
Peer
>
&
peer
)
{
}
}
Listener
::
Listener
()
Listener
::
Listener
()
...
...
src/listener.h
View file @
0d0d82fd
...
@@ -61,8 +61,8 @@ private:
...
@@ -61,8 +61,8 @@ private:
CpuSet
pins
;
CpuSet
pins
;
std
::
shared_ptr
<
Peer
>
getPeer
(
Fd
fd
)
const
;
std
::
shared_ptr
<
Peer
>
&
getPeer
(
Fd
fd
)
;
std
::
shared_ptr
<
Peer
>
getPeer
(
Polling
::
Tag
tag
)
const
;
std
::
shared_ptr
<
Peer
>
&
getPeer
(
Polling
::
Tag
tag
)
;
void
handleIncoming
(
const
std
::
shared_ptr
<
Peer
>&
peer
);
void
handleIncoming
(
const
std
::
shared_ptr
<
Peer
>&
peer
);
void
handleMailbox
();
void
handleMailbox
();
...
@@ -108,11 +108,11 @@ public:
...
@@ -108,11 +108,11 @@ public:
Handler
();
Handler
();
~
Handler
();
~
Handler
();
virtual
void
onInput
(
const
char
*
buffer
,
size_t
len
,
Tcp
::
Peer
&
peer
)
=
0
;
virtual
void
onInput
(
const
char
*
buffer
,
size_t
len
,
const
std
::
shared_ptr
<
Tcp
::
Peer
>
&
peer
)
=
0
;
virtual
void
onOutput
()
=
0
;
virtual
void
onOutput
()
=
0
;
virtual
void
onConnection
(
Tcp
::
Peer
&
peer
);
virtual
void
onConnection
(
const
std
::
shared_ptr
<
Tcp
::
Peer
>
&
peer
);
virtual
void
onDisconnection
(
Tcp
::
Peer
&
peer
);
virtual
void
onDisconnection
(
const
std
::
shared_ptr
<
Tcp
::
Peer
>
&
peer
);
};
};
...
...
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