(frameType wsOpCode, buf []byte, pos, rem int)
| 421 | } |
| 422 | |
| 423 | func (r *websocketReader) handleControlFrame(frameType wsOpCode, buf []byte, pos, rem int) (int, error) { |
| 424 | var payload []byte |
| 425 | var err error |
| 426 | |
| 427 | if rem > 0 { |
| 428 | payload, pos, err = wsGet(r.r, buf, pos, rem) |
| 429 | if err != nil { |
| 430 | return pos, err |
| 431 | } |
| 432 | } |
| 433 | switch frameType { |
| 434 | case wsCloseMessage: |
| 435 | status := wsCloseStatusNoStatusReceived |
| 436 | var body string |
| 437 | lp := len(payload) |
| 438 | // If there is a payload, the status is represented as a 2-byte |
| 439 | // unsigned integer (in network byte order). Then, there may be an |
| 440 | // optional body. |
| 441 | hasStatus, hasBody := lp >= wsCloseSatusSize, lp > wsCloseSatusSize |
| 442 | if hasStatus { |
| 443 | // Decode the status |
| 444 | status = int(binary.BigEndian.Uint16(payload[:wsCloseSatusSize])) |
| 445 | // Now if there is a body, capture it and make sure this is a valid UTF-8. |
| 446 | if hasBody { |
| 447 | body = string(payload[wsCloseSatusSize:]) |
| 448 | if !utf8.ValidString(body) { |
| 449 | // https://tools.ietf.org/html/rfc6455#section-5.5.1 |
| 450 | // If body is present, it must be a valid utf8 |
| 451 | status = wsCloseStatusInvalidPayloadData |
| 452 | body = "invalid utf8 body in close frame" |
| 453 | } |
| 454 | } |
| 455 | } |
| 456 | r.nc.wsEnqueueCloseMsg(r.nl, status, body) |
| 457 | // Return io.EOF so that readLoop will close the connection as client closed |
| 458 | // after processing pending buffers. |
| 459 | return pos, io.EOF |
| 460 | case wsPingMessage: |
| 461 | r.nc.wsEnqueueControlMsg(r.nl, wsPongMessage, payload) |
| 462 | case wsPongMessage: |
| 463 | // Nothing to do.. |
| 464 | } |
| 465 | return pos, nil |
| 466 | } |
| 467 | |
| 468 | func (w *websocketWriter) Write(p []byte) (int, error) { |
| 469 | if w.noMoreSend { |
no test coverage detected