Tuesday, September 24, 2013

Multiple SSL Host Headers in IIS

A client needs to setup SSL for both clientdomain.com and www.clientdomain.com for the same website on a IIS 2012 server.

Google around, I found the instruction here.

So we need to create 2 sites: clientdomain.com and www.clientdomain.com where one site (www.clientdomain.com) is configured to redirect request to the other (clientdomain.com) by using the HTTP Redirect module.

To bind the host clientdomain.com, we add site binding with Type: https, IP address: All Unassigned, Port: 443, Host name: clientdomain.com, SSL certificate: (select the SSL certificate)

To bind the host www.clientdomain.com, we need to use the command appcmd:

cd C:\Windows\System32\Inetsrv\
appcmd set site /site.name:"www.clientdomain.com" /+bindings.[protocol='https',bindingInformation='*:443:www.clientdomain.com']

It's done!

Saturday, September 14, 2013

Linux console prompt - weir characters

When login to the server, the console prompt shown up with weir characters (couldn't remember what's caused this)

Äroot§myServer ßÜ#
Äroot§ myServer ßÜ# echo $LANG

Google around, finally found the reset command. That's it :)

Thursday, September 12, 2013

Troubleshoot HTTP 400 Bad Request error on IIS

There's an J2EE app running on the Tomcat with ISAPI redirector on IIS 8 of Windows Server 2012.
Yesterday the client got the error related to an AJAX request. When debugging the problem, I found out that the IIS returns HTTP 400 Bad Request error instead of passing along the url for the Tomcat to handle it.

In the IIS log file, there's no record for this request nor error log neither.

Go to the IIS admin:
Website >
Advanced Settings > Limits > Maximum URL Segments: 32
Request Filtering module > Edit Feature Settings:
Maximum URL Length: 4096
Maximum query string: 2048

Everything is fine. The url that makes error meets those configuration since it has just few segments and the length is around 380 characters - far behind the limit settings.

Then I tried to shorten the url a little bit and then a little bit.. and then finally it worked. It seems there's a limit around 300 characters.

Google around to enable the error log and I found How to troubleshoot HTTP 400 errors
Then go to  Error logging in HTTP APIs
Download the Enable HTTP API error logging  Microsoft Fix it 50634 to install it, but it said the current OS is not matched! Though the instruction applies for Windows Server 2012 Standard as the app is running on.

So have to go to regedit and configure the Http.sys registry settings with following parameters:
EnableErrorLogging: Decimal 1
ErrorLogFileTruncateSize: Decimal 10 (MB)
ErrorLoggingDir: C:\inetpub\logs\LogFiles

Then do : net stop http

It asks to confirm another services also:
   Windows Remote Management (WS-Management)
   Windows Event Collector
   World Wide Web Publishing Service

Then do: net start http
The HTTP Service service was started successfully.

Check the website, it's stopped!
Do  net start http again, but it said the http service is already started!

So go to the services manager to start World Wide Web Publishing Service, then Windows Remote Management (WS-Management) and Windows Event Collector

Then test again and see the error log file with a record just shows a very simple error reason: URL

Continue to read and go to Http.sys registry settings for IIS

Wow, there's a limit setting called UrlSegmentMaxLength with 260 characters by default! I thought that caused the problem because the full url with domain name that worked when there's around 300 characters.

So go to regedit and add UrlSegmentMaxLength with 1000 characters value to the HTTP parameters and restart http, w3svc, winrm and wecsvc services again.

Finally it worked!

I wonder why the MS didn't make it for a each specific website like the Maximum URL Segments and easily to set. But we'll have to configure in the Windows registry that requires to restart whole services and affect all sites.


Monday, September 9, 2013

CVS Change Log for Eclipse

I've been using Eclipse and CVS plugin over 5 years. Sometimes I need to check recently change log of a day but the Eclipse CVS plugin doesn't have that feature and I do that by command line. Today I found a useful plugin and that works great. Because it doesn't provide a link to install directly in the Eclipse, but we can download the zip file and unzip it, then copy the plugins folder to the eclipse folder. There's another issue is the detail dialog doesn't show full file paths as the screenshot from their website. But that's fine.

Update (18 Oct 2013): this version is old and has bug that doesn't show correct logs. The newer version is available on http://code.google.com/a/eclipselabs.org/p/changelog/

Sunday, September 8, 2013

ISAPI Tomcat redirector on IIS 8 of Windows Server 2012 - special chars in URL

When using ISAPI Tomcat redirector on IIS 8 of Windows Server 2012, we faced with the problem of the URL having special chars such as colon (:) character. We had a T5 app that makes AJAX requests and returns IIS error page instead app's JSON data as expected. After debug, I found out that the IIS handles that url (has colon characters) by itself but not lets the ISAPI Tomcat redirector to do that.

The IIS might returns the error like: A potentially dangerous Request.Path value was detected from the client (:).

We might re-factor the app to use normal characters instead colon character but it requires more effort since the function relates to other libraries and have to test all functions...

I tried to place the Tomcat redirector on the top of the ISAPI Filters list or remove all ASP.NET filters, but both ways didn't work either.

Finally, I reconfigured the application pool to remove .NET framework (to No Managed Code) and it worked.





Thursday, September 5, 2013

Yahoo! OpenID attribute exchange

When implementing OpenId authentication with Spring Security with below config, the Yahoo! service doesn't provide any attributes values, although Google works.

 <security:attribute-exchange>  
      <security:openid-attribute name="email" type="http://schema.openid.net/contact/email" required="true"/>  
      <security:openid-attribute name="forename" type="http://schema.openid.net/namePerson/first" required="true"/>  
      <security:openid-attribute name="surname" type="http://schema.openid.net/namePerson/last" required="true"/>  
      <security:openid-attribute name="name" type="http://schema.openid.net/namePerson/friendly" required="true"/>  
 </security:attribute-exchange>  

After google around, I found this. So change the config as:

 <security:attribute-exchange>  
      <security:openid-attribute name="email" type="http://schema.openid.net/contact/email" required="true"/>  
      <security:openid-attribute name="forename" type="http://schema.openid.net/namePerson/first" required="true"/>  
      <security:openid-attribute name="surname" type="http://schema.openid.net/namePerson/last" required="true"/>  
      <security:openid-attribute name="name" type="http://schema.openid.net/namePerson/friendly" required="true"/>  
      <!--Yahoo-->  
      <security:openid-attribute name="axFullname" type="http://axschema.org/namePerson" required="true"/>  
      <security:openid-attribute name="axEmail" type="http://axschema.org/contact/email" required="true"/>  
 </security:attribute-exchange>  

The result is the email attribute has correct value while axEmail and axFullname are null. But if I remove the axEmail, then the email is null. That's interesting. So finally, below config works well with both Google and Yahoo!, though we'll have duplicate email attributes with the same value:

 <security:attribute-exchange>  
      <security:openid-attribute name="email" type="http://schema.openid.net/contact/email" required="true"/>  
      <security:openid-attribute name="forename" type="http://schema.openid.net/namePerson/first" required="true"/>  
      <security:openid-attribute name="surname" type="http://schema.openid.net/namePerson/last" required="true"/>  
      <security:openid-attribute name="name" type="http://schema.openid.net/namePerson/friendly" required="true"/>  
      <!--Yahoo-->  
      <security:openid-attribute name="fullname" type="http://axschema.org/namePerson" required="true"/>  
      <security:openid-attribute name="email" type="http://axschema.org/contact/email" required="true"/>  
 </security:attribute-exchange>