void test_truncated_data() { spdy_frame_t the_frame; spdy_frame_t *frame = &the_frame; spdy_frame_create(frame); int res = spdy_frame_parse(frame, (uint8_t*)test_packet_truncated_data, sizeof(test_packet_truncated_data)); assert(res == SPDY_FRAME_ERROR_INCOMPLETE); spdy_frame_destroy(frame); }
void test_data_frame_parse() { spdy_frame_t the_frame; spdy_frame_t *frame = &the_frame; spdy_frame_create(frame); int res = spdy_frame_parse(frame, (uint8_t*)test_packet_data_frame, sizeof(test_packet_data_frame)); assert(res > 0); assert(frame->frame_type == SPDY_DATA_FRAME); assert(frame->stream_id == 1); assert(frame->flags == 0); assert(frame->data_length == 13); assert(frame->data != 0); assert(memcmp("This is SPDY.", frame->data, frame->data_length) == 0); spdy_frame_destroy(frame); }
void test_ping_parse() { spdy_frame_t the_frame; spdy_frame_t *frame = &the_frame; spdy_frame_create(frame); int res = spdy_frame_parse(frame, (uint8_t*)test_packet_ping, sizeof(test_packet_ping)); assert(res > 0); assert(frame->frame_type == SPDY_CONTROL_FRAME); assert(frame->protocol_version == 2); assert(frame->control_frame_type == SPDY_CONTROL_PING); assert(frame->flags == 0); assert(frame->data_length == 4); assert(frame->control_header.ping.ping_id == 1); spdy_frame_destroy(frame); }
void test_settings_parse() { spdy_frame_t the_frame; spdy_frame_t *frame = &the_frame; spdy_frame_create(frame); int res = spdy_frame_parse(frame, (uint8_t*)test_packet_settings, sizeof(test_packet_settings)); assert(res > 0); assert(frame->frame_type == SPDY_CONTROL_FRAME); assert(frame->protocol_version == 2); assert(frame->control_frame_type == SPDY_CONTROL_SETTINGS); assert(frame->flags == 0); assert(frame->data_length == 12); // fixme: extract data spdy_frame_destroy(frame); }
void test_rst_stream_parse() { spdy_frame_t the_frame; spdy_frame_t *frame = &the_frame; spdy_frame_create(frame); int res = spdy_frame_parse(frame, (uint8_t*)test_packet_rst_stream, sizeof(test_packet_rst_stream)); assert(res > 0); assert(frame->frame_type == SPDY_CONTROL_FRAME); assert(frame->protocol_version == 2); assert(frame->control_frame_type == SPDY_CONTROL_RST_STREAM); assert(frame->flags == 0); assert(frame->data_length == 8); assert(frame->control_header.rst_stream.stream_id == 1); assert(frame->control_header.rst_stream.status == 1); spdy_frame_destroy(frame); }
void test_syn_reply_parse() { spdy_frame_t the_frame; spdy_frame_t *frame = &the_frame; spdy_frame_create(frame); int res = spdy_frame_parse(frame, (uint8_t*)test_packet_syn_reply, sizeof(test_packet_syn_reply)); assert(res > 0); assert(frame->frame_type == SPDY_CONTROL_FRAME); assert(frame->protocol_version == 2); assert(frame->control_frame_type == SPDY_CONTROL_SYN_REPLY); assert(frame->flags == 0); assert(frame->control_header.syn_reply.stream_id == 1); // FIXME: test headers spdy_frame_destroy(frame); }
void test_syn_stream() { spdy_frame_t the_frame; spdy_frame_t *frame = &the_frame; spdy_frame_create(frame); int res = spdy_frame_parse(frame, (uint8_t*)test_packet_syn_stream, sizeof(test_packet_syn_stream)); assert(res > 0); assert(frame->frame_type == SPDY_CONTROL_FRAME); assert(frame->protocol_version == 2); assert(frame->control_frame_type == SPDY_CONTROL_SYN_STREAM); assert(frame->flags == 1); assert(frame->control_header.syn_stream.stream_id == 1); assert(frame->control_header.syn_stream.associated_stream_id == 0); assert(frame->control_header.syn_stream.priority == 0); assert(frame->control_header.syn_stream.slot == 0); // FIXME: test headers spdy_frame_destroy(frame); }
/* * Returns information about incoming data, split up for consumption. * Subsequent calls will return the next result and so on until there's * nothing left to demux - until spindly_phys_incoming() is called again to * feed it with more data. * * When this function returns that there is no more message, it may still hold * trailing data that forms the beginning of the subsequent message. * * 'ptr' must point to the correct struct, read the first 'type' field of that * to know how to interpret the rest! */ spindly_error_t spindly_phys_demux(struct spindly_phys *phys, struct spindly_demux *ptr) { struct list_node *n = _spindly_list_first(&phys->inq); struct spindly_indata *in= (struct spindly_indata *)n; int rc = SPINDLYE_OK; assert(ptr != NULL); ptr->type = SPINDLY_DX_NONE; do { if(phys->data.data_end <= phys->data.cursor) /* if the previously stored data is all consumed then get the current queue data */ spdy_data_use(&phys->data, in->data, in->datalen); /* * Parse data. The parsing function wants a full frame to be in a * contiguous buffer so unless it is, we must create a full frame from the * input we have. */ rc = spdy_frame_parse(&phys->frame, phys, &phys->data); if(rc == SPDY_ERROR_NONE) { if(phys->frame.type == SPDY_CONTROL_FRAME) { spdy_syn_stream *syn; spdy_syn_reply *rep; struct spindly_stream *stream; struct hashnode *n; switch(phys->frame.frame.control.type) { case SPDY_CTRL_SYN_STREAM: /* * At this point there's a syn_stream struct that needs to be * converted to a full spinly_stream struct! * * phys->frame.frame.control.obj.syn_stream */ syn = &phys->frame.frame.control.obj.syn_stream; rc = _spindly_stream_init(phys, syn->priority, &stream, NULL, NULL, syn->stream_id); if(rc) /* TODO: how do we deal with a failure here? */ break; ptr->type = SPINDLY_DX_STREAM_REQ; ptr->msg.stream.stream = stream; break; case SPDY_CTRL_SYN_REPLY: /* * At this point there's a syn_reply struct that needs to be * converted to a full spinly_stream struct! * * phys->frame.frame.control.obj.syn_reply */ rep = &phys->frame.frame.control.obj.syn_reply; n = _spindly_hash_get(&phys->streamhash, rep->stream_id); if(!n) /* received a SYN_REPLY for an unknown streamid */ rc = SPINDLYE_PROTOCOL; else { stream = n->ptr; stream->state = STREAM_ACKED; ptr->type = SPINDLY_DX_STREAM_ACK; ptr->msg.stream.stream = stream; } break; case SPDY_CTRL_RST_STREAM: assert(0); /* not implemented yet! */ break; case SPDY_CTRL_SETTINGS: assert(0); /* not implemented yet! */ break; case SPDY_CTRL_NOOP: assert(0); /* not implemented yet! */ break; case SPDY_CTRL_PING: assert(0); /* not implemented yet! */ break; case SPDY_CTRL_GOAWAY: assert(0); /* not implemented yet! */ break; case SPDY_CTRL_HEADERS: assert(0); /* not implemented yet! */ break; case SPDY_CTRL_WINDOW_UPDATE: assert(0); /* not implemented yet! */ break; default: assert(0); /* internal error */ break; } spdy_frame_destroy(&phys->frame); } else { /* data */ ptr->type = SPINDLY_DX_DATA; } /* TODO: if the complete inq node was consumed, call the callback */ return SPINDLYE_OK; } else if(rc == SPDY_ERROR_INSUFFICIENT_DATA) { /* if there's too little data to parse, merge the buffer with the next * in the queue and loop and parse the bigger one */ bool more; rc = parse_append(phys, &more); if(!more) /* there's no more right now */ return SPINDLYE_OK; } } while(!rc); return rc; }