Commits

Paweł Wieczorek  committed fb91674 Draft

more tests

  • Participants
  • Parent commits f48cbf1

Comments (0)

Files changed (4)

File src/Sip_parser.ml

 open Sip_types
 
 (********************************************************************************************************************
- * Parsed request 
+ * Parsed request and response
  *)
 
 class parsed_sip_request _reqmethod _uri _version mime : sip_request =
 
     end
 
+class parsed_sip_response _response msg _version mime : sip_response =
+
+        (* compute and extract required informations *)
+
+        let response       = sip_response_code_of_string (int_of_string _response) in
+
+        let content_length = int_of_string (Hashtbl.find mime "content-length") in
+
+        let addr_from      = sip_address_of_string (Hashtbl.find mime "from") in
+
+        let addr_to        = sip_address_of_string (Hashtbl.find mime "to") in
+
+        let call_id        = sip_call_id_of_string (Hashtbl.find mime "call-id") in
+
+        let cseq           = sip_cseq_of_string (Hashtbl.find mime "cseq") in
+
+        let vias           = Hashtbl.find_all mime "via" in
+
+        let version        = sip_version_of_string _version in
+
+        let sip_contact    = Option.map sip_address_of_string (Hashtbl.find_option mime "contact") in
+
+        (* construct object *)
+
+    object
+
+        val mime                = mime
+
+        method sip_response_code = response
+
+        method sip_response_message = msg
+
+        method sip_version      = version
+
+        method content_length   = content_length
+
+        method addr_to          = addr_to
+
+        method addr_from        = addr_from
+
+        method vias             = List.map sip_via_of_string vias
+
+        method call_id          = call_id
+
+        method cseq             = cseq
+
+        method contact          = sip_contact
+
+        method header name      = Hashtbl.find mime name
+
+        method header_option name = Hashtbl.find_option mime name
+
+        method header_all name  = Hashtbl.find_all mime name
+
+    end
 (********************************************************************************************************************
  * Parser for request 
  *
     let (_,         last) = find_endline last buffer in
     (reqmethod, uri, ver, last)
 
+let parse_response_line buffer =
+    let (ver,   last) = find_word 0     buffer in
+    let (code,  last) = find_word last  buffer in
+    let (msg,   last) = find_endline last  buffer in
+    (ver, code, msg, last)
+
 let parse_mime buffer =
     let htable = Hashtbl.create 27 in
 
         Not_found | Invalid_argument _ ->
             raise Invalid_sip_message
 
+let early_parse_response buffer =
+    try
+        let (sipver, code, msg, last)      = parse_response_line buffer in
+        let (mime, last)                   = parse_mime buffer last in
+        (sipver, code, msg, mime, last)
+    with
+        Not_found | Invalid_argument _ ->
+            raise Invalid_sip_message
+
 let parse_request buffer : sip_request =
     let (reqmethod, uri, sipver, mime, last) = early_parse_request buffer in
     try
         Not_found | Failure _ ->
             raise Invalid_sip_message
 
+let parse_response buffer =
+    let (sipver, code, msg,  mime, last) = early_parse_response buffer in
+    try
+        new parsed_sip_response code msg sipver mime
+    with
+        Not_found | Failure _ ->
+            raise Invalid_sip_message
+
+type sip_parsed_message
+    = Request of sip_request
+    | Response of sip_response
+
+let sip_message_from_parsed = function
+    | Request  s -> (s : sip_request  :> sip_message)
+    | Response s -> (s : sip_response :> sip_message)
+
+let parse_message buffer =
+    if String.starts_with buffer "SIP/"
+    then Response (parse_response buffer)
+    else Request  (parse_request buffer)
+
+
+

File src/Sip_types.ml

 type sip_via =
     | SipVia of string
 
-class type sip_request =
+class type sip_message =
     object
 
-        method sip_method       : sip_request_method
-
         method sip_version      : sip_version
 
-        method uri              : sip_uri
-
         method content_length   : int
 
         method addr_to          : sip_address
 
         method cseq             : sip_cseq
 
-        method max_forwards     : int
-
         method contact          : sip_address option
 
         method header           : string -> string
 
         method header_all       : string -> string list
 
+    end
+
+class type sip_request =
+    object
+
+        method sip_method       : sip_request_method
+
+        method uri              : sip_uri
+
+        method max_forwards     : int
+
+        inherit sip_message
+
+    end
+
+class type sip_response =
+    object
+
+        method sip_response_code    : sip_response_code
+
+        method sip_response_message : string
+
+        inherit sip_message
 
     end
 
 
     | OtherResponse i -> i
 
+let sip_response_code_of_string = function
+    | i -> OtherResponse i
+
+
 let sip_version_of_string = function
     | "SIP/1.0" ->
         SIP_1_0

File tests/Test_parser.ml

  * Checking message against description
  *)
 
