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
cf26bf91
Commit
cf26bf91
authored
Nov 03, 2015
by
octal
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Now parsing query parameters in the Uri
parent
feb47116
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
133 additions
and
20 deletions
+133
-20
main.cc
main.cc
+1
-1
src/http.cc
src/http.cc
+89
-18
src/http.h
src/http.h
+18
-0
src/http_header.h
src/http_header.h
+1
-0
src/mime.cc
src/mime.cc
+5
-0
src/mime.h
src/mime.h
+1
-0
src/peer.cc
src/peer.cc
+7
-0
src/peer.h
src/peer.h
+2
-0
src/stream.h
src/stream.h
+9
-1
No files found.
main.cc
View file @
cf26bf91
...
...
@@ -24,7 +24,7 @@ class MyHandler : public Net::Http::Handler {
}
else
if
(
req
.
resource
()
==
"/echo"
)
{
if
(
req
.
method
()
==
Net
::
Http
::
Method
::
Post
)
{
response
.
send
(
Net
::
Http
::
Code
::
Ok
,
req
.
body
());
response
.
send
(
Net
::
Http
::
Code
::
Ok
,
req
.
body
()
,
MIME
(
Text
,
Plain
)
);
}
}
else
if
(
req
.
resource
()
==
"/exception"
)
{
...
...
src/http.cc
View file @
cf26bf91
...
...
@@ -27,6 +27,17 @@ std::basic_ostream<CharT, Traits>& crlf(std::basic_ostream<CharT, Traits>& os) {
os
.
write
(
CRLF
,
2
);
}
template
<
typename
H
,
typename
Stream
,
typename
...
Args
>
typename
std
::
enable_if
<
Header
::
IsHeader
<
H
>::
value
,
void
>::
type
writeHeader
(
Stream
&
stream
,
Args
&&
...
args
)
{
H
header
(
std
::
forward
<
Args
>
(
args
)...);
stream
<<
H
::
Name
<<
": "
;
header
.
write
(
stream
);
stream
<<
crlf
;
}
static
constexpr
const
char
*
ParserData
=
"__Parser"
;
namespace
Private
{
...
...
@@ -77,32 +88,54 @@ namespace Private {
if
(
!
cursor
.
advance
(
1
))
return
State
::
Again
;
size_t
start
=
cursor
;
StreamCursor
::
Token
resToken
(
cursor
);
while
((
n
=
cursor
.
current
())
!=
'?'
&&
n
!=
' '
)
if
(
!
cursor
.
advance
(
1
))
return
State
::
Again
;
request
->
resource_
=
resToken
.
text
();
while
((
n
=
cursor
.
next
())
!=
StreamCursor
::
Eof
&&
n
!=
' '
)
{
// Query parameters of the Uri
if
(
n
==
'?'
)
{
if
(
!
cursor
.
advance
(
1
))
return
State
::
Again
;
}
request
->
resource_
=
std
::
string
(
cursor
.
offset
(
start
),
cursor
.
diff
(
start
)
+
1
);
if
((
n
=
cursor
.
next
())
==
StreamCursor
::
Eof
)
return
State
::
Again
;
while
((
n
=
cursor
.
current
())
!=
' '
)
{
StreamCursor
::
Token
keyToken
(
cursor
);
if
(
!
match_until
(
'='
,
cursor
))
return
State
::
Again
;
if
(
n
!=
' '
)
raise
(
"Malformed HTTP request after Request-URI"
);
std
::
string
key
=
keyToken
.
text
();
if
(
!
cursor
.
advance
(
1
))
return
State
::
Again
;
StreamCursor
::
Token
valueToken
(
cursor
);
if
(
!
match_until
({
' '
,
'&'
},
cursor
))
return
State
::
Again
;
std
::
string
value
=
valueToken
.
text
();
request
->
query_
.
add
(
std
::
move
(
key
),
std
::
move
(
value
));
if
(
cursor
.
current
()
==
'&'
)
{
if
(
!
cursor
.
advance
(
1
))
return
State
::
Again
;
}
}
}
// @Todo: Fragment
// SP
if
(
!
cursor
.
advance
(
2
))
return
State
::
Again
;
if
(
!
cursor
.
advance
(
1
))
return
State
::
Again
;
// HTTP-Version
start
=
cursor
;
StreamCursor
::
Token
versionToken
(
cursor
)
;
while
(
!
cursor
.
eol
())
if
(
!
cursor
.
advance
(
1
))
return
State
::
Again
;
const
size_t
diff
=
cursor
.
diff
(
start
);
if
(
strncmp
(
cursor
.
offset
(
start
),
"HTTP/1.0"
,
diff
)
==
0
)
{
const
char
*
ver
=
versionToken
.
rawText
();
const
size_t
size
=
versionToken
.
size
();
if
(
strncmp
(
ver
,
"HTTP/1.0"
,
size
)
==
0
)
{
request
->
version_
=
Version
::
Http10
;
}
else
if
(
strncmp
(
cursor
.
offset
(
start
),
"HTTP/1.1"
,
diff
)
==
0
)
{
else
if
(
strncmp
(
ver
,
"HTTP/1.1"
,
size
)
==
0
)
{
request
->
version_
=
Version
::
Http11
;
}
else
{
...
...
@@ -256,6 +289,31 @@ Message::Message()
:
version_
(
Version
::
Http11
)
{
}
namespace
Uri
{
Query
::
Query
()
{
}
Query
::
Query
(
std
::
initializer_list
<
std
::
pair
<
const
std
::
string
,
std
::
string
>>
params
)
:
params
(
params
)
{
}
void
Query
::
add
(
std
::
string
name
,
std
::
string
value
)
{
params
.
insert
(
std
::
make_pair
(
std
::
move
(
name
),
std
::
move
(
value
)));
}
Optional
<
std
::
string
>
Query
::
get
(
const
std
::
string
&
name
)
const
{
auto
it
=
params
.
find
(
name
);
if
(
it
==
std
::
end
(
params
))
return
None
();
return
Some
(
it
->
second
);
}
}
// namespace Uri
Request
::
Request
()
:
Message
()
{
}
...
...
@@ -285,6 +343,11 @@ Request::headers() const {
return
headers_
;
}
const
Uri
::
Query
&
Request
::
query
()
const
{
return
query_
;
}
Response
::
Response
()
:
Message
()
{
}
...
...
@@ -306,8 +369,6 @@ Response::send(Code code) {
ssize_t
Response
::
send
(
Code
code
,
const
std
::
string
&
body
,
const
Mime
::
MediaType
&
mime
)
{
int
fd
=
peer
()
->
fd
();
char
buffer
[
Const
::
MaxBuffer
];
Io
::
OutArrayBuf
obuf
(
buffer
,
Io
::
Init
::
ZeroOut
);
...
...
@@ -318,6 +379,15 @@ Response::send(Code code, const std::string& body, const Mime::MediaType& mime)
stream
<<
code
;
stream
<<
crlf
;
if
(
mime
.
isValid
())
{
auto
contentType
=
headers_
.
tryGet
<
Header
::
ContentType
>
();
if
(
contentType
)
contentType
->
setMime
(
mime
);
else
{
writeHeader
<
Header
::
ContentType
>
(
stream
,
mime
);
}
}
for
(
const
auto
&
header
:
headers_
.
list
())
{
stream
<<
header
->
name
()
<<
": "
;
header
->
write
(
stream
);
...
...
@@ -325,14 +395,15 @@ Response::send(Code code, const std::string& body, const Mime::MediaType& mime)
}
if
(
!
body
.
empty
())
{
stream
<<
"Content-Length: "
<<
body
.
size
()
<<
crlf
;
writeHeader
<
Header
::
ContentLength
>
(
stream
,
body
.
size
())
;
stream
<<
crlf
;
stream
<<
body
;
}
else
{
stream
<<
crlf
;
}
ssize_t
bytes
=
::
send
(
fd
,
buffer
,
obuf
.
len
(),
0
);
return
bytes
;
return
peer
()
->
send
(
buffer
,
obuf
.
len
());
}
void
...
...
src/http.h
View file @
cf26bf91
...
...
@@ -37,6 +37,22 @@ public:
std
::
string
body_
;
};
namespace
Uri
{
typedef
std
::
string
Fragment
;
class
Query
{
public:
Query
();
Query
(
std
::
initializer_list
<
std
::
pair
<
const
std
::
string
,
std
::
string
>>
params
);
void
add
(
std
::
string
name
,
std
::
string
value
);
Optional
<
std
::
string
>
get
(
const
std
::
string
&
name
)
const
;
private:
std
::
unordered_map
<
std
::
string
,
std
::
string
>
params
;
};
}
// namespace Uri
// 5. Request
class
Request
:
private
Message
{
public:
...
...
@@ -54,10 +70,12 @@ public:
std
::
string
body
()
const
;
const
Header
::
Collection
&
headers
()
const
;
const
Uri
::
Query
&
query
()
const
;
private:
Method
method_
;
std
::
string
resource_
;
Uri
::
Query
query_
;
};
class
Handler
;
...
...
src/http_header.h
View file @
cf26bf91
...
...
@@ -237,6 +237,7 @@ public:
void
write
(
std
::
ostream
&
os
)
const
;
Mime
::
MediaType
mime
()
const
{
return
mime_
;
}
void
setMime
(
const
Mime
::
MediaType
&
mime
)
{
mime_
=
mime
;
}
private:
Mime
::
MediaType
mime_
;
...
...
src/mime.cc
View file @
cf26bf91
...
...
@@ -271,6 +271,11 @@ MediaType::toString() const {
return
res
;
}
bool
MediaType
::
isValid
()
const
{
return
top_
!=
Type
::
None
&&
sub_
!=
Subtype
::
None
;
}
}
// namespace Mime
}
// namespace Http
...
...
src/mime.h
View file @
cf26bf91
...
...
@@ -173,6 +173,7 @@ public:
void
setParam
(
std
::
string
name
,
std
::
string
value
);
std
::
string
toString
()
const
;
bool
isValid
()
const
;
private:
Mime
::
Type
top_
;
...
...
src/peer.cc
View file @
cf26bf91
...
...
@@ -6,6 +6,7 @@
#include "peer.h"
#include <iostream>
#include <stdexcept>
#include <sys/socket.h>
namespace
Net
{
...
...
@@ -74,6 +75,12 @@ Peer::tryGetData(std::string(name)) const {
return
it
->
second
;
}
ssize_t
Peer
::
send
(
const
void
*
buf
,
size_t
len
)
{
return
::
send
(
fd_
,
buf
,
len
,
0
);
}
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
const
Peer
&
peer
)
{
const
auto
&
addr
=
peer
.
address
();
os
<<
"("
<<
addr
.
host
()
<<
", "
<<
addr
.
port
()
<<
") ["
<<
peer
.
hostname
()
<<
"]"
;
...
...
src/peer.h
View file @
cf26bf91
...
...
@@ -45,6 +45,8 @@ public:
return
std
::
static_pointer_cast
<
T
>
(
data
);
}
ssize_t
send
(
const
void
*
buf
,
size_t
len
);
private:
Address
addr
;
...
...
src/stream.h
View file @
cf26bf91
...
...
@@ -98,9 +98,17 @@ public:
return
cursor
.
value
;
}
size_t
size
()
const
{
return
cursor
.
value
-
pos
;
}
std
::
string
text
()
{
const
char
*
beg
=
cursor
.
offset
(
pos
);
return
std
::
string
(
beg
,
end
()
-
start
());
return
std
::
string
(
beg
,
size
());
}
const
char
*
rawText
()
const
{
return
cursor
.
offset
(
pos
);
}
private:
...
...
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