Lifecycle of servlet filter doFilter method - servlets

I'm trying to set a header in the response object after I call
chain.doFilter()
However, the header does not get set. Does control ever come back to the doFilter() method after a call to chain.doFilter()?

However, the header does not get set.
That can happen if the response is already committed (read: when the first part of the response, including all headers, are already been sent to the client; this is a point of no return). A bit sane servletcontainer would throw an IllegalStateException on any attempt to set a header on an already committed response. This should be visible in the server logs. Have you read them?
Does control ever come back to the doFilter() method after a call to chain.doFilter()?
You could easily check it yourself by placing a breakpoint or a sysout/logger line. But yes, surely the control comes back the usual Java way and the remaining lines will be executed, provided that there's no uncaught exception coming from the doFilter() call.
Coming back to your concrete functional requirement, you'd need to rewrite your code in such way that the header is been set before the response is ever committed. As the concrete functional requirement is not elaborated in any way, it's not possible to give some hints or kickoff examples in this answer. The most straightforward way would be to just set the header before calling doFilter().

Request filters can:
perform security checks
reformat request headers or bodies
audit or log requests
Response filters can:
compress the response stream
append or alter the response stream
create a different response altogether

Related

Obtain error cause inside Fastly vcl_error subroutine

Fastly allows to customise vcl_error subroutine. However, If I override it (e.g.
sub vcl_error {
#FASTLY error
set obj.http.Custom-Header = "foo-bar";
return(deliver);
}
), original response body with error cause (e.g. "first byte timout") is lost.
Is it possible to obtain a cause, so I can add it to additional some header or syntetic body
The vcl_error subroutine is triggered either implicitly by Fastly (see the documentation for examples of when it does this) or explicitly using the error statement.
Within vcl_error the obj.status and obj.response variables provide information about the nature of the error.
If you're explicitly triggering vcl_error, then from within the subroutine you're invoking the error statement you should set a custom HTTP header on an object that you can read back from within vcl_error.
For example, the req object is available to all subroutines so you could use req.http.{NAME}) to store off any contextual error information you want to use as part of your synthetic error response.
One caveat with persisting data in this fashion is that you can't persist data across certain boundaries, such as the move from a subroutine on a 'fetching node' to a 'delivery node' (see clustering for details of what the difference between fetching/delivery nodes).
Off the top of my head (see also: https://www.integralist.co.uk/posts/fastly-varnish/#breadcrumb-trail) I believe if you're invoking error from vcl_fetch you'll need to persist the data to the beresp object and not req. Varnish will copy beresp to the obj object that is exposed to the vcl_error subroutine.
If you have any other questions or concerns, then please reach out to support#fastly.com who will be happy to help.
Please also refer to the Fastly 'Developer Hub' which has a bunch of resources on Varnish and VCL that might be useful to you.

Is there an operator which is the opposite of mergeMap()?

We have a case where we only want one HTTP request to go out at a time and only want to allow retry or call again if the pending call either succeeds or fails. We've been doing the classic wrap it in a boolean but were wondering if there was an operator for it. My hunch is no.
I think you would need switchMap. It will only subscribe to the last value of the external observable and it will map it to an internal observable. With switchMap, its possible to cancel previous http requests on the fly.
For more info take a look in the following link

Response Filters using ResposeWrapper

I came across a portion of code that zips the servlet output before returning it to the user, it uses a custom ServletResponseWrapper -it's so famous if u know what I am talking about-, my questions are :
1 - now the function of intercepting the response is totally the responsibility of the response wrapper -through overriding the output stream it returns- and the filter has no effect in such behaviour ? Am I correct ?
2- what happens if any of the servlets that the filters intercept its requests closed the output stream, will the code after chain.doFilter() be able to use this stream again ? and will the filter work ?
3 why does the wrapped response solve the problem of the "output returns directly to the container before being intercepted by the filter" ... I mean why the control over the response is then returned to the filter ?
I've recently used the example code from this book for my project:
Professional Java for Web Applications. There is a good example for a compression filter in chapter 9.
I'm not involved with the company behind the book.
These are the answers to your question:
Yes, you're correct. The filter wraps the original HttpServletResponse with a wrapper, and from this moment on the wrapper is responsible for managing the output stream (but not for closing the stream).
It's not a good idea at all to close the output stream in your own code, whether you use a wrapped HttpServletResponse or not.
The control over the output stream isn't returned to the filter. The execution of your web app is continued in the line after chain.doFilter(), and you can write some data to the wrapped response, if it's necessary. But don't close the stream, neither in your filter, nor in your servlet(s).

http service not working for parallel requests

I am using an http service object to make servlet requests inside a method in flex. The method is being invoked simultaneously in parallel by two events. I could see that both requests have reached the servlet, but only one returns to the result event. Also this behaviours is not consistent . is it possible that parallel invocation of the httpservice result in loss of some requests? I am sure that both requests have reached the servlet and data is returned from it. Its just that the result event is not triggered in certain cases.
Thanks in advance.
Including code to describe the issue better.
Please find the method below. The below method "callServlet" is being invoked by two separate events
private var httpObj:HTTPService=new HTTPService();
private function callServlet(text:String):void{
Alert.show(text);
httpObj = new HTTPService();
httpObj.url=<servlet URL>;
httpObj.method="POST";
httpObj.resultFormat="xml";
httpObj.contentType="application/xml";
var requestString:String=text;
httpObj.request=requestString;
httpObj.addEventListener(ResultEvent.RESULT,onResultMethods);
httpObj.addEventListener(FaultEvent.FAULT,onFaultMethod);
httpObj.send();
}
Each time i call the method, i pass a different "text" variable. I can see that the alert displays the two different texts send to it. And as explained earlier, both requests does reach the servlet and a response is sent from servlet.
But the result event "onResultMethod" is invoked just once.It doesnt invoke the "faultonFaultMethod" either.
Yes, I have seen this problem before, if you are making multiple requests from flex, some of them will be lost, that was back in 3.0 times. Browsers has a way of stopping the number of http calls, they can allow maximum of 2 calls at a time(depends on the browser), may be chain your requests one after the other or use a singleton which manages your calls.
Thanks all for help. I think i ve got the issue though i cannot guarantee the answer to be right.
The above method is called twice by two events. The httpOject variable is a private var global to the method callServlet. The listeners created in this method are being removed in the result and fault handler methods(this is not shown in the code above).
So i believe when multiple events call the method simultaneously there is a chance that the global variable httpObj is modified by both the events and hence both events result in servlet call using the same httpservice object. When the first call returns to the resulthandler i am removing the listener for resulthandler due to which the second result does not reach the resulthandler method.
This is my assumption and as of now i dont have any better solution. Do let me know if anyone comes up with a better explanation.

custom validator against remote object

I have a need to validate a field against our database to verify unique-ness. The problem I seem to be having is that the validators doValidation() exits before we've heard back from database.
How can I have the validator wait to return its payload until after we've heard from the DB?
Or perhaps a better question might be (since I think the first question is impossible), how can I set this up differently, so that I don't need to wait, or so that the wait doesn't cause the validation to automaticallly return valid?
If you're using a remote object, you can specify the method call inside your remote declaration and assign a function to the result call. The result call only runs once the remote server returns something, so it won't be run before your validation.
Do your validation call in said result function call (which you will have to create) and you should be good. Your code should go something like this:
<s:RemoteObject id="employeeService"
destination="ColdFusion"
source="f4iaw100.remoteData.employeeData"
endpoint="http://adobetes.com/flex2gateway/"
result="employeeService_resultHandler(event)"/>
**<s:method name="dataCheckCall" result="dataCheckResult(event)"/>**
<s:RemoteObject />
And in your script:
function protected dataCheckResult(event:ResultEvent):void {
**doValidate();**
}
Edit: As soon as you call "dataCheckCall" the method will start running. If, for whatever reason, you want to call this WITHIN your validator, you can do so, and then dataCheckResult will run whenever it returns with it's payload (pretend doValidate is called elsewhere). I've left a message below as well.
You are trying to fit an asynchronous process (fetching data from a DB) into a synchronous process (checking all the validators in turn).
This won't work...
You'll need to either roll your own validator framework, or use a different method of determining the legality of your controls.
P.S. The MX validators are rubbish anyway!
What I've managed to do, seems to work, mostly. I don't like it, but it at least performs the validation against the remote source.
What I've done, then, is to use an 'keyUp' event handler to spin off the database lookup portion. In the meanwhile, I set up a string variable to act as some kind of a Flag, which'll be marked as 'processing'. When the response event fires, I'll examine its contents, and either clear the flag, or set it to some kind of other error.
Then, I have created a new 'EmptyStringValidator' will check the contents of this flag, and do its job accordingly.
Its indirect, but, so far, seems to work.

Resources