How to prevent Alfresco webscript response caching - caching

I have a webscript in alfresco that does something simple: reads a property, and based on its value, creates a json response. Another webscript is in charge of updating this property. However, the response from the original script is sometimes cached, and not for all clients.
So, for one client, I get a current status, and for the other I get the previous state.
The webscript basically reads a property from a node (nodeRef was sent in webscript request):
var status = doc.properties["my:customProp"];
switch (status) {
case "something":
model.prop = "FirstResponse";
break;
case "somethingElse":
model.prop = "SecondResponse";
break;
default:
model.prop = "ThirdResponse";
}
The freemarker template then parses the prop and creates a json output for the response.
Now, this should be simple and straightforward. The use case is as follows:
1. When a user #1 first gets to the doc, the status was set to "something". He got a "FirstResponse", and with a webscript he changed it.
When he then get the document again, he gets the second response.
But if a second client accesses this same node and asks for the response, it still gets the first response, and even more, when I try to read that prop, I get the "old" prop.
So I'm refreshing the script from two clients and reading this property, one client gets one value, the other gets another value.
My only guess (so far) is that this is a caching issue. So, how do I prevent caching? And where did it happen? Hibernate? Some sort of repository cache? How to get rid of it?

check http://wiki.alfresco.com/wiki/Web_Scripts#cache

Well, found the problem here, the prop was defined as d:mltext. So it wasn't cached information, just multilanguage info. I had to extend the model and add a new prop that multilanguage, now all users have the same information.

Related

Laravel - retrieve data inside controller – POST x PATCH

First important information: I’m new to laravel, so your patience is appreciated.
I’m currently migrating a framework of mine to laravel, so I’m in the early stages.
Currently, I’m trying to set up an API endpoint to make small changes on some records. I’ve already managed to set up a API for inserting records and works perfectly. However, for setting up an API for small changes (patch), I’m having difficulties, probably because I’m not fully familiar with laravel’s Request class.
My successful insert set up looks like this:
\routes\api.php
Route::post('/categories/',[ApiCategoriesInsertController::class, 'insertCategories'], function($insertCategoriesResults) {
return response()->json($insertCategoriesResults);
})->name('api.categories.insert');
\app\Http\Controllers\ApiCategoriesInsertController.php
// some code
public function insertCategories(Request $req): array
{
$this->arrCategoriesInsertParameters['_tblCategoriesIdParent'] = $req->post('id_parent');
// some code
}
With this set up, I’m able to retrieve “id_parent” data set through POST.
So, I tried to do exactly the same architecture for patch, but doesn’t seem to work:
\routes\api.php
Route::patch('/records/',[ApiRecordsPatchController::class, 'patchRecords'], function($patchRecordsResults) {
return response()->json($patchRecordsResults);
})->name('api.records.patch');
\app\Http\Controllers\ApiRecordsPatchController.php
// some code
public function patchRecords(Request $req): array
{
$this->arrRecordsPatchParameters['_strTable'] = $req->post('strTable');
// some code
}
In this case, I´m using postman (PATCH request), testing the data in the "Body tab" with key "strTable" and value "123xxx" and I´m receiving “strTable” as null.
Any idea of why this is happening or if I should use another method in the Request class?
Thanks!
You can access parameters on the Request object using one of the following methods:
$req->strTable;
// or
$req->input('strTable');
The input method also accepts a second parameter which will be used as the default return value if the key is not present in the Request.
If you want to check whether or not the Request contains a value before you attempt to access it, you can use filled:
if ($req->filled('strTable')) {
// The request contains a value
}
Turns out that the way I had set up was in fact working and retrieving data:
$req->post('strTable');
The problem was in how I was testing it. In postman, there are several options to configure:
form-data
x-www-form-urlencoded
raw
binary
I had already switched to x-www-form-urlencoded to test it, but I forgot to fill the “key” and “value” information again. I didn’t realize that the fields blank as we switch between them.
Summing it up: It works when x-www-form-urlencoded selected but doesn’t work with form-data selected. Don’t know what the difference between them yet, but I’ll research it further.
By the way, it worked also with the suggestion from Rube Hart:

Unable to access POST parameter values - IIB Esql