-let validate_message request = function
+let _validate_message message parsed_message = function
     | DescrMimeField (field, expected) ->
         begin try
-            let actual = request#header (String.lowercase field) in
+            let actual = message#header (String.lowercase field) in
             assert_str_equal ("mime field " ^ field) expected actual
         with Not_found ->
             failwith ("Cannot find header " ^ field)
         end
 
     | DescrMimeFields (field, expected) ->
-        let actual = request#header_all (String.lowercase field) in
+        let actual = message#header_all (String.lowercase field) in
         assert_strs_equal ("mime fields " ^ field) expected actual
 
     | DescrContentLength expected ->
-        let extracted = request#content_length in
-        validate_extracted_field request
+        let extracted = message#content_length in
+        validate_extracted_field message
             int_of_string string_of_int
             "content-length" extracted expected
 
     | DescrMaxForwards expected ->
-        let extracted = request#max_forwards in
-        validate_extracted_field request
-            int_of_string string_of_int
-            "max-forwards" extracted expected
+        begin match parsed_message with
+            | Sip_parser.Request request ->
+                let extracted = request#max_forwards in
+                validate_extracted_field message
+                    int_of_string string_of_int
+                    "max-forwards" extracted expected
+
+            | _ ->
+                failwith "Message is not REQUEST"
+
+        end
+
 
     | DescrSipVersion expected ->
-        let extracted = request#sip_version in
+        let extracted = message#sip_version in
         assert_equal
             ~msg:"incorrect sip version"
             ~printer:string_of_sip_version
             expected extracted
 
     | DescrSipMethod expected ->
-        let extracted = request#sip_method in
-        assert_equal
-            ~msg:"incorrect sip method"
-            ~printer:string_of_sip_request_method
-            expected extracted
+        begin match parsed_message with
+            | Sip_parser.Request request ->
+                let extracted = request#sip_method in
+                assert_equal
+                    ~msg:"incorrect sip method"
+                    ~printer:string_of_sip_request_method
+                    expected extracted
+
+            | _ ->
+                failwith "Message is not REQUEST"
+
+        end
 
     | DescrUri expected ->
-        let extracted = request#uri in
-        assert_equal
-            ~msg:"incorrect reques uri"
-            ~printer:string_of_sip_uri
-            expected extracted
+        begin match parsed_message with
+            | Sip_parser.Request request ->
+                let extracted = request#uri in
+                assert_equal
+                    ~msg:"incorrect reques uri"
+                    ~printer:string_of_sip_uri
+                    expected extracted
+
+            | _ ->
+                failwith "Message is not REQUEST"
+        end
 
     | DescrCseq expected ->
-        let extracted = request#cseq in
-        validate_extracted_field request
+        let extracted = message#cseq in
+        validate_extracted_field message
             sip_cseq_of_string string_of_sip_cseq
             "cseq" extracted expected
 
     | DescrCallId expected ->
-        let extracted = request#call_id in
-        validate_extracted_field request
+        let extracted = message#call_id in
+        validate_extracted_field message
             sip_call_id_of_string string_of_sip_call_id
             "call-id" extracted expected
 
     | DescrTo expected ->
