Host.updateLicenseRequestInfo not able to add headers - chromecast

Hi I am trying to achieve any one of the below
1) Set a extra token to the license url by the code ' requestInfo.url = requestInfo.url + "#12345678";'
OR
2) Set headers by the code 'requestInfo.headers = new String('token:12345678\r\n');'
But nothing seems to work.
After updating the url in receiver logs i see 'Updated requestInfo.url ' with the extra '#12345678' at the end of the license url. But on license server I get only the url which is unmodified ( no #12345678).
Same with requestInfo.headers. I don't see any headers which I set in receiver app when the request comes in license server.
I also tried returning the requestInfo; but with this the chromecast is not able to play anything. So I commented the return statement.
Would appreciate any pointers to fix this issue. Here is my code.
var host = new cast.player.api.Host({
'url': url,
'mediaElement': this.mediaElement_
});
host.onManifestReady = function() {
self.log_('prototype.loadVideo_::My onManifestReady');
};
host.updateLicenseRequestInfo = function(requestInfo){
self.log_('prototype.loadVideo_::updateLicenseRequestInfo()');
self.log_('requestInfo.url ' + requestInfo.url);
self.log_('requestInfo.headers ' + requestInfo.headers);
self.log_('requestInfo.protectionSystem ' + requestInfo.protectionSystem);
self.log_('requestInfo.setResponse ' + requestInfo.setResponse);
self.log_('requestInfo.skipRequest ' + requestInfo.skipRequest);
self.log_('requestInfo.timeoutInterval ' + requestInfo.timeoutInterval);
self.log_('requestInfo.withCredentials ' + requestInfo.withCredentials );
requestInfo.url = requestInfo.url + "#12345678";
//host.licenseUrl = requestInfo.url;
//requestInfo.headers = new String('token:12345678\r\n');
self.log_('Updated requestInfo.url ' + requestInfo.url);
self.log_('Updated requestInfo.headers ' + requestInfo.headers);
//return requestInfo;
};
this.player_ = new cast.player.api.Player(host);

updateLicenseRequestInfo - enables the host to customize request information used to get media license from the server. Applications should override this method to add a token to the url, set headers or withCredentials flag.
Here is the example code on how to use it.
host.updateManifestRequestInfo = function(requestInfo) {
if (!requestInfo.url) {
requestInfo.url = this.url;
}
requestInfo.withCredentials = true;
};
host.updateLicenseRequestInfo = function(requestInfo) {
requestInfo.withCredentials = true;
};
host.updateSegmentRequestInfo = function(requestInfo) {
requestInfo.withCredentials = true;
};
You can also visit this page for more information.

Related

Custom HTTPRequestHandler for public file upload

I'm trying to add a HTTPRequestHandler for a public file upload service to wakanda server. Anybody should be able to POST a file to this service without logging in. Unfortunately I get a "403 Forbidden" error on all POST requests made to the HTTPRequestHandler? GET requests work fine but do not not help much in this case ;-)
The intention is to receive the file, process it, and send it back to the client.
Added my request handler as follows:
application.addHttpRequestHandler('^/fileUpload$', './backend/httpRequestHandler/file-upload.js', 'fileUpload');
Any help on how to solve this problem would be much appreciated.
Finally got it to work myself with cURL. Looks like there was some issue with my Postman setup.
cURL command:
curl --form "fileupload=#test.xml" http://localhost:8081/fileUpload
HTTPRequestHandler:
/**
* file upload handler
* #param request {HTTPRequest} http request
* #param response {HTTPResponse} http response
*/
function fileUpload(request, response) {
try {
var counter = 1;
var nameTemp;
var files = [];
var uploadFolder = Folder('/PROJECT/database/data/tmp/');
var result = [];
var newName;
var myBinaryStream;
// create upload folder if not existing
if (!uploadFolder.exists) {
uploadFolder.create();
}
// create file instances
for (var i = 0; i < request.parts.length; i++) {
files.push(new File(uploadFolder.path + request.parts[i].fileName.replace(/\s/g, '_')));
// create result object
result[i] = {};
result[i].name = request.parts[i].fileName;
result[i].type = request.parts[i].mediaType;
result[i].size = request.parts[i].size;
}
// write file content
for (var i = 0; i < files.length; i++) {
counter = 1;
if (!files[i].exists) {
myBinaryStream = BinaryStream(files[i], 'Write');
myBinaryStream.putBlob(request.parts[i].asBlob);
myBinaryStream.close();
} else {
while (files[i].exists) {
nameTemp = files[i].name.replace(/\s/g, '_');
files[i] = new File(uploadFolder.path + files[i].nameNoExt.replace(/\s/g, '_') + counter + '.' + files[i].extension);
newName = files[i].name;
if (files[i].exists) {
files[i] = new File(uploadFolder.path + nameTemp);
}
counter++;
}
myBinaryStream = BinaryStream(files[i], 'Write');
myBinaryStream.putBlob(request.parts[i].asBlob);
myBinaryStream.close();
result[i].name = newName;
}
}
result = JSON.stringify(result);
// add response header
response.contentType = 'application/json';
return result;
} catch (e) {
console.log(e.stack);
return e;
}
}

is my if statement doing what i think its doing?

Here I have tis function that is querying data and returning it to me and im putting that data in to html elements to make a post.my if statement at the bottom is where im having a bit of problem i trying to only apply my comment window once to the new clones once they have been pushed over to the new div called story board, i believe im telling my if statement that if the class already exists in that new clone then do nothing else apply it there.. to seee what i am talking about...here is my test domain...http://subdomain.jason-c.com/
sign in is "kio" pass is the same and when you hit publish on the stories, everytime a nw one hits it will apply comment box to a post in the storyboard window that already has a comment text area. what am i doing wrong.
function publishWindowHandler(){
var query = new Parse.Query('Post');
console.log(currentUser);
query.equalTo("User", currentUser);
query.include("User");
query.descending("createdAt")
console.log(user.get('username'));
query.find({
success:function(results){
document.getElementById("publishCenter").textContent = "";
for(var i =0; i < results.length; i++){
var userPost = results[i];
//console.log(userPost.get("User") + " / " + userPost.get("Author") + " / " + userPost.get("Story") + " / " + userPost.get("objectId"));
var authorTitle = document.createElement("p");
var newPost = document.createElement("P");
var title = document.createElement("P");
var userLabel = document.createElement("p");
var postId = userPost.id;
var postBtn = document.createElement("INPUT");
postBtn.className ="publishBtn";
postBtn.id ="publishBtn";
postBtn.setAttribute("Type", "button");
postBtn.setAttribute("value", "Publish");
title.textContent = "Story: " + userPost.get("Title");
authorTitle.textContent = "Author: " + userPost.get("Author");
newPost.textContent = userPost.get("Story");
userLabel.textContent = "Published by: " +userPost.get("User").get ("username");
var postWrapper = document.createElement("DIV");
postWrapper.className = "postWrapper";
postWrapper.id = postId;
document.getElementById("publishCenter").appendChild(postWrapper);
postWrapper.appendChild(title);
postWrapper.appendChild(authorTitle);
postWrapper.appendChild(newPost);
postWrapper.appendChild(userLabel);
postWrapper.appendChild(postBtn);
postBtn.addEventListener("click", publicViewHandler);
function publicViewHandler(){
$(this).parent(".postWrapper").clone().appendTo(".storyBoard");
function testWindow(){
if($(publicBoard).children().hasClass(".commentWindow")){
}
else
{
$(".storyBoard").children().append(commentWindow);
}
}
testWindow();
}
}
}
})
}
According to the documentation, jquery hasClass doesn't need '.' prefixing the passed in class name.
https://api.jquery.com/hasclass/
Try removing that and see if that get's you anywhere.
Also, where is the variable commentWindow defined? Is it global?
var myClone = $(this).parent().clone(true);
myClone.appendTo(".storyBoard");
console.log(publicBoard);
console.log("hello",$(this));
console.log($(publicBoard).find('.postWrapper').find("commentWindow"));
myClone.append($(commentWindow).clone());
this is what i ended up doing to solve my issue took me a while and a little help from a friend.

How to construct a WebSocket URI relative to the page URI?

I want to construct a WebSocket URI relative to the page URI at the browser side. Say, in my case convert HTTP URIs like
http://example.com:8000/path
https://example.com:8000/path
to
ws://example.com:8000/path/to/ws
wss://example.com:8000/path/to/ws
What I'm doing currently is replace the first 4 letters "http" by "ws", and append "/to/ws" to it. Is there any better way for that?
If your Web server has support for WebSockets (or a WebSocket handler module) then you can use the same host and port and just change the scheme like you are showing. There are many options for running a Web server and Websocket server/module together.
I would suggest that you look at the individual pieces of the window.location global and join them back together instead of doing blind string substitution.
var loc = window.location, new_uri;
if (loc.protocol === "https:") {
new_uri = "wss:";
} else {
new_uri = "ws:";
}
new_uri += "//" + loc.host;
new_uri += loc.pathname + "/to/ws";
Note that some web servers (i.e. Jetty based ones) currently use the path (rather than the upgrade header) to determine whether a specific request should be passed on to the WebSocket handler. So you may be limited in whether you can transform the path in the way you want.
Here is my version which adds the tcp port in case it's not 80 or 443:
function url(s) {
var l = window.location;
return ((l.protocol === "https:") ? "wss://" : "ws://") + l.hostname + (((l.port != 80) && (l.port != 443)) ? ":" + l.port : "") + l.pathname + s;
}
Edit 1: Improved version as by suggestion of #kanaka :
function url(s) {
var l = window.location;
return ((l.protocol === "https:") ? "wss://" : "ws://") + l.host + l.pathname + s;
}
Edit 2: Nowadays I create the WebSocket this:
var s = new WebSocket(((window.location.protocol === "https:") ? "wss://" : "ws://") + window.location.host + "/ws");
Using the Window.URL API - https://developer.mozilla.org/en-US/docs/Web/API/Window/URL
Works with http(s), ports etc.
var url = new URL('/path/to/websocket', window.location.href);
url.protocol = url.protocol.replace('http', 'ws');
url.href // => ws://www.example.com:9999/path/to/websocket
Assuming your WebSocket server is listening on the same port as from which the page is being requested, I would suggest:
function createWebSocket(path) {
var protocolPrefix = (window.location.protocol === 'https:') ? 'wss:' : 'ws:';
return new WebSocket(protocolPrefix + '//' + location.host + path);
}
Then, for your case, call it as follows:
var socket = createWebSocket(location.pathname + '/to/ws');
easy:
location.href.replace(/^http/, 'ws') + '/to/ws'
// or if you hate regexp:
location.href.replace('http://', 'ws://').replace('https://', 'wss://') + '/to/ws'
On localhost you should consider context path.
function wsURL(path) {
var protocol = (location.protocol === 'https:') ? 'wss://' : 'ws://';
var url = protocol + location.host;
if(location.hostname === 'localhost') {
url += '/' + location.pathname.split('/')[1]; // add context path
}
return url + path;
}
In typescript:
export class WebsocketUtils {
public static websocketUrlByPath(path) {
return this.websocketProtocolByLocation() +
window.location.hostname +
this.websocketPortWithColonByLocation() +
window.location.pathname +
path;
}
private static websocketProtocolByLocation() {
return window.location.protocol === "https:" ? "wss://" : "ws://";
}
private static websocketPortWithColonByLocation() {
const defaultPort = window.location.protocol === "https:" ? "443" : "80";
if (window.location.port !== defaultPort) {
return ":" + window.location.port;
} else {
return "";
}
}
}
Usage:
alert(WebsocketUtils.websocketUrlByPath("/websocket"));
I agree with #Eadz, something like this is cleaner and safer:
const url = new URL('./ws', location.href);
url.protocol = url.protocol.replace('http', 'ws');
const webSocket = new WebSocket(url);
The URL class saves work and deals with things like query parameters, etc.
Dead easy solution, ws and port, tested:
var ws = new WebSocket("ws://" + window.location.host + ":6666");
ws.onopen = function() { ws.send( .. etc

What exactly am I sending through the parameters?

When doing a XMLHttpRequest and using POST as the form method, what exactly am I sending? I know it should be like send(parameters), parameters = "variable1=Hello", for example. But what if I want to do this:
parameters = "variable1=" + encodeURIComponent(document.getElementById("variable1").value);
variable1 being the id of the HTML form input.
Can I do it like this or do I need to assign the encodeURIComponent value to a javascript variable and send that variable:
var variable2;
parameters = "variable2=" + encodeURIComponent(document.getElementById("variable1").value);
You're suppose to send the object and it's value, but, is it an object from the HTML form, a javascript object or a php object? The problem is I already tried it and I still can't get the encoded input in my database, all I get is the raw input from the user.
BTW, I know it's a pretty dull question, but I feel the need to understand exactly what I'm doing if I want to come up with a solution.
g
function createObject()
{
var request_type;
var browser = navigator.appName;
if(browser == "Microsoft Internet Explorer")
{
request_type = new ActiveXObject("Microsoft.XMLHTTP");
}
else
{
request_type = new XMLHttpRequest();
}
return request_type;
}
var http = createObject();
//INSERT
function insert()
{
var Faculty2 = encodeURIComponent(document.getElementById("Faculty").value);
var Major2 = encodeURIComponent(document.getElementById("Major").value);
var Professor2 = encodeURIComponent(document.getElementById("Professor").value);
var Lastname2 = encodeURIComponent(document.getElementById("Lastname").value);
var Course2 = encodeURIComponent(document.getElementById("Course").value);
var Comments2 = encodeURIComponent(document.getElementById("Comments").value);
var Grade2 = encodeURIComponent(document.getElementById("Grade").value);
var Redflag2 = encodeURIComponent(document.getElementById("Redflag").value);
var Owner2 = encodeURIComponent(document.getElementById("Owner").value);
//Location and parameters of data about to be sent are defined
//Required: verify that all fields are not empty. Use encode URI() to solve some issues about character encoding.
var params = "Faculty=" + Faculty2 + "&Major=" + Major2 + "&Professor=" + Professor2 + "&Lastname=" + Lastname2 + "&Course=" + Course2 + "&Comments=" + Comments2 + "&Grade=" + Grade2 + "&Redflag=" + Redflag2 + "&Owner=" + Owner2;
var url = "prehp/insert.php";
http.open("POST", url, true);
//Technical information about the data
http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
http.setRequestHeader("Content-length", params.length);
//Now, we send the data
http.onreadystatechange = function()
{
if(http.readyState == 4)
{ var answer = http.responseText;
document.getElementById('insert_response').innerHTML = "Ready!" + answer;
}
else
{document.getElementById('insert_response').innerHTML = "Error";
}}
http.send(params);
}
PHP code:
$insertAccounts_sql = "INSERT INTO Information (Faculty, Major, Professor, Lastname, Course, Comments, Grade, Redflag, Owner)
VALUES('$_POST[Faculty]','$_POST[Major]','$_POST[Professor]','$_POST[Lastname]','$_POST[Course]','$_POST[Comments]','$_POST[Grade]','$_POST[Redflag]','$_POST[Owner]')";
$dbq = mysql_query($insertAccounts_sql, $dbc);
if($dbq)
{
print "1 record added: Works very well!";
}
else
if(!$dbq)
{
die('Error: ' . mysql_error());
}
$dbk = mysql_close($dbc);
if($dbk)
{
print "Database closed!";
}
else
if(!$dbk)
{
print "Database not closed!";
}
I did that but the value that the database got was the raw input and not the encoded input. I'm running out of ideas, don't know what else to try. Could it be the settings of the database, can the database be decoding the input before storing it? That seems far-fetched to me, but I've been looking at this from all angles and still can't come up with a fresh answer.
PS: Sorry for posting my comments on the answer area, first timer here.
when creating query strings, it has really nothing to do with objects or anything like that. All you want to be sending is key/value pairs. how you construct that is up to you, but it often neater and more manageable to assign your values to variables first. i.e.
var myVar1Value = encodeURIComponent(document.getElementById('variable1').value);
var myVar2Value = encodeURIComponent(document.getElementById('variable2').value);
var url = "http://www.mydomain.com?" + "var1=" + myVar1Value + "&var2=" + myVar2Value;
It's called a query string, so it's just a string. what you do with it on the server side is what makes the 'magic' happen.
edit: If you're having problems with values, then you should print them to console to verify you are getting what you expect.

Inconsistent data corruption in a store loaded through a proxy reader

We're experiencing inconsistent data corruption in a store loaded through a proxy reader.
It's browser dependant.
Works fine in Chrome and Safari on the desktop all the time.
On our two testing iPhones it intermittently breaks depending on the data the store has loaded, larger data volume seems to cause more breaks. We can't see any errors or patterns in the JSON data where it breaks.
Symptoms:
data loads, but some of the data belonging to the last few items is missing
a read listener attached to the store doesn't fire when this data loss occurs, it does fire on the desktop browser where we experience not data loss
The piece of data that always seems to be lost is the start_time.
We've been trying to debug this one for a while now and are really stumped.
Thank you for any ideas you might have as to why this is occurring.
Our regModel
Ext.regModel('Booking', {
fields: ['id', 'start', 'end', 'title', 'service', 'service_id', 'client_note', 'stylist_note', 'utc_start','day_date', 'start_time', 'end_time', "home_ph", "mobile_ph", 'work_ph', 'work_ext', 'email', 'utc_end']
});
Our store
var store = new Ext.data.JsonStore({
model : 'Booking',
sorters: 'utc_start',
autoLoad: false,
proxy: {
type: 'ajax',
url: '../includes/get_appointments.php',
extraParams: {
req_start: '1295251200',
req_end: '1295856000'
},
reader: {
type: 'json',
root: 'events'
}
},
listeners: {
load:function(store, records, success) {
bookings.setLoading(false);
// check to see length of records, start i from there
for (var i = 0; i < records.length; i++){
utc_start = records[i].get('utc_start');
utc_end = records[i].get('utc_end');
// create day of week
// y,m,d
// time
var this_start_date = new Date((utc_start * 1000));
var this_end_date = new Date((utc_end * 1000));
var day_of_week = days_of_week[this_start_date.getDay()];
var date_of_month = this_start_date.getDate();
var month_of_year = month_names[this_start_date.getMonth()];
var full_year = this_start_date.getFullYear();
var start_military_hours = this_start_date.getHours();
var this_start_minutes = this_start_date.getMinutes();
var end_military_hours = this_end_date.getHours();
var this_end_minutes = this_end_date.getMinutes();
if(this_start_minutes == "0")
{
this_start_minutes = "00";
}
if(parseInt(start_military_hours) < 12)
{
var start_time = start_military_hours + ":" + this_start_minutes + " AM";
}
else if(parseInt(start_military_hours) == 12)
{
var start_time = start_military_hours + ":" + this_start_minutes + " PM";
}
else
{
var start_time = (parseInt(start_military_hours) - 12) + ":" + this_start_minutes + " PM";
}
if(this_end_minutes == "0")
{
this_end_minutes = "00";
}
if(parseInt(end_military_hours) < 12)
{
var end_time = end_military_hours + ":" + this_end_minutes + " AM";
}
else if(parseInt(end_military_hours) == 12)
{
var end_time = end_military_hours + ":" + this_end_minutes + " PM";
}
else
{
var end_time = (parseInt(end_military_hours) - 12) + ":" + this_end_minutes + " PM";
}
var day_date = day_of_week + ", " + full_year + " " + month_of_year + " " + date_of_month;
if(records[i].get('service_id') == 0)
{
records[i].set('title', 'Booked off');
records[i].set('service', '');
}
records[i].set('day_date', day_date);
records[i].set('start_time', start_time);
records[i].set('end_time', end_time);
}
if(store.proxy.reader.rawData.next_page_num == undefined)
{
store.start = store.proxy.reader.rawData.prev_page_num;
}
else
{
store.currentPage = store.proxy.reader.rawData.next_page_num;
}
}, read:function(store,records,success){
Ext.Msg.alert('data read');
}
},
getGroupString : function(record) {
return record.get('day_date'); // optional char from array removed
}
});
Our JSON
{"events":[{"id":"3739","start":"2011-01-18T10:00:00-08:00","end":"2011-01-18T11:45:00-08:00","title":"Jen Cannor","service":"Haircut & Highlights","service_id":"67","client_note":"","stylist_note":"Looking forward to seeing Jen when she comes in next.","utc_start":"1295373600","email":"jen.c#cannorfarms.net","home_ph":"232-433-2222","mobile_ph":"","work_ph":"","work_ext":"","utc_end":"1295379900"},{"id":"3740","start":"2011-01-18T12:00:00-08:00","end":"2011-01-18T13:30:00-08:00","title":"Michelle Steves","service":"Root Colour","service_id":"69","client_note":"","stylist_note":"","utc_start":"1295380800","email":"michelle5b64#telus.net","home_ph":"604-555-5555","mobile_ph":"","work_ph":"","work_ext":"","utc_end":"1295386200"},{"id":"3741","start":"2011-01-18T13:30:00-08:00","end":"2011-01-18T14:00:00-08:00","title":"Amanda Brenner","service":"Wash & blow dry","service_id":"70","client_note":"","stylist_note":"","utc_start":"1295386200","email":"amandab#coastfitness.com","home_ph":"555-235-2366","mobile_ph":"","work_ph":"","work_ext":"","utc_end":"1295388000"},{"id":"3742","start":"2011-01-18T14:00:00-08:00","end":"2011-01-18T15:45:00-08:00","title":"Janice Potters","service":"Haircut & Colour","service_id":"66","client_note":"","stylist_note":"","utc_start":"1295388000","email":"","home_ph":"","mobile_ph":"","work_ph":"","work_ext":"","utc_end":"1295394300"},{"id":"3743","start":"2011-01-18T15:45:00-08:00","end":"2011-01-18T16:45:00-08:00","title":"Angus Middleton","service":"Men's haircut","service_id":"61","client_note":"","stylist_note":"","utc_start":"1295394300","email":"angusman#hotmaile.com","home_ph":"","mobile_ph":"","work_ph":"","work_ext":"","utc_end":"1295397900"},{"id":"3025","start":"2011-01-19T08:00:00-08:00","end":"2011-01-19T09:45:00-08:00","title":"Jen Cannor","service":"Haircut & Highlights","service_id":"67","client_note":"","stylist_note":"","utc_start":"1295452800","email":"jen.c#cannorfarms.net","home_ph":"232-433-2222","mobile_ph":"","work_ph":"","work_ext":"","utc_end":"1295459100"},{"id":"3026","start":"2011-01-19T10:00:00-08:00","end":"2011-01-19T11:45:00-08:00","title":"Karen Walker","service":"Haircut & Colour","service_id":"66","client_note":"","stylist_note":"","utc_start":"1295460000","email":"karenwalker#officesurplusdirect.net","home_ph":"","mobile_ph":"","work_ph":"","work_ext":"","utc_end":"1295466300"},{"id":"3027","start":"2011-01-19T11:45:00-08:00","end":"2011-01-19T12:45:00-08:00","title":"Amanda Brenner","service":"Women's Haircut","service_id":"65","client_note":"","stylist_note":"","utc_start":"1295466300","email":"amandab#coastfitness.com","home_ph":"555-235-2366","mobile_ph":"","work_ph":"","work_ext":"","utc_end":"1295469900"},{"id":"3028","start":"2011-01-19T13:00:00-08:00","end":"2011-01-19T14:30:00-08:00","title":"Mary Thacker","service":"Root Colour","service_id":"69","client_note":"","stylist_note":"","utc_start":"1295470800","email":"","home_ph":"","mobile_ph":"","work_ph":"","work_ext":"","utc_end":"1295476200"},{"id":"3029","start":"2011-01-19T14:30:00-08:00","end":"2011-01-19T15:00:00-08:00","title":"Malcolm Anderson","service":"Men's haircut","service_id":"61","client_note":"","stylist_note":"","utc_start":"1295476200","email":"malcolm#testserveraddy.com","home_ph":"240-444-4444","mobile_ph":"","work_ph":"","work_ext":"","utc_end":"1295478000"},{"id":"4856","start":"2011-03-09T09:00:00-08:00","end":"2011-03-09T10:00:00-08:00","title":"Simon Chalk","service":"Men's haircut","service_id":"61","client_note":"","stylist_note":"","utc_start":"1299690000","email":"","home_ph":"","mobile_ph":"","work_ph":"","work_ext":"","utc_end":"1299693600"},{"id":"4858","start":"2011-03-09T10:00:00-08:00","end":"2011-03-09T10:15:00-08:00","title":"Brian Lytton","service":"Men's haircut","service_id":"61","client_note":"","stylist_note":"","utc_start":"1299693600","email":"","home_ph":"","mobile_ph":"","work_ph":"","work_ext":"","utc_end":"1299694500"},{"id":"4859","start":"2011-03-09T10:15:00-08:00","end":"2011-03-09T10:30:00-08:00","title":"Brad Wicker","service":"Men's haircut","service_id":"61","client_note":"","stylist_note":"","utc_start":"1299694500","email":"","home_ph":"","mobile_ph":"","work_ph":"","work_ext":"","utc_end":"1299695400"},{"id":"4860","start":"2011-03-09T10:30:00-08:00","end":"2011-03-09T10:45:00-08:00","title":"Brad Wicker","service":"Men's haircut","service_id":"61","client_note":"","stylist_note":"","utc_start":"1299695400","email":"","home_ph":"","mobile_ph":"","work_ph":"","work_ext":"","utc_end":"1299696300"},{"id":"4861","start":"2011-03-09T10:45:00-08:00","end":"2011-03-09T11:00:00-08:00","title":"Brian Lytton","service":"Men's haircut","service_id":"61","client_note":"","stylist_note":"","utc_start":"1299696300","email":"","home_ph":"","mobile_ph":"","work_ph":"","work_ext":"","utc_end":"1299697200"},{"id":"4862","start":"2011-03-09T11:00:00-08:00","end":"2011-03-09T11:15:00-08:00","title":"Brian Lytton","service":"Men's haircut","service_id":"61","client_note":"","stylist_note":"","utc_start":"1299697200","email":"","home_ph":"","mobile_ph":"","work_ph":"","work_ext":"","utc_end":"1299698100"},{"id":"4863","start":"2011-03-09T11:15:00-08:00","end":"2011-03-09T11:30:00-08:00","title":"Simon Chalk","service":"Men's haircut","service_id":"61","client_note":"","stylist_note":"","utc_start":"1299698100","email":"","home_ph":"","mobile_ph":"","work_ph":"","work_ext":"","utc_end":"1299699000"},{"id":"4864","start":"2011-03-09T11:30:00-08:00","end":"2011-03-09T11:45:00-08:00","title":"Chester Welling","service":"Men's haircut","service_id":"61","client_note":"","stylist_note":"","utc_start":"1299699000","email":"chester#eastern.pharma.net","home_ph":"604-555-5555","mobile_ph":"","work_ph":"","work_ext":"","utc_end":"1299699900"},{"id":"4865","start":"2011-03-09T11:45:00-08:00","end":"2011-03-09T12:00:00-08:00","title":"Brad Wicker","service":"Men's haircut","service_id":"61","client_note":"","stylist_note":"","utc_start":"1299699900","email":"","home_ph":"","mobile_ph":"","work_ph":"","work_ext":"","utc_end":"1299700800"},{"id":"4866","start":"2011-03-09T12:00:00-08:00","end":"2011-03-09T13:00:00-08:00","title":"Janice Potters","service":"Women's Haircut","service_id":"65","client_note":"","stylist_note":"","utc_start":"1299700800","email":"","home_ph":"","mobile_ph":"","work_ph":"","work_ext":"","utc_end":"1299704400"},{"id":"4867","start":"2011-03-09T13:00:00-08:00","end":"2011-03-09T13:15:00-08:00","title":"Jacqui Chan","service":"Women's Haircut","service_id":"65","client_note":"","stylist_note":"","utc_start":"1299704400","email":"jc#rebelfrontier.net","home_ph":"","mobile_ph":"","work_ph":"","work_ext":"","utc_end":"1299705300"},{"id":"4876","start":"2011-03-09T13:15:00-08:00","end":"2011-03-09T13:30:00-08:00","title":"Mary Thacker","service":"Women's Haircut","service_id":"65","client_note":"","stylist_note":"","utc_start":"1299705300","email":"","home_ph":"","mobile_ph":"","work_ph":"","work_ext":"","utc_end":"1299706200"},{"id":"4868","start":"2011-03-10T10:15:00-08:00","end":"2011-03-10T11:15:00-08:00","title":"Trisha Roberts","service":"Women's Haircut","service_id":"65","client_note":"","stylist_note":"","utc_start":"1299780900","email":"trb483408#gmail.com","home_ph":"604-555-5555","mobile_ph":"","work_ph":"","work_ext":"","utc_end":"1299784500"},{"id":"4870","start":"2011-03-10T11:30:00-08:00","end":"2011-03-10T12:30:00-08:00","title":"Jenson Bryant","service":"Women's Haircut","service_id":"65","client_note":"","stylist_note":"","utc_start":"1299785400","email":"","home_ph":"","mobile_ph":"","work_ph":"","work_ext":"","utc_end":"1299789000"},{"id":"4872","start":"2011-03-10T12:45:00-08:00","end":"2011-03-10T13:00:00-08:00","title":"Jenson Bryant","service":"Women's Haircut","service_id":"65","client_note":"","stylist_note":"","utc_start":"1299789900","email":"","home_ph":"","mobile_ph":"","work_ph":"","work_ext":"","utc_end":"1299790800"},{"id":"4873","start":"2011-03-10T13:00:00-08:00","end":"2011-03-10T13:15:00-08:00","title":"Jenson Bryant","service":"Women's Haircut","service_id":"65","client_note":"","stylist_note":"","utc_start":"1299790800","email":"","home_ph":"","mobile_ph":"","work_ph":"","work_ext":"","utc_end":"1299791700"},{"id":"4874","start":"2011-03-10T13:15:00-08:00","end":"2011-03-10T14:15:00-08:00","title":"Simon Chalk","service":"Men's haircut","service_id":"61","client_note":"","stylist_note":"","utc_start":"1299791700","email":"","home_ph":"","mobile_ph":"","work_ph":"","work_ext":"","utc_end":"1299795300"},{"id":"4875","start":"2011-03-11T10:15:00-08:00","end":"2011-03-11T11:15:00-08:00","title":"Karen Walker","service":"Women's Haircut","service_id":"65","client_note":"","stylist_note":"","utc_start":"1299867300","email":"karenwalker#officesurplusdirect.net","home_ph":"","mobile_ph":"","work_ph":"","work_ext":"","utc_end":"1299870900"},{"id":"4877","start":"2011-03-11T12:00:00-08:00","end":"2011-03-11T12:15:00-08:00","title":"Amanda Brenner","service":"Women's Haircut","service_id":"65","client_note":"","stylist_note":"","utc_start":"1299873600","email":"amandab#coastfitness.com","home_ph":"555-235-2366","mobile_ph":"","work_ph":"","work_ext":"","utc_end":"1299874500"},{"id":"4878","start":"2011-03-11T12:30:00-08:00","end":"2011-03-11T13:30:00-08:00","title":"Arnold Fieldman","service":"Men's haircut","service_id":"61","client_note":"","stylist_note":"","utc_start":"1299875400","email":"","home_ph":"","mobile_ph":"","work_ph":"","work_ext":"","utc_end":"1299879000"}], "next_page_num":"7"}
This is not a Sencha Touch specific issue: there are limits on the size of Ajax response that mobile safari can handle: see Too large an AJAX response for mobile safari?
Update: apparently this is not a mobile safari problem, this is a cellular network problem. Some networks will helpfully "paginate" the Ajax call -- thinking it's a regular web page download. Can you check to see if this is still the case on a wifi network?
After much head banging it appears that Sencha Touch stores only work well with up to approximately 10,000 characters I'm guess 8192 + the json delimiters?
After that it seems to start losing part of the data for us.
Can anyone else corroborate this?

Resources