Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Eclipse Titan » Support for HTTP/2 in Eclipse Titan
Support for HTTP/2 in Eclipse Titan [message #1773471] Thu, 28 September 2017 10:47 Go to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Dear all,

HTTP2 is basically a more performant version of HTTP ,
supporting header field compression and allowing multiple concurrent exchanges on the same connection.
It also introduces unsolicited push of representations from servers to clients.
HTTP2 is an alternative to, but does not obsolete HTTP/1.1.

For details please check https://http2.github.io/

As test server I will use http://nghttp2.org/
which exposes a number of request/response test services at http://nghttp2.org/httpbin/

For instance, if one navigates to :

http://nghttp2.org/httpbin/get

will get something like

{
  "args": {},
  "headers": {
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
    "Accept-Encoding": "gzip, deflate",
    "Accept-Language": "en-US,en;q=0.8",
    "Host": "nghttp2.org",
    "Upgrade-Insecure-Requests": "1",
    "User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36",
    "Via": "1.1 nghttpx"
  },
  "origin": "91.82.100.59",
  "url": "http://nghttp2.org/httpbin/get"
}

and http://nghttp2.org/httpbin/ip
returns your IP address:

{
  "origin": "91.82.100.59"
}


The referring standard RFC 7540 ( see https://tools.ietf.org/html/rfc7540)
defines three ways to establish an HTTP2 connection:

1. Connection upgrade

3.2. Starting HTTP/2 for "http" URIs

A client that makes a request for an "http" URI without prior
knowledge about support for HTTP/2 on the next hop uses the HTTP
Upgrade mechanism (Section 6.7 of [RFC7230]). The client does so by
making an HTTP/1.1 request that includes an Upgrade header field with
the "h2c" token. Such an HTTP/1.1 request MUST include exactly one
HTTP2-Settings (Section 3.2.1) header field.

For example:

GET / HTTP/1.1
Host: server.example.com
Connection: Upgrade, HTTP2-Settings
Upgrade: h2c
HTTP2-Settings: <base64url encoding of HTTP/2 SETTINGS payload>

:
:
A server that supports HTTP/2 accepts the upgrade with a 101
(Switching Protocols) response. After the empty line that terminates
the 101 response, the server can begin sending HTTP/2 frames. These
frames MUST include a response to the request that initiated the
upgrade.

For example:

HTTP/1.1 101 Switching Protocols
Connection: Upgrade
Upgrade: h2c

[ HTTP/2 connection ...



2. ALPN: application-layer protocol negotiation

Starting HTTP/2 for "https" URIs

A client that makes a request to an "https" URI uses TLS [TLS12] with
the application-layer protocol negotiation (ALPN) extension
[TLS-ALPN].

HTTP/2 over TLS uses the "h2" protocol identifier. The "h2c"
protocol identifier MUST NOT be sent by a client or selected by a
server; the "h2c" protocol identifier describes a protocol that does
not use TLS.

Once TLS negotiation is complete, both the client and the server MUST
send a connection preface (Section 3.5).



3. Previous knowledge

Starting HTTP/2 with Prior Knowledge

A client can learn that a particular server supports HTTP/2 by other
means. For example, [ALT-SVC] describes a mechanism for advertising
this capability.

A client MUST send the connection preface (Section 3.5) and then MAY
immediately send HTTP/2 frames to such a server; servers can identify
these connections by the presence of the connection preface. This
only affects the establishment of HTTP/2 connections over cleartext
TCP; implementations that support HTTP/2 over TLS MUST use protocol
negotiation in TLS [TLS-ALPN].


These three connection mechanisms can be made visible by using a up-to-date curl compiled together with nghttp2.
I have used curl 7.54.0 in the below experiments:

curl --version
curl 7.54.0 (x86_64-pc-linux-gnu) libcurl/7.54.0 OpenSSL/1.0.2g zlib/1.2.8 nghttp2/1.7.1
Protocols: dict file ftp ftps gopher http https imap imaps pop3 pop3s rtsp smb smbs smtp smtps telnet tftp 
Features: IPv6 Largefile NTLM NTLM_WB SSL libz TLS-SRP HTTP2 UnixSockets HTTPS-proxy 

And here are the three HTTP2 mechanisms replicated with curl:


//ALPN
curl --http2 -v https://nghttp2.org/httpbin/ip 
*   Trying 139.162.123.134...
* TCP_NODELAY set
*   Trying 2400:8902::f03c:91ff:fe69:a454...
* TCP_NODELAY set
* Immediate connect fail for 2400:8902::f03c:91ff:fe69:a454: Network is unreachable
* Connected to nghttp2.org (139.162.123.134) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: none
* TLSv1.2 (OUT), TLS header, Certificate Status (22):
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-ECDSA-AES256-GCM-SHA384
* ALPN, server accepted to use h2
* Server certificate:
*  subject: CN=nghttp2.org
*  start date: Sep 20 00:00:00 2017 GMT
*  expire date: Dec 19 00:00:00 2017 GMT
*  subjectAltName: host "nghttp2.org" matched cert's "nghttp2.org"
*  issuer: C=US; O=Let's Encrypt; CN=Let's Encrypt Authority X3
*  SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x1ca2f80)
> GET /httpbin/ip HTTP/2
> Host: nghttp2.org
> User-Agent: curl/7.54.0
> Accept: */*
> 
* Connection state changed (MAX_CONCURRENT_STREAMS updated)!
< HTTP/2 200 
< date: Thu, 28 Sep 2017 07:57:38 GMT
< content-type: application/json
< content-length: 31
< access-control-allow-origin: *
< access-control-allow-credentials: true
< x-backend-header-rtt: 0.002103
< strict-transport-security: max-age=31536000
< server: nghttpx
< via: 1.1 nghttpx
< x-frame-options: SAMEORIGIN
< x-xss-protection: 1; mode=block
< x-content-type-options: nosniff
< 
{
  "origin": "91.82.100.59"
}
* Connection #0 to host nghttp2.org left intact





//upgrade connection

curl --http2 -v http://nghttp2.org/httpbin/ip 
*   Trying 139.162.123.134...
* TCP_NODELAY set
*   Trying 2400:8902::f03c:91ff:fe69:a454...
* TCP_NODELAY set
* Immediate connect fail for 2400:8902::f03c:91ff:fe69:a454: Network is unreachable
* Connected to nghttp2.org (139.162.123.134) port 80 (#0)
> GET /httpbin/ip HTTP/1.1
> Host: nghttp2.org
> User-Agent: curl/7.54.0
> Accept: */*
> Connection: Upgrade, HTTP2-Settings
> Upgrade: h2c
> HTTP2-Settings: AAMAAABkAARAAAAAAAIAAAAA
> 
< HTTP/1.1 101 Switching Protocols
< Connection: Upgrade
< Upgrade: h2c
* Received 101
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=264
* Connection state changed (MAX_CONCURRENT_STREAMS updated)!
< HTTP/2 200 
< date: Thu, 28 Sep 2017 07:59:24 GMT
< content-type: application/json
< content-length: 31
< access-control-allow-origin: *
< access-control-allow-credentials: true
< x-backend-header-rtt: 0.002284
< server: nghttpx
< via: 1.1 nghttpx
< x-frame-options: SAMEORIGIN
< x-xss-protection: 1; mode=block
< x-content-type-options: nosniff
< 
{
  "origin": "91.82.100.59"
}
* Connection #0 to host nghttp2.org left intact


//prior knowledge


curl --http2-prior-knowledge -v  http://nghttp2.org/httpbin/ip
*   Trying 139.162.123.134...
* TCP_NODELAY set
*   Trying 2400:8902::f03c:91ff:fe69:a454...
* TCP_NODELAY set
* Immediate connect fail for 2400:8902::f03c:91ff:fe69:a454: Network is unreachable
* Connected to nghttp2.org (139.162.123.134) port 80 (#0)
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x80af80)
> GET /httpbin/ip HTTP/2
> Host: nghttp2.org
> User-Agent: curl/7.54.0
> Accept: */*
> 
* Connection state changed (MAX_CONCURRENT_STREAMS updated)!
< HTTP/2 200 
< date: Thu, 28 Sep 2017 08:00:05 GMT
< content-type: application/json
< content-length: 31
< access-control-allow-origin: *
< access-control-allow-credentials: true
< x-backend-header-rtt: 0.002401
< server: nghttpx
< via: 1.1 nghttpx
< x-frame-options: SAMEORIGIN
< x-xss-protection: 1; mode=block
< x-content-type-options: nosniff
< 
{
  "origin": "91.82.100.59"
}
* Connection #0 to host nghttp2.org left intact


Support for HTTP in Titan comes in several, somewhat confusing forms:

The HTTP test port ( or rather the associated small protocol module):
https://github.com/eclipse/titan.TestPorts.HTTPmsg
supports HTTP 1.0/HTTP 1.1

The below confusingly named HTTP protocol module
https://github.com/eclipse/titan.ProtocolModules.HTTP2.0
again supports HTTP 1.0/HTTP 1.1 , but with more user-friendly structures, and it is considered version 2 relative to the one in the test port.

Finally git://git.eclipse.org/gitroot/titan/titan.ProtocolModules.HTTP2.git HTTP/2
is a genuine HTTP/2 implementation.

As in some of the scenarios the communication starts with HTTP 1.1 messages , I have used both the above protocol modules.
As transport I have again used the IPL4 of which you are probably bored to death already.

Here's the code deployed:

module HTTP2   {


modulepar {

  charstring tsp_hostname:="nghttp2.org"; 
  charstring tsp_url:="/httpbin/ip" ;
  Http2_start tsp_start:=alpn;
}

import from IPL4asp_Types all;
import from IPL4asp_PortType all;
import from HTTP_Types all;
import from HTTP_MessageLen all;
import from HTTP2_Types all;


//*************************************************************************
function f_HTTP2_Message_len(  in octetstring stream,   inout ro_integer args) return integer
//*************************************************************************
{    
  return f_HTTP2_msglen(stream, args) ;                 
}

type component GeneralComp
{
  port IPL4asp_PT p;
  timer t;    
  var IPL4asp_Types.Result  c_res:= { errorCode := omit, connId  := omit, os_error_code:=omit, os_error_text:= omit };   
}

type component SystemComp
{
  port IPL4asp_PT p;
}


type enumerated Http2_start
  {
    alpn (0),
    upgrade_conn (1),
    prior_knowledge(2)
  }

template  HTTP2_Frame t_HTTP2_init_settings_frame:= {
      settings_frame :={
		ack_flag :=false,
		settings := {
{
 setting_id:=2, //SETTINGS_ENABLE_PUSH
 setting_value:=0
},
{
 setting_id:=3, //SETTINGS_MAX_CONCURRENT_STREAMS
 setting_value:=100
},
{
 setting_id:=4,//SETTINGS_INITIAL_WINDOW_SIZE
 setting_value:=1073741824//65536
}
}

}
}




template  HTTP2_Frame t_HTTP2_window_update_frame:= {
      window_update_frame :={
		stream_id :=0,
		window_size_increment := 1073676289
		}
}


template  HTTP2_Frame t_HTTP2_init_settings_frame_r:= {
      settings_frame :={
		ack_flag :=false,
		settings := *
		}
}



template  HTTP2_Frame t_HTTP2_init_settings_frame_ack:= {
      settings_frame :={
		ack_flag :=true,
		settings := omit 
}
}


template  HTTP2_header_block t_HTTP2_header_block:= {
pseudo_headers :={
 method:="GET",
  scheme:="http",
  authority:=tsp_hostname,
  path:=tsp_url,
  status:=omit
},
 headers :={{
  header_name:="accept",
  header_value:="*/*"
},
{
  header_name:="user-agent",
  header_value:="Titan"
}
}
}

template  HTTP2_Frame t_HTTP2_data_frame(in octetstring pdu):= {
      data_frame :={
  stream_id:=1,
  end_stream_flag :=false,
  data:=pdu,
  padding:=omit
}
}


template  HTTP2_Frame t_HTTP2_header_frame(in octetstring pdu):= {
      header_frame:=
{
   stream_id:=1,
  end_stream_flag :=true,
  end_header_flag :=true,
  priority_data:=omit,
  header_block_fragment:=pdu,
  padding:=omit
}

 }


template  ASP_Send t_data1(in integer p_id ) :={
  connId:=p_id,
  proto:=omit,
  msg:=ef_HTTP_Encode(valueof(t_message("")))
}


template  ASP_Send t_data2(in integer p_id, in octetstring pdu ) :={
  connId:=p_id,
  proto:=omit,
  msg:=pdu
}


template HTTP_Message t_message (in charstring payload) := {
  msg := {{request_line :={GET,tsp_url,1,1}},{
      host := tsp_hostname,
      connection := {{"Upgrade"},{"HTTP2-Settings"}},
      upgrade := {{"h2c"}},
      http2_settings := "AAMAAABkAARAAAAAAAIAAAAA",
      user_agent := "Titan"

    },omit}
}with { optional "implicit omit" } 




 //*************************************************************************
testcase TC_http2() runs on GeneralComp system SystemComp {
 //*************************************************************************

  var ASP_RecvFrom v_ASP_RecvFrom;
  var IPL4asp_Types.Result  vl_result;
  var HTTP_Message v_HTTP_Message;		
  var HTTP2_Frame v_HTTP2_Frame;	
  var HTTP2_comp_context v_HTTP2_comp_context;
  var HTTP2_decoder_error_descr v_err;
  var octetstring v_data:=''O, v_msg:=''O;
  var integer v_cid , v_ret 

  
  
  map(self:p, system:p); 

  vl_result := c_res;

if(tsp_start == alpn){

    vl_result :=f_IPL4_connect(p, tsp_hostname, 443,"",0, -1, {ssl := {} }, {{alpn_list:={"h2"}},{tls_hostname:=tsp_hostname}}  )
 }

 else  
 {
  vl_result :=f_IPL4_connect( p, tsp_hostname, 80,"",0, -1, {tcp := {} }, {} )
 }
 
  log("connect result",vl_result)

  if (not(ispresent(vl_result.connId)))  {  log("Could not connect");   stop;  } 
  v_cid:=vl_result.connId ;

if(tsp_start==upgrade_conn)
{
//register message length function of HTTP with IPL4:

//*************************************************************************
 //var f_IPL4_getMsgLen getMsg_Func := refers(f_HTTPMessage_len);
 //f_IPL4_setGetMsgLen(p,v_cid, getMsg_Func, {});
//*************************************************************************
// send connection upgrade request
 p.send(t_data1(v_cid));
   t.start(5.0) 
     
       alt 
        { 
              [] p.receive(ASP_RecvFrom:?) -> value v_ASP_RecvFrom	{ 
              v_HTTP_Message:= ef_HTTP_Decode(v_ASP_RecvFrom.msg) 
              log(v_HTTP_Message)              
              };
              [] t.timeout{log("Bye")}
        } 

}  else {}

//--------------------------------------------------------------------------

//register message length function of HTTP/2 with IPL4:

  //*************************************************************************
  var f_IPL4_getMsgLen getMsg_Func := refers(f_HTTP2_Message_len);
  f_IPL4_setGetMsgLen(p,v_cid, getMsg_Func, {});
  //*************************************************************************
//init compression context
v_HTTP2_comp_context:=HTTP2_comp_context_init();
// send connection preface "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"
p.send(t_data2(v_cid,HTTP2_connection_preface));
// send settings
p.send(t_data2(v_cid,f_HTTP2_encode_frame(valueof(t_HTTP2_init_settings_frame))));
// send window update
p.send(t_data2(v_cid,f_HTTP2_encode_frame(valueof(t_HTTP2_window_update_frame))));

if(not(tsp_start==upgrade_conn))
{
// send HEADER frame
HTTP2_comp_context_encode(v_HTTP2_comp_context,valueof(t_HTTP2_header_block), v_data )
//HTTP2_comp_context_decode(v_HTTP2_comp_context,v_HTTP2_header_block, v_data )
//log("v_HTTP2_header_block",v_HTTP2_header_block)
p.send(t_data2(v_cid,f_HTTP2_encode_frame(valueof(t_HTTP2_header_frame(v_data))))); 
}

  t.start(1.0) 

  alt 
  { 
    [] p.receive(ASP_RecvFrom:?) -> value v_ASP_RecvFrom { 
    
     f_HTTP2_decode_frame(v_ASP_RecvFrom.msg, v_HTTP2_Frame, v_err) 

     log("**********received frame:  ***********",v_HTTP2_Frame)
     
      if (ischosen(v_HTTP2_Frame.settings_frame))
      {
     if (match(v_HTTP2_Frame,t_HTTP2_init_settings_frame_ack ) ) 
     {  
     log("**********received init_settings_frame_ack   ") 
     repeat;
     } 
     else if  (match(v_HTTP2_Frame, t_HTTP2_init_settings_frame_r))
     {  
     log("**********received init_settings_frame    ") ;
     p.send(t_data2(v_cid,f_HTTP2_encode_frame(valueof(t_HTTP2_init_settings_frame_ack))));
     repeat;
     
     }
     
      }

    else  if (ischosen(v_HTTP2_Frame.header_frame))
      {
      log("**********received header frame    ") ;
        var HTTP2_header_block vl_HTTP2_header_block
    
    HTTP2_comp_context_decode(v_HTTP2_comp_context,vl_HTTP2_header_block, v_HTTP2_Frame.header_frame.header_block_fragment )
    
     log("************received header block:  ",vl_HTTP2_header_block)
     repeat;
      }

 else  if (ischosen(v_HTTP2_Frame.data_frame))
      {
           log("*************received data_frame    ") ;
      }

 else  if (ischosen(v_HTTP2_Frame.ping_frame))
      {
           log("*************received ping_frame    ") ;
      }

    };
    [] t.timeout{log("Bye")}

  }//endalt 

 HTTP2_comp_context_free(v_HTTP2_comp_context);
   
//----------------------------------------------------------------------------

  vl_result :=    f_IPL4_close(p, v_cid);
  log("close result",vl_result); 
  unmap(self:p, system:p); 
  setverdict(pass);

}//endtestcase


control{
execute(TC_http2());

}//endcontrol

}//endmodule  


with the following parameters

[MODULE_PARAMETERS]

HTTP2.tsp_hostname:="nghttp2.org" //"nghttp2.org"
HTTP2.tsp_url:="/httpbin/get" //"/httpbin/get" "/httpbin/ip"
HTTP2.tsp_start:=upgrade_conn //upgrade_conn, prior_knowledge, alpn


Of course I have cycled through the tsp_start parameters to reproduce all scenarios. In all the scenarios I have received the below answer:



01:12:55.447376 HTTP2.ttcn:357 **********received header frame    
01:12:55.448604 HTTP2.ttcn:362 ************received header block:  {
    pseudo_headers := {
        method := omit,
        scheme := omit,
        authority := omit,
        path := omit,
        status := 200
    },
    headers := {
        {
            header_name := "date",
            header_value := "Thu, 28 Sep 2017 08:12:55 GMT"
        },
        {
            header_name := "content-type",
            header_value := "application/json"
        }
    }
}
01:12:55.448926 HTTP2.ttcn:332 Matching on port p succeeded:  matched
01:12:55.448982 HTTP2.ttcn:332 Receive operation on port p succeeded, message from system(): @IPL4asp_Types.ASP_RecvFrom : {
    connId := 1,
    remName := "nghttp2.org",
    remPort := 80,
    locName := "192.168.139.129",
    locPort := 39655,
    proto := {
        tcp := { }
    },
    userData := 0,
    msg := '0000CE0001000000017B0A20202261726773223A207B7D2C0A20202268656164657273223A207B0A2020202022416363657074223A20222A2F2A222C0A2020202022486F7374223A20226E6768747470322E6F7267222C0A2020202022557365722D4167656E74223A2022546974616E222C0A2020202022566961223A202232206E676874747078220A20207D2C0A2020226F726967696E223A202239312E38322E3130302E3539222C0A20202275726C223A2022687474703A2F2F6E6768747470322E6F72672F6874747062696E2F676574220A7D0A'O
} id 4
01:12:55.449026 HTTP2.ttcn:332 Message with id 4 was extracted from the queue of p.
01:12:55.449050 HTTP2.ttcn:336 **********received frame:  ***********{
    data_frame := {
        stream_id := 1,
        end_stream_flag := true,
        data := '7B0A20202261726773223A207B7D2C0A20202268656164657273223A207B0A2020202022416363657074223A20222A2F2A222C0A2020202022486F7374223A20226E6768747470322E6F7267222C0A2020202022557365722D4167656E74223A2022546974616E222C0A2020202022566961223A202232206E676874747078220A20207D2C0A2020226F726967696E223A202239312E38322E3130302E3539222C0A20202275726C223A2022687474703A2F2F6E6768747470322E6F72672F6874747062696E2F676574220A7D0A'O ("{
  \"args\": {},
  \"headers\": {
    \"Accept\": \"*/*\",
    \"Host\": \"nghttp2.org\",
    \"User-Agent\": \"Titan\",
    \"Via\": \"2 nghttpx\"
  },
  \"origin\": \"91.82.100.59\",
  \"url\": \"http://nghttp2.org/httpbin/get\"
}
"),
        padding := omit
    }
} 


which is practically the same as the one obtained with a browser or curl.


Note1. The ALPN scenario requires support from the IPL4 port, see

IPL4asp Test Port for TTCN-3 Toolset with TITAN, Description

2.11.6 ALPN support
The test port supports the ALPN TLS extension and the ALPN negotiation.
Please note that the ALPN support requires OpenSSL 1.0.2 at least.
2.12 TLS hostname extension
The test port supports the TLS hostname extension as client only.

The TCP/TLS layer is established using the appropriate parameters:
if(tsp_start == alpn){

    vl_result :=f_IPL4_connect(p, tsp_hostname, 443,"",0, -1, {ssl := {} }, {{alpn_list:={"h2"}},{tls_hostname:=tsp_hostname}}  )
 }


Note2. In the "Upgrade Connection" scenario, communication starts on HTTP1.1, and then a connection upgrade is requested
(see also the previously published Websocket examples, which work along a similar logic)

The upgrade message template used here is:
template HTTP_Message t_message (in charstring payload) := {
  msg := {{request_line :={GET,tsp_url,1,1}},{
      host := tsp_hostname,
      connection := {{"Upgrade"},{"HTTP2-Settings"}},
      upgrade := {{"h2c"}},
      http2_settings := "AAMAAABkAARAAAAAAAIAAAAA",
      user_agent := "Titan"

    },omit}
}with { optional "implicit omit" } 




Note3: If one checks the decoded headers might notice that they are wrongly decoded:

23:41:55.096525 HTTP2.ttcn:357 **********received header frame    
23:41:55.097873 HTTP2.ttcn:362 ************received header block:  { pseudo_headers := { method := omit, scheme := omit, authority := omit, path := omit, status := 200 }, headers := { { header_name := "date", header_value := "Tue, 20 Jun 2017 06:41:56 GMT" }, { header_name := "content-type", header_value := "application/json" } } }

while Wireshark shows:

index.php/fa/30863/0/


In fact the decoder works correctly , but the headers contain extensions that are not (yet) covered.

Code and logs attached as usual.


Now, the main problem with the attached TTCN-3 code is the same I have highlighted in the STOMP/WebSocket/TCP example
(https://www.eclipse.org/forums/index.php/t/1088583/) :

there is no nice separation between the protocol layers in the TTCN-3 code;
next, we will look into a solution that is different from the usage of translation ports as proposed previously.


Best regards
Elemer

[Updated on: Sat, 30 September 2017 03:34]

Report message to a moderator

Re: Support for HTTP/2 in Eclipse Titan [message #1783014 is a reply to message #1773471] Tue, 06 March 2018 14:16 Go to previous messageGo to next message
Gustavo Gonnet is currently offline Gustavo GonnetFriend
Messages: 36
Registered: October 2015
Location: Montreal, Quebec, Canada
Member
Great post!

For people using Ubuntu 14.04, wireshark and curl updates were not easy to get.
For wireshark, I updated to this version and was able to decode http2 messages:
$ wireshark --version
Wireshark 2.4.4 (Git v2.4.4 packaged as 2.4.4-1~14.04.0)

And this is the recipe that worked for me to get the latest curl:

https://serversforhackers.com/c/curl-with-http2-support

Namely:

# Get build requirements
# Some of these are used for the Python bindings
# this package also installs
sudo apt-get install g++ make binutils autoconf automake autotools-dev libtool pkg-config \
zlib1g-dev libcunit1-dev libssl-dev libxml2-dev libev-dev libevent-dev libjansson-dev \
libjemalloc-dev cython python3-dev python-setuptools

# Build nghttp2 from source
git clone https://github.com/tatsuhiro-t/nghttp2.git
cd nghttp2
autoreconf -i
automake
autoconf
./configure
make
sudo make install

cd ~
sudo apt-get build-dep curl
wget http://curl.haxx.se/download/curl-7.46.0.tar.bz2
tar -xvjf curl-7.XX.X.tar.bz2
cd curl-7.XX.X
./configure --with-nghttp2=/usr/local --with-ssl
make
sudo make install
sudo ldconfig

That way, I was able to install curl 7.58:
$ curl --version
curl 7.58.0 (x86_64-pc-linux-gnu) libcurl/7.58.0 OpenSSL/1.0.1f zlib/1.2.8 nghttp2/1.32.0-DEV librtmp/2.3
Release-Date: 2018-01-24
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtmp rtsp smb smbs smtp smtps telnet tftp
Features: AsynchDNS IPv6 Largefile NTLM NTLM_WB SSL libz TLS-SRP HTTP2 UnixSockets HTTPS-proxy
ceajog@elx7506426x:~/Downloads/curl-7.58.0$

Cheers,
Gustavo.

[Updated on: Tue, 06 March 2018 14:19]

Report message to a moderator

Re: Support for HTTP/2 in Eclipse Titan [message #1783091 is a reply to message #1783014] Wed, 07 March 2018 18:14 Go to previous messageGo to next message
Gustavo Gonnet is currently offline Gustavo GonnetFriend
Messages: 36
Registered: October 2015
Location: Montreal, Quebec, Canada
Member
Do you need Wireshark 2.5 on ubuntu 14.04?

Here's how I installed it from source:

- download latest source: https://www.wireshark.org/#download
- sudo apt-get install build-essential checkinstall libcurl4-openssl-dev bison flex qt5-default qttools5-dev libssl-dev libgtk-3-dev libpcap-dev
- sudo apt-get install qttools5-dev-tools
- cd wireshark_source_dir
- ./configure
- make
- sudo make install
- sudo ldconfig

Sources:
http://linuxtechlab.com/install-wireshark-linux-centosubuntu/#comment-431
https://www.wireshark.org/lists/wireshark-dev/201608/msg00119.html
https://stackoverflow.com/questions/20450893/usr-lib-i386-linux-gnu-qt5-bin-lrelease-not-found-warning-target-is-empty

Cheers,
Gustavo.
Re: Support for HTTP/2 in Eclipse Titan [message #1810653 is a reply to message #1783091] Thu, 15 August 2019 08:56 Go to previous messageGo to next message
Sean Kuo is currently offline Sean KuoFriend
Messages: 28
Registered: August 2019
Junior Member
Hi Elemer,

May I ask some hints or tips to run your deployed code?

I have done these steps below:

mkdir example7
cd example7
mkdir src
mkdir bin
cd src

git clone https://github.com/eclipse/titan.ProtocolModules.HTTP2.0.git
git clone git://git.eclipse.org/gitroot/titan/titan.ProtocolModules.http2.git
git clone https://github.com/eclipse/titan.TestPorts.HTTPmsg.git
git clone https://github.com/eclipse/titan.TestPorts.IPL4asp.git
git clone https://github.com/eclipse/titan.ProtocolModules.COMMON.git
git clone https://github.com/eclipse/titan.TestPorts.Common_Components.Socket-API.git

cd ../bin

sudo ln -s ../src/titan.ProtocolModules.HTTP2/src/* ~/example7/bin/
sudo ln -s ../src/titan.ProtocolModules.HTTP2.0/src/* ~/example7/bin/
sudo ln -s ../src/titan.TestPorts.HTTPmsg/src/* ~/example7/bin/
sudo ln -s ../src/titan.TestPorts.IPL4asp/src/* ~/example7/bin/
sudo ln -s ../src/titan.ProtocolModules.COMMON/src/* ~/example7/bin/
sudo ln -s ../src/titan.TestPorts.Common_Components.Socket-API/src/* ~/example7/bin/


And I have edit the http2_types in line 15 to all CAPS like below:

module http2   {

modulepar {

  charstring tsp_hostname:="nghttp2.org"; 
  charstring tsp_url:="/httpbin/ip" ;
  http2_start tsp_start:=alpn;
}

import from IPL4asp_Types all;
import from IPL4asp_PortType all;
import from HTTP_Types all;
import from HTTP_MessageLen all;
import from HTTP2_Types all;


//*************************************************************************
function f_http2_Message_len(  in octetstring stream,   inout ro_integer args) return integer
//*************************************************************************
{    
  return f_http2_msglen(stream, args) ;                 
}

type component GeneralComp
{
  port IPL4asp_PT p;
  timer t;    
  var IPL4asp_Types.Result  c_res:= { errorCode := omit, connId  := omit, os_error_code:=omit, os_error_text:= omit };   
}

type component SystemComp
{
  port IPL4asp_PT p;
}


type enumerated http2_start
  {
    alpn (0),
    upgrade_conn (1),
    prior_knowledge(2)
  }

template  http2_Frame t_http2_init_settings_frame:= {
      settings_frame :={
		ack_flag :=false,
		settings := {
{
 setting_id:=2, //SETTINGS_ENABLE_PUSH
 setting_value:=0
},
{
 setting_id:=3, //SETTINGS_MAX_CONCURRENT_STREAMS
 setting_value:=100
},
{
 setting_id:=4,//SETTINGS_INITIAL_WINDOW_SIZE
 setting_value:=1073741824//65536
}
}

}
}




template  http2_Frame t_http2_window_update_frame:= {
      window_update_frame :={
		stream_id :=0,
		window_size_increment := 1073676289
		}
}


template  http2_Frame t_http2_init_settings_frame_r:= {
      settings_frame :={
		ack_flag :=false,
		settings := *
		}
}



template  http2_Frame t_http2_init_settings_frame_ack:= {
      settings_frame :={
		ack_flag :=true,
		settings := omit 
}
}


template  http2_header_block t_http2_header_block:= {
pseudo_headers :={
 method:="GET",
  scheme:="http",
  authority:=tsp_hostname,
  path:=tsp_url,
  status:=omit
},
 headers :={{
  header_name:="accept",
  header_value:="*/*"
},
{
  header_name:="user-agent",
  header_value:="Titan"
}
}
}

template  http2_Frame t_http2_data_frame(in octetstring pdu):= {
      data_frame :={
  stream_id:=1,
  end_stream_flag :=false,
  data:=pdu,
  padding:=omit
}
}


template  http2_Frame t_http2_header_frame(in octetstring pdu):= {
      header_frame:=
{
   stream_id:=1,
  end_stream_flag :=true,
  end_header_flag :=true,
  priority_data:=omit,
  header_block_fragment:=pdu,
  padding:=omit
}

 }


template  ASP_Send t_data1(in integer p_id ) :={
  connId:=p_id,
  proto:=omit,
  msg:=ef_HTTP_Encode(valueof(t_message("")))
}


template  ASP_Send t_data2(in integer p_id, in octetstring pdu ) :={
  connId:=p_id,
  proto:=omit,
  msg:=pdu
}


template HTTP_Message t_message (in charstring payload) := {
  msg := {{request_line :={GET,tsp_url,1,1}},{
      host := tsp_hostname,
      connection := {{"Upgrade"},{"http2-Settings"}},
      upgrade := {{"h2c"}},
      http2_settings := "AAMAAABkAARAAAAAAAIAAAAA",
      user_agent := "Titan"

    },omit}
}with { optional "implicit omit" } 




 //*************************************************************************
testcase TC_http2() runs on GeneralComp system SystemComp {
 //*************************************************************************

  var ASP_RecvFrom v_ASP_RecvFrom;
  var IPL4asp_Types.Result  vl_result;
  var HTTP_Message v_HTTP_Message;		
  var http2_Frame v_http2_Frame;	
  var http2_comp_context v_http2_comp_context;
  var http2_decoder_error_descr v_err;
  var octetstring v_data:=''O, v_msg:=''O;
  var integer v_cid , v_ret 

  
  
  map(self:p, system:p); 

  vl_result := c_res;

if(tsp_start == alpn){

    vl_result :=f_IPL4_connect(p, tsp_hostname, 443,"",0, -1, {ssl := {} }, {{alpn_list:={"h2"}},{tls_hostname:=tsp_hostname}}  )
 }

 else  
 {
  vl_result :=f_IPL4_connect( p, tsp_hostname, 80,"",0, -1, {tcp := {} }, {} )
 }
 
  log("connect result",vl_result)

  if (not(ispresent(vl_result.connId)))  {  log("Could not connect");   stop;  } 
  v_cid:=vl_result.connId ;

if(tsp_start==upgrade_conn)
{
//register message length function of HTTP with IPL4:

//*************************************************************************
 //var f_IPL4_getMsgLen getMsg_Func := refers(f_HTTPMessage_len);
 //f_IPL4_setGetMsgLen(p,v_cid, getMsg_Func, {});
//*************************************************************************
// send connection upgrade request
 p.send(t_data1(v_cid));
   t.start(5.0) 
     
       alt 
        { 
              [] p.receive(ASP_RecvFrom:?) -> value v_ASP_RecvFrom	{ 
              v_HTTP_Message:= ef_HTTP_Decode(v_ASP_RecvFrom.msg) 
              log(v_HTTP_Message)              
              };
              [] t.timeout{log("Bye")}
        } 

}  else {}

//--------------------------------------------------------------------------

//register message length function of HTTP/2 with IPL4:

  //*************************************************************************
  var f_IPL4_getMsgLen getMsg_Func := refers(f_http2_Message_len);
  f_IPL4_setGetMsgLen(p,v_cid, getMsg_Func, {});
  //*************************************************************************
//init compression context
v_http2_comp_context:=http2_comp_context_init();
// send connection preface "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"
p.send(t_data2(v_cid,http2_connection_preface));
// send settings
p.send(t_data2(v_cid,f_http2_encode_frame(valueof(t_http2_init_settings_frame))));
// send window update
p.send(t_data2(v_cid,f_http2_encode_frame(valueof(t_http2_window_update_frame))));

if(not(tsp_start==upgrade_conn))
{
// send HEADER frame
http2_comp_context_encode(v_http2_comp_context,valueof(t_http2_header_block), v_data )
//http2_comp_context_decode(v_http2_comp_context,v_http2_header_block, v_data )
//log("v_http2_header_block",v_http2_header_block)
p.send(t_data2(v_cid,f_http2_encode_frame(valueof(t_http2_header_frame(v_data))))); 
}

  t.start(1.0) 

  alt 
  { 
    [] p.receive(ASP_RecvFrom:?) -> value v_ASP_RecvFrom { 
    
     f_http2_decode_frame(v_ASP_RecvFrom.msg, v_http2_Frame, v_err) 

     log("**********received frame:  ***********",v_http2_Frame)
     
      if (ischosen(v_http2_Frame.settings_frame))
      {
     if (match(v_http2_Frame,t_http2_init_settings_frame_ack ) ) 
     {  
     log("**********received init_settings_frame_ack   ") 
     repeat;
     } 
     else if  (match(v_http2_Frame, t_http2_init_settings_frame_r))
     {  
     log("**********received init_settings_frame    ") ;
     p.send(t_data2(v_cid,f_http2_encode_frame(valueof(t_http2_init_settings_frame_ack))));
     repeat;
     
     }
     
      }

    else  if (ischosen(v_http2_Frame.header_frame))
      {
      log("**********received header frame    ") ;
        var http2_header_block vl_http2_header_block
    
    http2_comp_context_decode(v_http2_comp_context,vl_http2_header_block, v_http2_Frame.header_frame.header_block_fragment )
    
     log("************received header block:  ",vl_http2_header_block)
     repeat;
      }

 else  if (ischosen(v_http2_Frame.data_frame))
      {
           log("*************received data_frame    ") ;
      }

 else  if (ischosen(v_http2_Frame.ping_frame))
      {
           log("*************received ping_frame    ") ;
      }

    };
    [] t.timeout{log("Bye")}

  }//endalt 

 http2_comp_context_free(v_http2_comp_context);
   
//----------------------------------------------------------------------------

  vl_result :=    f_IPL4_close(p, v_cid);
  log("close result",vl_result); 
  unmap(self:p, system:p); 
  setverdict(pass);

}//endtestcase


control{
execute(TC_http2());

}//endcontrol

}//endmodule  


