Monday, 2 May 2016

How to host PHP web application on IIS web server

Although I work as a desktop application developer I talked the other day about PHP language with one of my colleagues who is a web developer. Having at home a Windows machine which comes with IIS web server (IIS10 on Win10), I became curious about what would it take to create a simple PHP web application and host it on IIS. I decided to make a single PHP page which would display the public IP address of the host which sends request.

And here we go. I googled for a simple PHP code which echoes the IP address of the client so all credits for the code below go to the guy who answered the following question on StackOverflow: How to get the client IP address in PHP?

main.php:


Index page in PHP world might have a different standard name and I am sure this code should be rearranged and optimized but I am leaving it as it is as my goal is to make fast proof of concept.

It has been a while since I touched IIS web server last time but I remember I could add a web application under the Default Web Site. Each web application has its own directory at path c:\inetpub\wwwroot so we can save main.php at a new directory: c:\inetpub\wwwroot\WhatIsMyIp. We can then add a new application:



When IIS receives request for PHP page, it has to forward it to PHP engine which would process it. This engine is actually PHP language binding for FastCGI protocol which comes as an executable (php-cgi.exe) within a PHP pack for Windows which can be downloaded from http://windows.php.net/download/. Side note on that page says "If you are using PHP as FastCGI with IIS you should use the Non-Thread Safe (NTS) versions of PHP." so I downloaded the latest version (php-7.0.6-nts-Win32-VC14-x64.zip at the moment...) and unpacked it into arbitrary location e.g. c:\PHP\php-7.0.6-nts-Win32-VC14-x64\.

CGI has to be enabled on IIS and this can be done in Windows Features. If we click on Windows start button and type Turn Windows features on and off, Windows Features window opens. We have to go to Internet Information Services, World Wide Web Services, Application Development Features and select (tick) CGI item:



We can now add a PHP CGI handler to our website in IIS:


We also have to make sure that World Wide Web Publishing Service (W3SVC) is running:


If IIS server and Default Web Site are started, we can test our web application from the local browser:


In order to allow accessing this web site from other devices on the same LAN we have to set Inbound rule on the firewall running on the IIS host. In case of Windows Firewall we can simply enable predefined rule World Wide Web Services (HTTP Traffic-In):


I am using default port for HTTP traffic (TCP port 80) so this rule will allow all incoming packets destined for IIS host and port 80 to reach IIS process - the one which listens to HTTP requests on that port.

If we want to access website hosted on another device within the same LAN we have to know what's its IP address (or hostname if we would set up some DNS resolution within this LAN or on the client device). ipconfig command run on IIS host outputs 192.168.0.3 as its IP.

If we open browser on another device which is on the same LAN and type http://192.168.0.3/WhatIsMyIp we'll get the following:



Obviously, all IP addresses we got are their IP addresses within the same LAN because so far both server and clients were on the same network. All devices behind router have the same public IP address which is the WAN (public) address of the router. This address is usually assigned by the ISP.

The true test would be if we try to load this page from a browser on a device which is not on this network. In order to allow accessing this web site from devices which are not on the same LAN, we have to enable port forwarding for HTTP traffic on the router behind which is host with our IIS server. That could look like this:


If WAN address of this router is e.g. 74.90.112.208 we can call our web app from e.g. mobile device connected to Internet via mobile 3G or 4G interface by typing in the browser: http://74.90.112.208/WhatIsMyIp.


Tuesday, 12 January 2016

Sniffing the traffic on the loopback interface on Windows with RawCap

If you ever had to write a chunk of code for inter-process communication via Internet Protocol (IP) you must have came across using the loopback interfaceIPv4 address 127.0.0.1 is usually the address of this virtual interface and also the address that hostname localhost  resolves to. You would, at least for tests, set one process (server) listening on some port on the localhost while the other process (client) would connect to the server and start their data exchange. 

In order to check the data sent from one end to another, we can use any kind of process output (standard output, log, ...) provided that given process actually shows that data. But what if there is no such output? We have to find a way how to sniff the traffic between these two parties.

RawCap is one of free tools capable of sniffing packets on the loopback interface. It collects packets and stores them in the file in pcap format. This file can be opened in Wireshark.

In order to demonstrate RawCap packet capturing we can use ready-made networking application which can serve both as a server and a client - Ncat. It comes as a part of Nmap for Windows and uses TCP by default.

Once Nmap is installed, open console window in C:\Program Files (x86)\Nmap directory and  type the following:


> ncat -v -4 -l localhost 6789


-v (or --verbose) sets verbose output
-4 instructs ncat to use IPv4 addresses only
-l (or --listen) switch makes Ncat to listen for incoming connections on the provided hostname and port. localhost will be resolved to 127.0.0.1 and I also used an arbitrary port which was free - 6789.

We effectively have server running now but before we run the client it is necessary to start capturing packets. From the directory with RawCap.exe we have to open terminal window with Administrator's privileges and run RawCap.exe (which has to be run as Administrator). Now we just have to follow the instructions. RawCap lists network interfaces and asks which interface shall be monitored. We have to type in the number next to the loopback interface. In the next step we can set the name of the packet dump file or just leave default name which is dumpfile.pcap. At this point we have started sniffing packets on the localhost!


