Put your message here! Contact me for more information
 
 







 

Archive for the ‘Web Scripting’ Category


 


Until recently I have decided to setup a local SVN repository on my computer, which runs Windows XP pro. Setting up SVN with Apache is the best way to access a SVN repository but the thing is, my computer has also IIS installed for ASP.NET development. Normally I have XAMPP installed and have to switch start/ stop Apache and IIS manually whenever I need to do something in either ASP.NET or PHP. To clarify, I do have PHP 5.x setup for IIS but Just didn’t bother to fix the session file permission issues of IIS; I’d rather just switch to the working Apache installation instead using the XAMPP control panel.

I started by installing the [[http://svn1clicksetup.tigris.org/|SVN1clickSetup]]. The installation was painless, however, I needed to restart the service to change some configurations. To register svnserve.exe to run as a serice again, I used this full command:


I:\Program Files\Subversion\bin\svnservice -install -d --listen-port 3690 --listen-host 0.0.0.0 -r K:\svnrepos

The -d param enables svnserve to run as a daemon. We specify the list-host of SVNServe.exe to be 0.0.0.0, which means it will bind to any IP available to the system. The -r specifies which folder to serve as the SVN repository. What left was opening up the 3690 port on the router and have the requests for the SVN service on this port routed to my box. Done!

* If you run `svnservice -debug` and see the `RegQueryValueEx failed with error 0, type 1`, it means that SVNService has successfully registered the SVNServe to run as a service. In fact, `RegQueryValueEx failed with error 0` is not an error or a failure.

* In case you have already run the above svnservice to register the SVNserve as a service but still cannot access the repository, you may have to start the SVNService manually by going through Start > Run > services.msc. Find the service called SVNService and start it. Also switch its Startup Type to Automatic so that SVNService is started on start up.

Cheers!

view comments
 


I was working on some javascript stuff for a project and ran into this problem with setInterval(): for IE 6, calling setInterval() to an object’s method results in the wrong scope. In the object’s method, the alfamous **this** keyword now refers to **window**, instead of the conventional “this” as in “**this object**”. So let me give you some more details on this and a free, amazingly simple solution to this head-ache.

**SPOILER:**\\ the solution uses eval(). if you are allergic to eval(), don’t take my advice.\\ **END SPOILER**

===== The code =====
Let’s look at some code and we’ll have a little discusssion. Here’s the psuedo-code for a fictional TimeTicker object, which is supposed to automatically update a “clock” on the screen every second.


/* A. Constructor */
function TimeTicker()
{
/* A.1 - populate internal variable here, like hour, minute, second, etc. */
...

/* A.2 - now we set the timer to periodically update the time value every 999 miliseconds */
this.timer = setInterval( this.updateTime, 999 );
}

/* B. This function is to update the time value somewhere on the screen */
TimeTicker.prototype.updateTime = function ()
{
/* B.1 - compute new value */
...
this.hour = new_hour_value;
this.minute = new_minute_value;
this.second = new_second_value;
...

/* B.2 - now update the screen */
...
}

===== The problem =====
The above psuedo code will sadly **FAIL** in both IE and FF (not because it’s only psuedo-code!), as the ‘’setInterval()” invocation has **totally changed the scope** of the polled function. First of all, let’s look at ”**A.2**” from above. Calling ”this” within the ‘’setInterval()” will change the reference of ”this” to some other object (which I think is ”this” now refers to ”window”.) Hence calling ‘’setInterval( this.updateTime, 999 )” fails in both Firefox and IE 6, as it means that the ‘’setInterval()” will poll the ”window.updateTime()” function every 999 ms. That’s not what we want, and ”window” object could care less about our ”updateTime()” since we suddenly found ourselves in the wrong scope.

===== The Firefox’s Solution =====
For firefox, the fix is a small rewrite of how we would call the polled-function, updateTime(). The setInterval() function in Firefox is improved and we can now pass an extra parameter to it, and that’s exactly what we will do. We pass in the current object’s reference as ”this” to the a proxy function, which in turn makes a call to the updateTime(). I found this solution through [[http://www.klevo.sk/javascript/javascripts-settimeout-and-how-to-use-it-with-your-methods/|Klevo’s blog]], a web developer from Slovakia.

We will have to rewrite ”**A.2**” as follows:


/* A.2 */
this.timer = setInterval ( function( that ) { that.updateTime(); }, 999, this );

What we just did is we create a proxy function, whose only parameter is ”that”, a pointer to another object. Within this proxy function, we can make invoke all of “that”’s methods! Basically we migrate the scope of ”this” as a reference to the current ”TimerTicker” object into the polled proxy function via a pass-by-reference ”that” parameter. Notice the extra 3rd parameter of ‘’setInterval()”: we are passing ”this”, in this case, a reference to the current ”TimeTicker” object, as the only parameter of the newly created proxy function. Since now ”that” is equivalent to ”this”, we can call all methods of TimeTicker object! Beautiful!

===== The Internet Explorer’s Problem =====
While setInterval() in Firefox provide us a way to pass in extra parameters, IE’s version of ‘’setInterval()” is less flexible (and it also did drive me nuts!) Anyway, let’s talk about the mechanism of IE’s ‘’setInterval()”. According to [[http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/setinterval.asp|MSDN’s manual on setInterval()]], the syntax of setInterval() is

”iTimerID” = ”window”.**setInterval(** ”vCode”, ”iMilliSeconds” [, sLanguage])

with ”vCode” is either a reference pointer or a “string that indicates the code to be executed when the specified interval has elapsed”. Since there’s no way we can pass an extra parameter to the polled-function, we cannot pass ”this” as a 3rd parameter of setInterval() as what we just did for Firefox.

If we rewrite the code as this.timer = setInterval ( this.updateTime(), 999);then 2 things are gonna happen: first,” this.updateTime()” is executed right away. It’s equivalent to a direct call to the ”updateTime()” function of the current object, ”TimeTicker”. As we are still in the scope of the current function, hence, ”this” refers to the current ”TimeTicker” object. Secondly, after the 999ms has elapsed, ‘’setInterval()”" will invoke ”this.updateTime()”, and now ”this” refers to ”window” as we are now out of the scope of the ”TimeTicker” object. And of course, ”window.updateTime()” is wrong. So what you see is that your script will work the first time (when this.updateTime() is executed in the correct scope), and then everything fails (when this.updateTime() is excuted by setInterval() in the wrong scope).

And If we write this.timer = setInterval ( this.updateTime, 999);(Notice the missing parenthesis). This will also fails as when this.updateTime is invoked, we are already in the wrong scope, the scope of ”window” object!

On the other hand, if we writethis.timer = setInterval ("this.updateTime()", 999);we are still in the wrong scope when setInterval() invoke the updateTime() method. ”this” still refers to ”window” when the updateTime() function is executed. Notice that we can include the parenthesis “( )” (and potentially other pass-by-value parameters since the method is refered to as a string and it’s not executed right away, but only when being invoiked by ‘’setInterval()”). However, we can’t pass a pointer to the current object in a string!

We’d like to pass a pass-by-reference pointer object to point to the current ”TimeTicker” object but no matter what we do, we cannot seem to do so. But be hold! Our salvation comes from the use of a glorifying global variable, and of course, a dash of ”eval()”, just enough to tame Internet Explorer.

===== The Internet Explorer’s Solution =====
I’d like to include the code for IE here, just read over and we will discuss later.


/* C. global scope object */
var globalScope = new Array();

/* A. Constructor */
function TimeTicker()
{
/* A.0 - An extra unique identifier for the current object */
this.uniqueId = some_text_or_numers;

/* A.1 - populate internal variable here, like hour, minute, second, etc. */
...

/* A.3 - setInterval Fix */
/* A.3.1 - for IE */
if( document.all )
{
/* A.3.1.1 - make a reference to the current object and saved in the global scope array
* to use later to correct the scope.
*/
globalScope[ this.uniqueId ] = this;
setInterval( 'ieIntervalHandler("' + this.uniqueId + '","updateTime")', 999 );
}
else
{
/* A.3.2 - Mozilla */
this.timer = setInterval ( function( that ) { that.updateTime(); }, 999, this );
}
}

And we add an extra function, ”ieIntervalHandler( **id**, **strFunc** )” to the script.

/* D. - Special IE setInterval handler function with scope corrected */
function ieIntervalHandler( id, strFunc )
{
/* D.1 - correct the scope then make the call */
var scope = globalScope[id];
eval( "scope." + strFunc + "()" );
}

All set? Here comes the explanations: First of all, we added a global associative array named globalScope (”**C**”). This associative array is used to store reference to a particle object based on that object’s unique identifier. Confused? Not a problem, just keep on reading.

Let’s read A.0, this is where we set the unique identifier for this ”TimeTicker” object. For this technique to work, each object **must** have a **unique identifier** since the unique identifier is used as the **key** of the global associative array.

Look at ”**A.3.1**”. Here we do a little browser-intelligence. If the browser doesn’t know ”document.all”, which is IE-specific, we use the improved version of ‘’setInterval()” as mentioned in the above Firefox’s solution section. If the browser is indeed IE, at ”**A.3.1.1**”, we store the reference to this ”TimeTicker” object as an element in the globalScope associative array. Then we cheerfully and confidently ‘’setInterval()” the ”ieIntervalHandler()” function (see ”**D.1**”). We do a pass-by-value the unique ID of the current ”TimeTicker” object as the first parameter of ”ieIntervalHandler()”, and ”updateTime” as the name of the method of the same ”TimeTicker” object.

Look at ”**D.1**”. Here we have a 2-line function. First, we get the reference to the particular TimeTicker object, which we already stored in the globalScope associative array back in ”**A.3.1.1**”. Since we are now in the scope of ieIntervalHandler(), our ‘’scope” variable is pointing to the ”TimeTicker” object. With the correct reference to the correct object, now we can make the call to the correct method with a quick, painless ”eval()”eval( "scope." + strFunc + "()" );

What did we just do? We use a global array to store the references so that later on we can get to the right object, even when ieIntervalHandler is invoked by ‘’setInterval()” and the scope now is all over the place — we could care less! Hence we now can solve the wrong scope issue within IE. And guess what, now we can have any object to poll a method of itself! How awesome is that?

===== Memory Issue =====
Since we need to keep polling a function, we need to be careful of not creating more and more objects or functions that the garbage collect will never be able to purge because of a hidden reference somewhere. If you do create a lot of objects that do self-polling using this global associative array technique, when destroying the object, you will probably have to set the element of the globalScope to ”**null**” also, so that there is no further reference to the destroyed object. Also, in ”**A.3.2**”, we do create a new function everytime we’d like to run the timer, this may be a potential memory leaking point on Firefox.

I’d like to leave the quest of battling memory-leak monster to somebody else, but just remeber to watch out for potential weak point where memory leak can happen, especially when your page will be opened for a prolonged preriod of time.

===== Keywords spam =====
This setInterval() and the scope problem is a pretty abstract and hard to describe problem. I just include some potential search keywords here so that other people can by chance find this page. Call it keyword spam, call it shameless-self advertising, I could care less, but if somebody find this helpful, then I call it success :)

setInterval scope loosing, setTimeout, this setInterval wrong scope, javascript setInterval scope, global associative array scope correction, object oriented setInterval, self polling, this polling scope error, internet explorer setInterval fail, firefox setInterval fail, setInterval object.

===== Final remarks =====
Thank you for reading! I hope this helps. And I’d like to wish you a …

Merry Christmas and Happy New Year!

4:13AM, Dec 23, 2006.

view comments
 

One of my little ColdFusion projects is to allow users to download a dynamically generated word document, whose contents are fetched from the database. Luckily, to open a file in word is pretty simple: just rename it into .doc and Word will open it. Especially, for HTML content, I can just force the user to download the HTML page and have him/her save it with a .doc extension and be done with it.

In my case, I didn’t want to write the dynamic content to a file and force the download via the Header of “Content-Disposition: attachment”. What I did was capturing all output into a file, then craft the HTTP header using the cfhead tag to force the inline download. Let me show you real quick how to do this, it may save you some time messing around with ColdFusion.

===== The script =====







…. output your database result here …





#content#

===== Explanation =====
Let’s go over the A, B, C, D in the above code snippet.

* **A**: Since we don’t want ColdFusion to randomly send the contents (and of course, the header too, which will mess up the force download) to the client’s browser, we explicitly tell ColdFusion to only flush out the content contained within the cfoutput tag.
* **B**: Here you can do all of your data access, such as running retrieval queries, etc. It’s the R in the CRUD, **C**reate, **R**etrieve, **U**pdate, **D**elete
* **C**: We capture all output produced by cfoutput into a variable, which allows us to do filtering or word replacment later on.
* **D**: Now we craft the header to force the download. We explicitly say that this is a word document, so if the user has Word installed, s/he will have the option to open the file with Word directly.Here is the heart of the solution. Since we don’t have a file to read the contents from but a whole bunch of HTML contained in a variable, we set the Content-Disposition to inline and specify the name of the file that the user is about to download. You can set the file to be .doc if you’d like the downloaded file to be associated with Word.We provide some description to the downloaded file.#content#And now we can just flush out the content to the browser. That wasn’t too bad, was it? When the user accesses the CFML script, s/he will be prompted to download the file to the local computer. Nice!

===== Further Readings =====
No good tutorials are without a reference section, so here is the list of interested articles that I find useful
* [[http://livedocs.macromedia.com/coldfusion/7/htmldocs/wwhelp/wwhimpl/common/html/wwhelp.htm?context=ColdFusion_Documentation&file=00000232.htm|Macromedia manual on Cfheader]]
* [[http://us2.php.net/readfile|PHP manual on readfile()]] and [[http://us2.php.net/header|PHP manual on header()]] - The 2 articles are particularly helpful to see how the header can be sent to the browser. Eventhough we used ColdFusion in this short tutorial, the same technique can also be applied to PHP.
* [[http://www.ietf.org/rfc/rfc2183.txt| RFC2183]] - The EITF Request for Changes technical details on header messages. I did use this as the starting point. When in doubt, look for RFC documents as they are is always the definitive (and most correct) guide.

view comments
 

Light Reading logoSo LightReading is a news portal for coprorate computer stuff, like networking, networking security, etc. They sometimes send out invitations for subscribers for extra info, web-minars.

I have come to know about Light Reading a while ago, and I randomly signed up for their newsletter. But I decide this is the day I unsubscribe from their list, so I clicked on the Unsubscribed linke at the footer area of the email.

Here’s is the link that I was taken to..

http://www.lightreading.com/unsubscribe.asp?subscriberid=6xx7xxx ( I masked out my ID # for privacy)

So I unsubscribed myself, but also changed the subscriberID to something else, just to see how the page works … oh uh, I got the “Unusubscribe Page” for someone else who is subscribing to 11 other newsletters from Light Reading. Phew. Too little work and I already discover a vulnerability.

I know portals like Light Reading can sell their services because they collect a huge database of emails of supposingly “C?O”, “Networking Engineers”, etc., so the commercial contents and products can be sold directly to these important corporate figures. Well, not if one day, LR find out that their newsletter has no reader because someone has conveniently (or mischievously) unsubscribed everyone else using the previous link. Of course noone will do that manually, but s/he can write some script that loop through any possible IDs (may take a while, I know, mine is in the upper 6 millions, LR has a pretty big colection of users), then request the page, and make a POST submit to the form. Or just make a page that continuously submitting POST requests to unsubscribe everyone (PHP CURL would make this an easy task). This method is faster, since I doubt that LR do any double checking for “unsubscribe request”. I mean something in the light reading of …

POST to unsubscribe.asp with subscriberID = #####

Humh … If I were Light Reading, I would seriously rewrite the unsubscribe mechanism.

(Disclaimer: I did accidentally unsubscribe someone else other than myself from the list while experiment with the site, so oops, sorry, don’t sue me. I did point out where you guys did wrong, so go fix it and thanks me later)

view comments
 

I was trying to setup a MySQL cluster with CentOS 4.4 and VMWare and I was initially successful at getting the NDB storage engine to work. However, I could not start the MySQL API (or MySQL client, whatever you call it) because I ran into the infamous MySQL error of “ERROR 2002 (HY000): Can’t connect to local MySQL server through socket ‘/var/lib/mysql/mysql.sock’ (2)“. Googling didn’t help much either because people were just asking and very few got the answer.

After a while, I was desparate. My cluster was up and I had no way to connect to it and test out the exciting cluster’s replicate feature. I went to bed at 4:00am last night and kept thinking what could go wrong? Setting up the ndb engine for the nodes was pretty straightforward but why just getting mysql client to run is so problematic? Well, here’s my solution to the puzzle:

My Setup

  • CentOS 4.4 installed from DVD with most packages unchecked, especially MySQL
  • The newest MySQL 5.0.27-max was used. See, I’m on the bleeding-side of technology.
  • MySQL is locaed in the default location at /usr/local/mysql/
  • When I installed MySQL, the mysql.server script was cp from /usr/local/mysql/support-files/mysql.server to /etc/init.d/
  • The my.cnf file is very simple like this

#file: /etc/my.cnf
ndbcluster
ndb-connectstring=’host=192.168.2.100′
[mysql_cluster]
ndb-connectring=’host=192.168.2.100′

Cause:

When the MySQL server (mysqld) starts, it created a sock file. Since I overwrote the original /etc/my.cnf without the socket parameter under [mysqld], the MySQL server (mysqld) created the socket file under /tmp/mysql.sock instead. Furthermore, I was also missing the socket parameter under [client] section in the my.cnf - I didn’t even have the [client] section.

What happens when I tried to start the mysql client (#mysql -u root) was that the mysql client was looking for the mysql.sock file but coudln’t find the path to the file. It then looked into the default path /usr/lib/mysql/ to find the mysql.sock file. Of course this doesn’t work because when mysqld was started, the socket file was created in /tmp instead. The client gave up, spit out the connect error prompt.

In brief, the cause of the infamous error is because the mysql client cannot find the socket file at run time.

Solutions

First of all, you should verify that mysqld is running by typing #ps aux | grep [m]ysqld. Then there are 2 ways to solve this: one is to fix the socket path in the /etc/my.cnf under [mysqld] and [client] like this

# file: /etc/my.cnf
[mysqld]
… # someother settings
socket=/var/lib/mysql/mysql.sock
[client]
… # some other settings
socket=/var/lib/mysql/mysql.sock

then restart the mysqld server so that the mysql.sock file is generated. The next time you start the client with #mysql -u root, you will magically get it. This fix is permanently but the catch is you will have to shutdown mysqld, the MySQL server itself.
The other way when you want to just login really fast to the mysql server, try this (actually I used this method to obtain the overall solution to the infamous error)

  • #find / | grep mysql.sock
    this will do a look up on the entire disk and look for the mysql.sock file. You will get back something like /tmp/mysql.sock. This is the socket file we will need to use.
  • #mysql -u root –socket=/tmp/mysql.sock
    this will tell the mysql client to login as root user and use the socket file located in /tmp/mysql.sock

Boom, you should get into the suddenly-loved mysql> prompt. I was so excited when I was able to fix the client and was able to access to the mysql prompt.

I hope this help you all. With this success in installing the MySQL 5.0.27 cluster, I am planning to do a screencast of setting the whole thing up (VMWare is just awesome. It allows me to have 3 CentOS 4.4 servers at the same time, making this installation a breeze)

view comments