Galin Iliev's blog

Software Architecture & Development

Hosting WCF service over net.tcp protocol in IIS7 (WAS)

There are several articles showing how to host non-http protocols on IIS7. Some steps are like black box while others could easily be misconfigured. 

The tasks is complicated additionally by obscured error messages returned in the browser :)

So let’s started (the example below is in Windows Server 2008. In Vista/Windows7 is similar but not exactly same):

Phase 1: Prepare server (prerequisites)

1. Add Web Server Role

  • Select following features as a minimum:
  • Common HTTP Features - all
  • Application Development
  • ASP.NET
  • .NET Extensibility
  • ISAPI extensions
  • ISAPI Filters
  • Security – all

2. Add Application Role

Add Application Server role and select all features (confirm all dependencies):

image

With this Phase 1 is complete. We should be able to navigate to Internet Information Services (IIS) Manage console in Administrative tools.

Phase 2: Deploying WCF application

1. Build WCF application with netTcpBinding :) (kindda obvious). For service endpoints leave address relative or empty.

   1: <services>
   2:   <service name="Microsoft.Test.Service" behaviorConfiguration="Service.ServiceBehavior">
   3:     <!-- Service Endpoints -->
   4:     <endpoint name="netTcp" address="" binding="netTcpBinding" bindingConfiguration="bigMessages" contract="Microsoft.Test.IService" />
   5:     <endpoint name="mexNetTcp" address="mex" binding="mexTcpBinding" contract="IMetadataExchange"/>
   6:   </service>
   7: </services>

2. Create website that will host it in IIS

Since it is not a challenge to create it via IIS Manager here is how it can be achieved via script (JS). This can be used as custom action in WiX/MSI as well

   1: var adminManager = new ActiveXObject('Microsoft.ApplicationHost.WritableAdminManager');
   2: adminManager.CommitPath = "MACHINE/WEBROOT/APPHOST";
   3:  
   4: var sitesSection = adminManager.GetAdminSection("system.applicationHost/sites", "MACHINE/WEBROOT/APPHOST");
   5:  
   6: var sitesCollection = sitesSection.Collection;
   7:  
   8: var siteElement = sitesCollection.CreateNewElement("site");
   9: siteElement.Properties.Item("name").Value = "WcfNetTcp";
  10: siteElement.Properties.Item("id").Value = 7;
  11:  
  12: var bindingsCollection = siteElement.ChildElements.Item("bindings").Collection;
  13:  
  14: var bindingElement = bindingsCollection.CreateNewElement("binding");
  15: bindingElement.Properties.Item("protocol").Value = "http";
  16: bindingElement.Properties.Item("bindingInformation").Value = "*:80:";
  17: bindingsCollection.AddElement(bindingElement);
  18:  
  19: var siteCollection = siteElement.Collection;
  20:  
  21: var applicationElement = siteCollection.CreateNewElement("application");
  22: applicationElement.Properties.Item("path").Value = "D:\\Hosting\\WcfApp";
  23: applicationElement.Properties.Item("applicationPool").Value = "DefaultAppPool";
  24: siteCollection.AddElement(applicationElement);
  25:  
  26: sitesCollection.AddElement(siteElement);
  27:  
  28: adminManager.CommitChanges();
  29:  

3. Add net.tcp protocol:

Here is how it should look from GUI:

image

And the script for it

   1: var adminManager = new ActiveXObject('Microsoft.ApplicationHost.WritableAdminManager');
   2: adminManager.CommitPath = "MACHINE/WEBROOT/APPHOST";
   3:  
   4: var sitesSection = adminManager.GetAdminSection("system.applicationHost/sites", "MACHINE/WEBROOT/APPHOST");
   5:  
   6: var sitesCollection = sitesSection.Collection;
   7:  
   8: var siteElementPos = FindElement(sitesCollection, "site", ["name", "WcfNetTcp"]);
   9: if (siteElementPos == -1) throw "Element not found!";
  10: var siteElement = sitesCollection.Item(siteElementPos);
  11:  
  12:  
  13: var bindingsCollection = siteElement.ChildElements.Item("bindings").Collection;
  14:  
  15: var bindingElement = bindingsCollection.CreateNewElement("binding");
  16: bindingElement.Properties.Item("protocol").Value = "net.tcp";
  17: bindingElement.Properties.Item("bindingInformation").Value = "809:*";
  18: bindingsCollection.AddElement(bindingElement);
  19:  
  20: adminManager.CommitChanges();