-        let extracted = request#addr_to in
-        validate_extracted_field request
+        let extracted = message#addr_to in
+        validate_extracted_field message
             sip_address_of_string string_of_sip_address
             "to" extracted expected
 
     | DescrFrom expected ->
-        let extracted = request#addr_from in
-        validate_extracted_field request
+        let extracted = message#addr_from in
+        validate_extracted_field message
             sip_address_of_string string_of_sip_address
             "from" extracted expected
 
     | DescrVia expected ->
-        let extracted = request#vias in
-        validate_extracted_field_all request
+        let extracted = message#vias in
+        validate_extracted_field_all message
             sip_via_of_string string_of_sip_via
             "via" extracted expected
 
     | DescrContact expected ->
-        let extracted = request#contact in
-        validate_extracted_field_option request
+        let extracted = message#contact in
+        validate_extracted_field_option message
             sip_address_of_string string_of_sip_address
             "contact" extracted expected
 
+    | _ ->
+        ()
+
+let validate_message parsed_message =
+    _validate_message (Sip_parser.sip_message_from_parsed parsed_message) parsed_message
+
 (*********************************************************************************************************************
  * Test generators
  *)
 let valid_message_parse_test (title, buffer, descr) = 
     "valid message -- " ^ title >::
     begin fun () ->
-        let request = Sip_parser.parse_request buffer in
-        List.iter (validate_message request) descr
+        let parsed_message = Sip_parser.parse_message buffer in
+        List.iter (validate_message parsed_message) descr
     end
 
 let invalid_message_parse_test (title, buffer) =
     "invalid message -- " ^ title >::
     begin fun () ->
-        assert_raises Sip_parser.Invalid_sip_message (fun () -> Sip_parser.parse_request buffer)
+        assert_raises Sip_parser.Invalid_sip_message
+            (fun () -> Sip_parser.parse_message buffer)
     end
 
 (*********************************************************************************************************************

File tests/data/Testdata_messages.ml

         | DescrFrom of sip_address
         | DescrVia of sip_via list
         | DescrContact of sip_address option
+        | DescrResponseCode of sip_response_code
+        | DescrResponseMessage of string
 
     let descr_content_length i = DescrContentLength i
     let descr_sip_version i    = DescrSipVersion i
 
     let descr_no_contact       = DescrContact None
     let descr_contact c        = DescrContact (Some c)
+
+    let descr_response_code c    = DescrResponseCode c
+    let descr_response_message c = DescrResponseMessage c
 end
 
 module Valid_messages = struct
                 ]
             ]
 
