Rest assured prematurely access response stream - asynchronous

I need to verify a text/event-stream response for its content up to a certain point in time after the request was sent. The response stream is kept alive indefinitely for new events.
The following code does not work:
given()
.contentType(JSON)
.when()
.get("/mypath/") // This method blocks indefinitely, never reaching the "then" block
.then()
.response()
.extract()
.asString()
How can we close the response stream at a certain point to access what it has so far? Or perhaps intercept the underlying InputStream of the response asynchronously somehow?

Related

HTTP Response Objects

Does every HTTP request need to be paired with a response? When you do some POST or DELETE actions, my understanding is that sometimes you don't need to send back data. I've always been told to send back an empty object, but is that necessary? Also, is sending a status code considered a response?
Q1: Does every HTTP request need to be paired with a response?
Yes, unless client cancel the request. Actually, one HTTP request needs to be paired with one or more HTTP responses. According to RFC7231:
A server listens on a connection for a request, parses each message received, interprets the message semantics in relation to the identified request target, and responds to that request with one or more response messages.
Q2: When you do some POST or DELETE actions, my understanding is that sometimes you don't need to send back data. I've always been told to send back an empty object, but is that necessary?
It's NOT necessary to send back an empty object (payload). According to RFC7230, the response payload is not required:
A server responds to a client's request by sending one or more HTTP response messages, each beginning with... and finally a message body containing the payload body (if any).
However, although you don't have to "send back data", you still need to send back message, such as HTTP response statuc code and some necessary response headers.
Q3: is sending a status code considered a response?
Yes. Theoretically, a minimal HTTP response can only include HTTP protocol version, status code and status code textual phrase.

HTTP request and response flow for get

I am having difficulties understanding the HTTP request and response flow. I am working with a system where I can "hijack" incoming HTTP request and give my own response. The problem I am having is that some type of GET request seem to assume that all data is sent back in first request.
For instance, JPEG image requests, no matter the size (my tests include 0-20 MB JPEG files) seems to assume that the entire data is sent in the first response. Even if I don't send any data and explicitly set range header to 0 I never get a response back from the client asking for the data.
Other data request types, such as mp4 video, the client seems perfectly fine with getting a response with only header information with no data and then sends a new request explicitly asking for byte range 0-.
Is there some kind of agreement between the the client and server that some types should be sent back in one request while others can be split up in a number of requests?

Does 200 mean the request successfully started or successfully finished?

I realize this might sound like an odd question, but I'm seeing some odd results in my network calls so I'm trying to figure out if perhaps I'm misunderstanding something.
I see situations where in isolated incidents, when I'm uploading data, even though the response is 200, the data doesn't appear on the server. My guess is that the 200 response arrives during the initial HTTP handshake and then something goes wrong after the fact. Is that a correct interpretation of the order of events? Or is the 200 delivered once the server has collected whatever data the sending Header tells it is in the request? (cause if so then I'm back to the drawing board as to how I'm seeing what I'm seeing).
It means it has been successfully finished. From the HTTP /1.1 Spec
10.2.1 200 OK
The request has succeeded. The information returned with the response is dependent on the method used in the request, for example:
GET an entity corresponding to the requested resource is sent in the response;
HEAD the entity-header fields corresponding to the requested resource are sent in the response without any message-body;
POST an entity describing or containing the result of the action;
TRACE an entity containing the request message as received by the end server.
Finished. It doesn't make sense otherwise. Something might go wrong and the code could throw an error. How could the server send that error code when it already sent 200 OK.
What you experience might be lag, caching, detached thread running after the server sent the 200 etc.
A success reply, like 200, is not sent until after server has received and processed the full request. Error replies, on the other hand, may be sent before the request is fully received. If that happens, stop sending your request.

What to do with errors when streaming the body of an Http request

How do I handle a server error in the middle of an Http message?
Assuming I already sent the header of the message and I am streaming the
the body of the message, what do I do when I encounter an unexpected error.
I am also assuming this error was caused while generating the content and not a connection error.
(Greatly) Simplified Code:
// I can define any transfer encoding or header fields i need to.
send(header); // Sends the header to the Http client.
// Using an iterable instead of stream for code simplicity's sake.
Iterable<String> stream = getBodyStream();
Iterator<String> iterator = stream.iterator();
while (iterator.hasNext()) {
String string;
try {
string = iterator.next();
catch (Throwable error) { // Oops! an error generating the content.
// What do i do here? (In regards to the Http protocol)
}
send(string);
}
Is there a way to tell the client the server failed and should either retry or abandon the connection or am I sool?
The code is greatly simplified but I am only asking in regards to the protocol and not the exact code.
Thank You
One of the following should do it:
Close the connection (reset or normal close)
Write a malformed chunk (and close the connection) which will trigger client error
Add a http trailer telling your client that something went wrong.
Change your higher level protocol. Last piece of data you send is a hash or a length and the client knows to deal with it.
If you can generate a hash or a length (in a custom header if using http chunks) of your content before you start sending you can send it in a header so your client knows what to expect.
It depends on what you want your client to do with the data (keep it or throw it away). You may not be able to make changes on the client side so the last option will not work for example.
Here is some explanation about the different ways to close. TCP option SO_LINGER (zero) - when it's required.
I think the server should return a response code start with 5xx as per RFC 2616.
Server Error 5xx
Response status codes beginning with the digit "5" indicate cases in which the server is aware that it has erred or is incapable of performing the request. Except when responding to a HEAD request, the server SHOULD include an entity containing an explanation of the error situation, and whether it is a temporary or permanent condition. User agents SHOULD display any included entity to the user. These response codes are applicable to any request method.

Why does Comet need chunked-encoding response?

I read some articles about Comet tech. All of them mentioned that the long-life HTTP response should be Transfer-Encoding: chunked . I'm wondering why it should be chunked-encoded. If the response is not chunked-encoded, the client javascript can still read and parse the responded text, right?
Is there any special reason that Comet response should be chunked-encoded?
Chunked-encoded response is used when the length of the response is not known until the response is completed. An empty chunk indicates the end of the response. This is the only way the client can be notified for the end of response.
All this fit nicely with Comet. You send the first chunk when the request is received. You may also send additional "heartbeat" chunks while waiting for an action to complete. An empty chunk will notify the client that the response is completed.

Resources