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
dc158320
Commit
dc158320
authored
Feb 19, 2017
by
Tatsuhiro Tsujikawa
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
nghttpx: Refactor API downstream connection to allow more endpoints
parent
0797e89a
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
122 additions
and
12 deletions
+122
-12
src/shrpx_api_downstream_connection.cc
src/shrpx_api_downstream_connection.cc
+89
-11
src/shrpx_api_downstream_connection.h
src/shrpx_api_downstream_connection.h
+33
-1
No files found.
src/shrpx_api_downstream_connection.cc
View file @
dc158320
...
...
@@ -33,8 +33,27 @@
namespace
shrpx
{
namespace
{
// List of API endpoints
const
APIEndpoint
apis
[]
=
{
APIEndpoint
{
StringRef
::
from_lit
(
"/api/v1beta1/backendconfig"
),
true
,
(
1
<<
API_METHOD_POST
)
|
(
1
<<
API_METHOD_PUT
),
&
APIDownstreamConnection
::
handle_backendconfig
,
},
};
}
// namespace
namespace
{
// The method string. This must be same order of APIMethod.
constexpr
StringRef
API_METHOD_STRING
[]
=
{
StringRef
::
from_lit
(
"GET"
),
StringRef
::
from_lit
(
"POST"
),
StringRef
::
from_lit
(
"PUT"
),
};
}
// namespace
APIDownstreamConnection
::
APIDownstreamConnection
(
Worker
*
worker
)
:
worker_
(
worker
),
a
bandone
d_
(
false
)
{}
:
worker_
(
worker
),
a
pi_
(
nullptr
),
shutdown_rea
d_
(
false
)
{}
APIDownstreamConnection
::~
APIDownstreamConnection
()
{}
...
...
@@ -64,7 +83,7 @@ enum {
int
APIDownstreamConnection
::
send_reply
(
unsigned
int
http_status
,
int
api_status
)
{
abandone
d_
=
true
;
shutdown_rea
d_
=
true
;
auto
upstream
=
downstream_
->
get_upstream
();
...
...
@@ -130,23 +149,45 @@ int APIDownstreamConnection::send_reply(unsigned int http_status,
int
APIDownstreamConnection
::
push_request_headers
()
{
auto
&
req
=
downstream_
->
request
();
auto
&
resp
=
downstream_
->
response
();
auto
path
=
StringRef
{
std
::
begin
(
req
.
path
),
std
::
find
(
std
::
begin
(
req
.
path
),
std
::
end
(
req
.
path
),
'?'
)};
if
(
path
!=
StringRef
::
from_lit
(
"/api/v1beta1/backendconfig"
))
{
for
(
auto
&
p
:
apis
)
{
if
(
p
.
path
==
path
)
{
api_
=
&
p
;
break
;
}
}
if
(
!
api_
)
{
send_reply
(
404
,
API_FAILURE
);
return
0
;
}
if
(
req
.
method
!=
HTTP_POST
&&
req
.
method
!=
HTTP_PUT
)
{
resp
.
fs
.
add_header_token
(
StringRef
::
from_lit
(
"allow"
),
StringRef
::
from_lit
(
"POST, PUT"
),
false
,
-
1
);
send_reply
(
405
,
API_FAILURE
);
switch
(
req
.
method
)
{
case
HTTP_GET
:
if
(
!
(
api_
->
allowed_methods
&
(
1
<<
API_METHOD_GET
)))
{
error_method_not_allowed
();
return
0
;
}
break
;
case
HTTP_POST
:
if
(
!
(
api_
->
allowed_methods
&
(
1
<<
API_METHOD_POST
)))
{
error_method_not_allowed
();
return
0
;
}
break
;
case
HTTP_PUT
:
if
(
!
(
api_
->
allowed_methods
&
(
1
<<
API_METHOD_PUT
)))
{
error_method_not_allowed
();
return
0
;
}
break
;
default:
error_method_not_allowed
();
return
0
;
}
...
...
@@ -161,9 +202,42 @@ int APIDownstreamConnection::push_request_headers() {
return
0
;
}
int
APIDownstreamConnection
::
error_method_not_allowed
()
{
auto
&
resp
=
downstream_
->
response
();
size_t
len
=
0
;
for
(
uint8_t
i
=
0
;
i
<
API_METHOD_MAX
;
++
i
)
{
if
(
api_
->
allowed_methods
&
(
1
<<
i
))
{
// The length of method + ", "
len
+=
API_METHOD_STRING
[
i
].
size
()
+
2
;
}
}
assert
(
len
>
0
);
auto
&
balloc
=
downstream_
->
get_block_allocator
();
auto
iov
=
make_byte_ref
(
balloc
,
len
+
1
);
auto
p
=
iov
.
base
;
for
(
uint8_t
i
=
0
;
i
<
API_METHOD_MAX
;
++
i
)
{
if
(
api_
->
allowed_methods
&
(
1
<<
i
))
{
auto
&
s
=
API_METHOD_STRING
[
i
];
p
=
std
::
copy
(
std
::
begin
(
s
),
std
::
end
(
s
),
p
);
p
=
std
::
copy_n
(
", "
,
2
,
p
);
}
}
p
-=
2
;
*
p
=
'\0'
;
resp
.
fs
.
add_header_token
(
StringRef
::
from_lit
(
"allow"
),
StringRef
{
iov
.
base
,
p
},
false
,
-
1
);
return
send_reply
(
405
,
API_FAILURE
);
}
int
APIDownstreamConnection
::
push_upload_data_chunk
(
const
uint8_t
*
data
,
size_t
datalen
)
{
if
(
abandoned_
)
{
if
(
shutdown_read_
||
!
api_
->
require_body
)
{
return
0
;
}
...
...
@@ -187,10 +261,14 @@ int APIDownstreamConnection::push_upload_data_chunk(const uint8_t *data,
}
int
APIDownstreamConnection
::
end_upload_data
()
{
if
(
abandone
d_
)
{
if
(
shutdown_rea
d_
)
{
return
0
;
}
return
api_
->
handler
(
*
this
);
}
int
APIDownstreamConnection
::
handle_backendconfig
()
{
auto
output
=
downstream_
->
get_request_buf
();
std
::
array
<
struct
iovec
,
2
>
iov
;
...
...
src/shrpx_api_downstream_connection.h
View file @
dc158320
...
...
@@ -26,11 +26,36 @@
#define SHRPX_API_DOWNSTREAM_CONNECTION_H
#include "shrpx_downstream_connection.h"
#include "template.h"
using
namespace
nghttp2
;
namespace
shrpx
{
class
Worker
;
// If new method is added, don't forget to update API_METHOD_STRING as
// well.
enum
APIMethod
{
API_METHOD_GET
,
API_METHOD_POST
,
API_METHOD_PUT
,
API_METHOD_MAX
,
};
class
APIDownstreamConnection
;
struct
APIEndpoint
{
// Endpoint path. It must start with "/api/".
StringRef
path
;
// true if we evaluate request body.
bool
require_body
;
// Allowed methods. This is bitwise OR of one or more of (1 <<
// APIMethod value).
uint8_t
allowed_methods
;
std
::
function
<
int
(
APIDownstreamConnection
&
)
>
handler
;
};
class
APIDownstreamConnection
:
public
DownstreamConnection
{
public:
APIDownstreamConnection
(
Worker
*
worker
);
...
...
@@ -59,10 +84,17 @@ public:
virtual
DownstreamAddr
*
get_addr
()
const
;
int
send_reply
(
unsigned
int
http_status
,
int
api_status
);
int
error_method_not_allowed
();
// Handles backendconfig API request.
int
handle_backendconfig
();
private:
Worker
*
worker_
;
bool
abandoned_
;
// This points to the requested APIEndpoint struct.
const
APIEndpoint
*
api_
;
// true if we stop reading request body.
bool
shutdown_read_
;
};
}
// namespace shrpx
...
...
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