4. Enable net.tcp for website (Virtual Application) that hosts Wcf Service – in this example we’re hosting in the root of website

image

And of course the script:

   1: var adminManager = new ActiveXObject('Microsoft.ApplicationHost.WritableAdminManager');
   2: adminManager.CommitPath = "MACHINE/WEBROOT/APPHOST";
   3:  
   4: var sitesSection = adminManager.GetAdminSection("system.applicationHost/sites", "MACHINE/WEBROOT/APPHOST");
   5:  
   6: var sitesCollection = sitesSection.Collection;
   7:  
   8: var siteElementPos = FindElement(sitesCollection, "site", ["name", "WcfNetTcp"]);
   9: if (siteElementPos == -1) throw "Element not found!";
  10: var siteElement = sitesCollection.Item(siteElementPos);
  11:  
  12: var siteCollection = siteElement.Collection;
  13:  
  14: var applicationElementPos = FindElement(siteCollection, "application", ["path", "/"]);
  15: if (applicationElementPos == -1) throw "Element not found!";
  16: var applicationElement = siteCollection.Item(applicationElementPos);
  17:  
  18: applicationElement.Properties.Item("enabledProtocols").Value = "http,net.tcp";
  19:  
  20: adminManager.CommitChanges();

Warning: Do not put any spaces in “Enabled Protocols” field. Although it might works for HTTP it doesn’t for net.tcp.

5. (Optional) Run in elevated mode (As Administrator):

   1: “%WINDIR%\Microsoft.NET\Framework\v3.0\Windows Communication Foundation\ServiceModelReg.exe" –i

I will cover why it is optional in next posts.

Note: Scripts are generated using IIS 7.5 IIS Management console and Windows 7

Hope that helps.

P.S. Here is the helper js function FindElement(). It is slightly modified from original generated by IIS Manager so it will compare values in case insensitive way.

IIS 7.5 features lists

Internet Information Services 7.5 (IIS)

The great Internet Information Services (IIS) has it’s v7.5 with following features in Windows Server 2008 R2

  • PowerShell provider for IIS 7 has more than 50 new cmdlets
  • Administration Pack extensions: Database Manager (SQL Server management within IIS Manager), Configuration Editor (generate scripts with a GUI to automate administrative tasks), IIS Reports, Request Filtering (HTTP filtering, URL rewriting, etc.)
  • One-click publishing in Visual Studio 10
  • Web Deployment Tool (formerly MS Deploy): Deployment, management, and migration of Web applications, sites, and entire servers
  • Configuration Tracing: track configuration changes to IIS and applications
  • New performance counters
  • .NET support for Server Core
  • WebDav integration (was available before as a separate extension)
  • URLScan 3.0 integration: restricts the types of HTTP requests (was available before as a separate extension)
  • FTP server services: integrated in the IIS administration interface; new .NET XML-based *.config format; virtual host names for FTP sites; improved logging
  • Integrated extensions: new kind of extensions that appear to be an integral part of IIS

(via 4sysops.com article)

VS2008 Web Setup Project and Win2008

I had interesting experience today. I tried to create a web setup project for one of my recent projects. As you know it is pretty straightforward: From Visual Studio 2008 File –> Add –> New Project –> Select Setup wizard.

image  

and just add output from existing project.
Then press Ctrl+Shift+B (Build ) and you’re ready… But not in Windows Server 2008. When I decided to test this newly made installation package I hit the ground with single dialog showing this message:

"The installer was interrupted before ApplicationName could be installed. You need to restart the installer to try again.

Click "Close" to exit."

 

Being experienced installer package developer I knew what I had to do: run the installer with verbose logging.

by executing this line:

   1: msiexec /i Installer.msi /lv detail.log

