Moving from govendor to dep, updated dependencies (#48)
* Moving from govendor to dep. * Making the pull request template more friendly. * Fixing akward space in PR template. * goimports run on whole project using ` goimports -w $(find . -type f -name '*.go' -not -path "./vendor/*" -not -path "./gen-go/*")` source of command: https://gist.github.com/bgentry/fd1ffef7dbde01857f66
This commit is contained in:
parent
9631aa3aab
commit
8d445c1c77
2186 changed files with 400410 additions and 352 deletions
82
vendor/git.apache.org/thrift.git/doc/specs/HeaderFormat.md
generated
vendored
Normal file
82
vendor/git.apache.org/thrift.git/doc/specs/HeaderFormat.md
generated
vendored
Normal file
|
@ -0,0 +1,82 @@
|
|||
<link href="http://kevinburke.bitbucket.org/markdowncss/markdown.css" rel="stylesheet"></link>
|
||||
|
||||
Header format for the THeader.h
|
||||
===============================
|
||||
|
||||
0 1 2 3 4 5 6 7 8 9 a b c d e f 0 1 2 3 4 5 6 7 8 9 a b c d e f
|
||||
+----------------------------------------------------------------+
|
||||
| 0| LENGTH |
|
||||
+----------------------------------------------------------------+
|
||||
| 0| HEADER MAGIC | FLAGS |
|
||||
+----------------------------------------------------------------+
|
||||
| SEQUENCE NUMBER |
|
||||
+----------------------------------------------------------------+
|
||||
| 0| Header Size(/32) | ...
|
||||
+---------------------------------
|
||||
|
||||
Header is of variable size:
|
||||
(and starts at offset 14)
|
||||
|
||||
+----------------------------------------------------------------+
|
||||
| PROTOCOL ID (varint) | NUM TRANSFORMS (varint) |
|
||||
+----------------------------------------------------------------+
|
||||
| TRANSFORM 0 ID (varint) | TRANSFORM 0 DATA ...
|
||||
+----------------------------------------------------------------+
|
||||
| ... ... |
|
||||
+----------------------------------------------------------------+
|
||||
| INFO 0 ID (varint) | INFO 0 DATA ...
|
||||
+----------------------------------------------------------------+
|
||||
| ... ... |
|
||||
+----------------------------------------------------------------+
|
||||
| |
|
||||
| PAYLOAD |
|
||||
| |
|
||||
+----------------------------------------------------------------+
|
||||
|
||||
The `LENGTH` field is 32 bits, and counts the remaining bytes in the
|
||||
packet, NOT including the length field. The header size field is 16
|
||||
bits, and defines the size of the header remaining NOT including the
|
||||
`HEADER MAGIC`, `FLAGS`, `SEQUENCE NUMBER` and header size fields. The
|
||||
Header size field is in bytes/4.
|
||||
|
||||
The transform ID's are varints. The data for each transform is
|
||||
defined by the transform ID in the code - no size is given in the
|
||||
header. If a transform ID is specified from a client and the server
|
||||
doesn't know about the transform ID, an error MUST be returned as we
|
||||
don't know how to transform the data.
|
||||
|
||||
Conversely, data in the info headers is ignorable. This should only
|
||||
be things like timestamps, debuging tracing, etc. Using the header
|
||||
size you should be able to skip this data and read the payload safely
|
||||
if you don't know the info ID.
|
||||
|
||||
Info's should be oldest supported to newest supported order, so that
|
||||
if we read an info ID we don't support, none of the remaining info
|
||||
ID's will be supported either, and we can safely skip to the payload.
|
||||
|
||||
Info ID's and transform ID's should share the same ID space.
|
||||
|
||||
### PADDING:
|
||||
|
||||
Header will be padded out to next 4-byte boundary with `0x00`.
|
||||
|
||||
Max frame size is `0x3FFFFFFF`, which is slightly less than `HTTP_MAGIC`.
|
||||
This allows us to distingush between different (older) transports.
|
||||
|
||||
### Transform IDs:
|
||||
|
||||
ZLIB_TRANSFORM 0x01 - No data for this. Use zlib to (de)compress the
|
||||
data.
|
||||
|
||||
HMAC_TRANSFORM 0x02 - Variable amount of mac data. One byte to specify
|
||||
size. Mac data is appended at the end of the packet.
|
||||
SNAPPY_TRANSFORM 0x03 - No data for this. Use snappy to (de)compress the
|
||||
data.
|
||||
|
||||
|
||||
###Info IDs:
|
||||
|
||||
INFO_KEYVALUE 0x01 - varint32 number of headers.
|
||||
- key/value pairs of varstrings (varint16 length plus
|
||||
no-trailing-null string).
|
||||
|
272
vendor/git.apache.org/thrift.git/doc/specs/idl.md
generated
vendored
Normal file
272
vendor/git.apache.org/thrift.git/doc/specs/idl.md
generated
vendored
Normal file
|
@ -0,0 +1,272 @@
|
|||
## Thrift interface description language
|
||||
The Thrift interface definition language (IDL) allows for the definition of [Thrift Types](/docs/types). A Thrift IDL file is processed by the Thrift code generator to produce code for the various target languages to support the defined structs and services in the IDL file.
|
||||
|
||||
## Description
|
||||
|
||||
*Under construction*
|
||||
|
||||
Here is a description of the Thrift IDL.
|
||||
|
||||
## Document
|
||||
|
||||
Every Thrift document contains 0 or more headers followed by 0 or more definitions.
|
||||
|
||||
[1] Document ::= Header* Definition*
|
||||
|
||||
## Header
|
||||
|
||||
A header is either a Thrift include, a C++ include, or a namespace declaration.
|
||||
|
||||
[2] Header ::= Include | CppInclude | Namespace
|
||||
|
||||
### Thrift Include
|
||||
|
||||
An include makes all the symbols from another file visible (with a prefix) and adds corresponding include statements into the code generated for this Thrift document.
|
||||
|
||||
[3] Include ::= 'include' Literal
|
||||
|
||||
### C++ Include
|
||||
|
||||
A C++ include adds a custom C++ include to the output of the C++ code generator for this Thrift document.
|
||||
|
||||
[4] CppInclude ::= 'cpp_include' Literal
|
||||
|
||||
### Namespace
|
||||
|
||||
A namespace declares which namespaces/package/module/etc. the type definitions in this file will be declared in for the target languages. The namespace scope indicates which language the namespace applies to; a scope of '*' indicates that the namespace applies to all target languages.
|
||||
|
||||
[5] Namespace ::= ( 'namespace' ( NamespaceScope Identifier ) |
|
||||
( 'smalltalk.category' STIdentifier ) |
|
||||
( 'smalltalk.prefix' Identifier ) ) |
|
||||
( 'php_namespace' Literal ) |
|
||||
( 'xsd_namespace' Literal )
|
||||
|
||||
[6] NamespaceScope ::= '*' | 'cpp' | 'java' | 'py' | 'perl' | 'rb' | 'cocoa' | 'csharp'
|
||||
|
||||
N.B.: Smalltalk has two distinct types of namespace commands:
|
||||
|
||||
- smalltalk.prefix: Prepended to generated classnames.
|
||||
- Smalltalk does not have namespaces for classes, so prefixes
|
||||
are used to avoid class-name collisions.
|
||||
Often, the prefix is the author's initials, like "KB" or "JWS",
|
||||
or an abbreviation of the package name, like "MC" for "Monticello".
|
||||
- smalltalk.category: Determines the category for generated classes.
|
||||
Any dots in the identifier will be replaced with hyphens when generating
|
||||
the category name.
|
||||
If not provided, defaults to "Generated-" + the program name.
|
||||
Methods will not be categorized beyond "as yet uncategorized".
|
||||
- Smalltalk allows filing both classes and methods within classes into named
|
||||
groups. These named groups of methods are called categories.
|
||||
|
||||
N.B.: The `php_namespace` directive will be deprecated at some point in the future in favor of the scoped syntax, but the scoped syntax is not yet supported for PHP.
|
||||
|
||||
N.B.: The `xsd_namespace` directive has some purpose internal to Facebook but serves no purpose in Thrift itself. Use of this feature is strongly discouraged
|
||||
|
||||
## Definition
|
||||
|
||||
[7] Definition ::= Const | Typedef | Enum | Senum | Struct | Union | Exception | Service
|
||||
|
||||
### Const
|
||||
|
||||
[8] Const ::= 'const' FieldType Identifier '=' ConstValue ListSeparator?
|
||||
|
||||
### Typedef
|
||||
|
||||
A typedef creates an alternate name for a type.
|
||||
|
||||
[9] Typedef ::= 'typedef' DefinitionType Identifier
|
||||
|
||||
### Enum
|
||||
|
||||
An enum creates an enumerated type, with named values. If no constant value is supplied, the value is either 0 for the first element, or one greater than the preceding value for any subsequent element. Any constant value that is supplied must be non-negative.
|
||||
|
||||
[10] Enum ::= 'enum' Identifier '{' (Identifier ('=' IntConstant)? ListSeparator?)* '}'
|
||||
|
||||
### Senum
|
||||
|
||||
Senum (and Slist) are now deprecated and should both be replaced with String.
|
||||
|
||||
[11] Senum ::= 'senum' Identifier '{' (Literal ListSeparator?)* '}'
|
||||
|
||||
### Struct
|
||||
|
||||
Structs are the fundamental compositional type in Thrift. The name of each field must be unique within the struct.
|
||||
|
||||
[12] Struct ::= 'struct' Identifier 'xsd_all'? '{' Field* '}'
|
||||
|
||||
N.B.: The `xsd_all` keyword has some purpose internal to Facebook but serves no purpose in Thrift itself. Use of this feature is strongly discouraged
|
||||
|
||||
### Union
|
||||
|
||||
Unions are similar to structs, except that they provide a means to transport exactly one field of a possible set of fields, just like union {} in C++. Consequently, union members are implicitly considered optional (see requiredness).
|
||||
|
||||
[13] Union ::= 'union' Identifier 'xsd_all'? '{' Field* '}'
|
||||
|
||||
N.B.: The `xsd_all` keyword has some purpose internal to Facebook but serves no purpose in Thrift itself. Use of this feature is strongly discouraged
|
||||
|
||||
### Exception
|
||||
|
||||
Exceptions are similar to structs except that they are intended to integrate with the native exception handling mechanisms in the target languages. The name of each field must be unique within the exception.
|
||||
|
||||
[14] Exception ::= 'exception' Identifier '{' Field* '}'
|
||||
|
||||
### Service
|
||||
|
||||
A service provides the interface for a set of functionality provided by a Thrift server. The interface is simply a list of functions. A service can extend another service, which simply means that it provides the functions of the extended service in addition to its own.
|
||||
|
||||
[15] Service ::= 'service' Identifier ( 'extends' Identifier )? '{' Function* '}'
|
||||
|
||||
## Field
|
||||
|
||||
[16] Field ::= FieldID? FieldReq? FieldType Identifier ('= ConstValue)? XsdFieldOptions ListSeparator?
|
||||
|
||||
### Field ID
|
||||
|
||||
[17] FieldID ::= IntConstant ':'
|
||||
|
||||
### Field Requiredness
|
||||
|
||||
There are two explicit requiredness values, and a third one that is applied implicity if neither *required* nor *optional* are given: *default* requiredness.
|
||||
|
||||
[18] FieldReq ::= 'required' | 'optional'
|
||||
|
||||
The general rules for requiredness are as follows:
|
||||
|
||||
#### required
|
||||
|
||||
- Write: Required fields are always written and are expected to be set.
|
||||
- Read: Required fields are always read and are expected to be contained in the input stream.
|
||||
- Defaults values: are always written
|
||||
|
||||
If a required field is missing during read, the expected behaviour is to indicate an unsuccessful read operation to the caller, e.g. by throwing an exception or returning an error.
|
||||
|
||||
Because of this behaviour, required fields drastically limit the options with regard to soft versioning. Because they must be present on read, the fields cannot be deprecated. If a required field would be removed (or changed to optional), the data are no longer compatible between versions.
|
||||
|
||||
#### optional
|
||||
|
||||
- Write: Optional fields are only written when they are set
|
||||
- Read: Optional fields may, or may not be part of the input stream.
|
||||
- Default values: are written when the isset flag is set
|
||||
|
||||
Most language implementations use the recommended pratice of so-called "isset" flags to indicate whether a particular optional field is set or not. Only fields with this flag set are written, and conversely the flag is only set when a field value has been read from the input stream.
|
||||
|
||||
#### default requiredness (implicit)
|
||||
|
||||
- Write: In theory, the fields are always written. There are some exceptions to that rule, see below.
|
||||
- Read: Like optional, the field may, or may not be part of the input stream.
|
||||
- Default values: may not be written (see next section)
|
||||
|
||||
Default requiredess is a good starting point. The desired behaviour is a mix of optional and required, hence the internal name "opt-in, req-out". Although in theory these fields are supposed to be written ("req-out"), in reality unset fields are not always written. This is especially the case, when the field contains a <null> value, which by definition cannot be transported through thrift. The only way to achieve this is by not writing that field at all, and that's what most languages do.
|
||||
|
||||
#### Semantics of Default Values
|
||||
|
||||
There are ongoing discussions about that topic, see JIRA for details. Not all implementations treat default values in the very same way, but the current status quo is more or less that default fields are typically set at initialization time. Therefore, a value that equals the default may not be written, because the read end will set the value implicitly. On the other hand, an implementation is free to write the default value anyways, as there is no hard restriction that prevents this.
|
||||
|
||||
The major point to keep in mind here is the fact, that any unwritten default value implicitly becomes part of the interface version. If that default is changed, the interface changes. If, in contrast, the default value is written into the output data, the default in the IDL can change at any time without affecting serialized data.
|
||||
|
||||
### XSD Options
|
||||
|
||||
N.B.: These have some internal purpose at Facebook but serve no current purpose in Thrift. Use of these options is strongly discouraged.
|
||||
|
||||
[19] XsdFieldOptions ::= 'xsd_optional'? 'xsd_nillable'? XsdAttrs?
|
||||
|
||||
[20] XsdAttrs ::= 'xsd_attrs' '{' Field* '}'
|
||||
|
||||
## Functions
|
||||
|
||||
[21] Function ::= 'oneway'? FunctionType Identifier '(' Field* ')' Throws? ListSeparator?
|
||||
|
||||
[22] FunctionType ::= FieldType | 'void'
|
||||
|
||||
[23] Throws ::= 'throws' '(' Field* ')'
|
||||
|
||||
## Types
|
||||
|
||||
[24] FieldType ::= Identifier | BaseType | ContainerType
|
||||
|
||||
[25] DefinitionType ::= BaseType | ContainerType
|
||||
|
||||
[26] BaseType ::= 'bool' | 'byte' | 'i8' | 'i16' | 'i32' | 'i64' | 'double' | 'string' | 'binary' | 'slist'
|
||||
|
||||
[27] ContainerType ::= MapType | SetType | ListType
|
||||
|
||||
[28] MapType ::= 'map' CppType? '<' FieldType ',' FieldType '>'
|
||||
|
||||
[29] SetType ::= 'set' CppType? '<' FieldType '>'
|
||||
|
||||
[30] ListType ::= 'list' '<' FieldType '>' CppType?
|
||||
|
||||
[31] CppType ::= 'cpp_type' Literal
|
||||
|
||||
## Constant Values
|
||||
|
||||
[32] ConstValue ::= IntConstant | DoubleConstant | Literal | Identifier | ConstList | ConstMap
|
||||
|
||||
[33] IntConstant ::= ('+' | '-')? Digit+
|
||||
|
||||
[34] DoubleConstant ::= ('+' | '-')? Digit* ('.' Digit+)? ( ('E' | 'e') IntConstant )?
|
||||
|
||||
[35] ConstList ::= '[' (ConstValue ListSeparator?)* ']'
|
||||
|
||||
[36] ConstMap ::= '{' (ConstValue ':' ConstValue ListSeparator?)* '}'
|
||||
|
||||
## Basic Definitions
|
||||
|
||||
### Literal
|
||||
|
||||
[37] Literal ::= ('"' [^"]* '"') | ("'" [^']* "'")
|
||||
|
||||
### Identifier
|
||||
|
||||
[38] Identifier ::= ( Letter | '_' ) ( Letter | Digit | '.' | '_' )*
|
||||
|
||||
[39] STIdentifier ::= ( Letter | '_' ) ( Letter | Digit | '.' | '_' | '-' )*
|
||||
|
||||
### List Separator
|
||||
|
||||
[40] ListSeparator ::= ',' | ';'
|
||||
|
||||
### Letters and Digits
|
||||
|
||||
[41] Letter ::= ['A'-'Z'] | ['a'-'z']
|
||||
|
||||
[42] Digit ::= ['0'-'9']
|
||||
|
||||
## Examples
|
||||
|
||||
Here are some examples of Thrift definitions, using the Thrift IDL:
|
||||
|
||||
* [ThriftTest.thrift][] used by the Thrift TestFramework
|
||||
* Thrift [tutorial][]
|
||||
* Facebook's [fb303.thrift][]
|
||||
* [Apache Cassandra's][] Thrift IDL: [cassandra.thrift][]
|
||||
* [Evernote API][]
|
||||
|
||||
[ThriftTest.thrift]: https://git-wip-us.apache.org/repos/asf?p=thrift.git;a=blob_plain;f=test/ThriftTest.thrift;hb=HEAD
|
||||
[tutorial]: /tutorial/
|
||||
[fb303.thrift]: https://git-wip-us.apache.org/repos/asf?p=thrift.git;a=blob_plain;f=contrib/fb303/if/fb303.thrift;hb=HEAD
|
||||
[Apache Cassandra's]: http://cassandra.apache.org/
|
||||
[cassandra.thrift]: http://svn.apache.org/viewvc/cassandra/trunk/interface/cassandra.thrift?view=co
|
||||
[Evernote API]: http://www.evernote.com/about/developer/api/
|
||||
|
||||
## To Do/Questions
|
||||
|
||||
Initialization of Base Types for all Languages?
|
||||
|
||||
* Do all Languages initialize them to 0, bool=false and string=""? or null, undefined?
|
||||
|
||||
Why does position of `CppType` vary between `SetType` and `ListType`?
|
||||
|
||||
* std::set does sort the elements automatically, that's the design. see [Thrift Types](/docs/types) or the [C++ std:set reference][] for further details
|
||||
* The question is, how other languages are doing that? What about custom objects, do they have a Compare function the set the order correctly?
|
||||
|
||||
[C++ std:set reference]: http://www.cplusplus.com/reference/stl/set/
|
||||
|
||||
Why can't `DefinitionType` be the same as `FieldType` (i.e. include `Identifier`)?
|
||||
|
||||
Examine the `smalltalk.prefix` and `smalltalk.category` status (esp `smalltalk.category`, which takes `STIdentifier` as its argument)...
|
||||
|
||||
What to do about `ListSeparator`? Do we really want to be as lax as we currently are?
|
||||
|
||||
Should `Field*` really be `Field+` in `Struct`, `Enum`, etc.?
|
||||
|
254
vendor/git.apache.org/thrift.git/doc/specs/thrift-binary-protocol.md
generated
vendored
Normal file
254
vendor/git.apache.org/thrift.git/doc/specs/thrift-binary-protocol.md
generated
vendored
Normal file
|
@ -0,0 +1,254 @@
|
|||
Thrift Binary protocol encoding
|
||||
===============================
|
||||
|
||||
<!--
|
||||
--------------------------------------------------------------------
|
||||
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF licenses this file
|
||||
to you under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing,
|
||||
software distributed under the License is distributed on an
|
||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, either express or implied. See the License for the
|
||||
specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
--------------------------------------------------------------------
|
||||
-->
|
||||
|
||||
This documents describes the wire encoding for RPC using the older Thrift *binary protocol*.
|
||||
|
||||
The information here is _mostly_ based on the Java implementation in the Apache thrift library (version 0.9.1 and
|
||||
0.9.3). Other implementation however, should behave the same.
|
||||
|
||||
For background on Thrift see the [Thrift whitepaper (pdf)](https://thrift.apache.org/static/files/thrift-20070401.pdf).
|
||||
|
||||
# Contents
|
||||
|
||||
* Binary protocol
|
||||
* Base types
|
||||
* Message
|
||||
* Struct
|
||||
* List and Set
|
||||
* Map
|
||||
* BNF notation used in this document
|
||||
|
||||
# Binary protocol
|
||||
|
||||
## Base types
|
||||
|
||||
### Integer encoding
|
||||
|
||||
In the _binary protocol_ integers are encoded with the most significant byte first (big endian byte order, aka network
|
||||
order). An `int8` needs 1 byte, an `int16` 2, an `int32` 4 and an `int64` needs 8 bytes.
|
||||
|
||||
The CPP version has the option to use the binary protocol with little endian order. Little endian gives a small but
|
||||
noticeable performance boost because contemporary CPUs use little endian when storing integers to RAM.
|
||||
|
||||
### Enum encoding
|
||||
|
||||
The generated code encodes `Enum`s by taking the ordinal value and then encoding that as an int32.
|
||||
|
||||
### Binary encoding
|
||||
|
||||
Binary is sent as follows:
|
||||
|
||||
```
|
||||
Binary protocol, binary data, 4+ bytes:
|
||||
+--------+--------+--------+--------+--------+...+--------+
|
||||
| byte length | bytes |
|
||||
+--------+--------+--------+--------+--------+...+--------+
|
||||
```
|
||||
|
||||
Where:
|
||||
|
||||
* `byte length` is the length of the byte array, a signed 32 bit integer encoded in network (big endian) order (must be >= 0).
|
||||
* `bytes` are the bytes of the byte array.
|
||||
|
||||
### String encoding
|
||||
|
||||
*String*s are first encoded to UTF-8, and then send as binary.
|
||||
|
||||
### Double encoding
|
||||
|
||||
Values of type `double` are first converted to an int64 according to the IEEE 754 floating-point "double format" bit
|
||||
layout. Most run-times provide a library to make this conversion. Both the binary protocol as the compact protocol then
|
||||
encode the int64 in 8 bytes in big endian order.
|
||||
|
||||
### Boolean encoding
|
||||
|
||||
Values of `bool` type are first converted to an int8. True is converted to `1`, false to `0`.
|
||||
|
||||
## Message
|
||||
|
||||
A `Message` can be encoded in two different ways:
|
||||
|
||||
```
|
||||
Binary protocol Message, strict encoding, 12+ bytes:
|
||||
+--------+--------+--------+--------+--------+--------+--------+--------+--------+...+--------+--------+--------+--------+--------+
|
||||
|1vvvvvvv|vvvvvvvv|unused |00000mmm| name length | name | seq id |
|
||||
+--------+--------+--------+--------+--------+--------+--------+--------+--------+...+--------+--------+--------+--------+--------+
|
||||
```
|
||||
|
||||
Where:
|
||||
|
||||
* `vvvvvvvvvvvvvvv` is the version, an unsigned 15 bit number fixed to `1` (in binary: `000 0000 0000 0001`).
|
||||
The leading bit is `1`.
|
||||
* `unused` is an ignored byte.
|
||||
* `mmm` is the message type, an unsigned 3 bit integer. The 5 leading bits must be `0` as some clients (checked for
|
||||
java in 0.9.1) take the whole byte.
|
||||
* `name length` is the byte length of the name field, a signed 32 bit integer encoded in network (big endian) order (must be >= 0).
|
||||
* `name` is the method name, a UTF-8 encoded string.
|
||||
* `seq id` is the sequence id, a signed 32 bit integer encoded in network (big endian) order.
|
||||
|
||||
The second, older encoding (aka non-strict) is:
|
||||
|
||||
```
|
||||
Binary protocol Message, old encoding, 9+ bytes:
|
||||
+--------+--------+--------+--------+--------+...+--------+--------+--------+--------+--------+--------+
|
||||
| name length | name |00000mmm| seq id |
|
||||
+--------+--------+--------+--------+--------+...+--------+--------+--------+--------+--------+--------+
|
||||
```
|
||||
|
||||
Where `name length`, `name`, `mmm`, `seq id` are as above.
|
||||
|
||||
Because `name length` must be positive (therefore the first bit is always `0`), the first bit allows the receiver to see
|
||||
whether the strict format or the old format is used. Therefore a server and client using the different variants of the
|
||||
binary protocol can transparently talk with each other. However, when strict mode is enforced, the old format is
|
||||
rejected.
|
||||
|
||||
Message types are encoded with the following values:
|
||||
|
||||
* _Call_: 1
|
||||
* _Reply_: 2
|
||||
* _Exception_: 3
|
||||
* _Oneway_: 4
|
||||
|
||||
## Struct
|
||||
|
||||
A *Struct* is a sequence of zero or more fields, followed by a stop field. Each field starts with a field header and
|
||||
is followed by the encoded field value. The encoding can be summarized by the following BNF:
|
||||
|
||||
```
|
||||
struct ::= ( field-header field-value )* stop-field
|
||||
field-header ::= field-type field-id
|
||||
```
|
||||
|
||||
Because each field header contains the field-id (as defined by the Thrift IDL file), the fields can be encoded in any
|
||||
order. Thrift's type system is not extensible; you can only encode the primitive types and structs. Therefore is also
|
||||
possible to handle unknown fields while decoding; these are simply ignored. While decoding the field type can be used to
|
||||
determine how to decode the field value.
|
||||
|
||||
Note that the field name is not encoded so field renames in the IDL do not affect forward and backward compatibility.
|
||||
|
||||
The default Java implementation (Apache Thrift 0.9.1) has undefined behavior when it tries to decode a field that has
|
||||
another field-type then what is expected. Theoretically this could be detected at the cost of some additional checking.
|
||||
Other implementation may perform this check and then either ignore the field, or return a protocol exception.
|
||||
|
||||
A *Union* is encoded exactly the same as a struct with the additional restriction that at most 1 field may be encoded.
|
||||
|
||||
An *Exception* is encoded exactly the same as a struct.
|
||||
|
||||
### Struct encoding
|
||||
|
||||
In the binary protocol field headers and the stop field are encoded as follows:
|
||||
|
||||
```
|
||||
Binary protocol field header and field value:
|
||||
+--------+--------+--------+--------+...+--------+
|
||||
|tttttttt| field id | field value |
|
||||
+--------+--------+--------+--------+...+--------+
|
||||
|
||||
Binary protocol stop field:
|
||||
+--------+
|
||||
|00000000|
|
||||
+--------+
|
||||
```
|
||||
|
||||
Where:
|
||||
|
||||
* `tttttttt` the field-type, a signed 8 bit integer.
|
||||
* `field id` the field-id, a signed 16 bit integer in big endian order.
|
||||
* `field-value` the encoded field value.
|
||||
|
||||
The following field-types are used:
|
||||
|
||||
* `BOOL`, encoded as `2`
|
||||
* `BYTE`, encoded as `3`
|
||||
* `DOUBLE`, encoded as `4`
|
||||
* `I16`, encoded as `6`
|
||||
* `I32`, encoded as `8`
|
||||
* `I64`, encoded as `10`
|
||||
* `STRING`, used for binary and string fields, encoded as `11`
|
||||
* `STRUCT`, used for structs and union fields, encoded as `12`
|
||||
* `MAP`, encoded as `13`
|
||||
* `SET`, encoded as `14`
|
||||
* `LIST`, encoded as `15`
|
||||
|
||||
## List and Set
|
||||
|
||||
List and sets are encoded the same: a header indicating the size and the element-type of the elements, followed by the
|
||||
encoded elements.
|
||||
|
||||
```
|
||||
Binary protocol list (5+ bytes) and elements:
|
||||
+--------+--------+--------+--------+--------+--------+...+--------+
|
||||
|tttttttt| size | elements |
|
||||
+--------+--------+--------+--------+--------+--------+...+--------+
|
||||
```
|
||||
|
||||
Where:
|
||||
|
||||
* `tttttttt` is the element-type, encoded as an int8
|
||||
* `size` is the size, encoded as an int32, positive values only
|
||||
* `elements` the element values
|
||||
|
||||
The element-type values are the same as field-types. The full list is included in the struct section above.
|
||||
|
||||
The maximum list/set size is configurable. By default there is no limit (meaning the limit is the maximum int32 value:
|
||||
2147483647).
|
||||
|
||||
## Map
|
||||
|
||||
Maps are encoded with a header indicating the size, the element-type of the keys and the element-type of the elements,
|
||||
followed by the encoded elements. The encoding follows this BNF:
|
||||
|
||||
```
|
||||
map ::= key-element-type value-element-type size ( key value )*
|
||||
```
|
||||
|
||||
```
|
||||
Binary protocol map (6+ bytes) and key value pairs:
|
||||
+--------+--------+--------+--------+--------+--------+--------+...+--------+
|
||||
|kkkkkkkk|vvvvvvvv| size | key value pairs |
|
||||
+--------+--------+--------+--------+--------+--------+--------+...+--------+
|
||||
```
|
||||
|
||||
Where:
|
||||
|
||||
* `kkkkkkkk` is the key element-type, encoded as an int8
|
||||
* `vvvvvvvv` is the value element-type, encoded as an int8
|
||||
* `size` is the size of the map, encoded as an int32, positive values only
|
||||
* `key value pairs` are the encoded keys and values
|
||||
|
||||
The element-type values are the same as field-types. The full list is included in the struct section above.
|
||||
|
||||
The maximum map size is configurable. By default there is no limit (meaning the limit is the maximum int32 value:
|
||||
2147483647).
|
||||
|
||||
# BNF notation used in this document
|
||||
|
||||
The following BNF notation is used:
|
||||
|
||||
* a plus `+` appended to an item represents repetition; the item is repeated 1 or more times
|
||||
* a star `*` appended to an item represents optional repetition; the item is repeated 0 or more times
|
||||
* a pipe `|` between items represents choice, the first matching item is selected
|
||||
* parenthesis `(` and `)` are used for grouping multiple items
|
294
vendor/git.apache.org/thrift.git/doc/specs/thrift-compact-protocol.md
generated
vendored
Normal file
294
vendor/git.apache.org/thrift.git/doc/specs/thrift-compact-protocol.md
generated
vendored
Normal file
|
@ -0,0 +1,294 @@
|
|||
Thrift Compact protocol encoding
|
||||
================================
|
||||
|
||||
<!--
|
||||
--------------------------------------------------------------------
|
||||
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF licenses this file
|
||||
to you under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing,
|
||||
software distributed under the License is distributed on an
|
||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, either express or implied. See the License for the
|
||||
specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
--------------------------------------------------------------------
|
||||
-->
|
||||
|
||||
This documents describes the wire encoding for RPC using the Thrift *compact protocol*.
|
||||
|
||||
The information here is _mostly_ based on the Java implementation in the Apache thrift library (version 0.9.1) and
|
||||
[THRIFT-110 A more compact format](https://issues.apache.org/jira/browse/THRIFT-110). Other implementation however,
|
||||
should behave the same.
|
||||
|
||||
For background on Thrift see the [Thrift whitepaper (pdf)](https://thrift.apache.org/static/files/thrift-20070401.pdf).
|
||||
|
||||
# Contents
|
||||
|
||||
* Compact protocol
|
||||
* Base types
|
||||
* Message
|
||||
* Struct
|
||||
* List and Set
|
||||
* Map
|
||||
* BNF notation used in this document
|
||||
|
||||
# Compact protocol
|
||||
|
||||
## Base types
|
||||
|
||||
### Integer encoding
|
||||
|
||||
The _compact protocol_ uses multiple encodings for ints: the _zigzag int_, and the _var int_.
|
||||
|
||||
Values of type `int32` and `int64` are first transformed to a *zigzag int*. A zigzag int folds positive and negative
|
||||
numbers into the positive number space. When we read 0, 1, 2, 3, 4 or 5 from the wire, this is translated to 0, -1, 1,
|
||||
-2 or 2 respectively. Here are the (Scala) formulas to convert from int32/int64 to a zigzag int and back:
|
||||
|
||||
```scala
|
||||
def intToZigZag(n: Int): Int = (n << 1) ^ (n >> 31)
|
||||
def zigzagToInt(n: Int): Int = (n >>> 1) ^ - (n & 1)
|
||||
def longToZigZag(n: Long): Long = (n << 1) ^ (n >> 63)
|
||||
def zigzagToLong(n: Long): Long = (n >>> 1) ^ - (n & 1)
|
||||
```
|
||||
|
||||
The zigzag int is then encoded as a *var int*. Var ints take 1 to 5 bytes (int32) or 1 to 10 bytes (int64). The most
|
||||
significant bit of each byte indicates if more bytes follow. The concatenation of the least significant 7 bits from each
|
||||
byte form the number, where the first byte has the most significant bits (so they are in big endian or network order).
|
||||
|
||||
Var ints are sometimes used directly inside the compact protocol to represent positive numbers.
|
||||
|
||||
To encode an `int16` as zigzag int, it is first converted to an `int32` and then encoded as such. The type `int8` simply
|
||||
uses a single byte as in the binary protocol.
|
||||
|
||||
### Enum encoding
|
||||
|
||||
The generated code encodes `Enum`s by taking the ordinal value and then encoding that as an int32.
|
||||
|
||||
### Binary encoding
|
||||
|
||||
Binary is sent as follows:
|
||||
|
||||
```
|
||||
Binary protocol, binary data, 1+ bytes:
|
||||
+--------+...+--------+--------+...+--------+
|
||||
| byte length | bytes |
|
||||
+--------+...+--------+--------+...+--------+
|
||||
```
|
||||
|
||||
Where:
|
||||
|
||||
* `byte length` is the length of the byte array, using var int encoding (must be >= 0).
|
||||
* `bytes` are the bytes of the byte array.
|
||||
|
||||
### String encoding
|
||||
|
||||
*String*s are first encoded to UTF-8, and then send as binary.
|
||||
|
||||
### Double encoding
|
||||
|
||||
Values of type `double` are first converted to an int64 according to the IEEE 754 floating-point "double format" bit
|
||||
layout. Most run-times provide a library to make this conversion. Both the binary protocol as the compact protocol then
|
||||
encode the int64 in 8 bytes in big endian order.
|
||||
|
||||
### Boolean encoding
|
||||
|
||||
Booleans are encoded differently depending on whether it is a field value (in a struct) or an element value (in a set,
|
||||
list or map). Field values are encoded directly in the field header. Element values of type `bool` are sent as an int8;
|
||||
true as `1` and false as `0`.
|
||||
|
||||
## Message
|
||||
|
||||
A `Message` on the wire looks as follows:
|
||||
|
||||
```
|
||||
Compact protocol Message (4+ bytes):
|
||||
+--------+--------+--------+...+--------+--------+...+--------+--------+...+--------+
|
||||
|pppppppp|mmmvvvvv| seq id | name length | name |
|
||||
+--------+--------+--------+...+--------+--------+...+--------+--------+...+--------+
|
||||
```
|
||||
|
||||
Where:
|
||||
|
||||
* `pppppppp` is the protocol id, fixed to `1000 0010`, 0x82.
|
||||
* `mmm` is the message type, an unsigned 3 bit integer.
|
||||
* `vvvvv` is the version, an unsigned 5 bit integer, fixed to `00001`.
|
||||
* `seq id` is the sequence id, a signed 32 bit integer encoded as a var int.
|
||||
* `name length` is the byte length of the name field, a signed 32 bit integer encoded as a var int (must be >= 0).
|
||||
* `name` is the method name to invoke, a UTF-8 encoded string.
|
||||
|
||||
Message types are encoded with the following values:
|
||||
|
||||
* _Call_: 1
|
||||
* _Reply_: 2
|
||||
* _Exception_: 3
|
||||
* _Oneway_: 4
|
||||
|
||||
### Struct
|
||||
|
||||
A *Struct* is a sequence of zero or more fields, followed by a stop field. Each field starts with a field header and
|
||||
is followed by the encoded field value. The encoding can be summarized by the following BNF:
|
||||
|
||||
```
|
||||
struct ::= ( field-header field-value )* stop-field
|
||||
field-header ::= field-type field-id
|
||||
```
|
||||
|
||||
Because each field header contains the field-id (as defined by the Thrift IDL file), the fields can be encoded in any
|
||||
order. Thrift's type system is not extensible; you can only encode the primitive types and structs. Therefore is also
|
||||
possible to handle unknown fields while decoding; these are simply ignored. While decoding the field type can be used to
|
||||
determine how to decode the field value.
|
||||
|
||||
Note that the field name is not encoded so field renames in the IDL do not affect forward and backward compatibility.
|
||||
|
||||
The default Java implementation (Apache Thrift 0.9.1) has undefined behavior when it tries to decode a field that has
|
||||
another field-type then what is expected. Theoretically this could be detected at the cost of some additional checking.
|
||||
Other implementation may perform this check and then either ignore the field, or return a protocol exception.
|
||||
|
||||
A *Union* is encoded exactly the same as a struct with the additional restriction that at most 1 field may be encoded.
|
||||
|
||||
An *Exception* is encoded exactly the same as a struct.
|
||||
|
||||
### Struct encoding
|
||||
|
||||
```
|
||||
Compact protocol field header (short form) and field value:
|
||||
+--------+--------+...+--------+
|
||||
|ddddtttt| field value |
|
||||
+--------+--------+...+--------+
|
||||
|
||||
Compact protocol field header (1 to 3 bytes, long form) and field value:
|
||||
+--------+--------+...+--------+--------+...+--------+
|
||||
|0000tttt| field id | field value |
|
||||
+--------+--------+...+--------+--------+...+--------+
|
||||
|
||||
Compact protocol stop field:
|
||||
+--------+
|
||||
|00000000|
|
||||
+--------+
|
||||
```
|
||||
|
||||
Where:
|
||||
|
||||
* `dddd` is the field id delta, an unsigned 4 bits integer, strictly positive.
|
||||
* `tttt` is field-type id, an unsigned 4 bit integer.
|
||||
* `field id` the field id, a signed 16 bit integer encoded as zigzag int.
|
||||
* `field-value` the encoded field value.
|
||||
|
||||
The field id delta can be computed by `current-field-id - previous-field-id`, or just `current-field-id` if this is the
|
||||
first of the struct. The short form should be used when the field id delta is in the range 1 - 15 (inclusive).
|
||||
|
||||
The following field-types can be encoded:
|
||||
|
||||
* `BOOLEAN_TRUE`, encoded as `1`
|
||||
* `BOOLEAN_FALSE`, encoded as `2`
|
||||
* `BYTE`, encoded as `3`
|
||||
* `I16`, encoded as `4`
|
||||
* `I32`, encoded as `5`
|
||||
* `I64`, encoded as `6`
|
||||
* `DOUBLE`, encoded as `7`
|
||||
* `BINARY`, used for binary and string fields, encoded as `8`
|
||||
* `LIST`, encoded as `9`
|
||||
* `SET`, encoded as `10`
|
||||
* `MAP`, encoded as `11`
|
||||
* `STRUCT`, used for both structs and union fields, encoded as `12`
|
||||
|
||||
Note that because there are 2 specific field types for the boolean values, the encoding of a boolean field value has no
|
||||
length (0 bytes).
|
||||
|
||||
## List and Set
|
||||
|
||||
List and sets are encoded the same: a header indicating the size and the element-type of the elements, followed by the
|
||||
encoded elements.
|
||||
|
||||
```
|
||||
Compact protocol list header (1 byte, short form) and elements:
|
||||
+--------+--------+...+--------+
|
||||
|sssstttt| elements |
|
||||
+--------+--------+...+--------+
|
||||
|
||||
Compact protocol list header (2+ bytes, long form) and elements:
|
||||
+--------+--------+...+--------+--------+...+--------+
|
||||
|1111tttt| size | elements |
|
||||
+--------+--------+...+--------+--------+...+--------+
|
||||
```
|
||||
|
||||
Where:
|
||||
|
||||
* `ssss` is the size, 4 bit unsigned int, values `0` - `14`
|
||||
* `tttt` is the element-type, a 4 bit unsigned int
|
||||
* `size` is the size, a var int (int32), positive values `15` or higher
|
||||
* `elements` are the encoded elements
|
||||
|
||||
The short form should be used when the length is in the range 0 - 14 (inclusive).
|
||||
|
||||
The following element-types are used (note that these are _different_ from the field-types):
|
||||
|
||||
* `BOOL`, encoded as `2`
|
||||
* `BYTE`, encoded as `3`
|
||||
* `DOUBLE`, encoded as `4`
|
||||
* `I16`, encoded as `6`
|
||||
* `I32`, encoded as `8`
|
||||
* `I64`, encoded as `10`
|
||||
* `STRING`, used for binary and string fields, encoded as `11`
|
||||
* `STRUCT`, used for structs and union fields, encoded as `12`
|
||||
* `MAP`, encoded as `13`
|
||||
* `SET`, encoded as `14`
|
||||
* `LIST`, encoded as `15`
|
||||
|
||||
|
||||
The maximum list/set size is configurable. By default there is no limit (meaning the limit is the maximum int32 value:
|
||||
2147483647).
|
||||
|
||||
## Map
|
||||
|
||||
Maps are encoded with a header indicating the size, the type of the keys and the element-type of the elements, followed
|
||||
by the encoded elements. The encoding follows this BNF:
|
||||
|
||||
```
|
||||
map ::= empty-map | non-empty-map
|
||||
empty-map ::= `0`
|
||||
non-empty-map ::= size key-element-type value-element-type (key value)+
|
||||
```
|
||||
|
||||
```
|
||||
Compact protocol map header (1 byte, empty map):
|
||||
+--------+
|
||||
|00000000|
|
||||
+--------+
|
||||
|
||||
Compact protocol map header (2+ bytes, non empty map) and key value pairs:
|
||||
+--------+...+--------+--------+--------+...+--------+
|
||||
| size |kkkkvvvv| key value pairs |
|
||||
+--------+...+--------+--------+--------+...+--------+
|
||||
```
|
||||
|
||||
Where:
|
||||
|
||||
* `size` is the size, a var int (int32), strictly positive values
|
||||
* `kkkk` is the key element-type, a 4 bit unsigned int
|
||||
* `vvvv` is the value element-type, a 4 bit unsigned int
|
||||
* `key value pairs` are the encoded keys and values
|
||||
|
||||
The element-types are the same as for lists. The full list is included in the 'List and set' section.
|
||||
|
||||
The maximum map size is configurable. By default there is no limit (meaning the limit is the maximum int32 value:
|
||||
2147483647).
|
||||
|
||||
# BNF notation used in this document
|
||||
|
||||
The following BNF notation is used:
|
||||
|
||||
* a plus `+` appended to an item represents repetition; the item is repeated 1 or more times
|
||||
* a star `*` appended to an item represents optional repetition; the item is repeated 0 or more times
|
||||
* a pipe `|` between items represents choice, the first matching item is selected
|
||||
* parenthesis `(` and `)` are used for grouping multiple items
|
101
vendor/git.apache.org/thrift.git/doc/specs/thrift-protocol-spec.md
generated
vendored
Normal file
101
vendor/git.apache.org/thrift.git/doc/specs/thrift-protocol-spec.md
generated
vendored
Normal file
|
@ -0,0 +1,101 @@
|
|||
Thrift Protocol Structure
|
||||
====================================================================
|
||||
|
||||
Last Modified: 2007-Jun-29
|
||||
|
||||
<!--
|
||||
--------------------------------------------------------------------
|
||||
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF licenses this file
|
||||
to you under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing,
|
||||
software distributed under the License is distributed on an
|
||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, either express or implied. See the License for the
|
||||
specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
--------------------------------------------------------------------
|
||||
-->
|
||||
|
||||
This document describes the structure of the Thrift protocol
|
||||
without specifying the encoding. Thus, the order of elements
|
||||
could in some cases be rearranged depending upon the TProtocol
|
||||
implementation, but this document specifies the minimum required
|
||||
structure. There are some "dumb" terminals like STRING and INT
|
||||
that take the place of an actual encoding specification.
|
||||
|
||||
They key point to notice is that ALL messages are just one wrapped
|
||||
`<struct>`. Depending upon the message type, the `<struct>` can be
|
||||
interpreted as the argument list to a function, the return value
|
||||
of a function, or an exception.
|
||||
|
||||
--------------------------------------------------------------------
|
||||
|
||||
```
|
||||
<message> ::= <message-begin> <struct> <message-end>
|
||||
|
||||
<message-begin> ::= <method-name> <message-type> <message-seqid>
|
||||
|
||||
<method-name> ::= STRING
|
||||
|
||||
<message-type> ::= T_CALL | T_REPLY | T_EXCEPTION | T_ONEWAY
|
||||
|
||||
<message-seqid> ::= I32
|
||||
|
||||
<struct> ::= <struct-begin> <field>* <field-stop> <struct-end>
|
||||
|
||||
<struct-begin> ::= <struct-name>
|
||||
|
||||
<struct-name> ::= STRING
|
||||
|
||||
<field-stop> ::= T_STOP
|
||||
|
||||
<field> ::= <field-begin> <field-data> <field-end>
|
||||
|
||||
<field-begin> ::= <field-name> <field-type> <field-id>
|
||||
|
||||
<field-name> ::= STRING
|
||||
|
||||
<field-type> ::= T_BOOL | T_BYTE | T_I8 | T_I16 | T_I32 | T_I64 | T_DOUBLE
|
||||
| T_STRING | T_BINARY | T_STRUCT | T_MAP | T_SET | T_LIST
|
||||
|
||||
<field-id> ::= I16
|
||||
|
||||
<field-data> ::= I8 | I16 | I32 | I64 | DOUBLE | STRING | BINARY
|
||||
<struct> | <map> | <list> | <set>
|
||||
|
||||
<map> ::= <map-begin> <field-datum>* <map-end>
|
||||
|
||||
<map-begin> ::= <map-key-type> <map-value-type> <map-size>
|
||||
|
||||
<map-key-type> ::= <field-type>
|
||||
|
||||
<map-value-type> ::= <field-type>
|
||||
|
||||
<map-size> ::= I32
|
||||
|
||||
<list> ::= <list-begin> <field-data>* <list-end>
|
||||
|
||||
<list-begin> ::= <list-elem-type> <list-size>
|
||||
|
||||
<list-elem-type> ::= <field-type>
|
||||
|
||||
<list-size> ::= I32
|
||||
|
||||
<set> ::= <set-begin> <field-data>* <set-end>
|
||||
|
||||
<set-begin> ::= <set-elem-type> <set-size>
|
||||
|
||||
<set-elem-type> ::= <field-type>
|
||||
|
||||
<set-size> ::= I32
|
||||
```
|
178
vendor/git.apache.org/thrift.git/doc/specs/thrift-rpc.md
generated
vendored
Normal file
178
vendor/git.apache.org/thrift.git/doc/specs/thrift-rpc.md
generated
vendored
Normal file
|
@ -0,0 +1,178 @@
|
|||
Thrift Remote Procedure Call
|
||||
============================
|
||||
|
||||
<!--
|
||||
--------------------------------------------------------------------
|
||||
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF licenses this file
|
||||
to you under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing,
|
||||
software distributed under the License is distributed on an
|
||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, either express or implied. See the License for the
|
||||
specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
--------------------------------------------------------------------
|
||||
-->
|
||||
|
||||
This document describes the high level message exchange between the Thrift RPC client and server.
|
||||
See [thrift-binary-protocol.md] and [thrift-compact-protocol.md] for a description of how the exchanges are encoded on
|
||||
the wire.
|
||||
|
||||
In addition, this document compares the binary protocol with the compact protocol. Finally it describes the framed vs.
|
||||
unframed transport.
|
||||
|
||||
The information here is _mostly_ based on the Java implementation in the Apache thrift library (version 0.9.1 and
|
||||
0.9.3). Other implementation however, should behave the same.
|
||||
|
||||
For background on Thrift see the [Thrift whitepaper (pdf)](https://thrift.apache.org/static/files/thrift-20070401.pdf).
|
||||
|
||||
# Contents
|
||||
|
||||
* Thrift Message exchange for Remote Procedure Call
|
||||
* Message
|
||||
* Request struct
|
||||
* Response struct
|
||||
* Protocol considerations
|
||||
* Comparing binary and compact protocol
|
||||
* Compatibility
|
||||
* Framed vs unframed transport
|
||||
|
||||
# Thrift Remote Procedure Call Message exchange
|
||||
|
||||
Both the binary protocol and the compact protocol assume a transport layer that exposes a bi-directional byte stream,
|
||||
for example a TCP socket. Both use the following exchange:
|
||||
|
||||
1. Client sends a `Message` (type `Call` or `Oneway`). The TMessage contains some metadata and the name of the method
|
||||
to invoke.
|
||||
2. Client sends method arguments (a struct defined by the generate code).
|
||||
3. Server sends a `Message` (type `Reply` or `Exception`) to start the response.
|
||||
4. Server sends a struct containing the method result or exception.
|
||||
|
||||
The pattern is a simple half duplex protocol where the parties alternate in sending a `Message` followed by a struct.
|
||||
What these are is described below.
|
||||
|
||||
Although the standard Apache Thrift Java clients do not support pipelining (sending multiple requests without waiting
|
||||
for an response), the standard Apache Thrift Java servers do support it.
|
||||
|
||||
## Message
|
||||
|
||||
A *Message* contains:
|
||||
|
||||
* _Name_, a string (can be empty).
|
||||
* _Message type_, a message types, one of `Call`, `Reply`, `Exception` and `Oneway`.
|
||||
* _Sequence id_, a signed int32 integer.
|
||||
|
||||
The *sequence id* is a simple message id assigned by the client. The server will use the same sequence id in the
|
||||
message of the response. The client uses this number to detect out of order responses. Each client has an int32 field
|
||||
which is increased for each message. The sequence id simply wraps around when it overflows.
|
||||
|
||||
The *name* indicates the service method name to invoke. The server copies the name in the response message.
|
||||
|
||||
When the *multiplexed protocol* is used, the name contains the service name, a colon `:` and the method name. The
|
||||
multiplexed protocol is not compatible with other protocols.
|
||||
|
||||
The *message type* indicates what kind of message is sent. Clients send requests with TMessages of type `Call` or
|
||||
`Oneway` (step 1 in the protocol exchange). Servers send responses with messages of type `Exception` or `Reply` (step
|
||||
3).
|
||||
|
||||
Type `Reply` is used when the service method completes normally. That is, it returns a value or it throws one of the
|
||||
exceptions defined in the Thrift IDL file.
|
||||
|
||||
Type `Exception` is used for other exceptions. That is: when the service method throws an exception that is not declared
|
||||
in the Thrift IDL file, or some other part of the Thrift stack throws an exception. For example when the server could
|
||||
not encode or decode a message or struct.
|
||||
|
||||
In the Java implementation (0.9.3) there is different behavior for the synchronous and asynchronous server. In the async
|
||||
server all exceptions are send as a `TApplicationException` (see 'Response struct' below). In the synchronous Java
|
||||
implementation only (undeclared) exceptions that extend `TException` are send as a `TApplicationException`. Unchecked
|
||||
exceptions lead to an immediate close of the connection.
|
||||
|
||||
Type `Oneway` is only used starting from Apache Thrift 0.9.3. Earlier versions do _not_ send TMessages of type `Oneway`,
|
||||
even for service methods defined with the `oneway` modifier.
|
||||
|
||||
When client sends a request with type `Oneway`, the server must _not_ send a response (steps 3 and 4 are skipped). Note
|
||||
that the Thrift IDL enforces a return type of `void` and does not allow exceptions for oneway services.
|
||||
|
||||
## Request struct
|
||||
|
||||
The struct that follows the message of type `Call` or `Oneway` contains the arguments of the service method. The
|
||||
argument ids correspond to the field ids. The name of the struct is the name of the method with `_args` appended.
|
||||
For methods without arguments an struct is sent without fields.
|
||||
|
||||
## Response struct
|
||||
|
||||
The struct that follows the message of type `Reply` are structs in which exactly 1 of the following fields is encoded:
|
||||
|
||||
* A field with name `success` and id `0`, used in case the method completed normally.
|
||||
* An exception field, name and id are as defined in the `throws` clause in the Thrift IDL's service method definition.
|
||||
|
||||
When the message is of type `Exception` the struct is encoded as if it was declared by the following IDL:
|
||||
|
||||
```
|
||||
exception TApplicationException {
|
||||
1: string message,
|
||||
2: i32 type
|
||||
}
|
||||
```
|
||||
|
||||
The following exception types are defined in the java implementation (0.9.3):
|
||||
|
||||
* _unknown_: 0, used in case the type from the peer is unknown.
|
||||
* _unknown method_: 1, used in case the method requested by the client is unknown by the server.
|
||||
* _invalid message type_: 2, no usage was found.
|
||||
* _wrong method name_: 3, no usage was found.
|
||||
* _bad sequence id_: 4, used internally by the client to indicate a wrong sequence id in the response.
|
||||
* _missing result_: 5, used internally by the client to indicate a response without any field (result nor exception).
|
||||
* _internal error_: 6, used when the server throws an exception that is not declared in the Thrift IDL file.
|
||||
* _protocol error_: 7, used when something goes wrong during decoding. For example when a list is too long or a required
|
||||
field is missing.
|
||||
* _invalid transform_: 8, no usage was found.
|
||||
* _invalid protocol_: 9, no usage was found.
|
||||
* _unsupported client type_: 10, no usage was found.
|
||||
|
||||
# Protocol considerations
|
||||
|
||||
## Comparing binary and compact protocol
|
||||
|
||||
The binary protocol is fairly simple and therefore easy to process. The compact protocol needs less bytes to send the
|
||||
same data at the cost of additional processing. As bandwidth is usually the bottleneck, the compact protocol is almost
|
||||
always slightly faster.
|
||||
|
||||
## Compatibility
|
||||
|
||||
A server could automatically determine whether a client talks the binary protocol or the compact protocol by
|
||||
investigating the first byte. If the value is `1000 0001` or `0000 0000` (assuming a name shorter then ±16 MB) it is the
|
||||
binary protocol. When the value is `1000 0010` it is talking the compact protocol.
|
||||
|
||||
## Framed vs. unframed transport
|
||||
|
||||
The first thrift binary wire format was unframed. This means that information is sent out in a single stream of bytes.
|
||||
With unframed transport the (generated) processors will read directly from the socket (though Apache Thrift does try to
|
||||
grab all available bytes from the socket in a buffer when it can).
|
||||
|
||||
Later, Thrift introduced the framed transport.
|
||||
|
||||
With framed transport the full request and response (the TMessage and the following struct) are first written to a
|
||||
buffer. Then when the struct is complete (transport method `flush` is hijacked for this), the length of the buffer is
|
||||
written to the socket first, followed by the buffered bytes. The combination is called a _frame_. On the receiver side
|
||||
the complete frame is first read in a buffer before the message is passed to a processor.
|
||||
|
||||
The length prefix is a 4 byte signed int, send in network (big endian) order.
|
||||
The following must be true: `0` <= length <= `16384000` (16M).
|
||||
|
||||
Framed transport was introduced to ease the implementation of async processors. An async processor is only invoked when
|
||||
all data is received. Unfortunately, framed transport is not ideal for large messages as the entire frame stays in
|
||||
memory until the message has been processed. In addition, the java implementation merges the incoming data to a single,
|
||||
growing byte array. Every time the byte array is full it needs to be copied to a new larger byte array.
|
||||
|
||||
Framed and unframed transports are not compatible with each other.
|
108
vendor/git.apache.org/thrift.git/doc/specs/thrift-sasl-spec.txt
generated
vendored
Normal file
108
vendor/git.apache.org/thrift.git/doc/specs/thrift-sasl-spec.txt
generated
vendored
Normal file
|
@ -0,0 +1,108 @@
|
|||
A Thrift SASL message shall be a byte array of the following form:
|
||||
|
||||
| 1-byte status code | 4-byte payload length | variable-length payload |
|
||||
|
||||
The length fields shall be interpreted as integers, with the high byte sent
|
||||
first. This indicates the length of the field immediately following it, not
|
||||
including the status code or the length bytes.
|
||||
|
||||
The possible status codes are:
|
||||
|
||||
0x01 - START - Hello, let's go on a date.
|
||||
0x02 - OK - Everything's been going alright so far, let's see each other again.
|
||||
0x03 - BAD - I understand what you're saying. I really do. I just don't like it. We have to break up.
|
||||
0x04 - ERROR - We can't go on like this. It's like you're speaking another language.
|
||||
0x05 - COMPLETE - Will you marry me?
|
||||
|
||||
The Thrift SASL communication will proceed as follows:
|
||||
|
||||
1. The client is configured at instantiation of the transport with a single
|
||||
underlying SASL security mechanism that it supports.
|
||||
|
||||
2. The server is configured with a mapping of underlying security mechanism
|
||||
name -> mechanism options.
|
||||
|
||||
3. At connection time, the client will initiate communication by sending the
|
||||
server a START message. The payload of this message will be the name of the
|
||||
underlying security mechanism that the client would like to use.
|
||||
This mechanism name shall be 1-20 characters in length, and follow the
|
||||
specifications for SASL mechanism names specified in RFC 2222.
|
||||
|
||||
4. The server receives this message and, if the mechanism name provided is
|
||||
among the set of mechanisms this server transport is configured to accept,
|
||||
appropriate initialization of the underlying security mechanism may take place.
|
||||
If the mechanism name is not one which the server is configured to support, the
|
||||
server shall return the BAD byte, followed by a 4-byte, potentially zero-value
|
||||
message length, followed by the potentially zero-length payload which may be a
|
||||
status code or message indicating failure. No further communication may take
|
||||
place via this transport. If the mechanism name is one which the server
|
||||
supports, then proceed to step 5.
|
||||
|
||||
5. Following the START message, the client must send another message containing
|
||||
the "initial response" of the chosen SASL implementation. The client may send
|
||||
this message piggy-backed on the "START" message of step 3. The message type
|
||||
of this message must be either "OK" or "COMPLETE", depending on whether the
|
||||
SASL implementation indicates that this side of the authentication has been
|
||||
satisfied.
|
||||
|
||||
6. The server then provides the byte array of the payload received to its
|
||||
underlying security mechanism. A challenge is generated by the underlying
|
||||
security mechanism on the server, and this is used as the payload for a message
|
||||
sent to the client. This message shall consist of an OK byte, followed by the
|
||||
non-zero message length word, followed by the payload.
|
||||
|
||||
7. The client receives this message from the server and passes the payload to
|
||||
its underlying security mechanism to generate a response. The client then sends
|
||||
the server an OK byte, followed by the non-zero-value length of the response,
|
||||
followed by the bytes of the response as the payload.
|
||||
|
||||
8. Steps 6 and 7 are repeated until both security mechanisms are satisfied with
|
||||
the challenge/response exchange. When either side has completed its security
|
||||
protocol, its next message shall be the COMPLETE byte, followed by a 4-byte
|
||||
potentially zero-value length word, followed by a potentially zero-length
|
||||
payload. This payload will be empty except for those underlying security
|
||||
mechanisms which provide additional data with success.
|
||||
|
||||
If at any point in time either side is able to interpret the challenge or
|
||||
response sent by the other, but is dissatisfied with the contents thereof, this
|
||||
side should send the other a BAD byte, followed by a 4-byte potentially
|
||||
zero-value length word, followed by an optional, potentially zero-length
|
||||
message encoded in UTF-8 indicating failure. This message should be passed to
|
||||
the protocol above the thrift transport by whatever mechanism is appropriate
|
||||
and idiomatic for the particular language these thrift bindings are for.
|
||||
|
||||
If at any point in time either side fails to interpret the challenge or
|
||||
response sent by the other, this side should send the other an ERROR byte,
|
||||
followed by a 4-byte potentially zero-value length word, followed by an
|
||||
optional, potentially zero-length message encoded in UTF-8. This message should
|
||||
be passed to the protocol above the thrift transport by whatever mechanism is
|
||||
appropriate and idiomatic for the particular language these thrift bindings are
|
||||
for.
|
||||
|
||||
If step 8 completes successfully, then the communication is considered
|
||||
authenticated and subsequent communication may commence.
|
||||
|
||||
If step 8 fails to complete successfully, then no further communication may
|
||||
take place via this transport.
|
||||
|
||||
8. All writes to the underlying transport must be prefixed by the 4-byte length
|
||||
of the payload data, followed by the payload. All reads from this transport
|
||||
should read the 4-byte length word, then read the full quantity of bytes
|
||||
specified by this length word.
|
||||
|
||||
If no SASL QOP (quality of protection) is negotiated during steps 6 and 7, then
|
||||
all subsequent writes to/reads from this transport are written/read unaltered,
|
||||
save for the length prefix, to the underlying transport.
|
||||
|
||||
If a SASL QOP is negotiated, then this must be used by the Thrift transport for
|
||||
all subsequent communication. This is done by wrapping subsequent writes to the
|
||||
transport using the underlying security mechanism, and unwrapping subsequent
|
||||
reads from the underlying transport. Note that in this case, the length prefix
|
||||
of the write to the underlying transport is the length of the data after it has
|
||||
been wrapped by the underlying security mechanism. Note that the complete
|
||||
message must be read before giving this data to the underlying security
|
||||
mechanism for unwrapping.
|
||||
|
||||
If at any point in time reading of a message fails either because of a
|
||||
malformed length word or failure to unwrap by the underlying security
|
||||
mechanism, then all further communication on this transport must cease.
|
1057
vendor/git.apache.org/thrift.git/doc/specs/thrift.tex
generated
vendored
Normal file
1057
vendor/git.apache.org/thrift.git/doc/specs/thrift.tex
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue