Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
N
nghttp2
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
nghttp2
Commits
8e6b92bd
Commit
8e6b92bd
authored
Oct 08, 2015
by
Tatsuhiro Tsujikawa
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'nghttpx-mruby'
parents
c71c357f
2b8b8f1f
Changes
18
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
209 additions
and
182 deletions
+209
-182
doc/nghttpx.h2r
doc/nghttpx.h2r
+28
-24
gennghttpxfun.py
gennghttpxfun.py
+1
-2
integration-tests/nghttpx_http1_test.go
integration-tests/nghttpx_http1_test.go
+14
-14
integration-tests/nghttpx_http2_test.go
integration-tests/nghttpx_http2_test.go
+14
-14
integration-tests/nghttpx_spdy_test.go
integration-tests/nghttpx_spdy_test.go
+14
-14
integration-tests/req-return.rb
integration-tests/req-return.rb
+12
-0
integration-tests/req-set-header.rb
integration-tests/req-set-header.rb
+6
-2
integration-tests/resp-return.rb
integration-tests/resp-return.rb
+12
-0
integration-tests/resp-set-header.rb
integration-tests/resp-set-header.rb
+6
-2
integration-tests/return.rb
integration-tests/return.rb
+0
-8
src/shrpx.cc
src/shrpx.cc
+3
-8
src/shrpx_config.cc
src/shrpx_config.cc
+6
-20
src/shrpx_config.h
src/shrpx_config.h
+2
-4
src/shrpx_mruby.cc
src/shrpx_mruby.cc
+70
-34
src/shrpx_mruby.h
src/shrpx_mruby.h
+5
-6
src/shrpx_mruby_module.cc
src/shrpx_mruby_module.cc
+13
-28
src/shrpx_mruby_module.h
src/shrpx_mruby_module.h
+1
-1
src/shrpx_worker.cc
src/shrpx_worker.cc
+2
-1
No files found.
doc/nghttpx.h2r
View file @
8e6b92bd
...
...
@@ -185,23 +185,20 @@ server. These hooks allows users to modify header fields, or common
HTTP variables, like authority or request path, and even return custom
response without forwarding request to backend servers.
To set request phase hook, use :option:`--request-phase-file` option.
To set response phase hook, use :option:`--response-phase-file`
option.
For request and response phase hook, user calls :rb:meth:`Nghttpx.run`
with block. The :rb:class:`Nghttpx::Env` is passed to the block.
User can can access :rb:class:`Nghttpx::Request` and
:rb:class:`Nghttpx::Response` objects via :rb:attr:`Nghttpx::Env#req`
and :rb:attr:`Nghttpx::Env#resp` respectively.
To specify mruby script file, use :option:`--mruby-file` option. The
script will be evaluated once per thread on startup, and it must
instantiate object and evaluate it as the return value (e.g.,
``App.new``). This object is called app object. If app object
defines ``on_req`` method, it is called with :rb:class:`Nghttpx::Env`
object on request hook. Similarly, if app object defines ``on_resp``
method, it is called with :rb:class:`Nghttpx::Env` object on response
hook. For each method invocation, user can can access
:rb:class:`Nghttpx::Request` and :rb:class:`Nghttpx::Response` objects
via :rb:attr:`Nghttpx::Env#req` and :rb:attr:`Nghttpx::Env#resp`
respectively.
.. rb:module:: Nghttpx
.. rb:classmethod:: run(&block)
Run request or response phase hook with given *block*.
:rb:class:`Nghttpx::Env` object is passed to the given block.
.. rb:const:: REQUEST_PHASE
Constant to represent request phase.
...
...
@@ -379,28 +376,35 @@ Modify requet path:
.. code-block:: ruby
Nghttpx.run do |env|
env.req.path = "/apps#{env.req.path}"
class App
def on_req(env)
env.req.path = "/apps#{env.req.path}"
end
end
Note that the file containing the above script must be set with
:option:`--request-phase-file` option since we modify request path.
App.new
Don't forget to instantiate and evaluate object at the last line.
Restrict permission of viewing a content to a specific client
addresses:
.. code-block:: ruby
Nghttpx.run do |env|
allowed_clients = ["127.0.0.1", "::1"]
class App
def on_req(env)
allowed_clients = ["127.0.0.1", "::1"]
if env.req.path.start_with?("/log/") &&
!allowed_clients.include?(env.remote_addr) then
env.resp.status = 404
env.resp.return "permission denied"
if env.req.path.start_with?("/log/") &&
!allowed_clients.include?(env.remote_addr) then
env.resp.status = 404
env.resp.return "permission denied"
end
end
end
App.new
SEE ALSO
--------
...
...
gennghttpxfun.py
View file @
8e6b92bd
...
...
@@ -98,8 +98,7 @@ OPTIONS = [
"tls-ticket-key-memcached-interval"
,
"tls-ticket-key-memcached-max-retry"
,
"tls-ticket-key-memcached-max-fail"
,
"request-phase-file"
,
"response-phase-file"
,
"mruby-file"
,
"accept-proxy-protocol"
,
"conf"
,
"fastopen"
,
...
...
integration-tests/nghttpx_http1_test.go
View file @
8e6b92bd
...
...
@@ -360,7 +360,7 @@ func TestH1H1Websocket(t *testing.T) {
// TestH1H1ReqPhaseSetHeader tests mruby request phase hook
// modifies request header fields.
func
TestH1H1ReqPhaseSetHeader
(
t
*
testing
.
T
)
{
st
:=
newServerTester
([]
string
{
"--
request-phase
-file="
+
testDir
+
"/req-set-header.rb"
},
t
,
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
st
:=
newServerTester
([]
string
{
"--
mruby
-file="
+
testDir
+
"/req-set-header.rb"
},
t
,
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
if
got
,
want
:=
r
.
Header
.
Get
(
"User-Agent"
),
"mruby"
;
got
!=
want
{
t
.
Errorf
(
"User-Agent = %v; want %v"
,
got
,
want
)
}
...
...
@@ -382,7 +382,7 @@ func TestH1H1ReqPhaseSetHeader(t *testing.T) {
// TestH1H1ReqPhaseReturn tests mruby request phase hook returns
// custom response.
func
TestH1H1ReqPhaseReturn
(
t
*
testing
.
T
)
{
st
:=
newServerTester
([]
string
{
"--
request-phase-file="
+
testDir
+
"/
return.rb"
},
t
,
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
st
:=
newServerTester
([]
string
{
"--
mruby-file="
+
testDir
+
"/req-
return.rb"
},
t
,
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
t
.
Fatalf
(
"request should not be forwarded"
)
})
defer
st
.
Close
()
...
...
@@ -401,7 +401,7 @@ func TestH1H1ReqPhaseReturn(t *testing.T) {
hdtests
:=
[]
struct
{
k
,
v
string
}{
{
"content-length"
,
"
11
"
},
{
"content-length"
,
"
20
"
},
{
"from"
,
"mruby"
},
}
for
_
,
tt
:=
range
hdtests
{
...
...
@@ -410,7 +410,7 @@ func TestH1H1ReqPhaseReturn(t *testing.T) {
}
}
if
got
,
want
:=
string
(
res
.
body
),
"Hello World"
;
got
!=
want
{
if
got
,
want
:=
string
(
res
.
body
),
"Hello World
from req
"
;
got
!=
want
{
t
.
Errorf
(
"body = %v; want %v"
,
got
,
want
)
}
}
...
...
@@ -418,7 +418,7 @@ func TestH1H1ReqPhaseReturn(t *testing.T) {
// TestH1H1RespPhaseSetHeader tests mruby response phase hook modifies
// response header fields.
func
TestH1H1RespPhaseSetHeader
(
t
*
testing
.
T
)
{
st
:=
newServerTester
([]
string
{
"--
response-phase
-file="
+
testDir
+
"/resp-set-header.rb"
},
t
,
noopHandler
)
st
:=
newServerTester
([]
string
{
"--
mruby
-file="
+
testDir
+
"/resp-set-header.rb"
},
t
,
noopHandler
)
defer
st
.
Close
()
res
,
err
:=
st
.
http1
(
requestParam
{
...
...
@@ -440,7 +440,7 @@ func TestH1H1RespPhaseSetHeader(t *testing.T) {
// TestH1H1RespPhaseReturn tests mruby response phase hook returns
// custom response.
func
TestH1H1RespPhaseReturn
(
t
*
testing
.
T
)
{
st
:=
newServerTester
([]
string
{
"--
response-phase-file="
+
testDir
+
"/
return.rb"
},
t
,
noopHandler
)
st
:=
newServerTester
([]
string
{
"--
mruby-file="
+
testDir
+
"/resp-
return.rb"
},
t
,
noopHandler
)
defer
st
.
Close
()
res
,
err
:=
st
.
http1
(
requestParam
{
...
...
@@ -457,7 +457,7 @@ func TestH1H1RespPhaseReturn(t *testing.T) {
hdtests
:=
[]
struct
{
k
,
v
string
}{
{
"content-length"
,
"
1
1"
},
{
"content-length"
,
"
2
1"
},
{
"from"
,
"mruby"
},
}
for
_
,
tt
:=
range
hdtests
{
...
...
@@ -466,7 +466,7 @@ func TestH1H1RespPhaseReturn(t *testing.T) {
}
}
if
got
,
want
:=
string
(
res
.
body
),
"Hello World"
;
got
!=
want
{
if
got
,
want
:=
string
(
res
.
body
),
"Hello World
from resp
"
;
got
!=
want
{
t
.
Errorf
(
"body = %v; want %v"
,
got
,
want
)
}
}
...
...
@@ -667,7 +667,7 @@ func TestH1H2NoVia(t *testing.T) {
// TestH1H2ReqPhaseReturn tests mruby request phase hook returns
// custom response.
func
TestH1H2ReqPhaseReturn
(
t
*
testing
.
T
)
{
st
:=
newServerTester
([]
string
{
"--http2-bridge"
,
"--
request-phase-file="
+
testDir
+
"/
return.rb"
},
t
,
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
st
:=
newServerTester
([]
string
{
"--http2-bridge"
,
"--
mruby-file="
+
testDir
+
"/req-
return.rb"
},
t
,
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
t
.
Fatalf
(
"request should not be forwarded"
)
})
defer
st
.
Close
()
...
...
@@ -686,7 +686,7 @@ func TestH1H2ReqPhaseReturn(t *testing.T) {
hdtests
:=
[]
struct
{
k
,
v
string
}{
{
"content-length"
,
"
11
"
},
{
"content-length"
,
"
20
"
},
{
"from"
,
"mruby"
},
}
for
_
,
tt
:=
range
hdtests
{
...
...
@@ -695,7 +695,7 @@ func TestH1H2ReqPhaseReturn(t *testing.T) {
}
}
if
got
,
want
:=
string
(
res
.
body
),
"Hello World"
;
got
!=
want
{
if
got
,
want
:=
string
(
res
.
body
),
"Hello World
from req
"
;
got
!=
want
{
t
.
Errorf
(
"body = %v; want %v"
,
got
,
want
)
}
}
...
...
@@ -703,7 +703,7 @@ func TestH1H2ReqPhaseReturn(t *testing.T) {
// TestH1H2RespPhaseReturn tests mruby response phase hook returns
// custom response.
func
TestH1H2RespPhaseReturn
(
t
*
testing
.
T
)
{
st
:=
newServerTester
([]
string
{
"--http2-bridge"
,
"--
response-phase-file="
+
testDir
+
"/
return.rb"
},
t
,
noopHandler
)
st
:=
newServerTester
([]
string
{
"--http2-bridge"
,
"--
mruby-file="
+
testDir
+
"/resp-
return.rb"
},
t
,
noopHandler
)
defer
st
.
Close
()
res
,
err
:=
st
.
http1
(
requestParam
{
...
...
@@ -720,7 +720,7 @@ func TestH1H2RespPhaseReturn(t *testing.T) {
hdtests
:=
[]
struct
{
k
,
v
string
}{
{
"content-length"
,
"
1
1"
},
{
"content-length"
,
"
2
1"
},
{
"from"
,
"mruby"
},
}
for
_
,
tt
:=
range
hdtests
{
...
...
@@ -729,7 +729,7 @@ func TestH1H2RespPhaseReturn(t *testing.T) {
}
}
if
got
,
want
:=
string
(
res
.
body
),
"Hello World"
;
got
!=
want
{
if
got
,
want
:=
string
(
res
.
body
),
"Hello World
from resp
"
;
got
!=
want
{
t
.
Errorf
(
"body = %v; want %v"
,
got
,
want
)
}
}
integration-tests/nghttpx_http2_test.go
View file @
8e6b92bd
...
...
@@ -644,7 +644,7 @@ func TestH2H1HeaderFields(t *testing.T) {
// TestH2H1ReqPhaseSetHeader tests mruby request phase hook
// modifies request header fields.
func
TestH2H1ReqPhaseSetHeader
(
t
*
testing
.
T
)
{
st
:=
newServerTester
([]
string
{
"--
request-phase
-file="
+
testDir
+
"/req-set-header.rb"
},
t
,
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
st
:=
newServerTester
([]
string
{
"--
mruby
-file="
+
testDir
+
"/req-set-header.rb"
},
t
,
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
if
got
,
want
:=
r
.
Header
.
Get
(
"User-Agent"
),
"mruby"
;
got
!=
want
{
t
.
Errorf
(
"User-Agent = %v; want %v"
,
got
,
want
)
}
...
...
@@ -666,7 +666,7 @@ func TestH2H1ReqPhaseSetHeader(t *testing.T) {
// TestH2H1ReqPhaseReturn tests mruby request phase hook returns
// custom response.
func
TestH2H1ReqPhaseReturn
(
t
*
testing
.
T
)
{
st
:=
newServerTester
([]
string
{
"--
request-phase-file="
+
testDir
+
"/
return.rb"
},
t
,
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
st
:=
newServerTester
([]
string
{
"--
mruby-file="
+
testDir
+
"/req-
return.rb"
},
t
,
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
t
.
Fatalf
(
"request should not be forwarded"
)
})
defer
st
.
Close
()
...
...
@@ -685,7 +685,7 @@ func TestH2H1ReqPhaseReturn(t *testing.T) {
hdtests
:=
[]
struct
{
k
,
v
string
}{
{
"content-length"
,
"
11
"
},
{
"content-length"
,
"
20
"
},
{
"from"
,
"mruby"
},
}
for
_
,
tt
:=
range
hdtests
{
...
...
@@ -694,7 +694,7 @@ func TestH2H1ReqPhaseReturn(t *testing.T) {
}
}
if
got
,
want
:=
string
(
res
.
body
),
"Hello World"
;
got
!=
want
{
if
got
,
want
:=
string
(
res
.
body
),
"Hello World
from req
"
;
got
!=
want
{
t
.
Errorf
(
"body = %v; want %v"
,
got
,
want
)
}
}
...
...
@@ -702,7 +702,7 @@ func TestH2H1ReqPhaseReturn(t *testing.T) {
// TestH2H1RespPhaseSetHeader tests mruby response phase hook modifies
// response header fields.
func
TestH2H1RespPhaseSetHeader
(
t
*
testing
.
T
)
{
st
:=
newServerTester
([]
string
{
"--
response-phase
-file="
+
testDir
+
"/resp-set-header.rb"
},
t
,
noopHandler
)
st
:=
newServerTester
([]
string
{
"--
mruby
-file="
+
testDir
+
"/resp-set-header.rb"
},
t
,
noopHandler
)
defer
st
.
Close
()
res
,
err
:=
st
.
http2
(
requestParam
{
...
...
@@ -724,7 +724,7 @@ func TestH2H1RespPhaseSetHeader(t *testing.T) {
// TestH2H1RespPhaseReturn tests mruby response phase hook returns
// custom response.
func
TestH2H1RespPhaseReturn
(
t
*
testing
.
T
)
{
st
:=
newServerTester
([]
string
{
"--
response-phase-file="
+
testDir
+
"/
return.rb"
},
t
,
noopHandler
)
st
:=
newServerTester
([]
string
{
"--
mruby-file="
+
testDir
+
"/resp-
return.rb"
},
t
,
noopHandler
)
defer
st
.
Close
()
res
,
err
:=
st
.
http2
(
requestParam
{
...
...
@@ -741,7 +741,7 @@ func TestH2H1RespPhaseReturn(t *testing.T) {
hdtests
:=
[]
struct
{
k
,
v
string
}{
{
"content-length"
,
"
1
1"
},
{
"content-length"
,
"
2
1"
},
{
"from"
,
"mruby"
},
}
for
_
,
tt
:=
range
hdtests
{
...
...
@@ -750,7 +750,7 @@ func TestH2H1RespPhaseReturn(t *testing.T) {
}
}
if
got
,
want
:=
string
(
res
.
body
),
"Hello World"
;
got
!=
want
{
if
got
,
want
:=
string
(
res
.
body
),
"Hello World
from resp
"
;
got
!=
want
{
t
.
Errorf
(
"body = %v; want %v"
,
got
,
want
)
}
}
...
...
@@ -1351,7 +1351,7 @@ func TestH2H2TLSXfp(t *testing.T) {
// TestH2H2ReqPhaseReturn tests mruby request phase hook returns
// custom response.
func
TestH2H2ReqPhaseReturn
(
t
*
testing
.
T
)
{
st
:=
newServerTester
([]
string
{
"--http2-bridge"
,
"--
request-phase-file="
+
testDir
+
"/
return.rb"
},
t
,
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
st
:=
newServerTester
([]
string
{
"--http2-bridge"
,
"--
mruby-file="
+
testDir
+
"/req-
return.rb"
},
t
,
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
t
.
Fatalf
(
"request should not be forwarded"
)
})
defer
st
.
Close
()
...
...
@@ -1370,7 +1370,7 @@ func TestH2H2ReqPhaseReturn(t *testing.T) {
hdtests
:=
[]
struct
{
k
,
v
string
}{
{
"content-length"
,
"
11
"
},
{
"content-length"
,
"
20
"
},
{
"from"
,
"mruby"
},
}
for
_
,
tt
:=
range
hdtests
{
...
...
@@ -1379,7 +1379,7 @@ func TestH2H2ReqPhaseReturn(t *testing.T) {
}
}
if
got
,
want
:=
string
(
res
.
body
),
"Hello World"
;
got
!=
want
{
if
got
,
want
:=
string
(
res
.
body
),
"Hello World
from req
"
;
got
!=
want
{
t
.
Errorf
(
"body = %v; want %v"
,
got
,
want
)
}
}
...
...
@@ -1387,7 +1387,7 @@ func TestH2H2ReqPhaseReturn(t *testing.T) {
// TestH2H2RespPhaseReturn tests mruby response phase hook returns
// custom response.
func
TestH2H2RespPhaseReturn
(
t
*
testing
.
T
)
{
st
:=
newServerTester
([]
string
{
"--http2-bridge"
,
"--
response-phase-file="
+
testDir
+
"/
return.rb"
},
t
,
noopHandler
)
st
:=
newServerTester
([]
string
{
"--http2-bridge"
,
"--
mruby-file="
+
testDir
+
"/resp-
return.rb"
},
t
,
noopHandler
)
defer
st
.
Close
()
res
,
err
:=
st
.
http2
(
requestParam
{
...
...
@@ -1404,7 +1404,7 @@ func TestH2H2RespPhaseReturn(t *testing.T) {
hdtests
:=
[]
struct
{
k
,
v
string
}{
{
"content-length"
,
"
1
1"
},
{
"content-length"
,
"
2
1"
},
{
"from"
,
"mruby"
},
}
for
_
,
tt
:=
range
hdtests
{
...
...
@@ -1413,7 +1413,7 @@ func TestH2H2RespPhaseReturn(t *testing.T) {
}
}
if
got
,
want
:=
string
(
res
.
body
),
"Hello World"
;
got
!=
want
{
if
got
,
want
:=
string
(
res
.
body
),
"Hello World
from resp
"
;
got
!=
want
{
t
.
Errorf
(
"body = %v; want %v"
,
got
,
want
)
}
}
integration-tests/nghttpx_spdy_test.go
View file @
8e6b92bd
...
...
@@ -233,7 +233,7 @@ func TestS3H1InvalidMethod(t *testing.T) {
// TestS3H1ReqPhaseSetHeader tests mruby request phase hook
// modifies request header fields.
func
TestS3H1ReqPhaseSetHeader
(
t
*
testing
.
T
)
{
st
:=
newServerTesterTLS
([]
string
{
"--npn-list=spdy/3.1"
,
"--
request-phase
-file="
+
testDir
+
"/req-set-header.rb"
},
t
,
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
st
:=
newServerTesterTLS
([]
string
{
"--npn-list=spdy/3.1"
,
"--
mruby
-file="
+
testDir
+
"/req-set-header.rb"
},
t
,
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
if
got
,
want
:=
r
.
Header
.
Get
(
"User-Agent"
),
"mruby"
;
got
!=
want
{
t
.
Errorf
(
"User-Agent = %v; want %v"
,
got
,
want
)
}
...
...
@@ -255,7 +255,7 @@ func TestS3H1ReqPhaseSetHeader(t *testing.T) {
// TestS3H1ReqPhaseReturn tests mruby request phase hook returns
// custom response.
func
TestS3H1ReqPhaseReturn
(
t
*
testing
.
T
)
{
st
:=
newServerTesterTLS
([]
string
{
"--npn-list=spdy/3.1"
,
"--
request-phase-file="
+
testDir
+
"/
return.rb"
},
t
,
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
st
:=
newServerTesterTLS
([]
string
{
"--npn-list=spdy/3.1"
,
"--
mruby-file="
+
testDir
+
"/req-
return.rb"
},
t
,
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
t
.
Fatalf
(
"request should not be forwarded"
)
})
defer
st
.
Close
()
...
...
@@ -274,7 +274,7 @@ func TestS3H1ReqPhaseReturn(t *testing.T) {
hdtests
:=
[]
struct
{
k
,
v
string
}{
{
"content-length"
,
"
11
"
},
{
"content-length"
,
"
20
"
},
{
"from"
,
"mruby"
},
}
for
_
,
tt
:=
range
hdtests
{
...
...
@@ -283,7 +283,7 @@ func TestS3H1ReqPhaseReturn(t *testing.T) {
}
}
if
got
,
want
:=
string
(
res
.
body
),
"Hello World"
;
got
!=
want
{
if
got
,
want
:=
string
(
res
.
body
),
"Hello World
from req
"
;
got
!=
want
{
t
.
Errorf
(
"body = %v; want %v"
,
got
,
want
)
}
}
...
...
@@ -291,7 +291,7 @@ func TestS3H1ReqPhaseReturn(t *testing.T) {
// TestS3H1RespPhaseSetHeader tests mruby response phase hook modifies
// response header fields.
func
TestS3H1RespPhaseSetHeader
(
t
*
testing
.
T
)
{
st
:=
newServerTesterTLS
([]
string
{
"--npn-list=spdy/3.1"
,
"--
response-phase
-file="
+
testDir
+
"/resp-set-header.rb"
},
t
,
noopHandler
)
st
:=
newServerTesterTLS
([]
string
{
"--npn-list=spdy/3.1"
,
"--
mruby
-file="
+
testDir
+
"/resp-set-header.rb"
},
t
,
noopHandler
)
defer
st
.
Close
()
res
,
err
:=
st
.
spdy
(
requestParam
{
...
...
@@ -313,7 +313,7 @@ func TestS3H1RespPhaseSetHeader(t *testing.T) {
// TestS3H1RespPhaseReturn tests mruby response phase hook returns
// custom response.
func
TestS3H1RespPhaseReturn
(
t
*
testing
.
T
)
{
st
:=
newServerTesterTLS
([]
string
{
"--npn-list=spdy/3.1"
,
"--
response-phase-file="
+
testDir
+
"/
return.rb"
},
t
,
noopHandler
)
st
:=
newServerTesterTLS
([]
string
{
"--npn-list=spdy/3.1"
,
"--
mruby-file="
+
testDir
+
"/resp-
return.rb"
},
t
,
noopHandler
)
defer
st
.
Close
()
res
,
err
:=
st
.
spdy
(
requestParam
{
...
...
@@ -330,7 +330,7 @@ func TestS3H1RespPhaseReturn(t *testing.T) {
hdtests
:=
[]
struct
{
k
,
v
string
}{
{
"content-length"
,
"
1
1"
},
{
"content-length"
,
"
2
1"
},
{
"from"
,
"mruby"
},
}
for
_
,
tt
:=
range
hdtests
{
...
...
@@ -339,7 +339,7 @@ func TestS3H1RespPhaseReturn(t *testing.T) {
}
}
if
got
,
want
:=
string
(
res
.
body
),
"Hello World"
;
got
!=
want
{
if
got
,
want
:=
string
(
res
.
body
),
"Hello World
from resp
"
;
got
!=
want
{
t
.
Errorf
(
"body = %v; want %v"
,
got
,
want
)
}
}
...
...
@@ -368,7 +368,7 @@ func TestS3H2ConnectFailure(t *testing.T) {
// TestS3H2ReqPhaseReturn tests mruby request phase hook returns
// custom response.
func
TestS3H2ReqPhaseReturn
(
t
*
testing
.
T
)
{
st
:=
newServerTesterTLS
([]
string
{
"--npn-list=spdy/3.1"
,
"--http2-bridge"
,
"--
request-phase-file="
+
testDir
+
"/
return.rb"
},
t
,
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
st
:=
newServerTesterTLS
([]
string
{
"--npn-list=spdy/3.1"
,
"--http2-bridge"
,
"--
mruby-file="
+
testDir
+
"/req-
return.rb"
},
t
,
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
t
.
Fatalf
(
"request should not be forwarded"
)
})
defer
st
.
Close
()
...
...
@@ -387,7 +387,7 @@ func TestS3H2ReqPhaseReturn(t *testing.T) {
hdtests
:=
[]
struct
{
k
,
v
string
}{
{
"content-length"
,
"
11
"
},
{
"content-length"
,
"
20
"
},
{
"from"
,
"mruby"
},
}
for
_
,
tt
:=
range
hdtests
{
...
...
@@ -396,7 +396,7 @@ func TestS3H2ReqPhaseReturn(t *testing.T) {
}
}
if
got
,
want
:=
string
(
res
.
body
),
"Hello World"
;
got
!=
want
{
if
got
,
want
:=
string
(
res
.
body
),
"Hello World
from req
"
;
got
!=
want
{
t
.
Errorf
(
"body = %v; want %v"
,
got
,
want
)
}
}
...
...
@@ -404,7 +404,7 @@ func TestS3H2ReqPhaseReturn(t *testing.T) {
// TestS3H2RespPhaseReturn tests mruby response phase hook returns
// custom response.
func
TestS3H2RespPhaseReturn
(
t
*
testing
.
T
)
{
st
:=
newServerTesterTLS
([]
string
{
"--npn-list=spdy/3.1"
,
"--http2-bridge"
,
"--
response-phase-file="
+
testDir
+
"/
return.rb"
},
t
,
noopHandler
)
st
:=
newServerTesterTLS
([]
string
{
"--npn-list=spdy/3.1"
,
"--http2-bridge"
,
"--
mruby-file="
+
testDir
+
"/resp-
return.rb"
},
t
,
noopHandler
)
defer
st
.
Close
()
res
,
err
:=
st
.
spdy
(
requestParam
{
...
...
@@ -421,7 +421,7 @@ func TestS3H2RespPhaseReturn(t *testing.T) {
hdtests
:=
[]
struct
{
k
,
v
string
}{
{
"content-length"
,
"
1
1"
},
{
"content-length"
,
"
2
1"
},
{
"from"
,
"mruby"
},
}
for
_
,
tt
:=
range
hdtests
{
...
...
@@ -430,7 +430,7 @@ func TestS3H2RespPhaseReturn(t *testing.T) {
}
}
if
got
,
want
:=
string
(
res
.
body
),
"Hello World"
;
got
!=
want
{
if
got
,
want
:=
string
(
res
.
body
),
"Hello World
from resp
"
;
got
!=
want
{
t
.
Errorf
(
"body = %v; want %v"
,
got
,
want
)
}
}
integration-tests/req-return.rb
0 → 100644
View file @
8e6b92bd
class
App
def
on_req
(
env
)
resp
=
env
.
resp
resp
.
clear_headers
resp
.
status
=
404
resp
.
add_header
"from"
,
"mruby"
resp
.
return
"Hello World from req"
end
end
App
.
new
integration-tests/req-set-header.rb
View file @
8e6b92bd
Nghttpx
.
run
do
|
env
|
env
.
req
.
set_header
"User-Agent"
,
"mruby"
class
App
def
on_req
(
env
)
env
.
req
.
set_header
"User-Agent"
,
"mruby"
end
end
App
.
new
integration-tests/resp-return.rb
0 → 100644
View file @
8e6b92bd
class
App
def
on_resp
(
env
)
resp
=
env
.
resp
resp
.
clear_headers
resp
.
status
=
404
resp
.
add_header
"from"
,
"mruby"
resp
.
return
"Hello World from resp"
end
end
App
.
new
integration-tests/resp-set-header.rb
View file @
8e6b92bd
Nghttpx
.
run
do
|
env
|
env
.
resp
.
set_header
"Alpha"
,
"bravo"
class
App
def
on_resp
(
env
)
env
.
resp
.
set_header
"Alpha"
,
"bravo"
end
end
App
.
new
integration-tests/return.rb
deleted
100644 → 0
View file @
c71c357f
Nghttpx
.
run
do
|
env
|
resp
=
env
.
resp
resp
.
clear_headers
resp
.
status
=
404
resp
.
add_header
"from"
,
"mruby"
resp
.
return
"Hello World"
end
src/shrpx.cc
View file @
8e6b92bd
...
...
@@ -1801,8 +1801,7 @@ int main(int argc, char **argv) {
89
},
{
SHRPX_OPT_TLS_TICKET_KEY_MEMCACHED_MAX_FAIL
,
required_argument
,
&
flag
,
90
},
{
SHRPX_OPT_REQUEST_PHASE_FILE
,
required_argument
,
&
flag
,
91
},
{
SHRPX_OPT_RESPONSE_PHASE_FILE
,
required_argument
,
&
flag
,
92
},
{
SHRPX_OPT_MRUBY_FILE
,
required_argument
,
&
flag
,
91
},
{
SHRPX_OPT_ACCEPT_PROXY_PROTOCOL
,
no_argument
,
&
flag
,
93
},
{
SHRPX_OPT_FASTOPEN
,
required_argument
,
&
flag
,
94
},
{
nullptr
,
0
,
nullptr
,
0
}};
...
...
@@ -2199,12 +2198,8 @@ int main(int argc, char **argv) {
optarg
);
break
;
case
91
:
// --request-phase-file
cmdcfgs
.
emplace_back
(
SHRPX_OPT_REQUEST_PHASE_FILE
,
optarg
);
break
;
case
92
:
// --response-phase-file
cmdcfgs
.
emplace_back
(
SHRPX_OPT_RESPONSE_PHASE_FILE
,
optarg
);
// --mruby-file
cmdcfgs
.
emplace_back
(
SHRPX_OPT_MRUBY_FILE
,
optarg
);
break
;
case
93
:
// --accept-proxy-protocol
...
...
src/shrpx_config.cc
View file @
8e6b92bd
...
...
@@ -672,6 +672,7 @@ enum {
SHRPX_OPTID_LISTENER_DISABLE_TIMEOUT
,
SHRPX_OPTID_LOG_LEVEL
,
SHRPX_OPTID_MAX_HEADER_FIELDS
,
SHRPX_OPTID_MRUBY_FILE
,
SHRPX_OPTID_NO_HOST_REWRITE
,
SHRPX_OPTID_NO_LOCATION_REWRITE
,
SHRPX_OPTID_NO_OCSP
,
...
...
@@ -685,8 +686,6 @@ enum {
SHRPX_OPTID_PRIVATE_KEY_PASSWD_FILE
,
SHRPX_OPTID_READ_BURST
,
SHRPX_OPTID_READ_RATE
,
SHRPX_OPTID_REQUEST_PHASE_FILE
,
SHRPX_OPTID_RESPONSE_PHASE_FILE
,
SHRPX_OPTID_RLIMIT_NOFILE
,
SHRPX_OPTID_STREAM_READ_TIMEOUT
,
SHRPX_OPTID_STREAM_WRITE_TIMEOUT
,
...
...
@@ -844,6 +843,9 @@ int option_lookup_token(const char *name, size_t namelen) {
case
10
:
switch
(
name
[
9
])
{
case
'e'
:
if
(
util
::
strieq_l
(
"mruby-fil"
,
name
,
9
))
{
return
SHRPX_OPTID_MRUBY_FILE
;
}
if
(
util
::
strieq_l
(
"write-rat"
,
name
,
9
))
{
return
SHRPX_OPTID_WRITE_RATE
;
}
...
...
@@ -1013,11 +1015,6 @@ int option_lookup_token(const char *name, size_t namelen) {
break
;
case
18
:
switch
(
name
[
17
])
{
case
'e'
:
if
(
util
::
strieq_l
(
"request-phase-fil"
,
name
,
17
))
{
return
SHRPX_OPTID_REQUEST_PHASE_FILE
;
}
break
;
case
'r'
:
if
(
util
::
strieq_l
(
"add-request-heade"
,
name
,
17
))
{
return
SHRPX_OPTID_ADD_REQUEST_HEADER
;
...
...
@@ -1036,9 +1033,6 @@ int option_lookup_token(const char *name, size_t namelen) {
if
(
util
::
strieq_l
(
"no-location-rewrit"
,
name
,
18
))
{
return
SHRPX_OPTID_NO_LOCATION_REWRITE
;
}
if
(
util
::
strieq_l
(
"response-phase-fil"
,
name
,
18
))
{
return
SHRPX_OPTID_RESPONSE_PHASE_FILE
;
}
if
(
util
::
strieq_l
(
"tls-ticket-key-fil"
,
name
,
18
))
{
return
SHRPX_OPTID_TLS_TICKET_KEY_FILE
;
}
...
...
@@ -1967,17 +1961,9 @@ int parse_config(const char *opt, const char *optarg,
case
SHRPX_OPTID_TLS_TICKET_KEY_MEMCACHED_MAX_FAIL
:
return
parse_uint
(
&
mod_config
()
->
tls_ticket_key_memcached_max_fail
,
opt
,
optarg
);
case
SHRPX_OPTID_REQUEST_PHASE_FILE
:
#ifdef HAVE_MRUBY
mod_config
()
->
request_phase_file
=
strcopy
(
optarg
);
#else // !HAVE_MRUBY
LOG
(
WARN
)
<<
opt
<<
": ignored because mruby support is disabled at build time."
;
#endif // !HAVE_MRUBY
return
0
;
case
SHRPX_OPTID_RESPONSE_PHASE_FILE
:
case
SHRPX_OPTID_MRUBY_FILE
:
#ifdef HAVE_MRUBY
mod_config
()
->
response_phase
_file
=
strcopy
(
optarg
);
mod_config
()
->
mruby
_file
=
strcopy
(
optarg
);
#else // !HAVE_MRUBY
LOG
(
WARN
)
<<
opt
<<
": ignored because mruby support is disabled at build time."
;
...
...
src/shrpx_config.h
View file @
8e6b92bd
...
...
@@ -184,8 +184,7 @@ constexpr char SHRPX_OPT_TLS_TICKET_KEY_MEMCACHED_MAX_RETRY[] =
"tls-ticket-key-memcached-max-retry"
;
constexpr
char
SHRPX_OPT_TLS_TICKET_KEY_MEMCACHED_MAX_FAIL
[]
=
"tls-ticket-key-memcached-max-fail"
;
constexpr
char
SHRPX_OPT_REQUEST_PHASE_FILE
[]
=
"request-phase-file"
;
constexpr
char
SHRPX_OPT_RESPONSE_PHASE_FILE
[]
=
"response-phase-file"
;
constexpr
char
SHRPX_OPT_MRUBY_FILE
[]
=
"mruby-file"
;
constexpr
char
SHRPX_OPT_ACCEPT_PROXY_PROTOCOL
[]
=
"accept-proxy-protocol"
;
constexpr
char
SHRPX_OPT_FASTOPEN
[]
=
"fastopen"
;
...
...
@@ -325,8 +324,7 @@ struct Config {
std
::
unique_ptr
<
char
[]
>
user
;
std
::
unique_ptr
<
char
[]
>
session_cache_memcached_host
;
std
::
unique_ptr
<
char
[]
>
tls_ticket_key_memcached_host
;
std
::
unique_ptr
<
char
[]
>
request_phase_file
;
std
::
unique_ptr
<
char
[]
>
response_phase_file
;
std
::
unique_ptr
<
char
[]
>
mruby_file
;
FILE
*
http2_upstream_dump_request_header
;
FILE
*
http2_upstream_dump_response_header
;
nghttp2_session_callbacks
*
http2_upstream_callbacks
;
...
...
src/shrpx_mruby.cc
View file @
8e6b92bd
...
...
@@ -37,10 +37,8 @@ namespace shrpx {
namespace
mruby
{
MRubyContext
::
MRubyContext
(
mrb_state
*
mrb
,
RProc
*
on_request_proc
,
RProc
*
on_response_proc
)
:
mrb_
(
mrb
),
on_request_proc_
(
on_request_proc
),
on_response_proc_
(
on_response_proc
),
running_
(
false
)
{}
MRubyContext
::
MRubyContext
(
mrb_state
*
mrb
,
mrb_value
app
,
mrb_value
env
)
:
mrb_
(
mrb
),
app_
(
std
::
move
(
app
)),
env_
(
std
::
move
(
env
))
{}
MRubyContext
::~
MRubyContext
()
{
if
(
mrb_
)
{
...
...
@@ -48,22 +46,38 @@ MRubyContext::~MRubyContext() {
}
}
int
MRubyContext
::
run_request_proc
(
Downstream
*
downstream
,
RProc
*
proc
,
int
phase
)
{
if
(
!
proc
||
running_
)
{
int
MRubyContext
::
run_app
(
Downstream
*
downstream
,
int
phase
)
{
if
(
!
mrb_
)
{
return
0
;
}
running_
=
true
;
MRubyAssocData
data
{
downstream
,
phase
};
mrb_
->
ud
=
&
data
;
int
rv
=
0
;
auto
ai
=
mrb_gc_arena_save
(
mrb_
);
auto
ai_d
=
defer
([
ai
,
this
]()
{
mrb_gc_arena_restore
(
mrb_
,
ai
);
});
const
char
*
method
;
switch
(
phase
)
{
case
PHASE_REQUEST
:
if
(
!
mrb_respond_to
(
mrb_
,
app_
,
mrb_intern_lit
(
mrb_
,
"on_req"
)))
{
return
0
;
}
method
=
"on_req"
;
break
;
case
PHASE_RESPONSE
:
if
(
!
mrb_respond_to
(
mrb_
,
app_
,
mrb_intern_lit
(
mrb_
,
"on_resp"
)))
{
return
0
;
}
method
=
"on_resp"
;
break
;
default:
assert
(
0
);
}
auto
res
=
mrb_
run
(
mrb_
,
proc
,
mrb_top_self
(
mrb_
)
);
auto
res
=
mrb_
funcall
(
mrb_
,
app_
,
method
,
1
,
env_
);
(
void
)
res
;
if
(
mrb_
->
exc
)
{
...
...
@@ -71,18 +85,16 @@ int MRubyContext::run_request_proc(Downstream *downstream, RProc *proc,
if
(
downstream
->
get_response_state
()
!=
Downstream
::
MSG_COMPLETE
)
{
rv
=
-
1
;
}
auto
error
=
mrb_str_ptr
(
mrb_funcall
(
mrb_
,
mrb_obj_value
(
mrb_
->
exc
),
"inspect"
,
0
));
auto
exc
=
mrb_obj_value
(
mrb_
->
exc
);
auto
inspect
=
mrb_inspect
(
mrb_
,
exc
);
LOG
(
ERROR
)
<<
"Exception caught while executing mruby code: "
<<
error
->
as
.
heap
.
ptr
;
mrb_
->
exc
=
0
;
<<
mrb_str_to_cstr
(
mrb_
,
inspect
);
}
mrb_
->
ud
=
nullptr
;
mrb_gc_arena_restore
(
mrb_
,
ai
);
if
(
data
.
request_headers_dirty
)
{
downstream
->
index_request_headers
();
}
...
...
@@ -91,17 +103,15 @@ int MRubyContext::run_request_proc(Downstream *downstream, RProc *proc,
downstream
->
index_response_headers
();
}
running_
=
false
;
return
rv
;
}
int
MRubyContext
::
run_on_request_proc
(
Downstream
*
downstream
)
{
return
run_
request_proc
(
downstream
,
on_request_proc_
,
PHASE_REQUEST
);
return
run_
app
(
downstream
,
PHASE_REQUEST
);
}
int
MRubyContext
::
run_on_response_proc
(
Downstream
*
downstream
)
{
return
run_
request_proc
(
downstream
,
on_response_proc_
,
PHASE_RESPONSE
);
return
run_
app
(
downstream
,
PHASE_RESPONSE
);
}
void
MRubyContext
::
delete_downstream
(
Downstream
*
downstream
)
{
...
...
@@ -111,6 +121,26 @@ void MRubyContext::delete_downstream(Downstream *downstream) {
delete_downstream_from_module
(
mrb_
,
downstream
);
}
namespace
{
mrb_value
instantiate_app
(
mrb_state
*
mrb
,
RProc
*
proc
)
{
mrb
->
ud
=
nullptr
;
auto
res
=
mrb_run
(
mrb
,
proc
,
mrb_top_self
(
mrb
));
if
(
mrb
->
exc
)
{
auto
exc
=
mrb_obj_value
(
mrb
->
exc
);
auto
inspect
=
mrb_inspect
(
mrb
,
exc
);
LOG
(
ERROR
)
<<
"Exception caught while executing mruby code: "
<<
mrb_str_to_cstr
(
mrb
,
inspect
);
return
mrb_nil_value
();
}
return
res
;
}
}
// namespace
// Based on
// https://github.com/h2o/h2o/blob/master/lib/handler/mruby.c. It is
// very hard to write these kind of code because mruby has almost no
...
...
@@ -155,12 +185,9 @@ RProc *compile(mrb_state *mrb, const char *filename) {
return
proc
;
}
std
::
unique_ptr
<
MRubyContext
>
create_mruby_context
()
{
auto
req_file
=
get_config
()
->
request_phase_file
.
get
();
auto
res_file
=
get_config
()
->
response_phase_file
.
get
();
if
(
!
req_file
&&
!
res_file
)
{
return
make_unique
<
MRubyContext
>
(
nullptr
,
nullptr
,
nullptr
);
std
::
unique_ptr
<
MRubyContext
>
create_mruby_context
(
const
char
*
filename
)
{
if
(
!
filename
)
{
return
make_unique
<
MRubyContext
>
(
nullptr
,
mrb_nil_value
(),
mrb_nil_value
());
}
auto
mrb
=
mrb_open
();
...
...
@@ -169,25 +196,34 @@ std::unique_ptr<MRubyContext> create_mruby_context() {
return
nullptr
;
}
init_modul
e
(
mrb
);
auto
ai
=
mrb_gc_arena_sav
e
(
mrb
);
auto
req_proc
=
compile
(
mrb
,
req_fil
e
);
auto
req_proc
=
compile
(
mrb
,
filenam
e
);
if
(
req_file
&&
!
req_proc
)
{
LOG
(
ERROR
)
<<
"Could not compile mruby code "
<<
req_file
;
if
(
!
req_proc
)
{
mrb_gc_arena_restore
(
mrb
,
ai
);
LOG
(
ERROR
)
<<
"Could not compile mruby code "
<<
filename
;
mrb_close
(
mrb
);
return
nullptr
;
}
auto
res_proc
=
compile
(
mrb
,
res_file
);
auto
env
=
init_module
(
mrb
);
if
(
res_file
&&
!
res_proc
)
{
LOG
(
ERROR
)
<<
"Could not compile mruby code "
<<
res_file
;
auto
app
=
instantiate_app
(
mrb
,
req_proc
);
if
(
mrb_nil_p
(
app
))
{
mrb_gc_arena_restore
(
mrb
,
ai
);
LOG
(
ERROR
)
<<
"Could not instantiate mruby app from "
<<
filename
;
mrb_close
(
mrb
);
return
nullptr
;
}
return
make_unique
<
MRubyContext
>
(
mrb
,
req_proc
,
res_proc
);
mrb_gc_arena_restore
(
mrb
,
ai
);
// TODO These are not necessary, because we retain app and env?
mrb_gc_protect
(
mrb
,
env
);
mrb_gc_protect
(
mrb
,
app
);
return
make_unique
<
MRubyContext
>
(
mrb
,
std
::
move
(
app
),
std
::
move
(
env
));
}
mrb_sym
intern_ptr
(
mrb_state
*
mrb
,
void
*
ptr
)
{
...
...
src/shrpx_mruby.h
View file @
8e6b92bd
...
...
@@ -40,21 +40,20 @@ namespace mruby {
class
MRubyContext
{
public:
MRubyContext
(
mrb_state
*
mrb
,
RProc
*
on_request_proc
,
RProc
*
on_response_proc
);
MRubyContext
(
mrb_state
*
mrb
,
mrb_value
app
,
mrb_value
env
);
~
MRubyContext
();
int
run_on_request_proc
(
Downstream
*
downstream
);
int
run_on_response_proc
(
Downstream
*
downstream
);
int
run_
request_proc
(
Downstream
*
downstream
,
RProc
*
proc
,
int
phase
);
int
run_
app
(
Downstream
*
downstream
,
int
phase
);
void
delete_downstream
(
Downstream
*
downstream
);
private:
mrb_state
*
mrb_
;
RProc
*
on_request_proc_
;
RProc
*
on_response_proc_
;
bool
running_
;
mrb_value
app_
;
mrb_value
env_
;
};
enum
{
...
...
@@ -72,7 +71,7 @@ struct MRubyAssocData {
RProc
*
compile
(
mrb_state
*
mrb
,
const
char
*
filename
);
std
::
unique_ptr
<
MRubyContext
>
create_mruby_context
();
std
::
unique_ptr
<
MRubyContext
>
create_mruby_context
(
const
char
*
filename
);
// Return interned |ptr|.
mrb_sym
intern_ptr
(
mrb_state
*
mrb
,
void
*
ptr
);
...
...
src/shrpx_mruby_module.cc
View file @
8e6b92bd
...
...
@@ -41,36 +41,21 @@ namespace shrpx {
namespace
mruby
{
namespace
{
mrb_value
run
(
mrb_state
*
mrb
,
mrb_value
self
)
{
mrb_value
b
;
mrb_get_args
(
mrb
,
"&"
,
&
b
);
if
(
mrb_nil_p
(
b
))
{
return
mrb_nil_value
();
}
mrb_value
create_env
(
mrb_state
*
mrb
)
{
auto
module
=
mrb_module_get
(
mrb
,
"Nghttpx"
);
auto
env_sym
=
mrb_intern_lit
(
mrb
,
"env"
);
auto
env
=
mrb_obj_iv_get
(
mrb
,
reinterpret_cast
<
RObject
*>
(
module
),
env_sym
);
if
(
mrb_nil_p
(
env
))
{
auto
env_class
=
mrb_class_get_under
(
mrb
,
module
,
"Env"
);
auto
request_class
=
mrb_class_get_under
(
mrb
,
module
,
"Request"
);
auto
response_class
=
mrb_class_get_under
(
mrb
,
module
,
"Response"
);
env
=
mrb_obj_new
(
mrb
,
env_class
,
0
,
nullptr
);
auto
req
=
mrb_obj_new
(
mrb
,
request_class
,
0
,
nullptr
);
auto
resp
=
mrb_obj_new
(
mrb
,
response_class
,
0
,
nullptr
);
auto
env_class
=
mrb_class_get_under
(
mrb
,
module
,
"Env"
);
auto
request_class
=
mrb_class_get_under
(
mrb
,
module
,
"Request"
);
auto
response_class
=
mrb_class_get_under
(
mrb
,
module
,
"Response"
);
mrb_iv_set
(
mrb
,
env
,
mrb_intern_lit
(
mrb
,
"req"
),
req
);
mrb_iv_set
(
mrb
,
env
,
mrb_intern_lit
(
mrb
,
"resp"
),
resp
);
auto
env
=
mrb_obj_new
(
mrb
,
env_class
,
0
,
nullptr
);
auto
req
=
mrb_obj_new
(
mrb
,
request_class
,
0
,
nullptr
);
auto
resp
=
mrb_obj_new
(
mrb
,
response_class
,
0
,
nullptr
);
mrb_obj_iv_set
(
mrb
,
reinterpret_cast
<
RObject
*>
(
module
),
env_sym
,
env
);
}
mrb_iv_set
(
mrb
,
env
,
mrb_intern_lit
(
mrb
,
"req"
),
req
);
mrb_iv_set
(
mrb
,
env
,
mrb_intern_lit
(
mrb
,
"resp"
),
resp
);
std
::
array
<
mrb_value
,
1
>
args
{{
env
}};
return
mrb_yield_argv
(
mrb
,
b
,
args
.
size
(),
args
.
data
());
return
env
;
}
}
// namespace
...
...
@@ -85,11 +70,9 @@ void delete_downstream_from_module(mrb_state *mrb, Downstream *downstream) {
mrb_iv_remove
(
mrb
,
env
,
intern_ptr
(
mrb
,
downstream
));
}
void
init_module
(
mrb_state
*
mrb
)
{
mrb_value
init_module
(
mrb_state
*
mrb
)
{
auto
module
=
mrb_define_module
(
mrb
,
"Nghttpx"
);
mrb_define_class_method
(
mrb
,
module
,
"run"
,
run
,
MRB_ARGS_REQ
(
1
)
|
MRB_ARGS_BLOCK
());
mrb_define_const
(
mrb
,
module
,
"REQUEST_PHASE"
,
mrb_fixnum_value
(
PHASE_REQUEST
));
mrb_define_const
(
mrb
,
module
,
"RESPONSE_PHASE"
,
...
...
@@ -98,6 +81,8 @@ void init_module(mrb_state *mrb) {
init_env_class
(
mrb
,
module
);
init_request_class
(
mrb
,
module
);
init_response_class
(
mrb
,
module
);
return
create_env
(
mrb
);
}
mrb_value
create_headers_hash
(
mrb_state
*
mrb
,
const
Headers
&
headers
)
{
...
...
src/shrpx_mruby_module.h
View file @
8e6b92bd
...
...
@@ -39,7 +39,7 @@ class Downstream;
namespace
mruby
{
void
init_module
(
mrb_state
*
mrb
);
mrb_value
init_module
(
mrb_state
*
mrb
);
void
delete_downstream_from_module
(
mrb_state
*
mrb
,
Downstream
*
downstream
);
...
...
src/shrpx_worker.cc
View file @
8e6b92bd
...
...
@@ -270,7 +270,8 @@ MemcachedDispatcher *Worker::get_session_cache_memcached_dispatcher() {
#ifdef HAVE_MRUBY
int
Worker
::
create_mruby_context
()
{
mruby_ctx_
=
mruby
::
create_mruby_context
();
auto
mruby_file
=
get_config
()
->
mruby_file
.
get
();
mruby_ctx_
=
mruby
::
create_mruby_context
(
mruby_file
);
if
(
!
mruby_ctx_
)
{
return
-
1
;
}
...
...
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