And I had nice 57 KB  file to read in wonderful notepad. And the problem action quickly appeared:

   1: Action start 16:22:53: WEBCA_SetTARGETSITE.
   2: MSI (c) (B4:4C) [16:22:53:082]: Note: 1: 2235 2:  3: ExtendedType 4: SELECT `Action`,`Type`,`Source`,`Target`, NULL, `ExtendedType` FROM `CustomAction` WHERE `Action` = 'WEBCA_SetTARGETSITE' 
   3: MSI (c) (B4:48) [16:22:53:082]: Invoking remote custom action. DLL: C:\Users\ADMINI~1\AppData\Local\Temp\MSIFB61.tmp, Entrypoint: SetTARGETSITE
   4: INFO   : [11/11/2008 16:22:53:097] [SetTARGETSITE                           ]: Custom Action is starting...
   5: INFO   : [11/11/2008 16:22:53:097] [SetTARGETSITE                           ]: CoInitializeEx - COM initialization Apartment Threaded...
   6: ERROR  : [11/11/2008 16:22:53:097] [SetTARGETSITE                           ]: FAILED:    -2147221164
   7: ERROR  : [11/11/2008 16:22:53:097] [SetTARGETSITE                           ]: Custom Action failed with code: '340'
   8: INFO   : [11/11/2008 16:22:53:097] [SetTARGETSITE                           ]: Custom Action completed with return code: '340'
   9: Action ended 16:22:53: WEBCA_SetTARGETSITE. Return value 3.
  10: MSI (c) (B4:4C) [16:22:53:097]: Doing action: FatalErrorForm
  11: Action start 16:22:53: FatalErrorForm.

Seeing WEBCA_SetTARGETSITE means that the installer was trying to set the destination. Having a web setup this means IIS was asked for “Default Web Site” and this call must be the one that fails. But why!? I have Web Server Role installed on the machine:

image

I and remembered from my MS DevDays 2008 IIS talk  – you still can use old (pre v7) IIS management tools with IIS7 as long as you have “IIS 6 Metabase Compatibility” role service installed.

image

I installed this role and … Voila!!! it works!!!

Microsoft.com on IIS7 performance data

You know www.microsoft.com, right? :) This the corporate web site of the biggest software company and the very wanted target of every hacker (or wanna-be hacker). When this website (or some other Microsoft websites like www.msdn.com) is down or show an unexpected error there are screenshots on the web (and blog posts) and this become a news of the day in software world :) - or at least on web dev world.

So now imagine of you are decision maker for hosting platform!? or hardware behind it?! or setting a bandwidth :)?! There is very little room for mistakes, huh?

And still www.microsoft.com is hosted on IIS7 .. since Beta3 (post is from June 15th, 2007). When Microsoft trust enough on IIS7 and host such important site on it, why you can't?

There is no doubt that the configuration behind Microsoft.com is interesting so here is it:

=============== Microsoft.com configuration ====================

Hardware:

  Model: HP DL585 G1 (4 dual-core CPUs)

  RAM: 32GB 

OS:

  Windows Server 2008 RTM (Build: 6.0.6001.18000) Enterprise version x6

Cluster:
  Number of clusters: 4 (in multiple datacenters)
  Machines in each cluster: 20
  Total machines: 80
Load Balancing:
  Hardware load balancing solution is used. The load balancing algorithm we are using is based on “Least Current Client Connections” to each load balanced member server of the cluster (not round robin, or other any other load balancing algorithms). The hardware load balancer will maintain the same number of current client connections to each member of the cluster. So if a W2K8 server is completing web requests faster than a W2K3 server, the load balancer will send more traffic to the server W2K8 RTM server.

======================================================

Recently some performance data has been released on TechNet and here is what it says:

  • Win2008/IIS7 process more Requests per second(RPS) than Win2003/IIS6.
  • Due to #1 Win2008's CPU is more utilized.
  • As Win2008/IIS7 is performing better the load balancer send more requests to it.

IIS7-vs-IIS6

Server Efficiency (RPS/ CPU %) – Efficiency of serving live web platform traffic

W2K3 SP2 4.36 “requests per CPU cycle”

W2K8 RTM 4.84 ~ 10.9% increased efficiency

CPU Utilization (%)

W2K3 SP2 44.8%

W2K8 RTM 52.8% ~ 17.9% degradation (This is impacted by the increased RPS the W2K8 servers are handling)

Web Service – Total Methods Requests/Sec (RPS)

W2K3 SP2 194

W2K8 RTM 255 ~ 31.4% more traffic is being sent to the W2K8 RTM servers

Web Service – Current Connections

W2K3 SP2 280

W2K8 RTM 294 ~ 5% increase

Load Balancing – Current Client Connections

W2K3 SP2 116

