<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-512188703456595011</id><updated>2012-02-02T09:26:47.561+01:00</updated><category term='linux'/><category term='apache'/><category term='dispute'/><category term='china great firewall'/><category term='fastcgi'/><category term='centos'/><category term='office'/><category term='mysql'/><category term='translation'/><category term='php'/><category term='web'/><category term='cookies'/><category term='400'/><category term='init.d'/><category term='vulnerability'/><category term='pptp vpn ios pptpd poptop problem fix'/><category term='old style logon screen'/><category term='ripoff'/><category term='drawingbrush'/><category term='issue'/><category term='http'/><category term='book'/><category term='mediaplayer'/><category term='windows 7'/><category term='playing'/><category term='plesk'/><category term='memcache'/><category term='troubleshooting'/><category term='outlook'/><category term='paypal'/><category term='configuration'/><category term='wpf'/><category term='nginx'/><category term='vpn1euro'/><category term='administration'/><category term='errors'/><category term='video'/><category term='memcached'/><category term='server'/><category term='email'/><category term='vpn'/><category term='ocr'/><category term='caching'/><category term='vhosts'/><category term='traffic'/><category term='alternative'/><category term='chinese'/><category term='videodrawing'/><title type='text'>Clement Nedelcu's Journal</title><subtitle type='html'>Welcome to my blog dedicated to software development &amp;amp; server administration. This blog contains or will contain articles on subjects that lack documentation in general, or just stuff that I find interesting and/or useful. Main subjects are Nginx HTTP server, Microsoft .NET, PHP, MySQL, and web development more generally.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://cnedelcu.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/512188703456595011/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://cnedelcu.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Clément Nedelcu</name><uri>http://www.blogger.com/profile/00168228978102132365</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>24</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-512188703456595011.post-8221874922538504654</id><published>2012-01-23T13:37:00.002+01:00</published><updated>2012-01-23T13:38:08.893+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='chinese'/><category scheme='http://www.blogger.com/atom/ns#' term='office'/><category scheme='http://www.blogger.com/atom/ns#' term='ocr'/><category scheme='http://www.blogger.com/atom/ns#' term='translation'/><title type='text'>Chinese OCR: translating scanned or photographied Chinese text to any language</title><content type='html'>&lt;br /&gt;Having lived in China for almost 3 years now I am able to recognize a good bunch of characters, I can type in Chinese on the computer too but writing is much easier than reading since it doesn't require you to actually memorize the characters, you just type in pinyin (phonetics). That is not enough to understand a full, complex text.&lt;br /&gt;After months of research I've finally figured out &lt;b&gt;how to recognize chinese characters automatically from a picture&lt;/b&gt;, in order to copy/paste the text into a translator such as Google translate or others. The solution was right under my eyes all this time: &lt;b&gt;Microsoft Office 2007&lt;/b&gt;. I had no idea that Office 2007 came with such features. I've always known of expensive solutions such as Ominpage Pro, but I refused to resort to purchasing the app considering its price and how little I would need it.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;OCR&lt;/b&gt;, which stands for &lt;i&gt;Optical Character Recognition&lt;/i&gt;, is the principle of proceeding to the digital analysis of an image to extract the characters/text that it contains, in order to be able to manipulate the text on a computer.&lt;br /&gt;&lt;br /&gt;The solution I describe is &lt;b&gt;for PC/Windows users only&lt;/b&gt;. If you're interested on doing the same, real time and in a much simpler way directly from your iPhone, I recommend the excellent &lt;a href="http://itunes.apple.com/us/app/pleco-chinese-dictionary/id341922306?mt=8"&gt;Pleco&lt;/a&gt;. I've tried out the demo version and am seriously considering purchasing the full version.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;u&gt;TLDR:&lt;/u&gt;&lt;/b&gt; there are basically four steps involved in the process:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Take a photo with your digital camera, or scan your document with your scanner&lt;/li&gt;&lt;li&gt;(Optional) Convert your photo to a TIF image&lt;/li&gt;&lt;li&gt;Open the TIF image with Microsoft Office Document Imaging, run the OCR&lt;/li&gt;&lt;li&gt;Export the text to Microsoft Word then translate it&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;This tutorial requires the following software to be installed on your computer:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Microsoft Office 2007 (though this supposedly works with &lt;b&gt;Microsoft Office 2003&lt;/b&gt;): installed with "Document Imaging" and "Picture Manager", both are components that you can select during the setup process. If you don't have those two installed on your computer, modify your Office setup to include them.&lt;/li&gt;&lt;li&gt;Chinese language support for Microsoft Office, which isn't exactly something you come across easily. I have the chance to work in China and we have licenses for the Chinese version of Microsoft Office, so I've had no trouble. As an alternative you can get the &lt;a href="http://bloggingabout.net/blogs/mglaser/archive/2006/12/18/microsoft-office-multi-language-pack-2007.aspx"&gt;Microsoft Office 2007 Multi-Language pack&lt;/a&gt;&amp;nbsp;and install Chinese support as well as a bunch of other languages if you're interested.&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;&lt;span style="font-size: large;"&gt;Step 1: Taking a picture or scanning a document&lt;/span&gt;&lt;/div&gt;&lt;div&gt;I don't need to remind you how you take pictures with a digital camera. Nor how to save pictures from a website with your favorite web browser.&amp;nbsp;If you are going to use a scanner though, and that is probably the solution that will get you the best results, you can probably skip the next step if your scanner supports saving as TIF/TIFF documents.&lt;br /&gt;&lt;br /&gt;To illustrate this tutorial I've chosen to work with a photo taken with my iPhone 4S. It's a document I've taken from a random advertisement booklet found at a friend's place. I tried to get a clear shot of the text to make sure OCR works as accurately as possible.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-rRK4OVGbtD8/Tx1NTj1ejtI/AAAAAAAADrM/VnJr_kRP2vg/s1600/Img_0322.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://4.bp.blogspot.com/-rRK4OVGbtD8/Tx1NTj1ejtI/AAAAAAAADrM/VnJr_kRP2vg/s200/Img_0322.jpg" width="150" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: large;"&gt;Step 2: Converting to TIF/TIFF image&lt;/span&gt;&lt;/div&gt;&lt;div&gt;Unfortunately, and I must admit I find this quite odd myself, the tool we're going to use for performing the OCR does not support anything other than the TIF format. So if your picture was saved under any other format (JPG typically, like mine) you'll have to convert it. There are plenty of ways to do so.&lt;br /&gt;&lt;br /&gt;Since you have Microsoft Office installed on your computer, you should have everything it takes. Right-click your JPG image and "Open with..." - "&lt;b&gt;Microsoft Office Picture Manager&lt;/b&gt;". Go to "File" - "Export..." and select the TIF format.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-3k3L2dKr3iw/Tx1O5rnsXXI/AAAAAAAADrU/xXu3i1jvA80/s1600/officepicturemanager.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="290" src="http://1.bp.blogspot.com/-3k3L2dKr3iw/Tx1O5rnsXXI/AAAAAAAADrU/xXu3i1jvA80/s320/officepicturemanager.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: large;"&gt;Step 3: Performing the OCR&lt;/span&gt;&lt;/div&gt;&lt;div&gt;The actual OCR (Optical Character Recognition) is performed by &lt;b&gt;Microsoft Office Document Imaging&lt;/b&gt;. Open the tool, which should be located in your Start Menu under Microsoft Office / Microsoft Office Tools / Microsoft Office Document Imaging.&lt;br /&gt;&lt;br /&gt;Before performing the OCR you need to specify the document language. To do so, open the "Tools" menu, go to "Options" - "OCR" and select "Chinese" in the drop-down list.&amp;nbsp;The next steps are simple...&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-ooKJZrC5Xns/Tx1QSSCmIhI/AAAAAAAADrc/HzS9B2wZL7w/s1600/nextstep.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="228" src="http://2.bp.blogspot.com/-ooKJZrC5Xns/Tx1QSSCmIhI/AAAAAAAADrc/HzS9B2wZL7w/s320/nextstep.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Open the file... Click on the OCR button... Click on the "Send Text to Word" button... press OK and you're done!&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-bfA00ssmO0k/Tx1Q6XH4UpI/AAAAAAAADrk/rOOouznfTV4/s1600/chinested.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="271" src="http://3.bp.blogspot.com/-bfA00ssmO0k/Tx1Q6XH4UpI/AAAAAAAADrk/rOOouznfTV4/s320/chinested.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;The text should be more or less faithfully transcripted depending on the quality of the original picture. Now onto translating it to something actually legible to the average westerner :-)&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;span style="font-size: large;"&gt;Step 4: Translation to English or other languages&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;There are tons of translators out there but I'm going to stick to Microsoft Office since that is what we've been using from the start.&amp;nbsp;Yes, you can translate Chinese directly from within Word 2007 if you follow the simple instructions described below:&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;ol&gt;&lt;li&gt;Select the text you want translated&lt;/li&gt;&lt;li&gt;Right-click the selected text and in the menu, go to "Translate" - "Translate..."&amp;nbsp;&lt;/li&gt;&lt;li&gt;Select the input and output languages and click the little green arrow&lt;/li&gt;&lt;li&gt;You'll be taken to Microsoft's online translation service, which provides a surprisingly accurate translation of my original text.&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;Before:&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-OWjnCbs59jI/Tx1THT5LsjI/AAAAAAAADrs/-BTsftXxCcg/s1600/translate.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="271" src="http://1.bp.blogspot.com/-OWjnCbs59jI/Tx1THT5LsjI/AAAAAAAADrs/-BTsftXxCcg/s320/translate.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;After:&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-goWTqbFfwcM/Tx1TfazAbGI/AAAAAAAADr0/ckSyyDbUJus/s1600/translationdone.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="195" src="http://4.bp.blogspot.com/-goWTqbFfwcM/Tx1TfazAbGI/AAAAAAAADr0/ckSyyDbUJus/s320/translationdone.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;i&gt;Note: the original document IS about shady management techniques. That's all I had.&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;Voila, you've successfully translated a document written in another language, based on a simple photo and Microsoft Office. Ah, isn't technology wonderful?&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/512188703456595011-8221874922538504654?l=cnedelcu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cnedelcu.blogspot.com/feeds/8221874922538504654/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=512188703456595011&amp;postID=8221874922538504654' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/512188703456595011/posts/default/8221874922538504654'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/512188703456595011/posts/default/8221874922538504654'/><link rel='alternate' type='text/html' href='http://cnedelcu.blogspot.com/2012/01/chinese-ocr-translating-scanned-or.html' title='Chinese OCR: translating scanned or photographied Chinese text to any language'/><author><name>Clément Nedelcu</name><uri>http://www.blogger.com/profile/00168228978102132365</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-rRK4OVGbtD8/Tx1NTj1ejtI/AAAAAAAADrM/VnJr_kRP2vg/s72-c/Img_0322.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-512188703456595011.post-2866526238788839742</id><published>2011-11-08T09:54:00.000+01:00</published><updated>2011-11-08T09:54:36.956+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='outlook'/><category scheme='http://www.blogger.com/atom/ns#' term='email'/><category scheme='http://www.blogger.com/atom/ns#' term='administration'/><title type='text'>Outlook 2007: replying to multiple emails or senders</title><content type='html'>Today, I received about 60 emails from my students who were handing in their assignments. Normally, I would just ask them to assume that I have received their emails correctly, but since we had trouble with the Internet connection, most of my students wanted to make sure I had received their work in due time. So I decided to send a kind confirmation reply to all the students that emailed me their work.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-ufhAwcauTyU/TrjkoJL-OyI/AAAAAAAADqM/NxX4C0PrWus/s1600/screenshot1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/-ufhAwcauTyU/TrjkoJL-OyI/AAAAAAAADqM/NxX4C0PrWus/s1600/screenshot1.png" /&gt;&lt;/a&gt;&lt;/div&gt;So here I go, opening &lt;b&gt;Microsoft Outlook 2007&lt;/b&gt;, selecting multiple emails, right click to find the option "&lt;b&gt;Reply to all&lt;/b&gt;" ... horror! It's not there! There's no apparent way to reply to all my students at once. What's worse is there isn't even an option to collect email addresses from people who emailed me (I would then have created one email with all recipients in BCC).&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;How it works, in a nutshell&lt;/span&gt;&lt;br /&gt;After Googling it for about an hour, turns out there is no regular solution to perform such a basic operation. All the solutions I found involved installation of 3rd-party software OR installing and running complex macros. Uh, no thanks. I found some kind of simple workaround that &lt;b&gt;requires no third-party software or macros&lt;/b&gt;. It's all in there, using advanced features.&lt;br /&gt;&lt;br /&gt;Before I detail each step, here is the principle:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;We create a "&lt;b&gt;Message Template&lt;/b&gt;". This template will contain the email to be sent to everyone.&lt;/li&gt;&lt;li&gt;We place emails we wish to reply to into a &lt;b&gt;specific category&lt;/b&gt;&lt;/li&gt;&lt;li&gt;We &lt;b&gt;create a rule&lt;/b&gt; that automatically sends the email template we created in 1) to all the senders of the emails we selected in 2)&lt;/li&gt;&lt;li&gt;We apply that rule and send out the emails.&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;All of the above four steps are extremely simple and require no technical skills. Read on.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Creating a message template&lt;/span&gt;&lt;/div&gt;&lt;div&gt;Follow the simple instructions given below.&amp;nbsp;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-YCB-lRxKWFE/Trjo2Y3PGbI/AAAAAAAADqU/Bc6JK8B4kz8/s1600/shittydiagram.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="248" src="http://1.bp.blogspot.com/-YCB-lRxKWFE/Trjo2Y3PGbI/AAAAAAAADqU/Bc6JK8B4kz8/s400/shittydiagram.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Instructions, as described on the image:&lt;/div&gt;&lt;div&gt;1) Write a regular email without a recipient&lt;/div&gt;&lt;div&gt;2) Click "Save As"...&lt;/div&gt;&lt;div&gt;3) Save it on your file system, making sure to select "&lt;b&gt;Outlook Template&lt;/b&gt;" as a file type ("Save as type...")&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Categorizing emails&lt;/span&gt;&lt;/div&gt;&lt;div&gt;The next step is to select the e-mails you want to reply to, and place them into a category.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-Tmzz0LD07ZA/Trjpr-gZA2I/AAAAAAAADqc/AF8h-jKkNeg/s1600/categorizing.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="175" src="http://4.bp.blogspot.com/-Tmzz0LD07ZA/Trjpr-gZA2I/AAAAAAAADqc/AF8h-jKkNeg/s400/categorizing.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;As you can see, all you have to do is:&lt;/div&gt;&lt;div&gt;1) Select some emails&lt;/div&gt;&lt;div&gt;2) Right-click on the selection&lt;/div&gt;&lt;div&gt;3) Unfold "&lt;b&gt;Categorize&lt;/b&gt;" and select a category, for example "Red Category".&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Creating a rule&lt;/span&gt;&lt;/div&gt;&lt;div&gt;This is the trickiest part so I'll write more detailed instructions.&amp;nbsp;Creating and managing rules is done from the "&lt;b&gt;Rules and Alerts&lt;/b&gt;" window. In order to access this window, on the main menu bar of Outlook 2007 go to "Tools" then "Rules and Alerts..."&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-bjNpV5L5z2I/Trjq27II-hI/AAAAAAAADqk/oewFoxjSis8/s1600/rulesandalerts.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="249" src="http://3.bp.blogspot.com/-bjNpV5L5z2I/Trjq27II-hI/AAAAAAAADqk/oewFoxjSis8/s320/rulesandalerts.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;To create the correct rule, follow the rule creation wizard which shows up&amp;nbsp;when you click the "New Rule" button:&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;&lt;i&gt;Selecting a Template&lt;/i&gt;. Under the "Start from a blank rule", select "Check messages when they arrive". Click next.&lt;/li&gt;&lt;li&gt;&lt;i&gt;Selecting Conditions&lt;/i&gt;. Locate the "Assigned to category category" item and check it. As you check the box, a new item appears in the rule description. Click the underlined word "category" to be able to select which category of emails should be replied to. Click next.&lt;/li&gt;&lt;li&gt;&lt;i&gt;Selecting Actions&lt;/i&gt;. Locate the option "Reply using a specific template" and check it. As you check the box, a new item appears in the rule description. Click the underlined part "a specific template", which will reveal the template selection window. At the top of this window, in the "Look in" drop-down list, select "User Templates in File System". Then you will be able to browse for the directory containing your template created in the first part of this tutorial. Once your template is selected correctly, click Next.&lt;/li&gt;&lt;li&gt;&lt;i&gt;Selecting Exceptions&lt;/i&gt;. If you want to exclude certain emails from getting replied to, select your conditions here. Click Next.&lt;/li&gt;&lt;li&gt;&lt;i&gt;Specify a name for your rule&lt;/i&gt;. Below the rule name input box, you will find two checkboxes: "&lt;b&gt;Run this rule now...&lt;/b&gt;" which you must enable; it will apply the rule to the folder currently selected in Outlook. Make sure to &lt;b&gt;disable&lt;/b&gt; the "&lt;b&gt;Turn on this rule&lt;/b&gt;" box, unless you want to automatically reply to similar messages in the future. Click Finish.&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;Upon clicking Finish, the rule will be applied: all the emails that you categorized will be replied to with the email template you selected previously.&amp;nbsp;Click "Send/Receive" to send out the emails.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Conclusion&lt;/span&gt;&lt;/div&gt;&lt;div&gt;Voila! Was it so hard? I don't believe so. But Microsoft should have made it a lot easier to reply to multiple emails, it seems to me that this is quite basic functionality and it should have been available from the start.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/512188703456595011-2866526238788839742?l=cnedelcu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cnedelcu.blogspot.com/feeds/2866526238788839742/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=512188703456595011&amp;postID=2866526238788839742' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/512188703456595011/posts/default/2866526238788839742'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/512188703456595011/posts/default/2866526238788839742'/><link rel='alternate' type='text/html' href='http://cnedelcu.blogspot.com/2011/11/outlook-2007-replying-to-multiple.html' title='Outlook 2007: replying to multiple emails or senders'/><author><name>Clément Nedelcu</name><uri>http://www.blogger.com/profile/00168228978102132365</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-ufhAwcauTyU/TrjkoJL-OyI/AAAAAAAADqM/NxX4C0PrWus/s72-c/screenshot1.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-512188703456595011.post-999333910225893129</id><published>2011-10-31T10:38:00.000+01:00</published><updated>2011-10-31T10:38:06.760+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='windows 7'/><category scheme='http://www.blogger.com/atom/ns#' term='old style logon screen'/><category scheme='http://www.blogger.com/atom/ns#' term='administration'/><title type='text'>Windows 7: restoring old-style logon screen tutorial</title><content type='html'>I've found a lot of information on the subject on various blogs and forums, strangely everyone seems to come to the conclusion that it is impossible to get back to the old style logon screen that appeared like this under Windows XP:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-qh11d5tz_pg/Tq5mQlPM8SI/AAAAAAAADoE/G2bwvdXJ91w/s1600/image38.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="202" src="http://1.bp.blogspot.com/-qh11d5tz_pg/Tq5mQlPM8SI/AAAAAAAADoE/G2bwvdXJ91w/s320/image38.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Why would anyone do this?&lt;/span&gt;&lt;br /&gt;Why would you go back to something like this? There could be thousands of reasons. The default logon screen of Windows 7 looks like this:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-z1DlbSa9L30/Tq5mwhWJHdI/AAAAAAAADoM/OaG8fmckUy0/s1600/banner4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="123" src="http://3.bp.blogspot.com/-z1DlbSa9L30/Tq5mwhWJHdI/AAAAAAAADoM/OaG8fmckUy0/s320/banner4.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;If, like me, you work in a computer-unfriendly environment such as a school, you'll find that a lot of people are unable to locate the "Switch user" button or simply wouldn't just dare to click it. All they were told is to enter their username and password and they never expected to have to do anything else.&lt;br /&gt;&lt;br /&gt;So how do you restore the good old logon screen with a simple text box for the user name, and a simple text box for the password? It's actually a lot simpler than some people would think.&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Local security policy management console&lt;/span&gt;&lt;br /&gt;Press Windows+R to get the "Run" dialog, and enter "secpol.msc" in the text box then click OK. You are opening up the Local security policy management console.&lt;br /&gt;In the option tree on the left, go to "Security Settings" / "Local Policies" / "Security options".&lt;br /&gt;In the list of settings on the right, locate "Interactive logon: Do not display last user name". Double click this setting and in the box that shows up, select "Enabled" and click OK. Restart your computer... and voila!&lt;br /&gt;You can also change a couple of other settings, such as disabling the annoying "Ctrl+alt+del" screen, the option right below the one I just described.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-CHqROpZuyOg/Tq5pa6NiyHI/AAAAAAAADoc/BA5QbeMRL1E/s1600/secpol.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="175" src="http://2.bp.blogspot.com/-CHqROpZuyOg/Tq5pa6NiyHI/AAAAAAAADoc/BA5QbeMRL1E/s320/secpol.PNG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Once you're all done you'll be seeing a screen like this when you start up your computer. If you didn't join a domain obviously you won't be seeing the domain part.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-vhdSBPygkrM/Tq5r0H_YW9I/AAAAAAAADok/xpUhoEO6Fr4/s1600/windows7oldstylelogonscreen.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="256" src="http://2.bp.blogspot.com/-vhdSBPygkrM/Tq5r0H_YW9I/AAAAAAAADok/xpUhoEO6Fr4/s320/windows7oldstylelogonscreen.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/512188703456595011-999333910225893129?l=cnedelcu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cnedelcu.blogspot.com/feeds/999333910225893129/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=512188703456595011&amp;postID=999333910225893129' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/512188703456595011/posts/default/999333910225893129'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/512188703456595011/posts/default/999333910225893129'/><link rel='alternate' type='text/html' href='http://cnedelcu.blogspot.com/2011/10/windows-7-restoring-old-style-logon.html' title='Windows 7: restoring old-style logon screen tutorial'/><author><name>Clément Nedelcu</name><uri>http://www.blogger.com/profile/00168228978102132365</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-qh11d5tz_pg/Tq5mQlPM8SI/AAAAAAAADoE/G2bwvdXJ91w/s72-c/image38.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-512188703456595011.post-1797334847996831268</id><published>2011-10-25T06:33:00.000+02:00</published><updated>2011-10-31T10:38:51.371+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='server'/><category scheme='http://www.blogger.com/atom/ns#' term='configuration'/><category scheme='http://www.blogger.com/atom/ns#' term='nginx'/><category scheme='http://www.blogger.com/atom/ns#' term='administration'/><category scheme='http://www.blogger.com/atom/ns#' term='book'/><title type='text'>Nginx market share soon to hit 10% mark</title><content type='html'>According to multiple sources such as:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;NetCraft's &lt;a href="http://news.netcraft.com/archives/2011/07/08/july-2011-web-server-survey.html"&gt;July 2011 Web Server survey&lt;/a&gt;&lt;/li&gt;&lt;li&gt;W3tech's &lt;a href="http://w3techs.com/technologies/details/ws-nginx/all/all"&gt;Web server usage statistics&lt;/a&gt; as of October 25&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;the amazing and lightning-fast web server known as &lt;b&gt;nginx&lt;/b&gt; is just about to hit the 10% market share mark in the next couple of months. This is a fantastic milestone for the author, &lt;a href="http://nginx.net/"&gt;Igor Sysoev&lt;/a&gt;, who probably didn't imagine that the application (which he originally developed on his own) would meet such fame.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-8y-5OnKZXQI/TqY12iwxydI/AAAAAAAADbg/vB2mzlJCdVY/s1600/ws-nginx.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="266" src="http://3.bp.blogspot.com/-8y-5OnKZXQI/TqY12iwxydI/AAAAAAAADbg/vB2mzlJCdVY/s400/ws-nginx.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;Diagram courtesy of W3Techs.com (article linked above). Its market share went from a little over 5% to almost 10% over the last year as you can see.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://www.amazon.com/Nginx-HTTP-Server-Cl%C3%A9ment-Nedelcu/dp/1849510865" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/-1_R_xZJuqyA/TqY5EFGp_8I/AAAAAAAADbo/wQFJCQB-KDE/s1600/72164853.JPG" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;I wouldn't go so far as to say that the release of my &lt;a href="http://www.amazon.com/Nginx-HTTP-Server-Cl%C3%A9ment-Nedelcu/dp/1849510865"&gt;Nginx HTTP Server book&lt;/a&gt;&amp;nbsp;(released Summer 2010) was one of the factors that contributed to the popularity of the Russian web server. It is my belief that the sole quality and efficiency of the software is what made its success.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The book was and is being translated into three languages:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;In &lt;a href="http://www.amazon.co.jp/%E3%83%8F%E3%82%A4%E3%83%91%E3%83%95%E3%82%A9%E3%83%BC%E3%83%9E%E3%83%B3%E3%82%B9HTTP%E3%82%B5%E3%83%BC%E3%83%90-Nginx%E5%85%A5%E9%96%80-Clement-Nedelcu/dp/4048702270"&gt;Japanese&lt;/a&gt;&lt;/li&gt;&lt;li&gt;In Chinese (to be published soon)&lt;/li&gt;&lt;li&gt;In Korean (release date unknown)&amp;nbsp;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;Nginx is already a popular web server in Russia and Asia; some of the most popular websites in these regions are powered by nginx; namely Yandex, 163 (China's #1 e-mail platform), Soso.com, Renren.com, and more internationally Wordpress, among many others. My own websites &lt;a href="http://gbatemp.net/"&gt;GBAtemp.net&lt;/a&gt;, &lt;a href="http://filetrip.net/"&gt;FileTrip.net&lt;/a&gt;, &lt;a href="http://shoptemp.net/"&gt;ShopTemp.net&lt;/a&gt; are powered by nginx as well.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/512188703456595011-1797334847996831268?l=cnedelcu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cnedelcu.blogspot.com/feeds/1797334847996831268/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=512188703456595011&amp;postID=1797334847996831268' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/512188703456595011/posts/default/1797334847996831268'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/512188703456595011/posts/default/1797334847996831268'/><link rel='alternate' type='text/html' href='http://cnedelcu.blogspot.com/2011/10/nginx-market-share-soon-to-hit-10-mark.html' title='Nginx market share soon to hit 10% mark'/><author><name>Clément Nedelcu</name><uri>http://www.blogger.com/profile/00168228978102132365</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-8y-5OnKZXQI/TqY12iwxydI/AAAAAAAADbg/vB2mzlJCdVY/s72-c/ws-nginx.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-512188703456595011.post-2557838362444563790</id><published>2011-10-13T06:27:00.000+02:00</published><updated>2011-10-13T06:27:08.015+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pptp vpn ios pptpd poptop problem fix'/><title type='text'>PPTP server fix for iOS problems (pptpd/PopTop)</title><content type='html'>Ever since I was offered an iPod touch 4th gen I have been unsuccessful in my attempts to connect to &lt;b&gt;PPTP based VPN servers from iOS&lt;/b&gt;. Apparently this is &lt;a href="https://discussions.apple.com/thread/2778039?start=60&amp;amp;tstart=0"&gt;a well known issue since iOS 4.3.3&lt;/a&gt; or earlier, that did not get fixed in the iOS 5 update.&lt;br /&gt;&lt;br /&gt;Having set up my own PPTP-based VPN servers using &lt;b&gt;Poptop&lt;/b&gt; (also known as &lt;b&gt;pptpd&lt;/b&gt;) under CentOS, I always found it strange that my servers would function perfectly fine under all versions of Windows, but completely refuse to work under iOS and reportedly MacOS X as well.&lt;br /&gt;&lt;br /&gt;Symptoms were the following:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Initially, the connection to the server starts ("Connecting... Starting... Authenticating... ") and appears successful for a second but then immediately drops, with a vague error message.&lt;/li&gt;&lt;li&gt;After &lt;a href="http://www.dd-wrt.com/wiki/index.php/PPTP_Server_Configuration#iOS_4.3"&gt;a few tweaks&lt;/a&gt; that I read on DD-WRT's PPTP server configuration page (pertinent given that DD-WRT uses poptop as well) the situation changed but still failed to solve all of my problems: I was able to connect normally, without any error message, however any network communication failed and timed out. Whenever I tried loading a page it would just keep loading forever. Any app that connects to the Internet did the same- loading forever.&lt;/li&gt;&lt;/ul&gt;&amp;nbsp;Finally after a combination of multiple tweaks I finally got it to work! The solution is given below but I'd like to credit people first. First I used the &lt;a href="http://www.dd-wrt.com/wiki/index.php/PPTP_Server_Configuration#iOS_4.3"&gt;DD-WRT tweaks&lt;/a&gt; as I previously said, then I followed the tips of two users who posted on &lt;a href="https://discussions.apple.com/thread/2778039?start=105&amp;amp;tstart=0"&gt;this page&lt;/a&gt;, sid2 and jeremy207. Massive thanks to both of them!&lt;br /&gt;&lt;br /&gt;Here's what got it to work for me. You need to open up the options file for pptpd usually located here: &lt;b&gt;/etc/ppp/options.pptpd&lt;/b&gt;&lt;br /&gt;At the very bottom of the file, insert the following lines:&lt;br /&gt;&lt;blockquote style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;nopcomp&lt;br /&gt;noaccomp&lt;br /&gt;mtu 1400&lt;br /&gt;mru 1400&lt;br /&gt;default-asyncmap&lt;/blockquote&gt;After saving the file, make sure to restart pptpd properly (I stopped it and started it again completely) and try connecting from iOS again. Worked for me! Hope it will for you as well.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/512188703456595011-2557838362444563790?l=cnedelcu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cnedelcu.blogspot.com/feeds/2557838362444563790/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=512188703456595011&amp;postID=2557838362444563790' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/512188703456595011/posts/default/2557838362444563790'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/512188703456595011/posts/default/2557838362444563790'/><link rel='alternate' type='text/html' href='http://cnedelcu.blogspot.com/2011/10/pptp-server-fix-for-ios-problems.html' title='PPTP server fix for iOS problems (pptpd/PopTop)'/><author><name>Clément Nedelcu</name><uri>http://www.blogger.com/profile/00168228978102132365</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-512188703456595011.post-1493997668305889766</id><published>2011-09-02T06:37:00.000+02:00</published><updated>2011-09-02T06:37:55.031+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ripoff'/><category scheme='http://www.blogger.com/atom/ns#' term='paypal'/><category scheme='http://www.blogger.com/atom/ns#' term='dispute'/><category scheme='http://www.blogger.com/atom/ns#' term='alternative'/><title type='text'>How Paypal rips off online businesses</title><content type='html'>Paypal has just "resolved" a dispute that a customer filed against our small-scale online business and I am absolutely disgusted by the outcome. Not because of the amount that they've stolen from us (11.25€, we will survive without it), but for what it represents and the inherent risks. I should never have been charged that fee. Let me explain.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;A regular purchase?&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;A few months ago a customer purchased the most expensive VPN plan (72€) on my website VPN1Euro.com. The account was immediately set up, and the customer started using it. A few months later, the customer requested a full refund for the payment (through an automated Paypal dispute), without contacting me prior to sending the request to Paypal. I responded to the dispute by telling the entire truth:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;the customer purchased the account legimitately (IP address matches the location entered in the Paypal billing address, nothing indicates that there was some kind of Paypal account fraud)&lt;/li&gt;&lt;li&gt;the customer used the account for a while&lt;/li&gt;&lt;li&gt;the customer never contacted our services to request anything&lt;/li&gt;&lt;li&gt;we offer refunds on prorated basis. Basically if you purchase a 1-year plan, you can get a refund after a while. But if you've already used your account for 2 months, you'll only be refund of the remaining 10 months (why would anyone refund a service that has been duely consumed?). That's what happened here. Had the customer contacted us to obtain a refund we would have sent it without question.&lt;/li&gt;&lt;/ul&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;Buyers abusing the system&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;From the moment the customer filed the dispute, Paypal froze the money (the whole 72€). I replied immediately, but it took over 3 weeks for Paypal to process my response. The outcome was just unveiled to me today: not only the customer is getting ALL of their money back, but I am ALSO being charged for a complementary fee called "settlement fee".&lt;br /&gt;&lt;br /&gt;So let's summarize what happened here:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;customer purchases expensive VPN plan&lt;/li&gt;&lt;li&gt;customer makes use of VPN plan&lt;/li&gt;&lt;li&gt;two months later, customer gets all of their money back&lt;/li&gt;&lt;li&gt;seller pays an additional 11.25€&lt;/li&gt;&lt;/ul&gt;Not only have we provided the service correctly, but we are also being charged for the payment reversal! This is completely absurd and Paypal won't budge on the matter.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;A flawed system&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;With such a system any ill-intended customer can just purchase anything, THEN get their money back, THEN have the seller charged for, well, whatever we're being charged for ("settlement fee"). So I'll say it again: the amount lost in this case is obviously neglectable. But what if it happens again? We haven't receive a single cent for a service that was correctly provided, and we've also been charged for it. What can businesses do against such malpractices? The only answer I'm thinking of right now is: &lt;b&gt;don't use Paypal&lt;/b&gt;. As if the 4.5% transaction fees weren't enough, they're now stealing money from us. That's great.&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/512188703456595011-1493997668305889766?l=cnedelcu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cnedelcu.blogspot.com/feeds/1493997668305889766/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=512188703456595011&amp;postID=1493997668305889766' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/512188703456595011/posts/default/1493997668305889766'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/512188703456595011/posts/default/1493997668305889766'/><link rel='alternate' type='text/html' href='http://cnedelcu.blogspot.com/2011/09/how-paypal-rips-off-online-businesses.html' title='How Paypal rips off online businesses'/><author><name>Clément Nedelcu</name><uri>http://www.blogger.com/profile/00168228978102132365</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-512188703456595011.post-2004309252734559364</id><published>2011-05-19T12:40:00.000+02:00</published><updated>2011-05-19T12:40:32.428+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='china great firewall'/><category scheme='http://www.blogger.com/atom/ns#' term='vpn'/><title type='text'>China upgrades its Great Firewall to regulate VPNs</title><content type='html'>&lt;div style="text-align: justify;"&gt;I have lived in China for two years now and I must say I am absolutely disgusted by the &lt;b&gt;new censorship measures&lt;/b&gt; enforced by the Chinese government. Especially this new one.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Here's how the story begins. Late April, before the Easter holidays, I was still enjoying live TV streaming from french channels through my regular VPN. It wasn't too fast but good enough to stream correctly without much buffering. When I got back from holiday early May, I noticed that all my VPNs still worked but the&lt;b&gt; speed had become incredibly bad&lt;/b&gt;, I could barely access websites - let alone stream live video. I thought it would be temporary or that maybe peering between China Telecom and Europe was saturated.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;But it got worse. At work (I work at a foreign school) ever since I got back from holiday, &lt;b&gt;our connection would get shut down every now and then&lt;/b&gt;. Nearly every single foreign website (most IP addresses outside of China) would be unreachable for hours. We decided to investigate the issue with our ISP, China Telecom. Unfortunately, it turns out that the reason our connection gets blocked is because the Great Firewall detected that some people in our school were using VPNs. &lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;a href="http://1.bp.blogspot.com/-hg9itmOa4sA/TdTwr030a2I/AAAAAAAACwM/DqE1-zX1VLc/s1600/thumbs_down.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="149" src="http://1.bp.blogspot.com/-hg9itmOa4sA/TdTwr030a2I/AAAAAAAACwM/DqE1-zX1VLc/s320/thumbs_down.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Today I got to talk with some China Telecom employee (#1 Internet Service Provider in China) and he informed me of the new measures taken by the government to enforce the Internet censorship laws. Here is a summary of the points that I remember hearing from the guy:&lt;/div&gt;&lt;ul style="text-align: justify;"&gt;&lt;li&gt;the GFW as they call it (GFW for Great FireWall) &lt;b&gt;is controlled by the government up there&lt;/b&gt; in Beijing, China Telecom themselves can't do anything about it. All Internet traffic goes through the firewall.&lt;/li&gt;&lt;li&gt;&lt;b&gt;they recently upgraded their systems&lt;/b&gt; to take further action to enforce Internet censorship law... sometime between late April and early May.&lt;/li&gt;&lt;li&gt;&lt;b&gt;previously, their systems only enforced a "black list"&lt;/b&gt; kind of censorship. They kept a massive list of blocked domains, IP address, keywords, and so on.&lt;/li&gt;&lt;li&gt;since the upgrade, they are able to modify routing tables in order to actually &lt;b&gt;prevent any communication with foreign IP addresses&lt;/b&gt; when they detect usage of a VPN.&lt;/li&gt;&lt;li&gt;both campuses of our school are having the same issue, even though they are in completely different areas. It is reported that other businesses/offices/organizations are experiencing the same issue as of late.&lt;/li&gt;&lt;li&gt;when it comes to the general consumer, when usage of VPN is detected, &lt;b&gt;bandwidth gets severely capped&lt;/b&gt;. I have no idea how they proceed, but anyhow that's what the China Telecom dude said.&lt;/li&gt;&lt;/ul&gt;&lt;div style="text-align: justify;"&gt;&amp;nbsp;Are you experiencing issues too? I would like to get additional information and testimonies from people all over China. While I am reporting pretty much exactly what the guy said, it could have been bullshit from China Telecom trying to clear their name seeing as &lt;a href="http://shanghaiist.com/2011/01/21/shanghai_home_to_the_slowest_intern.php"&gt;Internet in Shanghai is crappy&lt;/a&gt;.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;As a reminder, the Chinese censorship completely disable access to the following websites (including all related services): Facebook, Youtube, Dailymotion, Twitter, any form of video streaming hosted outside of China, any form of pornographic content, random searches on the Internet, global news websites from mainstream media, and so much more.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;I don't know what they are trying to achieve with this. There will always be ways to bypass the "great firewall", network technology always adapts itself. Tunnelling can be done in all sorts of ways, no matter the port, no matter the protocol, no matter the IP address, no matter the encryption method... &lt;b style="color: red;"&gt;tunnelling is merely a principle, a concept that they will never be able to block fully&lt;/b&gt;. They're just making it a lot less convenient right now, and the speed's worse than before... but still doesn't prevent anyone from accessing blocked sites.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/512188703456595011-2004309252734559364?l=cnedelcu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cnedelcu.blogspot.com/feeds/2004309252734559364/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=512188703456595011&amp;postID=2004309252734559364' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/512188703456595011/posts/default/2004309252734559364'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/512188703456595011/posts/default/2004309252734559364'/><link rel='alternate' type='text/html' href='http://cnedelcu.blogspot.com/2011/05/china-upgrades-its-great-firewall-to.html' title='China upgrades its Great Firewall to regulate VPNs'/><author><name>Clément Nedelcu</name><uri>http://www.blogger.com/profile/00168228978102132365</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-hg9itmOa4sA/TdTwr030a2I/AAAAAAAACwM/DqE1-zX1VLc/s72-c/thumbs_down.jpg' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-512188703456595011.post-9038823122728557157</id><published>2010-12-13T10:27:00.000+01:00</published><updated>2010-12-13T10:27:58.337+01:00</updated><title type='text'>Affiliate module for Interspire Shopping Cart</title><content type='html'>Hello,&lt;br /&gt;I have already implemented this module on two shops rather successfully. The concept is quite simple:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;websites that want to get rewarded through affiliation must link to your website using an identifier in the URL. If your website is http://website.com/, then your links must be of the form http://website.com/?ref=123 where 123 is the affiliate ID.&lt;/li&gt;&lt;li&gt;when a visitor clicks the link, the affiliate ID will be placed in a cookie that will expire after 15 days (this can be configured)&lt;/li&gt;&lt;li&gt;when the visitor purchases an item: if the affiliate ID cookie is still enabled, the affiliate will be credited of a certain amount, it can be a share of the sale or a fixed amount.&lt;/li&gt;&lt;li&gt;affiliate accounts are simple customer accounts, there is no modification to make regarding accounts. When a sale is made, they receive store credit. They can either spend the store credit to purchase items on the store, or they can manually request for a withdrawal (managing withdrawals is up to you).&lt;/li&gt;&lt;/ul&gt;I will detail the implementation of this module. It's actually quite simple. You will need:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;a tiny modification of the orders SQL table if you want to log individual sales&lt;/li&gt;&lt;li&gt;modifications in a few of the PHP scripts of Interspire Shopping Cart&lt;/li&gt;&lt;li&gt;an additional PHP script that I have provided for download.&lt;/li&gt;&lt;/ul&gt;Finally I have to mention that I have only applied this on Interspire Shopping Cart 5.x, I've never used it on Interspire Shopping Cart 6 but I don't see any reason why this wouldn't work. You can just try it out and revert the changes if it doesn't work.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Download and install the PHP module&lt;/h3&gt;&lt;a href="http://gbatemp.net/up/affiliate.php.zip"&gt;Download the module called affiliate.php&lt;/a&gt;. You need to place it in the &lt;span style="color: #660000;"&gt;/lib/&lt;/span&gt; folder of your website. You then need to include the module into Interspire Shopping Cart. To do so, open the /init.php which is at the root of your website. At the end of the file, add this line:&lt;br /&gt;&lt;br /&gt;&lt;div style="color: #660000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;require_once(dirname(__FILE__).'/lib/affiliate.php');&lt;/div&gt;&lt;br /&gt;&lt;h3&gt;Modification of the SQL table&lt;/h3&gt;Begin by modifying the orders SQL table that will allow us to log the sales made by affiliates. The modification is very small and it will NOT affect anything in your store. It will not break anything so don't be worried about it. I've done it multiple times like I said. You need to add a single field at the end of the table: "ordaffiliate". It's an "int" field with a size of at least 10. It will be used to hold the ID of the affiliate who got the sale.&lt;br /&gt;&lt;br /&gt;&lt;div style="color: #660000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;ALTER TABLE `isc_orders` ADD `ordaffiliate` INT( 11 ) NOT NULL COMMENT 'ID of the affiliate who got the sale'&lt;/div&gt;&lt;br /&gt;&lt;h3&gt;Logging sales properly&lt;/h3&gt;Next step is: when someone places an order on the website, we need to store the affiliate ID in the "ordaffiliate" field of the order, and also credit the affiliate for the sale. Open the /includes/class/class.checkout.php file. Find this text in the source code: "$pendingOrder = array" it is not a complete line but you should only get one result.&lt;br /&gt;Before the end of the array, in other words before the &lt;span style="color: #660000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;);&lt;/span&gt;&amp;nbsp; add this line:&lt;br /&gt;&lt;div style="color: #660000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; 'ordaffiliate' =&amp;gt; isset($_COOKIE["ref"]) ? intval($_COOKIE["ref"]) : "0",&lt;/div&gt;What it does is it checks if the "ref" cookie is set; if it's set then it will save its value in the database. If it's not set it just stores 0. NOTE: if you insert this line as the last line of the array, don't forget to add a comma to the line above! Like this:&lt;br /&gt;&lt;div style="color: #660000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; 'ordstatus' =&amp;gt; $orderStatus&lt;span style="color: red; font-size: x-large;"&gt;,&lt;/span&gt;&lt;/div&gt;&lt;div style="color: #660000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; 'ordaffiliate' =&amp;gt; isset($_COOKIE["ref"]) ? intval($_COOKIE["ref"]) : "0"&lt;/div&gt;&lt;div style="color: #660000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; );&lt;/div&gt;&lt;br /&gt;Another modification must be applied to this file: /lib/entities/entity.order.php&lt;br /&gt;When you open it, you will see a massive array of strings like this:&lt;br /&gt;&lt;div style="color: #660000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; $schema = array(&lt;/div&gt;&lt;div style="color: #660000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; "orderid" =&amp;gt; "int",&lt;/div&gt;&lt;div style="color: #660000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; "ordtoken" =&amp;gt; "text",&lt;/div&gt;...&lt;br /&gt;Anywhere in the array, add this line:&lt;br /&gt;&lt;div style="color: #660000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; "ordaffiliate" =&amp;gt; "int",&lt;/div&gt;&lt;br /&gt;Once that is done, you can get to the next step...&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Giving affiliate credit at the right time&lt;/h3&gt;You don't want to be giving affiliate credit when someone hasn't paid for their order yet. So we'll only give the credit when the sale is complete. Open /lib/orders.php and find this function: &lt;span style="color: #660000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;function UpdateOrderStatus&lt;/span&gt;.&lt;br /&gt;Scroll down in the function until you find this:&lt;br /&gt;&lt;div style="color: #660000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (OrderIsComplete($status)) {&lt;/div&gt;&lt;div style="color: #660000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;$updatedOrder['orddateshipped'] = time();&lt;/div&gt;&lt;div style="color: #660000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/div&gt;&lt;br /&gt;We are going to change this block a bit and replace it by this:&lt;br /&gt;&lt;div style="color: #660000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (OrderIsComplete($status)) {&lt;/div&gt;&lt;div style="color: #660000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; $updatedOrder['orddateshipped'] = time();&lt;/div&gt;&lt;div style="color: #660000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // Give affiliate credit!&lt;/div&gt;&lt;div style="color: #660000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; require_once("affiliate.php");&lt;/div&gt;&lt;div style="color: #660000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if ($order['ordaffiliate'])&lt;/div&gt;&lt;div style="color: #660000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; GiveAffiliateCredit($order);&lt;/div&gt;&lt;div style="color: #660000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/div&gt;&lt;br /&gt;We call the "GiveAffiliateCredit" function only if the order is complete/shipped, and if the order has an affiliate ID defined.&lt;br /&gt;&lt;br /&gt;At this point the module is functional. Affiliates will receive store credit for the sales they make. Now what you would like is to allow your affiliates to visualize the sales they have made! We're going to need another modification...&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Integrating an "affiliate account" link on the account page&lt;/h3&gt;The first modification that you have to make will be in the HTML templates of your store design. Open your Admin control panel, and click the "Store design" link at the top right of the page. On the Store Design page, click the "Browse Template Files..." button. Open the "account.html" page by clicking it in the menu on the left. In the account.html page you will find a bullet list (&amp;lt;ul&amp;gt; ... &amp;lt;/ul&amp;gt;) corresponding to the links from the account page. Add a new item in the bullet list (&amp;lt;li&amp;gt; tag) like this:&lt;br /&gt;&lt;br /&gt;&lt;div style="color: #660000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;lt;li&amp;gt;&amp;lt;a href='account.php?action=affiliate#affiliate' title='Manage my affiliate account'&amp;gt;Affiliate account&amp;lt;/a&amp;gt; - Manage your affiliate account and view your sales&amp;lt;/li&amp;gt;&lt;/div&gt;&lt;br /&gt;There is another modification you need to make. After the &amp;lt;/ul&amp;gt; tag, add this little bit:&lt;br /&gt;&lt;br /&gt;&lt;div style="color: #660000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;%%GLOBAL_AffiliateAccount%%&lt;/div&gt;&lt;br /&gt;Save the template and close the window. We are now going to create that affiliate page.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;The Affiliate Account page&lt;/h3&gt;At this point if you click the link "Affiliate account" that you have inserted on the account page, it won't take you anywhere. It just takes you back to the regular account page. We need to edit the /includes/classes/class.account.php file and make the following modification:&lt;br /&gt;&lt;br /&gt;Find the line where it says "switch ($action)" there should be only one in this file&lt;br /&gt;Right below this line, add the following code:&lt;br /&gt;&lt;div style="color: #660000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; case "affiliate": {&lt;/div&gt;&lt;div style="color: #660000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; DisplayAffiliateAccountPage();&lt;/div&gt;&lt;div style="color: #660000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; $this-&amp;gt;MyAccountPage();&lt;/div&gt;&lt;div style="color: #660000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; break;&lt;/div&gt;&lt;div style="color: #660000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/div&gt;&lt;br /&gt;To ensure that it works correctly, go to your account page and click the "Affiliate account" link. Here is a screenshot of the Affiliate Account section on the "My Account" page, with one affiliate sale.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_Ixt0VU0h5eU/TQXkb8-nTHI/AAAAAAAACbQ/XQ3dO2aIdwo/s1600/affiliate_module_screenshot.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="232" src="http://3.bp.blogspot.com/_Ixt0VU0h5eU/TQXkb8-nTHI/AAAAAAAACbQ/XQ3dO2aIdwo/s400/affiliate_module_screenshot.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Configuring the module&lt;/h3&gt;If you open the affiliate.php file that I've provided before, you will find interesting configuration settings at the beginning of the file.&lt;br /&gt;&lt;span style="color: #660000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;define( "AFFILIATE_ENABLED", &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; true ); &amp;nbsp;&amp;nbsp;&amp;nbsp; // enable or disable the affiliate module&lt;/span&gt;&lt;br /&gt;&lt;br style="color: #660000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="color: #660000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;define( "AFFILIATE_COOKIE_DURATION", &amp;nbsp;&amp;nbsp;&amp;nbsp; 14); &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // how many days should the affiliate cookie remain active?&lt;/span&gt;&lt;br style="color: #660000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="color: #660000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #660000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;define( "AFFILIATE_COMMISSION", &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; 5 / 100); &amp;nbsp;&amp;nbsp;&amp;nbsp; // commission that affiliates make when a sale is made. Here it's 5%&lt;/span&gt;&lt;br style="color: #660000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="color: #660000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #660000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;define( "AFFILIATE_FIXED_AMOUNT",&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; 10);&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // if you want to use a fixed amount IN ADDITION TO THE COMMISSION, define the amount here.&lt;/span&gt;&lt;br style="color: #660000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="color: #660000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #660000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;define( "AFFILIATE_REASON", "AFFILIATE-CASHBACK"); &amp;nbsp;&amp;nbsp;&amp;nbsp; // When an order is made, an entry in the "customer_credit" table is added. This is the credit "reason". If you change this after some sales were made, the sales won't be listed (see DisplayAffiliateAccountPage function below)&lt;/span&gt;&lt;br style="color: #660000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="color: #660000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #660000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;define( "AFFILIATE_SELF_AFFILIATE", &amp;nbsp;&amp;nbsp;&amp;nbsp; true);&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // If the affiliate account is the same as the customer account (the customer is the affiliate) do we credit the affiliate account?&lt;/span&gt;&lt;br style="color: #660000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="color: #660000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #660000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;define( "AFFILIATE_INCLUDE_SHIPPING", &amp;nbsp;&amp;nbsp;&amp;nbsp; false); &amp;nbsp;&amp;nbsp;&amp;nbsp; // Include shipping costs in the commission calculation?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Feel free to change the value of each setting according to the affiliate policy you want to implement.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;That's it! Your affiliate module is fully ready and functional.&lt;br /&gt;Clem&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/512188703456595011-9038823122728557157?l=cnedelcu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cnedelcu.blogspot.com/feeds/9038823122728557157/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=512188703456595011&amp;postID=9038823122728557157' title='14 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/512188703456595011/posts/default/9038823122728557157'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/512188703456595011/posts/default/9038823122728557157'/><link rel='alternate' type='text/html' href='http://cnedelcu.blogspot.com/2010/12/affiliate-module-for-interspire.html' title='Affiliate module for Interspire Shopping Cart'/><author><name>Clément Nedelcu</name><uri>http://www.blogger.com/profile/00168228978102132365</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_Ixt0VU0h5eU/TQXkb8-nTHI/AAAAAAAACbQ/XQ3dO2aIdwo/s72-c/affiliate_module_screenshot.jpg' height='72' width='72'/><thr:total>14</thr:total></entry><entry><id>tag:blogger.com,1999:blog-512188703456595011.post-1018976536224083574</id><published>2010-12-12T10:44:00.000+01:00</published><updated>2010-12-12T10:44:06.464+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='vpn1euro'/><category scheme='http://www.blogger.com/atom/ns#' term='vpn'/><title type='text'>Get a VPN account for just 1€ a month</title><content type='html'>What is a VPN?&lt;br /&gt;&lt;div class="CategoryDescription"&gt;               &lt;blockquote&gt;A virtual private network (&lt;strong&gt;VPN&lt;/strong&gt;) is a computer  network that uses a public telecommunication infrastructure such as the  Internet&amp;nbsp; to provide remote offices or individual users with secure  access to their organization's network. It aims to avoid an expensive  system of owned or leased lines that can be used by only one  organization. It encapsulates data transfers between two or more  networked devices which are not on the same private network so as to  keep the transferred data private from other devices on one or more  intervening local or wide area networks. There are many different  classifications, implementations, and uses for VPNs.&lt;/blockquote&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://www.vpn1euro.com/"&gt;&lt;img border="0" height="64" src="http://www.vpn1euro.com/product_images/uploaded_images/vpnbanner.png" width="320" /&gt;&lt;/a&gt;&amp;nbsp;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;VPN1EURO.com provides &lt;a href="http://www.vpn1euro.com/categories/VPN-Accounts/VPN-Premium-1%E2%82%AC/"&gt;VPN accounts&lt;/a&gt; for prices starting at 1€ per month. This is probably the best deal on the web when it comes to ad-free and reliable VPNs!&lt;br /&gt;&lt;br /&gt;Check out those &lt;a href="http://www.vpn1euro.com/categories/VPN-Accounts/VPN-Premium-1%E2%82%AC/"&gt;VPN accounts for 1€&lt;/a&gt; at &lt;a href="http://www.vpn1euro.com/"&gt;VPN1EURO Internet Services&lt;/a&gt;! You will be getting an account on a fast, secure and reliable server and  enjoy all the benefits offered by their centralized gateway. You can  upgrade to VPN Gold Services at any time by contacting their customer  support.&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/512188703456595011-1018976536224083574?l=cnedelcu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cnedelcu.blogspot.com/feeds/1018976536224083574/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=512188703456595011&amp;postID=1018976536224083574' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/512188703456595011/posts/default/1018976536224083574'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/512188703456595011/posts/default/1018976536224083574'/><link rel='alternate' type='text/html' href='http://cnedelcu.blogspot.com/2010/12/get-vpn-account-for-just-1-month.html' title='Get a VPN account for just 1€ a month'/><author><name>Clément Nedelcu</name><uri>http://www.blogger.com/profile/00168228978102132365</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-512188703456595011.post-2665321256979194577</id><published>2010-12-11T17:49:00.000+01:00</published><updated>2010-12-11T17:49:01.899+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='nginx'/><category scheme='http://www.blogger.com/atom/ns#' term='plesk'/><title type='text'>Nginx support for Plesk: my offer to Parallels</title><content type='html'>&lt;!--[if gte mso 9]&gt;&lt;xml&gt;  &lt;w:WordDocument&gt;   &lt;w:View&gt;Normal&lt;/w:View&gt;   &lt;w:Zoom&gt;0&lt;/w:Zoom&gt;   &lt;w:TrackMoves/&gt;   &lt;w:TrackFormatting/&gt;   &lt;w:HyphenationZone&gt;21&lt;/w:HyphenationZone&gt;   &lt;w:PunctuationKerning/&gt;   &lt;w:ValidateAgainstSchemas/&gt;   &lt;w:SaveIfXMLInvalid&gt;false&lt;/w:SaveIfXMLInvalid&gt;   &lt;w:IgnoreMixedContent&gt;false&lt;/w:IgnoreMixedContent&gt;   &lt;w:AlwaysShowPlaceholderText&gt;false&lt;/w:AlwaysShowPlaceholderText&gt;   &lt;w:DoNotPromoteQF/&gt;   &lt;w:LidThemeOther&gt;FR&lt;/w:LidThemeOther&gt;   &lt;w:LidThemeAsian&gt;ZH-CN&lt;/w:LidThemeAsian&gt;   &lt;w:LidThemeComplexScript&gt;X-NONE&lt;/w:LidThemeComplexScript&gt;   &lt;w:Compatibility&gt;    &lt;w:BreakWrappedTables/&gt;    &lt;w:SnapToGridInCell/&gt;    &lt;w:WrapTextWithPunct/&gt;    &lt;w:UseAsianBreakRules/&gt;    &lt;w:DontGrowAutofit/&gt;    &lt;w:SplitPgBreakAndParaMark/&gt;    &lt;w:DontVertAlignCellWithSp/&gt;    &lt;w:DontBreakConstrainedForcedTables/&gt;    &lt;w:DontVertAlignInTxbx/&gt;    &lt;w:Word11KerningPairs/&gt;    &lt;w:CachedColBalance/&gt;    &lt;w:UseFELayout/&gt;   &lt;/w:Compatibility&gt;   &lt;w:BrowserLevel&gt;MicrosoftInternetExplorer4&lt;/w:BrowserLevel&gt;   &lt;m:mathPr&gt;    &lt;m:mathFont m:val="Cambria Math"/&gt;    &lt;m:brkBin m:val="before"/&gt;    &lt;m:brkBinSub m:val="&amp;#45;-"/&gt;    &lt;m:smallFrac m:val="off"/&gt;    &lt;m:dispDef/&gt;    &lt;m:lMargin m:val="0"/&gt;    &lt;m:rMargin m:val="0"/&gt;    &lt;m:defJc m:val="centerGroup"/&gt;    &lt;m:wrapIndent m:val="1440"/&gt;    &lt;m:intLim m:val="subSup"/&gt;    &lt;m:naryLim m:val="undOvr"/&gt;   &lt;/m:mathPr&gt;&lt;/w:WordDocument&gt; &lt;/xml&gt;&lt;![endif]--&gt;&lt;!--[if gte mso 9]&gt;&lt;xml&gt;  &lt;w:LatentStyles DefLockedState="false" DefUnhideWhenUsed="true"  DefSemiHidden="true" DefQFormat="false" DefPriority="99"  LatentStyleCount="267"&gt;   &lt;w:LsdException Locked="false" Priority="0" SemiHidden="false"   UnhideWhenUsed="false" QFormat="true" Name="Normal"/&gt;   &lt;w:LsdException Locked="false" Priority="9" SemiHidden="false"   UnhideWhenUsed="false" QFormat="true" Name="heading 1"/&gt;   &lt;w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 2"/&gt;   &lt;w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 3"/&gt;   &lt;w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 4"/&gt;   &lt;w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 5"/&gt;   &lt;w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 6"/&gt;   &lt;w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 7"/&gt;   &lt;w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 8"/&gt;   &lt;w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 9"/&gt;   &lt;w:LsdException Locked="false" Priority="39" Name="toc 1"/&gt;   &lt;w:LsdException Locked="false" Priority="39" Name="toc 2"/&gt;   &lt;w:LsdException Locked="false" Priority="39" Name="toc 3"/&gt;   &lt;w:LsdException Locked="false" Priority="39" Name="toc 4"/&gt;   &lt;w:LsdException Locked="false" Priority="39" Name="toc 5"/&gt;   &lt;w:LsdException Locked="false" Priority="39" Name="toc 6"/&gt;   &lt;w:LsdException Locked="false" Priority="39" Name="toc 7"/&gt;   &lt;w:LsdException Locked="false" Priority="39" Name="toc 8"/&gt;   &lt;w:LsdException Locked="false" Priority="39" Name="toc 9"/&gt;   &lt;w:LsdException Locked="false" Priority="35" QFormat="true" Name="caption"/&gt;   &lt;w:LsdException Locked="false" Priority="10" SemiHidden="false"   UnhideWhenUsed="false" QFormat="true" Name="Title"/&gt;   &lt;w:LsdException Locked="false" Priority="1" Name="Default Paragraph Font"/&gt;   &lt;w:LsdException Locked="false" Priority="11" SemiHidden="false"   UnhideWhenUsed="false" QFormat="true" Name="Subtitle"/&gt;   &lt;w:LsdException Locked="false" Priority="22" SemiHidden="false"   UnhideWhenUsed="false" QFormat="true" Name="Strong"/&gt;   &lt;w:LsdException Locked="false" Priority="20" SemiHidden="false"   UnhideWhenUsed="false" QFormat="true" Name="Emphasis"/&gt;   &lt;w:LsdException Locked="false" Priority="59" SemiHidden="false"   UnhideWhenUsed="false" Name="Table Grid"/&gt;   &lt;w:LsdException Locked="false" UnhideWhenUsed="false" Name="Placeholder Text"/&gt;   &lt;w:LsdException Locked="false" Priority="1" SemiHidden="false"   UnhideWhenUsed="false" QFormat="true" Name="No Spacing"/&gt;   &lt;w:LsdException Locked="false" Priority="60" SemiHidden="false"   UnhideWhenUsed="false" Name="Light Shading"/&gt;   &lt;w:LsdException Locked="false" Priority="61" SemiHidden="false"   UnhideWhenUsed="false" Name="Light List"/&gt;   &lt;w:LsdException Locked="false" Priority="62" SemiHidden="false"   UnhideWhenUsed="false" Name="Light Grid"/&gt;   &lt;w:LsdException Locked="false" Priority="63" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Shading 1"/&gt;   &lt;w:LsdException Locked="false" Priority="64" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Shading 2"/&gt;   &lt;w:LsdException Locked="false" Priority="65" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium List 1"/&gt;   &lt;w:LsdException Locked="false" Priority="66" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium List 2"/&gt;   &lt;w:LsdException Locked="false" Priority="67" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Grid 1"/&gt;   &lt;w:LsdException Locked="false" Priority="68" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Grid 2"/&gt;   &lt;w:LsdException Locked="false" Priority="69" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Grid 3"/&gt;   &lt;w:LsdException Locked="false" Priority="70" SemiHidden="false"   UnhideWhenUsed="false" Name="Dark List"/&gt;   &lt;w:LsdException Locked="false" Priority="71" SemiHidden="false"   UnhideWhenUsed="false" Name="Colorful Shading"/&gt;   &lt;w:LsdException Locked="false" Priority="72" SemiHidden="false"   UnhideWhenUsed="false" Name="Colorful List"/&gt;   &lt;w:LsdException Locked="false" Priority="73" SemiHidden="false"   UnhideWhenUsed="false" Name="Colorful Grid"/&gt;   &lt;w:LsdException Locked="false" Priority="60" SemiHidden="false"   UnhideWhenUsed="false" Name="Light Shading Accent 1"/&gt;   &lt;w:LsdException Locked="false" Priority="61" SemiHidden="false"   UnhideWhenUsed="false" Name="Light List Accent 1"/&gt;   &lt;w:LsdException Locked="false" Priority="62" SemiHidden="false"   UnhideWhenUsed="false" Name="Light Grid Accent 1"/&gt;   &lt;w:LsdException Locked="false" Priority="63" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Shading 1 Accent 1"/&gt;   &lt;w:LsdException Locked="false" Priority="64" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Shading 2 Accent 1"/&gt;   &lt;w:LsdException Locked="false" Priority="65" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium List 1 Accent 1"/&gt;   &lt;w:LsdException Locked="false" UnhideWhenUsed="false" Name="Revision"/&gt;   &lt;w:LsdException Locked="false" Priority="34" SemiHidden="false"   UnhideWhenUsed="false" QFormat="true" Name="List Paragraph"/&gt;   &lt;w:LsdException Locked="false" Priority="29" SemiHidden="false"   UnhideWhenUsed="false" QFormat="true" Name="Quote"/&gt;   &lt;w:LsdException Locked="false" Priority="30" SemiHidden="false"   UnhideWhenUsed="false" QFormat="true" Name="Intense Quote"/&gt;   &lt;w:LsdException Locked="false" Priority="66" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium List 2 Accent 1"/&gt;   &lt;w:LsdException Locked="false" Priority="67" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Grid 1 Accent 1"/&gt;   &lt;w:LsdException Locked="false" Priority="68" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Grid 2 Accent 1"/&gt;   &lt;w:LsdException Locked="false" Priority="69" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Grid 3 Accent 1"/&gt;   &lt;w:LsdException Locked="false" Priority="70" SemiHidden="false"   UnhideWhenUsed="false" Name="Dark List Accent 1"/&gt;   &lt;w:LsdException Locked="false" Priority="71" SemiHidden="false"   UnhideWhenUsed="false" Name="Colorful Shading Accent 1"/&gt;   &lt;w:LsdException Locked="false" Priority="72" SemiHidden="false"   UnhideWhenUsed="false" Name="Colorful List Accent 1"/&gt;   &lt;w:LsdException Locked="false" Priority="73" SemiHidden="false"   UnhideWhenUsed="false" Name="Colorful Grid Accent 1"/&gt;   &lt;w:LsdException Locked="false" Priority="60" SemiHidden="false"   UnhideWhenUsed="false" Name="Light Shading Accent 2"/&gt;   &lt;w:LsdException Locked="false" Priority="61" SemiHidden="false"   UnhideWhenUsed="false" Name="Light List Accent 2"/&gt;   &lt;w:LsdException Locked="false" Priority="62" SemiHidden="false"   UnhideWhenUsed="false" Name="Light Grid Accent 2"/&gt;   &lt;w:LsdException Locked="false" Priority="63" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Shading 1 Accent 2"/&gt;   &lt;w:LsdException Locked="false" Priority="64" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Shading 2 Accent 2"/&gt;   &lt;w:LsdException Locked="false" Priority="65" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium List 1 Accent 2"/&gt;   &lt;w:LsdException Locked="false" Priority="66" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium List 2 Accent 2"/&gt;   &lt;w:LsdException Locked="false" Priority="67" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Grid 1 Accent 2"/&gt;   &lt;w:LsdException Locked="false" Priority="68" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Grid 2 Accent 2"/&gt;   &lt;w:LsdException Locked="false" Priority="69" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Grid 3 Accent 2"/&gt;   &lt;w:LsdException Locked="false" Priority="70" SemiHidden="false"   UnhideWhenUsed="false" Name="Dark List Accent 2"/&gt;   &lt;w:LsdException Locked="false" Priority="71" SemiHidden="false"   UnhideWhenUsed="false" Name="Colorful Shading Accent 2"/&gt;   &lt;w:LsdException Locked="false" Priority="72" SemiHidden="false"   UnhideWhenUsed="false" Name="Colorful List Accent 2"/&gt;   &lt;w:LsdException Locked="false" Priority="73" SemiHidden="false"   UnhideWhenUsed="false" Name="Colorful Grid Accent 2"/&gt;   &lt;w:LsdException Locked="false" Priority="60" SemiHidden="false"   UnhideWhenUsed="false" Name="Light Shading Accent 3"/&gt;   &lt;w:LsdException Locked="false" Priority="61" SemiHidden="false"   UnhideWhenUsed="false" Name="Light List Accent 3"/&gt;   &lt;w:LsdException Locked="false" Priority="62" SemiHidden="false"   UnhideWhenUsed="false" Name="Light Grid Accent 3"/&gt;   &lt;w:LsdException Locked="false" Priority="63" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Shading 1 Accent 3"/&gt;   &lt;w:LsdException Locked="false" Priority="64" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Shading 2 Accent 3"/&gt;   &lt;w:LsdException Locked="false" Priority="65" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium List 1 Accent 3"/&gt;   &lt;w:LsdException Locked="false" Priority="66" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium List 2 Accent 3"/&gt;   &lt;w:LsdException Locked="false" Priority="67" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Grid 1 Accent 3"/&gt;   &lt;w:LsdException Locked="false" Priority="68" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Grid 2 Accent 3"/&gt;   &lt;w:LsdException Locked="false" Priority="69" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Grid 3 Accent 3"/&gt;   &lt;w:LsdException Locked="false" Priority="70" SemiHidden="false"   UnhideWhenUsed="false" Name="Dark List Accent 3"/&gt;   &lt;w:LsdException Locked="false" Priority="71" SemiHidden="false"   UnhideWhenUsed="false" Name="Colorful Shading Accent 3"/&gt;   &lt;w:LsdException Locked="false" Priority="72" SemiHidden="false"   UnhideWhenUsed="false" Name="Colorful List Accent 3"/&gt;   &lt;w:LsdException Locked="false" Priority="73" SemiHidden="false"   UnhideWhenUsed="false" Name="Colorful Grid Accent 3"/&gt;   &lt;w:LsdException Locked="false" Priority="60" SemiHidden="false"   UnhideWhenUsed="false" Name="Light Shading Accent 4"/&gt;   &lt;w:LsdException Locked="false" Priority="61" SemiHidden="false"   UnhideWhenUsed="false" Name="Light List Accent 4"/&gt;   &lt;w:LsdException Locked="false" Priority="62" SemiHidden="false"   UnhideWhenUsed="false" Name="Light Grid Accent 4"/&gt;   &lt;w:LsdException Locked="false" Priority="63" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Shading 1 Accent 4"/&gt;   &lt;w:LsdException Locked="false" Priority="64" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Shading 2 Accent 4"/&gt;   &lt;w:LsdException Locked="false" Priority="65" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium List 1 Accent 4"/&gt;   &lt;w:LsdException Locked="false" Priority="66" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium List 2 Accent 4"/&gt;   &lt;w:LsdException Locked="false" Priority="67" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Grid 1 Accent 4"/&gt;   &lt;w:LsdException Locked="false" Priority="68" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Grid 2 Accent 4"/&gt;   &lt;w:LsdException Locked="false" Priority="69" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Grid 3 Accent 4"/&gt;   &lt;w:LsdException Locked="false" Priority="70" SemiHidden="false"   UnhideWhenUsed="false" Name="Dark List Accent 4"/&gt;   &lt;w:LsdException Locked="false" Priority="71" SemiHidden="false"   UnhideWhenUsed="false" Name="Colorful Shading Accent 4"/&gt;   &lt;w:LsdException Locked="false" Priority="72" SemiHidden="false"   UnhideWhenUsed="false" Name="Colorful List Accent 4"/&gt;   &lt;w:LsdException Locked="false" Priority="73" SemiHidden="false"   UnhideWhenUsed="false" Name="Colorful Grid Accent 4"/&gt;   &lt;w:LsdException Locked="false" Priority="60" SemiHidden="false"   UnhideWhenUsed="false" Name="Light Shading Accent 5"/&gt;   &lt;w:LsdException Locked="false" Priority="61" SemiHidden="false"   UnhideWhenUsed="false" Name="Light List Accent 5"/&gt;   &lt;w:LsdException Locked="false" Priority="62" SemiHidden="false"   UnhideWhenUsed="false" Name="Light Grid Accent 5"/&gt;   &lt;w:LsdException Locked="false" Priority="63" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Shading 1 Accent 5"/&gt;   &lt;w:LsdException Locked="false" Priority="64" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Shading 2 Accent 5"/&gt;   &lt;w:LsdException Locked="false" Priority="65" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium List 1 Accent 5"/&gt;   &lt;w:LsdException Locked="false" Priority="66" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium List 2 Accent 5"/&gt;   &lt;w:LsdException Locked="false" Priority="67" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Grid 1 Accent 5"/&gt;   &lt;w:LsdException Locked="false" Priority="68" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Grid 2 Accent 5"/&gt;   &lt;w:LsdException Locked="false" Priority="69" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Grid 3 Accent 5"/&gt;   &lt;w:LsdException Locked="false" Priority="70" SemiHidden="false"   UnhideWhenUsed="false" Name="Dark List Accent 5"/&gt;   &lt;w:LsdException Locked="false" Priority="71" SemiHidden="false"   UnhideWhenUsed="false" Name="Colorful Shading Accent 5"/&gt;   &lt;w:LsdException Locked="false" Priority="72" SemiHidden="false"   UnhideWhenUsed="false" Name="Colorful List Accent 5"/&gt;   &lt;w:LsdException Locked="false" Priority="73" SemiHidden="false"   UnhideWhenUsed="false" Name="Colorful Grid Accent 5"/&gt;   &lt;w:LsdException Locked="false" Priority="60" SemiHidden="false"   UnhideWhenUsed="false" Name="Light Shading Accent 6"/&gt;   &lt;w:LsdException Locked="false" Priority="61" SemiHidden="false"   UnhideWhenUsed="false" Name="Light List Accent 6"/&gt;   &lt;w:LsdException Locked="false" Priority="62" SemiHidden="false"   UnhideWhenUsed="false" Name="Light Grid Accent 6"/&gt;   &lt;w:LsdException Locked="false" Priority="63" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Shading 1 Accent 6"/&gt;   &lt;w:LsdException Locked="false" Priority="64" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Shading 2 Accent 6"/&gt;   &lt;w:LsdException Locked="false" Priority="65" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium List 1 Accent 6"/&gt;   &lt;w:LsdException Locked="false" Priority="66" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium List 2 Accent 6"/&gt;   &lt;w:LsdException Locked="false" Priority="67" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Grid 1 Accent 6"/&gt;   &lt;w:LsdException Locked="false" Priority="68" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Grid 2 Accent 6"/&gt;   &lt;w:LsdException Locked="false" Priority="69" SemiHidden="false"   UnhideWhenUsed="false" Name="Medium Grid 3 Accent 6"/&gt;   &lt;w:LsdException Locked="false" Priority="70" SemiHidden="false"   UnhideWhenUsed="false" Name="Dark List Accent 6"/&gt;   &lt;w:LsdException Locked="false" Priority="71" SemiHidden="false"   UnhideWhenUsed="false" Name="Colorful Shading Accent 6"/&gt;   &lt;w:LsdException Locked="false" Priority="72" SemiHidden="false"   UnhideWhenUsed="false" Name="Colorful List Accent 6"/&gt;   &lt;w:LsdException Locked="false" Priority="73" SemiHidden="false"   UnhideWhenUsed="false" Name="Colorful Grid Accent 6"/&gt;   &lt;w:LsdException Locked="false" Priority="19" SemiHidden="false"   UnhideWhenUsed="false" QFormat="true" Name="Subtle Emphasis"/&gt;   &lt;w:LsdException Locked="false" Priority="21" SemiHidden="false"   UnhideWhenUsed="false" QFormat="true" Name="Intense Emphasis"/&gt;   &lt;w:LsdException Locked="false" Priority="31" SemiHidden="false"   UnhideWhenUsed="false" QFormat="true" Name="Subtle Reference"/&gt;   &lt;w:LsdException Locked="false" Priority="32" SemiHidden="false"   UnhideWhenUsed="false" QFormat="true" Name="Intense Reference"/&gt;   &lt;w:LsdException Locked="false" Priority="33" SemiHidden="false"   UnhideWhenUsed="false" QFormat="true" Name="Book Title"/&gt;   &lt;w:LsdException Locked="false" Priority="37" Name="Bibliography"/&gt;   &lt;w:LsdException Locked="false" Priority="39" QFormat="true" Name="TOC Heading"/&gt;  &lt;/w:LatentStyles&gt; &lt;/xml&gt;&lt;![endif]--&gt;&lt;!--[if gte mso 10]&gt; &lt;style&gt; /* Style Definitions */ table.MsoNormalTable {mso-style-name:"Tableau Normal"; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-priority:99; mso-style-qformat:yes; mso-style-parent:""; mso-padding-alt:0cm 5.4pt 0cm 5.4pt; mso-para-margin:0cm; mso-para-margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:11.0pt; font-family:"Calibri","sans-serif"; mso-ascii-font-family:Calibri; mso-ascii-theme-font:minor-latin; mso-hansi-font-family:Calibri; mso-hansi-theme-font:minor-latin; mso-bidi-font-family:"Times New Roman"; mso-bidi-theme-font:minor-bidi;}&lt;/style&gt; &lt;![endif]--&gt;  &lt;br /&gt;&lt;div class="MsoNormal"&gt;Hello everyone.&lt;/div&gt;&lt;div class="MsoNormal"&gt; If like me, you enjoy using Plesk but would like to see Nginx as a web server instead of Apache, you are probably going to want to read the following message. I have emailed Parallels about possible Nginx support in Plesk, offering my help for the implementation (you could say I am qualified for this, being the author of the only book ever written about Nginx).&lt;/div&gt;&lt;div class="MsoNormal"&gt;------------------------------------------------------ &lt;/div&gt;&lt;blockquote style="font-family: Arial,Helvetica,sans-serif;"&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: x-small;"&gt;Dear Sir,&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span lang="EN-US"&gt;My name is Clement Nedelcu, technology consultant and university lecturer in Jiangsu (China).&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span lang="EN-US"&gt;I would like to begin by apologizing because I presume you are not the right person to contact for such an enquiry.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span lang="EN-US"&gt;I trust that you will forward this message to the proper person and I thank you in advance for it.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span lang="EN-US"&gt;I am a long time Parallels Plesk user. I have recently published a book about a groundbreaking new web server called Nginx.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span lang="EN-US"&gt;You will find more information about my book on Amazon: &lt;a href="http://www.amazon.com/Nginx-HTTP-Server-Cl%C3%A9ment-Nedelcu/dp/1849510865"&gt;http://www.amazon.com/Nginx-HTTP-Server-Clément-Nedelcu/dp/1849510865&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span lang="EN-US"&gt;I am certain that the Plesk development team has already heard of Nginx. It is much faster and much more efficient than Apache (the only Linux web server supported by Plesk, as far as I know).&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span lang="EN-US"&gt;Let’s get to the point. This might sound like a bold request, but since Parallels apparently has no intention of supporting Nginx in future iterations of Plesk, I would like to officially offer my help to the development team towards adding Nginx support to future Plesk versions.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span lang="EN-US"&gt;I am not afraid to openly claim that Nginx is contributing to making the Web faster. Unfortunately, major server management panels such as Plesk, CPanel or ISPConfig contribute to holding back the spreading of this little gem of a web server. But many of the most famous websites worldwide have already adopted Nginx:&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoListParagraph" style="text-indent: -18pt;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span&gt;·&lt;span style="font-size-adjust: none; font-stretch: normal; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;WordPress&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoListParagraph" style="text-indent: -18pt;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span&gt;·&lt;span style="font-size-adjust: none; font-stretch: normal; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;Rambler&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoListParagraph" style="text-indent: -18pt;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span&gt;·&lt;span style="font-size-adjust: none; font-stretch: normal; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;Hulu&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoListParagraph" style="text-indent: -18pt;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span&gt;·&lt;span style="font-size-adjust: none; font-stretch: normal; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;YouPorn&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoListParagraph" style="text-indent: -18pt;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span&gt;·&lt;span style="font-size-adjust: none; font-stretch: normal; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;GBAtemp&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoListParagraph" style="text-indent: -18pt;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span&gt;·&lt;span style="font-size-adjust: none; font-stretch: normal; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;MochiMedia&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoListParagraph" style="text-indent: -18pt;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span&gt;·&lt;span style="font-size-adjust: none; font-stretch: normal; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;…&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span lang="EN-US"&gt;If you are interested in implementing Nginx support in future (or current) versions of Plesk, I invite you to ask for my help. I am genuinely motivated by the idea of seeing more web servers running Nginx, because it has done a fantastic job at replacing Apache on all my web servers.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span lang="EN-US"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;span style="font-size: x-small;"&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span lang="EN-US"&gt;I shall hope that you will look into the matter and get back to me on this. I will equally be publishing your answer (or non-answer, for what it’s worth).&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span lang="EN-US"&gt;Sincerely,&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span lang="EN-US"&gt;Clement NEDELCU&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;span style="font-size: x-small;"&gt;&lt;a href="http://cnedelcu.net/"&gt;http://cnedelcu.net&lt;/a&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;div class="MsoNormal"&gt;&lt;span lang="EN-US"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;---------------------------------------- &lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;I will make sure to post the answer here, if I ever get one.&lt;br /&gt;Post comments if you approve of this. If you disapprove, tell us why! &lt;br /&gt;Clem&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/512188703456595011-2665321256979194577?l=cnedelcu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cnedelcu.blogspot.com/feeds/2665321256979194577/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=512188703456595011&amp;postID=2665321256979194577' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/512188703456595011/posts/default/2665321256979194577'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/512188703456595011/posts/default/2665321256979194577'/><link rel='alternate' type='text/html' href='http://cnedelcu.blogspot.com/2010/12/nginx-support-for-plesk-my-offer-to.html' title='Nginx support for Plesk: my offer to Parallels'/><author><name>Clément Nedelcu</name><uri>http://www.blogger.com/profile/00168228978102132365</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-512188703456595011.post-8263756850783026028</id><published>2010-12-04T09:11:00.001+01:00</published><updated>2010-12-04T09:17:35.404+01:00</updated><title type='text'>Nginx rewrite rules for Interspire Shopping Cart</title><content type='html'>It's been a while since I made my last post on this blog, but that's because I've been busy with work! Anyway, today I've chosen to publish a simple finding that I've come up with myself (not that it was any difficult anyway). It could be useful for people who want to run a web shop, particularly the excellent &lt;a href="http://www.interspire.com/"&gt;Interspire Shopping Cart&lt;/a&gt;. It comes with a set of rewrite rules for Apache to enable search-engine friendly URLs, but nothing for Nginx unfortunately.&lt;br /&gt;&lt;br /&gt;Here is the Apache .htaccess file provided with Interspire Shopping Cart. I'm only pasting the section that we are interested in, in other words the Rewrite Module section:&lt;br /&gt;&lt;blockquote style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;ifmodule mod_rewrite.c=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; RewriteEngine On&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; RewriteCond %{REQUEST_FILENAME} !-f&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; RewriteCond %{REQUEST_FILENAME} !-d&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; RewriteRule . index.php&lt;ifmodule mod_env.c=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/ifmodule&gt;&lt;/ifmodule&gt;&lt;/blockquote&gt;In order to achieve the same results in Nginx, you simply need to enable this location block:&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; location / {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; try_files $uri $uri/ /index.php?q=$uri&amp;amp;$args;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/blockquote&gt;The try_files directive will attempt to serve the first parameter ($uri, the URI of the client request), then the second one ($uri + slash, could be a folder), but if neither is found, it will redirect the request to index.php and specify the requested URI as parameter in the URL together with the original arguments. It's as simple as that! The PHP scripts will handle the actual rewrites themselves.&lt;br /&gt;&lt;br /&gt;Here is the full virtual host configuration which I used on a client's server:&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; server {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; listen 80;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; server_name .website.com;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; root /var/www/website.com;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; index index.php;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; location / {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; try_files $uri $uri/ /index.php?q=$uri&amp;amp;$args;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; location ~ \.php$ {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; fastcgi_pass 127.0.0.1:9000;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; fastcgi_index index.php;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; include fastcgi.conf;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt; &lt;/blockquote&gt;&lt;b style="color: red;"&gt;IMPORTANT NOTE:&lt;/b&gt; when you enable those rewrite rules in Nginx, Interspire does not automatically detect friendly URLs as being "available". So you need to go to your Interspire control panel, in the store settings, and force it to "Enable search-engine friendly URLs" instead of "Enable if available".&lt;br /&gt;&lt;br /&gt;Enjoy!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/512188703456595011-8263756850783026028?l=cnedelcu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cnedelcu.blogspot.com/feeds/8263756850783026028/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=512188703456595011&amp;postID=8263756850783026028' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/512188703456595011/posts/default/8263756850783026028'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/512188703456595011/posts/default/8263756850783026028'/><link rel='alternate' type='text/html' href='http://cnedelcu.blogspot.com/2010/12/nginx-rewrite-rules-for-interspire.html' title='Nginx rewrite rules for Interspire Shopping Cart'/><author><name>Clément Nedelcu</name><uri>http://www.blogger.com/profile/00168228978102132365</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-512188703456595011.post-6240383714949231859</id><published>2010-07-22T11:32:00.001+02:00</published><updated>2010-07-22T11:32:44.101+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='server'/><category scheme='http://www.blogger.com/atom/ns#' term='http'/><category scheme='http://www.blogger.com/atom/ns#' term='nginx'/><category scheme='http://www.blogger.com/atom/ns#' term='book'/><title type='text'>"Nginx HTTP Server" book published</title><content type='html'>Nginx HTTP Server was published and is now available for purchase on various locations. It will begin to appear in store in the coming weeks. You can already purchase the eBook from the publisher's website at the link below:&lt;br /&gt;&lt;a href="https://www.packtpub.com/nginx-http-server-for-web-applications/book"&gt;https://www.packtpub.com/nginx-http-server-for-web-applications/book&lt;/a&gt;&lt;br /&gt;The eBook can be purchased for 23.79€ whereas the book is 31.49€.&lt;br /&gt;There is also a preview chapter available on the website for anyone to read! &lt;br /&gt;Please feel free to leave your comments, feedback and questions if you have read the book.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/512188703456595011-6240383714949231859?l=cnedelcu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cnedelcu.blogspot.com/feeds/6240383714949231859/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=512188703456595011&amp;postID=6240383714949231859' title='11 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/512188703456595011/posts/default/6240383714949231859'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/512188703456595011/posts/default/6240383714949231859'/><link rel='alternate' type='text/html' href='http://cnedelcu.blogspot.com/2010/07/nginx-http-server-published.html' title='&quot;Nginx HTTP Server&quot; book published'/><author><name>Clément Nedelcu</name><uri>http://www.blogger.com/profile/00168228978102132365</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>11</thr:total></entry><entry><id>tag:blogger.com,1999:blog-512188703456595011.post-6066756915537302825</id><published>2010-07-12T07:32:00.002+02:00</published><updated>2010-07-12T07:42:42.435+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='server'/><category scheme='http://www.blogger.com/atom/ns#' term='nginx'/><category scheme='http://www.blogger.com/atom/ns#' term='administration'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><category scheme='http://www.blogger.com/atom/ns#' term='book'/><title type='text'>Nginx HTTP Server: the book</title><content type='html'>Hello,&lt;br /&gt;I am glad to to announce the first Nginx book on the market: &lt;b&gt;Nginx HTTP Server&lt;/b&gt;, written by... &lt;i&gt;me&lt;/i&gt;. :-)&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_Ixt0VU0h5eU/TDqk9oxvNEI/AAAAAAAAB_o/Wwf1iXodQrw/s1600/0868OS_MockupCover.jpg.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_Ixt0VU0h5eU/TDqk9oxvNEI/AAAAAAAAB_o/Wwf1iXodQrw/s320/0868OS_MockupCover.jpg.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;b&gt;NGINX HTTP SERVER&lt;/b&gt;&lt;br /&gt;"Adopt Nginx for your web applications to make the most of your infrastructure and server pages faster than ever."&lt;br /&gt;Focused on the primary aspect of Nginx (HTTP serving), the book covers the following topics:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Get started with Nginx to serve websites faster and safer&lt;/li&gt;&lt;li&gt;Learn to configure your servers and virtual hosts efficiently&lt;/li&gt;&lt;li&gt;Set up Nginx to work with PHP and other applications via FastCGI&lt;/li&gt;&lt;li&gt;Explore possible interactions between Nginx and Apache to get the  best of both worlds&lt;/li&gt;&lt;li&gt;A step-by-step guide to switching from Apache to Nginx&lt;/li&gt;&lt;li&gt;Complete configuration directive and module reference&lt;/li&gt;&lt;/ul&gt;There are 8 chapters and 3 appendices, listed here:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;1. Preparing your work environment:&lt;/b&gt; getting ready to work under a command-line environment, with a reminder on the basic tools and commands.&lt;/li&gt;&lt;li&gt;&lt;b&gt;2. Downloading and installing Nginx&lt;/b&gt;: downloading the source, the prerequisites, building the application, installing it and learning to solve installation issues.&lt;/li&gt;&lt;li&gt;&lt;b&gt;3. Nginx core configuration:&lt;/b&gt; configuring the core modules and optimizing your setup for your current hardware architecture.&lt;/li&gt;&lt;li&gt;&lt;b&gt;4. HTTP configuration:&lt;/b&gt; configuring the HTTP core module (virtual hosts, http/server/location blocks...)&lt;/li&gt;&lt;li&gt;&lt;b&gt;5. Module configuration:&lt;/b&gt; configuring and using additional modules such as the rewrite module, SSI module and all other first-party modules.&lt;/li&gt;&lt;li&gt;&lt;b&gt;6. Setting up Nginx to work with PHP and Python:&lt;/b&gt; learn to use the FastCGI module to set up PHP with Nginx, then Python.&lt;/li&gt;&lt;li&gt;&lt;b&gt;7. Setting up Nginx as a reverse proxy&lt;/b&gt;: discovering the Proxy module and setting up a reverse proxied architecture with Nginx as frontend and Apache as backend.&lt;/li&gt;&lt;li&gt;&lt;b&gt;8. Switching from Apache to Nginx&lt;/b&gt;: a complete guide to switching from Apache to Nginx, covering everything including converting Apache rewrite rules to Nginx.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Appendix A&lt;/b&gt;: full directive index. A list and description of all configuration directives, sorted alphabetically. Module directives are also described in their respective chapters too.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Appendix B&lt;/b&gt;: full module reference. A detailed list of all available modules.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Appendix C&lt;/b&gt;: troubleshooting. Discusses the most common issues that administrators face when they configure Nginx.&lt;/li&gt;&lt;/ul&gt;By covering both early setup stages and advanced topics, this book will  suit web administrators interested in solutions to optimize their  infrastructure, whether they are looking into replacing existing web  server software or integrating a new tool cooperating with applications  already up and running. If you, your visitors, and your operating system  have been disappointed by Apache, this book is exactly what you need.&lt;br /&gt;&lt;br /&gt;The book will be available online as eBook and of course in libraries in the major english speaking countries: USA, UK, India, Canada (to be confirmed) and many more. You will find more information and descriptions over at the publisher's website: &lt;a href="https://www.packtpub.com/nginx-http-server-for-web-applications/book"&gt;click here to see the official page about the first Nginx book&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;PS: In fact, it appears that there is already a book about Nginx, but it was written in Chinese and never translated and published on the western markets.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/512188703456595011-6066756915537302825?l=cnedelcu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cnedelcu.blogspot.com/feeds/6066756915537302825/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=512188703456595011&amp;postID=6066756915537302825' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/512188703456595011/posts/default/6066756915537302825'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/512188703456595011/posts/default/6066756915537302825'/><link rel='alternate' type='text/html' href='http://cnedelcu.blogspot.com/2010/07/first-nginx-book-on-market.html' title='Nginx HTTP Server: the book'/><author><name>Clément Nedelcu</name><uri>http://www.blogger.com/profile/00168228978102132365</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_Ixt0VU0h5eU/TDqk9oxvNEI/AAAAAAAAB_o/Wwf1iXodQrw/s72-c/0868OS_MockupCover.jpg.png' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-512188703456595011.post-343829968484809277</id><published>2010-07-03T06:13:00.000+02:00</published><updated>2010-07-03T06:13:04.287+02:00</updated><title type='text'>Visual Studio 2010 web development bible</title><content type='html'>Julien Dollon, whose &lt;a href="http://blogs.dotnet-france.com/juliend/"&gt;blog is available here&lt;/a&gt;, recently finished writing his book about web development under Visual Studio 2010.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_Ixt0VU0h5eU/TC64CfYLruI/AAAAAAAAB_g/nYjbk6syy6Q/s1600/41510_816424355_7153_n.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_Ixt0VU0h5eU/TC64CfYLruI/AAAAAAAAB_g/nYjbk6syy6Q/s320/41510_816424355_7153_n.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;Knowing the professionalism and the talent of Julien, this book should turn out to be an excellent read for all of us web developers interested in the .NET platform. The book is already available for pre-orders on &lt;a href="http://www.amazon.fr/Visual-Studio-2010-Developpez-Framework/dp/2746056194/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1278058293&amp;amp;sr=1-1"&gt;Amazon&lt;/a&gt;.&lt;br /&gt;Congratulations Julien!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/512188703456595011-343829968484809277?l=cnedelcu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cnedelcu.blogspot.com/feeds/343829968484809277/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=512188703456595011&amp;postID=343829968484809277' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/512188703456595011/posts/default/343829968484809277'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/512188703456595011/posts/default/343829968484809277'/><link rel='alternate' type='text/html' href='http://cnedelcu.blogspot.com/2010/07/visual-studio-2010-web-development.html' title='Visual Studio 2010 web development bible'/><author><name>Clément Nedelcu</name><uri>http://www.blogger.com/profile/00168228978102132365</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_Ixt0VU0h5eU/TC64CfYLruI/AAAAAAAAB_g/nYjbk6syy6Q/s72-c/41510_816424355_7153_n.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-512188703456595011.post-8799478154562187011</id><published>2010-05-26T13:40:00.004+02:00</published><updated>2010-05-29T03:30:50.164+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='server'/><category scheme='http://www.blogger.com/atom/ns#' term='issue'/><category scheme='http://www.blogger.com/atom/ns#' term='nginx'/><category scheme='http://www.blogger.com/atom/ns#' term='vulnerability'/><category scheme='http://www.blogger.com/atom/ns#' term='fastcgi'/><category scheme='http://www.blogger.com/atom/ns#' term='php'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><title type='text'>Nginx &amp; PHP via FastCGI important security issue</title><content type='html'>&lt;span style="font-family: inherit;"&gt;A&lt;/span&gt;&lt;span style="font-family: inherit;"&gt; critical security issue has recently been pointed out on servers that run Nginx and PHP via FastCGI. The issue allows anyone to execute their own PHP code on the system, I don't think I have to remind you of the consequences this could have. I will attempt to provide a simple explanation of the issue and more importantly how to fix it.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;b style="color: #660000; font-family: inherit;"&gt;What is the issue?&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;I would like to begin by discussing the nature of the problem: it is not caused by Nginx itself - it is not a bug or a security breach in itself. Actually, it is the way that people usually configure Nginx FastCGI options to work with PHP, and how PHP reacts to that configuration. Pretty much everyone adopts the same configuration without being aware of the issue.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;The issue itself can be understood simply, then I will explain why PHP behaves that way.&lt;/span&gt;&lt;span style="font-family: inherit;"&gt; Most dynamic websites allow for a reason or another uploading of files.&lt;/span&gt;&lt;span style="font-family: inherit;"&gt; Say, I'm running a forum-based community, users can upload images to use as personal photo or avatar.&lt;/span&gt;&lt;span style="font-family: inherit;"&gt; The photo gets uploaded and you get the following URL: &lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: #fce5cd; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;http://myforum.com/uploads/photo1234.jpg&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;The breach consists in appending an additional path element to the URL, making it end in .php:&lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: #fce5cd; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;http://myforum.com/uploads/photo1234.jpg/anything.php&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;Under certain conditions (and unfortunately with default settings), your photo1234.jpg gets processed as PHP file. So you could upload a PHP script renamed as .jpg, upload the image, then execute the script on the server.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;If you want to know instantly if your server is vulnerable to this attack, there is a simple way to know. Find a regular file on your server, such as &lt;span style="background-color: #fce5cd; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;http://myforum.com/robots.txt&lt;/span&gt;. Examine the HTTP headers of the response:&lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: #fce5cd; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;HTTP/1.1 200 OK&lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: #fce5cd; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;Server: nginx/0.7.64&lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: #fce5cd; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;Date: Wed, 26 May 2010 10:56:01 GMT&lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: #fce5cd; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;Content-Type: text/plain&lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: #fce5cd; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;Content-Length: 43&lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: #fce5cd; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;(...)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;Now add /test.php after the URL: &lt;span style="background-color: #fce5cd; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;http://myforum.com/robots.txt/test.php&lt;/span&gt;: &lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: #fce5cd; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;HTTP/1.1 200 OK&lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: #fce5cd; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;Server: nginx/0.7.64&lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: #fce5cd; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;Date: Wed, 26 May 2010 10:56:01 GMT&lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: #fce5cd; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;Content-Type: text/plain&lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: #fce5cd; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;Content-Length: 43&lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: #fce5cd; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;(...)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;i&gt;&lt;b&gt;&lt;span style="background-color: #fce5cd; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;X-Powered-By: PHP/5.2.3&lt;/span&gt;&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;The X-Powered-By header was added by PHP which shows that the file was processed by PHP. Now visit that URL &lt;/span&gt;&lt;span style="font-family: inherit;"&gt;&lt;span style="background-color: #fce5cd; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;http://myforum.com/robots.txt/test.php&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: inherit;"&gt; in your web browser. What do you see:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;- do you see the &lt;b&gt;robots.txt&lt;/b&gt; file ? if so, &lt;b&gt;your server is vulnerable&lt;/b&gt;.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;- do you see an error page (403, 404, 500, 502...) or just a simple message "No input file specified" ? if so, your server is not affected by the problem.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;b style="color: #660000; font-family: inherit;"&gt;Why does this happen?&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;There are two main reasons why this happens. First let's have a look at the data Nginx transmits to PHP.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;A regular FastCGI/PHP configuration would be as follows:&lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: #fce5cd; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&lt;b&gt;fastcgi_pass&lt;/b&gt; 127.0.0.1:9000;&lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: #fce5cd; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&lt;b&gt;fastcgi_index&lt;/b&gt; index.php;&lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: #fce5cd; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&lt;b&gt;fastcgi_param&lt;/b&gt; &lt;b&gt;SCRIPT_FILENAME&lt;/b&gt; /var/www/vhosts/myforum.com/httpdocs$fastcgi_script_name;&lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: #fce5cd; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&lt;b&gt;fastcgi_param&lt;/b&gt; &lt;b&gt;PATH_INFO&lt;/b&gt; $fastcgi_script_name;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;When requesting an URL like &lt;span style="background-color: #fce5cd; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;http://myforum.com/uploads/photo1234.jpg/anything.php&lt;/span&gt; to Nginx, here is the data that gets sent:&lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: #fce5cd; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&lt;b&gt;fastcgi_param SCRIPT_FILENAME&lt;/b&gt; /var/www/vhosts/myforum.com/httpdocs/uploads/photo1234.jpg/anything.php;&lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: #fce5cd; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&lt;b&gt;fastcgi_param PATH_INFO &lt;/b&gt;/robots.txt/test.php;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;So far, no problem. PHP is supposed to load a file &lt;span style="background-color: #fce5cd; font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;anything.php&lt;/span&gt;&lt;/span&gt;, in the directory &lt;span style="background-color: #fce5cd; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;/var/www/vhosts/myforum.com/httpdocs/uploads/photo1234.jpg/&lt;/span&gt;.&lt;/span&gt; &lt;span style="font-family: inherit;"&gt;Naturally, this directory should not exist, and &lt;b&gt;anything.php&lt;/b&gt; shouldn't exist either, so we should be getting a 404 error.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;However, that's where the problem comes in. &lt;/span&gt;&lt;span style="font-family: inherit;"&gt;The PHP option &lt;i&gt;&lt;b&gt;cgi.fix_pathinfo&lt;/b&gt;&lt;/i&gt;, when enabled (and it is usually enabled by default) will transform these two parameters.&lt;/span&gt;&lt;span style="font-family: inherit;"&gt; The &lt;b&gt;SCRIPT_FILENAME&lt;/b&gt; becomes &lt;span style="background-color: #fce5cd; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;/var/www/vhosts/myforum.com/httpdocs/uploads/photo1234.jpg&lt;/span&gt;, which means the .jpg file actually becomes the request filename, and it gets treated as PHP.&lt;/span&gt;&lt;span style="font-family: inherit;"&gt; And &lt;b&gt;PATH_INFO&lt;/b&gt; becomes &lt;span style="background-color: #fce5cd; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;/anything.php&lt;/span&gt;.&lt;/span&gt;&lt;span style="font-family: inherit;"&gt; The original purpose of this option was to allow such kind of URLs: index.php/param1/param2/...&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;But when combined with Nginx, this turns into a major issue.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;br style="font-family: inherit;" /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;b style="color: #660000; font-family: inherit;"&gt;How do I fix it?&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;Well, the simplest thing you can do is open up your php.ini configuration file, and insert this directive in the main section:&lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: #fce5cd; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;cgi.fix_pathinfo=0&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;Then restart PHP-FPM or whatever FastCGI manager you're using.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;Unfortunately in some cases that is not possible a solution, since perhaps other scripts on your server make the most of this option.&lt;/span&gt;&lt;span style="font-family: inherit;"&gt; So you could do mainly employ two different solutions on the Nginx side.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;First, you could check that the requested URI actually exists, before passing the request via FastCGI:&lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: #fce5cd; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;location \.php$ {&lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: #fce5cd; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (!-f $request_filename) {&lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: #fce5cd; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return 404;&lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: #fce5cd; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: #fce5cd; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; fastcgi_pass 127.0.0.1:9000;&lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: #fce5cd; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [...]&lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: #fce5cd; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;This solution is efficient and a few of us Nginx+PHP have retained it.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;Otherwise, if you think it's too consuming in terms of resources, you could check the URI to meet the following requirements:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;- if the URI contains a dot, then a slash (example: image.jpg/...)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;- if the URI ends with ".php" (example: image.jpg/test.php)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;- then return a 403 error.&lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: #fce5cd; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;location ~ \..*/.*\.php$ {&lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: #fce5cd; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return 403;&lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: #fce5cd; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: #fce5cd; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;location ~ \.php$ {&lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: #fce5cd; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; fastcgi_pass 127.0.0.1:9000;&lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: #fce5cd; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: #fce5cd; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;Alternatively, you could make sure that PHP is only enabled in certain directories, where file uploads are not allowed:&lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: #fce5cd; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;location ~ ^/(scripts|sources|src)/.*\.php$ {&lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: #fce5cd; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; fastcgi_pass 127.0.0.1:9000;&lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: #fce5cd; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: #fce5cd; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;Thanks for reading.&lt;/span&gt;&lt;span style="font-family: inherit;"&gt; And if you find this vulnerability on servers that do not belong to you, contact the server administrator immediately to report the problem!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;The problem was discovered here: &lt;a href="http://www.80sec.com/nginx-securit.html"&gt;http://www.80sec.com/nginx-securit.html&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;And discussed here: &lt;a href="http://www.pubbs.net/201005/nginx/39767-nginx-0day-exploit-for-nginx-fastcgi-php.html"&gt;http://www.pubbs.net/201005/nginx/39767-nginx-0day-exploit-for-nginx-fastcgi-php.html&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;Thanks to Martin F. for reporting the issue!&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/512188703456595011-8799478154562187011?l=cnedelcu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cnedelcu.blogspot.com/feeds/8799478154562187011/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=512188703456595011&amp;postID=8799478154562187011' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/512188703456595011/posts/default/8799478154562187011'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/512188703456595011/posts/default/8799478154562187011'/><link rel='alternate' type='text/html' href='http://cnedelcu.blogspot.com/2010/05/nginx-php-via-fastcgi-important.html' title='Nginx &amp; PHP via FastCGI important security issue'/><author><name>Clément Nedelcu</name><uri>http://www.blogger.com/profile/00168228978102132365</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-512188703456595011.post-4082206337089210643</id><published>2010-05-09T18:34:00.000+02:00</published><updated>2010-05-09T18:34:30.858+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='http'/><category scheme='http://www.blogger.com/atom/ns#' term='cookies'/><category scheme='http://www.blogger.com/atom/ns#' term='400'/><category scheme='http://www.blogger.com/atom/ns#' term='troubleshooting'/><category scheme='http://www.blogger.com/atom/ns#' term='nginx'/><category scheme='http://www.blogger.com/atom/ns#' term='errors'/><title type='text'>Dealing with Nginx 400 Bad Request HTTP errors</title><content type='html'>Today I'll write about something I experienced personally, on my websites.&lt;br /&gt;Some visitors reported that they were getting a &lt;b&gt;"400 Bad Request" Nginx error&lt;/b&gt; randomly when visiting pages. And when they start getting that error, they can't access the site anymore: it'll output the same error no matter the page, until you "clear your cache and cookies".&lt;br /&gt;&lt;br /&gt;The error is easily understandable and is likely to be caused by... &lt;b&gt;too much cookie data.&lt;/b&gt;&lt;br /&gt;Every time a visitor loads *any* page/content/file of your website, it sends the cookie data to the server.&lt;br /&gt;Cookie data is sent under the form of 1 header line starting with "Cookie: ".&lt;br /&gt;&lt;br /&gt;Basically, Nginx by default is configured to accept header lines of a maximum size of 4 kilobytes.&lt;br /&gt;When a line in the headers exceeds 4 kilobytes, Nginx returns the '400 Bad Request' error.&lt;br /&gt;Cookie data sometimes gets big, so it causes the error. It particularly happens on forums like vBulletin, Invision and others.&lt;br /&gt;So why does it happen only for some web browsers (Firefox, Chrome...) and not others? Because those browsers do not limit the amount of data a cookie may store. Or maybe they do, but the limit is higher than the default 4k of Nginx. Other browsers limit the amount of cookie data so they do not have the issue.&lt;br /&gt;&lt;br /&gt;There is a simple fix for that. The &lt;b style="color: #660000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;large_client_header_buffers&lt;/b&gt; directive of Nginx allows you to define size of buffers that will contain large headers like those big fat cookies.&lt;br /&gt;&lt;br /&gt;The directive specifies: the amount of buffers, and the size of buffers. You basically need to increase the size.&lt;br /&gt;In your http block (or your server block, if you want to apply the setting at the virtual host level), insert this directive with a size larger than 4k (actually the default size can be 8k depending on your system, so let's make it... &lt;b&gt;16k&lt;/b&gt;):&lt;br /&gt;&lt;br /&gt;&lt;div style="color: #660000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;http {&lt;/div&gt;&lt;div style="color: #660000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; [...]&lt;/div&gt;&lt;div style="color: #660000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; large_client_header_buffers 4 16k;&lt;/div&gt;&lt;div style="color: #660000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; [...]&lt;/div&gt;&lt;div style="color: #660000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/div&gt;&lt;br /&gt;Save your configuration, reload nginx by running /usr/local/nginx/sbin/nginx -s reload and it should now be fine. If you ever get the "400 Bad Request" again, you could either increase this value once more or look into the code and see why cookies get so big.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/512188703456595011-4082206337089210643?l=cnedelcu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cnedelcu.blogspot.com/feeds/4082206337089210643/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=512188703456595011&amp;postID=4082206337089210643' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/512188703456595011/posts/default/4082206337089210643'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/512188703456595011/posts/default/4082206337089210643'/><link rel='alternate' type='text/html' href='http://cnedelcu.blogspot.com/2010/05/dealing-with-nginx-400-bad-request-http.html' title='Dealing with Nginx 400 Bad Request HTTP errors'/><author><name>Clément Nedelcu</name><uri>http://www.blogger.com/profile/00168228978102132365</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-512188703456595011.post-1638130076759990287</id><published>2010-05-03T05:33:00.000+02:00</published><updated>2010-05-03T05:33:12.508+02:00</updated><title type='text'>Downloading MMS streams in Linux (CentOS, Ubuntu, Debian, Fedora...) with mmsclient</title><content type='html'>Hello!&lt;br /&gt;&lt;br /&gt;So I was looking into solutions for saving a MMS stream on my server. My connection at home isn't fast enough so I cant watch most of the streams, I'd rather have those downloaded by my dedicated server and then I download the file off my server.&lt;br /&gt;&lt;br /&gt;I first looked into &lt;b&gt;mimms&lt;/b&gt;: &lt;a href="http://savannah.nongnu.org/download/mimms/"&gt;http://savannah.nongnu.org/download/mimms/&lt;/a&gt;&lt;br /&gt;Unfortunately it was written in Python and I was missing Python 2.5. After struggling with my system I couldn't get it to work (missing dependencies one after the other).&lt;br /&gt;&lt;br /&gt;So I kept looking and I found &lt;b&gt;mmsclient&lt;/b&gt;.&lt;br /&gt;The official website: &lt;a href="http://ole.tange.dk/projekter/kontroversielt/www.geocities.com/majormms/"&gt;http://ole.tange.dk/projekter/kontroversielt/www.geocities.com/majormms/&lt;/a&gt; (actually a copy of the site, which was hosted on Geocities previously).&lt;br /&gt;Scroll down to the bottom of the page where it says "mmsclient". You will find a link to download it. I've mirrored the link here just in case: &lt;a href="http://gbatemp.net/up/mms_client-0.0.3.tar.gz"&gt;http://gbatemp.net/up/mms_client-0.0.3.tar.gz&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;To install mmsclient, follow these simple steps:&lt;br /&gt;1) Download the package:&lt;br /&gt;&lt;div style="color: #660000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;wget http://gbatemp.net/up/mms_client-0.0.3.tar.gz&lt;/div&gt;2) Extract it:&lt;br /&gt;&lt;div style="color: #660000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;tar xzvf mms_client-0.0.3.tar.gz&lt;/div&gt;3) Configure, make, make install:&lt;br /&gt;&lt;div style="color: #660000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;cd mms_client-0.0.3&lt;/span&gt;&lt;/div&gt;&lt;div style="color: #660000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;./configure&lt;/span&gt;&lt;/div&gt;&lt;div style="color: #660000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;make &amp;amp;&amp;amp; make install&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;That's it! Now you can download mms streams. Just use the "mmsclient" command, followed by the URL of the stream you want to download:&lt;br /&gt;&lt;div style="color: #660000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;mmsclient mms://example.com/stream.wmv&lt;/div&gt;Additionally, you will notice that it outputs a lot of data to the command line window. To make it quiet, add &amp;gt;/dev/null at the end:&lt;br /&gt;&lt;br /&gt;&lt;div style="color: #660000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;mmsclient mms://example.com/stream.wmv &amp;gt;/dev/null&lt;/div&gt;&lt;br /&gt;Enjoy your downloaded streams!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/512188703456595011-1638130076759990287?l=cnedelcu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cnedelcu.blogspot.com/feeds/1638130076759990287/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=512188703456595011&amp;postID=1638130076759990287' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/512188703456595011/posts/default/1638130076759990287'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/512188703456595011/posts/default/1638130076759990287'/><link rel='alternate' type='text/html' href='http://cnedelcu.blogspot.com/2010/05/downloading-mms-streams-in-linux-centos.html' title='Downloading MMS streams in Linux (CentOS, Ubuntu, Debian, Fedora...) with mmsclient'/><author><name>Clément Nedelcu</name><uri>http://www.blogger.com/profile/00168228978102132365</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-512188703456595011.post-1467938425159698726</id><published>2009-09-30T09:03:00.001+02:00</published><updated>2009-09-30T09:03:59.182+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='caching'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='memcached'/><category scheme='http://www.blogger.com/atom/ns#' term='memcache'/><category scheme='http://www.blogger.com/atom/ns#' term='centos'/><category scheme='http://www.blogger.com/atom/ns#' term='php'/><title type='text'>Setting up and using memcached &amp; memcache on Linux CentOS 5/Plesk 9</title><content type='html'>The second part of my tutorial on optimizing your server for hosting high traffic websites: installing and configuring memcached and the memcache php extension for your server. This is a little easier than the first step (setting up nginx as reverse proxy, see article below) and can be applied to any kind of dynamic website.&lt;br /&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;What's the point ?&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;On highly dynamic websites such as forums, news sites or any user content based website, the database server load is often very high. The more traffic you get, the more cluttered your database server becomes, sometimes rendering your website completely unavailable to visitors. Using a data caching daemon will allow you to save some data in memory instead of fetching the data from the database every time. You should know that memcached is used by major websites such as Wikipedia, SourceForge, SlashDot... need I say more?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;What is memcached ?&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;Memcached is the daemon running on your server. Its usage is extremely simple, there are no configuration files, all you do is start the daemon on a given port, and your websites will connect to this daemon to store data in memory. Yes, the data is stored in your RAM. So when starting memcached you'll have to decide how much RAM memcached will be allowed to use. If you start memcached with a 1GB memory space, memcached will store this much data; when the cache is full some of the older data will begin to disappear from the cache.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;What is memcache ?&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;Memcache, in our case, is the PHP extension that will allow us to connect to and make use of Memcached. This PHP extension is not part of the default ones so you'll have to download and install it (see step 2). It provides classes as well as functions that I must admit are very easy to use and understandable. In this article, I provide a mysql+memcache wrapper class for anyone to use.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;What is the difference between memcached and memcache ?&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;Well if you've read the two points above, you should already know. In short, memcached is the daemon running on your machine; memcache is the PHP extension allowing you to make use of memcached.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;1. Setting up memcached&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;I haven't found memcached in my repositories (might aswell try # yum install memcached just in case?) so I'll download the source and compile it. First go get the latest version from the &lt;a href="http://www.danga.com/memcached/"&gt;official website&lt;/a&gt;.&lt;br /&gt;&lt;div style="background-color: white; color: #45818e;"&gt;# wget http://memcached.googlecode.com/files/memcached-1.4.1.tar.gz&lt;br /&gt;&lt;/div&gt;&lt;div style="background-color: white; color: #45818e;"&gt;# tar zxvf memcached-1.4.1.tar.gz&lt;br /&gt;&lt;/div&gt;&lt;div style="background-color: white; color: #45818e;"&gt;# cd memcached-1.4.1&lt;br /&gt;&lt;/div&gt;&lt;div style="background-color: white; color: #45818e;"&gt;# ./configure&lt;br /&gt;&lt;/div&gt;If like me you get this message "libevent is missing" or something, you can run this command:&lt;br /&gt;&lt;div style="color: #45818e;"&gt;# yum install libevent-devel&lt;br /&gt;&lt;/div&gt;And then run configure again: &lt;br /&gt;&lt;div style="color: #45818e;"&gt;# ./configure&lt;br /&gt;&lt;/div&gt;Install memcached: &lt;br /&gt;&lt;span style="color: #45818e;"&gt;# make install&lt;/span&gt;&lt;br /&gt;That's it, you're set! That was pretty easy wasn't it? We'll now see the command line arguments for starting memcached:&lt;br /&gt;&lt;span style="color: #45818e;"&gt;# memcached -d -m 1024 -l 127.0.0.1 -p 11211 -u nobody&lt;/span&gt;&lt;br /&gt;The arguments are:&lt;br /&gt;&lt;b&gt;-d &lt;/b&gt;: start as daemon, running in the background&lt;br /&gt;&lt;b&gt;-m 1024&lt;/b&gt;: allow memcached to use up to 1024 MB of RAM (1GB)&lt;br /&gt;&lt;b&gt;-l 127.0.0.1&lt;/b&gt;: listen on local interface&lt;br /&gt;&lt;b&gt;-p 11211&lt;/b&gt;: listen on port 11211&lt;br /&gt;&lt;b&gt;-u nobody&lt;/b&gt;: run as user "nobody"&lt;br /&gt;&lt;br /&gt;If you're not sure how much memory you should allocate to memcached, try running this command first:&lt;br /&gt;&lt;div style="color: #45818e;"&gt;# free&lt;br /&gt;&lt;/div&gt;It will tell you how much free RAM you've got left.&lt;br /&gt;Note that upon starting memcached, if all is OK, you will see no output message. To see if memcached is correctly started, run this command:&lt;br /&gt;&lt;div style="color: #45818e;"&gt;# ps aux | grep memcached&lt;br /&gt;&lt;/div&gt;You should be seeing something like this:&lt;br /&gt;&lt;div style="color: #45818e;"&gt;nobody&amp;nbsp;&amp;nbsp; 13133&amp;nbsp; 0.0&amp;nbsp; 0.0&amp;nbsp; 43580&amp;nbsp;&amp;nbsp; 732 ?&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Ssl&amp;nbsp; 07:11&amp;nbsp;&amp;nbsp; 0:00 memcached -d -m 128 -l 127.0.0.1 -p 11211 -u nobody&lt;br /&gt;user &amp;nbsp;&amp;nbsp;&amp;nbsp; 13143&amp;nbsp; 0.0&amp;nbsp; 0.0&amp;nbsp;&amp;nbsp; 4152&amp;nbsp;&amp;nbsp; 648 pts/0&amp;nbsp;&amp;nbsp;&amp;nbsp; R+&amp;nbsp;&amp;nbsp; 07:11&amp;nbsp;&amp;nbsp; 0:00 grep memcached&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #45818e;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;2. Setting up memcache PHP extension&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;The memcache PHP extension should be found in the classic repositories, so try this command:&lt;br /&gt;&lt;div style="color: #45818e;"&gt;# yum install php-pecl-memcache&lt;br /&gt;&lt;/div&gt;If you're lucky (why should you be unlucky anyway?) the install will work fine and you'll be seeing these messages:&lt;br /&gt;&lt;span style="color: #45818e;"&gt;Installed: php-pecl-memcache.i386 0:2.2.3-1.el5_2&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #45818e;"&gt;Dependency Installed: php-pear.noarch 1:1.4.9-4.el5.1&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #45818e;"&gt;Complete!&lt;/span&gt;&lt;br /&gt;Just for reference, &lt;a href="http://www.php.net/memcache"&gt;here's a link&lt;/a&gt; to the official memcache website, if you need to grab the sources.&lt;br /&gt;&lt;br /&gt;&amp;nbsp;Let's see if memcache was installed properly. First restart the httpd:&lt;br /&gt;&lt;span style="color: #45818e;"&gt;&amp;nbsp;# service httpd restart&lt;/span&gt;&lt;br /&gt;Then place a simple php file on your website containing the following code:&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="color: #444444;"&gt;phpinfo();&amp;nbsp; &lt;/span&gt;&lt;br /&gt;&lt;/div&gt;Open the PHP file in your browser (eg. http://mydomain.com/phpinfo.php ) and have a look at the output. If you can find a "memcache" section looking like the following picture, it means memcache was successfully installed.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_Ixt0VU0h5eU/SsLr5q08xwI/AAAAAAAAAqI/BFgxYZNoCsU/s1600-h/memcache.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_Ixt0VU0h5eU/SsLr5q08xwI/AAAAAAAAAqI/BFgxYZNoCsU/s320/memcache.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;We will now have a look at the memcache configuration file. First locate your php module configuration files folder, in my case /etc/php.d/ . You should find the newly installed "memcache.ini" configuration file. Open it up to see a list of configuration keys and their meaning.&lt;br /&gt;&lt;/div&gt;The default options are just fine, but if you're interested, you should know that memcache offers load-balancing features through the "allow_failover" configuration key. I'm not going to make use of this feature so I will not be editing any of the settings.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;3. Using memcache in your code&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;Unfortunately, installing both components isn't enough. You'll have to edit your code in order to make use of the caching features. Be reassured though, it couldn't be easier! There are a couple of functions you'll need to use, nothing complex.&lt;br /&gt;If you want to find out the complete listing of the memcache php functions, visit the &lt;a href="http://www.php.net/memcache"&gt;official website&lt;/a&gt;. Basically we'll be using 5 methods:&lt;br /&gt;- &lt;b&gt;Memcache::connect&lt;/b&gt;($host, $port, $timeout): connect to your daemon&lt;br /&gt;- &lt;b&gt;Memcache::get&lt;/b&gt;($key) : fetch data from your cache&lt;br /&gt;- &lt;b&gt;Memcache::set&lt;/b&gt;($key, $var, $flag, $expire): store data in your cache&lt;br /&gt;- &lt;b&gt;Memcache::delete&lt;/b&gt;($key): remove data from your cache&lt;br /&gt;- &lt;b&gt;Memcache::close&lt;/b&gt;(): disconnect.&lt;br /&gt;&lt;br /&gt;You can cache any data that you want:&lt;br /&gt;&lt;div style="color: #444444; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;$mc = new Memcache;&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #444444; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;$mc-&amp;gt;connect("localhost", 11211);&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #444444; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;$saved_data = $mc-&amp;gt;get("saved_data");&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #444444; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;if (!$saved_data) {&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #444444; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; $saved_data = file_get_contents("myfile.txt");&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #444444; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; $mc-&amp;gt;set("saved_data", $saved_data, MEMCACHE_COMPRESSED, 60*60*24*7); // store for 7 days&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #444444; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #444444; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;echo $saved_data;&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #444444; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;$mc-&amp;gt;close();&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Applied to MySQL queries:&lt;br /&gt;&lt;br /&gt;&lt;div style="color: #444444; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;$mc = new Memcache;&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #444444; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;$mc-&amp;gt;connect("localhost", 11211);&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #444444; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;$news_articles = $mc-&amp;gt;get("news_articles");&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #444444; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;if (!$news_articles) {&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #444444; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; $news_articles = array();&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #444444; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; $query = "SELECT * FROM news_articles ORDER BY article_id DESC LIMIT 0,10";&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #444444; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; $result = mysql_query($query);&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #444444; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; while($row = mysql_fetch_assoc($result)) $news_articles[] = $row;&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #444444; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; $mc-&amp;gt;set("news_articles", serialize($news_articles), MEMCACHE_COMPRESSED, 60*60*24*7);&lt;span style="color: orange;"&gt; // store for 7 days, but don't forget to rebuild the cache when a new article is posted!&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #444444; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;} else {&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #444444; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; $news_articles = unserialize($news_articles);&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #444444; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #444444; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="color: orange;"&gt;// Display articles.. &lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;span style="color: #444444; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;$mc-&amp;gt;close();&lt;/span&gt;&lt;br /&gt;As you can see in the example above, I use the "serialize" and "unserialize" php functions. Why is that? The reason is because the Memcache::get() function always returns a string. So if you want to store an array of data (or an object), you'll have to serialize said array, and unserialize it after having read it from the database.&lt;br /&gt;If you know a better workaround for this problem please feel free to leave a comment.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;4. Wrapper class for memcache &amp;amp; mysql&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;I have just written a simple wrapper class for MySQL, making use of the powerful caching system offered by memcache. You can &lt;a href="http://gbatemp.net/up/class_mysql_memcache.zip"&gt;download the class here&lt;/a&gt;, I included a simple example for testing the class.&lt;br /&gt;The principle is very simple: when executing a query, the script will check if the query result is already in the cache. If the data is in the cache, it is returned immediatly (no query executed). if the data is not in the cache, the query is executed, and the results are then placed in the cache with the specified "time to live".&lt;br /&gt;&lt;br /&gt;Here are the wrapper class functions:&lt;br /&gt;function &lt;b&gt;MySQLMemcache&lt;/b&gt;($mysql_info, $memcache_info, $autoconnect=true, $enable_logging=true);&lt;br /&gt;function &lt;b&gt;connect&lt;/b&gt;();&lt;br /&gt;function &lt;b&gt;disconnect&lt;/b&gt;();&lt;br /&gt;function &lt;b&gt;dataQuery&lt;/b&gt;($query, $usecache=true, $ttl=0);&lt;br /&gt;function &lt;b&gt;nonDataQuery&lt;/b&gt;($query);&lt;br /&gt;function &lt;b&gt;fieldDataQuery&lt;/b&gt;($query, $field, $usecache=true, $ttl=0);&lt;br /&gt;&lt;br /&gt;More documentation is provided inside the actual php file.&lt;br /&gt;&lt;br /&gt;Thank you for reading, feel free to leave a comment if this article has been helpful to you.&lt;br /&gt;I'm finished with my server optimization thematic.&lt;br /&gt;TTFN!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/512188703456595011-1467938425159698726?l=cnedelcu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cnedelcu.blogspot.com/feeds/1467938425159698726/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=512188703456595011&amp;postID=1467938425159698726' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/512188703456595011/posts/default/1467938425159698726'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/512188703456595011/posts/default/1467938425159698726'/><link rel='alternate' type='text/html' href='http://cnedelcu.blogspot.com/2009/09/setting-up-and-using-memcached-memcache.html' title='Setting up and using memcached &amp; memcache on Linux CentOS 5/Plesk 9'/><author><name>Clément Nedelcu</name><uri>http://www.blogger.com/profile/00168228978102132365</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_Ixt0VU0h5eU/SsLr5q08xwI/AAAAAAAAAqI/BFgxYZNoCsU/s72-c/memcache.png' height='72' width='72'/><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-512188703456595011.post-8327192585126884229</id><published>2009-09-29T16:33:00.001+02:00</published><updated>2010-03-06T08:53:07.584+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='vhosts'/><category scheme='http://www.blogger.com/atom/ns#' term='centos'/><category scheme='http://www.blogger.com/atom/ns#' term='nginx'/><category scheme='http://www.blogger.com/atom/ns#' term='plesk'/><category scheme='http://www.blogger.com/atom/ns#' term='apache'/><category scheme='http://www.blogger.com/atom/ns#' term='init.d'/><title type='text'>Setting up nginx as reverse proxy on Linux Centos 5.2 (and Plesk 9)</title><content type='html'>Following my blog article on optimizing your web server by using nginx and memcached, I'll now detail the first step: setting up nginx as reverse proxy on your server. This is going to be a bit tricky, and you'll be getting your hands dirty, so be warned.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;What does this consist in?&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;Well basically, your website will be served by two daemons: nginx for the static content (images, js, css, html...) and Apache for the dynamic content. Nginx will be listening on port 80, will serve static content to visitors, and redirect any dynamic data query to Apache, running on another port -- in our case we'll be using port 8080.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;What is nginx?&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;Nginx is a lightweight open-source http daemon (http server). It is said to be extremely fast, a lot more than Apache, and I have to admit by personal experience this seems to be very true. Using nginx for serving static content dramatically improved the speed of my high traffic website. Actually, some major websites such as Wordpress.com, *cough* Youporn.com, use nginx exclusively for serving web content.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;Major issues&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;This configuration is a bit tricky and can be difficult to achieve particularly if you have numerous domains &amp;amp; subdomains. There are several issues with this configuration:&lt;br /&gt;1) I happen to be using Plesk 9 (admin control panel) for easy domain &amp;amp; subdomain management. Unfortunately it doesn't seem to be compatible with nginx at the moment, it only works with Apache. So we'll run into a few problems very soon.&lt;br /&gt;2) We'll have to work out the configuration files manually (including vhosts - virtual hosts configurations)&amp;nbsp; so be careful about what you're doing or you might run into annoying problems.&lt;br /&gt;3) Plesk rebuilds the virtual hosts configuration files every time you make the slightest change in the web configuration.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;Step 1: download and install nginx&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;nginx requires the PCRE library. If it's not installed on your system, run the following command: &lt;br /&gt;&lt;div style="color: #0b5394;"&gt;# yum install pcre&lt;/div&gt;&lt;div style="color: #0b5394;"&gt;# yum install pcre-devel&lt;/div&gt;Try these libraries aswell just in case they aren't on your system already:&lt;br /&gt;&lt;div style="color: #0b5394;"&gt;# yum install zlib&lt;/div&gt;&lt;div style="color: #0b5394;"&gt;# yum install openssl&lt;/div&gt;&lt;div style="color: #0b5394;"&gt;# yum install openssl-devel&lt;/div&gt;&lt;div style="color: #0b5394;"&gt;# yum install gcc&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Visit the official nginx website (&lt;a href="http://www.nginx.net/"&gt;nginx.net&lt;/a&gt;) and find the latest version. From your shell, run this command:&lt;br /&gt;&lt;div style="color: #0b5394;"&gt;# wget http://sysoev.ru/nginx/nginx-0.7.62.tar.gz&lt;/div&gt;Unzip the files with the following command&lt;br /&gt;&lt;div style="color: #0b5394;"&gt;# tar zxvf ./nginx-0.7.62.tar.gz&lt;/div&gt;Change directory to the nginx folder &lt;br /&gt;&lt;div style="color: #0b5394;"&gt;# cd nginx-0.7.62&lt;/div&gt;Run the following commands:&lt;br /&gt;&lt;div style="color: #0b5394;"&gt;# ./configure&lt;/div&gt;If you get no errors, you're all set, go on with the next couple of commands. If you get an error, try to make sure all the libraries are installed.&lt;br /&gt;&lt;div style="color: #0b5394;"&gt;# make&lt;/div&gt;&lt;div style="color: #0b5394;"&gt;# make install&lt;/div&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;2. Nginx base configuration&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;Congrats if you've made it this far! Now let's have a look at the base configuration of nginx. By default, the main configuration file should be found here: /usr/local/nginx/conf/nginx.conf or /etc/nginx/nginx.conf &lt;br /&gt;Open it up and we'll have a look at some of the settings:&lt;br /&gt;&lt;b&gt;- worker_processes : &lt;/b&gt;the amount of processes that will be ran. In most architectures, 1 process = 1 core; so if you want to fully make use of your multi-core CPU, might aswell use as many processes as your CPU has cores. In my case my CPU's a quad-core, so I'll be using 4 worker processes.&lt;br /&gt;&lt;b&gt;- worker_connections :&lt;/b&gt; how many connections a process will accepted simultaneously.&lt;br /&gt;For more configuration keys, I suggest having a look &lt;a href="http://articles.slicehost.com/2008/5/15/ubuntu-hardy-nginx-configuration/"&gt;here&lt;/a&gt; ! Excellent article.&lt;br /&gt;If you can't be arsed, here's the configuration I'll use:&lt;br /&gt;&lt;b&gt;- user apache apache;&lt;/b&gt; # might aswell use the same user and user group as apache! this will allow nginx to have read permissions on the same files as apache&lt;br /&gt;- &lt;b&gt;#tcp_nopush on&lt;/b&gt; -- leave this commented.&lt;br /&gt;&lt;div style="font-family: inherit;"&gt;-&amp;nbsp; &lt;code&gt;&lt;b&gt;tcp_nodelay        on;&lt;/b&gt; # to be inserted below #tcp_nopush on;&lt;br /&gt;&lt;/code&gt;&lt;/div&gt;&lt;div style="font-family: inherit;"&gt;&lt;code&gt;- &lt;b&gt;keepalive_timeout 30;&lt;/b&gt; # should be enough unless your site's really slow&lt;/code&gt;&lt;/div&gt;&lt;div style="font-family: inherit;"&gt;&lt;code&gt;- &lt;b&gt;gzip on;&lt;/b&gt; # yeah, why disable it? unless you have a really crappy CPU...&lt;/code&gt;&lt;/div&gt;&lt;div style="font-family: inherit;"&gt;&lt;code&gt;- &lt;/code&gt;&lt;code&gt;&lt;b&gt;gzip_proxied any;&lt;/b&gt; # proxied requests will also be gzipped&lt;/code&gt;&lt;/div&gt;&lt;div style="font-family: inherit;"&gt;&lt;code&gt;- &lt;/code&gt;&lt;code&gt;&lt;b&gt;gzip_comp_level 2;&lt;/b&gt; # set gzip compression to 2 (from 1-fast to 9-highly compressed)&lt;/code&gt;&lt;/div&gt;&lt;div style="font-family: inherit;"&gt;&lt;code&gt;&lt;br /&gt;&lt;/code&gt;&lt;/div&gt;&lt;div style="font-family: inherit;"&gt;&lt;code&gt;&lt;span style="font-family: inherit;"&gt;There isn't much more to configure here, so we'll start configuring Apache. But before doing so, there's one little additional configuration directive we'll add to nginx.conf, which will make handling virtual hosts a lot easier. In the nginx configuration folder, create a new folder: sites &lt;/span&gt;( &lt;/code&gt;/usr/local/nginx/conf/sites/ ).&lt;/div&gt;&lt;div style="font-family: inherit;"&gt;In the configuration file, below the configuration directives you've put above, insert that new one:&lt;/div&gt;&lt;pre style="font-family: inherit;"&gt;&lt;b&gt;&lt;code&gt;include &lt;/code&gt;/usr/local/nginx/conf/sites/&lt;code&gt;*.conf;&amp;nbsp;&lt;/code&gt;&lt;/b&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;3. Configuring Apache&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;This is where it'll get dirty. If like me you run Plesk, you probably already have some vhost configuration files all over. You'll have to edit these configuration files one by one, after having modified the main conf file.&lt;br /&gt;&lt;br /&gt;- Open your main apache configuration file, probably located somewhere like: /etc/httpd/conf/httpd.conf. Find the "Listen" directive at the beginning of your configuration file. It's probably already set to listen on port 80, so change it to port 8080, and add the line below. &lt;br /&gt;&lt;div style="color: #38761d;"&gt;&lt;b&gt;Listen &lt;/b&gt;8080&lt;/div&gt;&lt;div style="color: #38761d;"&gt;&lt;b&gt;NameVirtualHost &lt;/b&gt;X.X.X.X:8080 &lt;/div&gt;Replace X.X.X.X by your actual server IP address. Save and close the file.&lt;br /&gt;&lt;br /&gt;- Open your vhosts configuration files one by one, we're going to make some changes. If like me you're using Plesk, the config files for each domain should be located here: /var/www/vhosts/mydomain.com/conf/httpd.include&lt;br /&gt;Replace all references of port 80 by 8080.&lt;br /&gt;Example:&lt;br /&gt;&lt;b&gt;&lt;span style="color: #38761d;"&gt;&amp;lt; VirtualHost 49.32.113.160:&lt;i&gt;80 &lt;/i&gt;&amp;gt;&lt;/span&gt;&lt;/b&gt; =&amp;gt; &lt;b&gt;&lt;span style="color: #38761d;"&gt;&amp;lt; VirtualHost 49.32.113.160:&lt;i&gt;8080 &lt;/i&gt;&amp;gt; &lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;virtualhost 74.125.153.191:80=""&gt; &lt;/virtualhost&gt;&lt;b style="color: #38761d;"&gt;ServerName&amp;nbsp;&amp;nbsp; mydomain.com:&lt;i&gt;80&lt;/i&gt;&lt;/b&gt;&amp;nbsp; =&amp;gt;&amp;nbsp; &lt;b&gt;&lt;span style="color: #38761d;"&gt;ServerName&amp;nbsp;&amp;nbsp; mydomain.com:&lt;i&gt;8080 &lt;/i&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;Do the same for all domains and subdomains that use port 80. We can't allow Apache to use port 80 as it'll be used by nginx! No need to edit the 443 references though, we'll still use Apache for all our https content.&lt;br /&gt;&lt;br /&gt;- Once you've edited the configuration files of all your websites, reload your httpd service: service httpd restart.&lt;br /&gt;An error may (or may not) appear upon restarting:  &lt;i&gt;[warn] VirtualHost 49.32.113.160:8080 overlaps with VirtualHost 49.32.113.160:8080, the first has precedence, perhaps you need a NameVirtualHost directive&lt;/i&gt;.&lt;br /&gt;No need to worry, the fix is simple. Pick one of the vhosts configuration file. Find a vhost directive section such as this: &lt;virtualhost 74.125.153.191:8080=""&gt;, and add below: NameVirtualHost X.X.X.X:8080 where X.X.X.X is your server's IP address. Save the conf file and reload httpd.&lt;/virtualhost&gt;&lt;br /&gt;&lt;br /&gt;If your httpd reloads without warnings or error, you can proceed to the next section. Otherwise, read carefully the steps I've described above to see if you missed anything.&lt;br /&gt;You can test your changes by accessing your website on port 8080, for example: http://www.mydomain.com:8080/ . Your website should load, even though there might be some display errors due to the port change.&lt;br /&gt;&lt;br /&gt;Major issue: when you make any change to the web configuration in Plesk, Plesk rebuilds the vhosts configuration files, which means you'll have to make these changes every time you modify the configuration! There may be some way to prevent this, if you know any, please let me know by posting a comment, I'd be very grateful.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;4. Configuring nginx as reverse proxy&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;So far, we've only installed nginx, and made Apache listen on port 8080 instead of 80. If you stop here, everything's pretty much broken. So read on.&lt;br /&gt;The next step is to configure nginx in order to redirect dynamic content requests to Apache, and return them to the user properly. Start by creating a new file in the nginx configuration folder (same folder as your nginx.conf). Name this file proxy.conf. In this file we'll define the proxy settings. I won't detail each of the settings, this would take ages and you might aswell use the settings below as they should be valid for most sites:&lt;br /&gt;&lt;pre class="apache" style="font-family: monospace;"&gt;proxy_redirect     &lt;span style="color: blue;"&gt;off&lt;/span&gt;;&lt;br /&gt;proxy_set_header   Host             $host;&lt;br /&gt;proxy_set_header   X-Real-IP        $remote_addr;&lt;br /&gt;proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;&lt;br /&gt;client_max_body_size       10m;&lt;br /&gt;client_body_buffer_size    128k;&lt;br /&gt;proxy_connect_timeout      &lt;span style="color: red;"&gt;90&lt;/span&gt;;&lt;br /&gt;proxy_send_timeout         &lt;span style="color: red;"&gt;90&lt;/span&gt;;&lt;br /&gt;proxy_read_timeout         &lt;span style="color: red;"&gt;90&lt;/span&gt;;&lt;br /&gt;proxy_buffer_size          4k;&lt;br /&gt;proxy_buffers               &lt;span style="color: red;"&gt;4&lt;/span&gt; 32k;&lt;br /&gt;proxy_busy_buffers_size     64k;&lt;br /&gt;proxy_temp_file_write_size 64k;&lt;/pre&gt;Credit: &lt;a href="http://www.papygeek.com/software/optimiser-son-serveur-web-avec-nginx/"&gt;papygeek.com&lt;/a&gt;&lt;br /&gt;Paste the above lines in the proxy.conf file you've created. We'll be using this file to configure the proxy options in each of our virtual hosts. That's not all though, there is a problem introduced by the proxification of our architecture: how is Apache going to know the real client's IP address? Since nginx will forward the http requests, Apache will be receiving the nginx IP address, in other words, your local IP (your server's IP address). In order to fix this problem, an apache module was created: mod_rpaf.&lt;br /&gt;&lt;br /&gt;Begin by installing said module:&lt;br /&gt;&lt;div style="color: #45818e;"&gt;# wget http://stderr.net/apache/rpaf/download/mod_rpaf-0.6.tar.gz&lt;/div&gt;&lt;div style="color: #45818e;"&gt;# tar zxvf mod_rpaf-0.6.tar.gz&lt;/div&gt;&lt;div style="color: #45818e;"&gt;# cd mod_rpaf-0.6&lt;/div&gt;&lt;span style="color: #45818e;"&gt;# make rpaf-2.0 &amp;amp;&amp;amp; make install-2.0&lt;/span&gt;&lt;br /&gt;If you run apache2, replace "apxs" by "apxs2" in the command below. If apxs/2 isn't installed on your machine, run this command first: yum install httpd-devel&lt;br /&gt;&lt;div style="color: #45818e;"&gt;# apxs -i -c -n mod_rpaf-2.0.so mod_rpaf-2.0.c&lt;br /&gt;# a2enmod rpaf&lt;/div&gt;&lt;div style="color: #45818e;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #45818e;"&gt;# service httpd restart&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;5. Configuring the virtual hosts&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Let's now see the final part of this tutorial: configuring the virtual hosts for nginx. First go to your "sites" folder, which you created in the nginx configuration folder (default should be /usr/local/nginx/conf/sites/ ). We'll do this the clean way: for each domain hosted on your machine, create a new .conf file.&lt;br /&gt;&lt;br /&gt;Here is the configuration for the "mydomain.com" domain (and thus the content of your mydomain.conf) :&lt;br /&gt;&lt;div style="color: #666666;"&gt;&lt;b&gt;server &lt;/b&gt;{&lt;br /&gt;&amp;nbsp; &lt;b&gt;listen&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/b&gt;80;&lt;br /&gt;&amp;nbsp; &lt;b&gt;server_name&lt;/b&gt; www.mydomain.com;&lt;br /&gt;&amp;nbsp; &lt;b&gt;access_log&lt;/b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; off; &lt;span style="color: orange;"&gt;# Apache already creates access logs, I'd disable them unless you really need them&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &lt;b&gt;error_log&lt;/b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /var/log/httpd/nginx.errors.mydomain.com.log warn; &lt;span style="color: orange;"&gt;# error log, level "warn":&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &lt;span style="color: orange;"&gt;# Forward requests to Apache! This is the key to our system&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &lt;b&gt;location&lt;/b&gt; / {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;b&gt;proxy_pass&lt;/b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; http://www.mydomain.com:8080/;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;b&gt;include&lt;/b&gt;&amp;nbsp; /usr/local/nginx/conf/proxy.conf; &lt;span style="color: orange;"&gt;# the proxy.conf file &lt;/span&gt;&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&lt;span style="color: orange;"&gt; # Select files to be deserved by nginx&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &lt;b&gt;location &lt;/b&gt;~* ^.+\.(jpg|jpeg|gif|css|png|js|ico|txt|srt|swf|zip|rar|html|htm|pdf)$ {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;b&gt;root&amp;nbsp; &lt;/b&gt;/var/www/vhosts/mydomain.com/httpdocs; &lt;span style="color: orange;"&gt;# the httpdocs folder of your domain&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;b&gt;expires&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/b&gt;7d; &lt;span style="color: orange;"&gt;# caching, expire after 7 days&lt;/span&gt;&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;}&lt;/div&gt;&lt;div style="color: #666666;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #666666;"&gt;&lt;span style="color: orange;"&gt;# same configuration, without the www. &lt;/span&gt;&lt;/div&gt;&lt;div style="color: #666666;"&gt;&lt;b&gt;server &lt;/b&gt;{&lt;br /&gt;&amp;nbsp; &lt;b&gt;listen&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/b&gt;80;&lt;br /&gt;&amp;nbsp; &lt;b&gt;server_name&lt;/b&gt; mydomain.com;&lt;br /&gt;&amp;nbsp; &lt;b&gt;access_log&lt;/b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; off;&lt;/div&gt;&lt;div style="color: #666666;"&gt;&amp;nbsp; &lt;b&gt;error_log&lt;/b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /var/log/httpd/nginx.errors.mydomain.com.log warn;&lt;/div&gt;&lt;div style="color: #666666;"&gt;&amp;nbsp; &lt;b&gt;location &lt;/b&gt;/ {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;b&gt;proxy_pass&lt;/b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; http://mydomain.com:8080/;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;b&gt;include&amp;nbsp; &lt;/b&gt;/usr/local/nginx/conf/proxy.conf; &lt;span style="color: orange;"&gt;# the proxy.conf file &lt;/span&gt;&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; &lt;b&gt;location &lt;/b&gt;~* ^.+\.(jpg|jpeg|gif|css|png|js|ico|txt|srt|swf|zip|rar|html|htm|pdf)$ {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;b&gt;root&amp;nbsp; &lt;/b&gt;/var/www/vhosts/mydomain.com/httpdocs;&lt;/div&gt;&lt;div style="color: #666666;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;b&gt;expires&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/b&gt;7d;&lt;/div&gt;&lt;div style="color: #666666;"&gt;&amp;nbsp; }&lt;br /&gt;}&lt;/div&gt;&lt;div style="color: #666666;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #666666;"&gt;&lt;span style="color: orange;"&gt;# subdomains! replace "mysubdomain" by your subdomain name&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #666666;"&gt;&lt;b&gt;server &lt;/b&gt;{&lt;br /&gt;&amp;nbsp; &lt;b&gt;listen&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/b&gt;80;&lt;br /&gt;&amp;nbsp;&lt;b&gt; server_name&lt;/b&gt; mysubdomain.mydomain.com;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;b&gt;access_log&amp;nbsp;&amp;nbsp;&lt;/b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; off;&lt;/div&gt;&lt;div style="color: #666666;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;b&gt;error_log&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /var/log/httpd/nginx.errors.mysubdomain.mydomain.com.log warn;&lt;br /&gt;&amp;nbsp; &lt;b&gt;location &lt;/b&gt;/ {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;b&gt; proxy_pass&lt;/b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; http://mysubdomain.mydomain.com:8080/;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;b&gt;include&amp;nbsp; &lt;/b&gt;/usr/local/nginx/conf/proxy.conf; &lt;span style="color: orange;"&gt;# the proxy.conf file &lt;/span&gt;&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &lt;b&gt;location &lt;/b&gt;~* ^.+\.(jpg|jpeg|gif|css|png|js|ico|txt|srt|swf|zip|rar|html|htm|pdf)$ {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;b&gt;root&amp;nbsp; &lt;/b&gt;/var/www/vhosts/mydomain.com/subdomains/mysubdomain/httpdocs; &lt;span style="color: orange;"&gt;# httpdocs folder of your subdomain&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;b&gt;expires&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/b&gt;7d;&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;}&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Feel free to copy the subdomain section as many times as you have subdomains.&lt;br /&gt;Try your nginx configuration by running the following command:&lt;br /&gt;&lt;span style="color: #45818e;"&gt;# /usr/local/nginx/sbin/nginx -t&lt;/span&gt;&lt;br /&gt;You should be receiving this message, provided you've done it correctly: &lt;br /&gt;&lt;i&gt;the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok&lt;br /&gt;configuration file /usr/local/nginx/conf/nginx.conf test is successful&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;6. Setting nginx as service &amp;amp; startup&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;I've written an init.d script for you to use. Nearly all the credit goes to &lt;a href="http://articles.slicehost.com/2007/12/3/ubuntu-gutsy-adding-an-nginx-init-script"&gt;Slicehost&lt;/a&gt; for writing the original Ubuntu one; the one I wrote is for CentOS, although it should work for other systems: &lt;a href="http://gbatemp.net/up/nginx-startup-script.zip"&gt;download here&lt;/a&gt;. Unzip it and place it in your /etc/rc/init.d/ folder. If you have placed the nginx binary in a different folder, you'll have to open up the script and change the $DAEMON path. Give it execute permissions ( chmod +x /etc/rc/init.d/nginx ), after which you'll be able to use the following commands:&lt;br /&gt;Starting the server: &lt;span style="color: #45818e;"&gt;# service nginx start&lt;/span&gt;&lt;br /&gt;Stopping the server: &lt;span style="background-color: white; color: #45818e;"&gt;# service nginx stop&lt;/span&gt;&lt;br /&gt;Reloading the configuration: &lt;span style="color: #45818e;"&gt;# service nginx reload&lt;/span&gt;&lt;br /&gt;Restarting the server: &lt;span style="color: #45818e;"&gt;# service nginx restart&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;If you wish, you can add the "&lt;b&gt;service nginx start&lt;/b&gt;" command in the &lt;b&gt;/etc/rc.local&lt;/b&gt; file, this will allow you service to be ran on startup.&lt;br /&gt;&lt;br /&gt;Well, I guess that's about it!&lt;br /&gt;The next article will deal with memcached, so stay tuned!&lt;br /&gt;Clem&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/512188703456595011-8327192585126884229?l=cnedelcu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cnedelcu.blogspot.com/feeds/8327192585126884229/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=512188703456595011&amp;postID=8327192585126884229' title='14 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/512188703456595011/posts/default/8327192585126884229'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/512188703456595011/posts/default/8327192585126884229'/><link rel='alternate' type='text/html' href='http://cnedelcu.blogspot.com/2009/09/setting-up-nginx-as-reverse-proxy-on.html' title='Setting up nginx as reverse proxy on Linux Centos 5.2 (and Plesk 9)'/><author><name>Clément Nedelcu</name><uri>http://www.blogger.com/profile/00168228978102132365</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>14</thr:total></entry><entry><id>tag:blogger.com,1999:blog-512188703456595011.post-7366316296191183252</id><published>2009-09-26T15:18:00.002+02:00</published><updated>2009-09-26T17:00:07.421+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='traffic'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='memcached'/><category scheme='http://www.blogger.com/atom/ns#' term='memcache'/><category scheme='http://www.blogger.com/atom/ns#' term='nginx'/><category scheme='http://www.blogger.com/atom/ns#' term='php'/><category scheme='http://www.blogger.com/atom/ns#' term='apache'/><title type='text'>The final solution: nginx+apache2 and memcached</title><content type='html'>Been a while!&lt;br /&gt;But I'll make up for the huge time gap: this post will probably be one of the most useful I'll ever post.&lt;br /&gt;&lt;br /&gt;I happen to be running a high traffic website, have been running it for about 5 years now. Over the past few years though, my website has known a major traffic increase which resulted in my servers being regularly cluttered and my website inaccessible. My website profile: an Invision Powerd Board based website (heavily modded though), running under PHP 5 and MySQL 5. Servers are hosted in France at OVH.com.&lt;br /&gt;At first, my reasoning was quite simple: spend more money on a more powerful server. I ran about 5 or 6 server upgrades over the years. I must say it worked at first, since I was running low-end servers. But for the last couple of months the traffic became way too high, which resulted in my website being completely inaccessible for a part of the world (for visitors in remote countries such as Canada, connections frequently timed out) and just plain slow for everyone else. At that time the traffic was: nearly 60K unique visitors/day, about 10 million visits/month.&lt;br /&gt;My server setup: a quad-core with 8GB of ram for Apache, and a quad-core with 4GB of ram for MySQL, both using SATA2 RAID0  HDDs. Connected to eachother with a 1 Gb link.&lt;br /&gt;&lt;br /&gt;Well, I've finally settled for a solution that seems to be working great. The website's fast for everyone, even for me over there in China.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;1. Running PHP with Fast-CGI&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;My website is a community based website, which means the site is strongly dynamic. Every page served is PHP, strictly no HTML. The "default" option for serving PHP is to use PHP as an Apache module. The problem with this solution is that for every page served, a new Apache/httpd process has to be loaded in memory. With high traffic website this isn't necessarily a good solution especially if your server doesn't have much RAM.&lt;br /&gt;So the first thing I did was to switch PHP from Apache module to Fast-CGI module.&lt;br /&gt;&lt;br /&gt;Those tutorials should help you set up PHP as fast-cgi module for Apache:&lt;br /&gt;[english] &lt;a href="http://www.fastcgi.com/drupal/node/5?q=node/10"&gt;http://www.fastcgi.com/drupal/node/5?q=node/10&lt;/a&gt;&lt;br /&gt;[french] &lt;a href="http://www.sos-dedie.com/2009/01/15/apache-2-worker-et-php-fastcgi/"&gt;http://www.sos-dedie.com/2009/01/15/apache-2-worker-et-php-fastcgi/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;2. Setting up nginx for serving static content&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Apache will be serving dynamic content via PHP as FastCGI module. But on top of Apache, we'll be using another webserver, a very lightweight one, for serving static content. Basically, this means php pages will be served by Apache, but other content (images, javascript, css, static html...) is served by nginx, which is extremely fast and reliable for such things.&lt;br /&gt;How to put such a set up in production? Simple as that: nginx on port 80, Apache on port 8080 (or another) and nginx is configured to redirect all dynamic content to Apache. It's called "using nginx as reverse-proxy".&lt;br /&gt;&lt;br /&gt;Here are a few articles about it:&lt;br /&gt;[english] &lt;a href="http://kovyrin.net/2006/05/18/nginx-as-reverse-proxy/"&gt;http://kovyrin.net/2006/05/18/nginx-as-reverse-proxy/&lt;/a&gt;&lt;br /&gt;[english] &lt;a href="http://wiki.joyent.com/accelerators:nginx_apache_proxy"&gt;http://wiki.joyent.com/accelerators:nginx_apache_proxy&lt;/a&gt;&lt;br /&gt;[french] &lt;a href="http://www.papygeek.com/software/optimiser-son-serveur-web-avec-nginx/"&gt;http://www.papygeek.com/software/optimiser-son-serveur-web-avec-nginx/&lt;/a&gt;&lt;br /&gt;Both english articles don't cover vhosts issues, so if I ever get comments asking me how to proceed, I'll post a new article about it.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;3. Memcached and memcache&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I had a bit of trouble figuring that one out as I couldn't really find any article explaining the difference between memcache and memcached. So here's the deal.&lt;br /&gt;- Basically "memcached" (note the trailing "d", which stands for "daemon") is a process that runs on your machine and that allows you to easily cache data in memory--RAM. It's basically a simple and efficient cache manager. It listens on a given port and you can connect to it via...&lt;br /&gt;- memcache: this is the name of the PHP module that allows you to make use of memcached. You're going to need to install this because it doesn't come with PHP! Memcached and memcache can be found in the usual repositories (eg. rpmforge)&lt;br /&gt;&lt;br /&gt;[english] &lt;a href="http://www.danga.com/memcached/"&gt;http://www.danga.com/memcached/&lt;/a&gt; &lt; Memcached official website&lt;br /&gt;[english] &lt;a href="http://www.php.net/memcache"&gt;http://www.php.net/memcache&lt;/a&gt; &lt; Memcache (PHP module) official website&lt;br /&gt;&lt;br /&gt;Installing and configuring both isn't the only thing you have to do. You're going to have to make use of the memcache PHP module functions. That's the trick! But I'll guide you through it.&lt;br /&gt;&lt;br /&gt;Here are a couple of handy functions:&lt;br /&gt;&lt;a href="http://www.php.net/manual/en/function.memcache-connect.php"&gt;memcache_connect&lt;/a&gt; ($host, $port, $timeout) : connects to the memcache server you've set up on your machine.&lt;br /&gt;&lt;a href="http://www.php.net/manual/en/function.memcache-get.php"&gt;memcache_get&lt;/a&gt; ($key) : gets a string from the cache. Returns null if the string was not found.&lt;br /&gt;&lt;a href="http://www.php.net/manual/en/function.memcache-set.php"&gt;memcache_set&lt;/a&gt; ($key, $data, $flag, $ttl) : save a string into the cache.&lt;br /&gt;&lt;a href="http://www.php.net/manual/en/function.memcache-delete.php"&gt;memcache_delete&lt;/a&gt; ($key) : deletes the string from the cache&lt;br /&gt;&lt;br /&gt;Now how to use these functions: this couldn't be any simpler.&lt;br /&gt;- Begin by connecting to the memcached server using memcache_connect()&lt;br /&gt;- Before running any SQL query, ask yourself: can this query be cached? In theory, most queries can be. In my case, I used the memcache functions to optimize my portal page (index.php) which is basically a simple news article display. In other words, the content almost never changes, so this kind of query can definitely be cached.&lt;br /&gt;Here is a simple code example:&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 153, 0);"&gt;// Retrieve data from cache&lt;/span&gt;&lt;br /&gt;$articles = memcache_get( "news_articles");&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 153, 0);"&gt;// if $articles is null, it means the data isn't in the cache store&lt;/span&gt;&lt;br /&gt;if (!$articles) {&lt;br /&gt;  $articles = array();&lt;br /&gt;  $result = mysql_query("SELECT * FROM news ORDER BY news_id DESC LIMIT 0,10");&lt;br /&gt;  while ($row = mysql_fetch_assoc($result)) $articles[] = $row;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 153, 0);"&gt;  // Save the data into the cache.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 153, 0);"&gt;  // Since memcache_get can only return a string, you'll have to serialize the data before saving it into the cache.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 153, 0);"&gt;  // The data is saved for 1 week as defined with the last parameter.&lt;/span&gt;&lt;br /&gt;  memcache_set( "news_articles", serialize($articles),  &lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;MEMCACHE_COMPRESSED, 60*60*24*7&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;);&lt;br /&gt;}&lt;br /&gt;&lt;span style="color: rgb(255, 153, 0);"&gt;// $articles is not null&lt;/span&gt;&lt;br /&gt;else {&lt;br /&gt;  $articles = unserialize($articles); &lt;span style="color: rgb(255, 153, 0);"&gt;// unserialize the data&lt;/span&gt;&lt;br /&gt;}&lt;br /&gt;&lt;span style="color: rgb(255, 153, 0);"&gt;// You now have a fully loaded $articles array, ready for display!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Conclusion&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I managed to reduce the amount of SQL queries of my main page from an average of 15 to... 5. Every single page of my website loads nearly instantly even during high influx of visitors. Lately I had about 3000 users online simultaneously, and I didn't notice any slowdowns.&lt;br /&gt;So I can safely say that these 3 points described above actually solved all my issues.&lt;br /&gt;&lt;br /&gt;What a relief!&lt;br /&gt;Clem&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/512188703456595011-7366316296191183252?l=cnedelcu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cnedelcu.blogspot.com/feeds/7366316296191183252/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=512188703456595011&amp;postID=7366316296191183252' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/512188703456595011/posts/default/7366316296191183252'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/512188703456595011/posts/default/7366316296191183252'/><link rel='alternate' type='text/html' href='http://cnedelcu.blogspot.com/2009/09/final-solution-nginxapache2-and.html' title='The final solution: nginx+apache2 and memcached'/><author><name>Clément Nedelcu</name><uri>http://www.blogger.com/profile/00168228978102132365</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-512188703456595011.post-14375848101753132</id><published>2008-12-10T17:52:00.003+01:00</published><updated>2008-12-10T17:54:30.411+01:00</updated><title type='text'>Visual Studio 2008 Survey</title><content type='html'>My friend Fabien Lavocat from Microsoft France recently sent me an email regarding a Visual Studio 2008 survey they have just started.&lt;br /&gt;The survey is of course available in English.&lt;br /&gt;If you have a couple of minutes to kill, please answer the survey as this will help Microsoft improve their future editions of Visual Studio!&lt;br /&gt;&lt;br /&gt;&lt;a href="http://c2.microsoft.fr/49ae54c30ecc4382aeba1841073ee06b/?elng=1033"&gt;Click here to access the survey&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Thanks for your time!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/512188703456595011-14375848101753132?l=cnedelcu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cnedelcu.blogspot.com/feeds/14375848101753132/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=512188703456595011&amp;postID=14375848101753132' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/512188703456595011/posts/default/14375848101753132'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/512188703456595011/posts/default/14375848101753132'/><link rel='alternate' type='text/html' href='http://cnedelcu.blogspot.com/2008/12/visual-studio-2008-survey.html' title='Visual Studio 2008 Survey'/><author><name>Clément Nedelcu</name><uri>http://www.blogger.com/profile/00168228978102132365</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-512188703456595011.post-7759707340870201298</id><published>2008-12-09T14:30:00.002+01:00</published><updated>2008-12-09T14:33:17.270+01:00</updated><title type='text'>Dotnet-France</title><content type='html'>For french developers willing to obtain Microsoft Developer certifications, a colleague of mine (Julien Dollon) has just published a very useful website that will help you prepare for the certification exams:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://dotnet-france.com/"&gt;Dotnet-france.com&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I wish Julien good luck with his website and trust it will be a great help a lot of developers.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/512188703456595011-7759707340870201298?l=cnedelcu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cnedelcu.blogspot.com/feeds/7759707340870201298/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=512188703456595011&amp;postID=7759707340870201298' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/512188703456595011/posts/default/7759707340870201298'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/512188703456595011/posts/default/7759707340870201298'/><link rel='alternate' type='text/html' href='http://cnedelcu.blogspot.com/2008/12/dotnet-france.html' title='Dotnet-France'/><author><name>Clément Nedelcu</name><uri>http://www.blogger.com/profile/00168228978102132365</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-512188703456595011.post-7587535023799828329</id><published>2008-11-07T13:11:00.003+01:00</published><updated>2008-11-07T13:45:33.261+01:00</updated><title type='text'>[MySQL] Using SQL_CALC_FOUND_ROWS and FOUND_ROWS with MySQL</title><content type='html'>Hello,&lt;br /&gt;for this second blog article I've decided to explain this neat little feature of MySQL: &lt;span style="font-weight: bold;"&gt;SQL_CALC_FOUND_ROWS&lt;/span&gt; and &lt;span style="font-weight: bold;"&gt;FOUND_ROWS()&lt;/span&gt;.&lt;br /&gt;This article is about MySQL only, it is likely that these keywords/functions exist in other SQL-based languages but I've only ever used them with MySQL.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;What's the point, you ask?&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;When working with (my)SQL databases, you often find yourself using the LIMIT keyword, in order for example to limit the results of a large search. Let's study a particular case.&lt;br /&gt;- You're working on the "employees" table, which contains, say 1000 data rows.&lt;br /&gt;- You wish to display the list of employees in a particular department, 10 by 10.&lt;br /&gt;- &lt;span style="font-weight: bold;"&gt;You wish to display the amount of employees in this department&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="color: rgb(0, 0, 102); font-weight: bold;"&gt;What would you normally do?&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Here's a rough example:&lt;br /&gt;&lt;span style="color: rgb(102, 51, 0); font-weight: bold;font-family:courier new;" &gt;$result = mysql_query("SELECT * FROM employees WHERE department='sales' LIMIT 0,10 ");&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(102, 51, 0); font-weight: bold;font-family:courier new;" &gt;$total = mysql_num_rows($result);&lt;/span&gt;&lt;br /&gt;-&gt; This is &lt;span style="font-weight: bold;"&gt;incorrect &lt;/span&gt;because $total will never exceed 10 due to the LIMIT clause.&lt;br /&gt;&lt;br /&gt;You could also do this:&lt;br /&gt;&lt;span style="color: rgb(102, 51, 0); font-weight: bold;font-family:courier new;" &gt;$result = mysql_query("SELECT COUNT(*) cnt FROM employees WHERE department='sales'");&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(102, 51, 0); font-weight: bold;font-family:courier new;" &gt;$count = mysql_result($result, 0, "cnt");&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(102, 51, 0); font-weight: bold;font-family:courier new;" &gt;$result = mysql_query("SELECT * FROM employees WHERE department='sales' LIMIT 0,10 ");&lt;/span&gt;&lt;br /&gt;-&gt; But this means you have to process &lt;span style="font-weight: bold;"&gt;two SQL queries&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 102);font-size:130%;" &gt;So how do you fix this?&lt;/span&gt;&lt;br /&gt;Using the &lt;span style="font-weight: bold;"&gt;SQL_CALC_FOUND_ROWS&lt;/span&gt; keyword in your SQL query will allow you to fetch the total amount of results without being limited by the LIMIT clause.&lt;br /&gt;Here's how you use it:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(102, 51, 0);font-family:courier new;" &gt;$data_result = mysql_query("SELECT &lt;span style="color: rgb(255, 0, 0);"&gt;SQL_CALC_FOUND_ROWS&lt;/span&gt; * FROM employees WHERE department='sales' LIMIT 0,10");&lt;/span&gt;&lt;br /&gt; &lt;span style="font-weight: bold; color: rgb(102, 51, 0);font-family:courier new;" &gt;$count_result = mysql_query("SELECT &lt;span style="color: rgb(255, 0, 0);"&gt;FOUND_ROWS()&lt;/span&gt; cnt");&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(102, 51, 0);font-family:courier new;" &gt;&lt;span style="color: rgb(255, 0, 0);"&gt;$employees_count&lt;/span&gt; = mysql_result($count_result, 0, "cnt");&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(102, 51, 0);font-family:courier new;" &gt;echo "&lt;span style="color: rgb(255, 0, 0);"&gt;$employees_count&lt;/span&gt; employees found in the sales dept. Showing first 10: ";&lt;/span&gt;&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;As you can see, using the &lt;span style="font-weight: bold;"&gt;SQL_CALC_FOUND_ROWS&lt;/span&gt; keyword allows you to save the amount of results before applying the LIMIT clause; and this amount can be retrieved with a simple "&lt;span style="font-weight: bold;"&gt;SELECT FOUND_ROWS()&lt;/span&gt;" after the query is executed.&lt;br /&gt;&lt;br /&gt;I've found this to be pretty useful when designing search pages, directories, and so on...&lt;br /&gt;If you want more information about the FOUND_ROWS() function, and other useful functions aswell, check &lt;a href="http://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_found-rows"&gt;this page&lt;/a&gt; on the official MySQL documentation.&lt;br /&gt;&lt;br /&gt;Okay, that's all folks!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/512188703456595011-7587535023799828329?l=cnedelcu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cnedelcu.blogspot.com/feeds/7587535023799828329/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=512188703456595011&amp;postID=7587535023799828329' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/512188703456595011/posts/default/7587535023799828329'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/512188703456595011/posts/default/7587535023799828329'/><link rel='alternate' type='text/html' href='http://cnedelcu.blogspot.com/2008/11/mysql-using-sqlcalcfoundrows-and.html' title='[MySQL] Using SQL_CALC_FOUND_ROWS and FOUND_ROWS with MySQL'/><author><name>Clément Nedelcu</name><uri>http://www.blogger.com/profile/00168228978102132365</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-512188703456595011.post-6336275279949845395</id><published>2008-10-19T18:38:00.004+02:00</published><updated>2008-10-19T19:23:14.862+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='video'/><category scheme='http://www.blogger.com/atom/ns#' term='mediaplayer'/><category scheme='http://www.blogger.com/atom/ns#' term='wpf'/><category scheme='http://www.blogger.com/atom/ns#' term='playing'/><category scheme='http://www.blogger.com/atom/ns#' term='videodrawing'/><category scheme='http://www.blogger.com/atom/ns#' term='drawingbrush'/><title type='text'>WPF: drawing a video using MediaPlayer, VideoDrawing and DrawingBrush</title><content type='html'>I've decided to start this blog for a simple reason: I was recently doing some research on various  subjects, and was unable to find any clear documentation. And here I was thinking the World Wide Web had all the answers. Perhaps my contributions will help some of my fellow developers!&lt;br /&gt;&lt;br /&gt;This first article is about how to draw a video using the MediaPlayer class in WPF (C# only - my apologies to VB.NET users: I'm allergic to VB). I was in the middle of preparing a training session at Avanquest Software when I read something in the WPF MOC: using the MediaElement control isn't the only way you can draw a video on a surface. Doh! I investigated a little further on the subject but couldn't find anything on the subject.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;What does this do?&lt;/span&gt;&lt;br /&gt;This article will explain how to use the MediaPlayer class to play a video on a surface. To demonstrate the wide range of possibilities offered by this mechanism, I will explain how to draw the same video clip on 9 different controls simultaneously.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Ixt0VU0h5eU/SPtmkrwdJAI/AAAAAAAAAAM/XKxBbEYRyWM/s1600-h/mp_screenshot.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://1.bp.blogspot.com/_Ixt0VU0h5eU/SPtmkrwdJAI/AAAAAAAAAAM/XKxBbEYRyWM/s320/mp_screenshot.jpg" alt="" id="BLOGGER_PHOTO_ID_5258909770292470786" border="0" /&gt;&lt;/a&gt;&lt;span style="font-weight: bold;"&gt;MediaPlayer&lt;/span&gt;&lt;br /&gt;First, you need to instantiate the MediaPlayer class. This class lets you manage the playback of a media file by exposing methods such as Play, Pause, Stop, etc. The constructor doesn't accept any parameter. Then use the Open() method to specify the media you wish to play. In our example we'll be playing a video.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;            MediaPlayer mp = new MediaPlayer();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;            mp.Open(new Uri("c:/video.avi"));&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;VideoDrawing&lt;/span&gt;&lt;br /&gt;Then initialize a new instance of the VideoDrawing class. This class is used to do the actual drawing on a surface. Instantiate a new object and affect its "Player" member to the MediaPlayer instance you've declared above. Finally, affect the "Rect" member to specifiy the zone where the video will be drawn. Since we're going to be using the video source as a background for our controls, the video will be stretched to fit the control space so the value you specify here don't matter -- just make sure to specify a value greater than 0 as Width and Height.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;            VideoDrawing vd = new VideoDrawing();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;            vd.Player = mp;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;            vd.Rect = new Rect(0, 0, 100, 100);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;DrawingBrush&lt;/span&gt;&lt;br /&gt;At this point, nothing is drawn on the window. You need to instantiate a DrawingBrush based on your VideoDrawing instance:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;            DrawingBrush db = new DrawingBrush(vd);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Your "db" variable is now an instance of DrawingBrush, meaning you can affect any property that is of type Brush, such as Control.Background, etc. In my example, I've got a grid with 9 cells, each of these cells contains a button.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;            foreach (Button b in videoGrid.Children)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;                b.Background = db;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Once this is done, all you have to do is to call the Play() method of the MediaPlayer instance.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;            mp.Play();&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I've provided a quick demo source code with this article. It plays the file located at c:\video.avi so make sure to either have a file with the same name or, of course, change the location of the file you wish to play.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://gbatemp.net/up/M8_Demo2-MediaPlayer-VideoDrawing-DrawingBrush.zip"&gt;Download demo project&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/512188703456595011-6336275279949845395?l=cnedelcu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cnedelcu.blogspot.com/feeds/6336275279949845395/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=512188703456595011&amp;postID=6336275279949845395' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/512188703456595011/posts/default/6336275279949845395'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/512188703456595011/posts/default/6336275279949845395'/><link rel='alternate' type='text/html' href='http://cnedelcu.blogspot.com/2008/10/wpf-drawing-video-using-mediaplayer.html' title='WPF: drawing a video using MediaPlayer, VideoDrawing and DrawingBrush'/><author><name>Clément Nedelcu</name><uri>http://www.blogger.com/profile/00168228978102132365</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_Ixt0VU0h5eU/SPtmkrwdJAI/AAAAAAAAAAM/XKxBbEYRyWM/s72-c/mp_screenshot.jpg' height='72' width='72'/><thr:total>2</thr:total></entry></feed>
