How to read cookie in nsIChannel? - firefox

const {Cc,Ci,Cr} = require("chrome");
function TracingListener() {
//this.receivedData = [];
}
function CCIN(cName, ifaceName) {
return Cc[cName].createInstance(Ci[ifaceName]);
}
function CCSV(cName, ifaceName){
if (Cc[cName])
// if fbs fails to load, the error can be _CC[cName] has no properties
return Cc[cName].getService(Ci[ifaceName]);
};
TracingListener.prototype =
{
originalListener: null,
receivedData: null, // array for incoming data.
onDataAvailable: function(request, context, inputStream, offset, count)
{
this.originalListener.onDataAvailable(request, context,inputStream, offset, count);
},
onStartRequest: function(request, context) {
this.receivedData = [];
this.originalListener.onStartRequest(request, context);
//thechannel.setRequestHeader("X-Hello", "World", false);
//this part of code will stop the request
/*request.QueryInterface(Ci.nsIHttpChannel);
var cookie=request.getRequestHeader("Cookie");
console.log("cookie="+cookie);*/
var postText = this.readPostTextFromRequest(request, context);
console.log("postText="+postText111);
},
onStopRequest: function(request, context, statusCode)
{
//this part of code will successfullly print the cookie
/*request.QueryInterface(Ci.nsIHttpChannel);
var cookie=request.getRequestHeader("Cookie");
console.log("cookie="+cookie);*/
this.originalListener.onStopRequest(request, context, statusCode);
},
QueryInterface: function (aIID) {
if (aIID.equals(Ci.nsIStreamListener) ||
aIID.equals(Ci.nsISupports)) {
return this;
}
throw Cr.NS_NOINTERFACE;
},
readPostTextFromRequest : function(request, context) {
try
{
var is = request.QueryInterface(Ci.nsIUploadChannel).uploadStream;
if (is)
{
var ss = is.QueryInterface(Ci.nsISeekableStream);
var prevOffset;
if (ss)
{
prevOffset = ss.tell();
ss.seek(Ci.nsISeekableStream.NS_SEEK_SET, 0);
}
// Read data from the stream..
var charset = "UTF-8";
var text = this.readFromStream(is, charset, true);
// Seek locks the file so, seek to the beginning only if necko hasn't read it yet,
// since necko doesn't seek to 0 before reading (at lest not till 459384 is fixed).
if (ss && prevOffset == 0)
ss.seek(Ci.nsISeekableStream.NS_SEEK_SET, 0);
return text;
}
else {
//dump("Failed to Query Interface for upload stream.\n");
}
}
catch(exc)
{
//dumpError(exc);
}
return null;
},
readFromStream : function(stream, charset, noClose) {
var sis = CCSV("#mozilla.org/binaryinputstream;1", "nsIBinaryInputStream");
sis.setInputStream(stream);
var segments = [];
for (var count = stream.available(); count; count = stream.available())
segments.push(sis.readBytes(count));
if (!noClose)
sis.close();
var text = segments.join("");
return text;
}
}
hRO = {
observe: function(request, aTopic, aData){
try {
if (aTopic == "http-on-examine-response") {
request.QueryInterface(Ci.nsIHttpChannel);
//if (request.originalURI && piratequesting.baseURL == request.originalURI.prePath && request.originalURI.path.indexOf("/index.php?ajax=") == 0) {
var newListener = new TracingListener();
request.QueryInterface(Ci.nsITraceableChannel);
newListener.originalListener = request.setNewListener(newListener);
//}
}
} catch (e) {
/*dump("\nhRO error: \n\tMessage: " + e.message + "\n\tFile: " + e.fileName + " line: " + e.lineNumber + "\n");*/
}
},
QueryInterface: function(aIID){
if (aIID.equals(Ci.nsIObserver) ||
aIID.equals(Ci.nsISupports)) {
return this;
}
throw Cr.NS_NOINTERFACE;
},
};
var observerService = Cc["#mozilla.org/observer-service;1"]
.getService(Ci.nsIObserverService);
observerService.addObserver(hRO,
"http-on-examine-response", false);
My question is: the same lines of code:
request.QueryInterface(Ci.nsIHttpChannel);
var cookie=request.getRequestHeader("Cookie");
console.log("cookie="+cookie);
performs different results in onStartRequest and onStopRequest, why?
I can read the cookie in onStopRequest but fails in onStartRequest. I don't think the request is not ready in onStartRequest because I can read the postText in onStartRequest.

Related

Cloud Code, complex query with adding a key-value pair before response

I want to get a batch of User objects using Cloud Code. And before collection of objects will send to client they have to take a unique number.
Now it's looking like this
Parse.Cloud.define("getUsers", function(request, response)
{
var query = new Parse.Query(Parse.User);
var mode = parseInt(request.params.mode);
var username = request.params.username;
var skip = parseInt(request.params.skip);
var limit = parseInt(request.params.limit);
if(mode==1)
{
query.notEqualTo("fbLogged",true)
.descending("score")
.notEqualTo("username",username)
.skip(skip)
.limit(limit);
query.find({
success: function(objects)
{
var i = 0;
objects.forEach(function(item)
{
item["rank"]=skip+i; //setting a unique number (position based on score)
});
response.success(objects);
},
error: function(error)
{
response.error(error);
}
});
}
});
And how I use it on client side...
void Start () {
IDictionary<string, object> dict = new Dictionary<string, object>();
dict.Add("username", "477698883");
dict.Add("skip", "300");
dict.Add("limit", "50");
dict.Add("mode", "1");
ParseCloud.CallFunctionAsync<IEnumerable<object>>("getUsers", dict).ContinueWith(t =>
{
if(t.IsCanceled || t.IsFaulted)
{
foreach (var e in t.Exception.InnerExceptions)
Debug.LogError(e.Message);
}
else
{
var r = t.Result;
List<ParseUser> users = new List<ParseUser>();
foreach(var o in r)
{
try {
ParseObject pu = (ParseObject)o;
foreach (var key in pu.Keys)
Debug.Log(key + " = " + pu[key]);
}
catch(Exception e)
{
Debug.LogError(e.Message);
}
break;
}
}
});
}
As you see I just display first of received objects.
And it gives me this data.
But where is the "rank" field?
I just found solution. Each ParseObject which will send to Client by response.success() have to be saved on Parse before sent.
Now my code looks like this and it works
Parse.Cloud.define("getUsers", function(request, response)
{
var query = new Parse.Query(Parse.User);
var mode = parseInt(request.params.mode);
var username = request.params.username;
var skip = parseInt(request.params.skip);
var limit = parseInt(request.params.limit);
if(mode==1)
{
query.notEqualTo("fbLogged",true)
.descending("score")
.notEqualTo("username",username)
.skip(skip)
.limit(limit);
query.find({
success: function(objects)
{
for(var i = 0; i<objects.length; i++)
{
objects[i].set("rank", skip+i);
objects[i].save();
}
response.success(objects);
},
error: function(error)
{
response.error(error);
}
});
}
});

Json result returned as a file in Internet Explorer?

net MVC application, in which I have multiple charts. On these charts, I have applied filters and by clicking each filter, I do an ajax call which returns the result in Json and then applies to the charts.
Now its working perfectly in Firefox and Chrome, but in Internet Explorer - Ajax call is always unsuccessful. I tried hitting the web api url directly through my browser and the issue it seems is, the result json was being returned as a file to be downloaded.
This is my ajax code :
function getIssueResolvedGraphdata(control, departCode, departName) {
$.ajax(
{
type: "GET",
url: WebApiURL + "/api/home/GetQueryIssueResolvedData?deptCode=" + departCode,
dataType: "json",
crossDomain: true,
async: true,
cache: false,
success: function (myData) {
var resolvedStartDate = myData.data.IssueResolvedStartDate;
var issueData = myData.data.IssueData;
var resolveData = myData.data.ResolvedData;
//converting issueData into integer array...
var issue = issueData.replace("[", "");
var issue1 = issue.replace("]", "");
var issue2 = issue1.split(",");
for (var i = 0; i < issue2.length; i++) { issue2[i] = parseInt(issue2[i]); }
//converting resolvedData into integer array
var resolve = resolveData.replace("[", "");
var resolve1 = resolve.replace("]", "");
var resolve2 = resolve1.split(",");
for (var j = 0; j < resolve2.length; j++) { resolve2[j] = parseInt(resolve2[j]); }
//getting max value from array...
var issueMaxVal = Math.max.apply(null, issue2);
var resolveMaxVal = Math.max.apply(null, resolve2);
//Eliminating leading zeros in issue array
var removeIndex = 0;
var myDate;
var newDate;
var arrayLength;
if (issueMaxVal != 0) {
arrayLength = issue2.length;
for (var i = 0; i < arrayLength; i++) {
if (issue2[0] == 0) {
issue2.splice(0, 1);
removeIndex = i;
} else {
break;
}
}
//Getting days count of current month
var monthStart = new Date(new Date().getFullYear(), new Date().getMonth(), 1);
var monthEnd = new Date(new Date().getFullYear(), new Date().getMonth() + 1, 1);
var monthLength = (monthEnd - monthStart) / (1000 * 60 * 60 * 24);
var monthDays = 0;
if (monthLength == 28) {
monthDays = removeIndex;
}
else if (monthLength == 30) {
monthDays = removeIndex + 1;
}
else if (monthLength == 31 || monthLength == 29) {
monthDays = removeIndex + 2;
}
//matching the resultant issue array with resolve array & setting start date
var iDate = resolvedStartDate;
var tDate = '';
for (var i = 0; i < iDate.length; i++) {
if (iDate[i] == ',') {
tDate += '/';
}
else {
tDate += iDate[i];
}
}
if (removeIndex != 0) {
resolve2.splice(0, (removeIndex + 1));
var myDate = new Date(tDate);
myDate.setDate(myDate.getDate() + monthDays);
newDate = Date.UTC(myDate.getFullYear(), (myDate.getMonth() + 1), myDate.getDate());
} else {
var myDate = new Date(tDate);
newDate = Date.UTC(myDate.getFullYear(), (myDate.getMonth() + 1), myDate.getDate());
}
} else {
alert("Empty");
}
//updating chart here...
var chart = $('#performance-cart').highcharts();
chart.series[0].update({
pointStart: newDate,
data: issue2
});
chart.series[1].update({
pointStart: newDate,
data: resolve2
});
if (issueMaxVal > resolveMaxVal) {
chart.yAxis[0].setExtremes(0, issueMaxVal);
} else {
chart.yAxis[0].setExtremes(0, resolveMaxVal);
}
},
error: function (x, e) {
alert('There seems to be some problem while fetching records!');
} });}
Code from web api controller :
[HttpGet]
[CrossDomainActionFilter]
public Response<GraphIssueResolvedWrapper> GetQueryIssueResolvedData(string deptCode)
{
Response<GraphIssueResolvedWrapper> objResponse = new Response<GraphIssueResolvedWrapper>();
GraphIssueResolvedWrapper objGraphIssueResolvedWrapper = new GraphIssueResolvedWrapper();
try
{
....code.....
objResponse.isSuccess = true;
objResponse.errorDetail = string.Empty;
objResponse.data = objGraphIssueResolvedWrapper;
}
catch (Exception ex)
{
objResponse.isSuccess = false;
objResponse.errorDetail = ex.Message.ToString();
objResponse.data = null;
}
return objResponse;
}
Reponse Class :
public class Response<T>
{
public bool isSuccess { get; set; }
public string errorDetail { get; set; }
public T data { get; set; }
}
I am stuck at this for hours now. Any help will be appreciated.
I have solved my problem by using the following code : ( I guess it needed CORS support)
function isIE() {
var ua = window.navigator.userAgent;
var msie = ua.indexOf("MSIE");
if (msie > 0)
return true;
return false;
}
Then in document.ready function of my binding script :
$(document).ready(function () {
if (isIE())
$.support.cors = true;
});
Note : it still download Json stream as a file but now my AJAX call is successful upon each hit.
You've missed contentType: 'text/html' which is pretty important for IE7-8:
$.ajax(
{
type: "GET",
url: WebApiURL + "/api/home/GetQueryIssueResolvedData?deptCode=" + departCode,
dataType: "json",
contentType: 'text/html'
crossDomain: true,
async: true,
cache: false,
success: function (myData) {
var result = JSON.parse(myData);
///...code...
},
error: function (x, e) {
alert('There seems to be some problem while fetching records!');
}
}
);
To make it works in IE7-8 you also need to be sure that you've writing Conrent-Type Header into your response on server side. Add this line right before return statement;
response.Content.Headers.ContentType = new MediaTypeHeaderValue("text/html; charset=iso-8859-1");
And in code probably you will need to parse result in success method by using JSON.parse(myData);

Cached data returned when making same Web API call consecutively using Breeze.js

I am facing a strange issue while writing a Breeze.js with Durandal SPA (largely based on John Papa's Great SPA Jumpstart (https://github.com/johnpapa/PluralsightSpaJumpStartFinal) training ), the issue when a try to make the same server API call multiple times consecutively the server is hit only once and one the second call it seems I get cached data (call doesn't even hit server), this can be replicated in Jumpstart sample too, below is the modified code to replicate this on Jumpstart
var activate = function () {
for (var i = 0 ; i < 2 ; i++) {
datacontext.getSessionPartials(sessions, true);
}
};
var activate = function () {
for (var i = 0 ; i < 2 ; i++)
{
datacontext.getSpeakerPartials(speakers, true);
}
};
Edit- Updated with the complete code :
Code of my Viewmodel
define(['services/datacontext'], function (datacontext) {
var speakers = ko.observableArray();
var activate = function () {
for (var i = 0 ; i < 2 ; i++)
{
datacontext.getSpeakerPartials(speakers, true);
}
};
var refresh = function () {
return datacontext.getSpeakerPartials(speakers, true);
};
var vm = {
activate: activate,
speakers: speakers,
title: 'Speakers',
refresh: refresh
};
return vm;
});
Below is code of my datacontext/service :
define([
'durandal/system',
'services/model',
'config',
'services/logger',
'services/breeze.partial-entities'],
function (system, model, config, logger, partialMapper) {
var EntityQuery = breeze.EntityQuery;
var manager = configureBreezeManager();
var orderBy = model.orderBy;
var entityNames = model.entityNames;
var getSpeakerPartials = function (speakersObservable, forceRemote) {
if (!forceRemote) {
var p = getLocal('Persons', orderBy.speaker);
if (p.length > 0) {
speakersObservable(p);
return Q.resolve();
}
}
var query = EntityQuery.from('Speakers')
.select('id, firstName, lastName, imageSource')
.orderBy(orderBy.speaker);
return manager.executeQuery(query)
.then(querySucceeded)
.fail(queryFailed);
function querySucceeded(data) {
var list = partialMapper.mapDtosToEntities(
manager, data.results, entityNames.speaker, 'id');
if (speakersObservable) {
speakersObservable(list);
}
log('Retrieved [Speaker] from remote data source',
data, true);
}
};
var getSessionPartials = function (sessionsObservable, forceRemote) {
if (!forceRemote) {
var s = getLocal('Sessions', orderBy.session);
if (s.length > 3) {
// Edge case
// We need this check because we may have 1 entity already.
// If we start on a specific person, this may happen. So we check for > 2, really
sessionsObservable(s);
return Q.resolve();
}
}
var query = EntityQuery.from('Sessions')
.select('id, title, code, speakerId, trackId, timeSlotId, roomId, level, tags')
.orderBy('timeSlotId, level, speaker.firstName');
return manager.executeQuery(query)
.then(querySucceeded)
.fail(queryFailed);
function querySucceeded(data) {
var list = partialMapper.mapDtosToEntities(
manager, data.results, entityNames.session, 'id');
if (sessionsObservable) {
sessionsObservable(list);
}
log('Retrieved [Sessions] from remote data source',
data, true);
}
};
var getSessionById = function(sessionId, sessionObservable) {
// 1st - fetchEntityByKey will look in local cache
// first (because 3rd parm is true)
// if not there then it will go remote
return manager.fetchEntityByKey(
entityNames.session, sessionId, true)
.then(fetchSucceeded)
.fail(queryFailed);
// 2nd - Refresh the entity from remote store (if needed)
function fetchSucceeded(data) {
var s = data.entity;
return s.isPartial() ? refreshSession(s) : sessionObservable(s);
}
function refreshSession(session) {
return EntityQuery.fromEntities(session)
.using(manager).execute()
.then(querySucceeded)
.fail(queryFailed);
}
function querySucceeded(data) {
var s = data.results[0];
s.isPartial(false);
log('Retrieved [Session] from remote data source', s, true);
return sessionObservable(s);
}
};
var cancelChanges = function() {
manager.rejectChanges();
log('Canceled changes', null, true);
};
var saveChanges = function() {
return manager.saveChanges()
.then(saveSucceeded)
.fail(saveFailed);
function saveSucceeded(saveResult) {
log('Saved data successfully', saveResult, true);
}
function saveFailed(error) {
var msg = 'Save failed: ' + getErrorMessages(error);
logError(msg, error);
error.message = msg;
throw error;
}
};
var primeData = function () {
var promise = Q.all([
getLookups(),
getSpeakerPartials(null, true)])
.then(applyValidators);
return promise.then(success);
function success() {
datacontext.lookups = {
rooms: getLocal('Rooms', 'name', true),
tracks: getLocal('Tracks', 'name', true),
timeslots: getLocal('TimeSlots', 'start', true),
speakers: getLocal('Persons', orderBy.speaker, true)
};
log('Primed data', datacontext.lookups);
}
function applyValidators() {
model.applySessionValidators(manager.metadataStore);
}
};
var createSession = function() {
return manager.createEntity(entityNames.session);
};
var hasChanges = ko.observable(false);
manager.hasChangesChanged.subscribe(function(eventArgs) {
hasChanges(eventArgs.hasChanges);
});
var datacontext = {
createSession: createSession,
getSessionPartials: getSessionPartials,
getSpeakerPartials: getSpeakerPartials,
hasChanges: hasChanges,
getSessionById: getSessionById,
primeData: primeData,
cancelChanges: cancelChanges,
saveChanges: saveChanges
};
return datacontext;
//#region Internal methods
function getLocal(resource, ordering, includeNullos) {
var query = EntityQuery.from(resource)
.orderBy(ordering);
if (!includeNullos) {
query = query.where('id', '!=', 0);
}
return manager.executeQueryLocally(query);
}
function getErrorMessages(error) {
var msg = error.message;
if (msg.match(/validation error/i)) {
return getValidationMessages(error);
}
return msg;
}
function getValidationMessages(error) {
try {
//foreach entity with a validation error
return error.entitiesWithErrors.map(function(entity) {
// get each validation error
return entity.entityAspect.getValidationErrors().map(function(valError) {
// return the error message from the validation
return valError.errorMessage;
}).join('; <br/>');
}).join('; <br/>');
}
catch (e) { }
return 'validation error';
}
function queryFailed(error) {
var msg = 'Error retreiving data. ' + error.message;
logError(msg, error);
throw error;
}
function configureBreezeManager() {
breeze.NamingConvention.camelCase.setAsDefault();
var mgr = new breeze.EntityManager(config.remoteServiceName);
model.configureMetadataStore(mgr.metadataStore);
return mgr;
}
function getLookups() {
return EntityQuery.from('Lookups')
.using(manager).execute()
.then(processLookups)
.fail(queryFailed);
}
function processLookups() {
model.createNullos(manager);
}
function log(msg, data, showToast) {
logger.log(msg, data, system.getModuleId(datacontext), showToast);
}
function logError(msg, error) {
logger.logError(msg, error, system.getModuleId(datacontext), true);
}
//#endregion
});
Below is the code for BreezeController/WebApi
namespace CodeCamper.Controllers
{
[BreezeController]
public class BreezeController : ApiController
{
readonly EFContextProvider<CodeCamperDbContext> _contextProvider =
new EFContextProvider<CodeCamperDbContext>();
[HttpGet]
public string Metadata()
{
return _contextProvider.Metadata();
}
[HttpPost]
public SaveResult SaveChanges(JObject saveBundle)
{
return _contextProvider.SaveChanges(saveBundle);
}
[HttpGet]
public object Lookups()
{
var rooms = _contextProvider.Context.Rooms;
var tracks = _contextProvider.Context.Tracks;
var timeslots = _contextProvider.Context.TimeSlots;
return new {rooms, tracks, timeslots};
}
[HttpGet]
public IQueryable<Session> Sessions()
{
return _contextProvider.Context.Sessions;
}
[HttpGet]
public IQueryable<Person> Persons()
{
return _contextProvider.Context.Persons;
}
[HttpGet]
public IQueryable<Person> Speakers()
{
return _contextProvider.Context.Persons
.Where(p => p.SpeakerSessions.Any());
}
}
}
Please help/advise.

Facebook check in and windows phone

I've got a script that essentially gives the user the ability to check in to a specific location when they click it. Upon clicking it, it checks them into the same location each time.
On desktop this works fine and I suspect it works on Android too. I have a WP and thus obviously I want to get it working on there. This feature is pretty much going to be used exclusively on mobile so getting it working cross-device is important.
Now, to the actual issue. Upon clicking the check in button on WP it loads a blank page and hangs there. Whilst this may be a signal that it perhaps has checked in, when I look it hasn't. So it's hanging there and doing nothing.
This is the URL it's hanging on: https://m.facebook.com/dialog/oauth?display=touch&domain=www.staffscuesociety.com&scope=publish_stream&api_key=API_KEY&app_id=APP_ID&locale=en_US&sdk=joey&access_token=ACCESS_TOKEN&client_id=CLIENT_ID&redirect_uri=http%3A%2F%2Fstatic.ak.facebook.com%2Fconnect%2Fxd_arbiter.php%3Fversion%3D18%23cb%3Df35fef827217048%26origin%3Dhttp%253A%252F%252Fwww.staffscuesociety.com%252Ff166245837c3b6e%26domain%3Dwww.staffscuesociety.com%26relation%3Dopener%26frame%3Df398a7113310e64&origin=2&response_type=token%2Csigned_request
and this is the code:
var button;
(function(d){
var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0];
if (d.getElementById(id)) { return; }
js = d.createElement('script'); js.id = id; js.async = true;
js.src = "//connect.facebook.net/en_US/all.js";
ref.parentNode.insertBefore(js, ref);
}(document));
window.fbAsyncInit = function() {
FB.init({
appId : '260445377421174',
channelUrl : '//www.staffscuesociety.com/checkin/channel.html'
});
button = document.getElementById('checkinWidget');
if (!button) return;
if (!getPost()) {
allowCheckin();
} else {
allowUndo();
}
};
function setPost(value) {
var d = new Date();
d.setDate(d.getTime() + (10 * 60 * 1000));
document.cookie = 'post=' + escape(value) + ';expires=' + d.toUTCString();
}
function getPost() {
return getCookie('post');
}
function getCookie(key) {
currentcookie = document.cookie;
if (currentcookie.length > 0) {
firstidx = currentcookie.indexOf(key + '=');
if (firstidx != -1) {
firstidx = firstidx + key.length + 1;
lastidx = currentcookie.indexOf(';', firstidx);
if (lastidx == -1) {
lastidx = currentcookie.length;
}
return unescape(currentcookie.substring(firstidx, lastidx));
}
}
return '';
}
function checkin() {
allowNothing();
FB.login(function(response) {
if (response.authResponse) {
FB.api('/me/permissions', function (permissions) {
if (permissions.data.length > 0 && permissions.data[0].publish_stream) {
FB.api('/me/feed', 'post', { message: null, place: '117072761683514' }, function(post) {
if (!post || post.error) {
showError();
} else {
setPost(post.id);
allowUndo();
}
});
} else {
allowCheckin();
}
});
} else {
allowCheckin();
}
}, {scope : 'publish_stream'});
}
function undo() {
allowNothing();
FB.api('/' + getPost(), 'delete', function(response) {
setPost('');
allowCheckin();
});
}
function allowNothing() {
button.onclick = function() { };
button.className = 'pressed';
}
function allowCheckin() {
button.onclick = checkin;
button.className = '';
}
function allowUndo() {
button.onclick = undo;
button.className = 'pressed tick';
}
function showError() {
button.className = 'pressed error';
}
}

Not able to modify POST data in Firefox extension

I am trying to implement a Firefox Extension which modify the POST request data.
Code follows, it fails where marked "Fails here!!!"
Any insight would be helpful.
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
var newData = "test 123";
function LOG(msg) {
var consoleService = Components.classes["#mozilla.org/consoleservice;1"]
.getService(Components.interfaces.nsIConsoleService);
consoleService.logStringMessage(msg);
}
function CMP() {
this.registered = false;
this.register();
}
CMP.prototype = {
register: function() {
if (this.registered == false) {
var observerService = Components.classes["#mozilla.org/observer-service;1"]
.getService(Components.interfaces.nsIObserverService);
observerService.addObserver(this, "http-on-modify-request", false);
this.registered = true;
}
},
observe: function(subject, topic, data)
{
LOG("Inside observe");
if (topic == "http-on-modify-request")
{
LOG("TOPIC is http-on-modify-request");
var httpChannel = subject.QueryInterface(Components.interfaces.nsIHttpChannel);
if(httpChannel.requestMethod == "POST"){
LOG("Inside POST")
var uploadChannel = httpChannel.QueryInterface(Components.interfaces.nsIUploadChannel);
//var uploadChannelStream = uploadChannel.uploadStream;
Modify the data here. Here for testing i am passing "test 123" as new data
var newStringInputStream = Components.classes['#mozilla.org/io/string-input-stream;1'].createInstance(Components.interfaces.nsIStringInputStream);
newStringInputStream.setData(newData,newData.length);
LOG("set data in newStringInputStream!!");
uploadChannel.setUploadStream(newStringInputStream, "text/plain", -1 );// Fails here!!!
httpChannel.requestMethod = "POST";
LOG("upload DONE!!")
}
}
},
QueryInterface : function(aIID) {
if (aIID.equals(Components.interfaces.nsISupports) ||
aIID.equals(Components.interfaces.nsIObserver))
return this;
throw Components.results.NS_NOINTERFACE;
},
unregister: function() {
var observerService = Components.classes["#mozilla.org/observer-service;1"]
.getService(Components.interfaces.nsIObserverService);
observerService.removeObserver(this, "http-on-modify-request");
},
classID: Components.ID('{F799F47E-ABA5-4AF1-B8F2-BD74E3E5BCC0}'),
QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsIObserver])
};
if (XPCOMUtils.generateNSGetFactory)
{
var NSGetFactory = XPCOMUtils.generateNSGetFactory([CMP]);
}
Fixed it by changing by following in the above code. Main change was in setting modified data in httpChannel.uploadStream.
Hope this helps someone!
var httpChannel = subject.QueryInterface(Components.interfaces.nsIHttpChannel);
if(httpChannel.requestMethod == "POST")
{
LOG("Inside POST")
var uploadChannel = httpChannel.QueryInterface(Components.interfaces.nsIUploadChannel);
var newStringInputStream = Components.classes['#mozilla.org/io/string-input-stream;1'].createInstance(Components.interfaces.nsIStringInputStream);
newStringInputStream.setData(newData,newData.length);
var uploadChannelStream = uploadChannel.uploadStream;
uploadChannelStream = uploadChannelStream.QueryInterface(Components.interfaces.nsISeekableStream).seek(Components.interfaces.nsISeekableStream.NS_SEEK_SET, 0);
httpChannel.uploadStream.QueryInterface(Components.interfaces.nsIMIMEInputStream);
httpChannel.uploadStream.setData(newStringInputStream);
LOG("Done POST")
}

Resources