daltoniam / Starscream

Websockets in swift for iOS and OSX
Apache License 2.0
8.28k stars 1.2k forks source link

BUFFER_MAX too small in certain cases? #105

Closed ghost closed 9 years ago

ghost commented 9 years ago

I am using the Swift 2.0 branch and was attempting to connect to a wss service on IBM Bluemix and the connection would always fail. I tracked it down to the server returning a large amount of data (> BUFFER_MAX) resulting in multiple reads to clear the buffer.

Specifically, the first read of the buffer would contain the response status (101) and the Sec-WebSocket-Accept header. However, since the trailing cr-newline-cr-newline would not be found in the first read due to a large header (Set-Cookie), validateResponse would not be called.

In the second read of the buffer it would contain the remainder of the Upgrade headers as well as the trailing cr-newline-cr-newline so validateResponse would finally be called, but the 101 status would no longer be in the buffer and the entire response would be invalidated.

My fix was to simply increase BUFFER_MAX = 4096.

Below is an example of an unsuccessful connection attempt with BUFFER_MAX = 2048 and a successful connection with BUFFER_MAX = 4096. incomingBuff is buf!.bytes in processInputStream, printed just before length > 0 is checked.

let BUFFER_MAX = 2048: incomingBuff: (length: 2048) HTTP/1.1 101 Switching Protocols

Server: Apache-Coyote/1.1

Sec-WebSocket-Accept: FrIzA9bXIrgVN5dxFOyRpgH9vFs=

Date: Mon, 24 Aug 2015 23:07:33 GMT

Set-Cookie: Watson-DPAT=%2BIsv3vft9O92qYtqtmjHl7n4vhSmlxscchVlYS0n4qdfnp1wNVC3TDoD%2BH84uhmFZRdSLDsS2G9chZwsvAeHB7kDmosRMto1HqJgSSrp6vSG7kF%2FzkR4U5ieJQIZ6tL%2Bt3eDUf10QacqO34UtRpkCdlR5ZRaj%2BkzOZERAw3sceStcVjuRZnLyh2%2BMnkFisJZyIzFaUVGgS0jUvscu%2BJD6nX0F77hfeXmu7Bk9l%2BAyy02e1BANglyPCtvclz9frhBEtSUR48kNmJDVAhOhf80TwN6w1aXgQ2wWZW8BpuWYrAnag4QWVTV3WuVWsgcVdsfLqqM0dExL7r%2Bf3ZEADqI9iZkx2847Ke7MLXWl%2FcVTVjCh4iBihMHUyYuHPWVJCBtsy%2FpyDPAr3V3%2FqGVFBWm6BIQwSZ9zWWuK3nUcv8rpR4Bvo8uYB4rrLFQC05HuPsaekU%2FcdpJRI%2B8%2BLyKlAyTEpRld7lmEUHA1wiJPoX0y3Hg3kUYUuCzx5WGjiWJHQOCXD%2BIutVT7IiAP8%2B%2F1VPcYqj57NY%2Fk%2F5LmvbyTOCwoAwuODMDLUmzA90qCtcy0QGDSIU6uKGHdoc2sr0XrXSL9JLJdN2Tuuq5xy4Sn%2FJMG5VdK8QUhKILkFhpodTrFU7DNWxYXeeR9Fiq%2F6DMemt6AhlLPEwVq4U%2BAL7AFtjIHQP6JQaqFsCRdazTolq8xebY%2F%2BCeX1tp6ACZibZwPR4Mq8SJ6y7D6vT4OS2E6DUD6uu2c1wKv%2BYM1f4fa2%2Bth6qx44u34R8lewOwLhMmZzH6RVtwSZ1pR4Lr3cBD1lPX34PBv8qhXumXpaFOUlXERSiWVkzWLmXAlpGalZEGPBtE7X%2FMl9KYCDGARk28e8Jt6wbtjy4ZtH%2FXcyqiDkkm8PdMJfsrNia3dbXqqZqZUn5zYTjjNM2xMRn3pUwXw%2F9YsjA9F%2FZJsgBQCmSyce7j1P%2FsuHmXTHq%2F5Tsn%2FggOJnShl7PryQd2siQa7l4J9mTooLKk1nRlMBhuGbAEaB%2FhTk8FlYdOkJKFc5BnWXrRzgTWYhc1oeP%2F0QJmc5AwccwMyene1216jEfJRD%2F8BRXgLwaxwOS69wql4Zwijjh7FNzRwCxf3lm3DNOE8Nfw0d3e63G02FhdzN9MXpnX%2BCFLHnwEDri6fwx8BFf8SJ%2BblgKyW8ancsn2AY7G3DkdjoKYgIOHjCNGjRz0fpfKeWCSSl5MA9alqa5nvCYY8D92feX%2FaZ7dD3qj4vLHE889Tfx3HTtDBb%2FI3EUsF12lpvjaPdzaj9eUz8KFMxqzk%2BM95JM7C1mlUrcHZcWaBJOCxcZ7XjOl1CrMkOMfjELsWt5uuoY10W6gWpyKKi4rKzJGkMxi0LkIGG%2F0u3dkDgxTn1kJh1tlywi8eOLvTgtiRmsgLdI5CzdHtGiB5VlR8XfGWeRcKE42VUdufT4fHp4u%2BFpbLLqky6VFP1r2JjbMPccFiK5ZPDpZkSa4vRbdm6ovru6y1ovKglIASTinJPmfz2FYXz5aNVdEOcJX%2F%2FWIomBCtUl%2BaZRfzG6MY3Bqh4n0MC%2BZ%2BwyAO5jv9ISL3AoxttJJDIPsghDP29aHxWXGrAgEL%2F3BK4Rr24VXUiAYNufdzNYgyQ%2Bs6LhQfEQH47na3i68%2FaD1guTLKiGF33rN7B5wd1j5CjLNhQVPZNd5q%2FWRQLcrb0beiHtsp0b7XjBbzKC4EJeCjYvQfczUSOxIesr%2BPO5GeDEToKuXZg4q3fjreYGswT8uQV%2FaGcynssXA

