Compare commits
14 Commits
v1.1.0
...
4236a4943a
| Author | SHA1 | Date | |
|---|---|---|---|
|
4236a4943a
|
|||
|
23c728e535
|
|||
|
dfe814316f
|
|||
|
efc663a178
|
|||
|
2b8f52ac72
|
|||
|
bb7ffe1da2
|
|||
|
ad1aba9d22
|
|||
|
0107d09abc
|
|||
|
01767198f2
|
|||
|
5854ed1b32
|
|||
|
63c8a79479
|
|||
|
d489362a28
|
|||
|
c87869bef7
|
|||
|
fcf65f8377
|
@@ -113,8 +113,7 @@ foreach (page ${project_MAN_PAGES})
|
||||
endforeach (page)
|
||||
|
||||
# CPack
|
||||
set (CPACK_PACKAGE_DESCRIPTION_SUMMARY
|
||||
"A shell for running JSON-RPC 2.0 queries")
|
||||
set (CPACK_PACKAGE_DESCRIPTION_SUMMARY "A shell for JSON-RPC 2.0")
|
||||
set (CPACK_PACKAGE_VENDOR "Premysl Eric Janouch")
|
||||
set (CPACK_PACKAGE_CONTACT "Přemysl Eric Janouch <p@janouch.name>")
|
||||
set (CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE")
|
||||
|
||||
16
README.adoc
16
README.adoc
@@ -2,23 +2,25 @@ json-rpc-shell
|
||||
==============
|
||||
:compact-option:
|
||||
|
||||
'json-rpc-shell' is a simple shell for running JSON-RPC 2.0 queries.
|
||||
'json-rpc-shell' is a shell for running JSON-RPC 2.0 queries.
|
||||
|
||||
This software has been created as a replacement for the following shell, which
|
||||
is written in Java: http://software.dzhuvinov.com/json-rpc-2.0-shell.html
|
||||
This software was originally created as a replacement for
|
||||
http://software.dzhuvinov.com/json-rpc-2.0-shell.html[a different one] made by
|
||||
Vladimir Dzhuvinov, in order to avoid Java, but has evolved since.
|
||||
|
||||
Features
|
||||
--------
|
||||
In addition to most of the features provided by Vladimir Dzhuvinov's shell
|
||||
you get the following niceties:
|
||||
In addition to most of the features provided by its predecessor, you will get
|
||||
the following niceties:
|
||||
|
||||
- configurable JSON syntax highlight, which with prettyprinting turned on
|
||||
helps you make sense of the results significantly
|
||||
- ability to pipe output through a shell command, so that you can view the
|
||||
results in your favourite editor or redirect them to a file
|
||||
- ability to edit the input line in your favourite editor as well with Alt+E
|
||||
- WebSockets (RFC 6455) can also be used as a transport rather than HTTP
|
||||
- support for method name tab completion using OpenRPC discovery
|
||||
- WebSocket (RFC 6455) can also be used as a transport rather than HTTP
|
||||
- even Language Server Protocol servers may be launched as a slave command
|
||||
- support for method name tab completion using OpenRPC discovery or file input
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
|
||||
@@ -6,11 +6,11 @@ json-rpc-shell(1)
|
||||
|
||||
Name
|
||||
----
|
||||
json-rpc-shell - a simple JSON-RPC 2.0 shell
|
||||
json-rpc-shell - a shell for JSON-RPC 2.0
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
*json-rpc-shell* [_OPTION_]... _ENDPOINT_
|
||||
*json-rpc-shell* [_OPTION_]... { _ENDPOINT_ | _COMMAND_ [_ARG_]... }
|
||||
|
||||
Description
|
||||
-----------
|
||||
@@ -76,9 +76,14 @@ Protocol
|
||||
*-o* _ORIGIN_, *--origin*=_ORIGIN_::
|
||||
Set the HTTP Origin header to _ORIGIN_. Some servers may need this.
|
||||
|
||||
*-O*, *--openrpc*::
|
||||
*-O*[__PATH__], *--openrpc*[**=**__PATH__]::
|
||||
Call "rpc.discover" upon start-up in order to pull in OpenRPC data for
|
||||
tab completion of method names.
|
||||
tab completion of method names. If a path is given, it is read from a file.
|
||||
|
||||
*-e*, *--execute*::
|
||||
Rather than an _ENDPOINT_, accept a command line to execute and communicate
|
||||
with using the JSON-RPC 2.0 protocol variation used in the Language Server
|
||||
Protocol.
|
||||
|
||||
Program information
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
@@ -111,11 +116,11 @@ requests, it is often convenient or even necessary to run a full text editor
|
||||
in order to construct complex objects or arrays, and may even be used to import
|
||||
data from elsewhere. You can launch an editor for the current request using
|
||||
the M-e key combination. Both *readline*(3) and *editline*(7) also support
|
||||
multiline editing natively, though you need to press C-v C-j in order to insert
|
||||
multiline editing natively, press either M-Enter or C-v C-j in order to insert
|
||||
newlines.
|
||||
|
||||
WebSockets
|
||||
~~~~~~~~~~
|
||||
WebSocket
|
||||
~~~~~~~~~
|
||||
The JSON-RPC 2.0 specification doesn't say almost anything about underlying
|
||||
transports. The way it's implemented here is that every request is sent as
|
||||
a single text message. If it has an "id" field, i.e., it's not just
|
||||
|
||||
998
json-rpc-shell.c
998
json-rpc-shell.c
File diff suppressed because it is too large
Load Diff
@@ -525,11 +525,11 @@ fcgi_muxer_push (struct fcgi_muxer *self, const void *data, size_t len)
|
||||
}
|
||||
|
||||
/// @}
|
||||
// --- WebSockets --------------------------------------------------------------
|
||||
/// @defgroup WebSockets
|
||||
// --- WebSocket ---------------------------------------------------------------
|
||||
/// @defgroup WebSocket
|
||||
/// @{
|
||||
|
||||
// WebSockets aren't CGI-compatible, therefore we must handle the initial HTTP
|
||||
// WebSocket isn't CGI-compatible, therefore we must handle the initial HTTP
|
||||
// handshake ourselves. Luckily it's not too much of a bother with http-parser.
|
||||
// Typically there will be a normal HTTP server in front of us, proxying the
|
||||
// requests based on the URI.
|
||||
@@ -537,7 +537,7 @@ fcgi_muxer_push (struct fcgi_muxer *self, const void *data, size_t len)
|
||||
enum ws_handler_state
|
||||
{
|
||||
WS_HANDLER_CONNECTING, ///< Parsing HTTP
|
||||
WS_HANDLER_OPEN, ///< Parsing WebSockets frames
|
||||
WS_HANDLER_OPEN, ///< Parsing WebSocket frames
|
||||
WS_HANDLER_CLOSING, ///< Partial closure by us
|
||||
WS_HANDLER_FLUSHING, ///< Just waiting for client EOF
|
||||
WS_HANDLER_CLOSED ///< Dead, both sides closed
|
||||
@@ -1110,7 +1110,7 @@ ws_handler_finish_handshake (struct ws_handler *self)
|
||||
if (!connection || strcasecmp_ascii (connection, "Upgrade"))
|
||||
FAIL_HANDSHAKE (HTTP_400_BAD_REQUEST);
|
||||
|
||||
// Check if we can actually upgrade the protocol to WebSockets
|
||||
// Check if we can actually upgrade the protocol to WebSocket
|
||||
const char *upgrade = str_map_find (&self->headers, "Upgrade");
|
||||
struct http_protocol *offered_upgrades = NULL;
|
||||
bool can_upgrade = false;
|
||||
@@ -1286,7 +1286,7 @@ static struct simple_config_item g_config_table[] =
|
||||
{ "bind_host", NULL, "Address of the server" },
|
||||
{ "port_fastcgi", "9000", "Port to bind for FastCGI" },
|
||||
{ "port_scgi", NULL, "Port to bind for SCGI" },
|
||||
{ "port_ws", NULL, "Port to bind for WebSockets" },
|
||||
{ "port_ws", NULL, "Port to bind for WebSocket" },
|
||||
{ "pid_file", NULL, "Full path for the PID file" },
|
||||
// XXX: here belongs something like a web SPA that interfaces with us
|
||||
{ "static_root", NULL, "The root for static content" },
|
||||
@@ -1446,6 +1446,38 @@ json_rpc_handler_info_cmp (const void *first, const void *second)
|
||||
((struct json_rpc_handler_info *) second)->method_name);
|
||||
}
|
||||
|
||||
static json_t *
|
||||
open_rpc_describe (const char *method, json_t *result)
|
||||
{
|
||||
return json_pack ("{sssoso}", "name", method, "params", json_pack ("[]"),
|
||||
"result", json_pack ("{ssso}", "name", method, "schema", result));
|
||||
}
|
||||
|
||||
// This server rarely sees changes and we can afford to hardcode the schema
|
||||
static json_t *
|
||||
json_rpc_discover (struct server_context *ctx, json_t *params)
|
||||
{
|
||||
(void) ctx;
|
||||
(void) params;
|
||||
|
||||
json_t *info = json_pack ("{ssss}",
|
||||
"title", PROGRAM_NAME, "version", PROGRAM_VERSION);
|
||||
json_t *methods = json_pack ("[ooo]",
|
||||
open_rpc_describe ("date", json_pack ("{ssso}", "type", "object",
|
||||
"properties", json_pack ("{s{ss}s{ss}s{ss}s{ss}s{ss}s{ss}}",
|
||||
"year", "type", "number",
|
||||
"month", "type", "number",
|
||||
"day", "type", "number",
|
||||
"hours", "type", "number",
|
||||
"minutes", "type", "number",
|
||||
"seconds", "type", "number"))),
|
||||
open_rpc_describe ("ping", json_pack ("{ss}", "type", "string")),
|
||||
open_rpc_describe ("rpc.discover", json_pack ("{ss}", "$ref",
|
||||
"https://github.com/open-rpc/meta-schema/raw/master/schema.json")));
|
||||
return json_rpc_response (NULL, json_pack ("{sssoso}",
|
||||
"openrpc", "1.2.6", "info", info, "methods", methods), NULL);
|
||||
}
|
||||
|
||||
static json_t *
|
||||
json_rpc_ping (struct server_context *ctx, json_t *params)
|
||||
{
|
||||
@@ -1487,8 +1519,9 @@ process_json_rpc_request (struct server_context *ctx, json_t *request)
|
||||
// Eventually it might be better to move this into a map in the context.
|
||||
static struct json_rpc_handler_info handlers[] =
|
||||
{
|
||||
{ "date", json_rpc_date },
|
||||
{ "ping", json_rpc_ping },
|
||||
{ "date", json_rpc_date },
|
||||
{ "ping", json_rpc_ping },
|
||||
{ "rpc.discover", json_rpc_discover },
|
||||
};
|
||||
|
||||
if (!json_is_object (request))
|
||||
@@ -2419,12 +2452,12 @@ client_scgi_create (EV_P_ int sock_fd)
|
||||
return &self->client;
|
||||
}
|
||||
|
||||
// --- WebSockets client handler -----------------------------------------------
|
||||
// --- WebSocket client handler ------------------------------------------------
|
||||
|
||||
struct client_ws
|
||||
{
|
||||
struct client client; ///< Parent class
|
||||
struct ws_handler handler; ///< WebSockets connection handler
|
||||
struct ws_handler handler; ///< WebSocket connection handler
|
||||
};
|
||||
|
||||
static bool
|
||||
|
||||
2
liberty
2
liberty
Submodule liberty updated: e029aae1d3...69101eb155
Reference in New Issue
Block a user