Friday, June 27, 2008

Turn on HTTP Compression on IIS 6.0

I’ve seen my colleague have done it before, so I decided to try it out myself on my current project.

Here’s the background information on HTTP compression from TechNet, Using HTTP Compression for Faster Downloads (IIS 6.0).

Information on turning on and configuring HTTP compression from TechNet just too brief, as seen in the guide here. It shows how to turn on the HTTP compression feature from IIS 6, but that’s only half of the steps to make HTTP compression works. Therefore, I turn to blogs instead. Following the steps exactly from this article by Donny Mack works well for my case. Other’s might not be so lucky, as mentioned by Jeff Atwood on his blog.

In summary, following are the steps to turn on HTTP compression:

1. From IIS management console (inetmgr), right-click on Web Sites, then click properties, go to Service tab. Under HTTP compression, check Compress application files and Compress static files. Leave the Temporary directory and Maximum temporary directory size as default.

2. This step is optional for me, as I didn’t observe any difference in compression ratio if I skip this step. Right-click on Web Service Extension node and select Add a new Web service extension. In put extension name “HTTP Compression”, click on Add button and select “C:\WINDOWS\system32\inetsrv\gzip.dll”, check the checkbox Set extension status to Allowed.

3. Right-click on the root of the IIS server and select properties. Check Enable Direct Metabase Edit.

4. Now we proceed to edit the MetaBase.xml file, located at “C:\WINDOWS\system32\inetsrv\MetaBase.xml” Do make a backup first before you proceed.

5. Within the file, locate the tag <IISCompressionScheme>. There are two entries with the same tag, the first has a property of “…Compression/deflate”, while the second has a property of “…Compression/gzip”. We’re interested on the second one. I tried making changes on the deflate but there’s no difference for my case. So I left it as it is.

6. Most important properties to change are HcDynamicCompressionLevel, HcFileExtensions and HcScriptFileExtensions. I’ve set HcDynamicCompressionLevel to 10, added static file extensions to HcFileExtensions, and dynamic file extensions (e.g. aspx) to HcScriptFileExtensions. Note that the file extensions must be separated by next line (enter key).

7. Save the MetaBase.xml file and perform a iisreset.

I’ve used several pages from my SharePoint 2007 portal do benchmark the result, using Ethereal to sniff out the total packet size. Overall, I witness roughly compression ratio of 65% to 75%. Adding file extensions for images would not help much, as most browsers would have cached the files and would not perform another download. Unless, your pages contains lots of different images that the browser would not have cached before.

The following properties information are rather useful, taken directly from Donny’s blog:

  • HcDoDynamicCompression. Specifies whether dynamic content should be compressed. This is important because dynamic content is by definition always changing, and IIS does not cache compressed versions of dynamic output. Thus, if dynamic compression is enabled, each request for dynamic content causes the content to be compressed. Dynamic compression consumes considerable CPU time and memory resources, and should only be used on servers that have slow network connections, but CPU time to spare.
  • HcDoStaticCompression. Specifies whether static content should be compressed.
  • HcDoOnDemandCompression: Specifies whether static files, such as .htm and .txt files, are compressed if a compressed version of the file does not exist. If set to True and a file doesn't exist, the user will be sent an uncompressed file while a background thread creates a compressed version for the next request.
  • HcDynamicCompressionLevel. VAL(1-10) specifies the compression level for the compression scheme, when the scheme is compressing dynamic content. Low compression levels produce slightly larger compressed files, but with lower overall impact on CPU and memory resources. Higher compression levels generally result in smaller compressed files, but with higher CPU and memory usage.
  • HcFileExtensions. Indicates which file name extensions are supported by the compression scheme. Only static files with the specified file extensions are compressed by IIS. If this setting is empty, no static files are compressed.
  • HcScriptFileExtensions. Indicates which file name extensions are supported by the compression scheme. The output from dynamic files with the file extensions specified in this property are compressed by IIS.

Wednesday, June 18, 2008

Alternate Access Mapping Resources

I’ll add more as of when I find more resource on AAM


Wednesday, June 4, 2008

SharePoint security cache AD Group?

There seem to be a funny problem where AD group names are cached by SharePoint. So far I've observed two scenarios

Scenario 1: Unable to set AD group into MOSS security

I’ve created my own AD group and added the some users into the AD group. Then I add the AD group directly into some SharePoint subsite and granting them some permissions. This works out fine. Then I remove the AD group from SharePoint , delete the group from AD, and repeat the process again. I use back the exact same AD group name. This time, the user will not have access, as though the AD group is not added into SharePoint at all.

This problem can be fixed by performing an iisreset before re-adding the newly created AD group (with identical name as the previously deleted one) back into SharePoint. I’ll be performing “iisreset”s in the future when I’m setting up user permissions.

Scenario 2: People picker does not have the AD group

The scenario is like this: from a web part properties page, under Advnaced section, click on the browse button to bring up the people picker. Switch to find under Distribution/Security groups and perform a search. The AD groups that suppose to be around are not.

To fix this problem, just perform a full user profile import from the Shared Service Provider administration. But, there's a catch: you MUST delete all existing user profile, by viewing all existing user profile, and select all to perform the delete. Yes, painful process as there's no option to delete all existing user profile data, and it didn't work if you just perform a full user profile import directly.

Update: I've written a small console application to quickly delete all user profiles:

/*Include the following namespaces*/ using Microsoft.SharePoint; using Microsoft.SharePoint.Administration; using Microsoft.Office.Server.UserProfiles; using Microsoft.Office.Server; /*Here's the quick and dirty method*/ public void PurgeUserProfile(string url_) { using (SPSite site = new SPSite(url_)) { ServerContext context = ServerContext.GetContext(site); UserProfileManager profileManager = new UserProfileManager(context); foreach (UserProfile profile in profileManager) { System.Console.WriteLine("Deleting " + (String)profile[PropertyConstants.AccountName].Value); profileManager.RemoveUserProfile(profile.ID); } } }