sgk / sip-js

Automatically exported from code.google.com/p/sip-js
0 stars 0 forks source link

Response to REGISTER cannot be parsed #13

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. Use WebRTC, websocket connection
2. Register
3. Incoming message cannot be parsed

What is the expected output? What do you see instead?
Expected to see incoming response to REGISTER from server
Instead parse error displayed (output below)
Problem on sip.js

What version of the product are you using? On what operating system?
Latest version (checkout with SVN), Windows 7 OS (64 bit)

Please provide any additional information below.
detecting HTML support websocket=true video=true webrtc=true
register() "MelihLaptop" <sip:903122924321@officesip.local>
createSocket() transport=ws
  connecting to localhost:5006
socket connected=false
register() "MelihLaptop" <sip:903122924321@officesip.local>
createSocket() transport=ws
  connecting to localhost:5060
websocket connected
socket connected=true
=> 127.0.0.1:5060
REGISTER sip:officesip.local SIP/2.0
Via: SIP/2.0/WS 
r7292684279.invalid;rport;branch=z9hG4bKMDcwODU0M2Q2ZWJkNDlhMmE5NzZlNTFmMzk0YTJj
ZGI.
From: "MelihLaptop" <sip:903122924321@officesip.local>;tag=34429933146994790215
To: "MelihLaptop" <sip:903122924321@officesip.local>
Call-ID: 4982840256@r7292684279.invalid
CSeq: 1 REGISTER
Max-Forwards: 70
Contact: 
<sip:903122924321@r7292684279.invalid>;reg-id=1;+sip.instance="<urn:uuid:7f40120
2-5aae-4d9d-8a58-5b8a8a04824e>"
Route: <sip:localhost:5060;lr;transport=ws>
Content-Length: 0
Supported: path, outbound, gruu
Expires: 180

<= 127.0.0.1:0
[object Blob]
Error in received message: TypeError: Object #<Blob> has no method 'indexOf'
TypeError: Object #<Blob> has no method 'indexOf'
    at Message._parse (http://localhost:5060/sip.js:962:35)
    at Stack.received (http://localhost:5060/sip.js:2473:15)
    at Phone.onSockData (http://localhost:5060/phone.js:1363:17)
    at Phone.onWebSocketMessage (http://localhost:5060/phone.js:1392:10)
    at WebSocket._sock.onmessage (http://localhost:5060/phone.js:457:59)

Original issue reported on code.google.com by mel...@gmail.com on 6 Dec 2012 at 12:53

GoogleCodeExporter commented 9 years ago
You can replace the following code instead of the existing 
Message.prototype._parse:

function readBlob(value, m) {

        var start = 0;
        var stop = value.size - 1;

        var reader = new FileReader();

        // If we use onloadend, we need to check the readyState.
        reader.onloadend = function(evt) {
          if (evt.target.readyState == FileReader.DONE) { // DONE == 2

              handleMessage(evt.target.result, m);
          }
        };

        var blob = value.slice(start, stop + 1);
        reader.readAsBinaryString(blob);
    }

    Message.prototype._parse = function(value) {
        readBlob(value, this);
    }

    function handleMessage(value, m) {
        var indexCRLFCRLF = value.indexOf("\r\n\r\n");
        var indexLFLF = value.indexOf("\n\n");
        var firstheaders, body;
        if (indexCRLFCRLF >=0 && indexLFLF >= 0) {
            // use lower value
            if (indexCRLFCRLF < indexLFLF)
                indexLFLF = -1;
            else
                indexCRLFCRLF = -1;
        }
        else if (indexCRLFCRLF < 0 && indexLFLF < 0)  {
            log("Message.parse() did not find LFLF or CRLFCRLF");
        }

        if (indexCRLFCRLF >= 0) {
            firstheaders = value.substr(0, indexCRLFCRLF);
            body = value.substr(indexCRLFCRLF+4);
        }
        else if (indexLFLF >= 0) {
            firstheaders = value.substr(0, indexLFLF);
            body = value.substr(indexLFLF+2);
        }
        else {
            firstheaders = value;
            body = ''; // no body
        }
        var firstline, headers;
        var indexLF = firstheaders.indexOf("\n");
        if (indexLF > 0 && firstheaders.charAt(indexLF-1) == "\r") {
            firstline = firstheaders.substr(0, indexLF-1);
            headers = firstheaders.substr(indexLF+1);
        }
        else if (indexLF > 0) {
            firstline = firstheaders.substr(0, indexLF);
            headers = firstheaders.substr(indexLF+1);
        }

        var parts = firstline.split(" ");
        if (parts.length < 3) {
            throw new String("not enough parts in first line");
        }

        if (parts[1].match(/^\d+$/)) {
            this.protocol = parts.shift();
            this.response = parseInt(parts.shift());
            this.responsetext = parts.join(" ");
        }
        else if (parts.length > 3) {
            throw new String("invalid number of parts in request line");
        }
        else {
            this.method = parts[0];
            this.uri = new sip.URI(parts[1]);
            this.protocol = parts[2];
        }

        parts = headers.split("\n");
        for (var i=0; i<parts.length; ++i) {
            var h = parts[i];
            if (h && h.charAt(h.length-1) == "\r") {
                h = h.substr(0, h.length-1);
            }
            if (h.charAt(0) == " " || h.charAt(0) == "\t") {
                // need to handle the line folding
            }
            try {
                var hdrs = sip.Header.createHeaders(h);
                var name = hdrs[0];
                var values = hdrs[1];
                if (!m.hasItem(name)) {
                    m.setItem(name, values.length > 1 ? values : values[0])
                }
                else if (Message._single.indexOf(name) < 0) {
                    var existing = m.getItem(name);
                    if (!sip.is_array(existing)) {
                        m.setItem(name, [existing]);
                    }
                    existing = m.getItem(name);
                    for (var j=0; j<values.length; ++j) {
                        existing.push(values[j]);
                    }
                }
            }
            catch (e) {
                log("error parsing " + h);
                if (e['stack'] !== undefined)
                    log(e.stack);
                else
                    log(e);
                continue;
            }
        }

        var bodyLen = (m.hasItem('Content-Length') ? parseInt(m.getItem('Content-Length').value) : 0);
        if (body) {
            m.setBody(body);

            if (bodyLen != body.length) {
                throw new String("invalid content length " + bodyLen + " != " + body.length);
            }
        }
        var mandatory = ["To", "From", "CSeq", "Call-ID"];
        for (var k=0; k<mandatory.length; ++k) {
            if (!m.hasItem(mandatory[k])) {
                throw new String("mandatory header " + mandatory[k] + " is missing");
            }
        }
    };

Original comment by shahar.b...@gmail.com on 16 Jan 2013 at 9:32