Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vibe.d
Project overview
Project overview
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Container Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Jobs
Commits
Open sidebar
Debian D Language Group
vibe.d
Commits
8ab29186
Commit
8ab29186
authored
Feb 22, 2018
by
Matthias Klumpp
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
New upstream version 0.8.2
parent
5042c82d
Changes
48
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
48 changed files
with
2171 additions
and
1252 deletions
+2171
-1252
.travis.yml
.travis.yml
+12
-7
CHANGELOG.md
CHANGELOG.md
+743
-660
README.md
README.md
+6
-2
appveyor.yml
appveyor.yml
+12
-4
core/dub.sdl
core/dub.sdl
+1
-1
core/vibe/core/args.d
core/vibe/core/args.d
+27
-2
core/vibe/core/core.d
core/vibe/core/core.d
+1
-1
core/vibe/core/drivers/libevent2.d
core/vibe/core/drivers/libevent2.d
+11
-21
core/vibe/core/drivers/utils.d
core/vibe/core/drivers/utils.d
+4
-5
core/vibe/core/path.d
core/vibe/core/path.d
+1
-1
core/vibe/core/task.d
core/vibe/core/task.d
+2
-0
data/vibe/data/bson.d
data/vibe/data/bson.d
+27
-0
data/vibe/data/json.d
data/vibe/data/json.d
+100
-60
examples/http_forward_proxy/dub.json
examples/http_forward_proxy/dub.json
+8
-0
examples/http_forward_proxy/source/app.d
examples/http_forward_proxy/source/app.d
+13
-0
http/vibe/http/client.d
http/vibe/http/client.d
+6
-5
http/vibe/http/common.d
http/vibe/http/common.d
+43
-0
http/vibe/http/dist.d
http/vibe/http/dist.d
+4
-2
http/vibe/http/proxy.d
http/vibe/http/proxy.d
+73
-21
http/vibe/http/server.d
http/vibe/http/server.d
+311
-237
http/vibe/http/websockets.d
http/vibe/http/websockets.d
+70
-6
inet/meson.build
inet/meson.build
+1
-1
meson.build
meson.build
+1
-1
mongodb/vibe/db/mongo/collection.d
mongodb/vibe/db/mongo/collection.d
+5
-5
mongodb/vibe/db/mongo/sessionstore.d
mongodb/vibe/db/mongo/sessionstore.d
+181
-0
redis/vibe/db/redis/redis.d
redis/vibe/db/redis/redis.d
+32
-1
tests/args/test.sh
tests/args/test.sh
+1
-0
tests/redis/source/app.d
tests/redis/source/app.d
+2
-1
tests/vibe.http.server.1388/dub.sdl
tests/vibe.http.server.1388/dub.sdl
+0
-1
tests/vibe.http.server.1388/source/app.d
tests/vibe.http.server.1388/source/app.d
+7
-1
tests/vibe.http.server.1721/source/app.d
tests/vibe.http.server.1721/source/app.d
+2
-2
tests/vibe.http.server.host-header/source/app.d
tests/vibe.http.server.host-header/source/app.d
+4
-4
tests/vibe.web.rest.1922/.gitignore
tests/vibe.web.rest.1922/.gitignore
+1
-0
tests/vibe.web.rest.1922/dub.sdl
tests/vibe.web.rest.1922/dub.sdl
+2
-0
tests/vibe.web.rest.1922/source/app.d
tests/vibe.web.rest.1922/source/app.d
+112
-0
tls/dub.sdl
tls/dub.sdl
+13
-1
tls/vibe/stream/botan.d
tls/vibe/stream/botan.d
+7
-2
tls/vibe/stream/openssl.d
tls/vibe/stream/openssl.d
+8
-21
tls/vibe/stream/tls.d
tls/vibe/stream/tls.d
+5
-0
travis-ci.sh
travis-ci.sh
+1
-1
utils/vibe/internal/utilallocator.d
utils/vibe/internal/utilallocator.d
+5
-1
utils/vibe/utils/dictionarylist.d
utils/vibe/utils/dictionarylist.d
+4
-1
web/vibe/web/auth.d
web/vibe/web/auth.d
+25
-8
web/vibe/web/common.d
web/vibe/web/common.d
+37
-7
web/vibe/web/i18n.d
web/vibe/web/i18n.d
+56
-31
web/vibe/web/internal/rest/common.d
web/vibe/web/internal/rest/common.d
+8
-5
web/vibe/web/rest.d
web/vibe/web/rest.d
+72
-57
web/vibe/web/web.d
web/vibe/web/web.d
+104
-65
No files found.
.travis.yml
View file @
8ab29186
...
...
@@ -9,21 +9,25 @@ services:
addons
:
apt
:
packages
:
-
libevent-dev
-
libssl
-dev
-
pkg-config
-
zlib1g
-dev
-
pkg-config
-
zlib1g
-dev
-
libevent-dev
-
libssl
-dev
d
:
# order: latest DMD, oldest DMD, LDC/GDC, remaining DMD versions
# this way the overall test time gets cut down (GDC/LDC are a lot
# slower tham DMD, so they should be started early), while still
# catching most DMD version related build failures early
-
dmd-2.07
5
.0
-
dmd-2.07
7
.0
-
dmd-2.071.2
-
ldc-1.5.0
-
ldc-1.4.0
-
ldc-1.3.0
-
ldc-1.2.0
-
ldc-1.1.1
-
dmd-2.076.1
-
dmd-2.075.1
-
dmd-2.074.1
-
dmd-2.073.2
-
dmd-2.072.2
...
...
@@ -50,11 +54,12 @@ matrix:
env
:
VIBED_DRIVER=libasync BUILD_EXAMPLE=0 RUN_TEST=0
before_install
:
-
pip3 install meson>=0.40
-
pyenv global system
3.5
-
pip3 install 'meson>=0.42,!=0.43'
install
:
-
mkdir .ntmp
-
curl -L https://github.com/ninja-build/ninja/releases/download/v1.
7
.2/ninja-linux.zip -o .ntmp/ninja-linux.zip
-
curl -L https://github.com/ninja-build/ninja/releases/download/v1.
8
.2/ninja-linux.zip -o .ntmp/ninja-linux.zip
-
unzip .ntmp/ninja-linux.zip -d .ntmp
before_script
:
...
...
CHANGELOG.md
View file @
8ab29186
This diff is collapsed.
Click to expand it.
README.md
View file @
8ab29186
...
...
@@ -10,7 +10,7 @@ available.
Visit the website at
<http://vibed.org/>
for more information.
[

](https://code.dlang.org/packages/vibe-d)
[

](https://travis-ci.org/rejectedsoftware
/vibe.d)
[

](https://travis-ci.org/vibe-d
/vibe.d)
[

](https://ci.appveyor.com/project/s-ludwig/vibe-d/branch/master)
Hello Vibe.d
...
...
@@ -48,11 +48,15 @@ Support
Vibe.d aims to support at least the 3 latest minor releases of D.
At the moment, the following compilers are supported and tested:
-
DMD 2.075.0
-
DMD 2.077.0
-
DMD 2.076.1
-
DMD 2.075.1
-
DMD 2.074.1
-
DMD 2.073.2
-
DMD 2.072.2
**Warning: 2.072.0 and 2.072.1 are affected by a serious DMD regression: [16980](https://issues.dlang.org/show_bug.cgi?id=16980)**
-
DMD 2.071.2
-
LDC 1.5.0 (FE: 2.075.1)
-
LDC 1.4.0 (FE: 2.074.1)
-
LDC 1.3.0 (FE: 2.073.2)
-
LDC 1.2.0 (FE: 2.072.2)
-
LDC 1.1.1 (FE: 2.071.2)
...
...
appveyor.yml
View file @
8ab29186
...
...
@@ -2,19 +2,27 @@ platform: x64
environment
:
matrix
:
-
DC
:
dmd
DVersion
:
2.07
5
.0
DVersion
:
2.07
7
.0
arch
:
x86_mscoff
config
:
vibe-core
-
DC
:
dmd
DVersion
:
2.07
5
.0
DVersion
:
2.07
7
.0
arch
:
x86
config
:
win32
-
DC
:
dmd
DVersion
:
2.07
5
.0
DVersion
:
2.07
7
.0
arch
:
x64
config
:
win32
-
DC
:
dmd
DVersion
:
2.075.0
DVersion
:
2.077.0
arch
:
x86_mscoff
config
:
win32
-
DC
:
dmd
DVersion
:
2.076.1
arch
:
x86_mscoff
config
:
win32
-
DC
:
dmd
DVersion
:
2.075.1
arch
:
x86_mscoff
config
:
win32
-
DC
:
dmd
...
...
core/dub.sdl
View file @
8ab29186
...
...
@@ -55,5 +55,5 @@ configuration "winrt" {
configuration "vibe-core" {
targetType "none"
dependency "vibe-core" version="
~>1.
0"
dependency "vibe-core" version="
>=1.2.1-alpha.2 <2.0.0-
0"
}
core/vibe/core/args.d
View file @
8ab29186
...
...
@@ -16,7 +16,7 @@ module vibe.core.args;
import
vibe
.
core
.
log
;
import
vibe
.
data
.
json
;
import
std
.
algorithm
:
any
,
map
,
sort
;
import
std
.
algorithm
:
any
,
filter
,
map
,
sort
,
startsWith
;
import
std
.
array
:
array
,
join
,
replicate
,
split
;
import
std
.
exception
;
import
std
.
file
;
...
...
@@ -165,6 +165,31 @@ bool finalizeCommandLineOptions(string[]* args_out = null)
return
true
;
}
/**
This functions allows the usage of a custom command line argument parser
with vibe.d.
$(OL
$(LI build executable with version(VibeDisableCommandLineParsing))
$(LI parse main function arguments with a custom command line parser)
$(LI pass vibe.d arguments to `setCommandLineArgs`)
$(LI use vibe.d command line parsing utilities)
)
Params:
args = The arguments that should be handled by vibe.d
*/
void
setCommandLineArgs
(
string
[]
args
)
{
g_args
=
args
;
}
///
unittest
{
import
std
.
format
:
format
;
string
[]
args
=
[
"--foo"
,
"10"
];
setCommandLineArgs
(
args
);
}
private
struct
OptionInfo
{
string
[]
names
;
...
...
@@ -197,7 +222,7 @@ private void init()
import
vibe
.
utils
.
string
:
stripUTF8Bom
;
version
(
VibeDisableCommandLineParsing
)
{}
else
g_args
=
Runtime
.
args
;
else
g_args
=
Runtime
.
args
.
filter
!(
arg
=>
!
arg
.
startsWith
(
"--DRT-"
)).
array
;
if
(!
g_args
.
length
)
g_args
=
[
"dummy"
];
...
...
core/vibe/core/core.d
View file @
8ab29186
...
...
@@ -987,7 +987,7 @@ void setTaskEventCallback(TaskEventCb func)
/**
A version string representing the current vibe.d version
*/
enum
vibeVersionString
=
"0.8.
1
"
;
enum
vibeVersionString
=
"0.8.
2
"
;
/**
...
...
core/vibe/core/drivers/libevent2.d
View file @
8ab29186
...
...
@@ -60,43 +60,33 @@ version (Windows)
else
version
(
VibePragmaLib
)
pragma
(
lib
,
"event"
);
version
(
Windows
)
{
version
(
Windows
)
{
import
core
.
sys
.
windows
.
winsock2
;
alias
EWOULDBLOCK
=
WSAEWOULDBLOCK
;
}
version
(
OSX
)
{
static
if
(
__VERSION__
<
2077
)
{
}
else
version
(
OSX
)
{
static
if
(
__VERSION__
<
2077
)
{
enum
IP_ADD_MEMBERSHIP
=
12
;
enum
IP_MULTICAST_LOOP
=
11
;
}
else
import
core
.
sys
.
darwin
.
netinet
.
in_
:
IP_ADD_MEMBERSHIP
,
IP_MULTICAST_LOOP
;
}
else
version
(
FreeBSD
)
{
static
if
(
__VERSION__
<
2077
)
{
}
else
version
(
FreeBSD
)
{
static
if
(
__VERSION__
<
2077
)
{
enum
IP_ADD_MEMBERSHIP
=
12
;
enum
IP_MULTICAST_LOOP
=
11
;
}
else
import
core
.
sys
.
freebsd
.
netinet
.
in_
:
IP_ADD_MEMBERSHIP
,
IP_MULTICAST_LOOP
;
}
else
version
(
linux
)
{
static
if
(
__VERSION__
<
2077
)
{
}
else
version
(
linux
)
{
static
if
(
__VERSION__
<
2077
)
{
enum
IP_ADD_MEMBERSHIP
=
35
;
enum
IP_MULTICAST_LOOP
=
34
;
}
else
import
core
.
sys
.
linux
.
netinet
.
in_
:
IP_ADD_MEMBERSHIP
,
IP_MULTICAST_LOOP
;
}
else
version
(
Windows
)
{
// IP_ADD_MEMBERSHIP and IP_MULTICAST_LOOP are included in winsock(2) import above
}
else
version
(
Solaris
)
{
enum
IP_ADD_MEMBERSHIP
=
0x13
;
enum
IP_MULTICAST_LOOP
=
0x12
;
}
final
class
Libevent2Driver
:
EventDriver
{
...
...
@@ -396,7 +386,7 @@ final class Libevent2Driver : EventDriver {
int
tmp_reuse
=
1
;
socketEnforce
(()
@trusted
{
return
setsockopt
(
listenfd
,
SOL_SOCKET
,
SO_REUSEADDR
,
&
tmp_reuse
,
tmp_reuse
.
sizeof
);
}
()
==
0
,
"Error enabling socket address reuse on listening socket"
);
version
(
linux
)
{
static
if
(
is
(
typeof
(
SO_REUSEPORT
))
)
{
if
(
options
&
TCPListenOptions
.
reusePort
)
{
if
(()
@trusted
{
return
setsockopt
(
listenfd
,
SOL_SOCKET
,
SO_REUSEPORT
,
&
tmp_reuse
,
tmp_reuse
.
sizeof
);
}
())
{
if
(
errno
!=
EINVAL
&&
errno
!=
ENOPROTOOPT
)
{
...
...
core/vibe/core/drivers/utils.d
View file @
8ab29186
...
...
@@ -43,11 +43,10 @@ version (Windows) {
alias
SystemSocketException
=
WSAErrorException
;
}
else
alias
SystemSocketException
=
ErrnoException
;
version
(
linux
)
{
import
core
.
sys
.
posix
.
sys
.
socket
;
static
if
(!
is
(
typeof
(
SO_REUSEPORT
)))
{
enum
{
SO_REUSEPORT
=
15
}
}
import
core
.
sys
.
posix
.
sys
.
socket
;
static
if
(!
is
(
typeof
(
SO_REUSEPORT
)))
{
version
(
linux
)
enum
SO_REUSEPORT
=
15
;
else
enum
SO_REUSEPORT
=
0x200
;
}
T
socketEnforce
(
T
)(
T
value
,
lazy
string
msg
=
null
,
string
file
=
__FILE__
,
size_t
line
=
__LINE__
)
...
...
core/vibe/core/path.d
View file @
8ab29186
...
...
@@ -151,7 +151,7 @@ struct Path {
@property
bool
absolute
()
const
{
return
m_absolute
;
}
/// Forward compatibility property for vibe-code
@property
immutable
(
PathEntry
)[]
bySegment
()
{
return
nodes
;
}
@property
immutable
(
PathEntry
)[]
bySegment
()
const
{
return
nodes
;
}
/// Resolves all '.' and '..' path entries as far as possible.
void
normalize
()
...
...
core/vibe/core/task.d
View file @
8ab29186
...
...
@@ -67,7 +67,9 @@ struct Task {
// FIXME: this is not thread safe!
@property
ref
ThreadInfo
tidInfo
()
{
return
m_fiber
?
fiber
.
tidInfo
:
s_tidInfo
;
}
@property
ref
const
(
ThreadInfo
)
tidInfo
()
const
{
return
m_fiber
?
fiber
.
tidInfo
:
s_tidInfo
;
}
@property
Tid
tid
()
{
return
tidInfo
.
ident
;
}
@property
const
(
Tid
)
tid
()
const
{
return
tidInfo
.
ident
;
}
}
/// Reserved for internal use!
...
...
data/vibe/data/bson.d
View file @
8ab29186
...
...
@@ -67,6 +67,7 @@ import std.base64;
import
std
.
bitmanip
;
import
std
.
conv
;
import
std
.
datetime
;
import
std
.
uuid
:
UUID
;
import
std
.
exception
;
import
std
.
range
;
import
std
.
traits
;
...
...
@@ -216,6 +217,8 @@ struct Bson {
this
(
long
value
)
{
opAssign
(
value
);
}
/// ditto
this
(
in
Json
value
)
{
opAssign
(
value
);
}
/// ditto
this
(
in
UUID
value
)
{
opAssign
(
value
);
}
/**
Assigns a D type to a BSON value.
...
...
@@ -346,6 +349,11 @@ struct Bson {
m_type
=
writeBson
(
app
,
value
);
m_data
=
app
.
data
;
}
/// ditto
void
opAssign
(
in
UUID
value
)
{
opAssign
(
BsonBinData
(
BsonBinData
.
Type
.
uuid
,
value
.
data
.
idup
));
}
/**
Returns the BSON type of this value.
...
...
@@ -429,6 +437,13 @@ struct Bson {
pragma
(
msg
,
"Bson.get!Json() and Bson.opCast!Json() will soon be removed. Please use Bson.toJson() instead."
);
return
this
.
toJson
();
}
else
static
if
(
is
(
T
==
UUID
)
){
checkType
(
Type
.
binData
);
auto
bbd
=
this
.
get
!
BsonBinData
();
enforce
(
bbd
.
type
==
BsonBinData
.
Type
.
uuid
,
"BsonBinData value is type '"
~
to
!
string
(
bbd
.
type
)~
"', expected to be uuid"
);
const
ubyte
[
16
]
b
=
bbd
.
rawData
;
return
UUID
(
b
);
}
else
static
assert
(
false
,
"Cannot cast "
~
typeof
(
this
).
stringof
~
" to '"
~
T
.
stringof
~
"'."
);
}
...
...
@@ -589,6 +604,18 @@ struct Bson {
assert
(
value
[
"c"
]
==
Bson
(
"foo"
));
}
///
unittest
{
auto
srcUuid
=
UUID
(
"00010203-0405-0607-0809-0a0b0c0d0e0f"
);
Bson
b
=
srcUuid
;
auto
u
=
b
.
get
!
UUID
();
assert
(
b
.
type
==
Bson
.
Type
.
binData
);
assert
(
b
.
get
!
BsonBinData
().
type
==
BsonBinData
.
Type
.
uuid
);
assert
(
u
==
srcUuid
);
}
/** Allows index based access of a BSON array value.
Returns a null value if the index is out of bounds.
...
...
data/vibe/data/json.d
View file @
8ab29186
...
...
@@ -1192,7 +1192,7 @@ Json parseJson(R)(ref R range, int* line = null, string filename = null)
if
(
is_float
)
{
ret
=
to
!
double
(
num
);
}
else
if
(
is_long_overflow
)
{
ret
=
()
@trusted
{
return
BigInt
(
num
);
}
();
ret
=
()
@trusted
{
return
BigInt
(
num
.
to
!
string
);
}
();
}
else
{
ret
=
to
!
long
(
num
);
}
...
...
@@ -1267,32 +1267,50 @@ Json parseJsonString(string str, string filename = null)
}
@safe
unittest
{
assert
(
parseJsonString
(
"null"
)
==
Json
(
null
));
assert
(
parseJsonString
(
"true"
)
==
Json
(
true
));
assert
(
parseJsonString
(
"false"
)
==
Json
(
false
));
assert
(
parseJsonString
(
"1"
)
==
Json
(
1
));
// These currently don't work at compile time
assert
(
parseJsonString
(
"17559991181826658461"
)
==
Json
(
BigInt
(
17559991181826658461U
L
)));
assert
(
parseJsonString
(
"99999999999999999999999999"
)
==
()
@trusted
{
return
Json
(
BigInt
(
"99999999999999999999999999"
));
}
());
assert
(
parseJsonString
(
"2.0"
)
==
Json
(
2.0
));
assert
(
parseJsonString
(
"\"test\""
)
==
Json
(
"test"
));
assert
(
parseJsonString
(
"[1, 2, 3]"
)
==
Json
([
Json
(
1
),
Json
(
2
),
Json
(
3
)]));
assert
(
parseJsonString
(
"{\"a\": 1}"
)
==
Json
([
"a"
:
Json
(
1
)]));
assert
(
parseJsonString
(
`"\\\/\b\f\n\r\t\u1234"`
).
get
!
string
==
"\\/\b\f\n\r\t\u1234"
);
auto
json
=
parseJsonString
(
`{"hey": "This is @à test éhééhhéhéé !%/??*&?\ud83d\udcec"}`
);
assert
(
json
.
toPrettyString
()
==
parseJsonString
(
json
.
toPrettyString
()).
toPrettyString
());
bool
test
()
{
assert
(
parseJsonString
(
"null"
)
==
Json
(
null
));
assert
(
parseJsonString
(
"true"
)
==
Json
(
true
));
assert
(
parseJsonString
(
"false"
)
==
Json
(
false
));
assert
(
parseJsonString
(
"1"
)
==
Json
(
1
));
assert
(
parseJsonString
(
"2.0"
)
==
Json
(
2.0
));
assert
(
parseJsonString
(
"\"test\""
)
==
Json
(
"test"
));
assert
(
parseJsonString
(
"[1, 2, 3]"
)
==
Json
([
Json
(
1
),
Json
(
2
),
Json
(
3
)]));
assert
(
parseJsonString
(
"{\"a\": 1}"
)
==
Json
([
"a"
:
Json
(
1
)]));
assert
(
parseJsonString
(
`"\\\/\b\f\n\r\t\u1234"`
).
get
!
string
==
"\\/\b\f\n\r\t\u1234"
);
return
true
;
}
// Run at compile time and runtime
assert
(
test
());
static
assert
(
test
());
}
@safe
unittest
{
try
parseJsonString
(
" \t\n "
);
catch
(
Exception
e
)
assert
(
e
.
msg
.
endsWith
(
"JSON string contains only whitespaces."
));
try
parseJsonString
(
`{"a": 1`
);
catch
(
Exception
e
)
assert
(
e
.
msg
.
endsWith
(
"Missing '}' before EOF."
));
try
parseJsonString
(
`{"a": 1 x`
);
catch
(
Exception
e
)
assert
(
e
.
msg
.
endsWith
(
"Expected '}' or ',' - got 'x'."
));
try
parseJsonString
(
`[1`
);
catch
(
Exception
e
)
assert
(
e
.
msg
.
endsWith
(
"Missing ']' before EOF."
));
try
parseJsonString
(
`[1 x`
);
catch
(
Exception
e
)
assert
(
e
.
msg
.
endsWith
(
"Expected ']' or ',' - got 'x'."
));
bool
test
()
{
try
parseJsonString
(
" \t\n "
);
catch
(
Exception
e
)
assert
(
e
.
msg
.
endsWith
(
"JSON string contains only whitespaces."
));
try
parseJsonString
(
`{"a": 1`
);
catch
(
Exception
e
)
assert
(
e
.
msg
.
endsWith
(
"Missing '}' before EOF."
));
try
parseJsonString
(
`{"a": 1 x`
);
catch
(
Exception
e
)
assert
(
e
.
msg
.
endsWith
(
"Expected '}' or ',' - got 'x'."
));
try
parseJsonString
(
`[1`
);
catch
(
Exception
e
)
assert
(
e
.
msg
.
endsWith
(
"Missing ']' before EOF."
));
try
parseJsonString
(
`[1 x`
);
catch
(
Exception
e
)
assert
(
e
.
msg
.
endsWith
(
"Expected ']' or ',' - got 'x'."
));
return
true
;
}
// Run at compile time and runtime
assert
(
test
());
static
assert
(
test
());
}
/**
...
...
@@ -1914,7 +1932,7 @@ struct JsonStringSerializer(R, bool pretty = false)
bool
is_long_overflow
;
auto
num
=
m_range
.
skipNumber
(
is_float
,
is_long_overflow
);
enforceJson
(!
is_float
,
"Expecting integer number."
);
enforceJson
(!
is_long_overflow
,
num
~
" is too big for long."
);
enforceJson
(!
is_long_overflow
,
num
.
to
!
string
~
" is too big for long."
);
return
to
!
T
(
num
);
}
else
static
if
(
is
(
T
:
BigInt
))
{
bool
is_float
;
...
...
@@ -2268,71 +2286,93 @@ private string jsonUnescape(R)(ref R range)
return
ret
.
data
;
}
private
auto
skipNumber
(
R
)(
ref
R
s
,
out
bool
is_float
,
out
bool
is_long_overflow
)
@safe
if
(
isNarrowString
!
R
)
{
auto
r
=
s
.
representation
;
version
(
assert
)
auto
rEnd
=
(()
@trusted
=>
r
.
ptr
+
r
.
length
-
1
)();
auto
res
=
skipNumber
(
r
,
is_float
,
is_long_overflow
);
version
(
assert
)
assert
(
rEnd
==
(()
@trusted
=>
r
.
ptr
+
r
.
length
-
1
)());
// check nothing taken off the end
s
=
s
[$
-
r
.
length
..
$];
return
res
.
assumeUTF
();
}
/// private
private
string
skipNumber
(
R
)(
ref
R
s
,
out
bool
is_float
,
out
bool
is_long_overflow
)
private
auto
skipNumber
(
R
)(
ref
R
s
,
out
bool
is_float
,
out
bool
is_long_overflow
)
if
(!
isNarrowString
!
R
&&
isForwardRange
!
R
)
{
// TODO: make this work with input ranges
pragma
(
msg
,
R
);
auto
sOrig
=
s
.
save
;
size_t
idx
=
0
;
is_float
=
false
;
is_long_overflow
=
false
;
ulong
int_part
=
0
;
if
(
s
[
idx
]
==
'-'
)
idx
++;
if
(
s
[
idx
]
==
'0'
)
idx
++;
if
(
s
.
front
==
'-'
)
{
s
.
popFront
();
++
idx
;
}
if
(
s
.
front
==
'0'
)
{
s
.
popFront
();
++
idx
;
}
else
{
enforceJson
(
isDigit
(
s
[
idx
]),
"Digit expected at beginning of number."
);
int_part
=
s
[
idx
++]
-
'0'
;
while
(
idx
<
s
.
length
&&
isDigit
(
s
[
idx
])
)
{
if
(!
is_long_overflow
)
{
auto
dig
=
s
[
idx
]
-
'0'
;
if
((
long
.
max
/
10
)
>
int_part
||
((
long
.
max
/
10
)
==
int_part
&&
(
long
.
max
%
10
)
>=
dig
))
{
enforceJson
(
isDigit
(
s
.
front
),
"Digit expected at beginning of number."
);
int_part
=
s
.
front
-
'0'
;
s
.
popFront
();
++
idx
;
while
(
!
s
.
empty
&&
isDigit
(
s
.
front
)
)
{
if
(!
is_long_overflow
)
{
auto
dig
=
s
.
front
-
'0'
;
if
((
long
.
max
/
10
)
>
int_part
||
((
long
.
max
/
10
)
==
int_part
&&
(
long
.
max
%
10
)
>=
dig
))
{
int_part
*=
10
;
int_part
+=
dig
;
}
else
{
else
{
is_long_overflow
=
true
;
}
}
idx
++
;
s
.
popFront
();
++
idx
;
}
}
if
(
idx
<
s
.
length
&&
s
[
idx
]
==
'.'
)
{
idx
++
;
if
(
!
s
.
empty
&&
s
.
front
==
'.'
)
{
s
.
popFront
();
++
idx
;
is_float
=
true
;
while
(
idx
<
s
.
length
&&
isDigit
(
s
[
idx
])
)
idx
++;
while
(
!
s
.
empty
&&
isDigit
(
s
.
front
)
)
{
s
.
popFront
();
++
idx
;
}
}
if
(
idx
<
s
.
length
&&
(
s
[
idx
]
==
'e'
||
s
[
idx
]
==
'E'
)
)
{
idx
++
;
if
(
!
s
.
empty
&&
(
s
.
front
==
'e'
||
s
.
front
==
'E'
)
)
{
s
.
popFront
();
++
idx
;
is_float
=
true
;
if
(
idx
<
s
.
length
&&
(
s
[
idx
]
==
'+'
||
s
[
idx
]
==
'-'
)
)
idx
++;
enforceJson
(
idx
<
s
.
length
&&
isDigit
(
s
[
idx
]),
"Expected exponent."
~
s
[
0
..
idx
]);
idx
++;
while
(
idx
<
s
.
length
&&
isDigit
(
s
[
idx
])
)
idx
++;
if
(
!
s
.
empty
&&
(
s
.
front
==
'+'
||
s
.
front
==
'-'
)
)
{
s
.
popFront
();
++
idx
;
}
enforceJson
(
!
s
.
empty
&&
isDigit
(
s
.
front
),
"Expected exponent."
~
sOrig
.
takeExactly
(
idx
).
to
!
string
);
s
.
popFront
();
++
idx
;
while
(
!
s
.
empty
&&
isDigit
(
s
.
front
)
)
{
s
.
popFront
();
++
idx
;
}
}
string
ret
=
s
[
0
..
idx
];
s
=
s
[
idx
..
$];
return
ret
;
return
sOrig
.
takeExactly
(
idx
);
}
unittest
{
string
test_1
=
"9223372036854775806"
;
// lower then long.max
string
test_2
=
"9223372036854775807"
;
// long.max
string
test_3
=
"9223372036854775808"
;
// greater then long.max
bool
is_float
;
bool
is_long_overflow
;
test_1
.
skipNumber
(
is_float
,
is_long_overflow
);
assert
(!
is_long_overflow
);
test_2
.
skipNumber
(
is_float
,
is_long_overflow
);
assert
(!
is_long_overflow
);
test_3
.
skipNumber
(
is_float
,
is_long_overflow
);
assert
(
is_long_overflow
);
import
std
.
meta
:
AliasSeq
;
// test for string and for a simple range
foreach
(
foo
;
AliasSeq
!(
to
!
string
,
map
!
"a"
))
{
auto
test_1
=
foo
(
"9223372036854775806"
);
// lower then long.max
auto
test_2
=
foo
(
"9223372036854775807"
);
// long.max
auto
test_3
=
foo
(
"9223372036854775808"
);
// greater then long.max
bool
is_float
;
bool
is_long_overflow
;
test_1
.
skipNumber
(
is_float
,
is_long_overflow
);
assert
(!
is_long_overflow
);
test_2
.
skipNumber
(
is_float
,
is_long_overflow
);
assert
(!
is_long_overflow
);
test_3
.
skipNumber
(
is_float
,
is_long_overflow
);
assert
(
is_long_overflow
);
}
}
/// private
...
...
examples/http_forward_proxy/dub.json
0 → 100644
View file @
8ab29186
{
"name"
:
"http-forward-proxy-example"
,
"description"
:
"Sets up a simple forward proxy."
,
"dependencies"
:
{
"vibe-d:http"
:
{
"path"
:
"../../"
}
},
"versions"
:
[
"VibeDefaultMain"
]
}
\ No newline at end of file
examples/http_forward_proxy/source/app.d
0 → 100644
View file @
8ab29186
import
vibe
.
appmain
;
import
vibe
.
http
.
proxy
;
import
vibe
.
http
.
server
;
shared
static
this
()
{
auto
settings
=
new
HTTPServerSettings
;
settings
.
port
=
8080
;
settings
.
bindAddresses
=
[
"::1"
,
"127.0.0.1"
];
listenHTTPForwardProxy
(
settings
);
}
http/vibe/http/client.d
View file @
8ab29186
...
...
@@ -628,7 +628,7 @@ final class HTTPClient {
}
return
()
@trusted
{
// scoped
auto
req
=
scoped
!
HTTPClientRequest
(
m_stream
,
m_conn
.
localAddress
);
auto
req
=
scoped
!
HTTPClientRequest
(
m_stream
,
m_conn
);
if
(
m_useTLS
)
req
.
m_peerCertificate
=
m_tlsStream
.
peerCertificate
;
...
...
@@ -668,19 +668,20 @@ final class HTTPClientRequest : HTTPRequest {
FreeListRef
!
ChunkedOutputStream
m_chunkedStream
;
bool
m_headerWritten
=
false
;
FixedAppender
!(
string
,
22
)
m_contentLengthBuffer
;
NetworkAddress
m_localAddress
;
TCPConnection
m_rawConn
;
TLSCertificateInformation
m_peerCertificate
;
}
/// private
this
(
InterfaceProxy
!
Stream
conn
,
NetworkAddress
local_addr
)
this
(
InterfaceProxy
!
Stream
conn
,
TCPConnection
raw_conn
)
{
super
(
conn
);
m_
localAddress
=
local_addr
;
m_
rawConn
=
raw_conn
;
}
@property
NetworkAddress
localAddress
()
const
{
return
m_localAddress
;
}
@property
NetworkAddress
localAddress
()
const
{
return
m_rawConn
.
localAddress
;
}
@property
NetworkAddress
remoteAddress
()
const
{
return
m_rawConn
.
remoteAddress
;
}
@property
ref
inout
(
TLSCertificateInformation
)
peerCertificate
()
inout
{
return
m_peerCertificate
;
}
...
...
http/vibe/http/common.d
View file @
8ab29186
...
...
@@ -638,30 +638,72 @@ final class Cookie {
none
=
raw
}
/// Cookie payload
@property
void
value
(
string
value
)
{
m_value
=
urlEncode
(
value
);
}
/// ditto
@property
string
value
()
const
{
return
urlDecode
(
m_value
);
}
/// Undecoded cookie payload
@property
void
rawValue
(
string
value
)
{
m_value
=
value
;
}
/// ditto
@property
string
rawValue
()
const
{
return
m_value
;
}
/// The domain for which the cookie is valid
@property
void
domain
(
string
value
)
{
m_domain
=
value
;
}
/// ditto
@property
string
domain
()
const
{
return
m_domain
;
}
/// The path/local URI for which the cookie is valid
@property
void
path
(
string
value
)
{
m_path
=
value
;
}
/// ditto
@property
string
path
()
const
{
return
m_path
;
}
/// Expiration date of the cookie
@property
void
expires
(
string
value
)
{
m_expires
=
value
;
}
/// ditto
@property
void
expires
(
SysTime
value
)
{
m_expires
=
value
.
toRFC822DateTimeString
();
}
/// ditto
@property
string
expires
()
const
{
return
m_expires
;
}
/** Maximum life time of the cookie
This is the modern variant of `expires`. For backwards compatibility it
is recommended to set both properties, or to use the `expire` method.
*/
@property
void
maxAge
(
long
value
)
{
m_maxAge
=
value
;
}
/// ditto
@property
void
maxAge
(
Duration
value
)
{
m_maxAge
=
value
.
total
!
"seconds"
;
}
/// ditto
@property
long
maxAge
()
const
{
return
m_maxAge
;
}
/** Require a secure connection for transmission of this cookie
*/
@property
void
secure
(
bool
value
)
{
m_secure
=
value
;
}
/// ditto
@property
bool
secure
()
const
{
return
m_secure
;
}
/** Prevents access to the cookie from scripts.
*/
@property
void
httpOnly
(
bool
value
)
{
m_httpOnly
=
value
;
}
/// ditto
@property
bool
httpOnly
()
const
{
return
m_httpOnly
;
}
/** Sets the "expires" and "max-age" attributes to limit the life time of
the cookie.
*/
void
expire
(
Duration
max_age
)
{
this
.
expires
=
Clock
.
currTime
(
UTC
())
+
max_age
;
this
.
maxAge
=
max_age
;
}
/// ditto
void
expire
(
SysTime
expire_time
)
{
this
.
expires
=
expire_time
;
this
.
maxAge
=
expire_time
-
Clock
.
currTime
(
UTC
());
}
/// Sets the cookie value encoded with the specified encoding.
void
setValue
(
string
value
,
Encoding
encoding
)
{
final
switch
(
encoding
)
{
...
...
@@ -670,6 +712,7 @@ final class Cookie {
}
}
/// Writes out the full cookie in HTTP compatible format.
void
writeString
(
R
)(
R
dst
,
string
name
)
if
(
isOutputRange
!(
R
,
char
))
{
...
...
http/vibe/http/dist.d
View file @
8ab29186
...
...
@@ -23,7 +23,7 @@ import std.process;
This function is usable as direct replacement of listenHTTP
*/
void
listenHTTPDist
(
HTTPServerSettings
settings
,
HTTPServerRequestDelegate
handler
,
string
balancer_address
,
ushort
balancer_port
=
11000
)
HTTPListener
listenHTTPDist
(
HTTPServerSettings
settings
,
HTTPServerRequestDelegate
handler
,
string
balancer_address
,
ushort
balancer_port
=
11000
)
@safe
{
Json
regmsg
=
Json
.
emptyObject
;
regmsg
[
"host_name"
]
=
settings
.
hostName
;
...
...
@@ -36,7 +36,7 @@ void listenHTTPDist(HTTPServerSettings settings, HTTPServerRequestDelegate handl
local_settings
.
bindAddresses
=
[
"127.0.0.1"
];
local_settings
.
port
=
0
;
local_settings
.
disableDistHost
=
true
;
listenHTTP
(
local_settings
,
handler
);
auto
ret
=
listenHTTP
(
local_settings
,
handler
);