Scorm files, Ruby on Rails - ruby-on-rails

I have implemented a scorm api in my platform (LMS), for this I have used Ruby on rails, the Scorm gem and the javascript api.
Everything works correctly and the scorm contents are displayed with satisfaction. I do not have much experience in Scorm content, but there is a zip file that they sent me of type scorm, which when it is uploaded to the platform that I am using, it takes a long time to load and execute. when I test this file on Scorm cloud, the content runs normally. The problem is that the platform does not generate any error.
why can this happen?
bugs in my code? or optimization of the Scorm zip file?
The other scorm contents work normally, but this specific one, I have no idea why. I can not think of anything
any ideas? Thank you
this is de api js:
<html>
<head>
<title>VS SCORM - RTE API</title>
<script language="javascript">
function createRequest() {
// this is the object that we're going to (try to) create
var request;
// does the browser have native support for
// the XMLHttpRequest object
try {
request = new XMLHttpRequest();
}
// it failed so it's likely to be Internet Explorer which
// uses a different way to do this
catch (tryIE) {
// try to see if it's a newer version of Internet Explorer
try {
request = new ActiveXObject("Msxml2.XMLHTTP");
}
// that didn't work so ...
catch (tryOlderIE) {
// maybe it's an older version of Internet Explorer
try {
request = new ActiveXObject("Microsoft.XMLHTTP");
}
// even that didn't work (sigh)
catch (failed) {
alert("Error creating XMLHttpRequest");
}
}
}
return request;
}
//var debug = true;
var debug = false;
function sleep(milliseconds) {
var start = new Date().getTime();
for (var i = 0; i < 1e7; i++) {
if ((new Date().getTime() - start) > milliseconds){
break;
}
}
}
// ------------------------------------------
// SCORM RTE Functions - Initialization
// ------------------------------------------
function LMSInitialize(dummyString) {
// create request object
var req = createRequest();
// code to prevent caching
var d = new Date();
// set up request parameters - uses GET method
req.open('GET','/scorm/initializesco?code='+d.getTime(),false);
// submit to the server for processing
req.send(null);
// process returned data - error condition
if (req.status != 200) {
alert('Problem with Request');
return "";
}
// process returned data - OK
else {
return "true";
}
}
// ------------------------------------------
// SCORM RTE Functions - Getting and Setting Values
// ------------------------------------------
//function LMSGetValue(varname) {
// if (debug) {
// alert('*** LMSGetValue varname='+varname
// +' varvalue=value ***');
// }
// return "value";
//}
function LMSGetValue(varname) {
// create request object
var req = createRequest();
// set up request parameters - uses GET method
req.open('GET','/scorm/getValue?varname='+urlencode(varname)
+'&code='+Math.random(),false);
// submit to the server for processing
req.send(null);
//alert('LMSGetValue() - ' + req.responseText);
// process returned data - error condition
if (req.status != 200) {
alert('LMSGetValue() - Problem with Request');
return "";
}
// process returned data - OK
else {
return req.responseText.replace("\n","");
}
}
/*
function LMSSetValue(varname,varvalue) {
if (debug) {
alert('*** LMSSetValue varname='+varname
+' varvalue='+varvalue+' ***');
}
return "true";
}
*/
function LMSSetValue(varname,varvalue) {
// create request object
var req = createRequest();
// set up request parameters - uses combined GET and POST
//req.open('POST','nav/setValue?varname='+urlencode(varname)
// +'&code='+Math.random(),false);
// set up request parameters - uses combined GET and POST
req.open('POST','/scorm/setValue?varname='+urlencode(varname)
+'&code='+Math.random(),false);
// send header information along with the POST data
var params = 'varvalue='+urlencode(varvalue);
req.setRequestHeader("Content-type",
"application/x-www-form-urlencoded");
//req.setRequestHeader("Content-length", params.length);
//req.setRequestHeader("Connection", "close");
// submit to the server for processing
req.send(params);
// process returned data - error condition
if (req.status != 200) {
alert('LMSSetValue() - Problem with Request');
return "false";
}
// process returned data - OK
else {
return "true";
}
}
function LMSCommit(dummyString) {
LMSGetValue('');
if (debug)
{
//alert('*** LMSCommit ***');
}
return "true";
}
function LMSFinish(dummyString) {
// create request object
var req = createRequest();
// code to prevent caching
var d = new Date();
// set up request parameters - uses GET method
req.open('GET','/scorm/finishsco?code='+d.getTime(),false);
// submit to the server for processing
req.send(null);
// process returned data - error condition
if (req.status != 200) {
alert('Problem with Request');
return "";
}
// process returned data - OK
else {
return "true";
}
}
// ------------------------------------------
// SCORM RTE Functions - Error Handling
// ------------------------------------------
function LMSGetLastError() {
if (debug) { alert('*** LMSGetLastError ***'); }
sleep(1000);
return 0;
}
function LMSGetDiagnostic(errorCode) {
if (debug) {
alert('*** LMSGetDiagnostic errorCode='+errorCode+' ***');
}
return "diagnostic string";
}
function LMSGetErrorString(errorCode) {
if (debug) {
alert('*** LMSGetErrorString errorCode='+errorCode+' ***');
}
return "error string";
}
function urlencode( str ) {
//
// Ref: http://kevin.vanzonneveld.net/techblog/article/javascript_equivalent_for_phps_urlencode/
//
var histogram = {}, unicodeStr='', hexEscStr='';
var ret = (str+'').toString();
var replacer = function(search, replace, str) {
var tmp_arr = [];
tmp_arr = str.split(search);
return tmp_arr.join(replace);
};
// The histogram is identical to the one in urldecode.
histogram["'"] = '%27';
histogram['('] = '%28';
histogram[')'] = '%29';
histogram['*'] = '%2A';
histogram['~'] = '%7E';
histogram['!'] = '%21';
histogram['%20'] = '+';
histogram['\u00DC'] = '%DC';
histogram['\u00FC'] = '%FC';
histogram['\u00C4'] = '%D4';
histogram['\u00E4'] = '%E4';
histogram['\u00D6'] = '%D6';
histogram['\u00F6'] = '%F6';
histogram['\u00DF'] = '%DF';
histogram['\u20AC'] = '%80';
histogram['\u0081'] = '%81';
histogram['\u201A'] = '%82';
histogram['\u0192'] = '%83';
histogram['\u201E'] = '%84';
histogram['\u2026'] = '%85';
histogram['\u2020'] = '%86';
histogram['\u2021'] = '%87';
histogram['\u02C6'] = '%88';
histogram['\u2030'] = '%89';
histogram['\u0160'] = '%8A';
histogram['\u2039'] = '%8B';
histogram['\u0152'] = '%8C';
histogram['\u008D'] = '%8D';
histogram['\u017D'] = '%8E';
histogram['\u008F'] = '%8F';
histogram['\u0090'] = '%90';
histogram['\u2018'] = '%91';
histogram['\u2019'] = '%92';
histogram['\u201C'] = '%93';
histogram['\u201D'] = '%94';
histogram['\u2022'] = '%95';
histogram['\u2013'] = '%96';
histogram['\u2014'] = '%97';
histogram['\u02DC'] = '%98';
histogram['\u2122'] = '%99';
histogram['\u0161'] = '%9A';
histogram['\u203A'] = '%9B';
histogram['\u0153'] = '%9C';
histogram['\u009D'] = '%9D';
histogram['\u017E'] = '%9E';
histogram['\u0178'] = '%9F';
// Begin with encodeURIComponent, which most resembles PHP's encoding functions
ret = encodeURIComponent(ret);
for (unicodeStr in histogram) {
hexEscStr = histogram[unicodeStr];
ret = replacer(unicodeStr, hexEscStr, ret); // Custom replace. No regexing
}
// Uppercase for full PHP compatibility
return ret.replace(/(\%([a-z0-9]{2}))/g, function(full, m1, m2) {
return "%"+m2.toUpperCase();
});
}
</script>
</head>
<body>
<p>
</body>
</html>

