public abstract class HttpSender extends java.lang.Object implements AsyncContentProvider.Listener
HttpSender
abstracts the algorithm to send HTTP requests, so that subclasses only implement
the transport-specific code to send requests over the wire, implementing
sendHeaders(HttpExchange, HttpContent, Callback)
and
sendContent(HttpExchange, HttpContent, Callback)
.
HttpSender
governs two state machines.
The request state machine is updated by HttpSender
as the various steps of sending a request
are executed, see RequestState
.
At any point in time, a user thread may abort the request, which may (if the request has not been
completely sent yet) move the request state machine to RequestState#FAILURE
.
The request state machine guarantees that the request steps are executed (by I/O threads) only if
the request has not been failed already.
The sender state machine is updated by HttpSender
from three sources: deferred content notifications
(via onContent()
), 100-continue notifications (via proceed(HttpExchange, Throwable)
)
and normal request send (via sendContent(HttpExchange, HttpContent, Callback)
).
This state machine must guarantee that the request sending is never executed concurrently: only one of
those sources may trigger the call to sendContent(HttpExchange, HttpContent, Callback)
.
HttpReceiver
Modifier and Type | Class and Description |
---|---|
private class |
HttpSender.CommitCallback |
private class |
HttpSender.ContentCallback |
private class |
HttpSender.LastCallback |
private static class |
HttpSender.RequestState
The request states
HttpSender goes through when sending a request. |
private static class |
HttpSender.SenderState
The sender states
HttpSender goes through when sending a request. |
private class |
HttpSender.TrailersCallback |
Modifier and Type | Field and Description |
---|---|
private HttpChannel |
channel |
private Callback |
commitCallback |
private HttpContent |
content |
private IteratingCallback |
contentCallback |
private java.lang.Throwable |
failure |
private Callback |
lastCallback |
protected static Logger |
LOG |
private java.util.concurrent.atomic.AtomicReference<HttpSender.RequestState> |
requestState |
private java.util.concurrent.atomic.AtomicReference<HttpSender.SenderState> |
senderState |
private Callback |
trailersCallback |
Modifier | Constructor and Description |
---|---|
protected |
HttpSender(HttpChannel channel) |
Modifier and Type | Method and Description |
---|---|
boolean |
abort(HttpExchange exchange,
java.lang.Throwable failure) |
protected boolean |
anyToFailure(java.lang.Throwable failure) |
protected boolean |
beginToHeaders(HttpExchange exchange) |
protected void |
dispose() |
protected boolean |
expects100Continue(Request request) |
protected HttpChannel |
getHttpChannel() |
protected HttpExchange |
getHttpExchange() |
protected boolean |
headersToCommit(HttpExchange exchange) |
private void |
illegalSenderState(HttpSender.SenderState current) |
boolean |
isFailed() |
void |
onContent()
Callback method invoked when content is available
|
void |
proceed(HttpExchange exchange,
java.lang.Throwable failure) |
protected boolean |
queuedToBegin(HttpExchange exchange) |
protected void |
reset() |
void |
send(HttpExchange exchange) |
protected abstract void |
sendContent(HttpExchange exchange,
HttpContent content,
Callback callback)
Implementations should send the content at the
HttpContent cursor position over the wire. |
protected abstract void |
sendHeaders(HttpExchange exchange,
HttpContent content,
Callback callback)
Implementations should send the HTTP headers over the wire, possibly with some content,
in a single write, and notify the given
callback of the result of this operation. |
protected abstract void |
sendTrailers(HttpExchange exchange,
Callback callback)
Implementations should send the HTTP trailers and notify the given
callback of the
result of this operation. |
protected boolean |
someToContent(HttpExchange exchange,
java.nio.ByteBuffer content) |
protected boolean |
someToSuccess(HttpExchange exchange) |
private void |
terminateRequest(HttpExchange exchange) |
private void |
terminateRequest(HttpExchange exchange,
java.lang.Throwable failure,
Result result) |
java.lang.String |
toString() |
private boolean |
updateRequestState(HttpSender.RequestState from,
HttpSender.RequestState to) |
private boolean |
updateSenderState(HttpSender.SenderState from,
HttpSender.SenderState to) |
protected static final Logger LOG
private final java.util.concurrent.atomic.AtomicReference<HttpSender.RequestState> requestState
private final java.util.concurrent.atomic.AtomicReference<HttpSender.SenderState> senderState
private final Callback commitCallback
private final IteratingCallback contentCallback
private final Callback trailersCallback
private final Callback lastCallback
private final HttpChannel channel
private HttpContent content
private java.lang.Throwable failure
protected HttpSender(HttpChannel channel)
protected HttpChannel getHttpChannel()
protected HttpExchange getHttpExchange()
public boolean isFailed()
public void onContent()
AsyncContentProvider.Listener
onContent
in interface AsyncContentProvider.Listener
public void send(HttpExchange exchange)
protected boolean expects100Continue(Request request)
protected boolean queuedToBegin(HttpExchange exchange)
protected boolean beginToHeaders(HttpExchange exchange)
protected boolean headersToCommit(HttpExchange exchange)
protected boolean someToContent(HttpExchange exchange, java.nio.ByteBuffer content)
protected boolean someToSuccess(HttpExchange exchange)
protected boolean anyToFailure(java.lang.Throwable failure)
private void terminateRequest(HttpExchange exchange)
private void terminateRequest(HttpExchange exchange, java.lang.Throwable failure, Result result)
protected abstract void sendHeaders(HttpExchange exchange, HttpContent content, Callback callback)
callback
of the result of this operation.
If there is more content to send, then sendContent(HttpExchange, HttpContent, Callback)
will be invoked.
exchange
- the exchange to sendcontent
- the content to sendcallback
- the callback to notifyprotected abstract void sendContent(HttpExchange exchange, HttpContent content, Callback callback)
HttpContent
cursor position over the wire.
The HttpContent
cursor is advanced by HttpSender at the right time, and if more
content needs to be sent, this method is invoked again; subclasses need only to send the content
at the HttpContent
cursor position.
This method is invoked one last time when HttpContent.isConsumed()
is true and therefore
there is no actual content to send.
This is done to allow subclasses to write "terminal" bytes (such as the terminal chunk when the
transfer encoding is chunked) if their protocol needs to.
exchange
- the exchange to sendcontent
- the content to sendcallback
- the callback to notifyprotected abstract void sendTrailers(HttpExchange exchange, Callback callback)
callback
of the
result of this operation.exchange
- the exchange to sendcallback
- the callback to notifyprotected void reset()
protected void dispose()
public void proceed(HttpExchange exchange, java.lang.Throwable failure)
public boolean abort(HttpExchange exchange, java.lang.Throwable failure)
private boolean updateRequestState(HttpSender.RequestState from, HttpSender.RequestState to)
private boolean updateSenderState(HttpSender.SenderState from, HttpSender.SenderState to)
private void illegalSenderState(HttpSender.SenderState current)
public java.lang.String toString()
toString
in class java.lang.Object