> RawCap.exe
Interfaces:
0. 169.xxx.xxx.xxx Local Area Connection Ethernet
1. 169.xxx.xxx.xxx Local Area Connection* 2 Wireless80211
2. 169.xxx.xxx.xxx Ethernet Ethernet
3. 169.xxx.xxx.xxx Ethernet 2 Ethernet
4. 169.xxx.xxx.xxx Local Area Connection 2 Ethernet
5. 127.0.0.1 Loopback Pseudo-Interface 1 Loopback
6. 192.xxx.xxx.xxx Wireless Network Connection 2 Wireless80211
Select interface to sniff [default '0']: 5
Output path or filename [default 'dumpfile.pcap']:
Sniffing IP : 127.0.0.1
File : dumpfile.pcap
Packets : 0


Let's now start the client. We have to open another terminal window in Nmap's directory and run another instance of Ncat which will try to establish TCP connection with the localhost:6789 endpoint:


> ncat -v 127.0.0.1 6789


Both server and client show the state of their current connections:

Server:

> ncat -v -4 -l localhost 6789
Ncat: Version 7.01 ( https://nmap.org/ncat )
Ncat: Listening on 127.0.0.1:6789
Ncat: Connection from 127.0.0.1.
Ncat: Connection from 127.0.0.1:9323.



Client:

> ncat -v 127.0.0.1 6789
Ncat: Version 7.01 ( https://nmap.org/ncat )
Ncat: Connected to 127.0.0.1:6789.



So far, only TCP handshake has taken place in the communication between these two instances of Ncat. We can expect that RawCap has captured at least these 3 packets so far (SYN, SYN-ACK, ACK). Let's now send some user data. By default Ncat works as an echo server which means that it echoes any text message it receives. If we type in the client "hello from client", that string will appear on the server's output. The same happens if we go the other way round and send message from the server to the client. Once we want to stop communication, we can use CTRL-C combination to stop one process. The other will get disconnected and also terminate. We can use the same combination in order to stop RawCap.exe.

At the end of the session we have:

Server:


Client:


RawCap.exe:



RawCap.exe saved all captured packets in file dumpfile.pcap. If we open this file in Wireshark and filter out all packets with TCP port 6789 we can see packets exchanged between our Ncat processes:


If we follow that TCP stream we can see exact text messages sent between client and server:


Friday, 1 January 2016

How to use internal type as a unit test argument

Behavioral tests sometimes require access to types which are internal for the SUT assembly. If those types are used in test methods, test assembly name has to be specified through InternalsVisibleToAttribute in SUT assembly. For example, if MyAppTests is a library containing tests for classes within MyApp we have to do the following:
  • in MyAppTests: add the reference to MyApp so all public types are visible
  • in MyApp: specify MyAppTests as the assembly in which internal types are visible. The following line has to be added to MyApp/Properties/AssemblyInfo.cs:

[assembly: InternalsVisibleTo("MyAppTests")]



This makes internal types visible within unit tests. But if we want to pass such types as arguments to unit tests (via TestCase or TestCaseSource attributes), compiler will complain about inconsistent accessibility.

For example, if we have public class (SUT) and internal enum:


and the following test:


Compiler issues an error:

Error CS0051 Inconsistent accessibility: parameter type 'MyEnum' is less accessible than method 'MyClass_Tests.Foo_Does_This_When_MyEnum_Is_Value1_or_Value2(MyEnum)'

Unit test methods have to be public, otherwise unit test runners will not be able to see them or would report that test fails (Nunit Test Adapter also issues error message: "Method is not public"). Unit tests are public API so types of their arguments also have to be public (visible in any assembly, not just in test library).

The solution for this is to pass arguments to test method as type object and then cast them back to the original internal type:


In this particular case, when internal type is enum, we could gave passed type int instead of object but for any other custom internal type, object is the only solution.


Thread which explains reasons why NUnit fails but does not ignore non-public test methods.

Thursday, 31 December 2015

Performance tests

Code can always be optimized in terms of resources used. It makes sense adding performance tests when resources matter and their acceptable usage is a part of the requirements.

Resources can be time, memory, number of threads, sockets etc...but probably most measured are time and memory.

These tests are integration tests because:
- they rely on external factors (they are system- and hardware-dependent)
- asserted results can vary in time
- they can take much time to execute

An example of performance test is verifying that some algorithm performs some task within the acceptable time range.

There is a question on their consistency: e.g. the same algorithm takes more time to execute on slower machines so how to determine pass/fail criteria?



Further reading:
https://en.wikipedia.org/wiki/Software_performance_testing
http://www.dynatrace.com/en/javabook/performance-in-continuous-integration.html
http://stackoverflow.com/questions/751626/performance-testing-best-practices-when-doing-tdd
http://stackoverflow.com/questions/2870322/performance-testing-versus-unit-testing
http://stackoverflow.com/questions/457605/how-to-measure-code-performance-in-net
http://stackoverflow.com/questions/969290/exact-time-measurement-for-performance-testing
http://stackoverflow.com/questions/15181358/how-can-i-unit-test-performance-optimisations-in-c


Thursday, 24 December 2015

DRY in action - Use lambda to fixate method's argument


In the following example we have a situation where Foo() calls Bar() multiple times. Within each Foo() call, it passes to Bar() different value for string argument but always the same value for int argument:

Output:


i = 123, s = test1
i = 123, s = test2
i = 123, s = test3
i = 456, s = test1
i = 456, s = test2
i = 456, s = test3


To avoid unnecessary repetition we can introduce one level of indirection - a lambda which calls Bar() and provides it string value via its own argument and int value via capturing argument passed to Foo(). After refactoring:

Output:


i = 123, s = test1
i = 123, s = test2
i = 123, s = test3
i = 456, s = test1
i = 456, s = test2
i = 456, s = test3


Monday, 21 December 2015

OperationCanceledException vs TaskCanceledException when task is canceled


In my previous post, "How to cancel a Task", I mentioned that MSDN recommends throwing OperationCanceledException from a cancelled task. But the following example shows that canceling .NET methods makes them throw a different exception type - TaskCanceledException:

Output:


System.Threading.Tasks.TaskCanceledException: A task was canceled.
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Program.d__1.MoveNext()
Task.IsCanceled: True
Task.IsFaulted: False
Task.Exception: null


So why .NET does not follow its own rules? Why exception thrown in the example above was not OperationCanceledException?

I asked this question on SO and this is how I interpret the answer I got:

(1) System.OperationCanceledException class has been around longer than TPL. MSDN describes it as: "The exception that is thrown in a thread upon cancellation of an operation that the thread was executing." It is intended to be thrown from a thread in which operation is executed. .NET async API are actually synchronous operations (return Task, not marked as async). They don't have additional thread involved which makes OperationCanceledException not appropriate exception to be thrown.

(2) It is different to cancel a Task (setup of the engine which will execute "real work", user's operation) than to cancel operation itself. For example, we can pass already cancelled token to a task or can simply create already cancelled task. Operation and its thread are not started at all in these cases but if we await such task and catch OperationCanceledException we might think they were actually started. So it makes sense to use different type of the exception in these two different scenarios.

Example 1: Already canceled token is passed to task factory method:

Output:


System.Threading.Tasks.TaskCanceledException: A task was canceled.
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Program.d__1.MoveNext()
Task.IsCanceled: True
Task.IsFaulted: False
Task.Exception: null


Example 2: Awaiting task which is created as already canceled:

Output:


System.Threading.Tasks.TaskCanceledException: A task was canceled.
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNot
ification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   at Program.d__1.MoveNext()
Task.IsCanceled: True
Task.IsFaulted: False
Task.Exception: null


From the points made above we can conclude that caller of the cancelable task can expect two types of exceptions:OperationCanceledException and TaskCanceledException. As the latter derives from the former, it is enough to handle OperationCanceledException if we want to handle the case of canceled task:




Further reading:
SO Q&A: OperationCanceledException VS TaskCanceledException when task is canceled
SO Q&A: Difference between OperationCanceledException and TaskCanceledException?
Andrew L Arnott: Recommended patterns for CancellationToken

Sunday, 20 December 2015

How to cancel a Task


It is a good practice to offer users a chance to cancel some long-running operation. Such operation usually has to run asynchronously and in a TPL-based design is modeled as a method returning a Task.

Cancellation model requires some flag which is accessible by the caller and from inside the operation. Caller sets the flag when wants operation to be cancelled. Operation regularly checks the flag or is subscribed to the event "flag has been set" and if flag has been set, operation will stop doing the work. This model is in .NET abstracted with two types: CancellationTokenSource class and CancellationToken structure. Caller uses CancellationTokenSource to initiate cancellation and operation uses CancellationToken to check whether it has been cancelled.

When designing an API, if provision for operation cancellation is required, we have to add a CancellationToken to a list of method's arguments. API caller invokes CancellationTokenSource.Cancel method which sets CancellationToken.IsCancellationRequested to true. Target method checks this property and can either silently return or throw OperationCanceledException. The latter approach is better as only in this case returning task will come to Canceled state.

The following code depicts the whole process of task cancellation:

CancellationToken.ThrowIfCancellationRequested() method simply checks CancellationToken.IsCancellationRequested and if it's true, it throws OperationCanceledException. The output of the code above is:


.........System.OperationCanceledException: The operation was canceled.
   at System.Threading.CancellationToken.ThrowIfCancellationRequested()
   at MyService.d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Program.d__1.MoveNext()
Task.IsCanceled: True
Task.IsFaulted: False
Task.Exception: null


The following code shows that the await-ed task does not get aware that the task it holds got canceled if method silently returns on cancellation:

Output:

..........Task.IsCanceled: False
Task.IsFaulted: False
Task.Exception: null


Further reading:
Andrew Arnott - Recommended patterns for CancellationToken
MSDN: Task Cancellation