本文主要是介绍RFC6455-The WebSocket protocol 之四:Opening Handshake 4.1. Client Requirements,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
To _Establish a WebSocket Connection_, a client opens a connection
and sends a handshake as defined in this section. A connection is
defined to initially be in a CONNECTING state. A client will need to
supply a /host/, /port/, /resource name/, and a /secure/ flag, which
are the components of a WebSocket URI as discussed in Section 3,
along with a list of /protocols/ and /extensions/ to be used.
Additionally, if the client is a web browser, it supplies /origin/.
handsets tied to specific carriers, MAY offload the management of the
connection to another agent on the network. In such a situation, the
client for the purposes of this specification is considered to
include both the handset software and any such agents.
When the client is to _Establish a WebSocket Connection_ given a set
of (/host/, /port/, /resource name/, and /secure/ flag), along with a
list of /protocols/ and /extensions/ to be used, and an /origin/ in
the case of web browsers, it MUST open a connection, send an opening
handshake, and read the server’s handshake in response. The exact
requirements of how the connection should be opened, what should be
sent in the opening handshake, and how the server’s response should
be interpreted are as follows in this section. In the following
text, we will use terms from Section 3, such as "/host/" and
"/secure/ flag" as defined in that section.
1. The components of the WebSocket URI passed into this algorithm
(/host/, /port/, /resource name/, and /secure/ flag) MUST be
valid according to the specification of WebSocket URIs specified
in Section 3. If any of the components are invalid, the client
MUST _Fail the WebSocket Connection_ and abort these steps.
2. If the client already has a WebSocket connection to the remote
host (IP address) identified by /host/ and port /port/ pair, even
if the remote host is known by another name, the client MUST wait
until that connection has been established or for that connection
to have failed. There MUST be no more than one connection in a
CONNECTING state. If multiple connections to the same IP address
are attempted simultaneously, the client MUST serialize them so
that there is no more than one connection at a time running
through the following steps.
If the client cannot determine the IP address of the remote host
(for example, because all communication is being done through a
proxy server that performs DNS queries itself), then the client
MUST assume for the purposes of this step that each host name
refers to a distinct remote host, and instead the client SHOULD
limit the total number of simultaneous pending connections to a
reasonably low number (e.g., the client might allow simultaneous
pending connections to a.example.com and b.example.com, but if
thirty simultaneous connections to a single host are requested,
that may not be allowed). For example, in a web browser context,
the client needs to consider the number of tabs the user has open
in setting a limit to the number of simultaneous pending
connections.
service attack by just opening a large number of WebSocket
connections to a remote host. A server can further reduce the
load on itself when attacked by pausing before closing the
connection, as that will reduce the rate at which the client
reconnects.
NOTE: There is no limit to the number of established WebSocket
connections a client can have with a single remote host. Servers
can refuse to accept connections from hosts/IP addresses with an
excessive number of existing connections or disconnect resource-
hogging connections when suffering high load.
3. _Proxy Usage_: If the client is configured to use a proxy when
using the WebSocket Protocol to connect to host /host/ and port
/port/, then the client SHOULD connect to that proxy and ask it
to open a TCP connection to the host given by /host/ and the port
given by /port/.
EXAMPLE: For example, if the client uses an HTTP proxy for all
traffic, then if it was to try to connect to port 80 on server
example.com, it might send the following lines to the proxy
server:
CONNECT example.com:80 HTTP/1.1
Host: example.com
If there was a password, the connection might look like:
CONNECT example.com:80 HTTP/1.1
Host: example.com
Proxy-authorization: Basic ZWRuYW1vZGU6bm9jYXBlcyE=
Host: example.com
Host: example.com
Proxy-authorization: Basic ZWRuYW1vZGU6bm9jYXBlcyE=
If the client is not configured to use a proxy, then a direct TCP
connection SHOULD be opened to the host given by /host/ and the
port given by /port/.
NOTE: Implementations that do not expose explicit UI for
selecting a proxy for WebSocket connections separate from other
proxies are encouraged to use a SOCKS5 [RFC1928] proxy for
WebSocket connections, if available, or failing that, to prefer
the proxy configured for HTTPS connections over the proxy
configured for HTTP connections.
For the purpose of proxy autoconfiguration scripts, the URI to
pass the function MUST be constructed from /host/, /port/,
/resource name/, and the /secure/ flag using the definition of a
WebSocket URI as given in Section 3.
autoconfiguration scripts from the scheme ("ws" for unencrypted
connections and "wss" for encrypted connections).
4. If the connection could not be opened, either because a direct
connection failed or because any proxy used returned an error,
then the client MUST _Fail the WebSocket Connection_ and abort
the connection attempt.
5. If /secure/ is true, the client MUST perform a TLS handshake over
the connection after opening the connection and before sending
the handshake data [RFC2818]. If this fails (e.g., the server’s
certificate could not be verified), then the client MUST _Fail
the WebSocket Connection_ and abort the connection. Otherwise,
all further communication on this channel MUST run through the
encrypted tunnel [RFC5246].
Clients MUST use the Server Name Indication extension in the TLS
handshake [RFC6066].
Once a connection to the server has been established (including a
connection via a proxy or over a TLS-encrypted tunnel), the client
MUST send an opening handshake to the server. The handshake consists
of an HTTP Upgrade request, along with a list of required and
optional header fields. The requirements for this handshake are as
follows.
1. The handshake MUST be a valid HTTP request as specified by
[RFC2616].
2. The method of the request MUST be GET, and the HTTP version MUST
be at least 1.1.
For example, if the WebSocket URI is "ws://example.com/chat",
the first line sent should be "GET /chat HTTP/1.1".
3. The "Request-URI" part of the request MUST match the /resource
name/ defined in Section 3 (a relative URI) or be an absolute
http/https URI that, when parsed, has a /resource name/, /host/,
and /port/ that match the corresponding ws/wss URI.
4. The request MUST contain a |Host| header field whose value
contains /host/ plus optionally ":" followed by /port/ (when not
using the default port).
5. The request MUST contain an |Upgrade| header field whose value
MUST include the "websocket" keyword.
MUST include the "Upgrade" token.
7. The request MUST include a header field with the name
|Sec-WebSocket-Key|. The value of this header field MUST be a
nonce consisting of a randomly selected 16-byte value that has
been base64-encoded (see Section 4 of [RFC4648]). The nonce
MUST be selected randomly for each connection.
NOTE: As an example, if the randomly selected value was the
sequence of bytes 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09
0x0a 0x0b 0x0c 0x0d 0x0e 0x0f 0x10, the value of the header
field would be "AQIDBAUGBwgJCgsMDQ4PEC=="
8. The request MUST include a header field with the name |Origin|
[RFC6454] if the request is coming from a browser client. If
the connection is from a non-browser client, the request MAY
include this header field if the semantics of that client match
the use-case described here for browser clients. The value of
this header field is the ASCII serialization of origin of the
context in which the code establishing the connection is
running. See [RFC6454] for the details of how this header field
value is constructed.
As an example, if code downloaded from www.example.com attempts
to establish a connection to ww2.example.com, the value of the
header field would be "http://www.example.com".
9. The request MUST include a header field with the name
|Sec-WebSocket-Version|. The value of this header field MUST be
13.
NOTE: Although draft versions of this document (-09, -10, -11,
and -12) were posted (they were mostly comprised of editorial
changes and clarifications and not changes to the wire
protocol), values 9, 10, 11, and 12 were not used as valid
values for Sec-WebSocket-Version. These values were reserved in
the IANA registry but were not and will not be used.
10. The request MAY include a header field with the name
|Sec-WebSocket-Protocol|. If present, this value indicates one
or more comma-separated subprotocol the client wishes to speak,
ordered by preference. The elements that comprise this value
MUST be non-empty strings with characters in the range U+0021 to
U+007E not including separator characters as defined in
[RFC2616] and MUST all be unique strings. The ABNF for the
value of this header field is 1#token, where the definitions of
constructs and rules are as given in [RFC2616].
|Sec-WebSocket-Extensions|. If present, this value indicates
the protocol-level extension(s) the client wishes to speak. The
interpretation and format of this header field is described in
Section 9.1.
12. The request MAY include any other header fields, for example,
cookies [RFC6265] and/or authentication-related header fields
such as the |Authorization| header field [RFC2616], which are
processed according to documents that define them.
Once the client’s opening handshake has been sent, the client MUST
wait for a response from the server before sending any further data.
The client MUST validate the server’s response as follows:
1. If the status code received from the server is not 101, the
client handles the response per HTTP [RFC2616] procedures. In
particular, the client might perform authentication if it
receives a 401 status code; the server might redirect the client
using a 3xx status code (but clients are not required to follow
them), etc. Otherwise, proceed as follows.
2. If the response lacks an |Upgrade| header field or the |Upgrade|
header field contains a value that is not an ASCII case-
insensitive match for the value "websocket", the client MUST
_Fail the WebSocket Connection_.
3. If the response lacks a |Connection| header field or the
|Connection| header field doesn’t contain a token that is an
ASCII case-insensitive match for the value "Upgrade", the client
MUST _Fail the WebSocket Connection_.
4. If the response lacks a |Sec-WebSocket-Accept| header field or
the |Sec-WebSocket-Accept| contains a value other than the
base64-encoded SHA-1 of the concatenation of the |Sec-WebSocket-
Key| (as a string, not base64-decoded) with the string "258EAFA5-
E914-47DA-95CA-C5AB0DC85B11" but ignoring any leading and
trailing whitespace, the client MUST _Fail the WebSocket
Connection_.
5. If the response includes a |Sec-WebSocket-Extensions| header
field and this header field indicates the use of an extension
that was not present in the client’s handshake (the server has
indicated an extension not requested by the client), the client
MUST _Fail the WebSocket Connection_. (The parsing of this
header field to determine which extensions are requested is
discussed in Section 9.1.)
and this header field indicates the use of a subprotocol that was
not present in the client’s handshake (the server has indicated a
subprotocol not requested by the client), the client MUST _Fail
the WebSocket Connection_.
If the server’s response does not conform to the requirements for the
server’s handshake as defined in this section and in Section 4.2.2,
the client MUST _Fail the WebSocket Connection_.
Please note that according to [RFC2616], all header field names in
both HTTP requests and HTTP responses are case-insensitive.
If the server’s response is validated as provided for above, it is
said that _The WebSocket Connection is Established_ and that the
WebSocket Connection is in the OPEN state. The _Extensions In Use_
is defined to be a (possibly empty) string, the value of which is
equal to the value of the |Sec-WebSocket-Extensions| header field
supplied by the server’s handshake or the null value if that header
field was not present in the server’s handshake. The _Subprotocol In
Use_ is defined to be the value of the |Sec-WebSocket-Protocol|
header field in the server’s handshake or the null value if that
header field was not present in the server’s handshake.
Additionally, if any header fields in the server’s handshake indicate
that cookies should be set (as defined by [RFC6265]), these cookies
are referred to as _Cookies Set During the Server’s Opening
Handshake_.
这篇关于RFC6455-The WebSocket protocol 之四:Opening Handshake 4.1. Client Requirements的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!