I didn't change any other things of the above one

And I edited the config like this
[MODULE_PARAMETERS]

http2.tsp_hostname:="nghttp2.org"
http2.tsp_url:="/httpbin/get"
http2.tsp_start:=upgrade_conn 


After all of these steps,
I put this ttcn and cfg files in the bin filder and run the code with below command:
ttcn3_makefilegen -f -e http2 *.ttcn *.cc *.hh *.l *.y *.c *.h *.grp
make


And I get these error...
/home/seanwl/titan.core/Install/bin/compiler -L  \
general_typedefs.ttcn General_Types.ttcn http2.ttcn HTTP2_Types.ttcn HTTP_MessageLen.ttcn HTTPmsg_MessageLen.ttcn HTTPmsg_PortType.ttcn HTTPmsg_Types.ttcn HTTP_Types.ttcn http_www_w3_org_XML_1998_namespace.ttcn IPL4asp_Functions.ttcn IPL4asp_PortType.ttcn IPL4asp_Types.ttcn Socket_API_Definitions.ttcn UsefulTtcn3Types.ttcn XSD.ttcn  - general_typedefs.ttcn General_Types.ttcn http2.ttcn HTTP2_Types.ttcn HTTP_MessageLen.ttcn HTTPmsg_MessageLen.ttcn HTTPmsg_PortType.ttcn HTTPmsg_Types.ttcn HTTP_Types.ttcn http_www_w3_org_XML_1998_namespace.ttcn IPL4asp_Functions.ttcn IPL4asp_PortType.ttcn IPL4asp_Types.ttcn Socket_API_Definitions.ttcn UsefulTtcn3Types.ttcn XSD.ttcn
Notify: Parsing TTCN-3 module `general_typedefs.ttcn'...
Notify: Parsing TTCN-3 module `General_Types.ttcn'...
Notify: Parsing TTCN-3 module `http2.ttcn'...
Notify: Parsing TTCN-3 module `HTTP2_Types.ttcn'...
Notify: Parsing TTCN-3 module `HTTP_MessageLen.ttcn'...
Notify: Parsing TTCN-3 module `HTTPmsg_MessageLen.ttcn'...
Notify: Parsing TTCN-3 module `HTTPmsg_PortType.ttcn'...
Notify: Parsing TTCN-3 module `HTTPmsg_Types.ttcn'...
Notify: Parsing TTCN-3 module `HTTP_Types.ttcn'...
Notify: Parsing TTCN-3 module `http_www_w3_org_XML_1998_namespace.ttcn'...
Notify: Parsing TTCN-3 module `IPL4asp_Functions.ttcn'...
Notify: Parsing TTCN-3 module `IPL4asp_PortType.ttcn'...
Notify: Parsing TTCN-3 module `IPL4asp_Types.ttcn'...
Notify: Parsing TTCN-3 module `Socket_API_Definitions.ttcn'...
Notify: Parsing TTCN-3 module `UsefulTtcn3Types.ttcn'...
Notify: Parsing TTCN-3 module `XSD.ttcn'...
Notify: Checking modules...
IPL4asp_Functions.ttcn: In TTCN-3 module `IPL4asp_Functions':
 IPL4asp_Functions.ttcn:18.3-40: In import definition:
  IPL4asp_Functions.ttcn:18.3-40: error: There is no module with identifier `TCCInterface_Functions'