W2K8 RTM 116 Equal – as the hardware load balancer maintains the same amount of outstanding open client connections.

.NET CLR Memory – % Time in GC

W2K3 SP2 1.1%

W2K8 RTM 2.5% No significant degradation in “Time in GC

 

Source: Microsoft.com Operations blog post on TechNet.

IIS7 is really next generation web platform...

My Sessions at Microsoft Days 2008 in Sofia, Bulgaria

MS Days 2008 in Bulgaria is in history now and I could say I had a nice two days. There were many lecturers (about 50) and 72 sessions in 6 tracks.

For those who missed my talks or are interested in slides here are summary of the sessions:

LINQ to XML - Data Access Technologies

This session was focused on the new API from XML team for .NET languages. I gave a side by side comparison between traditional DOM vs. LINQ to XML regarding those most common actions:

  • Create XML
  • Traverse XML
  • Transform XML

I covered also VB9 Literals. At the moment I started talking about VB I was thinking people would throw rocks at me (and some really considered that option:) ). But at the moment when repeated some of demos with VB9 code the audience was very impressed and they forgot about those rocks in their pockets. Even there were initial brainstorming whether same things can be implemented in C# with custom code.(Unfortunately this is a compiler feature and we cannot do it very easily).

Another thing I mentioned was LINQ to XSD.

I've decided that people will understand my points better if I write code in front of them instead of just explaining it. This is also more challenging :). I think it went well...

Here are the downloads:

IIS7 for IT Pros

IIS7 is the most interesting feature in Windows Server 2008 and I already had some talks about it. In this talk I covered (from administration perspective) following key topics:

  • What is missing in IIS 6.0
  • IIS7 module architecture and it's benefits
  • New .NET-like configuration files and metadata
  • Delegated Administration
  • Shared Configuration
  • Tracing and Diagnostics

The things I've demonstrated are:

  1. New tools - new management console as well as APPCMD command-line tool
  2. Richness of new error pages and generated trace file - it is whole HTML+JS application built with XML & XSLT with incredible amount of information.
  3. WCAT stress test with view of live requests on the server.
  4. Analyze server and site load using IIS7 Admin Pack features.

And here is the presentation: MS PowerPoint 2007 format (0.98 MB)

Any feedback is very welcome.

How bad is SQL Injection

I have been presenting IIS (Internet Information Services) for a while and there is one slide in my deck which says that there is No critical security patch since RTM for IIS6.

Recently there was some news about 500k web pages was exploited with SQL Injection hack(more info here and here).

Although this could put some shadow on IIS security it has to be clear that this is not an IIS exploit. This is application exploit. Any application could suffer SQL Injection (video: Length: 6:01 - Size: 6.37 MB ).

It is not like uploading harmful file on the server and execute it, isn't it?

So it has to be clear: Do not use such code:

public bool Login(string userName, string password)
{
    string command = string.Format("SELECT COUNT(*) FROM User WHERE UserName='{0}' AND Password='{1}'",
        userName, password);

    using (conn)
    {
        SqlCommand cmdLogin = new SqlCommand(command, conn);
        conn.Open();
        int res = cmdLogin.ExecuteScalar();
        return res == 1;
    }
}

Do you know why?!

Because if you get as password the following string ' OR 1=1 '; drop table Users; you will drop the table from DB and apparently the application will stop working.

Do it this way:

public bool Login(string userName, string password)
{
    string command = string.Format("SELECT COUNT(*) FROM User WHERE UserName=@UserName AND Password=@Password",
        userName, password);

    using (conn)
    {
        SqlCommand cmdLogin = new SqlCommand(command, conn);
        cmdLogin.Parameters.AddWithValue("@UserName", userName);
        cmdLogin.Parameters.AddWithValue("@Password", password);

        conn.Open();
        int res = cmdLogin.ExecuteScalar();
        return res == 1;
    }
}

It is much safer...

Hope this helps!

VS2008 and .NET 3.5 (WCF, WPF, WF) Training Kit

Microsoft released a nice training kit for the latest technologies that will help you to become a real hero very quickly.

This package is a real treasure because it covers a bunch of technologies:

  • C# 3.0
  • VB 9.0
  • LINQ
  • WPF
  • WCF
  • WF
  • Silverlight
  • ASP.NET
  • AJAX
  • CardSpace
  • Mobile
  • Visual Studio Tools for Office
  • Visual Studio Team System
  • Application Lifecycle Management
