Author Archive

# Intercepting RO/.NET HttpServer requests

With the Spring 2010 release, RemObjects SDK for .NET lets you intercept any configurable path on any of the non-super http Server channels and do something completely different with the http request. This feature was added to support REST in Data Abstract, but can also easily be used to host custom pages or whole websites from within any of the http components (IpHttpServerChannel, HttpSysServerChannel, WebProcessor).

How it Works

Each of the HTTP servers implements IHttpServer and exposes a Register and Unregister method. An Extended Http Dispatcher passes it’s implementation of IHttpDispatcher that gets called for each request, returns if it can handle a specific url, and if so, is asked to process the request. Else the next dispatcher from the list gets called, until none are left and the default helpers get called.

Creating Your Own Dispatcher

Writing a custom dispatcher for a given url is quite simple. You simply need to write a new class descending from the ExtendedHttpDispatcher class and override the Process method.

class MyDispatcher: ExtendedHttpDispatcher 
{
  override Process(
    IHttpRequest aRequest,
    IHttpResponse aResponse,
    Stream aRequestData,
    Stream aResponseData)
  {
    StreamWriter sw = new StreamWriter(aResponseData);
    aResponse.ContentType = "text/html";
    sw.WriteLine(@"
<html>
  <head>
    <title>Hello World</title>
  </head>
  <body>
    <font size='7'>Hello World</font>
  </body>
</html>
");
  }
}
 
  //...
MyDispatcher disp = new MyDispatcher();
disp.Path = "/hello";
disp.Server = ipHttpServer1;

Given this code, all requests to /hello or ones that start with /hello/ will get a nice “Hello World” page.

REST

The RestSchemaDispatcher class that ships with Data Abstract essentially does the same as above. It intercepts all requests to a given path. the first identifier after the path url is the table name for that request, and anything after that is used to find a record by primary key. More on the features of the RestSchemaDispatcher will be in one of my next blog posts.

by Carlo Kok, March 13th, 2010

# RemObjects Script for .NET

A while ago, I started planning a new Data Abstract feature: we wanted to support scripting in the .NET parts of the product, for validating business rules on both the client and the server, and for writing server logic, like we already have in Data Abstract for Delphi. There were several options we considered to us to use:

