Пример #1
0
 /**
  * Eagerly reads {@code byteCount} bytes from the source before launching a background task to
  * process the data. This avoids corrupting the stream.
  */
 private void pushDataLater(
     final int streamId,
     final BufferedSource source,
     final int byteCount,
     final boolean inFinished)
     throws IOException {
   final Buffer buffer = new Buffer();
   source.require(byteCount); // Eagerly read the frame before firing client thread.
   source.read(buffer, byteCount);
   if (buffer.size() != byteCount) throw new IOException(buffer.size() + " != " + byteCount);
   pushExecutor.execute(
       new NamedRunnable("OkHttp %s Push Data[%s]", hostname, streamId) {
         @Override
         public void execute() {
           try {
             boolean cancel = pushObserver.onData(streamId, buffer, byteCount, inFinished);
             if (cancel) frameWriter.rstStream(streamId, ErrorCode.CANCEL);
             if (cancel || inFinished) {
               synchronized (FramedConnection.this) {
                 currentPushRequests.remove(streamId);
               }
             }
           } catch (IOException ignored) {
           }
         }
       });
 }
Пример #2
0
    @Override
    public boolean nextFrame(Handler handler) throws IOException {
      try {
        source.require(9); // Frame header size
      } catch (IOException e) {
        return false; // This might be a normal socket close.
      }

      /*  0                   1                   2                   3
       *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
       * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       * |                 Length (24)                   |
       * +---------------+---------------+---------------+
       * |   Type (8)    |   Flags (8)   |
       * +-+-+-----------+---------------+-------------------------------+
       * |R|                 Stream Identifier (31)                      |
       * +=+=============================================================+
       * |                   Frame Payload (0...)                      ...
       * +---------------------------------------------------------------+
       */
      int length = readMedium(source);
      if (length < 0 || length > INITIAL_MAX_FRAME_SIZE) {
        throw ioException("FRAME_SIZE_ERROR: %s", length);
      }
      byte type = (byte) (source.readByte() & 0xff);
      byte flags = (byte) (source.readByte() & 0xff);
      int streamId = (source.readInt() & 0x7fffffff); // Ignore reserved bit.
      if (logger.isLoggable(FINE)) logger.fine(formatHeader(true, streamId, length, type, flags));

      switch (type) {
        case TYPE_DATA:
          readData(handler, length, flags, streamId);
          break;

        case TYPE_HEADERS:
          readHeaders(handler, length, flags, streamId);
          break;

        case TYPE_PRIORITY:
          readPriority(handler, length, flags, streamId);
          break;

        case TYPE_RST_STREAM:
          readRstStream(handler, length, flags, streamId);
          break;

        case TYPE_SETTINGS:
          readSettings(handler, length, flags, streamId);
          break;

        case TYPE_PUSH_PROMISE:
          readPushPromise(handler, length, flags, streamId);
          break;

        case TYPE_PING:
          readPing(handler, length, flags, streamId);
          break;

        case TYPE_GOAWAY:
          readGoAway(handler, length, flags, streamId);
          break;

        case TYPE_WINDOW_UPDATE:
          readWindowUpdate(handler, length, flags, streamId);
          break;

        default:
          // Implementations MUST discard frames that have unknown or unsupported types.
          source.skip(length);
      }
      return true;
    }