| /****************************************************************************** |
| * Copyright (c) 2017-2019 Ericsson AB |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html |
| * Contributors: |
| * Gabor Szalai - initial implementation and initial documentation |
| ******************************************************************************/ |
| // |
| // File: HTTP2_Types.ttcn |
| // Description: Functions and types for HTTP2 |
| // Rev: R1D |
| // Prodnr: CNL 113 851 |
| module HTTP2_Types{ |
| |
| modulepar boolean tsp_HTTP2_comp_context_decode_debug:=false |
| |
| external function f_HTTP2_encode_frame(in HTTP2_Frame pl_frame) return octetstring |
| with { |
| extension "prototype(convert)" |
| } |
| |
| // return values: |
| // 1 - decoding failed |
| // 0 - OK |
| // |
| // The pl_error_descr contains the description of the error |
| |
| |
| external function f_HTTP2_decode_frame(in octetstring pl_stream, |
| out HTTP2_Frame pl_frame, |
| out HTTP2_decoder_error_descr pl_error_descr) return integer |
| |
| // Message dissector function for IPL4 test port |
| type record of integer HTTP2_ro_integer |
| |
| function f_HTTP2_msglen( |
| in octetstring stream, |
| inout HTTP2_ro_integer args |
| ) return integer { |
| var integer pl_len:=lengthof(stream) |
| if(pl_len<3){ |
| return -1; |
| } |
| if(pl_len<lengthof(HTTP2_connection_preface)){ |
| if(substr(HTTP2_connection_preface,0,pl_len)==stream ){ |
| return -1 |
| } |
| } else { |
| if(HTTP2_connection_preface==substr(stream,0,lengthof(HTTP2_connection_preface))){ |
| return lengthof(HTTP2_connection_preface) |
| } |
| |
| } |
| return oct2int(substr(stream,0,3))+9 |
| } |
| |
| const octetstring HTTP2_connection_preface:='505249202a20485454502f322e300d0a0d0a534d0d0a0d0a'O |
| |
| // Error classes |
| const integer c_connection_no_error_class := 0 |
| const integer c_connection_error_class := 1 |
| const integer c_stream_error_class := 2 |
| |
| // Error codes |
| const integer c_error_code_NO_ERROR:= 0 |
| const integer c_error_code_PROTOCOL_ERROR := 1 |
| const integer c_error_code_INTERNAL_ERROR :=2 |
| const integer c_error_code_FLOW_CONTROL_ERROR := 3 |
| const integer c_error_code_SETTINGS_TIMEOUT := 4 |
| const integer c_error_code_STREAM_CLOSED := 5 |
| const integer c_error_code_FRAME_SIZE_ERROR := 6 |
| const integer c_error_code_REFUSED_STREAM := 7 |
| const integer c_error_code_CANCEL := 8 |
| const integer c_error_code_COMPRESSION_ERROR := 9 |
| const integer c_error_code_CONNECT_ERROR := 10 |
| const integer c_error_code_ENHANCE_YOUR_CALM := 11 |
| const integer c_error_code_INADEQUATE_SECURITY := 12 |
| const integer c_error_code_HTTP_1_1_REQUIRED := 13 |
| |
| // Settings parameters |
| const integer c_SETTINGS_HEADER_TABLE_SIZE := 1 |
| const integer c_SETTINGS_ENABLE_PUSH := 2 |
| const integer c_SETTINGS_MAX_CONCURRENT_STREAMS := 3 |
| const integer c_SETTINGS_INITIAL_WINDOW_SIZE := 4 |
| const integer c_SETTINGS_MAX_FRAME_SIZE := 5 |
| const integer c_SETTINGS_MAX_HEADER_LIST_SIZE := 6 |
| |
| type record HTTP2_decoder_error_descr{ |
| integer error_class, |
| integer error_type, |
| charstring error_text |
| } |
| |
| // HTTP/2 Frame definition |
| // The length field handled automatically |
| type union HTTP2_Frame { |
| HTTP2_Data_frame data_frame, |
| HTTP2_Header_frame header_frame, |
| HTTP2_Priority_frame priority_frame, |
| HTTP2_RST_Stream_frame rst_frame, |
| HTTP2_Settings_frame settings_frame, |
| HTTP2_Push_Promise_frame push_promise_frame, |
| HTTP2_Ping_frame ping_frame, |
| HTTP2_Goaway_frame goaway_frame, |
| HTTP2_Window_Update_frame window_update_frame, |
| HTTP2_Continuation_frame continuation_frame, |
| HTTP2_Generic_frame generic_frame |
| } |
| |
| // Data Frame definition |
| // The padding flag are handled automatically |
| type record HTTP2_Data_frame{ |
| integer stream_id, |
| boolean end_stream_flag, |
| octetstring data, |
| octetstring padding optional |
| } |
| |
| // Header Frame definition |
| // The padding flag are handled automatically |
| // The priority flag are handled automatically |
| type record HTTP2_Header_frame{ |
| integer stream_id, |
| boolean end_stream_flag, |
| boolean end_header_flag, |
| HTTP2_Priority_data priority_data optional, |
| octetstring header_block_fragment, |
| octetstring padding optional |
| } |
| |
| type record HTTP2_Priority_data{ |
| boolean exclusive_flag, |
| integer stream_dependency, |
| integer weight |
| } |
| |
| type record HTTP2_Priority_frame{ |
| integer stream_id, |
| HTTP2_Priority_data priority_data |
| } |
| |
| type record HTTP2_RST_Stream_frame { |
| integer stream_id, |
| integer error_code |
| } |
| |
| type record HTTP2_Setting_data{ |
| integer setting_id, |
| integer setting_value |
| } |
| |
| type record of HTTP2_Setting_data HTTP2_Setting_list |
| |
| // Always use 0 stream |
| type record HTTP2_Settings_frame{ |
| boolean ack_flag, |
| HTTP2_Setting_list settings optional |
| } |
| |
| // The padding flag are handled automatically |
| type record HTTP2_Push_Promise_frame{ |
| integer stream_id, |
| boolean end_header_flag, |
| integer promised_stream_id, |
| octetstring header_block_fragment, |
| octetstring padding optional |
| } |
| |
| |
| // Always use 0 stream |
| type record HTTP2_Ping_frame{ |
| boolean ack_flag, |
| octetstring opaque_data length(8) |
| } |
| |
| // Always use 0 stream |
| type record HTTP2_Goaway_frame{ |
| integer last_stream_id, |
| integer error_code, |
| octetstring debug_data optional |
| } |
| |
| type record HTTP2_Window_Update_frame{ |
| integer stream_id, |
| integer window_size_increment |
| } |
| |
| type record HTTP2_Continuation_frame{ |
| integer stream_id, |
| boolean end_header_flag, |
| octetstring header_block_fragment |
| } |
| |
| // Use it to send/receive non-defined or errornous frame |
| // Only the length calculated by the encoder |
| type record HTTP2_Generic_frame{ |
| integer frame_type, |
| bitstring flags length(8), |
| integer stream_id, |
| octetstring payload |
| } |
| |
| |
| // HTTP2 request/response and header definitions |
| // RFC7540 8.1.2.1 |
| // Note: the encoder doesn't enforces validity |
| // of the specified pseudo header field combination |
| |
| type record HTTP2_pseudo_headers{ |
| charstring method optional, |
| charstring scheme optional, |
| charstring authority optional, |
| charstring path optional, |
| integer status optional |
| } |
| |
| type record HTTP2_header_field{ |
| charstring header_name, |
| charstring header_value optional |
| } |
| |
| type record of HTTP2_header_field HTTP2_header_list |
| |
| // This type should be used for request/response headers |
| type record HTTP2_header_block { |
| HTTP2_pseudo_headers pseudo_headers optional, |
| HTTP2_header_list headers optional |
| } |
| |
| |
| // Header compression releated type definitions |
| // For each connection (not streams) a separate |
| // compression context should be used. |
| |
| // Never touch the fields of the HTTP2_comp_context |
| // Don't even think about it !!!!! |
| |
| // 1. Create the context with function: |
| // HTTP2_comp_context_init |
| |
| // 2. Every header block should be encoded/decoded with the functions: |
| // HTTP2_comp_context_encode |
| // HTTP2_comp_context_decode |
| // in the exactly the same order as the header blocks are sent or received |
| // in order to maintain the header compression context |
| |
| // 3. Delete the context with |
| // HTTP2_comp_context_free |
| // Please note: non freed context leads to memory leak!!!! |
| |
| // Creates a new header compression context |
| external function HTTP2_comp_context_init(in integer h_table_size_local:=4096, // The initial size of the header table |
| in integer h_table_size_remote:=4096 |
| ) return HTTP2_comp_context |
| |
| // Retur value: |
| // 0 - OK |
| // otherwise - error code |
| external function HTTP2_comp_context_encode(inout HTTP2_comp_context pl_context, |
| in HTTP2_header_block pl_hblock, |
| out octetstring pl_frame_data) return integer |
| |
| // Retur value: |
| // 0 - OK |
| // otherwise - error code |
| external function HTTP2_comp_context_decode(inout HTTP2_comp_context pl_context, |
| out HTTP2_header_block pl_hblock, |
| in octetstring pl_frame_data, in boolean pl_enable_debug:=tsp_HTTP2_comp_context_decode_debug) return integer |
| |
| |
| // Free and release the header compression context |
| external function HTTP2_comp_context_free(inout HTTP2_comp_context pl_context) |
| |
| |
| // Set header table size |
| external function HTTP2_comp_context_set_table_size_remote(inout HTTP2_comp_context pl_context, |
| in integer h_table_size) |
| |
| external function HTTP2_comp_context_set_table_size_local(inout HTTP2_comp_context pl_context, |
| in integer h_table_size) |
| |
| //**************************************************// |
| // DO NOT TOUCH THE FIELDS OF THE HTTP2_comp_context |
| //**************************************************// |
| type record HTTP2_comp_context{ |
| integer internal_id1 |
| } |
| |
| |
| } |