So I'm quite new to IIB and Extended SQL but what I want to do should be straight forward. I have a REST application which has a resource that is attached to a subflow. What I want to do is to get the input value passed to the service and use it to call a remote web service using the HTTP request node as shown below
SET OutputLocalEnvironment.Destination.HTTP.RequestLine.Method = 'POST';
SET OutputLocalEnvironment.Destination.HTTP.RequestURL = 'http://localhost:8002/MyService';
SET OutputLocalEnvironment.Destination.HTTP.QueryString.RemoteParam= InputLocalEnvironment.REST.Input.Parameters.myValue;
What is happening is, when I call the REST method and pass the value as a GET, I'm able to access the value. However, when I pass the parameter value using POST, I'm unable to access the value. My current flow is as follows:
Input > Compute > HTTPRequest > Compute > Output
I have searched on Google and applied all recommendations (e.g. setting compute node to LocalEnvironment) but nothing seems to work.
Well, we need more information in order to solve your problem but I guess you have problem in your HTTP request node
Go to HTTP request then in properties go to HTTP setting and change HTTP method to the method that you are using ( get or post )
and if you want to see if you are fetching data from right property just lunch debugger and put breakepoint in before and after of your nodes, then you can see what data you are receiving in each level and you can call the proper property.
ps. don't forget to deploy your project again in order to see new
changes
I hope that works for you
After further research, I found that IIB does not automatically parse content submitted as application/x-www-form-urlencoded. I inserted a trace node and realised that the parameters are instead submitted as a BLOB. All I had to do was read the blob, cast it to a string then use a Split function or a message model to get the individual parameters. Thanks for the pointers

Hiding Query String Parameters

I have a GET action for creating records. Because the page is somewhat dynamic, I don't use a model to hold the data. I go off to do some OAuth, only to return to the create screen later on. In order to pass the data back, I am redirecting with a query string. I parse the query string in the GET action, and then show the view. The thing is, the query string is showing up in the browser. This displays pseudo-sensitive data.
Since I am only using the query string for transferring data, I am wondering if I can throw the query string away to prevent it from showing up on the browser.
Otherwise, is there a way to go to another action without redirecting? I've found, if I call the "other" action method directly, it tries to find the view of the original action. I can explicitly change the return View(viewModel) line to return View("create", viewModel) but that seems really dirty.
You should consider changing the action to accept POST requests. At least this will prevent the sensitive information from appearing in the browser. For extra security, your site should be served via SSL.
The other thing you can try is encrypting the sensitive values or the entire query string. The only problem is that this, too, will be preserved in the browser's history unless you require users to log in.
It looks like your action method is trying to do too much. Authentication/authorization is a separate concern which should not be part of the action method. It is better to move the authentication work in to an action filter.
Create an class that extends authorization attribute and override its OnAuthorization method to do your authorization work.
This frees your controller action method to accept POST requests.

GET vs POST in AJAX?

Why are there GET and POST requests in AJAX as it does not affect page URL anyway? What difference does it make by passing sensitive data over GET in AJAX as the data is not getting reflected to page URL?
You should use the proper HTTP verb according to what you require from your web service.
When dealing with a Collection URI like: http://example.com/resources/
GET: List the members of the collection, complete with their member URIs for further navigation. For example, list all the cars for sale.
PUT: Meaning defined as "replace the entire collection with another collection".
POST: Create a new entry in the collection where the ID is assigned automatically by the collection. The ID created is usually included as part of the data returned by this operation.
DELETE: Meaning defined as "delete the entire collection".
When dealing with a Member URI like: http://example.com/resources/7HOU57Y
GET: Retrieve a representation of the addressed member of the collection expressed in an appropriate MIME type.
PUT: Update the addressed member of the collection or create it with the specified ID.
POST: Treats the addressed member as a collection in its own right and creates a new subordinate of it.
DELETE: Delete the addressed member of the collection.
Source: Wikipedia
Well, as for GET, you still have the url length limitation. Other than that, it is quite conceivable that the server treats POST and GET requests differently; thus the need to be able to specify what request you're doing.
Another difference between GET and POST is the way caching is handled in browsers. POST response is never cached. GET may or may not be cached based on the caching rules specified in your response headers.
Two primary reasons for having them:
GET requests have some pretty restrictive limitations on size; POST are typically capable of containing much more information.
The backend may be expecting GET or POST, depending on how it's designed. We need the flexibility of doing a GET if the backend expects one, or a POST if that's what it's expecting.
It's simply down to respecting the rules of the http protocol.
Get - calls must be idempotent. This means that if you call it multiple times you will get the same result. It is not intended to change the underlying data. You might use this for a search box etc.
Post - calls are NOT idempotent. It is allowed to make a change to the underlying data, so might be used in a create method. If you call it multiple times you will create multiple entries.
You normally send parameters to the AJAX script, it returns data based on these parameters. It works just like a form that has method="get" or method="post". When using the GET method, the parameters are passed in the query string. When using POST method, the parameters are sent in the post body.
Generally, if your parameters have very few characters and do not contain sensitive information then you send them via GET method. Sensitive data (e.g. password) or long text (e.g. an 8000 character long bio of a person) are better sent via POST method.
Thanks..
I mainly use the GET method with Ajax and I haven't got any problems until now except the following:
Internet Explorer (unlike Firefox and Google Chrome) cache GET calling if using the same GET values.
So, using some interval with Ajax GET can show the same results unless you change URL with irrelevant random number usage for each Ajax GET.
Others have covered the main points (context/idempotency, and size), but i'll add another: encryption. If you are using SSL and want to encrypt your input args, you need to use POST.
When we use the GET method in Ajax, only the content of the value of the field is sent, not the format in which the content is. For example, content in the text area is just added in the URL in case of the GET method (without a new line character). That is not the case in the POST method.

