How to discover the proxy used from a Proxy Autoconfiguration file? - firefox

In Firefox internet connection is made through a proxy auto configuration file something.pac.
How do I know for a certain URL which proxy server is being used?

.pac file is just an ECMAscript - aka JavaScript. Check out the wikipedia article on the file format.
If you copy the PAC code you can process it to see what proxy is being used based on the target url. If you are feeling fancy, you can wrap the script into a web page (locally) to create a tool to evaluate locally.
Edit:
As an alternative to the method I started recommending, you might check out PACTester, available on Google Code. This will allow you to quickly test a range of options.
If you have .Net available and are interested in playing with C# then you can check out this article on MSDN which has code you can use in a similar fashion to the above.
To expand on the original method outlined above, there are a number of functions which may (and typically are) provided by the host browser. The basic function which must be implemented in a pac file is FindProxyForUrl(). This accepts two parameters: the url and the host (the host derived from the name of url). The "provided" functions include: isInNet(), localHostOrDomainIs(), isPlainHostName(), isResolvable(), etc.
If you are working in a Microsoft environment then you can check out this page on Technet which describes the .pac format with some useful examples.
Per the Microsoft documentation for isInNet():
The isInNet(host, pattern, mask) function returns TRUE if the host IP address matches the specified pattern. The mask indicates which part of the IP address to match (255=match, 0=ignore).
If you want to get technical, here is the Mozilla source code for the implementation of proxy auto-config related services. It specifies the JS code for isInNet() as:
200 function isInNet(ipaddr, pattern, maskstr) {
201 var test = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/(ipaddr);
202 if (test == null) {
203 ipaddr = dnsResolve(ipaddr);
204 if (ipaddr == null)
205 return false;
206 } else if (test[1] > 255 || test[2] > 255 ||
207 test[3] > 255 || test[4] > 255) {
208 return false; // not an IP address
209 }
210 var host = convert_addr(ipaddr);
211 var pat = convert_addr(pattern);
212 var mask = convert_addr(maskstr);
213 return ((host & mask) == (pat & mask));
214
215 }
Hope that helps!

I've created simple HTML page resolving proxy:
<html>
<head>
<script type="text/javascript">
function myIpAddress() {
return "192.168.1.2"; // Your IP
}
function isInNet(ipaddr, pattern, maskstr) {
var test = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/(ipaddr);
if (test == null) {
ipaddr = dnsResolve(ipaddr);
if (ipaddr == null) return false;
} else if (test[1] > 255 || test[2] > 255 || test[3] > 255 || test[4] > 255) {
return false; // not an IP address
}
var host = convert_addr(ipaddr);
var pat = convert_addr(pattern);
var mask = convert_addr(maskstr);
return ((host & mask) == (pat & mask));
}
function dnsResolve(host) {
try {
return dns.resolve(host, 0).getNextAddrAsString();
} catch (e) {
return null;
}
}
function convert_addr(ipchars) {
var bytes = ipchars.split('.');
var result = ((bytes[0] & 0xff) << 24) |
((bytes[1] & 0xff) << 16) |
((bytes[2] & 0xff) << 8) |
(bytes[3] & 0xff);
return result;
}
function isPlainHostName(host) {
return host.search('\\\\.') == -1;
}
function shExpMatch(url, pattern) {
pattern = pattern.replace(/\\./g, '\\\\.');
pattern = pattern.replace(/\\*/g, '.*');
pattern = pattern.replace(/\\?/g, '.');
var newRe = new RegExp('^' + pattern + '$');
return newRe.test(url);
}
function dnsDomainIs(host, domain) {
return host.length >= domain.length && host.substring(host.length - domain.length) == domain;
}
</script>
<!-- Your proxy script -->
<script type="text/javascript" src="webproxy.js"></script>
</head>
<body>
Host: <input id="host"/><br/>
URL: <input id="url"/><br/>
Proxy: <input id="proxy" disabled="disabled"/><br/>
<input type="button" value="Resolve"
onclick="document.getElementById('proxy').value = FindProxyForURL(document.getElementById('host').value, document.getElementById('url').value)"/><br/>
</body>
</html>
Code for myIpAddress etc I've got from mozilla sources.

Related

How to tell if a cell value has passed validation

I am familiar with the Google Apps script DataValidation object. To get and set validation criteria. But how to tell programatically if a cell value is actually valid. So I can see the little red validation fail message in the spreadsheet but can the fact the cell is currently failing validation be picked up thru code?
I have tried to see if there is a cell property that tells you this but there is not. Also I looked for some sort of DataValidation "validate" method - i.e. test a value against validation rules, but nothing there either
Any ideas? Is this possible??
Specific answer to your question, there is no method within Google Apps Script that will return the validity of a Range such as .isValid(). As you state, you could reverse engineer a programatic one using Range.getDataValidations() and then parsing the results of that in order to validate again the values of a Range.getValues() call.
It's a good suggestion. I've added a feature request to the issue tracker -> Add a Star to vote it up.
I've created a workaround for this issue that works in a very ugly -technically said- and slightly undetermined way.
About the workaround:
It works based on the experience that the web browser implementation of catch() function allows to access thrown errors from the Google's JS code parts.
In case an invalid input into a cell is rejected by a validation rule then the system will display an error message that is catchable by the user written GAS. In order to make it work first the reject value has to be set on the specified cell then its vale has to be re-entered (modified) then -right after this- calling the getDataValidation() built in function allows the user to catch the necessary error.
Only single cells can be tested with this method as setCellValues() ignores any data validation restriction (as of today).
Disadvantages:
The validity won't be necessarily re-checked for this function:
it calls a cell validation function right after the value is inserted into the cell.
Therefore the result of this function might be faulty.
The code messes up the history as cells will be changed - in case they are
valid.
I've tested it successfully on both Firefox and Chromium.
function getCellValidity(cell) {
var origValidRule = cell.getDataValidation();
if (origValidRule == null || ! (cell.getNumRows() == cell.getNumColumns() == 1)) {
return null;
}
var cell_value = cell.getValue();
if (cell_value === '') return true; // empty cell is always valid
var is_valid = true;
var cell_formula = cell.getFormula();
// Storing and checking if cell validation is set to allow invalid input with a warning or reject it
var reject_invalid = ! origValidRule.getAllowInvalid();
// If invalid value is allowed (just warning), then changing validation to reject it
// IMPORTANT: this will not throw an error!
if (! reject_invalid) {
var rejectValidRule = origValidRule.copy().setAllowInvalid(false).build();
cell.setDataValidation(rejectValidRule);
}
// Re-entering value or formula into the cell itself
var cell_formula = cell.getFormula();
if (cell_formula !== '') {
cell.setFormula(cell_formula);
} else {
cell.setValue(cell_value);
}
try {
var tempValidRule = cell.getDataValidation();
} catch(e) {
// Exception: The data that you entered in cell XY violates the data validation rules set on this cell.
// where XY is the A1 style address of the cell
is_valid = false;
}
// Restoring original rule
if (rejectValidRule != null) {
cell.setDataValidation(origValidRule.copy().setAllowInvalid(true).build());
}
return is_valid;
}
I still recommend starring the above Google bug report opened by Jonathon.
I'm using this solution. Simple to learn and fast to use! You may need to adapt this code for your needs. Hope you enjoy
function test_corr(link,name) {
var ss = SpreadsheetApp.openByUrl(link).getSheetByName(name);
var values = ss.getRange(2,3,200,1).getValues();
var types = ss.getRange(2,3,200,1).getDataValidations()
var ans
for (var i = 0; i < types.length; i++) {
if (types[i][0] != null){
var type = types[i][0].getCriteriaType()
var dval_values = types[i][0].getCriteriaValues()
ans = false
if (type == "VALUE_IN_LIST") {
for (var j = 0; j < dval_values[0].length; j++) {
if (dval_values[0][j] == values[i][0]) { ans = true }
}
} else if (type == "NUMBER_BETWEEN") {
if (values[i][0] >= dval_values[0] && values[i][0] <= dval_values[1]) { ans = true }
} else if (type == "CHECKBOX") {
if (values[i][0] == "Да" || values[i][0] == "Нет") { ans = true }
}
if (!ans) { return false }
}
}
return true;
}

Interpreting Typekit Network Requests

Can someone explain the bottom four network requests shown below for Typekit?
What I don't understand is:
Why do they show 0 B for size but 17.2 KB (et al) for content?
Are there really four HTTP requests occurring for these font files?
The same data is reported regardless of whether compression is enabled.
Dev Tools says the calls are being initiated by Modernizr in the line below that reads bool = node.offsetTop === 9;
tests['touch'] = function() {
var bool;
if (('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch) {
bool = true;
} else {
injectElementWithStyles(['#media (', prefixes.join('touch-enabled),('), mod, ')', '{#modernizr{top:9px;position:absolute}}'].join(''), function(node) {
bool = node.offsetTop === 9;
});
}
return bool;
};
They are base64ed - that means that the files were converted to a text embeddable data format, and then inlined in the file. 0Bs were used for downloading the request, since it was embedded in another file, but the content of that data URI was 17.2KB

Are application-level proxies possible in Windows?

I'd rather not change the global proxy settings as not just my app but a pile of others are running on the Windows Server (2K8 R2) and these others would be adversely affected by a global change.
Is it possible to set an application-level proxy in a Windows environment? I understand such things are possible in Linux and Mac.
ALSO
What is actually happening when one uses a free proxy server? How is the traffic managed and could I set up a app-level proxy myself?
// HttpRequest SetCredentials flags.
HTTPREQUEST_PROXYSETTING_DEFAULT = 0;
HTTPREQUEST_PROXYSETTING_PRECONFIG = 0;
HTTPREQUEST_PROXYSETTING_DIRECT = 1;
HTTPREQUEST_PROXYSETTING_PROXY = 2;
function HTTPGETPROXIED(oHTTP, url, proxyurl) {
var status, respsonse;
try {
var o = oHTTP.open("GET", url, false);
oHTTP.SetTimeouts( 0, 12000, 6000, 6000 ); // 2/10 the usual
if (proxyurl) {
oHTTP.SetProxy( HTTPREQUEST_PROXYSETTING_PROXY, proxyurl);
} else {
oHTTP.SetProxy( HTTPREQUEST_PROXYSETTING_DIRECT, "" );
}
var s = oHTTP.send();
status = oHTTP.Status;
response = oHTTP.ResponseText;
}
catch (err) {
status = -1;
response = err.message.replace(/\r\n|\n/g,"") + ": " + proxyurl;
}
return [status, response];
}
Based on code on MSDN

Less CSS and local storage issue

I'm using LESS CSS (more exactly less.js) which seems to exploit LocalStorage under the hood. I had never seen such an error like this before while running my app locally, but now I get "Persistent storage maximum size reached" at every page display, just above the link the unique .less file of my app.
This only happens with Firefox 12.0 so far.
Is there any way to solve this?
P.S.: mainly inspired by Calculating usage of localStorage space, this is what I ended up doing (this is based on Prototype and depends on a custom trivial Logger class, but this should be easily adapted in your context):
"use strict";
var LocalStorageChecker = Class.create({
testDummyKey: "__DUMMY_DATA_KEY__",
maxIterations: 100,
logger: new Logger("LocalStorageChecker"),
analyzeStorage: function() {
var result = false;
if (Modernizr.localstorage && this._isLimitReached()) {
this._clear();
}
return result;
},
_isLimitReached: function() {
var localStorage = window.localStorage;
var count = 0;
var limitIsReached = false;
do {
try {
var previousEntry = localStorage.getItem(this.testDummyKey);
var entry = (previousEntry == null ? "" : previousEntry) + "m";
localStorage.setItem(this.testDummyKey, entry);
}
catch(e) {
this.logger.debug("Limit exceeded after " + count + " iteration(s)");
limitIsReached = true;
}
}
while(!limitIsReached && count++ < this.maxIterations);
localStorage.removeItem(this.testDummyKey);
return limitIsReached;
},
_clear: function() {
try {
var localStorage = window.localStorage;
localStorage.clear();
this.logger.debug("Storage clear successfully performed");
}
catch(e) {
this.logger.error("An error occurred during storage clear: ");
this.logger.error(e);
}
}
});
document.observe("dom:loaded",function() {
var checker = new LocalStorageChecker();
checker.analyzeStorage();
});
P.P.S.: I didn't measure the performance impact on the UI yet, but a decorator could be created and perform the storage test only every X minutes (with the last timestamp of execution in the local storage for instance).
Here is a good resource for the error you are running into.
http://www.sitepoint.com/building-web-pages-with-local-storage/#fbid=5fFWRXrnKjZ
Gives some insight that localstorage only has so much room and you can max it out in each browser. Look into removing some data from localstorage to resolve your problem.
Less.js persistently caches content that is #imported. You can use this script to clear content that is cached. Using the script below you can call the function destroyLessCache('/path/to/css/') and it will clear your localStorage of css files that have been cached.
function destroyLessCache(pathToCss) { // e.g. '/css/' or '/stylesheets/'
if (!window.localStorage || !less || less.env !== 'development') {
return;
}
var host = window.location.host;
var protocol = window.location.protocol;
var keyPrefix = protocol + '//' + host + pathToCss;
for (var key in window.localStorage) {
if (key.indexOf(keyPrefix) === 0) {
delete window.localStorage[key];
}
}
}

Why don't InfoCards work in IE8?

What changed in IE8 that makes detecting InfoCard Selector support in javascript stop working unless IE8 is put in Compatibility Mode?
And more to the point, what is the new JavaScript code to detect the presence of InfoCard support?
Here is the script that worked up through IE7, including FireFox with a plug-in in some cases:
function AreCardsSupported() {
var IEVer = -1;
if (navigator.appName == 'Microsoft Internet Explorer') {
if (new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})").exec(navigator.userAgent) != null) {
IEVer = parseFloat(RegExp.$1);
}
}
// Look for IE 7+.
if (IEVer >= 7) {
var embed = document.createElement("object");
embed.setAttribute("type", "application/x-informationcard");
return "" + embed.issuerPolicy != "undefined" && embed.isInstalled;
}
// not IE (any version)
if (IEVer < 0 && navigator.mimeTypes && navigator.mimeTypes.length) {
// check to see if there is a mimeType handler.
x = navigator.mimeTypes['application/x-informationcard'];
if (x && x.enabledPlugin) {
return true;
}
// check for the IdentitySelector event handler is there.
if (document.addEventListener) {
var event = document.createEvent("Events");
event.initEvent("IdentitySelectorAvailable", true, true);
top.dispatchEvent(event);
if (top.IdentitySelectorAvailable == true) {
return true;
}
}
}
return false;
}
I got an answer out of band from the IE8 team:
Change
embed.setAttribute("type", "application/x-informationcard");
to
embed.type = "application/x-informationcard";

Resources