luvit / lit

Toolkit for developing, sharing, and running luvit/lua programs and libraries.
http://lit.luvit.io/
Apache License 2.0
245 stars 58 forks source link

Exposing WebSocket close messages #206

Closed SinisterRectus closed 7 years ago

SinisterRectus commented 7 years ago

The WebSocket standard describes a close frame, where a final message may be present.

5.5.1.  Close

   The Close frame contains an opcode of 0x8.

   The Close frame MAY contain a body (the "Application data" portion of
   the frame) that indicates a reason for closing, such as an endpoint
   shutting down, an endpoint having received a frame too large, or an
   endpoint having received a frame that does not conform to the format
   expected by the endpoint.  If there is a body, the first two bytes of
   the body MUST be a 2-byte unsigned integer (in network byte order)
   representing a status code with value /code/ defined in Section 7.4.
   Following the 2-byte integer, the body MAY contain UTF-8-encoded data
   with value /reason/, the interpretation of which is not defined by
   this specification.  This data is not necessarily human readable but
   may be useful for debugging or passing information relevant to the
   script that opened the connection.  As the data is not guaranteed to
   be human readable, clients MUST NOT show it to end users.

Here is an example close frame:

{ payload = '\015\162Error while decoding payload.', fin = true, mask = false, opcode = 8, rsv3 = false, rsv1 = false, len = 31, rsv2 = false }

This close message is not exposed by coro-websocket.

  local function read()
    while true do
      local message = rawRead()
      if not message then
        return cleanup()
      end
      if message.opcode < 8 then
        return message
      end
      if not closeSent then
        if message.opcode == 8 then
          write {
            opcode = 8,
            payload = message.payload
          }
        elseif message.opcode == 9 then
          write {
            opcode = 10,
            payload = message.payload
          }
        end
      end
    end
  end

I would like to expose this close message, but I don't know a good way to do it. Simply putting return message after the client writes the close response does not work, presumably due to coroutine yielding.

Edit: Apparently it does work.

SinisterRectus commented 7 years ago

See #207.