Issue #6728 - QUIC and HTTP/3
- Made HttpChannelOverHTTP3.needContent() to look for content if none is immediately available. - Improved javadocs. Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
This commit is contained in:
parent
23111b744f
commit
dc5ffe1a8e
|
@ -174,6 +174,14 @@ public class HttpChannelOverHTTP3 extends HttpChannel
|
|||
|
||||
public boolean onIdleTimeout(Throwable failure, Consumer<Runnable> consumer)
|
||||
{
|
||||
try (AutoLock l = lock.lock())
|
||||
{
|
||||
if (content == null)
|
||||
content = new HttpInput.ErrorContent(failure);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean delayed = delayedUntilContent;
|
||||
delayedUntilContent = false;
|
||||
|
||||
|
@ -185,12 +193,6 @@ public class HttpChannelOverHTTP3 extends HttpChannel
|
|||
|
||||
failure.addSuppressed(new Throwable("idle timeout"));
|
||||
|
||||
try (AutoLock l = lock.lock())
|
||||
{
|
||||
if (content == null)
|
||||
content = new HttpInput.ErrorContent(failure);
|
||||
}
|
||||
|
||||
boolean needed = getRequest().getHttpInput().onContentProducible();
|
||||
if (needed || delayed)
|
||||
{
|
||||
|
@ -225,8 +227,28 @@ public class HttpChannelOverHTTP3 extends HttpChannel
|
|||
try (AutoLock l = lock.lock())
|
||||
{
|
||||
if (content != null)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("need content has immediate content {} on {}", content, this);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Stream.Data data = stream.readData();
|
||||
if (data != null)
|
||||
{
|
||||
HttpInput.Content result = newContent(data);
|
||||
try (AutoLock l = lock.lock())
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("need content read content {} on {}", result, this);
|
||||
content = result;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("need content demanding content on {}", this);
|
||||
stream.demand();
|
||||
return false;
|
||||
}
|
||||
|
@ -254,26 +276,7 @@ public class HttpChannelOverHTTP3 extends HttpChannel
|
|||
if (data == null)
|
||||
return null;
|
||||
|
||||
result = new HttpInput.Content(data.getByteBuffer())
|
||||
{
|
||||
@Override
|
||||
public boolean isEof()
|
||||
{
|
||||
return data.isLast();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void succeeded()
|
||||
{
|
||||
data.complete();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void failed(Throwable x)
|
||||
{
|
||||
data.complete();
|
||||
}
|
||||
};
|
||||
result = newContent(data);
|
||||
try (AutoLock l = lock.lock())
|
||||
{
|
||||
content = result;
|
||||
|
@ -303,6 +306,30 @@ public class HttpChannelOverHTTP3 extends HttpChannel
|
|||
return result;
|
||||
}
|
||||
|
||||
private HttpInput.Content newContent(Stream.Data data)
|
||||
{
|
||||
return new HttpInput.Content(data.getByteBuffer())
|
||||
{
|
||||
@Override
|
||||
public boolean isEof()
|
||||
{
|
||||
return data.isLast();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void succeeded()
|
||||
{
|
||||
data.complete();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void failed(Throwable x)
|
||||
{
|
||||
data.complete();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean failAllContent(Throwable failure)
|
||||
{
|
||||
|
|
|
@ -171,6 +171,8 @@ class BlockingContentProducer implements ContentProducer
|
|||
boolean unready = _asyncContentProducer.isUnready();
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("onContentProducible releasing semaphore {} unready={}", _semaphore, unready);
|
||||
// Do not release the semaphore if we are not unready, as certain protocols may call this method
|
||||
// just after having received the request, not only when they have read all the available content.
|
||||
if (unready)
|
||||
_semaphore.release();
|
||||
return false;
|
||||
|
|
|
@ -140,10 +140,11 @@ public abstract class HttpChannel implements Runnable, HttpOutput.Interceptor
|
|||
/**
|
||||
* Notify the channel that content is needed. If some content is immediately available, true is returned and
|
||||
* {@link #produceContent()} has to be called and will return a non-null object.
|
||||
* If no content is immediately available, {@link HttpInput#onContentProducible()} is called once some content arrives
|
||||
* and {@link #produceContent()} can be called without returning null.
|
||||
* If a failure happens, then {@link HttpInput#onContentProducible()} will be called and an error content will return the
|
||||
* error on the next call to {@link #produceContent()}.
|
||||
* If no content is immediately available, an attempt to produce content must be made; if new content has been
|
||||
* produced, true is returned; otherwise {@link HttpInput#onContentProducible()} is called once some content
|
||||
* arrives and {@link #produceContent()} can be called without returning {@code null}.
|
||||
* If a failure happens, then {@link HttpInput#onContentProducible()} will be called and an error content will
|
||||
* return the error on the next call to {@link #produceContent()}.
|
||||
* @return true if content is immediately available.
|
||||
*/
|
||||
public abstract boolean needContent();
|
||||
|
|
Loading…
Reference in New Issue