{"id":1106,"date":"2013-04-27T11:55:02","date_gmt":"2013-04-27T11:55:02","guid":{"rendered":"http:\/\/www.nargalzius.com\/blog\/?p=1106"},"modified":"2017-02-10T01:51:31","modified_gmt":"2017-02-10T01:51:31","slug":"universal-proxy","status":"publish","type":"post","link":"http:\/\/nargalzius.com\/blog\/archives\/2013\/04\/27\/universal-proxy","title":{"rendered":"Universal Proxy"},"content":{"rendered":"<p>If you would notice this site&#8217;s <a href=\"http:\/\/www.nargalzius.com\">front page<\/a>, I&#8217;ve now replaced a bunch of parts of the side-bar (right side of the homepage) with some social feeds of networks I&#8217;m active on. This was an unintended effect of creating a <em>caching proxy<\/em> for work.<\/p>\n<p>A proxy is a script that pulls data from another domain and outputs the data as is. It may seem silly; to require something to simply mirror the data of another site, when you can simply pull the data from the source itself. Logically, this is true, but in the <em>intertubes,<\/em> nothing is really simple. <\/p>\n<p>You have to wrestle with domain implementation policies, wherein certain stuff simply doesn&#8217;t work because the application, browser, server won&#8217;t allow it as a matter of security.<\/p>\n<p>Flash as an example, can be annoyingly strict about pulling data from a different domain. If you build and test your app locally there&#8217;s no problem, but once you upload that and run it, the same exact algorithm may or may not work depending on the policies of both the plugin and sometimes even the server itself.<\/p>\n<p>A proxy placed in your localhost solves this by ensuring that the data your &#8220;application&#8221; is accessing comes from the same domain.<\/p>\n<p>Now a <em>caching<\/em> proxy is something more; just like with the <a href=\"http:\/\/en.wikipedia.org\/wiki\/Web_cache\">concept of caching in general<\/a> it allows a feed to be pulled from the source via the proxy, but then it&#8217;s written to a file locally, and have an expiration on it. As long as it&#8217;s not &#8220;expired&#8221;, then the proxy will simply re-use the file it had generated instead of pulling the feed from the source for a set period of time.<\/p>\n<p>This is extremely useful (and in my case, the reason why I made it) when dealing with rate-limited stuff. All social networks have their own rate limitations; if a user\/application is polling their APIs too often, they will block access temporarily to prevent their servers from being overloaded with requests (similar to, if not tantamount to a <a href=\"https:\/\/en.wikipedia.org\/wiki\/Denial-of-service_attack\">DoS attack<\/a>)<!--more--><!-- \/\/ --><\/p>\n<h1>Practical Example<\/h1>\n<p>So as an example, let&#8217;s say this site is a high traffic site, where hundreds of visitors visit it <strong>per minute.<\/strong> Let&#8217;s also assume I have the proper infrastructure to handle the traffic.<\/p>\n<p>Now my social feed on the side polls the various social networks, and I&#8217;ve implemented it via JQuery &#8211; so it&#8217;s kinda realtime when you load it. Meaning whenever a person visits the site, it will load the page, then run the JQuery script that then pulls the required feeds from the different social networks. As soon as that&#8217;s complete, it then loads them into their respective slots.<\/p>\n<p>Now imagine that happening hundreds of times <strong>per minute.<\/strong> Twitter as an example is one of the stricter services to work with; and has a <a href=\"https:\/\/dev.twitter.com\/docs\/rate-limiting\/1.1\/limits\">rate limit<\/a> of about 15 API calls every 15 mintues <span class=\"footnote_referrer\"><a role=\"button\" tabindex=\"0\" onclick=\"footnote_moveToReference_1106_1('footnote_plugin_reference_1106_1_1');\" onkeypress=\"footnote_moveToReference_1106_1('footnote_plugin_reference_1106_1_1');\" ><sup id=\"footnote_plugin_tooltip_1106_1_1\" class=\"footnote_plugin_tooltip_text\">1 <\/sup><\/a><span id=\"footnote_plugin_tooltip_text_1106_1_1\" class=\"footnote_tooltip\">Or roughly one call per minute. Call more often than that, it <em>will<\/em> <strong>block you<\/strong> [temporarily].<\/span><\/span><script type=\"text\/javascript\"> jQuery('#footnote_plugin_tooltip_1106_1_1').tooltip({ tip: '#footnote_plugin_tooltip_text_1106_1_1', tipClass: 'footnote_tooltip', effect: 'fade', predelay: 0, fadeInSpeed: 200, delay: 400, fadeOutSpeed: 200, position: 'top right', relative: true, offset: [10, 10], });<\/script> No need for advanced math to know your site will be polling Twitter&#8217;s servers more than once per minute. Probably within the first few <em>seconds,<\/em> you&#8217;ve already went overboard.<\/p>\n<p>With a cached proxy, you can easily solve that conundrum. You can set it to expire every minute &#8211; the first user to &#8220;trigger&#8221; the proxy will essentially be the first call to Twitter&#8217;s server, it will then store a cached version of that feed locally in your server. All requests henceforth will then be pulling from that cached file instead of Twitter&#8217;s servers. Until one minute&#8217;s up, then another user will eventually trigger the proxy when the cache has expired &#8211; only then will it pull the feed from Twitter&#8217;s server and &#8220;update&#8221; your local copy&#8230; and so on and so forth.<\/p>\n<p>If you do the math, regardless of how many visitors your site has, you&#8217;re just polling Twitter&#8217;s server once every minute. To be on the safe side, you could extend the expiration far longer say every 5 to 10 mintues. That way you&#8217;d be <strong>sure<\/strong> you&#8217;ll be in the clear \ud83d\ude42<\/p>\n<h1>The Proxy Script<\/h1>\n<pre><code>http:\/\/www.nargalzius.com\/downloads\/proxy\/proxy.php<\/code><\/pre>\n<p>So first, may I invite you to <a href=\"http:\/\/www.nargalzius.com\/downloads\/proxy\/proxy.php\">visit that link<\/a> to see what it does. You should see this:<\/p>\n<div align=\"center\"><a href=\"http:\/\/farm9.static.flickr.com\/8126\/8684692859_2784ffa842_o.png\" target=\"_blank\" title=\"You may click on the image for more details\"><img decoding=\"async\" src=\"http:\/\/farm9.static.flickr.com\/8126\/8684692859_8bce59a743_n.jpg\" class=\"wb\"><\/a><\/div>\n<p>As you have observed, when you load up the proxy page without any arguments, it will just show you a quick guide on how to use it. The url listed at the bottom is a sample of a string using all optional arguments. But to get things going we only need a value for the <code>url<\/code> attribute. So essentially what we need would be this:<\/p>\n<pre>http:\/\/www.nargalzius.com\/downloads\/proxy\/proxy.php?url=<strong>URLENCODED_STRING<\/strong><\/pre>\n<h1>The Feed We Want to Pull<\/h1>\n<p>So I searched some tutorials to find some random feed that works (I wouldn&#8217;t want to be giving off <strong>my own<\/strong> feeds, now wouldn&#8217;t I?) and here&#8217;s what I found: A Flickr feed of some group called <a href=\"http:\/\/www.flickr.com\/groups\/talkontravel\/pool\"><em>&#8220;Talk on Travel&#8221;<\/em><\/a><\/p>\n<p><a href=\"http:\/\/api.flickr.com\/services\/feeds\/groups_pool.gne?id=998875@N22&amp;#38;lang=en-us&amp;#38;format=json\"><code>http:\/\/api.flickr.com\/services\/feeds\/groups_pool.gne?id=998875@N22&amp;#38;lang=en-us&amp;#38;format=json<\/code><\/a><\/p>\n<p>The feed url above basically pulls off a JSON feed for that group. Your mileage may vary (YMMV) depending on your browser, but when you click on the link you should see something similar to this:<\/p>\n<div align=\"center\"><a href=\"http:\/\/farm9.static.flickr.com\/8403\/8684692719_23ce5287c8_o.png\" target=\"_blank\" title=\"You may click on the image for more details\"><img decoding=\"async\" src=\"http:\/\/farm9.static.flickr.com\/8403\/8684692719_de9640aee2_n.jpg\" class=\"wb\"><\/a><\/div>\n<p>Luckily, Flickr has a very robust system of feed generation, so we can also pull the same feed in <code>XML<\/code> format, the url is as follows:<\/p>\n<p><a href=\"http:\/\/api.flickr.com\/services\/feeds\/groups_pool.gne?id=998875@N22&amp;#38;lang=en-us&amp;#38;format=xml\"><code>http:\/\/api.flickr.com\/services\/feeds\/groups_pool.gne?id=998875@N22&amp;#38;lang=en-us&amp;#38;format=xml<\/code><\/a><\/p>\n<p>Again YMMV &#8211; but you should see something like this.<\/p>\n<div align=\"center\"><a href=\"http:\/\/farm9.static.flickr.com\/8542\/8684692243_5c052c9c99_o.png\" target=\"_blank\" title=\"You may click on the image for more details\"><img decoding=\"async\" src=\"http:\/\/farm9.static.flickr.com\/8542\/8684692243_77375be79e_n.jpg\" class=\"wb\"><\/a><\/div>\n<p>Now those are examples of the raw feeds. Since we&#8217;ve already covered earlier <em>why<\/em> we would ideally use proxies, lets just go on ahead and take one of the example feeds and use it with my proxy. Let&#8217;s take the <strong>XML<\/strong> one.<\/p>\n<p>Now we <strong>CANNOT<\/strong> just plug it into the proxy <em>as is<\/em> like so:<\/p>\n<pre>http:\/\/www.nargalzius.com\/downloads\/proxy\/proxy.php?url=<strong>http:\/\/api.flickr.com\/services\/feeds\/groups_pool.gne?id=998875@N22&amp;lang=en-us&amp;format=xml<\/strong><\/pre>\n<p>That&#8217;s just <strong>might<\/strong> give us all sorts of browser\/server parsing problems. The responsible thing to do is to &#8220;sanitize&#8221; to a safe format that&#8217;s friendly to any browser&#8217;s addressbar.<\/p>\n<p>Multiple languages have functions that do this, but for the purposes of this &#8220;tutorial&#8221; let&#8217;s just use some <a href=\"http:\/\/meyerweb.com\/eric\/tools\/dencoder\">url-encoding web service<\/a><\/p>\n<p>So we take that url, put it into the url-encoder, encode it, and you get this:<\/p>\n<p><code>http%3A%2F%2Fapi.flickr.com%2Fservices%2Ffeeds%2Fgroups_pool.gne%3Fid%3D998875%40N22%26lang%3Den-us%26format%3Dxml<\/code><\/p>\n<p><strong>Now<\/strong> we can use it with the proxy:<\/p>\n<pre>http:\/\/www.nargalzius.com\/downloads\/proxy\/proxy.php?url=<strong>http%3A%2F%2Fapi.flickr.com%2Fservices%2Ffeeds%2Fgroups_pool.gne%3Fid%3D998875%40N22%26lang%3Den-us%26format%3Dxml<\/strong><\/pre>\n<p>Now, if you <a href=\"http:\/\/www.nargalzius.com\/downloads\/proxy\/proxy.php?url=http%3A%2F%2Fapi.flickr.com%2Fservices%2Ffeeds%2Fgroups_pool.gne%3Fid%3D998875%40N22%26lang%3Den-us%26format%3Dxml\">visit that url<\/a>, you should see something like this:<\/p>\n<div align=\"center\"><a href=\"http:\/\/farm9.static.flickr.com\/8534\/8685810570_8a2a416a7c_o.png\" target=\"_blank\" title=\"You may click on the image for more details\"><img decoding=\"async\" src=\"http:\/\/farm9.static.flickr.com\/8534\/8685810570_71a7128442_n.jpg\" class=\"wb\"><\/a><\/div>\n<p>Success! You have loaded the feed <strong>and<\/strong> cached it locally on your server through the proxy \ud83d\ude42<\/p>\n<h1>Optional Parameters<\/h1>\n<h2>MIME Type<\/h2>\n<p>Now if you compare the <a href=\"http:\/\/api.flickr.com\/services\/feeds\/groups_pool.gne?id=998875@N22&amp;#38;lang=en-us&amp;#38;format=xml\">original feed<\/a> to the <a href=\"http:\/\/www.nargalzius.com\/downloads\/proxy\/proxy.php?url=http%3A%2F%2Fapi.flickr.com%2Fservices%2Ffeeds%2Fgroups_pool.gne%3Fid%3D998875%40N22%26lang%3Den-us%26format%3Dxml\">proxied feed<\/a>, you&#8217;ll notice it&#8217;s exactly the same data, but for some reason it&#8217;s not displaying the same way. Something was lost in translation. Data-wise, this is no issue, you can use the data as you normally would without incident.<\/p>\n<p>However when debugging or trying to craft your parsing algorithm, it does help to retain the legibility. That&#8217;s what the <code>type<\/code> attribute is for. Simply append the argument like so to force the MIME type into the :<\/p>\n<pre>http:\/\/www.nargalzius.com\/downloads\/proxy\/proxy.php?url=http%3A%2F%2Fapi.flickr.com%2Fservices%2Ffeeds%2Fgroups_pool.gne%3Fid%3D998875%40N22%26lang%3Den-us%26format%3Dxml<strong>&amp;type=xml<\/strong><\/pre>\n<p><a href=\"http:\/\/www.nargalzius.com\/downloads\/proxy\/proxy.php?url=http%3A%2F%2Fapi.flickr.com%2Fservices%2Ffeeds%2Fgroups_pool.gne%3Fid%3D998875%40N22%26lang%3Den-us%26format%3Dxml&amp;#38;type=xml\">Load it up<\/a> and viola!<\/p>\n<p>I think the reason for the loss of header information is because the proxy <strong>always<\/strong> reads from a written generic <code>.cache<\/code> file. Meaning even when you first run the proxy, it will first take the feed data, then write it to the <code>\/cache<\/code> directory, then loads it and displays it &#8211; so technically you&#8217;re never really loading the original feed directly in a sense. I guess when it does that, it basically just reads the local file (headers and all) as a plain generic file with no specific MIME type. Honestly it&#8217;s not that big of an issue for me to care about so it is what it is \ud83d\ude42<\/p>\n<h2>Expire<\/h2>\n<p>Again we&#8217;re talking about <strong>cached<\/strong> proxies. The <code>expire<\/code> attribute allows a person to set how long before it decides to &#8220;re-write&#8221; the cached file with the most recent version of the file it&#8217;s caching.<\/p>\n<p>When the attribute isn&#8217;t present, it defaults to 10 minutes I think. Which means whenever you load\/reload the proxy, it will be faster since you&#8217;re pulling a static [cached] file. It wouldn&#8217;t matter if you refresh 30 or 30,000 times under 10 minutes, it wouldn&#8217;t matter &#8211; the source will only be pulled once, until it detects that it&#8217;s time for a refresh\/re-write, then it will re-pull the data from the source.<\/p>\n<p>If you set the <code>expire<\/code> value to <code>-1<\/code> it will set the proxy to constantly refresh &#8211; so whenever you load it, it will always pull from the source and re-write the local cache file. <\/p>\n<p>Sufficed to say if you forget to set this to a decent interval and pull a feed from a rate-limited site too often&#8230; you&#8217;re gonna have a bad time \ud83d\ude09<\/p>\n<p>I also put in a failsafe wherein if the cache file exists, and the feed tries to refresh, but ends up with an error, it will just use the existing &#8220;working state&#8221; and double the expiration time &#8211; so it prevents from overwriting your cache with a malformed feed (in the event of an error)<\/p>\n<h2>Debug<\/h2>\n<p>Pretty self-explanatory. This is meant to check on various stuff. Just add the <code>debug<\/code> attribute and set it to <code>true<\/code> like so:<\/p>\n<div align=\"center\"><a href=\"http:\/\/farm9.static.flickr.com\/8536\/8684693095_b25bf97040_o.png\" target=\"_blank\" title=\"You may click on the image for more details\"><img decoding=\"async\" src=\"http:\/\/farm9.static.flickr.com\/8536\/8684693095_d5724a0189_n.jpg\" class=\"wb\"><\/a><\/div>\n<p>In the picture above you can immediately see useful information like:<\/p>\n<ul>\n<li>The url encoded <code>url<\/code> value being passed to the proxy.<\/li>\n<li>The same url string decoded back to a proper url &#8211; so you can practically visit the site and check if it&#8217;s actually pointing to the right feed.<\/li>\n<li>The filename of the cached file it&#8217;s writing to \/ pulling from.<\/li>\n<li>The expiration time set<\/li>\n<li>If it&#8217;s using a cached file or if it&#8217;s generating a new one. <a href=\"http:\/\/farm9.static.flickr.com\/8265\/8684693319_a04f223c54_o.png\">Here&#8217;s what it looks like<\/a> when you force it to expire<\/li>\n<li>A dump of the actual data below.<\/li>\n<\/ul>\n<p>This obviously bypasses the all the MIME shit, since it&#8217;s purpose is to just see what the hell the proxy is doing. This is a perfect way to test other optional arguments to just see if the proxy is recognizing the flags correctly.<\/p>\n<h1>Bugs<\/h1>\n<p>There are two bugs that I&#8217;m aware of:<\/p>\n<p>First is that it <strong>may<\/strong> <a href=\"http:\/\/farm9.static.flickr.com\/8539\/8684691777_ce60978db8_o.png\">throw an error whenever it generates a cached feed for the first time.<\/a> This seems to depend on the server environment. When I try it locally via MAMP, it just does it&#8217;s thing with no issues, but when I do it in nargalzius.com, it does make that error. Again, YMMV.<\/p>\n<p>It&#8217;s worth re-stating that this only happens (if ever it happens, that is) the very first time you generate a feed, <span class=\"footnote_referrer\"><a role=\"button\" tabindex=\"0\" onclick=\"footnote_moveToReference_1106_1('footnote_plugin_reference_1106_1_2');\" onkeypress=\"footnote_moveToReference_1106_1('footnote_plugin_reference_1106_1_2');\" ><sup id=\"footnote_plugin_tooltip_1106_1_2\" class=\"footnote_plugin_tooltip_text\">2 <\/sup><\/a><span id=\"footnote_plugin_tooltip_text_1106_1_2\" class=\"footnote_tooltip\"> The reason why the sample feeds weren&#8217;t throwing errors was because the files already exist. If you want to try it, try adding some variables in the SOURCE url (source, meaning the one you plan to urlencode) <\/span><\/span><script type=\"text\/javascript\"> jQuery('#footnote_plugin_tooltip_1106_1_2').tooltip({ tip: '#footnote_plugin_tooltip_text_1106_1_2', tipClass: 'footnote_tooltip', effect: 'fade', predelay: 0, fadeInSpeed: 200, delay: 400, fadeOutSpeed: 200, position: 'top right', relative: true, offset: [10, 10], });<\/script> and despite the error, it does successfully write the file. You can actually just press refresh and it will work henceforth. It doesn&#8217;t affect the over-writing procedure. Meaning once it has a file on there, you don&#8217;t have to worry about it throwing another error when it tries to re-write it.<\/p>\n<p><span style=\"color:maroon\">UPDATE 2013.04.27: I&#8217;ve suppressed the warning\/errors so I think i&#8217;ve just solved this issue &#8211; but I&#8217;m leaving the disclaimer\/bug above in case it still persists.<\/span><\/p>\n<p>Second bug is in the debug mode, sometimes when you set it in debug and have it expire immediately, even if you set it back to a timed interval it would continue to expire immediately. This is usually solved when you just disable debug load it, then enable it again.<\/p>\n<p>It also may help when you make sure that the expire attribute is <strong>not<\/strong> set to auto-expire (<code>-1<\/code>) when you first get into debug mode. Once you&#8217;re in, and you change it to auto-expire and back, it seems to work.<\/p>\n<h1>Download &#38; Instructions<\/h1>\n<p>This comes with no warranty, and you can modify it to suit your own needs.<\/p>\n<p>Download it <a href=\"http:\/\/www.nargalzius.com\/f\/p\/download.php?url=http:\/\/www.nargalzius.com\/downloads\/proxy\/proxy.zip\">here<\/a><\/p>\n<p>The only thing you have to do is make sure you have folder named &#8216;cache&#8217; (with proper write permissions) wherever you put the proxy.php file on. Dead simple.<\/p>\n<h3 style=\"color:maroon\">UPDATE 2013.04.30<\/h3>\n<p>This proxy is best used for its flexibility of making url-based <em>unauthenticated<\/em> <span class=\"footnote_referrer\"><a role=\"button\" tabindex=\"0\" onclick=\"footnote_moveToReference_1106_1('footnote_plugin_reference_1106_1_3');\" onkeypress=\"footnote_moveToReference_1106_1('footnote_plugin_reference_1106_1_3');\" ><sup id=\"footnote_plugin_tooltip_1106_1_3\" class=\"footnote_plugin_tooltip_text\">3 <\/sup><\/a><span id=\"footnote_plugin_tooltip_text_1106_1_3\" class=\"footnote_tooltip\">You can obviously also use rudimentary authenticated calls provided the access tokens can be put inline with the URL<\/span><\/span><script type=\"text\/javascript\"> jQuery('#footnote_plugin_tooltip_1106_1_3').tooltip({ tip: '#footnote_plugin_tooltip_text_1106_1_3', tipClass: 'footnote_tooltip', effect: 'fade', predelay: 0, fadeInSpeed: 200, delay: 400, fadeOutSpeed: 200, position: 'top right', relative: true, offset: [10, 10], });<\/script> calls &#8211; since you just have to set the the <code>url<\/code> value appropriately and see the changes right away. <\/p>\n<p>However, if you intend to use authenticated calls &#8211; and want to protect your codes\/tokens <span class=\"footnote_referrer\"><a role=\"button\" tabindex=\"0\" onclick=\"footnote_moveToReference_1106_1('footnote_plugin_reference_1106_1_4');\" onkeypress=\"footnote_moveToReference_1106_1('footnote_plugin_reference_1106_1_4');\" ><sup id=\"footnote_plugin_tooltip_1106_1_4\" class=\"footnote_plugin_tooltip_text\">4 <\/sup><\/a><span id=\"footnote_plugin_tooltip_text_1106_1_4\" class=\"footnote_tooltip\">Especially_ using JavaScript where the calls are essentially in plaintext<\/span><\/span><script type=\"text\/javascript\"> jQuery('#footnote_plugin_tooltip_1106_1_4').tooltip({ tip: '#footnote_plugin_tooltip_text_1106_1_4', tipClass: 'footnote_tooltip', effect: 'fade', predelay: 0, fadeInSpeed: 200, delay: 400, fadeOutSpeed: 200, position: 'top right', relative: true, offset: [10, 10], });<\/script> &#8211; it would be advisable to create a <strong>separate<\/strong> server-side file (e.g. <code>PHP<\/code>) file containing the authentication token\/codes and the final url to be called. You can simply point the proxy to that file instead. <\/p>\n<p>That way, the &#8220;call&#8221; will go through two steps; the <em>new file<\/em> will be the actual [authenticated] &#8220;proxy,&#8221; and our [original] proxy will be relegated to a mere caching service.<\/p><div class=\"speaker-mute footnotes_reference_container\"> <div class=\"footnote_container_prepare\"><p><span role=\"button\" tabindex=\"0\" class=\"footnote_reference_container_label pointer\" onclick=\"footnote_expand_collapse_reference_container_1106_1();\">Notes<\/span><span role=\"button\" tabindex=\"0\" class=\"footnote_reference_container_collapse_button\" style=\"display: none;\" onclick=\"footnote_expand_collapse_reference_container_1106_1();\">[<a id=\"footnote_reference_container_collapse_button_1106_1\">+<\/a>]<\/span><\/p><\/div> <div id=\"footnote_references_container_1106_1\" style=\"\"><table class=\"footnotes_table footnote-reference-container\"><caption class=\"accessibility\">Notes<\/caption> <tbody> \r\n\r\n<tr class=\"footnotes_plugin_reference_row\"> <th scope=\"row\" class=\"footnote_plugin_index_combi pointer\"  onclick=\"footnote_moveToAnchor_1106_1('footnote_plugin_tooltip_1106_1_1');\"><a id=\"footnote_plugin_reference_1106_1_1\" class=\"footnote_backlink\"><span class=\"footnote_index_arrow\">&#8673;<\/span>1<\/a><\/th> <td class=\"footnote_plugin_text\">Or roughly one call per minute. Call more often than that, it <em>will<\/em> <strong>block you<\/strong> [temporarily].<\/td><\/tr>\r\n\r\n<tr class=\"footnotes_plugin_reference_row\"> <th scope=\"row\" class=\"footnote_plugin_index_combi pointer\"  onclick=\"footnote_moveToAnchor_1106_1('footnote_plugin_tooltip_1106_1_2');\"><a id=\"footnote_plugin_reference_1106_1_2\" class=\"footnote_backlink\"><span class=\"footnote_index_arrow\">&#8673;<\/span>2<\/a><\/th> <td class=\"footnote_plugin_text\"> The reason why the sample feeds weren&#8217;t throwing errors was because the files already exist. If you want to try it, try adding some variables in the SOURCE url (source, meaning the one you plan to urlencode) <\/td><\/tr>\r\n\r\n<tr class=\"footnotes_plugin_reference_row\"> <th scope=\"row\" class=\"footnote_plugin_index_combi pointer\"  onclick=\"footnote_moveToAnchor_1106_1('footnote_plugin_tooltip_1106_1_3');\"><a id=\"footnote_plugin_reference_1106_1_3\" class=\"footnote_backlink\"><span class=\"footnote_index_arrow\">&#8673;<\/span>3<\/a><\/th> <td class=\"footnote_plugin_text\">You can obviously also use rudimentary authenticated calls provided the access tokens can be put inline with the URL<\/td><\/tr>\r\n\r\n<tr class=\"footnotes_plugin_reference_row\"> <th scope=\"row\" class=\"footnote_plugin_index_combi pointer\"  onclick=\"footnote_moveToAnchor_1106_1('footnote_plugin_tooltip_1106_1_4');\"><a id=\"footnote_plugin_reference_1106_1_4\" class=\"footnote_backlink\"><span class=\"footnote_index_arrow\">&#8673;<\/span>4<\/a><\/th> <td class=\"footnote_plugin_text\">Especially_ using JavaScript where the calls are essentially in plaintext<\/td><\/tr>\r\n\r\n <\/tbody> <\/table> <\/div><\/div><script type=\"text\/javascript\"> function footnote_expand_reference_container_1106_1() { jQuery('#footnote_references_container_1106_1').show(); jQuery('#footnote_reference_container_collapse_button_1106_1').text('\u2212'); } function footnote_collapse_reference_container_1106_1() { jQuery('#footnote_references_container_1106_1').hide(); jQuery('#footnote_reference_container_collapse_button_1106_1').text('+'); } function footnote_expand_collapse_reference_container_1106_1() { if (jQuery('#footnote_references_container_1106_1').is(':hidden')) { footnote_expand_reference_container_1106_1(); } else { footnote_collapse_reference_container_1106_1(); } } function footnote_moveToReference_1106_1(p_str_TargetID) { footnote_expand_reference_container_1106_1(); var l_obj_Target = jQuery('#' + p_str_TargetID); if (l_obj_Target.length) { jQuery( 'html, body' ).delay( 0 ); jQuery('html, body').animate({ scrollTop: l_obj_Target.offset().top - window.innerHeight * 0.2 }, 380); } } function footnote_moveToAnchor_1106_1(p_str_TargetID) { footnote_expand_reference_container_1106_1(); var l_obj_Target = jQuery('#' + p_str_TargetID); if (l_obj_Target.length) { jQuery( 'html, body' ).delay( 0 ); jQuery('html, body').animate({ scrollTop: l_obj_Target.offset().top - window.innerHeight * 0.2 }, 380); } }<\/script>","protected":false},"excerpt":{"rendered":"<p>If you would notice this site&#8217;s front page, I&#8217;ve now replaced a bunch of parts of the side-bar (right side of the homepage) with some social feeds of networks I&#8217;m active on. This was an unintended effect of creating a caching proxy for work. A proxy is a script that pulls data from another domain &hellip; <p class=\"link-more\"><a href=\"http:\/\/nargalzius.com\/blog\/archives\/2013\/04\/27\/universal-proxy\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Universal Proxy&#8221;<\/span><\/a><\/p><\/p>","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false},"version":2}},"categories":[9],"tags":[810],"class_list":["post-1106","post","type-post","status-publish","format-standard","hentry","category-nargalzius","tag-nargalzius"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack-related-posts":[],"_links":{"self":[{"href":"http:\/\/nargalzius.com\/blog\/wp-json\/wp\/v2\/posts\/1106","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/nargalzius.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/nargalzius.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/nargalzius.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/nargalzius.com\/blog\/wp-json\/wp\/v2\/comments?post=1106"}],"version-history":[{"count":1,"href":"http:\/\/nargalzius.com\/blog\/wp-json\/wp\/v2\/posts\/1106\/revisions"}],"predecessor-version":[{"id":1660,"href":"http:\/\/nargalzius.com\/blog\/wp-json\/wp\/v2\/posts\/1106\/revisions\/1660"}],"wp:attachment":[{"href":"http:\/\/nargalzius.com\/blog\/wp-json\/wp\/v2\/media?parent=1106"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/nargalzius.com\/blog\/wp-json\/wp\/v2\/categories?post=1106"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/nargalzius.com\/blog\/wp-json\/wp\/v2\/tags?post=1106"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}