-        ]
-
-
-    let response =
-        [ prepare_valid_message "sip response from RFC3261.4"
+        ; prepare_valid_message "sip response from RFC3261.4"
             [ "SIP/2.0 200 OK"
             ; "Via: SIP/2.0/UDP server10.biloxi.com"
-            ; "   ;branch=z9hG4bKnashds8;received=192.0.2.3"
+            ; " ;branch=z9hG4bKnashds8;received=192.0.2.3"
             ; "Via: SIP/2.0/UDP bigbox3.site3.atlanta.com"
-            ; "   ;branch=z9hG4bK77ef4c2312983.1;received=192.0.2.2"
+            ; " ;branch=z9hG4bK77ef4c2312983.1;received=192.0.2.2"
             ; "Via: SIP/2.0/UDP pc33.atlanta.com"
-            ; "   ;branch=z9hG4bK776asdhds ;received=192.0.2.1"
+            ; " ;branch=z9hG4bK776asdhds ;received=192.0.2.1"
             ; "To: Bob <sip:bob@biloxi.com>;tag=a6c85cf"
             ; "From: Alice <sip:alice@atlanta.com>;tag=1928301774"
             ; "Call-ID: a84b4c76e66710@pc33.atlanta.com"
             ; String.repeat "a" 131
             ]
 
-            [
+            [ descr_response_code
+                RESP_200_OK
+
+            ; descr_response_message
+                "OK"
+
+            ; descr_to
+                (sip_address_of_string "Bob <sip:bob@biloxi.com>;tag=a6c85cf")
+
+            ; descr_from
+                (sip_address_of_string "Alice <sip:alice@atlanta.com>;tag=1928301774")
+
+            ; descr_contact
+                (sip_address_of_string "<sip:bob@192.0.2.4>")
+
+            ; descr_mime_field "Content-type"
+                "application/sdp"
+
+            ; descr_via
+                [ sip_via_of_string
+                    "SIP/2.0/UDP server10.biloxi.com;branch=z9hG4bKnashds8;received=192.0.2.3"
+                ; sip_via_of_string
+                    "SIP/2.0/UDP bigbox3.site3.atlanta.com;branch=z9hG4bK77ef4c2312983.1;received=192.0.2.2"
+                ; sip_via_of_string
+                    "SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK776asdhds ;received=192.0.2.1"
+                ]
             ]
 
          ; prepare_valid_message "sip response from RFC3261.11"
             ; String.repeat "a" 274
             ]
 
-            [
+            [ descr_response_code 
+                RESP_200_OK
+
+            ; descr_response_message
+                "OK"
+
+            ; descr_from
+                (sip_address_of_string "Alice <sip:alice@atlanta.com>;tag=1928301774")
+
+            ; descr_to
+                (sip_address_of_string "<sip:carol@chicago.com>;tag=93810874")
+
+            ; descr_mime_fields "Supported"
+                [ "foo"
+                ]
+
+            ; descr_mime_field "Accept"
+                "application/sdp"
+
+            ; descr_mime_field "Accept-encoding"
+                "gzip"
+
+            ; descr_mime_field "Accept-language"
+                "en"
+
+            ; descr_mime_field "Allow"
+                "INVITE, ACK, CANCEL, OPTIONS, BYE"
+
             ]
 ]
 
             ; String.repeat "a" 142
             ]
 
+        ; prepare_invalid_message "sip response from RFC3261.4, without the CSeq header"
+            [ "SIP/2.0 200 OK"
+            ; "Via: SIP/2.0/UDP server10.biloxi.com"
+            ; " ;branch=z9hG4bKnashds8;received=192.0.2.3"
+            ; "Via: SIP/2.0/UDP bigbox3.site3.atlanta.com"
+            ; " ;branch=z9hG4bK77ef4c2312983.1;received=192.0.2.2"
+            ; "Via: SIP/2.0/UDP pc33.atlanta.com"
+            ; " ;branch=z9hG4bK776asdhds ;received=192.0.2.1"
+            ; "To: Bob <sip:bob@biloxi.com>;tag=a6c85cf"
+            ; "From: Alice <sip:alice@atlanta.com>;tag=1928301774"
+            ; "Call-ID: a84b4c76e66710@pc33.atlanta.com"
+            ; "Contact: <sip:bob@192.0.2.4>"
+            ; "Content-Type: application/sdp"
+            ; "Content-Length: 131"
+            ; ""
+            ; String.repeat "a" 131
+            ]
+
+        ; prepare_invalid_message "sip response from RFC3261.4, without the Call-ID header"
+            [ "SIP/2.0 200 OK"
+            ; "Via: SIP/2.0/UDP server10.biloxi.com"
+            ; " ;branch=z9hG4bKnashds8;received=192.0.2.3"
+            ; "Via: SIP/2.0/UDP bigbox3.site3.atlanta.com"
+            ; " ;branch=z9hG4bK77ef4c2312983.1;received=192.0.2.2"
+            ; "Via: SIP/2.0/UDP pc33.atlanta.com"
+            ; " ;branch=z9hG4bK776asdhds ;received=192.0.2.1"
+            ; "To: Bob <sip:bob@biloxi.com>;tag=a6c85cf"
+            ; "From: Alice <sip:alice@atlanta.com>;tag=1928301774"
+            ; "CSeq: 314159 INVITE"
+            ; "Contact: <sip:bob@192.0.2.4>"
+            ; "Content-Type: application/sdp"
+            ; "Content-Length: 131"
+            ; ""
+            ; String.repeat "a" 131
+            ]
+
         ]
 
 end