IPL4asp_Types.ttcn: In TTCN-3 module `IPL4asp_Types':
 IPL4asp_Types.ttcn:555.17-49: In constant definition `IPL4_ERROR_LENGTH':
  IPL4asp_Types.ttcn:555.38-49: error: There is no local or imported definition with name `ERROR_LENGTH'
http2.ttcn: In TTCN-3 module `http2':
 http2.ttcn:19.1-23.1: In function definition `f_http2_Message_len':
  http2.ttcn:22.3-37: In return statement:
   http2.ttcn:22.10-37: error: There is no local or imported definition with name `f_http2_msglen'
 http2.ttcn:45.1-64.1: In template definition `t_http2_init_settings_frame':
  http2.ttcn:45.11-21: error: There is no local or imported definition with name `http2_Frame'
 http2.ttcn:69.1-74.1: In template definition `t_http2_window_update_frame':
  http2.ttcn:69.11-21: error: There is no local or imported definition with name `http2_Frame'
 http2.ttcn:77.1-82.1: In template definition `t_http2_init_settings_frame_r':
  http2.ttcn:77.11-21: error: There is no local or imported definition with name `http2_Frame'
 http2.ttcn:86.1-91.1: In template definition `t_http2_init_settings_frame_ack':
  http2.ttcn:86.11-21: error: There is no local or imported definition with name `http2_Frame'
 http2.ttcn:94.1-111.1: In template definition `t_http2_header_block':
  http2.ttcn:94.11-28: error: There is no local or imported definition with name `http2_header_block'
 http2.ttcn:113.1-120.1: In template definition `t_http2_data_frame':
  http2.ttcn:113.11-21: error: There is no local or imported definition with name `http2_Frame'
 http2.ttcn:123.1-134.2: In template definition `t_http2_header_frame':
  http2.ttcn:123.11-21: error: There is no local or imported definition with name `http2_Frame'
 http2.ttcn:166.1-310.1: In testcase definition `TC_http2':
  http2.ttcn:172.19-31: In variable definition `v_http2_Frame':
   http2.ttcn:172.7-17: error: There is no local or imported definition with name `http2_Frame'
  http2.ttcn:173.26-45: In variable definition `v_http2_comp_context':
   http2.ttcn:173.7-24: error: There is no local or imported definition with name `http2_comp_context'
  http2.ttcn:174.33-37: In variable definition `v_err':
   http2.ttcn:174.7-31: error: There is no local or imported definition with name `http2_decoder_error_descr'
  http2.ttcn:231.1-47: In variable assignment:
   http2.ttcn:231.23-47: error: There is no local or imported definition with name `http2_comp_context_init'
  http2.ttcn:233.1-47: In send statement:
   http2.ttcn:233.15-46: In actual parameter list of template `@http2.t_data2':
    http2.ttcn:233.22-45: In parameter #2 for `pdu':
     http2.ttcn:233.22-45: error: There is no local or imported definition with name `http2_connection_preface'
  http2.ttcn:235.1-81: In send statement:
   http2.ttcn:235.15-80: In actual parameter list of template `@http2.t_data2':
    http2.ttcn:235.22-79: In parameter #2 for `pdu':
     http2.ttcn:235.22-79: error: There is no local or imported definition with name `f_http2_encode_frame'
  http2.ttcn:237.1-81: In send statement:
   http2.ttcn:237.15-80: In actual parameter list of template `@http2.t_data2':
    http2.ttcn:237.22-79: In parameter #2 for `pdu':
     http2.ttcn:237.22-79: error: There is no local or imported definition with name `f_http2_encode_frame'
  http2.ttcn:239.1-246.1: In if statement:
   http2.ttcn:242.1-86: In function or altstep instance:
    http2.ttcn:242.1-86: error: There is no local or imported definition with name `http2_comp_context_encode'
   http2.ttcn:245.1-82: In send statement:
    http2.ttcn:245.15-81: In actual parameter list of template `@http2.t_data2':
     http2.ttcn:245.22-80: In parameter #2 for `pdu':
      http2.ttcn:245.22-80: error: There is no local or imported definition with name `f_http2_encode_frame'
  http2.ttcn:250.3-299.3: In alt construct:
   http2.ttcn:254.6-67: In function or altstep instance:
    http2.ttcn:254.6-67: error: There is no local or imported definition with name `f_http2_decode_frame'
   http2.ttcn:258.7-273.7: In if statement:
    http2.ttcn:265.6-271.6: In if statement:
     http2.ttcn:268.6-90: In send statement:
      http2.ttcn:268.20-89: In actual parameter list of template `@http2.t_data2':
       http2.ttcn:268.27-88: In parameter #2 for `pdu':
        http2.ttcn:268.27-88: error: There is no local or imported definition with name `f_http2_encode_frame'
   http2.ttcn:275.5-284.7: In if statement:
    http2.ttcn:278.32-52: In variable definition `vl_http2_header_block':
     http2.ttcn:278.13-30: error: There is no local or imported definition with name `http2_header_block'
    http2.ttcn:280.5-124: In function or altstep instance:
     http2.ttcn:280.5-124: error: There is no local or imported definition with name `http2_comp_context_decode'
  http2.ttcn:301.2-46: In function or altstep instance:
   http2.ttcn:301.2-46: error: There is no local or imported definition with name `http2_comp_context_free'
IPL4asp_Functions.ttcn: In TTCN-3 module `IPL4asp_Functions':
 IPL4asp_Functions.ttcn:20.3-38.3: In function definition `f_setUpInterface':
  IPL4asp_Functions.ttcn:32.5-37.5: In for statement:
   IPL4asp_Functions.ttcn:34.7-35.70: In function or altstep instance:
    IPL4asp_Functions.ttcn:34.7-35.70: error: There is no local or imported definition with name `f_setIP'
 IPL4asp_Functions.ttcn:40.3-49.3: In function definition `f_setDownInterface':
  IPL4asp_Functions.ttcn:45.5-48.5: In for statement:
   IPL4asp_Functions.ttcn:47.7-43: In function or altstep instance:
    IPL4asp_Functions.ttcn:47.7-43: error: There is no local or imported definition with name `f_deleteIP'
