Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-20094] TCP Socket buffer corrupts data if too large

GitHub Issuen/a
TypeBug
Priorityn/a
StatusOpen
ResolutionUnresolved
Affected Version/sn/a
Fix Version/sn/a
ComponentsTiAPI
Labelssockets, tcp, titanium, xmpp
ReporterAggelos Papageorgiou
AssigneeUnknown
Created2015-06-22T22:29:09.000+0000
Updated2018-02-28T19:55:24.000+0000

Description

I have duplicated an XMPP communication system using the TCP Sockets Module on Titanium Studio and for the most part it is working like a dream. The part where it does not work correctly is if I receive a message that is too big and the heap needs to grow in order to accommodate it in memory. It is then that many parts of the message are lost, thus making the message unreadable from the XML parser. I am placing the code that receives the buffer data below:
JXMPPConnection.prototype._pumpCallback = function(e) {
	//that.oDbg.log("pumpCallback ...", 1);

	 if (e.bytesProcessed ==-1) {// EOF 
		Ti.API.error("<EOF> - Can't perform any more operations on connected socket");
	} else if (e.errorDescription == null || e.errorDescription == "") {
		Ti.API.debug("DATA>>>: " + e.buffer.toString());
		var data = e.buffer.toString();
		repeatInterval=false;
		//var i=0;
		e.buffer.clear();
		//while(i<data.length){
			if(data.indexOf('<')<0 || data.length<10)
			return;
			data=data.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/ /g,' ').replace(/&g/g,'>').replace(/>/g,'>');
			// if(data.charAt(0)!='<'){
				// data=data.substr(1);
				// }else{break;}
			// i++;
		// }
		if(data.indexOf("ping")>=0){
			that._doAutoPing(Ti.XML.parseString(data));
			that.registerHandler('autoPing',that._doAutoPingResult);
			return;
		}
		//fix xml finish and prefix
		var response = data.replace(/\<\?xml.+\?\>/, "");
		if(response.indexOf("</stream:stream>")==0) {
			Ti.API.error("end connection XML: " + response);
			that._req.close();
			return;
		}
		if (that.autenticated()) {
			var xmls = that._getSplitXml(response);
			for ( i = 0; i < xmls.length; i++) {
				var xml = xmls[i];
				xml=that._fixXmlToParse(xml);
				Ti.API.info('length: '+xmls.length+xml);
				if(xml.indexOf('<message')>=0 && xml.indexOf('</message>')<0){buffer.push(xml);break;}
				if(buffer.length>=1 && (xml.indexOf('<message')<0 && xml.indexOf('</message>')<0)){buffer.push(xml);break;}
				 if(xml.indexOf('<message')<0 && xml.indexOf('</message>')>0){xml=buffer.toString()+xml;buffer=new Array();}
				if(buffer.length>0 && xmls.length>1){
					for(i;i<xmls.length;i++){
						xml+=xmls[i];
						if(xml.indexOf('</message')>0){buffer=new Array();break;}
					}
				}
				Ti.API.info("_handleResponse: " +xml);
				that._handleResponse(xml);
			}
		} else {
			response=that._fixXmlToParse(response);
			that._getStreamID(response);
		}

	} else {
		Ti.API.error("READ ERROR: " + e.errorDescription);
		that.disconnect();
	}
};
this code works like magic for most of my messages but when I request the history of a user of my xmpp service, which is quite a big message, the message gets corrupt. example of the reply of the server with the corrupt part included
<message id=“xxxxxx|1435011247" to=“xxxxxx@domain.com" from="triphistory@domain.com/res“><body><TripHistory>
<Trips>
<total>10</total>
<Trip>
<id>xxxxxxxx</id>
<hailtime>1434576550000</hailtime>
<pickuptime>1434576725000</pickuptime>
<from><![CDATA[xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx]]></from>
<to><![CDATA[]]></to>
<special><![CDATA[xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx]]></special>
<agent>s</agent>
<status>com</status>
<rating>0</rating>
<plateno>xxxxxxxx</plateno>
<carmodel>xxxxxxxx</carmodel>
<drivername>xx</drivername>
<driversurname>xx</driversurname>
<drivercode>xxxxxx</drivercode>
<driverid>xxxx</driverid>
<isfaved>false</isfaved>
<isblocked>false</isblocked>
<tripfare>0.000000</tripfare>
<tripcurr></tripcurr>
<tripchannel></tripchannel>
<companyemail>aggelos@domain.gr</companyemail>
<companyfacebook>domain</companyfacebook>
<companytwitter>domain</companytwitter>
</Trip><Trip>
<id>xxxxxxx</id>
{color:red}xxxxxSome String]]>{color}
<agent>s</agent>
<status>com</status>
<rating>0</rating>
<plateno>xxxxxx</plateno>
<carmodel>xxxxxxxxx</carmodel>
<drivername>xxxx</drivername>
<driversurname>xxxxx</driversurname>
<drivercode>xxxxxx</drivercode>
<driverid>xxxx</driverid>
<isfaved>false</isfaved>
<isblocked>false</isblocked>
<tripfare>0.000000</tripfare>
<tripcurr></tripcurr>
<tripchannel></tripchannel>
<companyemail>aggelos@domain.gr</companyemail>
<companyfacebook>domain</companyfacebook>
<companytwitter>domain</companytwitter>
</Trip><Trip>
<id>xxxxxxxx</id>
<hailtime>1434576550000</hailtime>
<pickuptime>1434576725000</pickuptime>
<from><![CDATA[xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx]]></from>
<to><![CDATA[]]></to>
<special><![CDATA[xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx]]></special>
<agent>s</agent>
<status>com</status>
<rating>0</rating>
<plateno>xxxxxxxx</plateno>
<carmodel>xxxxxxxx</carmodel>
<drivername>xx</drivername>
<driversurname>xx</driversurname>
<drivercode>xxxxxx</drivercode>
<driverid>xxxx</driverid>
<isfaved>false</isfaved>
<isblocked>false</isblocked>
<tripfare>0.000000</tripfare>
<tripcurr></tripcurr>
<tripchannel></tripchannel>
<companyemail>aggelos@domain.gr</companyemail>
<companyfacebook>domain</companyfacebook>
<companytwitter>domain</companytwitter>
</Trip></Trips>
</TripHistory></body></message>
I have highlighted the corrupt part of the message in red. Is this behavior to be expected? If it is how can I alleviate it? I need to have my messages correctly reported back to me from the socket no matter what the computational cost that may bring. I am attaching below the code used to setup the tcp socket:
try {
			this._req = Ti.Network.Socket.createTCP({
				host : this.host,
				port : this.port,
				connected : function(e) {
					//send initial request

					var reqstr = that._getInitialRequestString();
					Ti.API.debug(reqstr);

					e.socket.write(Ti.createBuffer({
						type:Titanium.Codec.CHARSET_UTF8,
						value : reqstr
					}));
					Ti.Stream.pump(e.socket, that._pumpCallback, 1000000, true);

				},
				error : function(e) {
					Ti.API.error('Socket error');
					that._connected=false;
					that.disconnect();
				},
				closed : function(e) {
					Ti.API.error('Socket close');
					that._connected=false;
				},
			});
			this._req.connect();
		} catch (e) {
			Ti.API.error('Error creating socket');
			that._connected=false;
			that.disconnect();
		}

Comments

  1. Aggelos Papageorgiou 2015-07-01

    Please look into this issue I am on a really tight schedule and this bug is a really BIG showstopper. Please ask for any further information required to resolve this bug. thank you
  2. Chee Kiat Ng 2015-12-04

    Have you tried with the latest environment we have? And is this specific to android or ios?
  3. Aggelos Papageorgiou 2015-12-04

    I have tried up to the 5.1.0.GA SDK and it has not remedied it self neither on iOS nor on Android!

JSON Source