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
9ee9db90
Commit
9ee9db90
authored
Aug 23, 2015
by
Mathieu STEFANI
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added MIME/MediaType types and parsing. Headers constructors are also now explicit
parent
0329db6a
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
294 additions
and
12 deletions
+294
-12
main.cc
main.cc
+3
-2
src/http.cc
src/http.cc
+0
-3
src/http_header.cc
src/http_header.cc
+157
-0
src/http_header.h
src/http_header.h
+134
-7
No files found.
main.cc
View file @
9ee9db90
...
...
@@ -15,8 +15,9 @@ class MyHandler : public Net::Http::Handler {
using
namespace
Net
::
Http
;
Net
::
Http
::
Response
response
(
Net
::
Http
::
Code
::
Ok
,
"PONG"
);
// response.headers
// .add(std::make_shared<Server>("lys"));
response
.
headers
.
add
(
std
::
make_shared
<
Server
>
(
"lys"
))
.
add
(
std
::
make_shared
<
ContentType
>
(
MIME
(
Text
,
Plain
)));
response
.
writeTo
(
peer
);
}
...
...
src/http.cc
View file @
9ee9db90
...
...
@@ -143,9 +143,6 @@ namespace Private {
else
if
(
tryMatch
(
"DELETE"
))
{
request
->
method
=
Method
::
Delete
;
}
else
{
raise
(
"Lol wat"
);
}
auto
n
=
cursor
.
next
();
if
(
n
==
Cursor
::
Eof
)
return
State
::
Again
;
...
...
src/http_header.cc
View file @
9ee9db90
...
...
@@ -8,6 +8,8 @@
#include "common.h"
#include <stdexcept>
#include <iterator>
#include <cstring>
#include <iostream>
using
namespace
std
;
...
...
@@ -15,6 +17,150 @@ namespace Net {
namespace
Http
{
namespace
Mime
{
MediaType
MediaType
::
fromString
(
const
std
::
string
&
str
)
{
return
fromRaw
(
str
.
c_str
(),
str
.
size
());
}
MediaType
MediaType
::
fromString
(
std
::
string
&&
str
)
{
return
fromRaw
(
str
.
c_str
(),
str
.
size
());
}
MediaType
MediaType
::
fromRaw
(
const
char
*
str
,
size_t
len
)
{
MediaType
res
;
// HUGE @Todo: Validate the input when parsing to avoid overflow
// Parse type
const
char
*
p
=
strchr
(
str
,
'/'
);
if
(
p
==
NULL
)
return
res
;
const
ptrdiff_t
size
=
p
-
str
;
Mime
::
Type
top
;
// The reason we are using a do { } while (0); syntax construct here is to emulate
// if / else-if. Since we are using items-list macros to compare the strings,
// we want to avoid evaluating all the branches when one of them evaluates to true.
//
// Instead, we break the loop when a branch evaluates to true so that we do
// not evaluate all the subsequent ones.
//
// Watch out, this pattern is repeated throughout the function
do
{
#define TYPE(val, s) \
if (strncmp(str, s, size) == 0) { \
top = Type::val; \
break; \
}
MIME_TYPES
#undef TYPE
else
{
top
=
Type
::
Ext
;
}
}
while
(
0
);
if
(
top
==
Type
::
Ext
)
return
res
;
res
.
top
=
top
;
// Parse subtype
Mime
::
Subtype
sub
;
++
p
;
do
{
#define SUB_TYPE(val, s) \
if (strncmp(p, s, sizeof (s) - 1) == 0) { \
sub = Subtype::val; \
p += sizeof(s) - 1; \
break; \
}
MIME_SUBTYPES
#undef SUB_TYPE
else
{
sub
=
Subtype
::
Ext
;
}
}
while
(
0
);
if
(
sub
==
Subtype
::
Ext
)
return
res
;
res
.
sub
=
sub
;
// Parse suffix
Mime
::
Suffix
suffix
=
Suffix
::
None
;
if
(
*
p
==
'+'
)
{
++
p
;
do
{
#define SUFFIX(val, s, _) \
if (strncmp(p, s, sizeof (s) - 1) == 0) { \
suffix = Suffix::val; \
break; \
}
MIME_SUFFIXES
#undef SUFFIX
else
{
suffix
=
Suffix
::
Ext
;
}
}
while
(
0
);
res
.
suffix
=
suffix
;
}
return
res
;
}
std
::
string
MediaType
::
toString
()
const
{
auto
topString
=
[](
Mime
::
Type
top
)
->
const
char
*
{
switch
(
top
)
{
#define TYPE(val, str) \
case Mime::Type::val: \
return str;
MIME_TYPES
#undef TYPE
}
};
auto
subString
=
[](
Mime
::
Subtype
sub
)
->
const
char
*
{
switch
(
sub
)
{
#define SUB_TYPE(val, str) \
case Mime::Subtype::val: \
return str;
MIME_SUBTYPES
#undef TYPE
}
};
auto
suffixString
=
[](
Mime
::
Suffix
suffix
)
->
const
char
*
{
switch
(
suffix
)
{
#define SUFFIX(val, str, _) \
case Mime::Suffix::val: \
return "+" str;
MIME_SUFFIXES
#undef SUFFIX
}
};
std
::
string
res
;
res
+=
topString
(
top
);
res
+=
"/"
;
res
+=
subString
(
sub
);
if
(
suffix
!=
Suffix
::
None
)
{
res
+=
suffixString
(
suffix
);
}
return
res
;
}
}
// namespace Mime
const
char
*
encodingString
(
Encoding
encoding
)
{
switch
(
encoding
)
{
case
Encoding
:
:
Gzip
:
...
...
@@ -154,6 +300,17 @@ Server::write(std::ostream& os) const
std
::
ostream_iterator
<
std
::
string
>
(
os
,
" "
));
}
void
ContentType
::
parseRaw
(
const
char
*
str
,
size_t
len
)
{
}
void
ContentType
::
write
(
std
::
ostream
&
os
)
const
{
os
<<
"Content-Type: "
;
os
<<
mime_
.
toString
();
}
}
// namespace Http
}
// namespace Net
src/http_header.h
View file @
9ee9db90
...
...
@@ -61,6 +61,113 @@ enum class Encoding {
const
char
*
encodingString
(
Encoding
encoding
);
namespace
Mime
{
#define MIME_TYPES \
TYPE(Star , "*") \
TYPE(Text , "text") \
TYPE(Image , "image") \
TYPE(Audio , "audio") \
TYPE(Video , "video") \
TYPE(Application, "application") \
TYPE(Message , "message") \
TYPE(Multipart , "multipart")
#define MIME_SUBTYPES \
SUB_TYPE(Star , "*") \
SUB_TYPE(Plain , "plain") \
SUB_TYPE(Html , "html") \
SUB_TYPE(Xhtml , "xhtml") \
SUB_TYPE(Xml , "xml") \
SUB_TYPE(Javascript, "javascript") \
SUB_TYPE(Css , "css") \
\
SUB_TYPE(Json , "json") \
SUB_TYPE(FormUrlEncoded, "x-www-form-urlencoded") \
\
SUB_TYPE(Png, "png") \
SUB_TYPE(Gif, "gif") \
SUB_TYPE(Bmp, "bmp") \
SUB_TYPE(Jpeg, "jpeg")
#define MIME_SUFFIXES \
SUFFIX(Json , "json" , "JavaScript Object Notation") \
SUFFIX(Ber , "ber" , "Basic Encoding Rules") \
SUFFIX(Der , "der" , "Distinguished Encoding Rules") \
SUFFIX(Fastinfoset, "fastinfoset", "Fast Infoset") \
SUFFIX(Wbxml , "wbxml" , "WAP Binary XML") \
SUFFIX(Zip , "zip" , "ZIP file storage") \
SUFFIX(Xml , "xml" , "Extensible Markup Language")
enum
class
Type
{
#define TYPE(val, _) val,
MIME_TYPES
#undef TYPE
Ext
};
enum
class
Subtype
{
#define SUB_TYPE(val, _) val,
MIME_SUBTYPES
#undef SUB_TYPE
Ext
};
enum
class
Suffix
{
#define SUFFIX(val, _, __) val,
MIME_SUFFIXES
#undef SUFFIX
None
,
Ext
};
// 3.7 Media Types
class
MediaType
{
public:
constexpr
MediaType
()
:
top
(
Type
::
Ext
)
,
sub
(
Subtype
::
Ext
)
,
suffix
(
Suffix
::
None
)
{
}
constexpr
MediaType
(
Mime
::
Type
top
,
Mime
::
Subtype
sub
)
:
top
(
top
)
,
sub
(
sub
)
,
suffix
(
Suffix
::
None
)
{
}
constexpr
MediaType
(
Mime
::
Type
top
,
Mime
::
Subtype
sub
,
Mime
::
Suffix
suffix
)
:
top
(
top
)
,
sub
(
sub
)
,
suffix
(
suffix
)
{
}
Mime
::
Type
top
;
Mime
::
Subtype
sub
;
Mime
::
Suffix
suffix
;
static
MediaType
fromRaw
(
const
char
*
str
,
size_t
len
);
static
MediaType
fromString
(
const
std
::
string
&
str
);
static
MediaType
fromString
(
std
::
string
&&
str
);
std
::
string
toString
()
const
;
};
inline
bool
operator
==
(
const
MediaType
&
lhs
,
const
MediaType
&
rhs
)
{
return
lhs
.
top
==
rhs
.
top
&&
lhs
.
sub
==
rhs
.
sub
;
}
}
// namespace Mime
#define MIME(top, sub) \
Net::Http::Mime::MediaType(Net::Http::Mime::Type::top, Net::Http::Mime::Subtype::sub)
#define MIME3(top, sub, suffix) \
Net::Http::Mime::MediaType(Net::Http::Mime::Type::top, Net::Http::Mime::Subtype::sub, Net::Http::Mime::Suffix::suffix);
class
Header
{
public:
virtual
const
char
*
name
()
const
=
0
;
...
...
@@ -115,7 +222,7 @@ public:
:
value_
(
0
)
{
}
ContentLength
(
uint64_t
val
)
explicit
ContentLength
(
uint64_t
val
)
:
value_
(
val
)
{
}
...
...
@@ -137,7 +244,7 @@ public:
,
port_
(
-
1
)
{
}
Host
(
const
std
::
string
&
host
,
int16_t
port
=
-
1
)
explicit
Host
(
const
std
::
string
&
host
,
int16_t
port
=
-
1
)
:
host_
(
host
)
,
port_
(
port
)
{
}
...
...
@@ -158,7 +265,7 @@ public:
NAME
(
"User-Agent"
)
UserAgent
()
{
}
UserAgent
(
const
std
::
string
&
ua
)
:
explicit
UserAgent
(
const
std
::
string
&
ua
)
:
ua_
(
ua
)
{
}
...
...
@@ -192,7 +299,7 @@ public:
:
encoding_
(
Encoding
::
Identity
)
{
}
ContentEncoding
(
Encoding
encoding
)
explicit
ContentEncoding
(
Encoding
encoding
)
:
encoding_
(
encoding
)
{
}
...
...
@@ -211,9 +318,9 @@ public:
Server
()
{
}
Server
(
const
std
::
vector
<
std
::
string
>&
tokens
);
Server
(
const
std
::
string
&
token
);
Server
(
const
char
*
token
);
explicit
Server
(
const
std
::
vector
<
std
::
string
>&
tokens
);
explicit
Server
(
const
std
::
string
&
token
);
explicit
Server
(
const
char
*
token
);
void
parse
(
const
std
::
string
&
data
);
void
write
(
std
::
ostream
&
os
)
const
;
...
...
@@ -223,6 +330,26 @@ private:
std
::
vector
<
std
::
string
>
tokens_
;
};
class
ContentType
:
public
Header
{
public:
NAME
(
"Content-Type"
)
ContentType
()
{
}
explicit
ContentType
(
const
Mime
::
MediaType
&
mime
)
:
mime_
(
mime
)
{
}
void
parseRaw
(
const
char
*
str
,
size_t
len
);
void
write
(
std
::
ostream
&
os
)
const
;
Mime
::
MediaType
mime
()
const
{
return
mime_
;
}
private:
Mime
::
MediaType
mime_
;
};
}
// namespace Http
}
// namespace Net
...
...
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