Ejemplo n.º 1
0
static void test_small_data_framing(void) {
  grpc_sopb_add_no_op(&g_sopb);
  verify_sopb(10, 0, 0, "");

  grpc_sopb_add_flow_ctl_cb(&g_sopb, assert_result_ok, NULL);
  grpc_sopb_add_slice(&g_sopb, create_test_slice(3));
  verify_sopb(10, 0, 3, "000003 0000 deadbeef 000102");

  grpc_sopb_add_slice(&g_sopb, create_test_slice(4));
  verify_sopb(10, 0, 4, "000004 0000 deadbeef 00010203");

  grpc_sopb_add_slice(&g_sopb, create_test_slice(3));
  grpc_sopb_add_slice(&g_sopb, create_test_slice(4));
  verify_sopb(10, 0, 7, "000007 0000 deadbeef 000102 00010203");

  grpc_sopb_add_slice(&g_sopb, create_test_slice(0));
  grpc_sopb_add_slice(&g_sopb, create_test_slice(0));
  grpc_sopb_add_slice(&g_sopb, create_test_slice(0));
  grpc_sopb_add_slice(&g_sopb, create_test_slice(0));
  grpc_sopb_add_slice(&g_sopb, create_test_slice(3));
  verify_sopb(10, 0, 3, "000003 0000 deadbeef 000102");

  verify_sopb(10, 1, 0, "000000 0001 deadbeef");

  grpc_sopb_add_begin_message(&g_sopb, 255, 0);
  verify_sopb(10, 0, 5, "000005 0000 deadbeef 00000000ff");
}
Ejemplo n.º 2
0
/* Copy the contents of a byte buffer into stream ops */
static void copy_byte_buffer_to_stream_ops(grpc_byte_buffer *byte_buffer,
                                           grpc_stream_op_buffer *sopb) {
  size_t i;

  switch (byte_buffer->type) {
    case GRPC_BB_SLICE_BUFFER:
      for (i = 0; i < byte_buffer->data.slice_buffer.count; i++) {
        gpr_slice slice = byte_buffer->data.slice_buffer.slices[i];
        gpr_slice_ref(slice);
        grpc_sopb_add_slice(sopb, slice);
      }
      break;
  }
}
Ejemplo n.º 3
0
/** Assembles a new grpc_stream_op_buffer with the compressed slices, modifying
 * the associated GRPC_OP_BEGIN_MESSAGE accordingly (new compressed length,
 * flags indicating compression is in effect) and replaces \a send_ops with it.
 * */
