blob: b77d5c6a5ee20c2295d954ad79c410f5786e4efc [file] [log] [blame]
Jeff Thompson08ab3cd2012-10-08 02:56:20 -07001/*
2 * @author: ucla-cs
Jeff Thompson745026e2012-10-13 12:49:20 -07003 * See COPYING for copyright and distribution information.
4 * This is the ccnx protocol handler for NDN.
Jeff Thompson08ab3cd2012-10-08 02:56:20 -07005 * Protocol handling code derived from http://mike.kaply.com/2011/01/18/writing-a-firefox-protocol-handler/
6 */
7
8const Cc = Components.classes;
9const Ci = Components.interfaces;
10const Cr = Components.results;
11
12const nsIProtocolHandler = Ci.nsIProtocolHandler;
13
14Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
15Components.utils.import("chrome://modules/content/ndn-js.jsm");
16Components.utils.import("chrome://modules/content/ContentChannel.jsm");
17
18function CcnxProtocol() {
19}
20
21CcnxProtocol.prototype = {
22 scheme: "ccnx",
23 protocolFlags: nsIProtocolHandler.URI_NORELATIVE |
24 nsIProtocolHandler.URI_NOAUTH |
25 nsIProtocolHandler.URI_LOADABLE_BY_ANYONE,
26
27 newURI: function(aSpec, aOriginCharset, aBaseURI)
28 {
29 var uri = Cc["@mozilla.org/network/simple-uri;1"].createInstance(Ci.nsIURI);
30 uri.spec = aSpec;
31 return uri;
32 },
33
34 newChannel: function(aURI)
35 {
36 try {
Jeff Thompsondf0a6f72012-10-21 15:58:58 -070037 // Save the mostRecentWindow from the moment of newChannel.
38 var wm = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);
39 var mostRecentWindow = wm.getMostRecentWindow("navigator:browser");
40
Jeff Thompson08ab3cd2012-10-08 02:56:20 -070041 var requestContent = function(contentListener) {
Jeff Thompson34419762012-10-15 22:24:12 -070042 var name = aURI.spec.split(":")[1];
Jeff Thompsonf0761452012-10-09 23:17:40 -070043 // 131.179.141.18 is lioncub.metwi.ucla.edu .
44 var ndn = new NDN('131.179.141.18');
Jeff Thompson08ab3cd2012-10-08 02:56:20 -070045
Jeff Thompson34419762012-10-15 22:24:12 -070046 var ContentClosure = function ContentClosure() {
47 // Inherit from Closure.
48 Closure.call(this);
49 }
50 ContentClosure.prototype.upcall = function(kind, upcallInfo) {
51 if (!(kind == Closure.UPCALL_CONTENT ||
52 kind == Closure.UPCALL_CONTENT_UNVERIFIED))
53 // The upcall is not for us.
Jeff Thompson741108b2012-10-15 23:07:09 -070054 return Closure.RESULT_ERR;
Jeff Thompson34419762012-10-15 22:24:12 -070055
56 var contentObject = upcallInfo.contentObject;
Jeff Thompsondf0a6f72012-10-21 15:58:58 -070057 if (contentObject.content == null) {
58 dump("CcnxProtocol.newChannel: contentObject.content is null\n");
59 return Closure.RESULT_ERR;
60 }
Jeff Thompson34419762012-10-15 22:24:12 -070061
Jeff Thompsondf0a6f72012-10-21 15:58:58 -070062 var content = DataUtils.toString(contentObject.content);
63 // TODO: Should look at the returned Name to get contentType. For now,
64 // just look at the original name.
65 var contentTypeAndCharset = getContentTypeAndCharset(name);
66 contentListener.onReceivedContent(content,
67 contentTypeAndCharset.contentType, contentTypeAndCharset.contentCharset);
68
69 // Assume that onReceivedContent sends all the content immediately and that
70 // the URLBar is updated if the content is for the main window.
71 var urlBar = mostRecentWindow.gURLBar;
72
Jeff Thompson741108b2012-10-15 23:07:09 -070073 return Closure.RESULT_OK;
Jeff Thompson08ab3cd2012-10-08 02:56:20 -070074 };
75
Jeff Thompson34419762012-10-15 22:24:12 -070076 ndn.expressInterest(new Name(name), new ContentClosure());
Jeff Thompson08ab3cd2012-10-08 02:56:20 -070077 };
78
79 return new ContentChannel(aURI, requestContent);
80 } catch (ex) {
81 dump("CcnxProtocol.newChannel exception: " + ex + "\n");
82 }
83 },
84
85 classDescription: "ccnx Protocol Handler",
86 contractID: "@mozilla.org/network/protocol;1?name=" + "ccnx",
87 classID: Components.ID('{8122e660-1012-11e2-892e-0800200c9a66}'),
88 QueryInterface: XPCOMUtils.generateQI([Ci.nsIProtocolHandler])
89}
90
91if (XPCOMUtils.generateNSGetFactory)
92 var NSGetFactory = XPCOMUtils.generateNSGetFactory([CcnxProtocol]);
93else
94 var NSGetModule = XPCOMUtils.generateNSGetModule([CcnxProtocol]);
95
Jeff Thompsondf0a6f72012-10-21 15:58:58 -070096/*
97 * Based on name, return and object with properties contentType and charset.
98 */
99function getContentTypeAndCharset(name) {
100 // Set up defaults.
101 var contentType = "text/html";
102 var charset = "utf-8";
Jeff Thompson08ab3cd2012-10-08 02:56:20 -0700103
Jeff Thompsondf0a6f72012-10-21 15:58:58 -0700104 var nameLowerCase = name.toLowerCase();
105 if (nameLowerCase.indexOf(".gif") >= 0) {
106 contentType = "image/gif";
107 charset = "ISO-8859-1";
108 }
109 else if (nameLowerCase.indexOf(".jpg") >= 0 ||
110 nameLowerCase.indexOf(".jpeg") >= 0) {
111 contentType = "image/jpeg";
112 charset = "ISO-8859-1";
113 }
114 else if (nameLowerCase.indexOf(".png") >= 0) {
115 contentType = "image/png";
116 charset = "ISO-8859-1";
117 }
118 else if (nameLowerCase.indexOf(".bmp") >= 0) {
119 contentType = "image/bmp";
120 charset = "ISO-8859-1";
121 }
122 else if (nameLowerCase.indexOf(".css") >= 0)
123 contentType = "text/css";
124
125 return {
126 contentType: contentType,
127 charset: charset
128 };
129}