Subject: Decision on Rules Language

From: "Anwar M. Haneef" <[email-masked]>
Date: Sat, 20 Sep 2003 00:41:48 -0500

Hi Alex,

>My vote is against native support in P because the majority of
>applications would find existing string operators (substring
>searching, essentially) and application-specific interfaces
>sufficient. (BTW, I will add a length() and index() string functions
>to Core).
>> These would be used a lot in a rules language.
>
>Can you give a couple of examples where REs would be essential, given
>available substring searching operators _and_ ability of
>application-specific modules to split application objects (e.g., HTTP
>headers) into semantically valid but smaller pieces for you?

I suppose if you have modules that can process REGEXs as quickly, it should be all right.

> Section 2. Escape sequences for the grammar (from C++):
>
> escape-sequence:
> 	basic-escape-sequence/
> 	octal-escape-sequence/
> 	hex-escape-sequence
>
>Yeah, and we would need to add a universal-character-name as a part of
>string-char or escape-sequence. This all looks kind of heavy. Is there
>a simpler, but still complete solution? Replacing support for
>octal-escape-sequence and hex-escape-sequence with
>universal-character-name? What does XML have to offer here?

Sorry, I am not well versed in this space :-(

But, I have tried to write up a few (simple) examples for the examples to-do:

Example1: (edited from the current version)

   	Http := import "http://ietf.org/opes/rules/p/HTTP";

   	// Is the requested web document our home page?
   	isHome := request.uri.looksLikeHome();

   	// Does the user send us a specific cookie?
   	cookie := makeHeader("Cookie", "sew=23");
   	haveCookie := request.headers.have(cookie);

   	if (isHome and haveCookie) {
   		Services := import "http://ietf.org/opes/rules/p/Services";
   		service := Services.findOne("opes://local.net/add-lcl-content");
   		service.clientIp(request.clientIp);
   		Services.applyOne(service);
   	}

Example 2: HTTP header anonymization

   	Http := import "http://ietf.org/opes/rules/p/HTTP";
	
	haveClientAddress := defined request.getRemoteAddress();
	haveUserAgentInfo := defined request.getUserAgent();

  	if(haveClientAddress and haveUserAgentInfo )
	{
   		Services := import "http://ietf.org/opes/rules/p/Services";
   		service := Services.findOne("opes://anon.net/anonymize");
		Services.applyOne(service, request.header);
	}

	//forward the request to the content server
	request.forwardRequest();

Example 3: SMTP Email filter

	Smtp := import "http://ietf.org/opes/rules/p/SMTP";
	
	haveAttachment := message.header.getContentType() equal "multipart/mixed"

	if(haveAttachment)
	{
   		Services := import "http://ietf.org/opes/rules/p/Services";
   		service := Services.findOne("opes://norton.com/VirusCheck");
		Services.applyOne(service, message.body);		
	}

	if ( currentUserEmail equal message.header.getSenderEmail() )
	{
		message.returnToSender("Your attachment had a virus.");	
	}
	else
	{
		message.replaceBody("The message had a virus infected attachment.");
	}

Example 4: User-Agent-based content transcoding - This might be a more complicated example. In case you are interested, I can write this up. Being a telecom industry person, this would be more relevant for my applications.

Regards,
Anwar

---

From: Alex Rousskov <[email-masked]>
Date: Sun, 21 Sep 2003 15:52:10 -0600 (MDT)

On Sat, 20 Sep 2003, Anwar M. Haneef wrote:

> Example 4: User-Agent-based content transcoding - This might be a
> more complicated example. In case you are interested, I can write
> this up. Being a telecom industry person, this would be more
> relevant for my applications.

I would be interested to see this implemented. IMO, at least one
complicated example would be good for both us writing the spec and
folks considering supporting it.

Thanks,

Alex.

P.S. I will work your other examples in, thank you for posting them!

---

From: "Anwar M. Haneef" <[email-masked]>
Date: Mon, 22 Sep 2003 01:10:44 -0500

Hi Alex,

Here is the content transcoding example. I have tried to keep it simple and yet functional. Please let me know if its too simple - I tried to simplify things since I work with this kind of functionality all the time, so I wasn't sure whether it would be difficult/easy for other people to grasp the idea quicky.

Example 4: User-Agent-based content transcoding. The request is parsed for User-Agent and subscriber info. This info is used  to authenticate the user and forward the request if authenticated. The response data is passed through transcoders based on  their content types and finally directed to the client.

	userAgentInfo := request.getUserAgent();
	subscriberInfo := request.getSubscriberAccountInfo();

	if( defined subscriberInfo )
	{	
		/* Check  if the user is a valid subscriber */
		{
   			userAccountingService := Services.findOne("opes://isp.net/UserValidatorNAccounting");
			Services.applyOne(userAccountingService, request.header);
		} 
		otherwise
		{
			/* Use backup service provider in case of failures */
   			userAccountingService := Services.findOne("opes://ispbackup.net/BackupUserValidatorNBilling");
			Services.applyOne(userAccountingService, request.header);
		}
		otherwise
		{
			/* Deny access in case the accounting server is inaccessible */
			request.denyAccess();
		}
		
		if( !request.isAuthorized() )
		{
			/* respond to the client with an error message since user is not authorized*/
			response.header.setStatus(401, "Unauthorized User");
			response.setBody("<html>You are not an authorized user</html>");
			sendResponse();
		}
		else
		{
			/* The user is an authorized user and has access to transcoding services */

			/* forward the request to the content server and wait till response received */
			forwardRequest();
	
			contentType := Http.response.getContentType();
			if(contentType begins_with "image/")
			{
   				transcoderService := Services.findOne("opes://ispservices.net/Transcoder");
				service.setUserDevice( userAgentInfo );
				Services.applyOne(transcoderService, response.body);

				//track user service record via the accounting service
				Services.applyOne(userAccountingService, "Service name = "+transcoderService,  subscriberInfo);	
			}
			else if (contentType equals "application/x-shockwave-flash")
			{
		   		flashTranscoderService := Services.findOne("opes://ispservices.net/Flash2PNG");
				service.setUserDevice( userAgentInfo );
				Services.applyOne(flashTranscoderService, response.body);		
	
				//track user service record via the accounting service
				Services.applyOne(userAccountingService, "Service name = "+flashTranscoderService,  subscriberInfo);	
			}
		
			/* forward the response (possibly modified) to client */
			sendResponse();
		}
	}

Suggestion 2:
*************

Since string is a primitive type, can we add a binary operator , '+' or 'append' for string, such that operations such as :
"sampl" + "e" would equal "sample" ? Or is this already covered ?

Thanks,
Anwar

-----Original Message-----
From: Alex Rousskov [mailto:[email-masked]]
Sent: Sunday, September 21, 2003 4:52 PM
To: Anwar M. Haneef
Cc: [email-masked]
Subject: Re: Decision on Rules Language

Thanks,

Alex.

---

From: Alex Rousskov <[email-masked]>
Date: Mon, 22 Sep 2003 07:43:57 -0600 (MDT)

On Mon, 22 Sep 2003, Anwar M. Haneef wrote:

> Since string is a primitive type, can we add a binary operator , '+'
> or 'append' for string, such that operations such as : "sampl" + "e"
> would equal "sample" ? Or is this already covered ?

No, a concatenation operator for strings was not documented due to an
oversight. Now, it is.

Thank you,

Alex.