std::multimap< std::string, std::string > Hpack_index_table::hpack_decode(const unsigned char* s, int len) { if(!hpack_inited) init_hpack(); int i = 0; std::multimap<std::string, std::string> headers; bool noDynamic = false; while(i < len) { if(s[i] & 0x80) { noDynamic = true; uint32_t index; i += integer_decode(s+i, 7, &index); const Hpack_index *value = getvalue(index); if(value == nullptr){ LOGE("get null index from %d\n", index); throw ERR_COMPRESSION_ERROR; } headers.insert(std::make_pair(value->name, value->value)); }else if(s[i] & 0x40) { noDynamic = true; uint32_t index; i += integer_decode(s+i, 6, &index); std::string name, value; if(index) { name = getvalue(index)->name; } else { i += literal_decode(s+i, name); } i += literal_decode(s+i, value); headers.insert(std::make_pair(name, value)); add_dynamic_table(name, value); }else if(s[i] & 0x20) { if(noDynamic){ LOGE("found update dynamic talbe limit after normal entry\n"); throw ERR_COMPRESSION_ERROR; } uint32_t size; i += integer_decode(s+i, 5, &size); set_dynamic_table_size_limit(size); }else { noDynamic = true; uint32_t index; i += integer_decode(s+i, 4, &index); std::string name, value; if(index) { name = getvalue(index)->name; } else { i += literal_decode(s+i, name); } i += literal_decode(s+i, value); headers.insert(std::make_pair(name, value)); } if(i > len){ LOGE("may be overflow: %d/%d\n", i, len); throw ERR_COMPRESSION_ERROR; } } //evict_dynamic_table(); return headers; }
int _cdk_filter_literal( void * opaque, int ctl, FILE * in, FILE * out ) { if( ctl == STREAMCTL_READ ) return literal_decode( opaque, in, out ); else if( ctl == STREAMCTL_WRITE ) return literal_encode( opaque, in, out ); else if( ctl == STREAMCTL_FREE ) { literal_filter_t * pfx = opaque; if( pfx ) { cdk_free( pfx->filename ); pfx->filename = NULL; } } return CDK_Inv_Mode; }
int _cdk_filter_literal (void *data, int ctl, FILE * in, FILE * out) { if (ctl == STREAMCTL_READ) return literal_decode (data, in, out); else if (ctl == STREAMCTL_WRITE) return literal_encode (data, in, out); else if (ctl == STREAMCTL_FREE) { literal_filter_t *pfx = data; if (pfx) { _cdk_log_debug ("free literal filter\n"); cdk_free (pfx->filename); pfx->filename = NULL; cdk_free (pfx->orig_filename); pfx->orig_filename = NULL; return 0; } } return CDK_Inv_Mode; }