src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/websocket/FrameConsumer.java
branchhttp-client-branch
changeset 56048 f9b6016727b5
parent 48083 b1c1b4ef4be2
child 56058 a02d0098c630
equal deleted inserted replaced
56047:2e86bda80f79 56048:f9b6016727b5
     1 /*
     1 /*
     2  * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     7  * published by the Free Software Foundation.  Oracle designates this
    24  */
    24  */
    25 
    25 
    26 package jdk.incubator.http.internal.websocket;
    26 package jdk.incubator.http.internal.websocket;
    27 
    27 
    28 import jdk.incubator.http.WebSocket.MessagePart;
    28 import jdk.incubator.http.WebSocket.MessagePart;
    29 import jdk.incubator.http.internal.common.Log;
       
    30 import jdk.incubator.http.internal.websocket.Frame.Opcode;
    29 import jdk.incubator.http.internal.websocket.Frame.Opcode;
    31 
    30 
    32 import java.nio.ByteBuffer;
    31 import java.nio.ByteBuffer;
    33 import java.nio.CharBuffer;
    32 import java.nio.CharBuffer;
    34 import java.nio.charset.CharacterCodingException;
    33 import java.nio.charset.CharacterCodingException;
    48  * form a message.
    47  * form a message.
    49  */
    48  */
    50 /* Non-final for testing purposes only */
    49 /* Non-final for testing purposes only */
    51 class FrameConsumer implements Frame.Consumer {
    50 class FrameConsumer implements Frame.Consumer {
    52 
    51 
       
    52     private final static boolean DEBUG = true;
    53     private final MessageStreamConsumer output;
    53     private final MessageStreamConsumer output;
    54     private final UTF8AccumulatingDecoder decoder = new UTF8AccumulatingDecoder();
    54     private final UTF8AccumulatingDecoder decoder = new UTF8AccumulatingDecoder();
    55     private boolean fin;
    55     private boolean fin;
    56     private Opcode opcode, originatingOpcode;
    56     private Opcode opcode, originatingOpcode;
    57     private MessagePart part = MessagePart.WHOLE;
    57     private MessagePart part = MessagePart.WHOLE;
    68         return output;
    68         return output;
    69     }
    69     }
    70 
    70 
    71     @Override
    71     @Override
    72     public void fin(boolean value) {
    72     public void fin(boolean value) {
    73         Log.logTrace("Reading fin: {0}", value);
    73         if (DEBUG) {
       
    74             System.out.printf("Reading fin: %s%n", value);
       
    75         }
    74         fin = value;
    76         fin = value;
    75     }
    77     }
    76 
    78 
    77     @Override
    79     @Override
    78     public void rsv1(boolean value) {
    80     public void rsv1(boolean value) {
    79         Log.logTrace("Reading rsv1: {0}", value);
    81         if (DEBUG) {
       
    82             System.out.printf("Reading rsv1: %s%n", value);
       
    83         }
    80         if (value) {
    84         if (value) {
    81             throw new FailWebSocketException("Unexpected rsv1 bit");
    85             throw new FailWebSocketException("Unexpected rsv1 bit");
    82         }
    86         }
    83     }
    87     }
    84 
    88 
    85     @Override
    89     @Override
    86     public void rsv2(boolean value) {
    90     public void rsv2(boolean value) {
    87         Log.logTrace("Reading rsv2: {0}", value);
    91         if (DEBUG) {
       
    92             System.out.printf("Reading rsv2: %s%n", value);
       
    93         }
    88         if (value) {
    94         if (value) {
    89             throw new FailWebSocketException("Unexpected rsv2 bit");
    95             throw new FailWebSocketException("Unexpected rsv2 bit");
    90         }
    96         }
    91     }
    97     }
    92 
    98 
    93     @Override
    99     @Override
    94     public void rsv3(boolean value) {
   100     public void rsv3(boolean value) {
    95         Log.logTrace("Reading rsv3: {0}", value);
   101         if (DEBUG) {
       
   102             System.out.printf("Reading rsv3: %s%n", value);
       
   103         }
    96         if (value) {
   104         if (value) {
    97             throw new FailWebSocketException("Unexpected rsv3 bit");
   105             throw new FailWebSocketException("Unexpected rsv3 bit");
    98         }
   106         }
    99     }
   107     }
   100 
   108 
   101     @Override
   109     @Override
   102     public void opcode(Opcode v) {
   110     public void opcode(Opcode v) {
   103         Log.logTrace("Reading opcode: {0}", v);
   111         if (DEBUG) {
       
   112             System.out.printf("Reading opcode: %s%n", v);
       
   113         }
   104         if (v == Opcode.PING || v == Opcode.PONG || v == Opcode.CLOSE) {
   114         if (v == Opcode.PING || v == Opcode.PONG || v == Opcode.CLOSE) {
   105             if (!fin) {
   115             if (!fin) {
   106                 throw new FailWebSocketException("Fragmented control frame  " + v);
   116                 throw new FailWebSocketException("Fragmented control frame  " + v);
   107             }
   117             }
   108             opcode = v;
   118             opcode = v;
   120                 throw new FailWebSocketException(
   130                 throw new FailWebSocketException(
   121                         format("Unexpected frame %s (fin=%s)", v, fin));
   131                         format("Unexpected frame %s (fin=%s)", v, fin));
   122             }
   132             }
   123             opcode = v;
   133             opcode = v;
   124         } else {
   134         } else {
   125             throw new FailWebSocketException("Unknown opcode " + v);
   135             throw new FailWebSocketException("Unexpected opcode " + v);
   126         }
   136         }
   127     }
   137     }
   128 
   138 
   129     @Override
   139     @Override
   130     public void mask(boolean value) {
   140     public void mask(boolean value) {
   131         Log.logTrace("Reading mask: {0}", value);
   141         if (DEBUG) {
       
   142             System.out.printf("Reading mask: %s%n", value);
       
   143         }
   132         if (value) {
   144         if (value) {
   133             throw new FailWebSocketException("Masked frame received");
   145             throw new FailWebSocketException("Masked frame received");
   134         }
   146         }
   135     }
   147     }
   136 
   148 
   137     @Override
   149     @Override
   138     public void payloadLen(long value) {
   150     public void payloadLen(long value) {
   139         Log.logTrace("Reading payloadLen: {0}", value);
   151         if (DEBUG) {
       
   152             System.out.printf("Reading payloadLen: %s%n", value);
       
   153         }
   140         if (opcode.isControl()) {
   154         if (opcode.isControl()) {
   141             if (value > 125) {
   155             if (value > 125) {
   142                 throw new FailWebSocketException(
   156                 throw new FailWebSocketException(
   143                         format("%s's payload length %s", opcode, value));
   157                         format("%s's payload length %s", opcode, value));
   144             }
   158             }
   162         throw new InternalError();
   176         throw new InternalError();
   163     }
   177     }
   164 
   178 
   165     @Override
   179     @Override
   166     public void payloadData(ByteBuffer data) {
   180     public void payloadData(ByteBuffer data) {
   167         Log.logTrace("Reading payloadData: data={0}", data);
   181         if (DEBUG) {
       
   182             System.out.printf("Reading payloadData: %s%n", data);
       
   183         }
   168         unconsumedPayloadLen -= data.remaining();
   184         unconsumedPayloadLen -= data.remaining();
   169         boolean isLast = unconsumedPayloadLen == 0;
   185         boolean isLast = unconsumedPayloadLen == 0;
   170         if (opcode.isControl()) {
   186         if (opcode.isControl()) {
   171             if (binaryData != null) { // An intermediate or the last chunk
   187             if (binaryData != null) { // An intermediate or the last chunk
   172                 binaryData.put(data);
   188                 binaryData.put(data);
   205         }
   221         }
   206     }
   222     }
   207 
   223 
   208     @Override
   224     @Override
   209     public void endFrame() {
   225     public void endFrame() {
       
   226         if (DEBUG) {
       
   227             System.out.println("End frame");
       
   228         }
   210         if (opcode.isControl()) {
   229         if (opcode.isControl()) {
   211             binaryData.flip();
   230             binaryData.flip();
   212         }
   231         }
   213         switch (opcode) {
   232         switch (opcode) {
   214             case CLOSE:
   233             case CLOSE: