Syskall Olivier Lalonde's blog. https://syskall.com/ Wed, 21 May 2025 01:33:04 +0000 Wed, 21 May 2025 01:33:04 +0000 Jekyll v3.10.0 2021 Update <p>I was quite busy in recent years and kind of abandoned my blog so I thought I would do a very condensed summary of what I’ve been up to in these past few years.</p> <p>I got quite involved with Bitcoin. I developed a web based, “read-only” Bitcoin wallet which was called “ColdMonitor”. The intended market was primarily charities and organisations who wanted to be transparent about their finances. In the process, I essentially developed a full Bitcoin node from scratch in Node.js using Postgres as a data store. I had to learn a lot about <a href="https://github.com/olalonde/bitcoin-notes">Bitcoin’s inner workings</a>. I also <a href="https://github.com/olalonde/proof-of-liabilities">pioneered the “proof of liabilities”</a> cryptographic scheme that some exchanges eventually adopted. This was around the time of the MtGox disaster when multiple people started questioning the solvability of Bitcoin exchanges.</p> <p>The ColdMonitor project didn’t gain as much traction as I had hoped but it did lead to me joining Blockai, a startup that was using the Bitcoin blockchain to register and timestamp copyrights (using the <code class="language-plaintext highlighter-rouge">OP_RETURN</code> opcode). The startup pivoted multiple times and was re-branded to Binded.com. We eventually got acquired by <a href="https://www.pixsy.com/binded/">Pixsy.com</a>.</p> <p>During my time as CTO and co-founder of Binded, I got to manage a small team of engineers. I did a lot of full stack development with React/Node.js. I also learned a lot about deep learning, computer vision and information retrieval (we built a reverse image search engine for the web). I had to learn a lot of that on the spot which lead me to completing Stanford’s Machine Learning course as well as the Deep Learning specialisation on Coursera by Andrew Ng (I highly recommend both). Since we were a small team, I was also responsible for operations so I got to do a lot of DevOps stuff (Kubernetes, Docker, CI/CD pipeline, Terraform, etc.).</p> <p>Following Binded’s acquisition in 2019, I did some open source development (e.g. <a href="https://github.com/nodejs/node/pull/34600">added a new crypto API to Node.js</a>), some consulting, learned Rust, etc. I also got quite lucky with a few investments. I am currently working on a new project at which touches on algorithmic trading, DeFi and cryptocurrency.</p> Mon, 18 Jan 2021 17:00:00 +0000 https://syskall.com/2021-update/ https://syskall.com/2021-update/ perso Boot2docker: Using nfs instead of vboxsf to mount /Users <p>After trying to run bitcoind in a docker container on boot2docker and mounting my local ~/.bitcoin directory as a volume I discovered that the file system VirtualBox uses for mounting directories (vboxsf) doesn’t support some operations that LevelDB needs in order to operate.</p> <p>Unfortunately, at the time of this writing, boot2docker doesn’t have an official way to switch from VirtualBox shared folders to nfs.</p> <p>Which prompted me to write this short script that does exactly this:</p> <script src="https://gist.github.com/olalonde/3f7512c0bd2bc8abb46d.js"> </script> Tue, 14 Apr 2015 17:00:00 +0000 https://syskall.com/using-boot2docker-using-nfs-instead-of-vboxsf/ https://syskall.com/using-boot2docker-using-nfs-instead-of-vboxsf/ docker devops Crazy And Not So Crazy Startup Ideas (2015 edition) <ul> <li><a href="#1.-bitcoin-(read-only)-wallet-as-a-service">1. Bitcoin (Read-Only) Wallet as a Service</a></li> <li><a href="#2.-turnkey-website-for-factories-on-alibaba.com">2. Turnkey website for factories on Alibaba.com</a></li> <li><a href="#3.-startup-as-a-service">3. Startup as a Service</a></li> <li><a href="#4.-cold-calling-as-a-service">4. Cold Calling as a Service</a></li> <li><a href="#5.-door-to-door-marketing-as-a-service">5. Door to Door Marketing as a Service</a></li> <li><a href="#6.-proxy-as-a-service-or-distributed-javascript-as-a-service">6. Proxy as a Service or Distributed Javascript as a Service</a></li> <li><a href="#7.-advice/consulting-as-a-service">7. Advice/Consulting as a Service</a></li> <li><a href="#8.-algorithmic-website-theme-generation">8. Algorithmic website theme generation</a></li> <li><a href="#9.-microservices-marketplace-(aka-the-npm/gem-of-microservices)">9. Microservices Marketplace (aka the NPM/GEM of Microservices)</a></li> <li><a href="#10.-module/package/library-search-engine">10. Module/Package/Library Search Engine</a></li> <li><a href="#11.-(professional)-hackaton-league">11. (Professional) Hackaton League</a></li> <li><a href="#12.-code-as-a-service">12. Code as a Service</a></li> <li><a href="#13.-a-gui-interface-for-fig.sh-and-other-similar-tools">13. A GUI interface for fig.sh and other similar tools</a></li> <li><a href="#14.-hosted-open-source-software-as-a-service">14. Hosted Open Source Software as a Service</a></li> <li><a href="#conclusion">Conclusion</a></li> </ul> <h1 id="1-bitcoin-read-only-wallet-as-a-service">1. Bitcoin (Read-Only) Wallet as a Service</h1> <h3 id="problem">Problem</h3> <p><img src="/images/btc_logo.png" align="right" /></p> <p>A lot of people use desktop Bitcoin wallets because they don’t require trust in a third party. The problem with those wallets is that they are hard to extend and build upon.</p> <h3 id="solution">Solution</h3> <p>An read only web wallet would enable third party developers to offer services that require access to someone’s wallet data. For example:</p> <ul> <li>A tax calculator.</li> <li>A money management service like <a href="http://www.mint.com">Mint</a>.</li> <li>Sales reports service for business wallets.</li> <li>Receiving Bitcoin safely without having to run a Bitcoin node or a custom code.</li> <li>Triggering actions when Bitcoin is received or spent from the wallet. For example: Send an SMS when X BTC was spent from the wallet. Update a user’s balance when BTCs are received to a specific address. Send me a warning when my balance goes below X BTC.</li> <li>Monitoring a cold wallet.</li> <li>Embedded the wallet on any web page. This could be useful for charities who want to be transparent about their finances.</li> </ul> <p>If this read-only wallet service offers an API, other developers could build those services. OAuth could be used to gain access to a user’s wallet, in the same standard way many developers ask users access for their Facebook/Twitter accounts.</p> <p>This would enable the creation of an app ecosystem built around Bitcoin wallets.</p> <p>Here’s how a typical user would use the service:</p> <ol> <li>Create account (email/password/2FA).</li> <li>Enter Electrum “read seed” (aka public master key), BIP39 “read” seed or add some Bitcoin addresses manually. There could also be a “Connect with Coinbase” to access Coinbase’s API or to other exchange/web wallet services.</li> <li>The wallet would then display the history of transactions like desktop wallets do.</li> </ol> <p>There could also be an option for users to add some private key(s) to the wallet in order to be able to spend from it. However, the amount of spendable BTCs should be limited to a small (insurable) amount.</p> <p>Some inspiration:</p> <ul> <li>Paypal’s Instant Payment Notification API (something similar could be implemented)</li> </ul> <h3 id="why-it-might-work">Why it might work</h3> <p>There’s a lot of Bitcoin apps waiting to be written but not many developes understand the Bitcoin protocol well enough to write apps for it. Having a simple API to interact with wallets would empower more people to safely build on top of Bitcoin.</p> <h3 id="why-it-might-not-work">Why it might not work</h3> <p>A lot of people do not want to share their financial information with a third party even if that information is “read only”. There is a lot of competition in the space. It’s not clear how to monetize the service.</p> <h1 id="2-turnkey-website-for-factories-on-alibabacom">2. Turnkey website for factories on Alibaba.com</h1> <h3 id="problem-1">Problem</h3> <p><img src="/images/alibaba_logo.png" align="right" /></p> <p>A lot of factories which are listed on <a href="http://www.alibaba.com">Alibaba</a> pour in millions of revenues but yet they have <a href="http://www.bodawutong.com/">dated websites</a> or no website at all.</p> <h3 id="solution-1">Solution</h3> <p>Provide pre-built websites tailored to the needs of those factories.</p> <p>This could be done by scraping data from Alibaba.com and using that data to populate open source platforms such as <a href="http://magentocommerce.com">Magento</a> (e-commerce) or <a href="http://www.wordpress.org">Wordpress</a> with the company’s information and catalog of products.</p> <p>The process can be <em>completely automated</em>:</p> <ul> <li>Crawl Alibaba for companies.</li> <li>Pick a theme randomly or heuristically (depending on the company’s industry for example). Themes could possibly be <a href="#8.-algorithmic-website-theme-generation">generated on the fly</a>.</li> <li>Scrape data such as company name, logo, location, industry, product catalog and populate the database of a simple CMS or e-commerce system.</li> <li>Put the website online at http://<strong>companyname</strong>.turnkeywebsite.com</li> <li>Have a small banner on top of the website with a call to action to buy the website for X$/month.</li> <li>Email or message their company’s website URL and an introduction text (e.g. “We build this website for you, check it out!”).</li> </ul> <p>The same idea and process could be applied to sellers on Ebay, Amazon, Yelp or even freelancers on Elance.com.</p> <h3 id="why-it-might-work-1">Why it might work</h3> <p>Even if 1% of your generated websites generate sales at 10$/month, this could add up quickly if you are able to reach hundred thousands or millions of users. Remember, the process can be entirely automated.</p> <h3 id="why-it-might-not-work-1">Why it might not work</h3> <p>You might be violating Alibaba’s ToS and get blocked from crawling. You might not get on email spam lists. You might end up doing more support then expected.</p> <p>Possible (unethical) fix: use a bunch of proxies.</p> <h1 id="3-startup-as-a-service">3. Startup as a Service</h1> <p><img class="img-rounded" src="/images/startuplogos.jpg" align="right" /></p> <h3 id="problem-2">Problem</h3> <p>When you create a new project or startup, you have to sign up for a bunch of different services, grab a domain name, setup hosting, setup email, etc. Maybe get a 1-800 number?</p> <p>Sometimes, you don’t even know which services could help you be more productive.</p> <p>Similarly, freelancers and web development shops are often required to setup all those things for their customers even when it is not spelled out in their contract.</p> <h3 id="solution-2">Solution</h3> <p>Build a service where a user can pick a bunch of services to sign up for (e.g. Google Apps, Gmail, AWS, Reddit, AngelList, UserVoice, etc.) or a pre-defined service bundle (e.g. SaaS bundle).</p> <p>The service would then generate a form which would encompass the <em>minimal information required</em> (without repetition) to successfuly sign up for all the selected services. The service would then execute all the appropriate POST requests and possibly outsource CAPTCHAs verification (e.g. to Amazon Mechanical Turk).</p> <h3 id="why-it-might-work-2">Why it might work</h3> <p>I personally would kill for such a service.</p> <p>There are similar services on the market that are sometimes described as “cloud integration” services (<a href="http://www.snaplogic.com/">SnapLogic</a>). I am not sure however if the idea I just described is comparable to the service they offer.</p> <h3 id="why-it-might-not-work-2">Why it might not work</h3> <p>This is probably against the ToS of many of the servcies mentioned above. Also, some of those services require credit card information and I’m not sure MasterCard/Visa would allow such a service to handle credit card data.</p> <p>Possible (unethical) fix: use a bunch of proxies.</p> <h1 id="4-cold-calling-as-a-service">4. Cold Calling as a Service</h1> <p><strong>Update</strong>: <a href="https://www.upcall.com/">UpCall</a> is a service that is solving this problem</p> <p><img class="img-rounded" src="/images/coldcall.jpg" align="right" /></p> <h3 id="problem-3">Problem</h3> <p>If you are anything like me, you probably hate talking on the phone, especially to strangers. Plus, you might have a weird accent or you might not be that fluent in spoken English. Or maybe talking on the phone makes you nervous? Or maybe you are scared you might burn a bridge if a phone call goes badly. Or maybe you just don’t have enough time to call all those people you want to call? Or maybe you are living abroad and your phone line sucks?</p> <p>Wouldn’t it be nice if you could outsource those painful phone calls to someone else?</p> <h3 id="solution-3">Solution</h3> <p>Build a platform where people can submit phone call requests. Those requests should contain:</p> <ul> <li>A list of phone numbers and information about the recipient of the call if available.</li> <li>The purpose of the call.</li> <li>How the caller should present him(her)self.</li> <li>What information / actions the call should produce.</li> </ul> <p>There are a few way to execute this idea.</p> <p>There could be a way for people to sign up as “callers” so you don’t have to hire and manage a bunch of people to do the calls.</p> <p>Pricing of phone calls could be done by bidding similar to how freelancing sites work.</p> <p>Pricing could be “per minute” and the calls could be automatically recorded and archived.</p> <p>Another possible twist: make it possible for the call requesters to listen in on live phone calls and have the ability provide instant feedback to the callers through a private chatroom or through an audio channel which only the caller can hear.</p> <p>Another possible twist: if the service has an API, third party developers could build apps which somehow require a human talking on the phone. One idea that comes to mind would be a non-robotic appointment reminder service.</p> <h3 id="why-it-might-work-3">Why it might work</h3> <p>This service would be immensely useful to people who need to (temporarily) scale their cold calling infrastructure or for startup founders who are scared of the phone!</p> <h3 id="why-it-might-not-work-3">Why it might not work</h3> <p>I’m sure there’s a ton of competition in that space already (e.g. <a href="https://elasticsales.com://elasticsales.com/">ElasticSales</a> - it pivoted recently).</p> <p>There’s also the problem of how callers should introduce themselves without sounding like “professional callers”.</p> <h1 id="5-door-to-door-marketing-as-a-service">5. Door to Door Marketing as a Service</h1> <p><img class="img-rounded" src="/images/door2door.jpg" align="right" /></p> <h3 id="problem-4">Problem</h3> <p>For some businesses (e.g. restaurants, lawn mowing service, cleaning service, laundry service, hairdressers, painting, etc.) the best way to advertise is through local advertising.</p> <p>One way to do that is to go from door to door in the neighborhood and to either offer your services or slip a small promotional flyer in the mailbox or under the door.</p> <p>This doesn’t scale well and it’s not always easy to hire people who will do the job for you.</p> <h3 id="solution-4">Solution</h3> <p>Offer a service where localized business can specify an area to cover and a description of what has to be done at every door.</p> <p>One obvious pricing model would be to charge per door.</p> <h3 id="why-it-might-work-4">Why it might work</h3> <p>There’s a lot of small businesses out there who need more customers!</p> <h3 id="why-it-might-not-work-4">Why it might not work</h3> <p>It’s difficult to market that service. The best way would be to start small with a small area and expand from there.</p> <p>It’s not clear that in the Internet age, door to door marketing is still an efficient way to market services.</p> <p>Some small business don’t necessarily have a budget for that.</p> <h1 id="6-proxy-as-a-service-or-distributed-javascript-as-a-service">6. Proxy as a Service or Distributed Javascript as a Service</h1> <p><img class="img-rounded" src="/images/malware.jpg" align="right" /></p> <p><strong>Warning: I’d say this idea is pretty unethical but I still put it here in case it might inspire a better idea.</strong></p> <h3 id="problem-5">Problem</h3> <p>Sometimes you just want to abuse a website but your run out of non-banned IPs. Or maybe you want to do a distributed computation for cheap?</p> <h3 id="solution-5">Solution</h3> <p>A lot of websites have “difficult to monetize” traffic (porn websites, content farms, etc.). What if they could embed a small Javascript script and earn money on every visit?</p> <p>The idea here would be to build a marketplace where people could submit Javascript programs and have the code run on thousands of machines with different IPs.</p> <p>Webmasters could sign up for the service by adding a small embed Javascript in their pages.</p> <p>The system would then automatically dispatch user submitted Javascript programs on all the participating websites, similarly to how ad networks work.</p> <p>This service could be used to run distributed computations or perform HTTP requests using thousands of IPs.</p> <h3 id="why-it-might-work-5">Why it might work</h3> <p>There’s a lot of hard to monetize traffic out there and lots of people who want to perform computations cheaply or cover their origin using tons of IPs.</p> <h3 id="why-it-might-not-work-5">Why it might not work</h3> <p>This idea is unethical and possibly illegal. Also, cross origin policy and CSRF tokens could make this unusable as a proxy service. Plus, IPv6 makes it a lot easier to evade IP level ban.</p> <p>This service could be gamed in the same way ad networks frequently are.</p> <p>There is also the chicken/egg problem: how to get webmasters if there are no one to submit requests and vice versa.</p> <h1 id="7-adviceconsulting-as-a-service">7. Advice/Consulting as a Service</h1> <p><img class="img-rounded" src="/images/question.jpg" align="right" /></p> <h3 id="problem-6">Problem</h3> <p>Sometimes you know about someone who has expertise in a domain and you know this person could help you out but you don’t know exactly how to reach them or make their time worthwhile.</p> <h3 id="solution-6">Solution</h3> <p>Build a service where people can enter the email and name of the person they need advice from (the mentor). They should also be able to specify an hourly rate they are willing to pay or decide to let the mentor pick one.</p> <p>The service would then send out a customized email to the mentor asking them if they want to accept the request.</p> <p>If the recipient agrees, the system would match both recipients for a time to do the call.</p> <p>The call could be proxied through the service so that calling time is monitored. At the end of the call, the correct amount would be deducted from the requesters balance and awarded to the “mentor”.</p> <p>Possible use case: “I want to develop software for hairdressing businesses but I don’t know anyone in that business so I’d like a hairdresser to answer some of my questions.”</p> <p>Twist: the general concept could also be applied to request code reviews from experts.</p> <h3 id="why-it-might-work-6">Why it might work</h3> <p>Using this platform would probably be more efficient and cheaper than having to invite someone for coffee which is the typical way of doing this today.</p> <h3 id="why-it-might-not-work-6">Why it might not work</h3> <p>There are already similar services on the market although I believe most of them require the “mentors” to already be signed up with the service. It’s also not clear how to market the service efficiently.</p> <h1 id="8-algorithmic-website-theme-generation">8. Algorithmic website theme generation</h1> <p><img src="/images/themeforest_logo.png" align="right" /></p> <p>Devise an algorithm that can automatically generate website themes and submit them on theme marketplaces. The algorithm could work as following:</p> <ul> <li>Pick a color theme from a predefined selection of color themes</li> <li>Pick a layout from a predefined selection of layouts. The algorithm could be recursive: each layout element (e.g. header) could have selections of sub-layouts. <a href="http://en.wikipedia.org/wiki/Natural_language_generation">Natural language generation</a> techniques could be useful here.</li> <li>Pick a font theme from a predefined selection of fonts. Selections could consist of “header” font, “main text” font, “monospace” font, etc.</li> <li>Generate a logo</li> <li>Randomly chose pictures and backgrounds images if the layouts needs some of them.</li> </ul> <p>The generated themes could be automatically submitted to theme marketplaces such as <a href="themeforest.net">ThemeForrest</a>. This idea is conceptually similar to those people who generate books and put them for sale on Amazon.</p> <p>Be careful, doing this might be against the ToS of some marketplaces.</p> <h1 id="9-microservices-marketplace-aka-the-npmgem-of-microservices">9. Microservices Marketplace (aka the NPM/GEM of Microservices)</h1> <p><img class="img-rounded" src="/images/microservices.jpg" align="right" /></p> <p>Microservices architecture is rapidly gaining popularity. The idea is to build larger systems composed of smaller self contained services who own their data. Those services typically communicate with each others through a REST API or a messge queue.</p> <p>It would be nice if web applications could be built more rapidly by being able to re-use common services: a user/authentication service, a mailing service, a CMS service, an activity stream services, etc.</p> <p>This is already possible at the library and framework levels. For example, Rails and Django both have a large selection of third-party components that can handle common use cases.</p> <p>However, those components are built with the monolithic architecture in mind. They are often built for a specific framework or language and they often do not own their data.</p> <p>It would be nice if instead of framework specific library/packages, there was an easy way to import self contained, language agnostic, microservices.</p> <p>Those microservice packages could take the form of (<a href="http://www.fig.sh">collections of</a>) configurable Docker images for example.</p> <p>This is not a new idea (see <a href="http://en.wikipedia.org/wiki/Service-oriented_architecture">SOA</a> and <a href="http://en.wikipedia.org/wiki/Enterprise_integration">Enterprise Integration</a>) but the things that hindered the adoption of SOA might not be problematic today. For example, today it is a lot easier to automate deployments and automate monitoring. The devops and “infrastructure as code” movements have produced many tools that make it significantly easier than before to orchestrate distributed systems with multiple moving parts.</p> <p>The marketplace itself could work in a similar way that npm, gem or the Docker registry work. There could be open source or paid microservices.</p> <p>I could see such a marketplace taking market share out of services that are operated by third parties (e.g. MailChimp, Disqus, UserVoice, Mashape, etc.).</p> <h1 id="10-modulepackagelibrary-search-engine">10. Module/Package/Library Search Engine</h1> <p><img class="img-rounded" src="/images/npm.png" align="right" /></p> <p>Most package repositories (<a href="https://www.npmjs.com/">npm</a>, <a href="https://rubygems.org/search">gems</a>, [PyPi[(https://pypi.python.org)) don’t get search quite right. Most developers prefer to head directly to Github and pick libraries according to their starts count.</p> <p>I’m sure we can do better than that. What if there was a library search engine that could find the best possible library given a language and a few key words?</p> <p>Some signals that could be used to rank libraries in search results:</p> <ul> <li>Code quality metrics</li> <li>Github stars count</li> <li>Creation data, recent commits</li> <li>Authors</li> <li>Number of libraries that depend on the library (<a href="http://en.wikipedia.org/wiki/PageRank">PageRank</a> like algorithm?)</li> <li>Number of downloads</li> <li>Number of closed and opened issues</li> <li>Number of tests (do they pass?)</li> <li>Documentation?</li> </ul> <h1 id="11-professional-hackaton-league">11. (Professional) Hackaton League</h1> <p><img src="/images/hackaton.jpg" class="img-rounded" align="right" /></p> <p>There are lots of <a href="http://en.wikipedia.org/wiki/Electronic_sports">eSports gaming leagues</a> but the closest we have in the hacker/startup world are “one off” or “once a year” online hackatons. What if there was a league for hackers and founders that would operate similarly to how gaming leagues operate?</p> <p>The idea would be to build a “MVP league” that would combine aspects of eSports leagues and online hackatons (e.g. <a href="nodeknockout.com">Node Knockout</a>).</p> <p>Participants could form teams and submit a new MVP every X weeks. Another option would be to have theme/technology based tournaments (e.g. “open source”, “Node.js”, “education”).</p> <p>Winners could be selected after each cycle, new teams could be formed, there could be a leader board of teams/participants, etc. Sponsors could offer prizes to winners or investors could offer funding.</p> <p>Additionally, this would be a great way to meet potential co-founders and socialize with like minded peers.</p> <p>There are already a couple of websites that aggregate online hackatons (<a href="http://challengepost.com">ChallengePost</a>, <a href="http://www.wehack.it/">WeHack.it</a>) but I haven’t seen one that operates as a league.</p> <h1 id="12-code-as-a-service">12. Code as a Service</h1> <p><img src="/images/tdd.png" class="img-rounded" align="right" /></p> <p>The idea is about taking Test Driven Development to its limit.</p> <p>The service would allow developers to write a series of test that must pass and wait for someone to write the code that passes those tests.</p> <p>Money/karma would be automatically awarded to the first person who successfully submits code which passes the tests.</p> <p>The biggest problems with this idea are:</p> <ul> <li>In many cases it would be easy to “game” the tests Most developers</li> <li>don’t have a budget for this or don’t know how to price the code they need.</li> <li>Sometimes writing the tests is as difficult or as time consuming as actually writing the code.</li> </ul> <h1 id="13-a-gui-interface-for-figsh-and-other-similar-tools">13. A GUI interface for fig.sh and other similar tools</h1> <p><img src="https://juju.ubuntu.com/wp-content/uploads/2013/10/homepage-hero.png" class="img-rounded" align="right" /></p> <p>Allow devops and sysadmins to visualize and orchestrate their system infrastructure through a simple GUI. Logical services could be represented as squares on a canvas and services that depend on each others (that need to communicate) could be linked with lines. After editing the schema, the tool could write the systems specifications in a text file.</p> <p>The tool could support <a href="http://www.fig.sh">fig.yml</a>, <a href="https://www.terraform.io/">TerraForm</a>, <a href="http://kubernetes.io">Kubernetes</a>, <a href="http://docs.cloudfoundry.org/bosh/">BOSH</a> or <a href="http://www.vagrantup.com">Vagrant</a> for example.</p> <p><a href="https://juju.ubuntu.com/">Ubuntu Juju</a> is a tool that does something along those lines although I don’t think it can read/write to a configuration file such as <code class="language-plaintext highlighter-rouge">fig.yml</code> which is not ideal you adhere to the <a href="http://devops.com/blogs/meet-infrastructure-code/">infrastructure as code</a> philosophy and want to keep your infrastructure under version control in a Git repository.</p> <h1 id="14-hosted-open-source-software-as-a-service">14. Hosted Open Source Software as a Service</h1> <p><img src="/images/opensource.png" class="img-rounded" align="right" /></p> <p>This is not really a specific startup idea but a general business model that is not especially novel either.</p> <p>There is a lot of open source software out there that can be hard to install or operate for the average consumer or even for some developers with minimal sysadmin experience.</p> <p>The general idea is to pick an open source software, completely automate its deployment and sell it as a paid service. In other words, SaaSifying open source projects.</p> <p>You can then put up a simple promotional website where people can sign up and pay a monthly fee for you to host the software for them.</p> <p>Obviously, most well known open source software (e.g. Wordpress) already have tons of <a href="http://www.wordpress.com">companies</a> doing this but some more obscure software might not yet have such services available on the market.</p> <h1 id="conclusion">Conclusion</h1> <p>Hope you liked my crazy shower ideas. Let me know if you plan to borrow one! I’d also be curious to hear about some more crazy ideas in the comments if you have any.</p> Thu, 15 Jan 2015 17:00:00 +0000 https://syskall.com/crazy-and-not-so-crazy-startup-ideas-2015-edition/ https://syskall.com/crazy-and-not-so-crazy-startup-ideas-2015-edition/ startup ideas 2014 Braindump <p>I haven’t updated this blog in a while so I’ll just dump what I have been up to lately.</p> <ul> <li> <p><a href="https://github.com/olalonde/minios">Minios</a>: a toy OS I am building with the help of <a href="littleosbook.github.io">The Little Os Book</a></p> </li> <li> <p><a href="https://github.com/olalonde/dotfiles">Dotfiles</a>: a repository with all my personal dotfiles (tmux, zsh, vim).</p> </li> <li> <p><a href="https://lonehackers.com">Lone Hackers</a>: a small IRC style community for remote hackers and founders.</p> </li> <li> <p><a href="https://github.com/olalonde/proof-of-solvency">Proof of Solvency</a>: a scheme designed to let Bitcoin deposit instutions prove they are solvent.</p> </li> <li> <p><a href="https://github.com/olalonde/coinscript">Coinscript</a>: an experimental language that compiles to Bitcoin script OPCODES.</p> </li> <li> <p><a href="https://bitcointalk.org/index.php?topic=893077.0">Trustless Gambling Scheme using the Bitcoin Blockchain</a></p> </li> <li> <p>Read <a href="http://the-cloud-book.com/">The Practice of Cloud System Administration: Designing and Operating Large Distributed Systems, Volume 2</a>, <a href="http://shop.oreilly.com/product/0636920033158.do">Building Microservices</a> and <a href="http://dcg.ethz.ch/lectures/podc_allstars/">Principles oof Distributed Computing</a></p> </li> <li> <p>Built stuff with Python, Golang, Docker, Fig.sh</p> </li> </ul> Wed, 14 Jan 2015 23:50:13 +0000 https://syskall.com/2014-braindump/ https://syskall.com/2014-braindump/ personal Introducing Boolasync - a library for async boolean logic <ul> <li>Github: <a href="https://github.com/olalonde/boolasync">olalonde/boolasync</a></li> <li>NPM: <code class="language-plaintext highlighter-rouge">npm install boolasync</code></li> <li>License: MIT</li> </ul> <p>Who would have thoughts things would have gone that far? Yes, I have created a Javascript library for handling boolean logic that involves asynchronous callbacks.</p> <p>Let’s say you have a web app that has an authorization layer like so:</p> <div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">if</span> <span class="p">(</span><span class="nx">is_user</span><span class="p">()</span> <span class="o">&amp;&amp;</span> <span class="p">(</span><span class="nx">is_admin</span><span class="p">()</span> <span class="o">||</span> <span class="nx">is_super_admin</span><span class="p">())</span> <span class="p">{</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">Authorize!</span><span class="dl">'</span><span class="p">);</span> <span class="p">}</span> </code></pre></div></div> <p>Note: this is a fictional example for demonstration purposes.</p> <p>However, here is the catch: your functions are asynchronous which means that they take a callback argument which in turns takes an error and result argument. <code class="language-plaintext highlighter-rouge">function callback(err, res) {}</code></p> <p>How do you rewrite the above code elegantly?</p> <p>You could use the nice <code class="language-plaintext highlighter-rouge">async</code> library.</p> <div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">async</span><span class="p">.</span><span class="nx">parallel</span><span class="p">([</span> <span class="nx">is_user</span><span class="p">,</span> <span class="nx">is_admin</span><span class="p">,</span> <span class="nx">is_super_admin</span> <span class="p">],</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">err</span><span class="p">,</span> <span class="nx">results</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="nx">results</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">&amp;&amp;</span> <span class="p">(</span><span class="nx">results</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">||</span> <span class="nx">results</span><span class="p">[</span><span class="mi">2</span><span class="p">]))</span> <span class="p">{</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">Authorize!</span><span class="dl">'</span><span class="p">);</span> <span class="p">}</span> <span class="p">});</span> </code></pre></div></div> <p>There are two problems however:</p> <ol> <li> <p>The code is not very expressive.</p> </li> <li> <p>We have to wait for all functions to finish.</p> <p>In the example above, if <code class="language-plaintext highlighter-rouge">is_user</code> returns <code class="language-plaintext highlighter-rouge">false</code>, we would already know that the user is not authorized. <code class="language-plaintext highlighter-rouge">false &amp;&amp; ...</code> is always false no matter what the <code class="language-plaintext highlighter-rouge">...</code> represents. In computer science, this is called lazy evaluation.</p> </li> </ol> <p>Here is how you would rewrite the above with boolasync:</p> <div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">is_user</span><span class="p">.</span><span class="nx">and</span><span class="p">(</span><span class="nx">is_admin</span><span class="p">.</span><span class="nx">or</span><span class="p">(</span><span class="nx">is_super_admin</span><span class="p">)).</span><span class="nb">eval</span><span class="p">(</span><span class="kd">function</span> <span class="p">(</span><span class="nx">err</span><span class="p">,</span> <span class="nx">authorized</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="nx">authorized</span><span class="p">)</span> <span class="p">{</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">Authorize!</span><span class="dl">'</span><span class="p">);</span> <span class="p">}</span> <span class="p">});</span> </code></pre></div></div> <p>Notice how terse and expressive the code is compared to the async example. In bonus, boolasync won’t wait for an async call to terminate if it already knows the result of an expression.</p> <p>For more documentation and examples, visit the Github page: <a href="https://github.com/olalonde/boolasync">https://github.com/olalonde/boolasync</a></p> <p>Cheers!</p> Wed, 12 Jun 2013 00:23:00 +0000 https://syskall.com/introducing-boolasync-async-boolean-logic-library/ https://syskall.com/introducing-boolasync-async-boolean-logic-library/ node.js javascript Executing multiple shell commands cleanly in Node.js with async <div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">async</span><span class="p">.</span><span class="nx">parallel</span><span class="p">([</span> <span class="k">async</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="nx">exec</span><span class="p">,</span> <span class="dl">'</span><span class="s1">git rev-parse HEAD</span><span class="dl">'</span><span class="p">),</span> <span class="k">async</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="nx">exec</span><span class="p">,</span> <span class="dl">'</span><span class="s1">git symbolic-ref --short HEAD</span><span class="dl">'</span><span class="p">)</span> <span class="p">],</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">err</span><span class="p">,</span> <span class="nx">results</span><span class="p">)</span> <span class="p">{</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">results</span><span class="p">);</span> <span class="p">});</span> </code></pre></div></div> <p>First, the <code class="language-plaintext highlighter-rouge">async.parallel</code> call executes all functions in the array concurrently. If you need the commands to be executed in order, use <code class="language-plaintext highlighter-rouge">async.series</code> instead. <code class="language-plaintext highlighter-rouge">async.apply</code> returns the function passed as a first argument with values already applied to its arguments and sets the <code class="language-plaintext highlighter-rouge">async.parallel</code> callback for us. Finally, the last functions receives the results in order when all functions have finished executing. It preserves the order of results as you would expect them.</p> <p>For more info:</p> <p><a href="https://github.com/caolan/async">https://github.com/caolan/async</a></p> Mon, 27 May 2013 18:04:00 +0000 https://syskall.com/executing-multiple-shell-commands-cleanly-in-node-dot-js-with-async/ https://syskall.com/executing-multiple-shell-commands-cleanly-in-node-dot-js-with-async/ node.js async My biggest Vim productivity boost <p>This week I added the following snippet to my .vimrc (.vimrc.after if you are using Janus):</p> <div class="language-vim highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">map</span> <span class="p">&lt;</span>C<span class="p">-</span>J<span class="p">&gt;</span> <span class="p">:</span><span class="k">bnext</span><span class="p">&lt;</span>CR<span class="p">&gt;</span> <span class="nb">map</span> <span class="p">&lt;</span>C<span class="p">-</span>K<span class="p">&gt;</span> <span class="p">:</span>bprev<span class="p">&lt;</span>CR<span class="p">&gt;</span> <span class="nb">map</span> <span class="p">&lt;</span>C<span class="p">-</span>L<span class="p">&gt;</span> <span class="p">:</span><span class="k">tabn</span><span class="p">&lt;</span>CR<span class="p">&gt;</span> <span class="nb">map</span> <span class="p">&lt;</span>C<span class="p">-</span>H<span class="p">&gt;</span> <span class="p">:</span><span class="k">tabp</span><span class="p">&lt;</span>CR<span class="p">&gt;</span> </code></pre></div></div> <p>It maps <code class="language-plaintext highlighter-rouge">CTRL-j</code> and <code class="language-plaintext highlighter-rouge">CTRL-k</code> to next and previous buffer and <code class="language-plaintext highlighter-rouge">CTRL-l</code> and <code class="language-plaintext highlighter-rouge">CTRL-h</code> to next and previous tabs.</p> <p>It is by far the biggest productivity boost I have gotten out of my <code class="language-plaintext highlighter-rouge">.vimrc</code> file.</p> <p>Buffer and tab switching has never been that fast and easy.</p> <p>Macbook tip: remap your CAPS LOCK key to CTRL.</p> Tue, 21 May 2013 10:50:00 +0000 https://syskall.com/my-biggest-vim-productivity-boost/ https://syskall.com/my-biggest-vim-productivity-boost/ vim Connectr: Programmatically manipulating the Connect stack <p><a href="https://github.com/olalonde/connectr">Connectr</a> is a Node.js module I wrote that aims to solve the following problem: how to manipulate the <a href="https://github.com/senchalabs/connect">Connect</a> stack after it has been created.</p> <p>This is a problem I faced while writing a REST framework on top of <a href="http://expressjs.com">Express.js</a>. The framework initialized the middleware stack but there was no easy way to expose the stack to end users of the framework so they could add their own middlewares at arbitrary positions on the stack.</p> <h1 id="install">Install</h1> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>npm install connectr </code></pre></div></div> <h1 id="usage">Usage</h1> <div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">var</span> <span class="nx">connectr</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="dl">'</span><span class="s1">connectr</span><span class="dl">'</span><span class="p">)(</span><span class="nx">app</span><span class="p">);</span> <span class="c1">// Add labeled middleware</span> <span class="nx">connectr</span><span class="p">.</span><span class="nx">use</span><span class="p">(</span><span class="nx">middleware</span><span class="p">).</span><span class="k">as</span><span class="p">(</span><span class="nx">label</span><span class="p">);</span> <span class="c1">// Insert before middleware</span> <span class="nx">connectr</span><span class="p">.</span><span class="nx">before</span><span class="p">(</span><span class="nx">label</span><span class="p">).</span><span class="nx">use</span><span class="p">(</span><span class="nx">middleware</span><span class="p">).</span><span class="k">as</span><span class="p">(</span><span class="nx">label</span><span class="p">);</span> <span class="c1">// Insert after middleware</span> <span class="nx">connectr</span><span class="p">.</span><span class="nx">after</span><span class="p">(</span><span class="nx">label</span><span class="p">).</span><span class="nx">use</span><span class="p">(</span><span class="nx">middleware</span><span class="p">);</span> <span class="c1">// Remove middleware</span> <span class="nx">connectr</span><span class="p">.</span><span class="nx">remove</span><span class="p">(</span><span class="nx">label</span><span class="p">);</span> <span class="c1">// the .as, .before and .after calls are optional</span> </code></pre></div></div> <h1 id="simple-example">Simple Example</h1> <div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">var</span> <span class="nx">connect</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="dl">'</span><span class="s1">connect</span><span class="dl">'</span><span class="p">),</span> <span class="kd">var</span> <span class="nx">app</span> <span class="o">=</span> <span class="nx">connect</span><span class="p">();</span> <span class="kd">var</span> <span class="nx">connectr</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="dl">'</span><span class="s1">connectr</span><span class="dl">'</span><span class="p">)(</span><span class="nx">app</span><span class="p">);</span> <span class="nx">connectr</span><span class="p">.</span><span class="nx">use</span><span class="p">(</span><span class="nx">connect</span><span class="p">.</span><span class="nx">cookieParser</span><span class="p">).</span><span class="k">as</span><span class="p">(</span><span class="dl">'</span><span class="s1">cookieParser</span><span class="dl">'</span><span class="p">);</span> <span class="cm">/* ... */</span> <span class="nx">connectr</span><span class="p">.</span><span class="nx">before</span><span class="p">(</span><span class="dl">'</span><span class="s1">cookieParser</span><span class="dl">'</span><span class="p">).</span><span class="nx">use</span><span class="p">(</span><span class="kd">function</span> <span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">,</span> <span class="nx">next</span><span class="p">)</span> <span class="p">{</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">Before cookie parser...</span><span class="dl">'</span><span class="p">);</span> <span class="nx">next</span><span class="p">();</span> <span class="p">}).</span><span class="k">as</span><span class="p">(</span><span class="dl">'</span><span class="s1">log before cookie parser</span><span class="dl">'</span><span class="p">);</span> </code></pre></div></div> <p>I am hoping the methods that Connectr provide can eventually be supported natively by Connect but until then, Connectr does the job.</p> <p>If you use Connectr, please <a href="https://github.com/olalonde/connectr/blob/master/README.md">star the project on Github</a> to show your support.</p> <p>Happy coding!</p> Sat, 18 May 2013 12:36:00 +0000 https://syskall.com/connectr-programmatically-manipulating-the-connect-stack/ https://syskall.com/connectr-programmatically-manipulating-the-connect-stack/ node.js javascript Pagination with Handlebars <p>Pagination can be quite tricky with Handlebars since Handlebars does not have any built in way to do for/while loops. One solution mix some presentation code within your logic layer and passing an array containing all your pages in an array.</p> <p>For example:</p> <div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span> <span class="nl">pagination</span><span class="p">:</span> <span class="p">[</span> <span class="p">{</span> <span class="na">previous</span><span class="p">:</span> <span class="nx">disabled</span> <span class="p">},</span> <span class="p">{</span> <span class="na">page</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span> <span class="na">active</span><span class="p">:</span> <span class="kc">true</span> <span class="p">},</span> <span class="p">{</span> <span class="na">page</span><span class="p">:</span> <span class="mi">2</span> <span class="p">},</span> <span class="p">{</span> <span class="na">page</span><span class="p">:</span> <span class="mi">3</span> <span class="p">},</span> <span class="p">{</span> <span class="na">page</span><span class="p">:</span> <span class="mi">4</span> <span class="p">},</span> <span class="p">{</span> <span class="na">page</span><span class="p">:</span> <span class="mi">5</span> <span class="p">}</span> <span class="p">]</span> <span class="p">}</span> </code></pre></div></div> <p>This solution has several drawbacks: mixing of logic/view code, code duplication, difficult to reuse, etc.</p> <p>The other, cleaner solution, is to write a Handlebars helper, which I have already done so you don’t have to!</p> <p><img src="https://github.com/olalonde/handlebars-paginate/raw/master/screenshot.png" alt="screenshot" /></p> <p>The helper is available for download or forking on Github:</p> <p><a href="https://github.com/olalonde/handlebars-paginate">https://github.com/olalonde/handlebars-paginate</a></p> <p>or through NPM:</p> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>npm <span class="nb">install </span>handlebars-paginate </code></pre></div></div> <p>To use it, all you have to do is register it as an helper:</p> <div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">Handlebars</span><span class="p">.</span><span class="nx">registerHelper</span><span class="p">(</span><span class="dl">'</span><span class="s1">paginate</span><span class="dl">'</span><span class="p">,</span> <span class="nx">require</span><span class="p">(</span><span class="dl">'</span><span class="s1">handlebars-paginate</span><span class="dl">'</span><span class="p">));</span> </code></pre></div></div> <p>And all you need to pass to your template is an object containing a <code class="language-plaintext highlighter-rouge">page</code> parameter which is the number of the current page and a <code class="language-plaintext highlighter-rouge">pageCount</code> parameter which is the total number of pages.</p> <p>For example:</p> <div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span> <span class="nl">pagination</span><span class="p">:</span> <span class="p">{</span> <span class="na">page</span><span class="p">:</span> <span class="mi">3</span><span class="p">,</span> <span class="na">pageCount</span><span class="p">:</span> <span class="mi">10</span> <span class="p">}</span> <span class="p">}</span> </code></pre></div></div> <p>Handlebars-paginate let’s you define three types of blocks in your template:</p> <p><strong>middle</strong>:</p> <p>This will iterate over all the possible pages. An optional <code class="language-plaintext highlighter-rouge">limit</code> parameter is available if you’d like to limit how many page links to display. <code class="language-plaintext highlighter-rouge">limit=7</code> will only display 3 links to the left of the active page and 3 pages to its right.</p> <p>For example:</p> <div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code>{{#paginate pagination type="middle" limit="7"}} <span class="nt">&lt;li</span> <span class="err">{{</span><span class="na">#if</span> <span class="na">active</span><span class="err">}}</span><span class="na">class=</span><span class="s">"active"</span><span class="err">{{/</span><span class="na">if</span><span class="err">}}</span><span class="nt">&gt;&lt;a</span> <span class="na">href=</span><span class="s">"?p={{n}}"</span><span class="nt">&gt;</span>{{n}}<span class="nt">&lt;/a&gt;&lt;/li&gt;</span> {{/paginate}} </code></pre></div></div> <p><strong>previous</strong> and <strong>next</strong>:</p> <p>Finally, previous and next are used to define how you want to display the “previous” and “next” buttons.</p> <p>For example:</p> <div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code>{{#paginate pagination type="previous"}} <span class="nt">&lt;li</span> <span class="err">{{</span><span class="na">#if</span> <span class="na">disabled</span><span class="err">}}</span><span class="na">class=</span><span class="s">"disabled"</span><span class="err">{{/</span><span class="na">if</span><span class="err">}}</span><span class="nt">&gt;&lt;a</span> <span class="na">href=</span><span class="s">"?p={{n}}"</span> <span class="nt">&gt;</span>Prev<span class="nt">&lt;/a&gt;&lt;/li&gt;</span> {{/paginate}} </code></pre></div></div> <div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code>{{#paginate pagination type="next"}} <span class="nt">&lt;li</span> <span class="err">{{</span><span class="na">#if</span> <span class="na">disabled</span><span class="err">}}</span><span class="na">class=</span><span class="s">"disabled"</span><span class="err">{{/</span><span class="na">if</span><span class="err">}}</span><span class="nt">&gt;&lt;a</span> <span class="na">href=</span><span class="s">"?p={{n}}"</span><span class="nt">&gt;</span>Next<span class="nt">&lt;/a&gt;&lt;/li&gt;</span> {{/paginate}} </code></pre></div></div> <p>Enjoy and feel free to fork or <a href="https://github.com/olalonde/handlebars-paginate/issues">report issues</a>!</p> Sat, 17 Nov 2012 09:05:00 +0000 https://syskall.com/pagination-with-handlebars/ https://syskall.com/pagination-with-handlebars/ javascript node.js How to follow HTTP redirects in Node.js <p>One of the biggest annoyance with Node.js’ native HTTP and HTTPS clients is that there is no way to automatically follow HTTP redirects. Let’s say you want to fetch the content of a page that has moved (301 redirect), you will have to write a lot of <em>boilerplate code</em> to handle the redirect(s) by yourself.</p> <p>Since following redirects is fairly common, I decided to write a a drop-in replacement for the native HTTP and HTTPS module that would handle redirection seamlessly.</p> <p>This module has exactly the same interface has the native HTTP and HTTPS module but it will handle redirects automatically. In other words, if you want to automatically start following redirects, all you have to do is replace</p> <div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">var</span> <span class="nx">http</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="dl">'</span><span class="s1">http</span><span class="dl">'</span><span class="p">);</span> </code></pre></div></div> <p>by</p> <div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">var</span> <span class="nx">http</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="dl">'</span><span class="s1">follow-redirects</span><span class="dl">'</span><span class="p">).</span><span class="nx">http</span> </code></pre></div></div> <p>Before that, you will of course need to install the module through NPM:</p> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>npm <span class="nb">install </span>follow-redirects </code></pre></div></div> <p>Here are some usage examples:</p> <div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">var</span> <span class="nx">http</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="dl">'</span><span class="s1">follow-redirects</span><span class="dl">'</span><span class="p">).</span><span class="nx">http</span><span class="p">;</span> <span class="kd">var</span> <span class="nx">https</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="dl">'</span><span class="s1">follow-redirects</span><span class="dl">'</span><span class="p">).</span><span class="nx">https</span><span class="p">;</span> <span class="cm">/* * http and https are just like Node.js' http and https modules except * that they follow redirects seamlessly. */</span> <span class="nx">http</span><span class="p">.</span><span class="kd">get</span><span class="p">(</span><span class="dl">'</span><span class="s1">http://bit.ly/900913</span><span class="dl">'</span><span class="p">,</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">res</span><span class="p">)</span> <span class="p">{</span> <span class="nx">res</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="dl">'</span><span class="s1">data</span><span class="dl">'</span><span class="p">,</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">chunk</span><span class="p">)</span> <span class="p">{</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">chunk</span><span class="p">);</span> <span class="p">});</span> <span class="p">}).</span><span class="nx">on</span><span class="p">(</span><span class="dl">'</span><span class="s1">error</span><span class="dl">'</span><span class="p">,</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">err</span><span class="p">)</span> <span class="p">{</span> <span class="nx">console</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="nx">err</span><span class="p">);</span> <span class="p">});</span> <span class="cm">/* * You can optionnally pass the maxRedirect option which defaults to 5 */</span> <span class="nx">https</span><span class="p">.</span><span class="nx">request</span><span class="p">({</span> <span class="na">host</span><span class="p">:</span> <span class="dl">'</span><span class="s1">bitly.com</span><span class="dl">'</span><span class="p">,</span> <span class="na">path</span><span class="p">:</span> <span class="dl">'</span><span class="s1">/UHfDGO</span><span class="dl">'</span><span class="p">,</span> <span class="na">maxRedirects</span><span class="p">:</span> <span class="mi">3</span> <span class="p">},</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">res</span><span class="p">)</span> <span class="p">{</span> <span class="nx">res</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="dl">'</span><span class="s1">data</span><span class="dl">'</span><span class="p">,</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">chunk</span><span class="p">)</span> <span class="p">{</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">chunk</span><span class="p">);</span> <span class="p">});</span> <span class="p">}).</span><span class="nx">on</span><span class="p">(</span><span class="dl">'</span><span class="s1">error</span><span class="dl">'</span><span class="p">,</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">err</span><span class="p">)</span> <span class="p">{</span> <span class="nx">console</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="nx">err</span><span class="p">);</span> <span class="p">});</span> </code></pre></div></div> <p>More info is available at the Github repository: <a href="https://github.com/olalonde/follow-redirects/">https://github.com/olalonde/follow-redirects/</a></p> Fri, 16 Nov 2012 06:16:00 +0000 https://syskall.com/how-to-follow-http-redirects-in-node-dot-js/ https://syskall.com/how-to-follow-http-redirects-in-node-dot-js/ node.js javascript