/** * Parse a SYN_STREAM control frame. * Parses the header of a SYN_STREAM control frame and extracts the * NV block. * @param syn_stream - Destination frame. * @param hash - Streamid lookup * @param data - Data to parse. * @param frame_length - Length of the frame. * @see spdy_control_frame * @see SPDY_SYN_STREAM_MIN_LENGTH * @return 0 on success, -1 on failure. */ int spdy_syn_stream_parse(spdy_syn_stream *syn_stream, struct spindly_phys *phys, spdy_data *data, uint32_t frame_length) { int ret; size_t length = data->data_end - data->cursor; struct hashnode *hn; assert(phys != NULL); if(length < frame_length) { data->needed = frame_length - length; SPDYDEBUG("Not enough data for parsing the stream."); return SPDY_ERROR_INSUFFICIENT_DATA; } /* TODO: Optimize the double length check away. */ if(length < SPDY_SYN_STREAM_MIN_LENGTH) { data->needed = SPDY_SYN_STREAM_MIN_LENGTH - length; SPDYDEBUG("Not enough data for parsing the stream."); return SPDY_ERROR_INSUFFICIENT_DATA; } /* Parse the frame header. */ ret = spdy_syn_stream_parse_header(syn_stream, data); if(ret) { SPDYDEBUG("Failed to parse header."); return ret; } /* make sure the incoming streamid isn't already used */ hn = _spindly_hash_get(&phys->streamhash, syn_stream->stream_id); if(hn) { SPDYDEBUG("Got a SPDY_STREAM with an exiting id!"); return SPDY_ERROR_INVALID_DATA; } /* Init NV block. */ ret = spdy_nv_block_init(&syn_stream->nv_block); if(ret) return ret; /* Parse NV block. */ ret = spdy_nv_block_inflate_parse(&syn_stream->nv_block, data->cursor, frame_length, &phys->zlib_in); if(ret) { /* Clean up. */ SPDYDEBUG("Failed to parse NV block."); return ret; } data->cursor += frame_length - SPDY_SYN_STREAM_HEADER_MIN_LENGTH; return SPDY_ERROR_NONE; }
/** * Parse a SYN_STREAM control frame. * Parses the header of a SYN_STREAM control frame and extracts the * NV block. * @param syn_stream - Destination frame. * @param data - Data to parse. * @param frame_length - Length of the frame. * @param zlib_ctx - The zlib context to use. * @see spdy_control_frame * @see SPDY_SYN_STREAM_MIN_LENGTH * @return 0 on success, -1 on failure. */ int spdy_syn_stream_parse(spdy_syn_stream *syn_stream, spdy_data *data, uint32_t frame_length, spdy_zlib_context *zlib_ctx) { int ret; size_t length = data->data_end - data->cursor; if(length < frame_length) { data->needed = frame_length - length; SPDYDEBUG("Not enough data for parsing the stream."); return SPDY_ERROR_INSUFFICIENT_DATA; } /* TODO: Optimize the double length check away. */ if(length < SPDY_SYN_STREAM_MIN_LENGTH) { data->needed = SPDY_SYN_STREAM_MIN_LENGTH - length; SPDYDEBUG("Not enough data for parsing the stream."); return SPDY_ERROR_INSUFFICIENT_DATA; } /* Parse the frame header. */ if((ret = spdy_syn_stream_parse_header(syn_stream, data)) != SPDY_ERROR_NONE) { SPDYDEBUG("Failed to parse header."); return ret; } /* Init NV block. */ ret = spdy_nv_block_init(&syn_stream->nv_block); if(ret) { return ret; } /* Parse NV block. */ if((ret = spdy_nv_block_inflate_parse(&syn_stream->nv_block, data->cursor, frame_length, zlib_ctx)) != SPDY_ERROR_NONE) { /* Clean up. */ SPDYDEBUG("Failed to parse NV block."); return ret; } data->cursor += frame_length - SPDY_SYN_STREAM_HEADER_MIN_LENGTH; return SPDY_ERROR_NONE; }