예제 #1
0
 public void eot() {
   if (getReadyState() == READYSTATE.NOT_YET_CONNECTED) {
     closeConnection(CloseFrame.NEVER_CONNECTED, true);
   } else if (flushandclosestate) {
     closeConnection(closecode, closemessage, closedremotely);
   } else if (draft.getCloseHandshakeType() == CloseHandshakeType.NONE) {
     closeConnection(CloseFrame.NORMAL, true);
   } else if (draft.getCloseHandshakeType() == CloseHandshakeType.ONEWAY) {
     if (role == Role.SERVER) closeConnection(CloseFrame.ABNORMAL_CLOSE, true);
     else closeConnection(CloseFrame.NORMAL, true);
   } else {
     closeConnection(CloseFrame.ABNORMAL_CLOSE, true);
   }
 }
예제 #2
0
 /**
  * Send Binary data (plain bytes) to the other end.
  *
  * @throws IllegalArgumentException
  * @throws NotYetConnectedException
  */
 @Override
 public void send(ByteBuffer bytes)
     throws IllegalArgumentException, WebsocketNotConnectedException {
   if (bytes == null)
     throw new IllegalArgumentException("Cannot send 'null' data to a WebSocketImpl.");
   send(draft.createFrames(bytes, role == Role.CLIENT));
 }
예제 #3
0
  /**
   * @param remote Indicates who "generated" <code>code</code>.<br>
   *     <code>true</code> means that this endpoint received the <code>code</code> from the other
   *     endpoint.<br>
   *     false means this endpoint decided to send the given code,<br>
   *     <code>remote</code> may also be true if this endpoint started the closing handshake since
   *     the other endpoint may not simply echo the <code>code</code> but close the connection the
   *     same time this endpoint does do but with an other <code>code</code>. <br>
   */
  protected synchronized void closeConnection(int code, String message, boolean remote) {
    if (readystate == READYSTATE.CLOSED) {
      return;
    }

    if (key != null) {
      // key.attach( null ); //see issue #114
      key.cancel();
    }
    if (channel != null) {
      try {
        channel.close();
      } catch (IOException e) {
        wsl.onWebsocketError(this, e);
      }
    }
    try {
      this.wsl.onWebsocketClose(this, code, message, remote);
    } catch (RuntimeException e) {
      wsl.onWebsocketError(this, e);
    }
    if (draft != null) draft.reset();
    handshakerequest = null;

    readystate = READYSTATE.CLOSED;
    this.outQueue.clear();
  }
예제 #4
0
 public f(g g1, Draft draft)
 {
     l = false;
     m = com.mixpanel.android.java_websocket.WebSocket.READYSTATE.a;
     p = null;
     r = null;
     s = ByteBuffer.allocate(0);
     t = null;
     u = null;
     v = null;
     w = null;
     x = null;
     if (g1 == null || draft == null && q == com.mixpanel.android.java_websocket.WebSocket.Role.b)
     {
         throw new IllegalArgumentException("parameters must not be null");
     }
     h = new LinkedBlockingQueue();
     i = new LinkedBlockingQueue();
     n = g1;
     q = com.mixpanel.android.java_websocket.WebSocket.Role.a;
     if (draft != null)
     {
         p = draft.c();
     }
 }
예제 #5
0
 private void open(Handshakedata d) {
   if (DEBUG) System.out.println("open using draft: " + draft.getClass().getSimpleName());
   readystate = READYSTATE.OPEN;
   try {
     wsl.onWebsocketOpen(this, d);
   } catch (RuntimeException e) {
     wsl.onWebsocketError(this, e);
   }
 }
예제 #6
0
 /**
  * crates a websocket with client role
  *
  * @param socket may be unbound
  */
 public WebSocketImpl(WebSocketListener listener, Draft draft) {
   if (listener == null
       || (draft == null
           && role
               == Role
                   .SERVER)) // socket can be null because we want do be able to create the object
                             // without already having a bound channel
   throw new IllegalArgumentException("parameters must not be null");
   this.outQueue = new LinkedBlockingQueue<ByteBuffer>();
   inQueue = new LinkedBlockingQueue<ByteBuffer>();
   this.wsl = listener;
   this.role = Role.CLIENT;
   if (draft != null) this.draft = draft.copyInstance();
 }
