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
c04c09ff
Commit
c04c09ff
authored
Jun 05, 2012
by
Tatsuhiro Tsujikawa
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Avoid too large buffering in upstream output.
parent
fad7f51f
Changes
14
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
267 additions
and
49 deletions
+267
-49
examples/Makefile.am
examples/Makefile.am
+1
-0
examples/shrpx.cc
examples/shrpx.cc
+1
-1
examples/shrpx_client_handler.cc
examples/shrpx_client_handler.cc
+3
-3
examples/shrpx_config.h
examples/shrpx_config.h
+2
-0
examples/shrpx_downstream.cc
examples/shrpx_downstream.cc
+23
-0
examples/shrpx_downstream.h
examples/shrpx_downstream.h
+5
-1
examples/shrpx_error.h
examples/shrpx_error.h
+2
-0
examples/shrpx_https_upstream.cc
examples/shrpx_https_upstream.cc
+48
-12
examples/shrpx_https_upstream.h
examples/shrpx_https_upstream.h
+5
-1
examples/shrpx_io_control.cc
examples/shrpx_io_control.cc
+61
-0
examples/shrpx_io_control.h
examples/shrpx_io_control.h
+58
-0
examples/shrpx_spdy_upstream.cc
examples/shrpx_spdy_upstream.cc
+56
-31
examples/shrpx_spdy_upstream.h
examples/shrpx_spdy_upstream.h
+1
-0
examples/shrpx_upstream.h
examples/shrpx_upstream.h
+1
-0
No files found.
examples/Makefile.am
View file @
c04c09ff
...
@@ -77,6 +77,7 @@ shrpx_SOURCES = ${HELPER_OBJECTS} ${HELPER_HFILES} \
...
@@ -77,6 +77,7 @@ shrpx_SOURCES = ${HELPER_OBJECTS} ${HELPER_HFILES} \
shrpx_downstream.cc shrpx_downstream.h
\
shrpx_downstream.cc shrpx_downstream.h
\
shrpx_log.cc shrpx_log.h
\
shrpx_log.cc shrpx_log.h
\
shrpx_http.cc shrpx_http.h
\
shrpx_http.cc shrpx_http.h
\
shrpx_io_control.cc shrpx_io_control.h
\
htparse/htparse.c htparse/htparse.h
htparse/htparse.c htparse/htparse.h
noinst_PROGRAMS
=
spdycli
noinst_PROGRAMS
=
spdycli
...
...
examples/shrpx.cc
View file @
c04c09ff
...
@@ -285,7 +285,7 @@ int main(int argc, char **argv)
...
@@ -285,7 +285,7 @@ int main(int argc, char **argv)
mod_config
()
->
upstream_read_timeout
.
tv_sec
=
30
;
mod_config
()
->
upstream_read_timeout
.
tv_sec
=
30
;
mod_config
()
->
upstream_read_timeout
.
tv_usec
=
0
;
mod_config
()
->
upstream_read_timeout
.
tv_usec
=
0
;
mod_config
()
->
upstream_write_timeout
.
tv_sec
=
3
0
;
mod_config
()
->
upstream_write_timeout
.
tv_sec
=
6
0
;
mod_config
()
->
upstream_write_timeout
.
tv_usec
=
0
;
mod_config
()
->
upstream_write_timeout
.
tv_usec
=
0
;
mod_config
()
->
spdy_upstream_read_timeout
.
tv_sec
=
600
;
mod_config
()
->
spdy_upstream_read_timeout
.
tv_sec
=
600
;
...
...
examples/shrpx_client_handler.cc
View file @
c04c09ff
...
@@ -48,12 +48,12 @@ void upstream_readcb(bufferevent *bev, void *arg)
...
@@ -48,12 +48,12 @@ void upstream_readcb(bufferevent *bev, void *arg)
namespace
{
namespace
{
void
upstream_writecb
(
bufferevent
*
bev
,
void
*
arg
)
void
upstream_writecb
(
bufferevent
*
bev
,
void
*
arg
)
{
{
if
(
ENABLE_LOG
)
{
LOG
(
INFO
)
<<
"<upstream> upstream_writecb"
;
}
ClientHandler
*
handler
=
reinterpret_cast
<
ClientHandler
*>
(
arg
);
ClientHandler
*
handler
=
reinterpret_cast
<
ClientHandler
*>
(
arg
);
if
(
handler
->
get_should_close_after_write
())
{
if
(
handler
->
get_should_close_after_write
())
{
delete
handler
;
delete
handler
;
}
else
{
Upstream
*
upstream
=
handler
->
get_upstream
();
upstream
->
on_write
();
}
}
}
}
}
// namespace
}
// namespace
...
...
examples/shrpx_config.h
View file @
c04c09ff
...
@@ -25,6 +25,8 @@
...
@@ -25,6 +25,8 @@
#ifndef SHRPX_CONFIG_H
#ifndef SHRPX_CONFIG_H
#define SHRPX_CONFIG_H
#define SHRPX_CONFIG_H
#include "shrpx.h"
#include <stdint.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/socket.h>
...
...
examples/shrpx_downstream.cc
View file @
c04c09ff
...
@@ -41,6 +41,7 @@ Downstream::Downstream(Upstream *upstream, int stream_id, int priority)
...
@@ -41,6 +41,7 @@ Downstream::Downstream(Upstream *upstream, int stream_id, int priority)
bev_
(
0
),
bev_
(
0
),
stream_id_
(
stream_id
),
stream_id_
(
stream_id
),
priority_
(
priority
),
priority_
(
priority
),
ioctrl_
(
0
),
request_state_
(
INITIAL
),
request_state_
(
INITIAL
),
chunked_request_
(
false
),
chunked_request_
(
false
),
request_connection_close_
(
false
),
request_connection_close_
(
false
),
...
@@ -56,6 +57,7 @@ Downstream::Downstream(Upstream *upstream, int stream_id, int priority)
...
@@ -56,6 +57,7 @@ Downstream::Downstream(Upstream *upstream, int stream_id, int priority)
bev_
=
bufferevent_socket_new
bev_
=
bufferevent_socket_new
(
evbase
,
-
1
,
(
evbase
,
-
1
,
BEV_OPT_CLOSE_ON_FREE
|
BEV_OPT_DEFER_CALLBACKS
);
BEV_OPT_CLOSE_ON_FREE
|
BEV_OPT_DEFER_CALLBACKS
);
ioctrl_
.
set_bev
(
bev_
);
}
}
Downstream
::~
Downstream
()
Downstream
::~
Downstream
()
...
@@ -75,6 +77,16 @@ Downstream::~Downstream()
...
@@ -75,6 +77,16 @@ Downstream::~Downstream()
}
}
}
}
void
Downstream
::
pause_read
(
IOCtrlReason
reason
)
{
ioctrl_
.
pause_read
(
reason
);
}
bool
Downstream
::
resume_read
(
IOCtrlReason
reason
)
{
return
ioctrl_
.
resume_read
(
reason
);
}
namespace
{
namespace
{
void
check_transfer_encoding_chunked
(
bool
*
chunked
,
void
check_transfer_encoding_chunked
(
bool
*
chunked
,
const
Headers
::
value_type
&
item
)
const
Headers
::
value_type
&
item
)
...
@@ -394,6 +406,16 @@ int Downstream::get_response_state() const
...
@@ -394,6 +406,16 @@ int Downstream::get_response_state() const
return
response_state_
;
return
response_state_
;
}
}
namespace
{
void
body_buf_cb
(
evbuffer
*
body
,
size_t
oldlen
,
size_t
newlen
,
void
*
arg
)
{
Downstream
*
downstream
=
reinterpret_cast
<
Downstream
*>
(
arg
);
if
(
newlen
==
0
)
{
downstream
->
resume_read
(
SHRPX_NO_BUFFER
);
}
}
}
// namespace
int
Downstream
::
init_response_body_buf
()
int
Downstream
::
init_response_body_buf
()
{
{
assert
(
response_body_buf_
==
0
);
assert
(
response_body_buf_
==
0
);
...
@@ -401,6 +423,7 @@ int Downstream::init_response_body_buf()
...
@@ -401,6 +423,7 @@ int Downstream::init_response_body_buf()
if
(
response_body_buf_
==
0
)
{
if
(
response_body_buf_
==
0
)
{
DIE
();
DIE
();
}
}
evbuffer_setcb
(
response_body_buf_
,
body_buf_cb
,
this
);
return
0
;
return
0
;
}
}
...
...
examples/shrpx_downstream.h
View file @
c04c09ff
...
@@ -39,6 +39,8 @@ extern "C" {
...
@@ -39,6 +39,8 @@ extern "C" {
#include "htparse/htparse.h"
#include "htparse/htparse.h"
}
}
#include "shrpx_io_control.h"
namespace
shrpx
{
namespace
shrpx
{
class
Upstream
;
class
Upstream
;
...
@@ -52,6 +54,8 @@ public:
...
@@ -52,6 +54,8 @@ public:
int
start_connection
();
int
start_connection
();
Upstream
*
get_upstream
()
const
;
Upstream
*
get_upstream
()
const
;
int32_t
get_stream_id
()
const
;
int32_t
get_stream_id
()
const
;
void
pause_read
(
IOCtrlReason
reason
);
bool
resume_read
(
IOCtrlReason
reason
);
// downstream request API
// downstream request API
const
Headers
&
get_request_headers
()
const
;
const
Headers
&
get_request_headers
()
const
;
void
add_request_header
(
const
std
::
string
&
name
,
const
std
::
string
&
value
);
void
add_request_header
(
const
std
::
string
&
name
,
const
std
::
string
&
value
);
...
@@ -89,7 +93,7 @@ private:
...
@@ -89,7 +93,7 @@ private:
bufferevent
*
bev_
;
bufferevent
*
bev_
;
int32_t
stream_id_
;
int32_t
stream_id_
;
int
priority_
;
int
priority_
;
IOControl
ioctrl_
;
int
request_state_
;
int
request_state_
;
std
::
string
request_method_
;
std
::
string
request_method_
;
std
::
string
request_path_
;
std
::
string
request_path_
;
...
...
examples/shrpx_error.h
View file @
c04c09ff
...
@@ -25,6 +25,8 @@
...
@@ -25,6 +25,8 @@
#ifndef SHRPX_ERROR_H
#ifndef SHRPX_ERROR_H
#define SHRPX_ERROR_H
#define SHRPX_ERROR_H
#include "shrpx.h"
namespace
shrpx
{
namespace
shrpx
{
enum
ErrorCode
{
enum
ErrorCode
{
...
...
examples/shrpx_https_upstream.cc
View file @
c04c09ff
...
@@ -38,9 +38,14 @@ using namespace spdylay;
...
@@ -38,9 +38,14 @@ using namespace spdylay;
namespace
shrpx
{
namespace
shrpx
{
namespace
{
const
size_t
SHRPX_HTTPS_UPSTREAM_OUTPUT_UPPER_THRES
=
512
*
1024
;
}
// namespace
HttpsUpstream
::
HttpsUpstream
(
ClientHandler
*
handler
)
HttpsUpstream
::
HttpsUpstream
(
ClientHandler
*
handler
)
:
handler_
(
handler
),
:
handler_
(
handler
),
htp_
(
htparser_new
())
htp_
(
htparser_new
()),
ioctrl_
(
handler
->
get_bev
())
{
{
if
(
ENABLE_LOG
)
{
if
(
ENABLE_LOG
)
{
LOG
(
INFO
)
<<
"HttpsUpstream ctor"
;
LOG
(
INFO
)
<<
"HttpsUpstream ctor"
;
...
@@ -221,7 +226,7 @@ int HttpsUpstream::on_read()
...
@@ -221,7 +226,7 @@ int HttpsUpstream::on_read()
evbuffer_drain
(
input
,
nread
);
evbuffer_drain
(
input
,
nread
);
htpparse_error
htperr
=
htparser_get_error
(
htp_
);
htpparse_error
htperr
=
htparser_get_error
(
htp_
);
if
(
htperr
==
htparse_error_user
)
{
if
(
htperr
==
htparse_error_user
)
{
bufferevent_disable
(
bev
,
EV_READ
);
pause_read
(
SHRPX_MSG_BLOCK
);
if
(
ENABLE_LOG
)
{
if
(
ENABLE_LOG
)
{
LOG
(
INFO
)
<<
"<upstream> remaining bytes "
<<
evbuffer_get_length
(
input
);
LOG
(
INFO
)
<<
"<upstream> remaining bytes "
<<
evbuffer_get_length
(
input
);
}
}
...
@@ -235,6 +240,15 @@ int HttpsUpstream::on_read()
...
@@ -235,6 +240,15 @@ int HttpsUpstream::on_read()
return
0
;
return
0
;
}
}
int
HttpsUpstream
::
on_write
()
{
Downstream
*
downstream
=
get_top_downstream
();
if
(
downstream
)
{
downstream
->
resume_read
(
SHRPX_NO_BUFFER
);
}
return
0
;
}
int
HttpsUpstream
::
on_event
()
int
HttpsUpstream
::
on_event
()
{
{
return
0
;
return
0
;
...
@@ -245,11 +259,18 @@ ClientHandler* HttpsUpstream::get_client_handler() const
...
@@ -245,11 +259,18 @@ ClientHandler* HttpsUpstream::get_client_handler() const
return
handler_
;
return
handler_
;
}
}
void
HttpsUpstream
::
resume_read
()
void
HttpsUpstream
::
pause_read
(
IOCtrlReason
reason
)
{
ioctrl_
.
pause_read
(
reason
);
}
void
HttpsUpstream
::
resume_read
(
IOCtrlReason
reason
)
{
{
bufferevent_enable
(
handler_
->
get_bev
(),
EV_READ
);
if
(
ioctrl_
.
resume_read
(
reason
))
{
// Process remaining data in input buffer here.
// Process remaining data in input buffer here because these bytes
on_read
();
// are not notified by readcb until new data arrive.
on_read
();
}
}
}
namespace
{
namespace
{
...
@@ -264,7 +285,14 @@ void https_downstream_readcb(bufferevent *bev, void *ptr)
...
@@ -264,7 +285,14 @@ void https_downstream_readcb(bufferevent *bev, void *ptr)
assert
(
downstream
==
upstream
->
get_top_downstream
());
assert
(
downstream
==
upstream
->
get_top_downstream
());
upstream
->
pop_downstream
();
upstream
->
pop_downstream
();
delete
downstream
;
delete
downstream
;
upstream
->
resume_read
();
upstream
->
resume_read
(
SHRPX_MSG_BLOCK
);
}
else
{
ClientHandler
*
handler
=
upstream
->
get_client_handler
();
bufferevent
*
bev
=
handler
->
get_bev
();
size_t
outputlen
=
evbuffer_get_length
(
bufferevent_get_output
(
bev
));
if
(
outputlen
>
SHRPX_HTTPS_UPSTREAM_OUTPUT_UPPER_THRES
)
{
downstream
->
pause_read
(
SHRPX_NO_BUFFER
);
}
}
}
}
else
{
}
else
{
if
(
downstream
->
get_response_state
()
==
Downstream
::
HEADER_COMPLETE
)
{
if
(
downstream
->
get_response_state
()
==
Downstream
::
HEADER_COMPLETE
)
{
...
@@ -274,7 +302,7 @@ void https_downstream_readcb(bufferevent *bev, void *ptr)
...
@@ -274,7 +302,7 @@ void https_downstream_readcb(bufferevent *bev, void *ptr)
assert
(
downstream
==
upstream
->
get_top_downstream
());
assert
(
downstream
==
upstream
->
get_top_downstream
());
upstream
->
pop_downstream
();
upstream
->
pop_downstream
();
delete
downstream
;
delete
downstream
;
upstream
->
resume_read
();
upstream
->
resume_read
(
SHRPX_MSG_BLOCK
);
}
}
}
}
}
}
...
@@ -320,7 +348,7 @@ void https_downstream_eventcb(bufferevent *bev, short events, void *ptr)
...
@@ -320,7 +348,7 @@ void https_downstream_eventcb(bufferevent *bev, short events, void *ptr)
}
}
upstream
->
pop_downstream
();
upstream
->
pop_downstream
();
delete
downstream
;
delete
downstream
;
upstream
->
resume_read
();
upstream
->
resume_read
(
SHRPX_MSG_BLOCK
);
}
else
if
(
events
&
(
BEV_EVENT_ERROR
|
BEV_EVENT_TIMEOUT
))
{
}
else
if
(
events
&
(
BEV_EVENT_ERROR
|
BEV_EVENT_TIMEOUT
))
{
if
(
ENABLE_LOG
)
{
if
(
ENABLE_LOG
)
{
LOG
(
INFO
)
<<
"<downstream> error/timeout. "
<<
downstream
;
LOG
(
INFO
)
<<
"<downstream> error/timeout. "
<<
downstream
;
...
@@ -336,7 +364,7 @@ void https_downstream_eventcb(bufferevent *bev, short events, void *ptr)
...
@@ -336,7 +364,7 @@ void https_downstream_eventcb(bufferevent *bev, short events, void *ptr)
}
}
upstream
->
pop_downstream
();
upstream
->
pop_downstream
();
delete
downstream
;
delete
downstream
;
upstream
->
resume_read
();
upstream
->
resume_read
(
SHRPX_MSG_BLOCK
);
}
}
}
}
}
// namespace
}
// namespace
...
@@ -384,12 +412,20 @@ void HttpsUpstream::pop_downstream()
...
@@ -384,12 +412,20 @@ void HttpsUpstream::pop_downstream()
Downstream
*
HttpsUpstream
::
get_top_downstream
()
Downstream
*
HttpsUpstream
::
get_top_downstream
()
{
{
return
downstream_queue_
.
front
();
if
(
downstream_queue_
.
empty
())
{
return
0
;
}
else
{
return
downstream_queue_
.
front
();
}
}
}
Downstream
*
HttpsUpstream
::
get_last_downstream
()
Downstream
*
HttpsUpstream
::
get_last_downstream
()
{
{
return
downstream_queue_
.
back
();
if
(
downstream_queue_
.
empty
())
{
return
0
;
}
else
{
return
downstream_queue_
.
back
();
}
}
}
int
HttpsUpstream
::
on_downstream_header_complete
(
Downstream
*
downstream
)
int
HttpsUpstream
::
on_downstream_header_complete
(
Downstream
*
downstream
)
...
...
examples/shrpx_https_upstream.h
View file @
c04c09ff
...
@@ -36,6 +36,7 @@ extern "C" {
...
@@ -36,6 +36,7 @@ extern "C" {
}
}
#include "shrpx_upstream.h"
#include "shrpx_upstream.h"
#include "shrpx_io_control.h"
namespace
shrpx
{
namespace
shrpx
{
...
@@ -46,6 +47,7 @@ public:
...
@@ -46,6 +47,7 @@ public:
HttpsUpstream
(
ClientHandler
*
handler
);
HttpsUpstream
(
ClientHandler
*
handler
);
virtual
~
HttpsUpstream
();
virtual
~
HttpsUpstream
();
virtual
int
on_read
();
virtual
int
on_read
();
virtual
int
on_write
();
virtual
int
on_event
();
virtual
int
on_event
();
//int send();
//int send();
virtual
ClientHandler
*
get_client_handler
()
const
;
virtual
ClientHandler
*
get_client_handler
()
const
;
...
@@ -58,7 +60,8 @@ public:
...
@@ -58,7 +60,8 @@ public:
Downstream
*
get_last_downstream
();
Downstream
*
get_last_downstream
();
void
error_reply
(
Downstream
*
downstream
,
int
status_code
);
void
error_reply
(
Downstream
*
downstream
,
int
status_code
);
void
resume_read
();
void
pause_read
(
IOCtrlReason
reason
);
void
resume_read
(
IOCtrlReason
reason
);
virtual
int
on_downstream_header_complete
(
Downstream
*
downstream
);
virtual
int
on_downstream_header_complete
(
Downstream
*
downstream
);
virtual
int
on_downstream_body
(
Downstream
*
downstream
,
virtual
int
on_downstream_body
(
Downstream
*
downstream
,
...
@@ -69,6 +72,7 @@ private:
...
@@ -69,6 +72,7 @@ private:
ClientHandler
*
handler_
;
ClientHandler
*
handler_
;
htparser
*
htp_
;
htparser
*
htp_
;
std
::
deque
<
Downstream
*>
downstream_queue_
;
std
::
deque
<
Downstream
*>
downstream_queue_
;
IOControl
ioctrl_
;
};
};
}
// namespace shrpx
}
// namespace shrpx
...
...
examples/shrpx_io_control.cc
0 → 100644
View file @
c04c09ff
/*
* Spdylay - SPDY Library
*
* Copyright (c) 2012 Tatsuhiro Tsujikawa
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "shrpx_io_control.h"
#include <algorithm>
namespace
shrpx
{
IOControl
::
IOControl
(
bufferevent
*
bev
)
:
bev_
(
bev
),
ctrlv_
(
SHRPX_REASON_MAX
)
{}
IOControl
::~
IOControl
()
{}
void
IOControl
::
set_bev
(
bufferevent
*
bev
)
{
bev_
=
bev
;
}
void
IOControl
::
pause_read
(
IOCtrlReason
reason
)
{
ctrlv_
[
reason
]
=
1
;
bufferevent_disable
(
bev_
,
EV_READ
);
}
bool
IOControl
::
resume_read
(
IOCtrlReason
reason
)
{
ctrlv_
[
reason
]
=
0
;
if
(
std
::
find
(
ctrlv_
.
begin
(),
ctrlv_
.
end
(),
1
)
==
ctrlv_
.
end
())
{
bufferevent_enable
(
bev_
,
EV_READ
);
return
true
;
}
else
{
return
false
;
}
}
}
// namespace shrpx
examples/shrpx_io_control.h
0 → 100644
View file @
c04c09ff
/*
* Spdylay - SPDY Library
*
* Copyright (c) 2012 Tatsuhiro Tsujikawa
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef SHRPX_IO_CONTROL_H
#define SHRPX_IO_CONTROL_H
#include "shrpx.h"
#include <vector>
#include <event.h>
#include <event2/bufferevent.h>
namespace
shrpx
{
enum
IOCtrlReason
{
SHRPX_NO_BUFFER
=
0
,
SHRPX_MSG_BLOCK
,
SHRPX_REASON_MAX
};
class
IOControl
{
public:
IOControl
(
bufferevent
*
bev
);
~
IOControl
();
void
set_bev
(
bufferevent
*
bev
);
void
pause_read
(
IOCtrlReason
reason
);
// Returns true if read operation is enabled after this call
bool
resume_read
(
IOCtrlReason
reason
);
private:
bufferevent
*
bev_
;
std
::
vector
<
int
>
ctrlv_
;
};
}
// namespace shrpx
#endif // SHRPX_IO_CONTROL_H
examples/shrpx_spdy_upstream.cc
View file @
c04c09ff
...
@@ -37,6 +37,10 @@ using namespace spdylay;
...
@@ -37,6 +37,10 @@ using namespace spdylay;
namespace
shrpx
{
namespace
shrpx
{
namespace
{
const
size_t
SHRPX_SPDY_UPSTREAM_OUTPUT_UPPER_THRES
=
512
*
1024
;
}
// namespace
namespace
{
namespace
{
ssize_t
send_callback
(
spdylay_session
*
session
,
ssize_t
send_callback
(
spdylay_session
*
session
,
const
uint8_t
*
data
,
size_t
len
,
int
flags
,
const
uint8_t
*
data
,
size_t
len
,
int
flags
,
...
@@ -47,6 +51,11 @@ ssize_t send_callback(spdylay_session *session,
...
@@ -47,6 +51,11 @@ ssize_t send_callback(spdylay_session *session,
ClientHandler
*
handler
=
upstream
->
get_client_handler
();
ClientHandler
*
handler
=
upstream
->
get_client_handler
();
bufferevent
*
bev
=
handler
->
get_bev
();
bufferevent
*
bev
=
handler
->
get_bev
();
evbuffer
*
output
=
bufferevent_get_output
(
bev
);
evbuffer
*
output
=
bufferevent_get_output
(
bev
);
// Check buffer length and return WOULDBLOCK if it is large enough.
if
(
evbuffer_get_length
(
output
)
>
SHRPX_SPDY_UPSTREAM_OUTPUT_UPPER_THRES
)
{
return
SPDYLAY_ERR_WOULDBLOCK
;
}
rv
=
evbuffer_add
(
output
,
data
,
len
);
rv
=
evbuffer_add
(
output
,
data
,
len
);
if
(
rv
==
-
1
)
{
if
(
rv
==
-
1
)
{
return
SPDYLAY_ERR_CALLBACK_FAILURE
;
return
SPDYLAY_ERR_CALLBACK_FAILURE
;
...
@@ -228,6 +237,12 @@ int SpdyUpstream::on_read()
...
@@ -228,6 +237,12 @@ int SpdyUpstream::on_read()
return
0
;
return
0
;
}
}
int
SpdyUpstream
::
on_write
()
{
send
();
return
0
;
}
int
SpdyUpstream
::
send
()
int
SpdyUpstream
::
send
()
{
{
int
rv
;
int
rv
;
...
@@ -306,47 +321,51 @@ void spdy_downstream_eventcb(bufferevent *bev, short events, void *ptr)
...
@@ -306,47 +321,51 @@ void spdy_downstream_eventcb(bufferevent *bev, short events, void *ptr)
LOG
(
INFO
)
<<
"<downstream> EOF stream_id="
LOG
(
INFO
)
<<
"<downstream> EOF stream_id="
<<
downstream
->
get_stream_id
();
<<
downstream
->
get_stream_id
();
}
}
if
(
downstream
->
get_response_state
()
==
Downstream
::
HEADER_COMPLETE
)
{
if
(
downstream
->
get_request_state
()
==
Downstream
::
STREAM_CLOSED
)
{
// Server may indicate the end of the request by EOF
//If stream was closed already, we don't need to send reply at
if
(
ENABLE_LOG
)
{
// the first place. We can delete downstream.
LOG
(
INFO
)
<<
"<downstream> Assuming content-length is 0 byte"
;
}
upstream
->
on_downstream_body_complete
(
downstream
);
downstream
->
set_response_state
(
Downstream
::
MSG_COMPLETE
);
// downstream wil be deleted in on_stream_close_callback.
}
else
if
(
downstream
->
get_response_state
()
==
Downstream
::
MSG_COMPLETE
)
{
// nothing todo
}
else
{
// error
if
(
ENABLE_LOG
)
{
LOG
(
INFO
)
<<
"<downstream> Treated as error"
;
}
upstream
->
error_reply
(
downstream
,
502
);
upstream
->
send
();
upstream
->
remove_downstream
(
downstream
);
upstream
->
remove_downstream
(
downstream
);
delete
downstream
;
delete
downstream
;
}
else
{
// downstream wil be deleted in on_stream_close_callback.
if
(
downstream
->
get_response_state
()
==
Downstream
::
HEADER_COMPLETE
)
{
// Server may indicate the end of the request by EOF
if
(
ENABLE_LOG
)
{
LOG
(
INFO
)
<<
"<downstream> Assuming content-length is 0 byte"
;
}
downstream
->
set_response_state
(
Downstream
::
MSG_COMPLETE
);
upstream
->
on_downstream_body_complete
(
downstream
);
}
else
if
(
downstream
->
get_response_state
()
!=
Downstream
::
MSG_COMPLETE
)
{
// If stream was not closed, then we set MSG_COMPLETE and let
// on_stream_close_callback delete downstream.
upstream
->
error_reply
(
downstream
,
502
);
downstream
->
set_response_state
(
Downstream
::
MSG_COMPLETE
);
upstream
->
send
();
}
}
}
}
else
if
(
events
&
(
BEV_EVENT_ERROR
|
BEV_EVENT_TIMEOUT
))
{
}
else
if
(
events
&
(
BEV_EVENT_ERROR
|
BEV_EVENT_TIMEOUT
))
{
if
(
ENABLE_LOG
)
{
if
(
ENABLE_LOG
)
{
LOG
(
INFO
)
<<
"<downstream> error/timeout. Downstream "
<<
downstream
;
LOG
(
INFO
)
<<
"<downstream> error/timeout. Downstream "
<<
downstream
;
}
}
// For Downstream::MSG_COMPLETE case, downstream will be deleted
if
(
downstream
->
get_request_state
()
==
Downstream
::
STREAM_CLOSED
)
{
// in on_stream_close_callback.
upstream
->
remove_downstream
(
downstream
);
if
(
downstream
->
get_response_state
()
!=
Downstream
::
MSG_COMPLETE
)
{
delete
downstream
;
if
(
downstream
->
get_response_state
()
==
Downstream
::
HEADER_COMPLETE
)
{
}
else
{
upstream
->
rst_stream
(
downstream
,
SPDYLAY_INTERNAL_ERROR
);
if
(
downstream
->
get_response_state
()
!=
Downstream
::
MSG_COMPLETE
)
{
}
else
{
if
(
downstream
->
get_response_state
()
==
Downstream
::
HEADER_COMPLETE
)
{
int
status
;
upstream
->
rst_stream
(
downstream
,
SPDYLAY_INTERNAL_ERROR
);
if
(
events
&
BEV_EVENT_TIMEOUT
)
{
status
=
504
;
}
else
{
}
else
{
status
=
502
;
int
status
;
if
(
events
&
BEV_EVENT_TIMEOUT
)
{
status
=
504
;
}
else
{
status
=
502
;
}
upstream
->
error_reply
(
downstream
,
status
);
}
}
upstream
->
error_reply
(
downstream
,
status
);
downstream
->
set_response_state
(
Downstream
::
MSG_COMPLETE
);
upstream
->
send
();
}
}
upstream
->
send
();
upstream
->
remove_downstream
(
downstream
);
delete
downstream
;
}
}
}
}
}
}
...
@@ -511,6 +530,12 @@ int SpdyUpstream::on_downstream_body(Downstream *downstream,
...
@@ -511,6 +530,12 @@ int SpdyUpstream::on_downstream_body(Downstream *downstream,
evbuffer_add
(
body
,
data
,
len
);
evbuffer_add
(
body
,
data
,
len
);
spdylay_session_resume_data
(
session_
,
downstream
->
get_stream_id
());
spdylay_session_resume_data
(
session_
,
downstream
->
get_stream_id
());
//send();
//send();
size_t
bodylen
=
evbuffer_get_length
(
body
);
if
(
bodylen
>
SHRPX_SPDY_UPSTREAM_OUTPUT_UPPER_THRES
)
{
downstream
->
pause_read
(
SHRPX_NO_BUFFER
);
}
return
0
;
return
0
;
}
}
...
...
examples/shrpx_spdy_upstream.h
View file @
c04c09ff
...
@@ -41,6 +41,7 @@ public:
...
@@ -41,6 +41,7 @@ public:
SpdyUpstream
(
uint16_t
version
,
ClientHandler
*
handler
);
SpdyUpstream
(
uint16_t
version
,
ClientHandler
*
handler
);
virtual
~
SpdyUpstream
();
virtual
~
SpdyUpstream
();
virtual
int
on_read
();
virtual
int
on_read
();
virtual
int
on_write
();
virtual
int
on_event
();
virtual
int
on_event
();
int
send
();
int
send
();
virtual
ClientHandler
*
get_client_handler
()
const
;
virtual
ClientHandler
*
get_client_handler
()
const
;
...
...
examples/shrpx_upstream.h
View file @
c04c09ff
...
@@ -38,6 +38,7 @@ class Upstream {
...
@@ -38,6 +38,7 @@ class Upstream {
public:
public:
virtual
~
Upstream
()
{}
virtual
~
Upstream
()
{}
virtual
int
on_read
()
=
0
;
virtual
int
on_read
()
=
0
;
virtual
int
on_write
()
=
0
;
virtual
int
on_event
()
=
0
;
virtual
int
on_event
()
=
0
;
virtual
bufferevent_data_cb
get_downstream_readcb
()
=
0
;
virtual
bufferevent_data_cb
get_downstream_readcb
()
=
0
;
virtual
bufferevent_data_cb
get_downstream_writecb
()
=
0
;
virtual
bufferevent_data_cb
get_downstream_writecb
()
=
0
;
...
...
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