How can I prevent IE Caching from causing duplicate Ajax requests?

We are using the Dynamic Script Tag with JsonP mechanism to achieve cross-domain Ajax calls. The front end widget is very simple. It just calls a search web service, passing search criteria supplied by the user and receiving and dynamically rendering the results.
Note - For those that aren’t familiar with the Dynamic Script Tag with JsonP method of performing Ajax-like requests to a service that return Json formatted data, I can explain how to utilise it if you think it could be relevant to the problem.
The service is WCF hosted on IIS. It is Restful so the first thing we do when the user clicks search is to generate a Url containing the criteria. It looks like this...
https://.../service.svc?criteria=john+smith
We then use a dynamically created Html Script Tag with the source attribute set to the above Url to make the request to our service. The result is returned and we process it to show the results.
This all works fine, but we noticed that when using IE the service receives the request from the client Twice. I used Fiddler to monitor the traffic leaving the browser and sure enough I see two requests with the following urls...
Request 1: https://.../service.svc?criteria=john+smith
Request 2: https://.../service.svc?criteria=john+smith&_=123456789
The second request has been appended with some kind of Id. This Id is different for every request.
My immediate thought is it was something to do with caching. Adding a random number to the end of the url is one of the classic approaches to disabling browser caching. To prove this I adjusted the cache settings in IE.
I set “Check for newer versions of stored pages” to “Never” – This resulted in only one request being made every time. The one with the random number on the end.
I set this setting value back to the default of “Automatic” and the requests immediately began to be sent twice again.
Interestingly I don’t receive both requests on the client. I found this reference where someone is suggesting this could be a bug with IE. The fact that this doesn’t happen for me on Firefox supports this theory.
Can anyone confirm if this is a bug with IE? It could be by design.
Does anyone know of a way I can stop it happening?
Some of the more vague searches that my users will run take up enough processing resource to make doubling up anything a very bad idea. I really want to avoid this if at all possible :-)
I just wrote an article on how to avoid caching of ajax requests :-)
It basically involves adding the no cache headers to any ajax request that comes in
public abstract class MyWebApplication : HttpApplication
{
protected MyWebApplication()
{
this.BeginRequest += new EventHandler(MyWebApplication_BeginRequest);
}
void MyWebApplication_BeginRequest(object sender, EventArgs e)
{
string requestedWith = this.Request.Headers["x-requested-with"];
if (!string.IsNullOrEmpty(requestedWith) && requestedWith.Equals(”XMLHttpRequest”, StringComparison.InvariantCultureIgnoreCase))
{
this.Response.Expires = 0;
this.Response.ExpiresAbsolute = DateTime.Now.AddDays(-1);
this.Response.AddHeader(”pragma”, “no-cache”);
this.Response.AddHeader(”cache-control”, “private”);
this.Response.CacheControl = “no-cache”;
}
}
}
I eventually established the reason for the duplicate requests. As I said, the mechanism I chose to use for making Ajax calls was with Dynamic Script Tags. I build the request Url, created a new Script element and assigned the Url to the src property...
var script = document.createElement(“script”);
script.src = https://....”;
Then to execute the script by appending it to the Document Head. Crucially, I was using the JQuery append function...
$(“head”).append(script);
Inside the append function JQuery was anticipating that I was trying to make an Ajax call. If the type of element being appended is a Script, then it executes a special routine that makes an Ajax request using the XmlHttpRequest object. But the script was still being appended to the document head, and being executed there by the browser too. Hence the double request.
The first came direct from the script – the one I intended to happen.
The second came from inside the JQuery append function. This was the request suffixed with the randomly generated query string argument in the form “&_=123456789”.
I simplified things by preventing the JQuery library side effect. I used the native append function...
document.getElementByTagName(“head”).appendChild(script);
One request now happens in the way I intended. I had no idea that the JQuery append function could have such a significant side effect built in.
See www.enhanceie.com/redir/?id=httpperf for further discussion.

Resources