예제 #7
0
  public void startHandshake(ClientHandshakeBuilder handshakedata)
      throws InvalidHandshakeException {
    assert (readystate != READYSTATE.CONNECTING) : "shall only be called once";

    // Store the Handshake Request we are about to send
    this.handshakerequest = draft.postProcessHandshakeRequestAsClient(handshakedata);

    resourceDescriptor = handshakedata.getResourceDescriptor();
    assert (resourceDescriptor != null);

    // Notify Listener
    try {
      wsl.onWebsocketHandshakeSentAsClient(this, this.handshakerequest);
    } catch (InvalidDataException e) {
      // Stop if the client code throws an exception
      throw new InvalidHandshakeException("Handshake data rejected by client.");
    } catch (RuntimeException e) {
      wsl.onWebsocketError(this, e);
      throw new InvalidHandshakeException("rejected because of" + e);
    }

    // Send
    write(draft.createHandshake(this.handshakerequest, role));
  }
예제 #8
0
  protected synchronized void flushAndClose(int code, String message, boolean remote) {
    if (flushandclosestate) {
      return;
    }
    closecode = code;
    closemessage = message;
    closedremotely = remote;

    flushandclosestate = true;

    wsl.onWriteDemand(
        this); // ensures that all outgoing frames are flushed before closing the connection
    try {
      wsl.onWebsocketClosing(this, code, message, remote);
    } catch (RuntimeException e) {
      wsl.onWebsocketError(this, e);
    }
    if (draft != null) draft.reset();
    handshakerequest = null;
  }
예제 #9
0
 private void close(int code, String message, boolean remote) {
   if (readystate != READYSTATE.CLOSING && readystate != READYSTATE.CLOSED) {
     if (readystate == READYSTATE.OPEN) {
       if (code == CloseFrame.ABNORMAL_CLOSE) {
         assert (remote == false);
         readystate = READYSTATE.CLOSING;
         flushAndClose(code, message, false);
         return;
       }
       if (draft.getCloseHandshakeType() != CloseHandshakeType.NONE) {
         try {
           if (!remote) {
             try {
               wsl.onWebsocketCloseInitiated(this, code, message);
             } catch (RuntimeException e) {
               wsl.onWebsocketError(this, e);
             }
           }
           sendFrame(new CloseFrameBuilder(code, message));
         } catch (InvalidDataException e) {
           wsl.onWebsocketError(this, e);
           flushAndClose(CloseFrame.ABNORMAL_CLOSE, "generated frame is invalid", false);
         }
       }
       flushAndClose(code, message, remote);
     } else if (code == CloseFrame.FLASHPOLICY) {
       assert (remote);
       flushAndClose(CloseFrame.FLASHPOLICY, message, true);
     } else {
       flushAndClose(CloseFrame.NEVER_CONNECTED, message, false);
     }
     if (code == CloseFrame.PROTOCOL_ERROR) // this endpoint found a PROTOCOL_ERROR
     flushAndClose(code, message, remote);
     readystate = READYSTATE.CLOSING;
     tmpHandshakeBytes = null;
     return;
   }
 }
