/*
* Copyright 2015 Netflix, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package io.reactivex.netty.protocol.http.server;
import io.reactivex.netty.protocol.http.TrailingHeaders;
import rx.Observable;
import rx.functions.Func0;
import rx.functions.Func1;
import rx.functions.Func2;
/**
* A facility to optionally write content to the response.
*
* <h2>Thread safety</h2>
*
* This object is not thread-safe and can not be accessed from multiple threads.
*/
public abstract class ResponseContentWriter<C> extends Observable<Void> {
ResponseContentWriter(OnSubscribe<Void> f) {
super(f);
}
/**
* On subscription of the returned {@link Observable}, writes the passed message stream on the underneath channel.
*
* <h2>Flush</h2>
*
* The writes are flushed when the passed stream completes.
*
* @param msgs Stream of messages to write.
*
* @return {@link Observable} representing the result of this write. Every subscription to this {@link Observable}
* will replay the write on the channel.
*/
public abstract ResponseContentWriter<C> write(Observable<C> msgs);
/**
* Uses the passed {@link Observable} as the source of content for this request. This method provides a way to
* write trailing headers.
*
* A new instance of {@link TrailingHeaders} will be created using the passed {@code trailerFactory} and the passed
* {@code trailerMutator} will be invoked for every item emitted from the content source, giving a chance to modify
* the trailing headers instance.
*
* <h2>Multiple invocations</h2>
*
* This method can <em>not</em> be invoked multiple times for the same response as on completion of the passed
* source, it writes the trailing headers and trailing headers can only be written once for an HTTP response.
* So, any subsequent invocation of this method will always emit an error when subscribed.
*
* <h2>Flush</h2>
*
* The writes are flushed when the passed stream completes.
*
* @param contentSource Content source for the response.
* @param trailerFactory A factory function to create a new {@link TrailingHeaders} per subscription of the content.
* @param trailerMutator A function to mutate the trailing header on each item emitted from the content source.
*
* @return An new instance of {@link Observable} which can be subscribed to execute the request.
*/
public abstract <T extends TrailingHeaders> Observable<Void> write(Observable<C> contentSource,
Func0<T> trailerFactory,
Func2<T, C, T> trailerMutator);
/**
* Uses the passed {@link Observable} as the source of content for this request. This method provides a way to
* write trailing headers.
*
* A new instance of {@link TrailingHeaders} will be created using the passed {@code trailerFactory} and the passed
* {@code trailerMutator} will be invoked for every item emitted from the content source, giving a chance to modify
* the trailing headers instance.
*
* <h2>Multiple invocations</h2>
*
* This method can <em>not</em> be invoked multiple times for the same response as on completion of the passed
* source, it writes the trailing headers and trailing headers can only be written once for an HTTP response.
* So, any subsequent invocation of this method will always emit an error when subscribed.
*
* @param contentSource Content source for the response.
* @param trailerFactory A factory function to create a new {@link TrailingHeaders} per subscription of the content.
* @param trailerMutator A function to mutate the trailing header on each item emitted from the content source.
* @param flushSelector A {@link Func1} which is invoked for every item emitted from {@code msgs}. Channel is
* flushed, iff this function returns, {@code true}.
*
* @return An new instance of {@link Observable} which can be subscribed to execute the request.
*/
public abstract <T extends TrailingHeaders> Observable<Void> write(Observable<C> contentSource,
Func0<T> trailerFactory,
Func2<T, C, T> trailerMutator,
Func1<C, Boolean> flushSelector);
/**
* On subscription of the returned {@link Observable}, writes the passed message stream on the underneath channel
* and flushes the channel, everytime, {@code flushSelector} returns {@code true} . Any writes issued before
* subscribing, will also be flushed. However, the returned {@link Observable} will not capture the result of those
* writes, i.e. if the other writes, fail and this write does not, the returned {@link Observable} will not fail.
*
* @param msgs Message stream to write.
* @param flushSelector A {@link Func1} which is invoked for every item emitted from {@code msgs}.
* Channel is flushed, iff this function returns, {@code true}.
*
* @return An {@link Observable} representing the result of this and all writes done prior to the flush. Every
* subscription to this {@link Observable} will write the passed messages and flush all pending writes, when the
* {@code flushSelector} returns {@code true}
*/
public abstract ResponseContentWriter<C> write(Observable<C> msgs, Func1<C, Boolean> flushSelector);
/**
* On subscription of the returned {@link Observable}, writes the passed message stream on the underneath channel
* and flushes the channel, on every write. Any writes issued before subscribing, will also be flushed. However, the
* returned {@link Observable} will not capture the result of those writes, i.e. if the other writes, fail and this
* write does not, the returned {@link Observable} will not fail.
*
* @param msgs Message stream to write.
*
* @return An {@link Observable} representing the result of this and all writes done prior to the flush. Every
* subscription to this {@link Observable} will write the passed messages and flush all pending writes, on every
* write.
*/
public abstract ResponseContentWriter<C> writeAndFlushOnEach(Observable<C> msgs);
/**
* On subscription of the returned {@link Observable}, writes the passed message stream on the underneath channel.
*
* <h2>Flush</h2>
*
* The writes are flushed when the passed stream completes.
*
* @param msgs Stream of messages to write.
*
* @return {@link Observable} representing the result of this write. Every subscription to this {@link Observable}
* will replay the write on the channel.
*/
public abstract ResponseContentWriter<C> writeString(Observable<String> msgs);
/**
* Uses the passed {@link Observable} as the source of content for this request. This method provides a way to
* write trailing headers.
*
* A new instance of {@link TrailingHeaders} will be created using the passed {@code trailerFactory} and the passed
* {@code trailerMutator} will be invoked for every item emitted from the content source, giving a chance to modify
* the trailing headers instance.
*
* <h2>Multiple invocations</h2>
*
* This method can <em>not</em> be invoked multiple times for the same response as on completion of the passed
* source, it writes the trailing headers and trailing headers can only be written once for an HTTP response.
* So, any subsequent invocation of this method will always emit an error when subscribed.
*
* <h2>Flush</h2>
*
* The writes are flushed when the passed stream completes.
*
* @param contentSource Content source for the response.
* @param trailerFactory A factory function to create a new {@link TrailingHeaders} per subscription of the content.
* @param trailerMutator A function to mutate the trailing header on each item emitted from the content source.
*
* @return An new instance of {@link Observable} which can be subscribed to execute the request.
*/
public abstract <T extends TrailingHeaders> Observable<Void> writeString(Observable<String> contentSource,
Func0<T> trailerFactory,
Func2<T, String, T> trailerMutator);
/**
* Uses the passed {@link Observable} as the source of content for this request. This method provides a way to
* write trailing headers.
*
* A new instance of {@link TrailingHeaders} will be created using the passed {@code trailerFactory} and the passed
* {@code trailerMutator} will be invoked for every item emitted from the content source, giving a chance to modify
* the trailing headers instance.
*
* <h2>Multiple invocations</h2>
*
* This method can <em>not</em> be invoked multiple times for the same response as on completion of the passed
* source, it writes the trailing headers and trailing headers can only be written once for an HTTP response.
* So, any subsequent invocation of this method will always emit an error when subscribed.
*
* @param contentSource Content source for the response.
* @param trailerFactory A factory function to create a new {@link TrailingHeaders} per subscription of the content.
* @param trailerMutator A function to mutate the trailing header on each item emitted from the content source.
* @param flushSelector A {@link Func1} which is invoked for every item emitted from {@code msgs}. Channel is
* flushed, iff this function returns, {@code true}.
*
* @return An new instance of {@link Observable} which can be subscribed to execute the request.
*/
public abstract <T extends TrailingHeaders> Observable<Void> writeString(Observable<String> contentSource,
Func0<T> trailerFactory,
Func2<T, String, T> trailerMutator,
Func1<String, Boolean> flushSelector);
/**
* On subscription of the returned {@link Observable}, writes the passed message stream on the underneath channel
* and flushes the channel, everytime, {@code flushSelector} returns {@code true} . Any writes issued before
* subscribing, will also be flushed. However, the returned {@link Observable} will not capture the result of those
* writes, i.e. if the other writes, fail and this write does not, the returned {@link Observable} will not fail.
*
* @param msgs Message stream to write.
* @param flushSelector A {@link Func1} which is invoked for every item emitted from {@code msgs}.
* Channel is flushed, iff this function returns, {@code true}.
*
* @return An {@link Observable} representing the result of this and all writes done prior to the flush. Every
* subscription to this {@link Observable} will write the passed messages and flush all pending writes, when the
* {@code flushSelector} returns {@code true}
*/
public abstract ResponseContentWriter<C> writeString(Observable<String> msgs, Func1<String, Boolean> flushSelector);
/**
* On subscription of the returned {@link Observable}, writes the passed message stream on the underneath channel
* and flushes the channel, on every write. Any writes issued before subscribing, will also be flushed. However, the
* returned {@link Observable} will not capture the result of those writes, i.e. if the other writes, fail and this
* write does not, the returned {@link Observable} will not fail.
*
* @param msgs Message stream to write.
*
* @return An {@link Observable} representing the result of this and all writes done prior to the flush. Every
* subscription to this {@link Observable} will write the passed messages and flush all pending writes, on every
* write.
*/
public abstract ResponseContentWriter<C> writeStringAndFlushOnEach(Observable<String> msgs);
/**
* On subscription of the returned {@link Observable}, writes the passed message stream on the underneath channel.
*
* <h2>Flush</h2>
*
* The writes are flushed when the passed stream completes.
*
* @param msgs Stream of messages to write.
*
* @return {@link Observable} representing the result of this write. Every subscription to this {@link Observable}
* will replay the write on the channel.
*/
public abstract ResponseContentWriter<C> writeBytes(Observable<byte[]> msgs);
/**
* Uses the passed {@link Observable} as the source of content for this request. This method provides a way to
* write trailing headers.
*
* A new instance of {@link TrailingHeaders} will be created using the passed {@code trailerFactory} and the passed
* {@code trailerMutator} will be invoked for every item emitted from the content source, giving a chance to modify
* the trailing headers instance.
*
* <h2>Multiple invocations</h2>
*
* This method can <em>not</em> be invoked multiple times for the same response as on completion of the passed
* source, it writes the trailing headers and trailing headers can only be written once for an HTTP response.
* So, any subsequent invocation of this method will always emit an error when subscribed.
*
* <h2>Flush</h2>
*
* The writes are flushed when the passed stream completes.
*
* @param contentSource Content source for the response.
* @param trailerFactory A factory function to create a new {@link TrailingHeaders} per subscription of the content.
* @param trailerMutator A function to mutate the trailing header on each item emitted from the content source.
*
* @return An new instance of {@link Observable} which can be subscribed to execute the request.
*/
public abstract <T extends TrailingHeaders> Observable<Void> writeBytes(Observable<byte[]> contentSource,
Func0<T> trailerFactory,
Func2<T, byte[], T> trailerMutator);
/**
* Uses the passed {@link Observable} as the source of content for this request. This method provides a way to
* write trailing headers.
*
* A new instance of {@link TrailingHeaders} will be created using the passed {@code trailerFactory} and the passed
* {@code trailerMutator} will be invoked for every item emitted from the content source, giving a chance to modify
* the trailing headers instance.
*
* <h2>Multiple invocations</h2>
*
* This method can <em>not</em> be invoked multiple times for the same response as on completion of the passed
* source, it writes the trailing headers and trailing headers can only be written once for an HTTP response.
* So, any subsequent invocation of this method will always emit an error when subscribed.
*
* @param contentSource Content source for the response.
* @param trailerFactory A factory function to create a new {@link TrailingHeaders} per subscription of the content.
* @param trailerMutator A function to mutate the trailing header on each item emitted from the content source.
* @param flushSelector A {@link Func1} which is invoked for every item emitted from {@code msgs}. Channel is
* flushed, iff this function returns, {@code true}.
*
* @return An new instance of {@link Observable} which can be subscribed to execute the request.
*/
public abstract <T extends TrailingHeaders> Observable<Void> writeBytes(Observable<byte[]> contentSource,
Func0<T> trailerFactory,
Func2<T, byte[], T> trailerMutator,
Func1<byte[], Boolean> flushSelector);
/**
* On subscription of the returned {@link Observable}, writes the passed message stream on the underneath channel
* and flushes the channel, everytime, {@code flushSelector} returns {@code true} . Any writes issued before
* subscribing, will also be flushed. However, the returned {@link Observable} will not capture the result of those
* writes, i.e. if the other writes, fail and this write does not, the returned {@link Observable} will not fail.
*
* @param msgs Message stream to write.
* @param flushSelector A {@link Func1} which is invoked for every item emitted from {@code msgs}.
* Channel is flushed, iff this function returns, {@code true}.
*
* @return An {@link Observable} representing the result of this and all writes done prior to the flush. Every
* subscription to this {@link Observable} will write the passed messages and flush all pending writes, when the
* {@code flushSelector} returns {@code true}
*/
public abstract ResponseContentWriter<C> writeBytes(Observable<byte[]> msgs, Func1<byte[], Boolean> flushSelector);
/**
* On subscription of the returned {@link Observable}, writes the passed message stream on the underneath channel
* and flushes the channel, on every write. Any writes issued before subscribing, will also be flushed. However, the
* returned {@link Observable} will not capture the result of those writes, i.e. if the other writes, fail and this
* write does not, the returned {@link Observable} will not fail.
*
* @param msgs Message stream to write.
*
* @return An {@link Observable} representing the result of this and all writes done prior to the flush. Every
* subscription to this {@link Observable} will write the passed messages and flush all pending writes, on every
* write.
*/
public abstract ResponseContentWriter<C> writeBytesAndFlushOnEach(Observable<byte[]> msgs);
}