Issue #1416 GzipHandler If-Match

This commit is contained in:
Greg Wilkins 2017-09-05 18:31:56 +10:00
parent ca750cf582
commit 57e86c5c41
3 changed files with 135 additions and 12 deletions

View File

@ -26,6 +26,7 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
@ -98,6 +99,12 @@ public class HttpFields implements Iterable<HttpField>
{
return new Itr();
}
public ListIterator<HttpField> listIterator()
{
return new Itr();
}
public Stream<HttpField> stream()
{
@ -1063,7 +1070,7 @@ public class HttpFields implements Iterable<HttpField>
}
private class Itr implements Iterator<HttpField>
private class Itr implements ListIterator<HttpField>
{
int _cursor; // index of next element to return
int _last=-1;
@ -1091,6 +1098,49 @@ public class HttpFields implements Iterable<HttpField>
_cursor=_last;
_last=-1;
}
@Override
public boolean hasPrevious()
{
return _cursor>0;
}
@Override
public HttpField previous()
{
if (_cursor == 0)
throw new NoSuchElementException();
return _fields[_last=--_cursor];
}
@Override
public int nextIndex()
{
return _cursor+1;
}
@Override
public int previousIndex()
{
return _cursor-1;
}
@Override
public void set(HttpField field)
{
if (_last<0)
throw new IllegalStateException();
_fields[_last] = field;
}
@Override
public void add(HttpField field)
{
_fields = Arrays.copyOf(_fields,_fields.length+1);
System.arraycopy(_fields,_cursor,_fields,_cursor+1,_size++);
_fields[_cursor++] = field;
_last=-1;
}
}
}

View File

@ -21,7 +21,9 @@ package org.eclipse.jetty.http;
import java.nio.ByteBuffer;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Locale;
import java.util.NoSuchElementException;
@ -31,6 +33,7 @@ import org.junit.Assert;
import org.junit.Test;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
@ -628,4 +631,68 @@ public class HttpFieldsTest
assertFalse(header.containsKey("n11"));
}
@Test
public void testIteration() throws Exception
{
HttpFields header = new HttpFields();
Iterator<HttpField> i = header.iterator();
assertThat(i.hasNext(),is(false));
header.put("name1", "valueA");
header.put("name2", "valueB");
header.add("name3", "valueC");
i = header.iterator();
assertThat(i.hasNext(),is(true));
assertThat(i.next().getName(),is("name1"));
assertThat(i.next().getName(),is("name2"));
i.remove();
assertThat(i.next().getName(),is("name3"));
assertThat(i.hasNext(),is(false));
i = header.iterator();
assertThat(i.hasNext(),is(true));
assertThat(i.next().getName(),is("name1"));
assertThat(i.next().getName(),is("name3"));
assertThat(i.hasNext(),is(false));
ListIterator<HttpField> l = header.listIterator();
assertThat(l.hasNext(),is(true));
l.add(new HttpField("name0","value"));
assertThat(l.hasNext(),is(true));
assertThat(l.next().getName(),is("name1"));
l.set(new HttpField("NAME1","value"));
assertThat(l.hasNext(),is(true));
assertThat(l.hasPrevious(),is(true));
assertThat(l.previous().getName(),is("NAME1"));
assertThat(l.hasNext(),is(true));
assertThat(l.hasPrevious(),is(true));
assertThat(l.previous().getName(),is("name0"));
assertThat(l.hasNext(),is(true));
assertThat(l.hasPrevious(),is(false));
assertThat(l.next().getName(),is("name0"));
assertThat(l.hasNext(),is(true));
assertThat(l.hasPrevious(),is(true));
assertThat(l.next().getName(),is("NAME1"));
l.add(new HttpField("name2","value"));
assertThat(l.next().getName(),is("name3"));
assertThat(l.hasNext(),is(false));
assertThat(l.hasPrevious(),is(true));
l.add(new HttpField("name4","value"));
assertThat(l.hasNext(),is(false));
assertThat(l.hasPrevious(),is(true));
assertThat(l.previous().getName(),is("name4"));
i = header.iterator();
assertThat(i.hasNext(),is(true));
assertThat(i.next().getName(),is("name0"));
assertThat(i.next().getName(),is("NAME1"));
assertThat(i.next().getName(),is("name2"));
assertThat(i.next().getName(),is("name3"));
assertThat(i.next().getName(),is("name4"));
assertThat(i.hasNext(),is(false));
}
}

View File

@ -22,6 +22,7 @@ import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.ListIterator;
import java.util.Set;
import java.util.zip.Deflater;
@ -495,22 +496,27 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory
}
// Special handling for etags
String etag = baseRequest.getHttpFields().get(HttpHeader.IF_NONE_MATCH);
if (etag!=null)
for (ListIterator<HttpField> fields = baseRequest.getHttpFields().listIterator(); fields.hasNext();)
{
int i=etag.indexOf(CompressedContentFormat.GZIP._etagQuote);
if (i>0)
HttpField field = fields.next();
if (field.getHeader()==HttpHeader.IF_NONE_MATCH || field.getHeader()==HttpHeader.IF_MATCH)
{
baseRequest.setAttribute("o.e.j.s.h.gzip.GzipHandler.etag",etag);
while (i>=0)
String etag = field.getValue();
int i=etag.indexOf(CompressedContentFormat.GZIP._etagQuote);
if (i>0)
{
etag=etag.substring(0,i)+etag.substring(i+CompressedContentFormat.GZIP._etag.length());
i=etag.indexOf(CompressedContentFormat.GZIP._etagQuote,i);
}
baseRequest.getHttpFields().put(new HttpField(HttpHeader.IF_NONE_MATCH,etag));
baseRequest.setAttribute("o.e.j.s.h.gzip.GzipHandler.etag",etag);
while (i>=0)
{
etag=etag.substring(0,i)+etag.substring(i+CompressedContentFormat.GZIP._etag.length());
i=etag.indexOf(CompressedContentFormat.GZIP._etagQuote,i);
}
fields.set(new HttpField(field.getHeader(),etag));
}
}
}
HttpOutput.Interceptor orig_interceptor = out.getInterceptor();
try
{