static void finish_compressed_sopb(grpc_stream_op_buffer *send_ops,
                                   grpc_call_element *elem) {
  size_t i;
  call_data *calld = elem->call_data;
  int new_slices_added = 0; /* GPR_FALSE */
  grpc_metadata_batch metadata;
  grpc_stream_op_buffer new_send_ops;
  grpc_sopb_init(&new_send_ops);

  for (i = 0; i < send_ops->nops; i++) {
    grpc_stream_op *sop = &send_ops->ops[i];
    switch (sop->type) {
      case GRPC_OP_BEGIN_MESSAGE:
        GPR_ASSERT(calld->slices.length <= GPR_UINT32_MAX);
        grpc_sopb_add_begin_message(
            &new_send_ops, (gpr_uint32)calld->slices.length,
            sop->data.begin_message.flags | GRPC_WRITE_INTERNAL_COMPRESS);
        break;
      case GRPC_OP_SLICE:
        /* Once we reach the slices section of the original buffer, simply add
         * all the new (compressed) slices. We obviously want to do this only
         * once, hence the "new_slices_added" guard. */
        if (!new_slices_added) {
          size_t j;
          for (j = 0; j < calld->slices.count; ++j) {
            grpc_sopb_add_slice(&new_send_ops,
                                gpr_slice_ref(calld->slices.slices[j]));
          }
          new_slices_added = 1; /* GPR_TRUE */
        }
        break;
      case GRPC_OP_METADATA:
        /* move the metadata to the new buffer. */
        grpc_metadata_batch_move(&metadata, &sop->data.metadata);
        grpc_sopb_add_metadata(&new_send_ops, metadata);
        break;
      case GRPC_NO_OP:
        break;
    }
  }
  grpc_sopb_swap(send_ops, &new_send_ops);
  grpc_sopb_destroy(&new_send_ops);
}
Ejemplo n.º 4
0
grpc_chttp2_parse_error grpc_chttp2_data_parser_parse(
    void *parser, grpc_chttp2_transport_parsing *transport_parsing,
    grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last) {
  gpr_uint8 *const beg = GPR_SLICE_START_PTR(slice);
  gpr_uint8 *const end = GPR_SLICE_END_PTR(slice);
  gpr_uint8 *cur = beg;
  grpc_chttp2_data_parser *p = parser;
  gpr_uint32 message_flags = 0;

  if (is_last && p->is_last_frame) {
    stream_parsing->received_close = 1;
  }

  if (cur == end) {
    return GRPC_CHTTP2_PARSE_OK;
  }

  switch (p->state) {
  fh_0:
    case GRPC_CHTTP2_DATA_FH_0:
      p->frame_type = *cur;
      switch (p->frame_type) {
        case 0:
          p->is_frame_compressed = 0; /* GPR_FALSE */
          break;
        case 1:
          p->is_frame_compressed = 1; /* GPR_TRUE */
          break;
        default:
          gpr_log(GPR_ERROR, "Bad GRPC frame type 0x%02x", p->frame_type);
          return GRPC_CHTTP2_STREAM_ERROR;
      }
      if (++cur == end) {
        p->state = GRPC_CHTTP2_DATA_FH_1;
        return GRPC_CHTTP2_PARSE_OK;
      }
    /* fallthrough */
    case GRPC_CHTTP2_DATA_FH_1:
      p->frame_size = ((gpr_uint32)*cur) << 24;
      if (++cur == end) {
        p->state = GRPC_CHTTP2_DATA_FH_2;
        return GRPC_CHTTP2_PARSE_OK;
      }
    /* fallthrough */
    case GRPC_CHTTP2_DATA_FH_2:
      p->frame_size |= ((gpr_uint32)*cur) << 16;
      if (++cur == end) {
        p->state = GRPC_CHTTP2_DATA_FH_3;
        return GRPC_CHTTP2_PARSE_OK;
      }
    /* fallthrough */
    case GRPC_CHTTP2_DATA_FH_3:
      p->frame_size |= ((gpr_uint32)*cur) << 8;
      if (++cur == end) {
        p->state = GRPC_CHTTP2_DATA_FH_4;
        return GRPC_CHTTP2_PARSE_OK;
      }
    /* fallthrough */
    case GRPC_CHTTP2_DATA_FH_4:
      p->frame_size |= ((gpr_uint32)*cur);
      p->state = GRPC_CHTTP2_DATA_FRAME;
      ++cur;
      if (p->is_frame_compressed) {
        message_flags |= GRPC_WRITE_INTERNAL_COMPRESS;
      }
      grpc_sopb_add_begin_message(&p->incoming_sopb, p->frame_size,
                                  message_flags);
    /* fallthrough */
    case GRPC_CHTTP2_DATA_FRAME:
      if (cur == end) {
        grpc_chttp2_list_add_parsing_seen_stream(transport_parsing,
                                                 stream_parsing);
        return GRPC_CHTTP2_PARSE_OK;
      }
      grpc_chttp2_list_add_parsing_seen_stream(transport_parsing,
                                               stream_parsing);
      if ((gpr_uint32)(end - cur) == p->frame_size) {
        grpc_sopb_add_slice(&p->incoming_sopb,
                            gpr_slice_sub(slice, cur - beg, end - beg));
        p->state = GRPC_CHTTP2_DATA_FH_0;
        return GRPC_CHTTP2_PARSE_OK;
      } else if ((gpr_uint32)(end - cur) > p->frame_size) {
        grpc_sopb_add_slice(
            &p->incoming_sopb,
            gpr_slice_sub(slice, cur - beg, cur + p->frame_size - beg));
        cur += p->frame_size;
        goto fh_0; /* loop */
      } else {
        grpc_sopb_add_slice(&p->incoming_sopb,
                            gpr_slice_sub(slice, cur - beg, end - beg));
        p->frame_size -= (end - cur);
        return GRPC_CHTTP2_PARSE_OK;
      }
  }

  gpr_log(GPR_ERROR, "should never reach here");
  abort();
  return GRPC_CHTTP2_CONNECTION_ERROR;
}
Ejemplo n.º 5
0
int main(int argc, char **argv) {
  /* some basic test data */
  gpr_slice test_slice_1 = gpr_slice_malloc(1);
  gpr_slice test_slice_2 = gpr_slice_malloc(2);
  gpr_slice test_slice_3 = gpr_slice_malloc(3);
  gpr_slice test_slice_4 = gpr_slice_malloc(4);
  unsigned i;

  grpc_stream_op_buffer buf;
  grpc_stream_op_buffer buf2;

  grpc_test_init(argc, argv);
  /* initialize one of our buffers */
  grpc_sopb_init(&buf);
  /* it should start out empty */
  GPR_ASSERT(buf.nops == 0);

  /* add some data to the buffer */
  grpc_sopb_add_begin_message(&buf, 1, 2);
  grpc_sopb_add_slice(&buf, test_slice_1);
  grpc_sopb_add_slice(&buf, test_slice_2);
  grpc_sopb_add_slice(&buf, test_slice_3);
  grpc_sopb_add_slice(&buf, test_slice_4);
  grpc_sopb_add_no_op(&buf);

  /* verify that the data went in ok */
  GPR_ASSERT(buf.nops == 6);
  GPR_ASSERT(buf.ops[0].type == GRPC_OP_BEGIN_MESSAGE);
  GPR_ASSERT(buf.ops[0].data.begin_message.length == 1);
  GPR_ASSERT(buf.ops[0].data.begin_message.flags == 2);
  GPR_ASSERT(buf.ops[1].type == GRPC_OP_SLICE);
  assert_slices_equal(buf.ops[1].data.slice, test_slice_1);
  GPR_ASSERT(buf.ops[2].type == GRPC_OP_SLICE);
  assert_slices_equal(buf.ops[2].data.slice, test_slice_2);
  GPR_ASSERT(buf.ops[3].type == GRPC_OP_SLICE);
  assert_slices_equal(buf.ops[3].data.slice, test_slice_3);
  GPR_ASSERT(buf.ops[4].type == GRPC_OP_SLICE);
  assert_slices_equal(buf.ops[4].data.slice, test_slice_4);
  GPR_ASSERT(buf.ops[5].type == GRPC_NO_OP);

  /* initialize the second buffer */
  grpc_sopb_init(&buf2);
  /* add a no-op, and then the original buffer */
  grpc_sopb_add_no_op(&buf2);
  grpc_sopb_append(&buf2, buf.ops, buf.nops);
  /* should be one element bigger than the original */
  GPR_ASSERT(buf2.nops == buf.nops + 1);
  GPR_ASSERT(buf2.ops[0].type == GRPC_NO_OP);
  /* and the tail should be the same */
  for (i = 0; i < buf.nops; i++) {
    GPR_ASSERT(buf2.ops[i + 1].type == buf.ops[i].type);
  }

  /* destroy the buffers */
  grpc_sopb_destroy(&buf);
  grpc_sopb_destroy(&buf2);

  gpr_slice_unref(test_slice_1);
  gpr_slice_unref(test_slice_2);
  gpr_slice_unref(test_slice_3);
  gpr_slice_unref(test_slice_4);

  return 0;
}