incomingBuff: (length: 908) k71ZOrm15eBmcSJGWMIPWsHhdPVz66zOKm%2BPG730JY9PnAcIDwbMcUqhZKywO1Z9dU%2FALMAmed0rTzlHmXdC7ymdgo4vlTST0bBlO8aNgaHbcrsgFK%2BtHzpEu7%2Fe189sRwRVASMp9LwpTZ%2BYJsfunerfA4Qe1s%2FY5sImVUlt1uQ4PJMws4D7a0eciYgDdT%2BTVN0khcETxJ0FTHrujh2szSQuGWVShRh1zca6QjGRje7BknyeEDShfUQUDvECqUDzrhXLodMzhCMQ4CNEm2GXtK%2BAW9P%2FcIxA4l1LAD7jVSxJr5N7rvRlkaaLWswRqG1EqK78gAGeE6vrIQG%2BMDd2uOF36cBU2F9z8ZwkXEUJG45O45EQiYH3X3PD%2Fyk3JslO1Pa2FkJIa%2BJSvuG3efBkFr6M7u3%2BbPci%2Ft0C9WdgNQuvnMYiP%2BVbDQlc0M%2B6VIslO5wGC0v57EMrTGE%2FEwT%2FRUgGsB5c8CUcFqq8EyA4XvKTNh0aqxToAaHu5NBmKYPTN7p2fE2BrZ4iNPdVE8LAuMUOPx%2F714tdRVZOeJaYJQwk3iD2Kxhwa0f1K8Cr2oiIwSr7SB0CsN0JniRcCrFKXscug4V4EHbS%2BzWxPC%2FT401aAa48%2BxxwneApz3NaPdbcHlY3uxRoC5yuJUEY3SnIuwHYYuQL; path=/speech-to-text/api; secure; HttpOnly

X-Global-Transaction-ID: 258205405

Content-Type:

X-DP-Watson-Tran-ID: csf_platform_prod_dp02-258205405

Upgrade: websocket

Connection: Upgrade

websocket is disconnected: Invalid HTTP upgrade (this line is from the delegate websocketDidDisconnect)

let BUFFER_MAX = 4096:

incomingBuff: (length: 2990) HTTP/1.1 101 Switching Protocols

Server: Apache-Coyote/1.1

Sec-WebSocket-Accept: MoNm+ZrSpMXWTmgxFRSiw/uwXgI=

Date: Mon, 24 Aug 2015 23:19:39 GMT

Set-Cookie: Watson-DPAT=SaXW7YmbqrAt9IvfCNMju5gpGhQVK3WeVwtKgh7e7ExNagAcLqEkCGE08XatKgAYemKf%2Fb81%2BSBSvHdUdn72p8QyaLBudmIceqXR8X31GCnpBuUOAaEzQNIEnxu1kNpyi%2BWj50NRInt3trhBnlv4FwPBzunxmy24Gv0n12KnLV1khDCoQ9dj36PdnR7kggTkPZNQXIM4ApPYbtgsI3qaOYiVjdTEJr%2F1CgUhLdL6DLmeVfxKnu9iUemUiHPc7b6JEPV%2BPRa%2FS1bffeUETjmC9FrKj0qB8hKsP04%2FPDCcbf%2BcSABdSlQagL9edHgyZrx3QcIjpcAFKURpm8b010V1XYin%2FbRHisvJy6iId7DbUfGp%2BEtp9AIcTIlEbrCqEz0tjDC4Z1itPDioqfiV7B%2FXhL60QK%2F1ph8tKlh1qtQiVK%2Fj4tMpxo1WrMMqOoZkfDuVMRQ7pL8eWYiV5TQDrLRpM3m3X%2Bu72tRFCB1esZd2bbyAtPe%2BXpFPIyYNd%2F4zF8ZNPFu8ZdVDiAJabgY%2Bmu%2BLTFBiIQnXnELFDMDVodrDkcTBfJ%2Br3la5AlBCP%2BYhBbDlk14rgrl%2B9NbjIEgOENr6xi0fTOz6goegYDCkhkmpXoF5vcX021PbfIZz2fLYG8yLkR%2BUmitsIqc0gcovGk%2Bk4CoRRyEYPyh%2FzvTV2O7EV5zS6WMaZuMt4ijuP5E1FWzQqnFqAYq8y2nGJh4ym98cSPbkIefmW1o1XF%2B4gUwEGdlIIbhIjhdqfkMWZNXTZit1q1m3RBNp6BxYlTie0ezrxVmOLgN6OoJbH%2BnGSifQqHilIa6mhJr%2BcRv7H%2FhKEm%2B%2Bp3XJ8%2FArdHRf8pXYf2YuyYnKaxyY%2FozYr5tscUNFOzu0iML1YNLkzEPdpWgX1Q%2BHAGPeHAROCVehvrtK7O38lF7Qk3zHqisW09up%2BxEWpR8NutqKTG7zPEBYAvtU%2B4k9dcW%2BqHyjMLwnKuBq3Q8jZQNaGx07gVlhbbcsnsmoUSPbWITCkYXUJbi4oK6bsRxS%2BLw2kelqdrys609jdRViwQPDEojnxt2CE4TJJLvyCLwcG6rAWI2u9ezMv4CoIQfQrdeldP2g3XrYbU3jRAPOVyRSEDIaMRW71Wasx70sNcIplpvM3kuBUbrQvve4ZNzBKM5kR2m3Vgf9VKTcSpZj%2BoKTFnBPDnijAfJGy7wRWv%2BSo%2F4%2F4XOJXI%2FqWvB4IZ0CwdnxUn7isbk9tY2v5%2Bw4rW1b2nloZ0i%2BCGBhdkrWapgS%2BTdsVu%2FJxNbFBcN9g99k052LAdYzaCic5hx2OjreqijoTBZAjl4rUPuhjeLnDnNBsBAMqg%2BqdnrGyo0ZdPyYm3uGMRD%2BJIbaOAx4OFkgJGATbKWjbC0A5Iku%2Foj1u9nI2TGOzvs%2FC83j2RgJJRJhcbB5Rl3EPWRcEkTYMmCW6G5WDD9nDqSiSFJBlXTW8LsArxzUuo%2B6xVfiPGsACbRPUl68M%2FwCyz%2FAbure8Zz8my8T1DZTSiAHtKLG8jUzA%2FUsBOSniM59nwUCWsylgj0sWvqyP%2FlmMyW3fq2CcsR5vKrAJWC2tnZkfyNR7r1vdL7xe8uPs2arMkY2duXoTaFAevlE%2F0VNRhwhCrR1yD97BCyI%2Fj2bfrl5c7jMVB8q0Poo5MmSaia3ct3FvowztIxvj4oUZhOcSHeppd4g0eU2odRGrhkPeqW6xX0fDB7Ra4vOJrFxcWRD7%2Bu1rIxuSnR2DQdZCltDGPJ9zj89AKoYXpOJTbasobMAyiv1xh3428Drh9M%2FodX0Thf7oCa%2BzvUCs6%2BKzujMOlUROktVfXUi0Qr2szLPzrJ1epGV25q%2BlrwUbqHsmymQKn7fiFDQLFqrA%2B0a3dUKJAry95%2Bt4M3hvXOAvhLl1%2BS0L5tQRjdtTL9lgt9OnUKEB3AkuCo9Wga6NnFlQ0pQuov8qCpTL4az8rE9JQzPpVSfy%2BKPdbsk9UDEAgZNHaDBw7Q43V0Dae%2FNS50CE2smjgt9wfYUPC%2B5hrsIObxz2HQZziGGsSAaEVSAAvP%2BUZJgjRKRtN7cbVJRY0sBRE3rCd8RDhOCAly4RyOmWpAFUZqrtRWbQJpl7vuHi41tX8YCsLWiLiF7mySnNlHmm0sBk%2BMLl%2BCwm2Xhv%2Boay%2FSY5nDbbxLkikNz4%2FnEY0k9Or4LWI3ZKTwQ6HI5L%2FbbnTXbkJ98ANSLlzAkxo1IsuV7DJwkfxoN5AhPk528WbEigZvQ5boTH71Jx8tT1xLmVFeGZn%2FZd2YrhyRIwBYVQZeHyYoM9ZY%2FIGHgTB4%2BPG2%2FZH5ZX%2B%2BtzpU5p8T90D2Fwpvl%2FBtT7qwPlA%2FhTzXCYTSa%2Bw3gz7AdiN2hgfwWRLADg6t3SrJbbjjl7J6lCIOxOJCZTDh9JQfLje4TFthLIPQOk0ierLPAMsWL9HOI44QVZDCuT%2BdF%2BOs32dBU09fyE%2FKJEls%3D; path=/speech-to-text/api; secure; HttpOnly

X-Global-Transaction-ID: 575434213

Content-Type:

X-DP-Watson-Tran-ID: csf_platform_prod_dp02-575434213

Upgrade: websocket

Connection: Upgrade

websocket is connected (this line is from the websocketDidConnect delegate)

daltoniam commented 9 years ago

Thanks for the detailed write up. Making the BUFFER_MAX bigger is certainly a quick and simple way to fix it, but I think we should probably implement a touch more robust logic that better handles a fragmented HTTP packet on the first read (we could run into this again if we don't :confused: ). Thanks again for the report, I will investigate and hopefully implement a robust solution soon.

ghost commented 9 years ago

No problem and I certainly agree that my fix is nothing more than a bandage. Thank you for this project, I'm using it in a project and this is my first experience with websockets. So far it's definitely nicer than sending chunked-data messages.

daltoniam commented 9 years ago

Glad to hear it helps out!