image

And the materials are of the different types:

  • Presentation - will be very helpful to prepare talks for community
  • Demos
  • Labs - very helpful to walk through new technologies in deep.

Go grab it!

IIS7 Admin Packs add analytics features

IIS7 is grew to a development platform and become the most wanted feature in the new Windows Server 2008. But this is not the end - IIS7 Admin Pack first CTP is here and provides a nice set of features that can help you to understand what is happening on the server...

here are new features in short:

  • Database Manager: Built-in SQL Server database management, including the ability to create, delete, and edit tables and indexes, create/edit SPROCs and execute custom queries.  Because it is integrated in the IIS administration tool it all works over HTTP/SSL - which means you can use the module to remotely manage your hosted applications (even with low-cost shared hosting accounts), without having to expose your database directly on the Internet.

  • Log Reports: Built-in report visualization with charting support for log files data.  Full range selection and custom chart creation is supported, as well as the ability to print or save reports.  Like the database manager you can use this module remotely over HTTP/SSL - which means it works in remote shared hosting scenarios.

  • Configuration Editor: This is a power module that provides complete control over editing all web.config settings within the admin tool.  You can configure it to track the changes you make using the UI and have it auto-generate configuration change scripts that you can then save and tweak to re-run later in an automated way.

  • Request Filtering UI: This admin module provides more control over the new request filtering feature in IIS7.  Check out Carlos' blog post here for details on how to use it.

  • .NET Authorization: This admin module provides a custom authorization rules editor which allows you to more easily manage the ASP.NET <authorization> configuration section.

  • FastCGI UI: This admin module provides more support for editing all the new <fastCGI> settings (for when you use FastCGI modules with IIS7 like PHP).

 

While DB manager can save you time jumping between applications Log Reports definitely rocks. It gives you an option to view activities on the server in very convenient form in following categories:

  • Web Server\Status code:  This report gives the comparison between number of hits and status code.
  • Web Server\Hits Per Url: This report gives the comparison between number of hits and the Url.
  • Web Server\Hits By Hour: This report gives the comparison between number of hits and the Hour.
  • Web Server\User Agent: This report gives the comparison between number of hits and the User Agent.
  • Web Server\File Extension: This report gives the comparison between number of hits and the file extension.
  • Web Server\User: This report gives the comparison between number of hits and the User.
  • Web Server\Time Taken: This report gives the comparison between Average time taken and the Url.
  • Web Server\Win32 Errors: This report gives the comparison between Hits and the Win32 Errors.
  • Web Server\Client Machine: This report gives the comparison between Hits and the Client Machine.
  • Web Server\Http Method: This report gives the comparison between Hits and the Http Method.

Just see these screenshots:

For more info visit these links:

IIS7 supports media streaming through new module

IIS7 team released a new module that will optimize the work and bandwidth usage of media serving sites

Imagine this scenario - a client connects to your video site, clicks on your featured video, watches 5 seconds of it to realize they have no interest in watching further, and move on to the next video.

In those 5 seconds, the server could have sent out 5 minutes worth of the video, and you paid for 5 minutes worth of bandwidth. With the bit-rate throttler + media bitrate detection, the server would only end up sending a little over 5 seconds worth, and you would end up paying only for what was used.

 

Download links:
- 32 bit - http://www.iis.net/downloads/default.aspx?tabid=34&g=6&i=1640
- 64 bit - http://www.iis.net/downloads/default.aspx?tabid=34&g=6&i=1641

Read full blog post of the daddy of this project.

Update:ScottGu posted a more detailed post on his blog covering this module with some screenshots

The below whitepapers describe how to enable and use it more:

Microsoft DevDays 2008 in April

The registration for the biggest annual event for developers in IT pros in Bulgaria is open. It will be held in International Exhibition Center - Sofia, Bulgaria. For second year in row it is paid event but the price is very low for the knowledge one can gain - it is just 50 EUR.

I am going to present two sessions: LINQ to XML - Data Access Technologies and IIS7 for Administrators.

If you're particularly interested in some details drop me a line and I will try to cover it. In case it is too specific to present we can chat after the session.

Almost forgot: The event will take place at April 24th and 25th 2008.

See you there!