I think scrolling and showing the output as soon as possible is the most useful as this shows the user what is happening and it is the same behavior for all other terminals I have used. Often you can make out patterns in the output even though it is scrolling and this can be handy.

The other thing I noticed is that Ctrl+C does not appear to work, is it meant to?

The key bit of information here is the 'service unavailable' error being returned rather than say a 'not authorized' or 'not found' errors. By default when out of licenses we return the service unavailable error so if anyone else sees this they should check license usage as a first step. If you get not authorized errors it is probably a security issue so check the audit log as this often shows the exact problem.

It sounds like somewhere in your application you have a call that returns OID values to the client, then as a separate step you wish to return the stream associated with this OID. Is it possible instead of returning the OID to the client you just return the stream directly to the client? So what is the need for the client to store the OID when it is really the stream the client wants?

Assuming there is a good reason for returning the OID you can follow this pattern.

  • Server gets request where it would previously return the OID
  • Server generates a new random number using $system.Encryption.GenCryptRand to generate a random number
  • Server stores this random number in a table against the OID it wishes to associate it with and a timetstamp
  • Server sends the random number to the client
  • Client at some point wishes to get the stream so it sends the random number to the server
  • Server looks up the random number in the table and finds the OID and serves up this stream if the request is within some time period of the random number being generated. Then it deletes the random number from the table.

You also need to write some code to cleanup this table and remove expired random numbers from the table periodically or it could grow over time if you generate values and the client never uses them.

As you know these escape sequences are valid HTML escaping of unicode characters. The general principal is always that you store the text in the database  as characters i.e. not escaped at all and you apply any escaping needed when serving this content to a client. So it appears you need to convert these escaped characters into something you can store in your 8bit database.

Now in general I would suggest using unicode in which case you can just make sure the data being sent to you is correctly converted into unicode characters and then you just store the characters in the database. This would then work with any characters and not just the few you are having problems with. However it sounds like you do not want to move from 8bit to unicode. If that is the case anything you do will be something of a hack, but you can just use $replace on the data coming in to convert say "%u2019" to "'" before you store it in the database to 'normalize' the input. This solution will only cover a few characters where you can find a suitable replacement but it may be enough to get by for the short term while you investigate moving to unicode as a permanent solution.

Note that any time you build a query as a string if you allow users to insert parameter values or control the string you are building in any way into you need to be aware of SQL injection attacks. This is not a problem with '?' query argument substitution as it is designed to avoid injection attacks, but if you have say:

Set sql="select Name from MyTable where Age > "_userage

And the user supplies 'userage' then they could provide "100; drop table MyTable;" or worse.

In Cache 2017.1 we have light weight SQL profiling enabled by default which will keep track of the number of times each SQL query is called and how long these queries take.  So you can quickly answer the question as to which SQL queries matter to your application and then investigate these important queries in more detail.

This information will show up in the system management portal in the SQL explorer section under the sql queries in this namespace section.

Note that NIST has come up with new recommendations about password security, here is a good overview:


Specifically see this section:

No composition rules. What this means is, no more rules that force you to use particular characters or combinations, like those daunting conditions on some password reset pages that say, “Your password must contain one lowercase letter, one uppercase letter, one number, four symbols but not &%#@_, and the surname of at least one astronaut.”

So it recommends against complex patterns such as the one you are asking about. Also of interest is this one:

No more expiration without reason. This is my favourite piece of advice: If we want users to comply and choose long, hard-to-guess passwords, we shouldn’t make them change those passwords unnecessarily.

The only time passwords should be reset is when they are forgotten, if they have been phished, or if you think (or know) that your password database has been stolen and could therefore be subjected to an offline brute-force attack.

Some tools do not like the fact that the RSS feed is badly formatted as there are no title fields, this was reported a long time ago but is still not fixed for example the start of 'https://community.intersystems.com/group/8046/feed':

<?xml version="1.0" encoding="utf-8" ?><rss version="2.0" xml:base="https://community.intersystems.com/group/8046" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:foaf="http://xmlns.com/foaf/0.1/" xmlns:og="http://ogp.me/ns#" xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" xmlns:sioc="http://rdfs.org/sioc/ns#" xmlns:sioct="http://rdfs.org/sioc/types#" xmlns:skos="http://www.w3.org/2004/02/skos/core#" xmlns:xsd="http://www.w3.org/2001/XMLSchema#">

The 'Do While' is in fact identical to the 'For' block structure except it adds a redundant while condition at the end which is never false as it will have already exited this block from the 'Quit:Sub1=""' condition earlier, so you should probably remove this as it just takes the 'For' structure and adds this extra test which will slow the loop down.

A disadvantage of the 'While' structure is first you need to repeat the iteration construct, e.g. 'Set Sub1=$O(^Trans(Sub1))' before entering the loop and at the end. Also if you need to skip an item with say the 'For' structure you can just issue a 'Continue' but with the 'While' structure you have to advance the current subscript value manually before issuing a 'Continue'

In the 'Method Levels' the lines like 'Goto Level1' are not needed as the previous line says 'Set Sub2="" Goto Level2' so it will always be evaluating this 'Goto Level2' and so will never get to the next line. Rather than having this you can simplify to just 'Set Sub2=""' and remove both 'Goto' statements so it will just drop down into Level2 automatically.

Why do you want the connection id to change? In CSP we route multiple requests to a few server processes to be able to handle massive numbers of client efficiently. However the process that handles the request does not hold any information about the session at all, all this information such as the license we hold is in the %session object so as long as you have a new %session object this is a brand new connection.