Skip to content

Commit cb2bce5

Browse files
committed
WIP
1 parent d041adc commit cb2bce5

File tree

4 files changed

+41
-20
lines changed

4 files changed

+41
-20
lines changed

invoker/core/src/main/java/com/google/cloud/functions/invoker/HttpFunctionExecutor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,13 @@ public boolean handle(Request request, Response response, Callback callback) thr
6868
try {
6969
Thread.currentThread().setContextClassLoader(function.getClass().getClassLoader());
7070
function.service(reqImpl, respImpl);
71+
respImpl.close();
7172
callback.succeeded();
7273
} catch (Throwable t) {
7374
logger.log(Level.SEVERE, "Failed to execute " + function.getClass().getName(), t);
7475
Response.writeError(request, response, callback, t);
7576
} finally {
7677
Thread.currentThread().setContextClassLoader(oldContextLoader);
77-
respImpl.flush();
7878
}
7979
return true;
8080
}

invoker/core/src/main/java/com/google/cloud/functions/invoker/TypedFunctionExecutor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ public boolean handle(Request req, Response res, Callback callback) throws Excep
105105
try {
106106
Thread.currentThread().setContextClassLoader(function.getClass().getClassLoader());
107107
handleRequest(reqImpl, resImpl);
108-
resImpl.flush();
108+
resImpl.close();
109109
callback.succeeded();
110110
} catch (Throwable t) {
111111
Response.writeError(req, res, callback, t);

invoker/core/src/main/java/com/google/cloud/functions/invoker/http/HttpRequestImpl.java

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,6 @@ public Map<String, List<String>> getQueryParameters() {
8181

8282
@Override
8383
public Map<String, HttpPart> getParts() {
84-
8584
// TODO initiate reading the parts asynchronously before invocation
8685
String contentType = request.getHeaders().get(HttpHeader.CONTENT_TYPE);
8786
if (Type.MULTIPART_FORM_DATA.is(MimeTypes.getContentTypeWithoutCharset(contentType))) {
@@ -115,15 +114,31 @@ public Optional<String> getCharacterEncoding() {
115114
return Optional.ofNullable(charset == null ? null : charset.name());
116115
}
117116

117+
private InputStream inputStream;
118+
private BufferedReader reader;
119+
118120
@Override
119121
public InputStream getInputStream() throws IOException {
120-
return Content.Source.asInputStream(request);
122+
if (reader != null) {
123+
throw new IllegalStateException("getReader() already called");
124+
}
125+
if (inputStream == null) {
126+
inputStream = Content.Source.asInputStream(request);
127+
}
128+
return inputStream;
121129
}
122130

123131
@Override
124132
public BufferedReader getReader() throws IOException {
125-
return new BufferedReader(new InputStreamReader(getInputStream(),
126-
getCharacterEncoding().orElse(StandardCharsets.UTF_8.name())));
133+
if (reader == null) {
134+
if (inputStream != null) {
135+
throw new IllegalStateException("getInputStream already called");
136+
}
137+
inputStream = Content.Source.asInputStream(request);
138+
reader = new BufferedReader(new InputStreamReader(getInputStream(),
139+
getCharacterEncoding().orElse(StandardCharsets.UTF_8.name())));
140+
}
141+
return reader;
127142
}
128143

129144
@Override

invoker/core/src/main/java/com/google/cloud/functions/invoker/http/HttpResponseImpl.java

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import static java.util.stream.Collectors.toMap;
1818

1919
import com.google.cloud.functions.HttpResponse;
20+
import java.io.BufferedOutputStream;
2021
import java.io.BufferedWriter;
2122
import java.io.IOException;
2223
import java.io.OutputStream;
@@ -32,7 +33,7 @@
3233
import org.eclipse.jetty.http.HttpField;
3334
import org.eclipse.jetty.http.HttpHeader;
3435
import org.eclipse.jetty.io.Content;
35-
import org.eclipse.jetty.io.AbstractOutputStreamWriter;
36+
import org.eclipse.jetty.io.WriteThroughWriter;
3637
import org.eclipse.jetty.server.Response;
3738

3839
public class HttpResponseImpl implements HttpResponse {
@@ -83,41 +84,46 @@ private static <T> List<T> list(Collection<T> collection) {
8384
return (collection instanceof List<?>) ? (List<T>) collection : new ArrayList<>(collection);
8485
}
8586

87+
private OutputStream outputStream;
8688
private BufferedWriter writer;
8789

8890
@Override
89-
public OutputStream getOutputStream() throws IOException {
91+
public OutputStream getOutputStream() {
9092
if (writer != null) {
9193
throw new IllegalStateException("getWriter called");
94+
} else if (outputStream == null) {
95+
// TODO use BufferedSink when it is available
96+
outputStream = new BufferedOutputStream(Content.Sink.asOutputStream(response));
9297
}
93-
return Content.Sink.asOutputStream(response);
98+
return outputStream;
9499
}
95100

96101
@Override
97102
public synchronized BufferedWriter getWriter() throws IOException {
98103
if (writer == null) {
104+
if (outputStream != null) {
105+
throw new IllegalStateException("getOutputStream called");
106+
}
99107
String contentType = getContentType().orElse(null);
100108
Charset charset = Objects.requireNonNullElse(
101109
response.getRequest().getContext().getMimeTypes().getCharset(contentType),
102110
StandardCharsets.UTF_8);
103-
writer = new BufferedWriter(AbstractOutputStreamWriter.newWriter(getOutputStream(), charset));
111+
// TODO should we buffer in the input stream rather than as characters
112+
outputStream = Content.Sink.asOutputStream(response);
113+
writer = new BufferedWriter(WriteThroughWriter.newWriter(getOutputStream(), charset));
104114
}
105115
return writer;
106116
}
107117

108-
public void flush() {
118+
public void close() {
109119
try {
110-
// We can't use HttpServletResponse.flushBuffer() because we wrap the
111-
// PrintWriter returned by HttpServletResponse in our own BufferedWriter
112-
// to match our API. So we have to flush whichever of getWriter() or
113-
// getOutputStream() works.
114-
try {
115-
getOutputStream().flush();
116-
} catch (IllegalStateException e) {
117-
getWriter().flush();
120+
if (writer != null) {
121+
writer.close();
122+
} else if (outputStream != null) {
123+
outputStream.close();
118124
}
119125
} catch (IOException e) {
120-
// Too bad, can't flush.
126+
// Too bad, can't close.
121127
}
122128
}
123129
}

0 commit comments

Comments
 (0)