Message ID | 20200703175303.4366-1-kevr.gtalk@gmail.com |
---|---|
State | New |
Headers | show |
Series | Add POST support for RPC API | expand |
Apologies, `application/data` in the commit message's example should be `application/json`, and will need to be updated after review(s) in the final commit. On Fri, Jul 3, 2020 at 10:53 AM Kevin Morris <kevr.gtalk@gmail.com> wrote: > When we received a POST method from a client, deduce our `$data` > by determining which `Content-Type` is used. > > Supported `Content-Type`s > ========================= > > * `application/json` > * `multipart/form-data` > > `application/json` POST Example, searching for 'test': > ``` > curl -X POST -H 'Content-Type: application/data' \ > --data '{"v": "5", "type": "search", "arg": "test"}' \ > https://aur.archlinux.org/rpc/ > ``` > > `multipart/form-data` POST Example, search for 'test': > ``` > curl -X POST -H 'Content-Type: multipart/form-data' \ > -F v=5 -F type=search -F arg=test \ > https://aur.archlinux.org/rpc/ > ``` > > This change was written as a solution to > https://bugs.archlinux.org/task/49089. > > NOTE: This commit is not final; would like a review and a bit more > consideration on `multipart/form-data` and ensuring that we're > handling everything we need to. > > Signed-off-by: Kevin Morris <kevr.gtalk@gmail.com> > --- > web/html/rpc.php | 37 ++++++++++++++++++++++++++++++++++--- > 1 file changed, 34 insertions(+), 3 deletions(-) > > diff --git a/web/html/rpc.php b/web/html/rpc.php > index 64c95622..41762aa3 100644 > --- a/web/html/rpc.php > +++ b/web/html/rpc.php > @@ -2,16 +2,47 @@ > set_include_path(get_include_path() . PATH_SEPARATOR . '../lib'); > include_once("aurjson.class.php"); > > -if ( $_SERVER['REQUEST_METHOD'] != 'GET' ) { > +$exposed_methods = array('GET', 'POST'); > +$request_method = strtoupper($_SERVER['REQUEST_METHOD']); > + > +if ( !in_array($request_method, $exposed_methods) ) { > header('HTTP/1.1 405 Method Not Allowed'); > exit(); > } > > -if ( isset($_GET['type']) ) { > +if ( $request_method === 'GET' ) { > + $data = $_GET; > +} else { > + // Otherwise, we were given a POST method, and we'll do some more > + // work to deduce our data input. > + > + // Extract Content-Type; remove any trailing arguments from the > string. > + $content_type = $_SERVER['CONTENT_TYPE']; > + if ( strpos($content_type, ';') ) { > + // Example: `multipart/form-data; boundary blahblah` is > extracted as > + // `multipart/form-data`. > + $content_type = explode(';', $content_type)[0]; > + } > + $content_type = rtrim(trim($content_type)); > + > + if ($content_type === 'application/json') { > + $json = file_get_contents('php://input'); > + $data = json_decode($json, true); > + } elseif ($content_type === 'multipart/form-data') { > + $data = $_POST; > + } else { > + header('HTTP/1.1 400 Bad Request'); > + echo "Error: Unsupported Content-Type header.\n"; > + exit(); > + } > +} > + > +if ( isset($data['type']) ) { > $rpc_o = new AurJSON(); > - echo $rpc_o->handle($_GET); > + echo $rpc_o->handle($data); > } > else { > echo file_get_contents('../../doc/rpc.html'); > } > + > ?> > -- > 2.20.1 > >
diff --git a/web/html/rpc.php b/web/html/rpc.php index 64c95622..41762aa3 100644 --- a/web/html/rpc.php +++ b/web/html/rpc.php @@ -2,16 +2,47 @@ set_include_path(get_include_path() . PATH_SEPARATOR . '../lib'); include_once("aurjson.class.php"); -if ( $_SERVER['REQUEST_METHOD'] != 'GET' ) { +$exposed_methods = array('GET', 'POST'); +$request_method = strtoupper($_SERVER['REQUEST_METHOD']); + +if ( !in_array($request_method, $exposed_methods) ) { header('HTTP/1.1 405 Method Not Allowed'); exit(); } -if ( isset($_GET['type']) ) { +if ( $request_method === 'GET' ) { + $data = $_GET; +} else { + // Otherwise, we were given a POST method, and we'll do some more + // work to deduce our data input. + + // Extract Content-Type; remove any trailing arguments from the string. + $content_type = $_SERVER['CONTENT_TYPE']; + if ( strpos($content_type, ';') ) { + // Example: `multipart/form-data; boundary blahblah` is extracted as + // `multipart/form-data`. + $content_type = explode(';', $content_type)[0]; + } + $content_type = rtrim(trim($content_type)); + + if ($content_type === 'application/json') { + $json = file_get_contents('php://input'); + $data = json_decode($json, true); + } elseif ($content_type === 'multipart/form-data') { + $data = $_POST; + } else { + header('HTTP/1.1 400 Bad Request'); + echo "Error: Unsupported Content-Type header.\n"; + exit(); + } +} + +if ( isset($data['type']) ) { $rpc_o = new AurJSON(); - echo $rpc_o->handle($_GET); + echo $rpc_o->handle($data); } else { echo file_get_contents('../../doc/rpc.html'); } + ?>
When we received a POST method from a client, deduce our `$data` by determining which `Content-Type` is used. Supported `Content-Type`s ========================= * `application/json` * `multipart/form-data` `application/json` POST Example, searching for 'test': ``` curl -X POST -H 'Content-Type: application/data' \ --data '{"v": "5", "type": "search", "arg": "test"}' \ https://aur.archlinux.org/rpc/ ``` `multipart/form-data` POST Example, search for 'test': ``` curl -X POST -H 'Content-Type: multipart/form-data' \ -F v=5 -F type=search -F arg=test \ https://aur.archlinux.org/rpc/ ``` This change was written as a solution to https://bugs.archlinux.org/task/49089. NOTE: This commit is not final; would like a review and a bit more consideration on `multipart/form-data` and ensuring that we're handling everything we need to. Signed-off-by: Kevin Morris <kevr.gtalk@gmail.com> --- web/html/rpc.php | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-)