  • IronPython/Ruby
  • JScript.NET
  • Active Scripting JScript COM objects
  • CodeDom (C#, VB.NET)

But each came with it’s own problems. CodeDom, IronPython & IronRuby wouldn’t work for the Delphi and OS X side of things, and we wanted the new solution to be compatible across platforms. JScript.NET was deprecated a while ago and isn’t updated anymore, and the JScript COM objects aren’t very easy to manage from .NET, and wouldn’t work on Mono.

So what we did instead was write our own JavaScript (or as it’s properly called ECMAScript) engine. Microsoft had just introduced the new DLR, so we decided to base it on that, to have a good framework that would let us have an implementation with good performance and interoperability with other DLR and non-DLR based languages.

Initially, the development of this went rather slow, as the DLR at the time was very new, not even a 1.0 version was available, there were few docs and the samples online were hopelessly out of date. Adding to that was the problem that every update of the DLR code changed something. But now the DLR is becoming quite stable and parts of it will be in the soon-to-be released .NET 4.0 framework.

Introducing Script for .NET

Script for .NET is the end result of this work, and it’s a free-with-source implementation of ECMAScript (edition 3). It has all the features expected from JavaScript and the default (non-browser) objects like Object, Array, Function, Math, Number, Date, String, Boolean and RegExp. As mentioned above, the engine is based on the Dynamic Language Runtime, but it works on version 2.0 and later of .NET, as well as on Mono.

Debugging Support

The engine includes support for in-process debugging by the host, allowing to step through, step into and step out of the current function, and inspect all the locals and their current state. The following screenshot of one of the included sample applications shows this i action:

Usage

To make the engine easier to use, the class library includes an EcmaScriptComponent class which wraps the DLR and Scripting engine, lets the application run and debug arbitrary scripts, as can be seen below.

 
private void ShowMsg(string s)
{
  MessageBox.Show(s);
}
 
 
  ScriptEngine = new EcmaScriptComponent();
  ScriptEngine.Globals.SetVariable("ShowMessage", new Action<string>(MessageBox.Show));
  ScriptEngine.Source = @"
    var pi = Math.PI;
    ShowMessage('Todays value of PI is : '+pi);";
  ScriptEngine.Run();

It is also possible to and expose classes or complete .NET assemblies to the engine for use from within the script:

  ScriptEngine.ExposeAssembly(typeof(System.Object).Assembly); 
  // exposes all namespaces in mscorlib.

Where to get it

You can read more about RemObjects Script on its product homepage. The project itself is maintained on our code.remobjects.com open source repository, with full access to the SVN and bug tracker. The Spring 2010 release is available for download, now.

With the script engine itself out of the way, we are now working o the integration with Data Abstract, for our Summer releases.

by Carlo Kok, February 23rd, 2010

# Using LDAP for User Authentication

We at RemObjects Software have been using LDAP for centralizing the authentication for all our different projects, like our issue tracker, internal websites, calendar and jabber and it’s been working very well. However for .NET there’s only one library that can be used on both Mono & .NET to talk to an LDAP server, namely Novell.Directory.Ldap.

While this library supports all the features one could want out of an LDAP implementation, it had some issues with records not arriving when talking to an OpenLDAP server, so what we did is write our own, as part of InternetPack. It’s a simple LDAP client implementation but offers everything required for searching records and authenticating and supports both LDAPS and StartTLS over LDAP.

Simplifying the process

Included with the new LDAP classes is a wrapper that, given a few properties, handles the following:

  • Find a user by name, not by it’s full LDAP distinguished name
  • Validate the users’ credentials
  • Return the list of groups this user is member of
  • Return all available info about the user by returning it’s user record

We’re using this new class internally already and it works very well, but any comments on it would be appreciated. For those that are new to Internet Pack: it’s free.

by Carlo Kok, February 8th, 2010

# .NET 4.0 BigInteger support

The February release of Delphi Prism will include support for the new .NET 4.0 “BigInteger” type for all integer constants. BigInteger is a new class that let’s it’s users define an arbitrarily large integer. Using this new type for integer constants is simple in Delphi Prism:

  var r := 6985743574365784365432758943759843265983427594356349776534765743928657843567843625437564392067452985674398563429;
  var y := 8574398256943285643296524390;
  Console.WriteLine(y);
  Console.WriteLine(r);
  y := r - y;
  Console.WriteLine(y);

Output:

8574398256943285643296524390
6985743574365784365432758943759843265983427594356349776534765743928657843567843625437564392067452985674398563429
6985743574365784365432758943759843265983427594356349776534765743928657843567843625428989993810509700031102039039

Any constant that does not fit the largest type supported ((U)Int64) will become a BigInteger, or fail compiling if the new type isn’t referenced. BigInteger acts and works like a regular integer type, although it has some extra operations, like GreatestCommonDivisor, Remainder, Pow(er) and conversions to and from regular integer types.

by Carlo Kok, January 25th, 2010

# New blog engine

Today we switched to to a new blog engine (Wordpress to be specific), all addresses should have stayed compatible and so if you’re reading this it means everything is working. B2evolution became more and more tiresome to update while Wordpress can update without rewriting the templates from scratch.

With this update we also hope to spend a lot more time blogging.

by Carlo Kok, January 11th, 2010

# Obfuscar

A few releases ago we switched to Obfuscar for obfuscation of our libraries, after some critical issues with the commercial obfuscator that we used. I’ve been providing the original authors with new issues and patches for things I fixed in the process of using this project (ranging from bugs to features), however it looks like the original project is dead.

So now at code.remobjects.com/p/obfuscar you can find the latest version with my changes and binaries of that version. Among the new features are:

* Unreadable unicode characters for obfuscated identifiers
* Signing assemblies

Enjoy,

by Carlo Kok, November 4th, 2009

# Porting a Delphi/Win32 Code Parser to Delphi Prism

For an internal QA/Docs project, we’re working on a tool that, given a .NET library, Delphi .pas file or Objective-C .h file emits an XML file with all public types and members of those types. This tool will be used as part of the process to make sure we have all publicly accessible members documented in our wiki. There are few parsers available that understand all Delphi code (our own Prism parser does not support all Delphi/Win32 constructs, so it wasn’t an option for this little project), however there is one out there, that has always worked very well: mwdelpar, which Jacob Thurman took over as part of his work on Castalia: Castalia Delphi Parser. This is a free parser for Delphi licensed under the MPL.

Since I needed this to work in Delphi Prism, I spend an hour porting the code to Prism, and in this blog post I’ll cover some of the things I had to change to get it working.

Unit names and uses

For the 4 units involved, I had to change the unit header, as I wanted them all in the same namespace. The original looked like

unit CastaliaPasLex

I changed it to:

  {$IFDEF PRISM}
  Castalia.Pascal.Parser
  {$ELSE}
  CastaliaPasLex
{$ENDIF}

;

The second thing needed was to add a {$IFDEF PRISM} {$ENDIF} around the uses clauses.

After that I set the Allow Globals, Delphi Compatibility and the Allow Create keyword option and added {$IFDEF PRISM} {$ENDIF}around the destructors found in the file.

Making types public

Another difference in Prism is that the types are internal (assembly) by default and cannot be used outside the assembly. What I did is add {$IFDEF PRISM}public {$ENDIF} before the enums and classes I needed to expose.

Converting pointer to record to classes

The parser code had types like:

PDefineRec = ^TDefineRec;
TDefineRec = record
  Defined: Boolean;
  StartCount: Integer;
  Next: PDefineRec;
end;

This linked list could be converted to a generic LinkedList supported by .NET, but in this case it was much easier to just turn it into a class:

{$IFDEF PRISM}
  PDefineRec = TDefineRec;
{$ELSE}
  PDefineRec = ^TDefineRec;
{$ENDIF}
TDefineRec = {$IFNDEF PRISM}
  record
  {$ELSE}
  class public
  {$ENDIF}
  Defined: Boolean;
  StartCount: Integer;
  Next: PDefineRec;
end;

Most of the code that used this worked right away after that, except for the places it used a ^ to dereference the Next pointer.

Function pointers

The Prism compiler is a bit more strict when it comes to function pointers, especially when assigning a function to a variable of a function pointer type. A simple fix was to replace:

fIdentFuncTable[I] := Func15;

with

fIdentFuncTable[I] := {$IFDEF PRISM}@{$ENDIF} Func15;

Enum Members

The next part was slightly harder to do: Delphi Prism requires enums to be prefixed by the type that they’re defined in. This could be solved with a simple (interactive) search/replace in the file, since all keywords started with pt, I did a search/replace on ‘ pt’ and ‘[pt’ with ‘ {$IFDEF PRISM}TptTokenKind{$ENDIF}.pt’ or ‘[{$IFDEF PRISM}TptTokenKind{$ENDIF}.pt‘.

The Rest

After that, there were a only few small tweaks left to do, like changing calls to GetEnumValue to value.ToString, replace a few PChars with strings and a few RTL string functions to their .NET counter parts. All in all, it only took about an hour to convert the entire parser – and with the ifdefs I used it still compiles in Delphi/Win32, too.

by Carlo Kok, September 23rd, 2009

# CS2PAS 0.2

Just uploaded CS2PAS 0.2, this release should be able to do a conversion of the most common C# constructs. Download

Changes:

* 36: Bad conversion of array typed variable
* 37: Error during processing: Index was out of range.
* 40: Char constants declared like ‘\x1A’ cannot be converted
* 39: this. keyword is not converted to self.
* 30: && and || operators should automatically add parenthesis
* 29: simple “if (x) return” gets way to verbose
* 42: Class marked as internal is left using the internal keyword
* 31: DO for while, with and the others should do a space first
* 25: constructors get emitted with class name, in decl
* 24: “protected” gets translates as “assembly or protected”
* 26: inherited calls dont lose the dot
* 28: switch statement gets converted badly

by Carlo Kok, June 8th, 2009

# Compiling and running monodevelop from VS.NET

I’ve been spending a bit of time on MonoDevelop this week and gathered this information to get going with MonoDevelop.

First of all, you need GTK:
GTK the “GTK# for .NET” binary (just install that)

Also you need this zip file for binaries, or grab them yourself:
ICSharpCode.SharpZip.dll (from mono 2.4/lib)
MonoDoc.dll (from mono 2.4/lib)
Mono.Posix.dll (from mono 2.4/lib)
MonoPosixHelper.dll (from mono 2.4/bin); this will need to be copied next to the MonoDevelop binaries
Mono.Addins.* (compiled version of http://anonsvn.mono-project.com/source/trunk/mono-addins)

Place these files in a directory and add a registry entry for them so VS.NET can find them:

(win64)
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v2.0.50727\AssemblyFoldersEx\MonoBinaries]
@="D:\\Projects\\MD-checkouts\\bin"
(win32)
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v2.0.50727\AssemblyFoldersEx\MonoBinaries]
@="D:\\Projects\\MD-checkouts\\bin"

Monodevelop itself can be fetched from:
http://anonsvn.mono-project.com/source/trunk/monodevelop

Then open the sln file in the source dir. Change the Configuration to DebugWin32 and go to Build/Configuration manager. Check all projects except:
GnomePlatform
MacPlatform
MonoDevelop.NUnit (unless you have nunit)
MonoDevelop.XmlEditor.Tests (unless you have nunit)
UnitTests (unless you have nunit)

apply this temporary change (fixed in GTK svn already):

Index: main/src/core/Mono.Texteditor/Mono.TextEditor/TextEditor.cs
===================================================================
--- main/src/core/Mono.Texteditor/Mono.TextEditor/TextEditor.cs	(revision 134437)
+++ main/src/core/Mono.Texteditor/Mono.TextEditor/TextEditor.cs	(working copy)
@@ -292,7 +292,7 @@
Gtk.TargetList list = new Gtk.TargetList ();
list.AddTextTargets (ClipboardActions.CopyOperation.TextType);
-			Gtk.Drag.DestSet (this, DestDefaults.All, (TargetEntry[])list, DragAction.Ask | DragAction.Default | DragAction.Move |Â DragAction.Copy);
+			//Gtk.Drag.DestSet (this, DestDefaults.All, (TargetEntry[])list, DragAction.Ask | DragAction.Default | DragAction.Move |Â DragAction.Copy);
imContext = new IMMulticontext ();
imContext.Commit += IMCommit;

Set the startup Project to Mono.Startup and run it.
When you get a “File in use” error during compiling after you ran it before, open the task manager and kill the mdhost.exe task.

by Carlo Kok, May 20th, 2009

# CSharp to Oxygene 0.1

I’ve just written a new tool that converts C# code to Prism code. It’s the first version, and it’s still a work in progress, but the first release is out, and available on:

http://code.remobjects.com/p/csharptoxy/

It includes the source (in SVN) and is licensed as MPL. Feedback appreciated.

by Carlo Kok, April 10th, 2009