@@ -155,7 +155,7 @@ public class GrizzlyAsyncHttpProvider implements AsyncHttpProvider {
155
155
private final static Logger LOGGER = LoggerFactory .getLogger (GrizzlyAsyncHttpProvider .class );
156
156
private static final boolean SEND_FILE_SUPPORT ;
157
157
static {
158
- SEND_FILE_SUPPORT = /* configSendFileSupport();*/ false ;
158
+ SEND_FILE_SUPPORT = configSendFileSupport ();
159
159
}
160
160
private final Attribute <HttpTransactionContext > REQUEST_STATE_ATTR =
161
161
Grizzly .DEFAULT_ATTRIBUTE_BUILDER .createAttribute (HttpTransactionContext .class .getName ());
@@ -398,7 +398,7 @@ public void onTimeout(Connection connection) {
398
398
}
399
399
fcb .add (eventFilter );
400
400
fcb .add (clientFilter );
401
-
401
+
402
402
if (providerConfig != null ) {
403
403
final TransportCustomizer customizer = (TransportCustomizer )
404
404
providerConfig .getProperty (TRANSPORT_CUSTOMIZER );
@@ -433,7 +433,29 @@ void touchConnection(final Connection c, final Request request) {
433
433
434
434
435
435
// --------------------------------------------------------- Private Methods
436
-
436
+
437
+ private static boolean configSendFileSupport () {
438
+
439
+ return !((System .getProperty ("os.name" ).equalsIgnoreCase ("linux" )
440
+ && !linuxSendFileSupported ())
441
+ || System .getProperty ("os.name" ).equalsIgnoreCase ("HP-UX" ));
442
+ }
443
+
444
+
445
+ private static boolean linuxSendFileSupported () {
446
+ final String version = System .getProperty ("java.version" );
447
+ if (version .startsWith ("1.6" )) {
448
+ int idx = version .indexOf ('_' );
449
+ if (idx == -1 ) {
450
+ return false ;
451
+ }
452
+ final int patchRev = Integer .parseInt (version .substring (idx + 1 ));
453
+ return (patchRev >= 18 );
454
+ } else {
455
+ return version .startsWith ("1.7" ) || version .startsWith ("1.8" );
456
+ }
457
+ }
458
+
437
459
private void doDefaultTransportConfig () {
438
460
final ExecutorService service = clientConfig .executorService ();
439
461
if (service != null ) {
@@ -515,7 +537,7 @@ boolean sendRequest(final FilterChainContext ctx,
515
537
throws IOException {
516
538
517
539
boolean isWriteComplete = true ;
518
-
540
+
519
541
if (requestHasEntityBody (request )) {
520
542
final HttpTransactionContext context = getHttpTransactionContext (ctx .getConnection ());
521
543
BodyHandler handler = bodyHandlerFactory .getBodyHandler (request );
@@ -529,7 +551,7 @@ boolean sendRequest(final FilterChainContext ctx,
529
551
ctx .write (requestPacket , ctx .getTransportContext ().getCompletionHandler ());
530
552
}
531
553
LOGGER .debug ("REQUEST: {}" , requestPacket );
532
-
554
+
533
555
return isWriteComplete ;
534
556
}
535
557
@@ -585,7 +607,7 @@ final class HttpTransactionContext {
585
607
String lastRedirectURI ;
586
608
AtomicLong totalBodyWritten = new AtomicLong ();
587
609
AsyncHandler .STATE currentState ;
588
-
610
+
589
611
String wsRequestURI ;
590
612
boolean isWSRequest ;
591
613
HandShake handshake ;
@@ -883,9 +905,9 @@ private boolean sendAsGrizzlyRequest(final Request request,
883
905
}
884
906
885
907
if (proxy .getPrincipal () != null && proxy .isBasic ()) {
886
- requestPacket .setHeader (Header .ProxyAuthorization , AuthenticatorUtils .computeBasicAuthentication (proxy ));
908
+ requestPacket .setHeader (Header .ProxyAuthorization , AuthenticatorUtils .computeBasicAuthentication (proxy ));
887
909
}
888
-
910
+
889
911
}
890
912
}
891
913
final AsyncHandler h = httpCtx .handler ;
@@ -909,7 +931,7 @@ private boolean isWSRequest(final String requestUri) {
909
931
return (requestUri .charAt (0 ) == 'w' && requestUri .charAt (1 ) == 's' );
910
932
}
911
933
912
-
934
+
913
935
private void convertToUpgradeRequest (final HttpTransactionContext ctx ) {
914
936
final int colonIdx = ctx .requestUrl .indexOf (':' );
915
937
@@ -1224,7 +1246,7 @@ protected void onHttpHeadersParsed(HttpHeader httpHeader,
1224
1246
}
1225
1247
}
1226
1248
final HttpTransactionContext context = provider .getHttpTransactionContext (ctx .getConnection ());
1227
-
1249
+
1228
1250
if (httpHeader .isSkipRemainder () || (context .establishingTunnel && context .statusHandler ==null )) {
1229
1251
return ;
1230
1252
}
@@ -2132,7 +2154,7 @@ public boolean doHandle(final FilterChainContext ctx,
2132
2154
content .setLast (true );
2133
2155
ctx .write (content , ((!requestPacket .isCommitted ()) ? ctx .getTransportContext ().getCompletionHandler () : null ));
2134
2156
}
2135
-
2157
+
2136
2158
return true ;
2137
2159
}
2138
2160
@@ -2197,7 +2219,9 @@ public boolean doHandle(final FilterChainContext ctx,
2197
2219
final File f = request .getFile ();
2198
2220
requestPacket .setContentLengthLong (f .length ());
2199
2221
final HttpTransactionContext context = getHttpTransactionContext (ctx .getConnection ());
2200
- if (!SEND_FILE_SUPPORT || requestPacket .isSecure ()) {
2222
+ if (!SEND_FILE_SUPPORT
2223
+ || requestPacket .isSecure ()) {
2224
+ //|| requestPacket.getHeaders().contains(Header.TransferEncoding)) {
2201
2225
final FileInputStream fis = new FileInputStream (request .getFile ());
2202
2226
final MemoryManager mm = ctx .getMemoryManager ();
2203
2227
AtomicInteger written = new AtomicInteger ();
@@ -2236,7 +2260,10 @@ public void updated(WriteResult result) {
2236
2260
final AsyncHandler handler = context .handler ;
2237
2261
if (handler != null ) {
2238
2262
if (TransferCompletionHandler .class .isAssignableFrom (handler .getClass ())) {
2239
- final long written = result .getWrittenSize ();
2263
+ // WriteResult keeps a track of the total amount written,
2264
+ // so we need to calculate the delta ourselves.
2265
+ final long resultTotal = result .getWrittenSize ();
2266
+ final long written = resultTotal - context .totalBodyWritten .get ();
2240
2267
final long total = context .totalBodyWritten .addAndGet (written );
2241
2268
((TransferCompletionHandler ) handler ).onContentWriteProgress (
2242
2269
written ,
0 commit comments