예제 #1
0
int nghttp2_submit_window_update(nghttp2_session *session, uint8_t flags,
                                 int32_t stream_id,
                                 int32_t window_size_increment) {
  int rv;
  nghttp2_stream *stream = 0;
  if (window_size_increment == 0) {
    return 0;
  }
  flags = 0;
  if (stream_id == 0) {
    rv = nghttp2_adjust_local_window_size(
        &session->local_window_size, &session->recv_window_size,
        &session->recv_reduction, &window_size_increment);
    if (rv != 0) {
      return rv;
    }
  } else {
    stream = nghttp2_session_get_stream(session, stream_id);
    if (!stream) {
      return 0;
    }

    rv = nghttp2_adjust_local_window_size(
        &stream->local_window_size, &stream->recv_window_size,
        &stream->recv_reduction, &window_size_increment);
    if (rv != 0) {
      return rv;
    }
  }

  if (window_size_increment > 0) {
    if (stream_id == 0) {
      session->consumed_size =
          nghttp2_max(0, session->consumed_size - window_size_increment);
    } else {
      stream->consumed_size =
          nghttp2_max(0, stream->consumed_size - window_size_increment);
    }

    return nghttp2_session_add_window_update(session, flags, stream_id,
                                             window_size_increment);
  }
  return 0;
}
예제 #2
0
void test_nghttp2_adjust_local_window_size(void)
{
  int32_t local_window_size = 100;
  int32_t recv_window_size = 50;
  int32_t recv_reduction = 0;
  int32_t delta;

  delta = 0;
  CU_ASSERT(0 == nghttp2_adjust_local_window_size(&local_window_size,
                                                  &recv_window_size,
                                                  &recv_reduction,
                                                  &delta));
  CU_ASSERT(100 == local_window_size);
  CU_ASSERT(50 == recv_window_size);
  CU_ASSERT(0 == recv_reduction);
  CU_ASSERT(0 == delta);

  delta = 49;
  CU_ASSERT(0 == nghttp2_adjust_local_window_size(&local_window_size,
                                                  &recv_window_size,
                                                  &recv_reduction,
                                                  &delta));
  CU_ASSERT(100 == local_window_size);
  CU_ASSERT(1 == recv_window_size);
  CU_ASSERT(0 == recv_reduction);
  CU_ASSERT(49 == delta);

  delta = 1;
  CU_ASSERT(0 == nghttp2_adjust_local_window_size(&local_window_size,
                                                  &recv_window_size,
                                                  &recv_reduction,
                                                  &delta));
  CU_ASSERT(100 == local_window_size);
  CU_ASSERT(0 == recv_window_size);
  CU_ASSERT(0 == recv_reduction);
  CU_ASSERT(1 == delta);

  delta = 1;
  CU_ASSERT(0 == nghttp2_adjust_local_window_size(&local_window_size,
                                                  &recv_window_size,
                                                  &recv_reduction,
                                                  &delta));
  CU_ASSERT(101 == local_window_size);
  CU_ASSERT(0 == recv_window_size);
  CU_ASSERT(0 == recv_reduction);
  CU_ASSERT(1 == delta);

  delta = -1;
  CU_ASSERT(0 == nghttp2_adjust_local_window_size(&local_window_size,
                                                  &recv_window_size,
                                                  &recv_reduction,
                                                  &delta));
  CU_ASSERT(100 == local_window_size);
  CU_ASSERT(-1 == recv_window_size);
  CU_ASSERT(1 == recv_reduction);
  CU_ASSERT(0 == delta);

  delta = 1;
  CU_ASSERT(0 == nghttp2_adjust_local_window_size(&local_window_size,
                                                  &recv_window_size,
                                                  &recv_reduction,
                                                  &delta));
  CU_ASSERT(101 == local_window_size);
  CU_ASSERT(0 == recv_window_size);
  CU_ASSERT(0 == recv_reduction);
  CU_ASSERT(0 == delta);

  delta = 100;
  CU_ASSERT(0 == nghttp2_adjust_local_window_size(&local_window_size,
                                                  &recv_window_size,
                                                  &recv_reduction,
                                                  &delta));
  CU_ASSERT(201 == local_window_size);
  CU_ASSERT(0 == recv_window_size);
  CU_ASSERT(0 == recv_reduction);
  CU_ASSERT(100 == delta);

  delta = -3;
  CU_ASSERT(0 == nghttp2_adjust_local_window_size(&local_window_size,
                                                  &recv_window_size,
                                                  &recv_reduction,
                                                  &delta));
  CU_ASSERT(198 == local_window_size);
  CU_ASSERT(-3 == recv_window_size);
  CU_ASSERT(3 == recv_reduction);
  CU_ASSERT(0 == delta);

  recv_window_size += 3;

  delta = 3;
  CU_ASSERT(0 == nghttp2_adjust_local_window_size(&local_window_size,
                                                  &recv_window_size,
                                                  &recv_reduction,
                                                  &delta));
  CU_ASSERT(201 == local_window_size);
  CU_ASSERT(3 == recv_window_size);
  CU_ASSERT(0 == recv_reduction);
  CU_ASSERT(0 == delta);

  local_window_size = 100;
  recv_window_size = 50;
  recv_reduction = 0;
  delta = INT32_MAX;
  CU_ASSERT(NGHTTP2_ERR_FLOW_CONTROL ==
            nghttp2_adjust_local_window_size(&local_window_size,
                                             &recv_window_size,
                                             &recv_reduction,
                                             &delta));
  CU_ASSERT(100 == local_window_size);
  CU_ASSERT(50 == recv_window_size);
  CU_ASSERT(0 == recv_reduction);
  CU_ASSERT(INT32_MAX == delta);

  delta = INT32_MIN;
  CU_ASSERT(NGHTTP2_ERR_FLOW_CONTROL ==
            nghttp2_adjust_local_window_size(&local_window_size,
                                             &recv_window_size,
                                             &recv_reduction,
                                             &delta));
  CU_ASSERT(100 == local_window_size);
  CU_ASSERT(50 == recv_window_size);
  CU_ASSERT(0 == recv_reduction);
  CU_ASSERT(INT32_MIN == delta);
}
예제 #3
0
int nghttp2_session_set_local_window_size(nghttp2_session *session,
                                          uint8_t flags, int32_t stream_id,
                                          int32_t window_size) {
  int32_t window_size_increment;
  nghttp2_stream *stream;
  int rv;

  if (window_size < 0) {
    return NGHTTP2_ERR_INVALID_ARGUMENT;
  }

  flags = 0;

  if (stream_id == 0) {
    window_size_increment = window_size - session->local_window_size;

    if (window_size_increment == 0) {
      return 0;
    }

    if (window_size_increment < 0) {
      return nghttp2_adjust_local_window_size(
          &session->local_window_size, &session->recv_window_size,
          &session->recv_reduction, &window_size_increment);
    }

    rv = nghttp2_increase_local_window_size(
        &session->local_window_size, &session->recv_window_size,
        &session->recv_reduction, &window_size_increment);

    if (rv != 0) {
      return rv;
    }
  } else {
    stream = nghttp2_session_get_stream(session, stream_id);

    if (stream == NULL) {
      return 0;
    }

    window_size_increment = window_size - stream->local_window_size;

    if (window_size_increment == 0) {
      return 0;
    }

    if (window_size_increment < 0) {
      return nghttp2_adjust_local_window_size(
          &stream->local_window_size, &stream->recv_window_size,
          &stream->recv_reduction, &window_size_increment);
    }

    rv = nghttp2_increase_local_window_size(
        &stream->local_window_size, &stream->recv_window_size,
        &stream->recv_reduction, &window_size_increment);

    if (rv != 0) {
      return rv;
    }
  }

  if (window_size_increment > 0) {
    return nghttp2_session_add_window_update(session, flags, stream_id,
                                             window_size_increment);
  }

  return 0;
}