nuclearace / Socket.IO-Client-Swift

socket.io-client for Swift
Other
361 stars 53 forks source link

Incorrect calculation of packet length in the module SocketEnginePollable.swift #105

Closed twox closed 8 years ago

twox commented 8 years ago

The line code: let len = packet.characters.count is not correct calculate the length of packet because server will be to receive this packet in UTF8-encoding and for chars \n will added \r. Need use this function for it: let len = packet.lengthOfBytesUsingEncoding(NSUTF8StringEncoding) ` func createRequestForPostWithPostWait() -> NSURLRequest {

    var postStr = ""

    for packet in postWait {
        let len = packet.characters.count

        postStr += "\(len):\(packet)"
    }

    DefaultSocketLogger.Logger.log("Created POST string: %@", type: "SocketEnginePolling", args: postStr)

    postWait.removeAll(keepCapacity: false)

    let req = NSMutableURLRequest(URL: urlPollingWithSid)

    addHeaders(req)

    req.HTTPMethod = "POST"
    req.setValue("text/plain; charset=UTF-8", forHTTPHeaderField: "Content-Type")

    let postData = postStr.dataUsingEncoding(NSUTF8StringEncoding,
        allowLossyConversion: false)!

    req.HTTPBody = postData
    req.setValue(String(postData.length), forHTTPHeaderField: "Content-Length")

    return req
}

`

nuclearace commented 8 years ago

Hm, the thing is, engine.io isn't counting the length of the bytes, it's strictly counting the number of characters. So using lengthOfBytesUsingEncoding seems to break things a lot more.

twox commented 8 years ago

Try to insert this code after line: let len = packet.characters.count

           let len2 = packet.lengthOfBytesUsingEncoding(NSUTF8StringEncoding)
            NSLog("len=\(len), len2=\(len2)")

Then will send the packet with NSData and you will see that len != len2 It's look like:

len=1050, len2=1066
LOG SocketEnginePolling: Created POST string: 49:451-["new message",{"num":0,"_placeholder":true}]1050:b4/9j/4AAQSkZJRgABAQAASABIAAD/4QBMRXhpZgAATU0AKgAAAAgAAgESAAMAAAAB
AAEAAIdpAAQAAAABAAAAJgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAA
AAD/7QA4UGhvdG9zaG9wIDMuMAA4QklNBAQAAAAAAAA4QklNBCUAAAAAABDUHYzZ
jwCyBOmACZjs+EJ+/8AAEQgAAQABAwERAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAA
AAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFB
BhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNE
RUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqi
o6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz
9PX29/j5+v/EAB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIB
AgQEAwQHBQQEAAECdwABAgMRBAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy
0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpz
dHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXG
x8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/bAEMAAQEBAQEBAQEBAQEB
AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB
AQEBAf/bAEMBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB
AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAf/dAAQAAf/aAAwDAQACEQMRAD8A/cCv
x8/YD//Z
nuclearace commented 8 years ago

Right, but using lengthOfBytesUsingEncoding seems to cause engine.io to fail with parse errors.

Right now if you do

socket.emit("stringTest", "lïne one\nlīne \rtwo")

The post packet will be 41:42["stringTest","lïne one\nlīne \rtwo"]

Which if you check what socket.io/engine.io sends from the server it's the same

41:42["stringTest","lïne one\nlīne \rtwo"]

twox commented 8 years ago

After send this packet to the socket.io server, server was closed connection, because the packet was with incorrect the length. After fixing code, error was disappeared

nuclearace commented 8 years ago

What does the exact emit look like

twox commented 8 years ago

Test code for send your message: 2016-01-29 23-35-28 iphone 6s ios 9 1 - iphone 6s ios 9 1 13b143

Not Fixed code: 2016-01-29 23-42-36 socketenginepollable swift edited Not Fixed: Log: 2016-01-29 23-36-39 iphone 6s ios 9 1 - iphone 6s ios 9 1 13b143 Not Fixed: Result: 2016-01-29 23-34-37 iphone 6s ios 9 1 - iphone 6s ios 9 1 13b143

Looks like good!

Fixed code: 2016-01-29 23-49-31 socketenginepollable swift

Fixed: Log:

2016-01-29 23-53-57 socketenginepollable swift

Fixed: Result: You right, for this test packet server broken connection. But for me it working... How to resolve this problem?

nuclearace commented 8 years ago

What are you trying to send that's causing it to break? And is the server running the latest socket.io version?

twox commented 8 years ago

I'm use last version socket.io I'm send image converted to NSData like this:

if let data = UIImageJPEGRepresentation(image, 1) {
   socket?.emit("new message", data)
}

Result you see in my second post

nuclearace commented 8 years ago

Okay I see what's going on. I'll push a new version

twox commented 8 years ago

Thanks, I will look forward to

nuclearace commented 8 years ago

Should be fixed in 5.3.1

nuclearace commented 8 years ago

The problem was because I was adding new lines to the base64, which apparently causes socket.io to explode.

twox commented 8 years ago

Thank you! Everything right working!