use netstrings for framing binary data with json at the end
This will be easy to implement with servant. It's also very efficient, and fairly future-proof. Eg, could add another frame with other data. This does make it a bit harder to use this protocol, but netstrings probably take about 5 minutes to implement? Let's see... import Text.Read import Data.List toNetString :: String -> String toNetString s = show (length s) ++ ":" ++ s ++ "," nextNetString :: String -> Maybe (String, String) nextNetString s = case break (== ':') s of ([], _) -> Nothing (sn, rest) -> do n <- readMaybe sn let (v, rest') = splitAt n (drop 1 rest) return (v, drop 1 rest') Ok, well, that took about 10 minutes ;-)
This commit is contained in:
parent
95ba4d4480
commit
5e564947d7
1 changed files with 36 additions and 15 deletions
|
@ -62,6 +62,23 @@ version, to create a P2P session. The P2P session is driven through
|
||||||
the AUTH, VERSION, and BYPASS messages, leaving the session ready to
|
the AUTH, VERSION, and BYPASS messages, leaving the session ready to
|
||||||
service requests.]
|
service requests.]
|
||||||
|
|
||||||
|
## binary data framing
|
||||||
|
|
||||||
|
When a request body or response body includes binary data, eg the content
|
||||||
|
of a large file, the body is framed using
|
||||||
|
[netstrings](http://cr.yp.to/proto/netstrings.txt).
|
||||||
|
|
||||||
|
The netstring framing is simply the length of the string in ASCII
|
||||||
|
digits, followed by the string, and then a comma.
|
||||||
|
|
||||||
|
This allows efficiently sending binary data in one frame, followed by a
|
||||||
|
second frame that can contain eg a JSON document.
|
||||||
|
|
||||||
|
For example, a body containing the binary data "foo" followed by
|
||||||
|
a JSON document `{"valid": true}` is framed like this:
|
||||||
|
|
||||||
|
3:foo,15:{"valid": true},
|
||||||
|
|
||||||
## request messages
|
## request messages
|
||||||
|
|
||||||
All the requests below are sent with the HTTP POST method.
|
All the requests below are sent with the HTTP POST method.
|
||||||
|
@ -166,9 +183,8 @@ Example:
|
||||||
|
|
||||||
> POST /git-annex/v3/put?key=SHA1--foo&associatedfile=bar&clientuuid=79a5a1f4-07e8-11ef-873d-97f93ca91925&serveruuid=ecf6d4ca-07e8-11ef-8990-9b8c1f696bf6 HTTP/1.1
|
> POST /git-annex/v3/put?key=SHA1--foo&associatedfile=bar&clientuuid=79a5a1f4-07e8-11ef-873d-97f93ca91925&serveruuid=ecf6d4ca-07e8-11ef-8990-9b8c1f696bf6 HTTP/1.1
|
||||||
> Content-Type: application/octet-stream
|
> Content-Type: application/octet-stream
|
||||||
> Content-Length: 20
|
> Content-Length: 25
|
||||||
> foo
|
> 3:foo,15:{"valid": true},
|
||||||
> {"valid": true}
|
|
||||||
< {"stored": true}
|
< {"stored": true}
|
||||||
|
|
||||||
There is one required additional parameter, `key`.
|
There is one required additional parameter, `key`.
|
||||||
|
@ -185,14 +201,17 @@ There are are also these optional parameters:
|
||||||
Number of bytes that have been omitted from the beginning of the file.
|
Number of bytes that have been omitted from the beginning of the file.
|
||||||
Usually this will be determined by making a `putoffset` request.
|
Usually this will be determined by making a `putoffset` request.
|
||||||
|
|
||||||
The body of the request is the content of the key, starting from the
|
The body of the request is two items framed with netstrings.
|
||||||
specified offset or from the beginning. After the content of the key,
|
|
||||||
there is a newline, followed by a JSON object.
|
|
||||||
|
|
||||||
The JSON object has a field "valid" that is true when the content
|
The first item is the content of the key, starting from the specified
|
||||||
was not changed while it was being sent, or false when modified
|
offset or from the beginning when no offset was specified.
|
||||||
content was sent and should be disregarded by the server. (This corresponds
|
|
||||||
to the `VALID` and `INVALID` messages in the P2P protocol.)
|
The second item is a JSON object.
|
||||||
|
|
||||||
|
The JSON object has a field "valid" that is true when the content was not
|
||||||
|
changed while it was being sent, or false when modified content was sent
|
||||||
|
and should be disregarded by the server. (This corresponds to the `VALID`
|
||||||
|
and `INVALID` messages in the P2P protocol.)
|
||||||
|
|
||||||
The `Content-Type` header should be `application/octet-stream`.
|
The `Content-Type` header should be `application/octet-stream`.
|
||||||
|
|
||||||
|
@ -248,8 +267,7 @@ Example:
|
||||||
> POST /git-annex/v3/get?key=SHA1--foo&associatedfile=bar&clientuuid=79a5a1f4-07e8-11ef-873d-97f93ca91925&serveruuid=ecf6d4ca-07e8-11ef-8990-9b8c1f696bf6 HTTP/1.1
|
> POST /git-annex/v3/get?key=SHA1--foo&associatedfile=bar&clientuuid=79a5a1f4-07e8-11ef-873d-97f93ca91925&serveruuid=ecf6d4ca-07e8-11ef-8990-9b8c1f696bf6 HTTP/1.1
|
||||||
< Content-Type: application/octet-stream
|
< Content-Type: application/octet-stream
|
||||||
> Content-Length: 20
|
> Content-Length: 20
|
||||||
> foo
|
> 3:foo,15:{"valid": true},
|
||||||
> {"valid": true}
|
|
||||||
|
|
||||||
There is one required additional parameter, `key`.
|
There is one required additional parameter, `key`.
|
||||||
|
|
||||||
|
@ -272,9 +290,12 @@ The server's response will have a `Content-Type` header of
|
||||||
The server's response will have a `Content-Length` header
|
The server's response will have a `Content-Length` header
|
||||||
set to the length of the body.
|
set to the length of the body.
|
||||||
|
|
||||||
The server's response body is the content of the key, from the specified
|
The body of the response is two items framed with netstrings.
|
||||||
offset. After the content of the key, there is a newline, followed by a
|
|
||||||
JSON object.
|
The first item is the content of the key, starting from the specified
|
||||||
|
offset or from the beginning when no offset was specified.
|
||||||
|
|
||||||
|
The second item is a JSON object.
|
||||||
|
|
||||||
The JSON object has a field "valid" that is true when the content
|
The JSON object has a field "valid" that is true when the content
|
||||||
was not changed while it was being sent, or false when whatever
|
was not changed while it was being sent, or false when whatever
|
||||||
|
|
Loading…
Add table
Reference in a new issue