예제 #10
0
    private void c(int i1, String s1, boolean flag)
    {
label0:
        {
            if (m != WebSocket.READYSTATE.d && m != WebSocket.READYSTATE.e)
            {
                if (m != com.mixpanel.android.java_websocket.WebSocket.READYSTATE.c)
                {
                    break MISSING_BLOCK_LABEL_191;
                }
                if (i1 != 1006)
                {
                    break label0;
                }
                if (!k && flag)
                {
                    throw new AssertionError();
                }
                m = WebSocket.READYSTATE.d;
                b(i1, s1, false);
            }
            return;
        }
        if (p.b() == com.mixpanel.android.java_websocket.drafts.Draft.CloseHandshakeType.a) goto _L2; else goto _L1
예제 #11
0
 @Override
 public void sendFrame(Framedata framedata) {
   if (DEBUG) System.out.println("send frame: " + framedata);
   write(draft.createBinaryFrame(framedata));
 }
예제 #12
0
 @Override
 public void sendFragmentedFrame(Opcode op, ByteBuffer buffer, boolean fin) {
   send(draft.continuousFrame(op, buffer, fin));
 }
예제 #13
0
 /**
  * Send Text data to the other end.
  *
  * @throws IllegalArgumentException
  * @throws NotYetConnectedException
  */
 @Override
 public void send(String text) throws WebsocketNotConnectedException {
   if (text == null)
     throw new IllegalArgumentException("Cannot send 'null' data to a WebSocketImpl.");
   send(draft.createFrames(text, role == Role.CLIENT));
 }
예제 #14
0
  private void decodeFrames(ByteBuffer socketBuffer) {

    List<Framedata> frames;
    try {
      frames = draft.translateFrame(socketBuffer);
      for (Framedata f : frames) {
        if (DEBUG) System.out.println("matched frame: " + f);
        Opcode curop = f.getOpcode();
        boolean fin = f.isFin();

        if (curop == Opcode.CLOSING) {
          int code = CloseFrame.NOCODE;
          String reason = "";
          if (f instanceof CloseFrame) {
            CloseFrame cf = (CloseFrame) f;
            code = cf.getCloseCode();
            reason = cf.getMessage();
          }
          if (readystate == READYSTATE.CLOSING) {
            // complete the close handshake by disconnecting
            closeConnection(code, reason, true);
          } else {
            // echo close handshake
            if (draft.getCloseHandshakeType() == CloseHandshakeType.TWOWAY)
              close(code, reason, true);
            else flushAndClose(code, reason, false);
          }
          continue;
        } else if (curop == Opcode.PING) {
          wsl.onWebsocketPing(this, f);
          continue;
        } else if (curop == Opcode.PONG) {
          wsl.onWebsocketPong(this, f);
          continue;
        } else if (!fin || curop == Opcode.CONTINUOUS) {
          if (curop != Opcode.CONTINUOUS) {
            if (current_continuous_frame_opcode != null)
              throw new InvalidDataException(
                  CloseFrame.PROTOCOL_ERROR, "Previous continuous frame sequence not completed.");
            current_continuous_frame_opcode = curop;
          } else if (fin) {
            if (current_continuous_frame_opcode == null)
              throw new InvalidDataException(
                  CloseFrame.PROTOCOL_ERROR, "Continuous frame sequence was not started.");
            current_continuous_frame_opcode = null;
          } else if (current_continuous_frame_opcode == null) {
            throw new InvalidDataException(
                CloseFrame.PROTOCOL_ERROR, "Continuous frame sequence was not started.");
          }
          try {
            wsl.onWebsocketMessageFragment(this, f);
          } catch (RuntimeException e) {
            wsl.onWebsocketError(this, e);
          }

        } else if (current_continuous_frame_opcode != null) {
          throw new InvalidDataException(
              CloseFrame.PROTOCOL_ERROR, "Continuous frame sequence not completed.");
        } else if (curop == Opcode.TEXT) {
          try {
            wsl.onWebsocketMessage(this, Charsetfunctions.stringUtf8(f.getPayloadData()));
          } catch (RuntimeException e) {
            wsl.onWebsocketError(this, e);
          }
        } else if (curop == Opcode.BINARY) {
          try {
            wsl.onWebsocketMessage(this, f.getPayloadData());
          } catch (RuntimeException e) {
            wsl.onWebsocketError(this, e);
          }
        } else {
          throw new InvalidDataException(
              CloseFrame.PROTOCOL_ERROR, "non control or continious frame expected");
        }
      }
    } catch (InvalidDataException e1) {
      wsl.onWebsocketError(this, e1);
      close(e1);
      return;
    }
  }
예제 #15
0
  /**
   * Returns whether the handshake phase has is completed. In case of a broken handshake this will
   * be never the case.
   */
  private boolean decodeHandshake(ByteBuffer socketBufferNew) {
    ByteBuffer socketBuffer;
    if (tmpHandshakeBytes.capacity() == 0) {
      socketBuffer = socketBufferNew;
    } else {
      if (tmpHandshakeBytes.remaining() < socketBufferNew.remaining()) {
        ByteBuffer buf =
            ByteBuffer.allocate(tmpHandshakeBytes.capacity() + socketBufferNew.remaining());
        tmpHandshakeBytes.flip();
        buf.put(tmpHandshakeBytes);
        tmpHandshakeBytes = buf;
      }

      tmpHandshakeBytes.put(socketBufferNew);
      tmpHandshakeBytes.flip();
      socketBuffer = tmpHandshakeBytes;
    }
    socketBuffer.mark();
    try {
      if (draft == null) {
        HandshakeState isflashedgecase = isFlashEdgeCase(socketBuffer);
        if (isflashedgecase == HandshakeState.MATCHED) {
          try {
            write(ByteBuffer.wrap(Charsetfunctions.utf8Bytes(wsl.getFlashPolicy(this))));
            close(CloseFrame.FLASHPOLICY, "");
          } catch (InvalidDataException e) {
            close(
                CloseFrame.ABNORMAL_CLOSE,
                "remote peer closed connection before flashpolicy could be transmitted",
                true);
          }
          return false;
        }
      }
      HandshakeState handshakestate = null;

      try {
        if (role == Role.SERVER) {
          if (draft == null) {
            for (Draft d : knownDrafts) {
              d = d.copyInstance();
              try {
                d.setParseMode(role);
                socketBuffer.reset();
                Handshakedata tmphandshake = d.translateHandshake(socketBuffer);
                if (tmphandshake instanceof ClientHandshake == false) {
                  flushAndClose(CloseFrame.PROTOCOL_ERROR, "wrong http function", false);
                  return false;
                }
                ClientHandshake handshake = (ClientHandshake) tmphandshake;
                handshakestate = d.acceptHandshakeAsServer(handshake);
                if (handshakestate == HandshakeState.MATCHED) {
                  resourceDescriptor = handshake.getResourceDescriptor();
                  ServerHandshakeBuilder response;
                  try {
                    response = wsl.onWebsocketHandshakeReceivedAsServer(this, d, handshake);
                  } catch (InvalidDataException e) {
                    flushAndClose(e.getCloseCode(), e.getMessage(), false);
                    return false;
                  } catch (RuntimeException e) {
                    wsl.onWebsocketError(this, e);
                    flushAndClose(CloseFrame.NEVER_CONNECTED, e.getMessage(), false);
                    return false;
                  }
                  write(
                      d.createHandshake(
                          d.postProcessHandshakeResponseAsServer(handshake, response), role));
                  draft = d;
                  open(handshake);
                  return true;
                }
              } catch (InvalidHandshakeException e) {
                // go on with an other draft
              }
            }
            if (draft == null) {
              close(CloseFrame.PROTOCOL_ERROR, "no draft matches");
            }
            return false;
          } else {
            // special case for multiple step handshakes
            Handshakedata tmphandshake = draft.translateHandshake(socketBuffer);
            if (tmphandshake instanceof ClientHandshake == false) {
              flushAndClose(CloseFrame.PROTOCOL_ERROR, "wrong http function", false);
              return false;
            }
            ClientHandshake handshake = (ClientHandshake) tmphandshake;
            handshakestate = draft.acceptHandshakeAsServer(handshake);

            if (handshakestate == HandshakeState.MATCHED) {
              open(handshake);
              return true;
            } else {
              close(CloseFrame.PROTOCOL_ERROR, "the handshake did finaly not match");
            }
            return false;
          }
        } else if (role == Role.CLIENT) {
          draft.setParseMode(role);
          Handshakedata tmphandshake = draft.translateHandshake(socketBuffer);
          if (tmphandshake instanceof ServerHandshake == false) {
            flushAndClose(CloseFrame.PROTOCOL_ERROR, "wrong http function", false);
            return false;
          }
          ServerHandshake handshake = (ServerHandshake) tmphandshake;
          handshakestate = draft.acceptHandshakeAsClient(handshakerequest, handshake);
          if (handshakestate == HandshakeState.MATCHED) {
            try {
              wsl.onWebsocketHandshakeReceivedAsClient(this, handshakerequest, handshake);
            } catch (InvalidDataException e) {
              flushAndClose(e.getCloseCode(), e.getMessage(), false);
              return false;
            } catch (RuntimeException e) {
              wsl.onWebsocketError(this, e);
              flushAndClose(CloseFrame.NEVER_CONNECTED, e.getMessage(), false);
              return false;
            }
            open(handshake);
            return true;
          } else {
            close(CloseFrame.PROTOCOL_ERROR, "draft " + draft + " refuses handshake");
          }
        }
      } catch (InvalidHandshakeException e) {
        close(e);
      }
    } catch (IncompleteHandshakeException e) {
      if (tmpHandshakeBytes.capacity() == 0) {
        socketBuffer.reset();
        int newsize = e.getPreferedSize();
        if (newsize == 0) {
          newsize = socketBuffer.capacity() + 16;
        } else {
          assert (e.getPreferedSize() >= socketBuffer.remaining());
        }
        tmpHandshakeBytes = ByteBuffer.allocate(newsize);

        tmpHandshakeBytes.put(socketBufferNew);
        // tmpHandshakeBytes.flip();
      } else {
        tmpHandshakeBytes.position(tmpHandshakeBytes.limit());
        tmpHandshakeBytes.limit(tmpHandshakeBytes.capacity());
      }
    }
    return false;
  }
예제 #16
0
 private void a(com.mixpanel.android.java_websocket.b.f f1)
 {
     if (d)
     {
         System.out.println((new StringBuilder()).append("open using draft: ").append(p.getClass().getSimpleName()).toString());
     }
     m = com.mixpanel.android.java_websocket.WebSocket.READYSTATE.c;
     try
     {
         n.a(this, f1);
         return;
     }
     // Misplaced declaration of an exception variable
     catch (com.mixpanel.android.java_websocket.b.f f1)
     {
         n.a(this, f1);
     }
 }