Notify: Errors found in the input modules. Code will not be generated.
Makefile:158: recipe for target 'compile' failed
make: *** [compile] Error 1



I searched "There is no module with identifier `TCCInterface_Functions" and found out it is part of titan core.
And it lay peacefully in the titan core folder.

So I currently have no idea how to fix this compile error.
It would be wonderful if it isn't bother you too much offering me some hints.

Best Regards

Sean

[Updated on: Thu, 15 August 2019 08:57]

Report message to a moderator

Re: Support for HTTP/2 in Eclipse Titan [message #1810656 is a reply to message #1810653] Thu, 15 August 2019 09:50 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Sean,


pls do the follwing:

-download HTTP2.tgz
-decompress it to a folder say HTTP2


you will get a structure under HTTP2

/src
/bin
titan.ProtocolModules.COMMON
titan.ProtocolModules.HTTP2
titan.ProtocolModules.HTTP2.0
titan.TestPorts.Common_Components.Socket-API
titan.TestPorts.IPL4asp


-change to /bin
-clean the folder

rm *

-run the install.script

chmod +x ../src/install.script
../src/install.script

make


should now be OK

However, I suggest you try first some minimalistic example , like the HelloWorld that comes with Titan install, and continue only when you feel comfortable with Titan.


BR

Elemer
Re: Support for HTTP/2 in Eclipse Titan [message #1810750 is a reply to message #1810656] Mon, 19 August 2019 08:05 Go to previous messageGo to next message
Sean Kuo is currently offline Sean KuoFriend
Messages: 28
Registered: August 2019
Junior Member
Hi Elemer,

Thanks for your kindly reply first.
I have run a couple test of titan.TestPorts.STDINOUTmsg and hello in titan.core, and return to this http2 module test again.
The compilation by make was successfully, but I have some problem about how to execute it.
I executed by this command:
ttcn3_start ./http2 HTTP2.cfg


I got result like below:
ttcn3_start ./http2 HTTP2.cfg 
ttcn3_start: Starting the test suite
spawn /home/user1/titan.core/Install/bin/mctr_cli HTTP2.cfg

*************************************************************************
* TTCN-3 Test Executor - Main Controller 2                              *
* Version: CRL 113 200/6 R6A                                            *
* Copyright (c) 2000-2019 Ericsson Telecom 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            *
*************************************************************************

Using configuration file: HTTP2.cfg
MC@ubuntu: Unix server socket created successfully.
MC@ubuntu: Listening on TCP port 8035.
MC2> ubuntu is the default
spawn ././http2 ubuntu 8035
TTCN-3 Host Controller (parallel mode), version CRL 113 200/6 R6A
MC@ubuntu: New HC connected from localhost [127.0.0.1]. ubuntu: Linux 5.0.0-25-generic on x86_64.
cmtc
MC@ubuntu: Downloading configuration file to all HCs.
MC@ubuntu: Configuration file was processed on all HCs.
MC@ubuntu: Creating MTC on host localhost.
MC@ubuntu: MTC is created.
MC2> smtc
Executing all items of [EXECUTE] section.
MC2> MTC@ubuntu: connect result{ errorCode := omit, connId := 1, os_error_code := omit, os_error_text := omit }
MTC@ubuntu: { msg := { start_line := { status_line := { version_major := 1, version_minor := 1, status_code := 101, reason_phrase := "Switching Protocols" } }, headers := { accept := omit, accept_charset := omit, accept_encoding := omit, accept_language := omit, accept_ranges := omit, age := omit, allow := omit, authorization := omit, cache_control := omit, connection := { { "Upgrade" } }, content_disposition := omit, content_encoding := omit, content_language := omit, content_length := omit, content_location := omit, content_range := omit, content_type := omit, cookie := omit, dasl := omit, dav := omit, date := omit, depth := omit, destination := omit, etag := omit, expect := omit, expires := omit, forwarded := omit, fRom := omit, host := omit, http2_settings := omit, iF := omit, if_match := omit, if_modified_since := omit, if_none_match := omit, if_range := omit, if_schedule_tag_match := omit, if_unmodified_since := omit, last_modified := omit, location := omit, lock_token := omit, max_forwards := omit, mime_version := omit, ordering_type := omit, origin := omit, overwrite := omit, position := omit, pragma := omit, prefer := omit, preference_applied := omit, proxy_authenticate := omit, proxy_authorization := omit, range := omit, referer := omit, retry_after := omit, schedule_reply := omit, schedule_tag := omit, sec_websocket_accept := omit, sec_websocket_extensions := omit, sec_websocket_key := omit, sec_websocket_protocol := omit, sec_websocket_version := omit, server := omit, set_cookie := omit, slug := omit, strict_transport_security := omit, tE := omit, tImeout := omit, trailer := omit, transfer_encoding := omit, upgrade := { { "h2c" } }, user_agent := omit, vary := omit, via := omit, www_authenticate := omit, warning := omit, undefined_header_list := omit }, body := '000018040000000000000300000064000400100000000800000001000100002000'O } }
MTC@ubuntu: **********received frame:  ***********{ header_frame := { stream_id := 1, end_stream_flag := false, end_header_flag := true, priority_data := omit, header_block_fragment := '886196D07ABE940BEA436CCA08017D403B702DDC6DD53168DF5F8B1D75D0620D263D4C7441EA54012A409619085421621EA4D87A161D141FC2C4B0B216A4987423834D96970F0D03313636408FF2B4632752D522D3947216C5AC4A7F8602E00082E07F7686AA69D29AFCFF7C880AE152A9A74A6BF3408BF2B4B60E92AC7AD263D48F89DD0E8C1AB6E4C5934F408CF2B794216AEC3A4A4498F57F8A0FDA949E42C11D07275F4090F2B10F524B52564FAACAB1EB498F523F85A8E8A8D2CB'O, padding := omit } }
MTC@ubuntu: **********received header frame    
decoded header len 1 :status 200
decoded header len 24 date Mon, 19 Aug 2019 07:15:57 GMT
decoded header len 13 content-type application/json
decoded header len 3 access-control-allow-origin *
decoded header len 28 access-control-allow-credentials true
MTC@ubuntu: ************received header block:  { pseudo_headers := { method := omit, scheme := omit, authority := omit, path := omit, status := 200 }, headers := { { header_name := "date", header_value := "Mon, 19 Aug 2019 07:15:57 GMT" }, { header_name := "content-type", header_value := "application/json" }, { header_name := "access-control-allow-origin", header_value := "*" }, { header_name := "access-control-allow-credentials", header_value := "true" } } }
MTC@ubuntu: **********received frame:  ***********{ data_frame := { stream_id := 1, end_stream_flag := true, data := '7B0A20202261726773223A207B7D2C200A20202268656164657273223A207B0A2020202022486F7374223A20226E6768747470322E6F7267222C200A2020202022557365722D4167656E74223A2022546974616E220A20207D2C200A2020226F726967696E223A20223134302E3131332E3137392E32222C200A20202275726C223A2022687474703A2F2F6E6768747470322E6F72672F6874747062696E2F676574220A7D0A'O ("{\n  \"args\": {}, \n  \"headers\": {\n    \"Host\": \"nghttp2.org\", \n    \"User-Agent\": \"Titan\"\n  }, \n  \"origin\": \"140.113.___.___ \", \n  \"url\": \"http://nghttp2.org/httpbin/get\"\n}\n"), padding := omit } }
MTC@ubuntu: *************received data_frame    
MTC@ubuntu: close result{ errorCode := omit, connId := 1, os_error_code := omit, os_error_text := omit }
MC@ubuntu: Test execution finished.
Execution of [EXECUTE] section finished.
emtc
MC@ubuntu: Terminating MTC.
MC@ubuntu: MTC terminated.
MC2> exit
MC@ubuntu: Shutting down session.
MC@ubuntu: Shutdown complete.

I can see that ttcn has received message from http://nghttp2.org/httpbin/get\ successfully,
but I don't understand why there is not a verdict when the test is shut down.
I couldn't found any clue about missing verdict in the http2.ttcn file, could you please tell me what is going wrong here?

And like execution command, I would like to know what if I want to generate a makefile on my own, what is the correct command?
ttcn2_makefilegen -s -f HTTP2 *.ttcn *.cc *.hh

doesn't seems so right.

By the way, all of these testing projects, DNS and http2, I assigned for, only serve one goal: test my teammate's 5g network function.
I'm really grateful for your reply and guidance, but I don't want to being too bothering either.
So if you know where to acquire the minimal knowledge to achieve my goal, that would be really amazing, and I can ask question less trivial.

Best Regards

Sean

[Updated on: Mon, 19 August 2019 08:30]

Report message to a moderator

Re: Support for HTTP/2 in Eclipse Titan [message #1810763 is a reply to message #1810750] Mon, 19 August 2019 11:52 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Sean,


to see the details of the execution and the verdict , you need to look into the logfiles generated ( see *.log in /bin)
What you have attached is the console log, which typically is set for a summary information only.
Granularity of the logfiles generated can be changed in the config file, see reference guide.

Also, I'd recommend to look into auxiliary commands logmerge, logfilter, logformat.


There's no problem in generating your own Makefile, but you have to know exactly what you want to do .

At the first glance I see two problems with your attempt :

-s will generate a Makefile for single mode execution ; that has to be in sync with the intention expressed in the code;
I don't recommend you use it, it's for special cases only.

you did not include *.h, *.c files, please look into the attached Makefile and understand it first


You need 3 areas at minimum to cover to run your tests:

-TTCN-3 knowledge; for that the standard is sufficiently readable
-Titan knowledge; I suggest you look through the reference guide
-Domain specific knowledge (such as DNS and HTTP/2)-that is beside the scope of this forum

for the first two we have also published training material


Ericsson TTCN-3 Course, Presentation material
https://www.eclipse.org/downloads/download.php?file=/titan/TTCN3_Course_PartI_EclipseLicensed.pdf

Ericsson TTCN-3 Course, Presentation material, part II (Titan specifics)
https://www.eclipse.org/downloads/download.php?file=/titan/TTCN3_Course_PartII_EclipseLicensed.pdf



I hope this helps

Best regards
Elemer


Re: Support for HTTP/2 in Eclipse Titan [message #1814233 is a reply to message #1810763] Fri, 06 September 2019 08:54 Go to previous messageGo to next message
Sean Kuo is currently offline Sean KuoFriend
Messages: 28
Registered: August 2019
Junior Member
Hi Elemer,

Thanks for your every reply, they contains so many precious information for my work with titan.
Now I have to come back to dabble with http2, and keep annoying you, hope that you don't mind.

For this simplyfied part of TS29518_Namf_Communication.ttcn:
external function f_enc_AmfStatusChangeNotification(in AmfStatusChangeNotification pdu) return octetstring 
with { extension "prototype(convert) encode(JSON)" }

external function f_dec_AmfStatusChangeNotification(in octetstring stream, out AmfStatusChangeNotification pdu) return integer 
with { extension "prototype(backtrack) decode(JSON)" }

    type set AmfStatusChangeNotification {
        set of       AmfStatusInfo    amfStatusInfoList optional
    }

    type set AmfStatusInfo {
        set of       TS29571_CommonData.Guami    guamiList optional,
        StatusChange    statusChange,
        TS29571_CommonData.AmfName    targetAmfRemoval optional,
        TS29571_CommonData.AmfName    targetAmfFailure optional
    }
    type union StatusChange {
        StatusChange_enum  enum_val,
        charstring           other_val
    } with {
        variant "JSON: as value"
    }
  
  type enumerated StatusChange_enum { AMF_UNAVAILABLE, AMF_AVAILABLE}


And assumed I have programmed a template for the JSON.
(Here is a question, how did you program that JSON_PDU template of geoplugin? I don't even know what data would be in this AmfStatusChangeNotification)
template AmfStatusChangeNotification t_jsonTemplate :=
{
	/*
    bla bla bla
    how to I program this part
    abracadabra
    may be in some 3gpp doc?
    */
}


Would the encoding and decoding be like this?:
var octetstring v_encodedPDU := f_enc_AmfStatusChangeNotification(valueof(t_jsonTemplate));
var integer v_decodedPDU := f_dec_AmfStatusChangeNotification(v_encodedPDU, t_jsonTemplate);


And if I want to send and receive some JSON to a server in the most simple http2 way, would it looks like these?
p.send(t_data2(v_cid,f_HTTP2_encode_frame( v_encodedPDU )));


p.receive(ASP_RecvFrom:?) -> value v_ASP_RecvFrom { 
    f_HTTP2_decode_frame(v_ASP_RecvFrom.msg, v_HTTP2_Frame, v_err) 
        if (ischosen(v_HTTP2_Frame.data_frame))
        {
            var HTTP2_I_dont_know_block vl_HTTP2_I_dont_know_block  //currently have no idea what should be here...
            HTTP2_comp_context_decode(v_HTTP2_comp_context, vl_HTTP2_I_dont_know_block, v_HTTP2_Frame.data_frame.I_dont_know_block_fragment
            var integer v_decodedPDU := f_dec_AmfStatusChangeNotification(vl_HTTP2_I_dont_know_block, t_jsonTemplate)
        }
};


Best regards

Sean

[Updated on: Fri, 06 September 2019 08:55]

Report message to a moderator

Re: Support for HTTP/2 in Eclipse Titan [message #1814259 is a reply to message #1814233] Fri, 06 September 2019 15:07 Go to previous message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Sean,

Here you have the answers in order:
1.
You need to download the standards

https://www.3gpp.org/ftp/Specs/archive/29_series/29.502/
They will explain the message flow etc.
2.
Yes, encoding/decoding should look like that.

3. Message sending is a bit more complicated.

The template will be first encoded into a JSON represented in octetstring. This will be made the payload of an HTTP/2 data frame. That will also have to be encoded into an octetstring and made the payload of an ASP_SEND (encoding/decoding of each layer will have to appear explicitly).
This data frame will have to be preceded by init frame etc.

4. When receiving, the JSON payload of the data frame has to be extracted and decoded.


I hope this helps.


BR
Elemer

Previous Topic:Titan 6.6.0 in Debian testing/unstable
Next Topic:How to reference union value in another module?
Goto Forum:
  


Current Time: Tue Apr 23 11:22:08 GMT 2024

Powered by FUDForum. Page generated in 0.03683 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top