You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2017/11/28 20:49:46 UTC
svn commit: r1816571 - in /tomcat/trunk/java/org/apache/coyote/http2:
Http2AsyncUpgradeHandler.java Http2UpgradeHandler.java SendfileData.java
StreamProcessor.java
Author: markt
Date: Tue Nov 28 20:49:45 2017
New Revision: 1816571
URL: http://svn.apache.org/viewvc?rev=1816571&view=rev
Log:
Refactor sendfile with compression support in mind. Use an approach similar to HTTP/1.1 so the StreamProcessor will have visibility of whether sendfile is in use when deciding whether or not to compress.
Added:
tomcat/trunk/java/org/apache/coyote/http2/SendfileData.java (with props)
Modified:
tomcat/trunk/java/org/apache/coyote/http2/Http2AsyncUpgradeHandler.java
tomcat/trunk/java/org/apache/coyote/http2/Http2UpgradeHandler.java
tomcat/trunk/java/org/apache/coyote/http2/StreamProcessor.java
Modified: tomcat/trunk/java/org/apache/coyote/http2/Http2AsyncUpgradeHandler.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http2/Http2AsyncUpgradeHandler.java?rev=1816571&r1=1816570&r2=1816571&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http2/Http2AsyncUpgradeHandler.java (original)
+++ tomcat/trunk/java/org/apache/coyote/http2/Http2AsyncUpgradeHandler.java Tue Nov 28 20:49:45 2017
@@ -16,10 +16,8 @@
*/
package org.apache.coyote.http2;
-import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
-import java.nio.MappedByteBuffer;
import java.nio.channels.CompletionHandler;
import java.nio.channels.FileChannel;
import java.nio.channels.FileChannel.MapMode;
@@ -264,47 +262,37 @@ public class Http2AsyncUpgradeHandler ex
}
@Override
- protected SendfileState processSendfile(Stream stream) {
- String fileName = (String) stream.getCoyoteRequest().getAttribute(
- org.apache.coyote.Constants.SENDFILE_FILENAME_ATTR);
- if (fileName != null) {
- java.nio.file.Path path = new File(fileName).toPath();
- SendfileData sendfile = new SendfileData();
- sendfile.pos = ((Long) stream.getCoyoteRequest().getAttribute(
- org.apache.coyote.Constants.SENDFILE_FILE_START_ATTR)).longValue();
- sendfile.end = ((Long) stream.getCoyoteRequest().getAttribute(
- org.apache.coyote.Constants.SENDFILE_FILE_END_ATTR)).longValue();
- sendfile.left = sendfile.end - sendfile.pos;
+ protected SendfileState processSendfile(SendfileData sendfile) {
+ if (sendfile != null) {
try {
- try (FileChannel channel = FileChannel.open(path, StandardOpenOption.READ)) {
+ try (FileChannel channel = FileChannel.open(sendfile.path, StandardOpenOption.READ)) {
sendfile.mappedBuffer = channel.map(MapMode.READ_ONLY, sendfile.pos, sendfile.end - sendfile.pos);
- sendfile.stream = stream;
}
// Reserve as much as possible right away
int reservation = (sendfile.end - sendfile.pos > Integer.MAX_VALUE) ? Integer.MAX_VALUE : (int) (sendfile.end - sendfile.pos);
- sendfile.streamReservation = stream.reserveWindowSize(reservation, true);
- sendfile.connectionReservation = reserveWindowSize(stream, sendfile.streamReservation);
+ sendfile.streamReservation = sendfile.stream.reserveWindowSize(reservation, true);
+ sendfile.connectionReservation = reserveWindowSize(sendfile.stream, sendfile.streamReservation);
} catch (IOException e) {
return SendfileState.ERROR;
}
// Actually perform the write
int frameSize = Integer.min(getMaxFrameSize(), sendfile.connectionReservation);
- boolean finished = (frameSize == sendfile.left) && stream.getCoyoteResponse().getTrailerFields() == null;
+ boolean finished = (frameSize == sendfile.left) && sendfile.stream.getCoyoteResponse().getTrailerFields() == null;
// Need to check this now since sending end of stream will change this.
- boolean writeable = stream.canWrite();
+ boolean writeable = sendfile.stream.canWrite();
byte[] header = new byte[9];
ByteUtil.setThreeBytes(header, 0, frameSize);
header[3] = FrameType.DATA.getIdByte();
if (finished) {
header[4] = FLAG_END_OF_STREAM;
- stream.sentEndOfStream();
- if (!stream.isActive()) {
+ sendfile.stream.sentEndOfStream();
+ if (!sendfile.stream.isActive()) {
activeRemoteStreamCount.decrementAndGet();
}
}
if (writeable) {
- ByteUtil.set31Bits(header, 5, stream.getIdentifier().intValue());
+ ByteUtil.set31Bits(header, 5, sendfile.stream.getIdentifier().intValue());
sendfile.mappedBuffer.limit(sendfile.mappedBuffer.position() + frameSize);
socketWrapper.write(BlockingMode.SEMI_BLOCK, protocol.getWriteTimeout(),
TimeUnit.MILLISECONDS, sendfile, COMPLETE_WRITE_WITH_COMPLETION,
@@ -397,19 +385,6 @@ public class Http2AsyncUpgradeHandler ex
}
}
- protected class SendfileData {
- protected Stream stream;
- // Note: a mapped buffer is a special construct with an underlying file
- // that doesn't need to be closed
- protected MappedByteBuffer mappedBuffer;
- protected int frameSize;
- protected long left;
- protected int streamReservation;
- protected int connectionReservation;
- protected long pos;
- protected long end;
- }
-
protected class AsyncPingManager extends PingManager {
@Override
public void sendPing(boolean force) throws IOException {
Modified: tomcat/trunk/java/org/apache/coyote/http2/Http2UpgradeHandler.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http2/Http2UpgradeHandler.java?rev=1816571&r1=1816570&r2=1816571&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http2/Http2UpgradeHandler.java (original)
+++ tomcat/trunk/java/org/apache/coyote/http2/Http2UpgradeHandler.java Tue Nov 28 20:49:45 2017
@@ -808,14 +808,15 @@ class Http2UpgradeHandler extends Abstra
* Process send file (if supported) for the given stream. The appropriate
* request attributes should be set before calling this method.
*
- * @param stream The stream to process
+ * @param sendfileData The stream and associated data to process
*
* @return The result of the send file processing
*/
- protected SendfileState processSendfile(Stream stream) {
+ protected SendfileState processSendfile(SendfileData sendfileData) {
return SendfileState.DONE;
}
+
private synchronized Set<AbstractStream> releaseBackLog(int increment) {
Set<AbstractStream> result = new HashSet<>();
if (backLogSize < increment) {
Added: tomcat/trunk/java/org/apache/coyote/http2/SendfileData.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http2/SendfileData.java?rev=1816571&view=auto
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http2/SendfileData.java (added)
+++ tomcat/trunk/java/org/apache/coyote/http2/SendfileData.java Tue Nov 28 20:49:45 2017
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.coyote.http2;
+
+import java.nio.MappedByteBuffer;
+import java.nio.file.Path;
+
+class SendfileData {
+ Path path;
+ Stream stream;
+ // Note: a mapped buffer is a special construct with an underlying file
+ // that doesn't need to be closed
+ MappedByteBuffer mappedBuffer;
+ int frameSize;
+ long left;
+ int streamReservation;
+ int connectionReservation;
+ long pos;
+ long end;
+}
\ No newline at end of file
Propchange: tomcat/trunk/java/org/apache/coyote/http2/SendfileData.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: tomcat/trunk/java/org/apache/coyote/http2/StreamProcessor.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http2/StreamProcessor.java?rev=1816571&r1=1816570&r2=1816571&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http2/StreamProcessor.java (original)
+++ tomcat/trunk/java/org/apache/coyote/http2/StreamProcessor.java Tue Nov 28 20:49:45 2017
@@ -16,6 +16,7 @@
*/
package org.apache.coyote.http2;
+import java.io.File;
import java.io.IOException;
import java.util.Iterator;
@@ -45,6 +46,7 @@ class StreamProcessor extends AbstractPr
private final Http2UpgradeHandler handler;
private final Stream stream;
+ private SendfileData sendfileData = null;
private SendfileState sendfileState = null;
@@ -101,11 +103,30 @@ class StreamProcessor extends AbstractPr
@Override
protected final void prepareResponse() throws IOException {
response.setCommitted(true);
+ if (handler.hasAsyncIO() && handler.getProtocol().getUseSendfile()) {
+ prepareSendfile();
+ }
prepareHeaders(response);
stream.writeHeaders();
}
+ private void prepareSendfile() {
+ String fileName = (String) stream.getCoyoteRequest().getAttribute(
+ org.apache.coyote.Constants.SENDFILE_FILENAME_ATTR);
+ if (fileName != null) {
+ sendfileData.path = new File(fileName).toPath();
+ sendfileData = new SendfileData();
+ sendfileData.pos = ((Long) stream.getCoyoteRequest().getAttribute(
+ org.apache.coyote.Constants.SENDFILE_FILE_START_ATTR)).longValue();
+ sendfileData.end = ((Long) stream.getCoyoteRequest().getAttribute(
+ org.apache.coyote.Constants.SENDFILE_FILE_END_ATTR)).longValue();
+ sendfileData.left = sendfileData.end - sendfileData.pos;
+ sendfileData.stream = stream;
+ }
+ }
+
+
static void prepareHeaders(Response coyoteResponse) {
MimeHeaders headers = coyoteResponse.getMimeHeaders();
int statusCode = coyoteResponse.getStatus();
@@ -135,7 +156,7 @@ class StreamProcessor extends AbstractPr
@Override
protected final void finishResponse() throws IOException {
- sendfileState = handler.processSendfile(stream);
+ sendfileState = handler.processSendfile(sendfileData);
if (!(sendfileState == SendfileState.PENDING)) {
stream.getOutputBuffer().close();
}
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org