You're using blocking GET/SET requests (XHR async=false) to your backend for every LMSGetValue call. Some courses are much more aggressive about how many things they get and set at launch/initialization time. Most SCORM implementations do the heavy lifting in JS (all GET value processing never touches a server, most commonly) and only go to the backend for user state storage, often at a commit or some storage frequency. If that's the issue, there's no way to fix it that doesn't involve rewriting your interface to do all the SCORM logic client-side instead of server-side, as you can't switch to using async GET calls since LMSGetValue expects the return to be the value needed.

Related

Cloudflare service worker code to "Bypass cache on cookie" not working

I wrote this code as a Cloudflare Service Worker which is meant to precisely emulate their native function for "Bypass cache on cookie". Specifically, if someone has a Wordpress cookie - it would bypass cache, otherwise it does not.
It does not seem to function at all - in that despite having a cookie and being logged in (confirmed via Chrome developer tools) - I still get a Cloudflare cache HIT on this example domain - Tallyfy. Anything wrong with it? Help appreciated!
// A Service Worker which skips cache if the request contains a cookie.
addEventListener('fetch', event => {
let request = event.request;
var flag=false;
if(request.headers.cookie) {
var pairs = request.headers.cookie.split(";");
var patt = new RegExp("wp-.*|wordpress.*|comment_.*|woocommerce_.*")
for(var i=0;i<pairs.length;i++){
if(patt.test(pairs[i])){
flag = true;
break;
}
}
}
if (request.headers.has('Cookie') && flag) {
// Cookie present. Add Cache-Control: no-cache.
let newHeaders = new Headers(request.headers)
newHeaders.set('Cache-Control', 'no-cache')
event.respondWith(fetch(request, {headers: newHeaders}))
}
// Use default behavior.
return
})
try this and let me know
addEventListener('fetch', event => {
let request = event.request
var flag = false;
if (request.headers.has('Cookie')) {
var cookie = request.headers.get('Cookie');
pairs = cookie.split(";");
var patt = new RegExp("wordpress_logged_in.*|wp_woocommerce_session.*");
for(var i=0;i<pairs.length;i++){
if(patt.test(pairs[i])){
flag = true;
break;
}
}
console.log(flag);
if (request.headers.has('Cookie') && flag) {
let newHeaders = new Headers(request.headers)
newHeaders.set('Cache-Control', 'no-cache')
newHeaders.set('Pragma', 'no-cache')
event.respondWith(fetch(request, {headers: newHeaders}))
}
// Use default behavior.
return;
}
})

Performing an AJAX call from JS in asp.net MVC without Jquery

I am developing an app that will be used on an old WInCE devices where IE Embedded doesn't support Jquery, which is why I can use it. So, my question is, what is the way to perform an AJAX call from within a js file.
Code:
html
#using (Html.BeginForm("", "SomeAction", FormMethod.Post, new { id = "myId" }))
{
input field 1: <input type="text" name="somename1"><br>
}
What I need to do is call a validate routine and return a string when the user clicks enter on the somename1 input field.
Normally, this would be done with Jquery, so how do I do it without only utilizing what the MVC asp has to offer (again, the ajax might not work at all on the old browser, but I would like to give it a shot and avoid refreshing the whole page).
Step 1: Get a XMLHttp Object using:
function getXMLHttpRequest() {
var xmlHttpReq = false;
// to create XMLHttpRequest object in non-Microsoft browsers
if (window.XMLHttpRequest) {
xmlHttpReq = new XMLHttpRequest();
} else if (window.ActiveXObject) {
try {
xmlHttpReq = new ActiveXObject("Msxml2.XMLHTTP");
} catch (exp1) {
try {
// to create XMLHttpRequest object in older versions
// of Internet Explorer
xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
} catch (exp2) {
xmlHttpReq = false;
}
}
}
return xmlHttpReq;
}
Then do this (Just an example for downloading a file ajax request)
function myFunction(){
var xmlHttpRequest = getXMLHttpRequest();
xmlHttpRequest.onreadystatechange = getReadyStateHandler_download_file(xmlHttpRequest,file_indicator);
xmlHttpRequest.open("GET", "/wasa-app/DownloadServlet?pmuId="+pmuID+"&dlDate=" + formatted_date+"&check_flag=1"+"&file_indicator="+file_indicator, true);
xmlHttpRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xmlHttpRequest.send(null);
}
function getReadyStateHandler_download_file(xmlHttpRequest, fileIndicator) {
return function() {
if (xmlHttpRequest.readyState == 4) {
if (xmlHttpRequest.status == 200) {
populateSchedule();
var resp = xmlHttpRequest.responseText;
if (resp == ""){
document.getElementById("save_" + fileIndicator).disabled = false;
document.getElementById("message").innerHTML = "";
}
else{
document.getElementById("save_" + fileIndicator).disabled = true;
document.getElementById("message").innerHTML = xmlHttpRequest.responseText;
}
} else {
alert("HTTP error -- " + xmlHttpRequest.status + ": " + xmlHttpRequest.statusText);
}
}
};

Firefox SDK: How to make trigger for certain domain

I need to catch requests on sites with URLs *.net and take some actions (stop request and put HTML code from disk, but this I can do). How do I catch these requests?
I tried to use progress listeners, but something is wrong:
const STATE_START = Ci.nsIWebProgressListener.STATE_START;
var myListener = {
QueryInterface: XPCOMUtils.generateQI(["nsIWebProgressListener",
"nsISupportsWeakReference"]),
onStateChange: function(aWebProgress, aRequest, aFlag, aStatus) {
if (aFlag & STATE_START) {
// actions
}
}
use nsIHTTPChannel and observer service. copy paste it. however .net can be included in resources like javascript things, if you want to test if its specfically a window you have to check for some load flags of LOAD_INITIAL_DOCUMENT_URI, also will want to chec
Cu.import('resource://gre/modules/Services.jsm');
var httpRequestObserver = {
observe: function (subject, topic, data) {
var httpChannel, requestURL;
if (topic == "http-on-modify-request") {
httpChannel = subject.QueryInterface(Ci.nsIHttpChannel);
requestURL = httpChannel.URI.spec;
var newRequestURL, i;
if (httpChannel.loadFlags & httpChannel.LOAD_INITIAL_DOCUMENT_URI) {
//ok continue because loadFlags is a document
} else {
//its not a document, probably a resource like a js file image or css or something, but maybe could be ajax call
return;
}
if (requestURL.indexOf('.net')) {
var goodies = loadContextGoodies(httpChannel);
if (goodies) {
httpChannel.cancel(Cr.NS_BINDING_ABORTED);
goodies.contentWindow.location = self.data.url('pages/test.html');
} else {
//dont do anything as there is no contentWindow associated with the httpChannel, liekly a google ad is loading or some ajax call or something, so this is not an error
}
}
return;
}
}
};
Services.obs.addObserver(httpRequestObserver, "http-on-modify-request", false);
//this function gets the contentWindow and other good stuff from loadContext of httpChannel
function loadContextGoodies(httpChannel) {
//httpChannel must be the subject of http-on-modify-request QI'ed to nsiHTTPChannel as is done on line 8 "httpChannel = subject.QueryInterface(Ci.nsIHttpChannel);"
//start loadContext stuff
var loadContext;
try {
var interfaceRequestor = httpChannel.notificationCallbacks.QueryInterface(Ci.nsIInterfaceRequestor);
//var DOMWindow = interfaceRequestor.getInterface(Components.interfaces.nsIDOMWindow); //not to be done anymore because: https://developer.mozilla.org/en-US/docs/Updating_extensions_for_Firefox_3.5#Getting_a_load_context_from_a_request //instead do the loadContext stuff below
try {
loadContext = interfaceRequestor.getInterface(Ci.nsILoadContext);
} catch (ex) {
try {
loadContext = subject.loadGroup.notificationCallbacks.getInterface(Ci.nsILoadContext);
} catch (ex2) {}
}
} catch (ex0) {}
if (!loadContext) {
//no load context so dont do anything although you can run this, which is your old code
//this probably means that its loading an ajax call or like a google ad thing
return null;
} else {
var contentWindow = loadContext.associatedWindow;
if (!contentWindow) {
//this channel does not have a window, its probably loading a resource
//this probably means that its loading an ajax call or like a google ad thing
return null;
} else {
var aDOMWindow = contentWindow.top.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShellTreeItem)
.rootTreeItem
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindow);
var gBrowser = aDOMWindow.gBrowser;
var aTab = gBrowser._getTabForContentWindow(contentWindow.top); //this is the clickable tab xul element, the one found in the tab strip of the firefox window, aTab.linkedBrowser is same as browser var above //can stylize tab like aTab.style.backgroundColor = 'blue'; //can stylize the tab like aTab.style.fontColor = 'red';
if (aTab == null) {
return null;
}
else {
var browser = aTab.linkedBrowser; //this is the browser within the tab //this is where the example in the previous section ends
return {
aDOMWindow: aDOMWindow,
gBrowser: gBrowser,
aTab: aTab,
browser: browser,
contentWindow: contentWindow
};
}
}
//end loadContext stuff
}

Display progress of a command line process that is running in MVC

I wrote an MVC action that runs a utility with input parameters and writes the utilities output to the response html. here is the full method:
var jobID = Guid.NewGuid();
// save the file to disk so the CMD line util can access it
var inputfilePath = Path.Combine(#"c:\", String.Format("input_{0:n}.json", jobID));
var outputfilePath = Path.Combine(#"c:\", String.Format("output{0:n}.json", jobID));
using (var inputFile = System.IO.File.CreateText(inputfilePath))
{
inputFile.Write(i_JsonInput);
}
var psi = new ProcessStartInfo(#"C:\Code\FoxConcept\FoxConcept\test.cmd", String.Format("{0} {1}", inputfilePath, outputfilePath))
{
WorkingDirectory = Environment.CurrentDirectory,
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true
};
using (var process = new Process { StartInfo = psi })
{
// delegate for writing the process output to the response output
Action<Object, DataReceivedEventArgs> dataReceived = ((sender, e) =>
{
if (e.Data != null) // sometimes a random event is received with null data, not sure why - I prefer to leave it out
{
Response.Write(e.Data);
Response.Write(Environment.NewLine);
Response.Flush();
}
});
process.OutputDataReceived += new DataReceivedEventHandler(dataReceived);
process.ErrorDataReceived += new DataReceivedEventHandler(dataReceived);
// use text/plain so line breaks and any other whitespace formatting is preserved
Response.ContentType = "text/plain";
// start the process and start reading the standard and error outputs
process.Start();
process.BeginErrorReadLine();
process.BeginOutputReadLine();
// wait for the process to exit
process.WaitForExit();
// an exit code other than 0 generally means an error
if (process.ExitCode != 0)
{
Response.StatusCode = 500;
}
}
Response.End();
The utility takes around a minute to complete and it displays relevant information along the way.
is it possible to display the the information as it runs on the user's browser ?
I hope this link will help: Asynchronous processing in ASP.Net MVC with Ajax progress bar
You can call Controller's action method and get the status of the process.
Controller code:
/// <summary>
/// Starts the long running process.
/// </summary>
/// <param name="id">The id.</param>
public void StartLongRunningProcess(string id)
{
longRunningClass.Add(id);
ProcessTask processTask = new ProcessTask(longRunningClass.ProcessLongRunningAction);
processTask.BeginInvoke(id, new AsyncCallback(EndLongRunningProcess), processTask);
}
jQuery Code:
$(document).ready(function(event) {
$('#startProcess').click(function() {
$.post("Home/StartLongRunningProcess", { id: uniqueId }, function() {
$('#statusBorder').show();
getStatus();
});
event.preventDefault;
});
});
function getStatus() {
var url = 'Home/GetCurrentProgress/' + uniqueId;
$.get(url, function(data) {
if (data != "100") {
$('#status').html(data);
$('#statusFill').width(data);
window.setTimeout("getStatus()", 100);
}
else {
$('#status').html("Done");
$('#statusBorder').hide();
alert("The Long process has finished");
};
});
}

An observer for page loads in a custom xul:browser

In my firefox extension I'm creating a xul:browser element. I want to have an observer that intercepts any url changes within the embedded browser and opens the url in a new browser tab (in the main browser). I'd also like new windows spawned by the xul:browser window to open in a tab instead of a new browser window.
I've created an observer which works, but I don't yet know how to apply that observer only to the xul:browser element.
function myFunction(){
var container = jQuery("#container")[0];
var new_browser_element = document.createElement('browser');
container.appendChild(new_browser_element);
var observerService = Components.classes["#mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService);
observerService.addObserver(myObserver, "http-on-modify-request", false);
}
var myObserver = {
observe: function(aSubject, aTopic, aData){
if (aTopic != 'http-on-modify-request'){
aSubject.QueryInterface(Components.interfaces.nsIHttpChannel);
// alert(aSubject.URI.spec);
// Now open url in new tab
}
},
QueryInterface: function(iid){
if (!iid.equals(Components.interfaces.nsISupports) &&
!iid.equals(Components.interfaces.nsIObserver))
throw Components.results.NS_ERROR_NO_INTERFACE;
return this;
}
};
You could try:
var myObserver = {
observe: function(aSubject, aTopic, aData){
if (aTopic == 'http-on-modify-request')
{
aSubject.QueryInterface(Components.interfaces.nsIHttpChannel);
var url = aSubject.URI.spec;
var postData ;
if (aSubject.requestMethod.toLowerCase() == "post")
{
var postText = this.readPostTextFromRequest(request);
if (postText)
{
var dataString = parseQuery(postText);
postData = postDataFromString(dataString);
}
}
var oHttp = aSubject.QueryInterface(Components.interfaces.nsIHttpChannel);
var interfaceRequestor = oHttp.notificationCallbacks.QueryInterface(Components.interfaces.nsIInterfaceRequestor);
var DOMWindow = interfaceRequestor.getInterface(Components.interfaces.nsIDOMWindow);
//check if it is one of your mini browser windows
if (jQuery(DOMWindow).hasClass('mini_browser'))
{
openInTab(url, postData);
var request = aSubject.QueryInterface(Components.interfaces.nsIRequest);
request.cancel(Components.results.NS_BINDING_ABORTED);
}
}
},
QueryInterface: function(iid){
if (!iid.equals(Components.interfaces.nsISupports) &&
!iid.equals(Components.interfaces.nsIObserver))
throw Components.results.NS_ERROR_NO_INTERFACE;
return this;
},
readPostTextFromRequest : function(request) {
var is = request.QueryInterface(Components.interfaces.nsIUploadChannel).uploadStream;
if (is)
{
var ss = is.QueryInterface(Components.interfaces.nsISeekableStream);
var prevOffset;
if (ss)
{
prevOffset = ss.tell();
ss.seek(Components.interfaces.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(Components.interfaces.nsISeekableStream.NS_SEEK_SET, 0);
return text;
}
else {
dump("Failed to Query Interface for upload stream.\n");
}
}
return null;
},
readFromStream : function(stream, charset, noClose)
{
var sis = Components.classes["#mozilla.org/binaryinputstream;1"]
.getService(Components.interfaces.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;
}
};
function openInTab(url, postData)
{
var wm = Components.classes["#mozilla.org/appshell/window-mediator;1"]
.getService(Components.interfaces.nsIWindowMediator);
var recentWindow = wm.getMostRecentWindow("navigator:browser");
if (recentWindow)
{
// Use an existing browser window, open tab and "select" it
recentWindow.gBrowser.selectedTab = recentWindow.gBrowser.addTab(url, null, null, postData);
}
}
function parseQuery() {
var qry = this;
var rex = /[?&]?([^=]+)(?:=([^&#]*))?/g;
var qmatch, key;
var paramValues = {};
// parse querystring storing key/values in the ParamValues associative array
while (qmatch = rex.exec(qry)) {
key = decodeURIComponent(qmatch[1]);// get decoded key
val = decodeURIComponent(qmatch[2]);// get decoded value
paramValues[key] = val;
}
return paramValues;
}
function postDataFromString(dataString)
{
// POST method requests must wrap the encoded text in a MIME
// stream
var stringStream = Components.classes["#mozilla.org/io/string-input-stream;1"]
.createInstance(Components.interfaces.nsIStringInputStream);
if ("data" in stringStream) // Gecko 1.9 or newer
stringStream.data = dataString;
else // 1.8 or older
stringStream.setData(dataString, dataString.length);
var postData = Components.classes["#mozilla.org/network/mime-input-stream;1"].
createInstance(Components.interfaces.nsIMIMEInputStream);
postData.addHeader("Content-Type", "application/x-www-form-urlencoded");
postData.addContentLength = true;
postData.setData(stringStream);
return postData;
}
I'll update this to fill in the blanks in a bit.
edit: see http://forums.mozillazine.org/viewtopic.php?p=2772951#p2772951 for how to get the source window of a request.
Request cancellation code from http://zenit.senecac.on.ca/wiki/index.php/Support_For_OpenID.
see http://mxr.mozilla.org/mozilla-central/source/netwerk/base/public/nsIRequest.idl for details on nsIRequest.
See http://forums.mozillazine.org/viewtopic.php?p=2404533#p2404533 and https://developer.mozilla.org/en/XUL/Method/addTab for the definition of addTab.
parseQuery comes from http://blog.strictly-software.com/2008/10/using-javascript-to-parse-querystring.html.
See https://developer.mozilla.org/en/Code_snippets/Post_data_to_window#Preprocessing_POST_data for how to process post data in a form suitable for addTab.
ReadPostFromText and ReadTextFromStream both come from firebug (though slightly modified)

Resources