jetty-9 work in progress. developing ServerConnection abstraction
This commit is contained in:
parent
c04a195256
commit
dc29d73d0b
|
@ -1,178 +0,0 @@
|
|||
// ========================================================================
|
||||
// Copyright (c) 2008-2009 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
|
||||
package org.eclipse.jetty.http;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
import org.eclipse.jetty.util.MultiMap;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.TypeUtil;
|
||||
import org.eclipse.jetty.util.URIUtil;
|
||||
import org.eclipse.jetty.util.UrlEncoded;
|
||||
import org.eclipse.jetty.util.Utf8StringBuffer;
|
||||
|
||||
public class EncodedHttpURI extends HttpURI
|
||||
{
|
||||
private final String _encoding;
|
||||
|
||||
public EncodedHttpURI(String encoding)
|
||||
{
|
||||
super();
|
||||
_encoding = encoding;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getScheme()
|
||||
{
|
||||
if (_scheme==_authority)
|
||||
return null;
|
||||
int l=_authority-_scheme;
|
||||
if (l==5 &&
|
||||
_raw[_scheme]=='h' &&
|
||||
_raw[_scheme+1]=='t' &&
|
||||
_raw[_scheme+2]=='t' &&
|
||||
_raw[_scheme+3]=='p' )
|
||||
return HttpScheme.HTTP.toString();
|
||||
if (l==6 &&
|
||||
_raw[_scheme]=='h' &&
|
||||
_raw[_scheme+1]=='t' &&
|
||||
_raw[_scheme+2]=='t' &&
|
||||
_raw[_scheme+3]=='p' &&
|
||||
_raw[_scheme+4]=='s' )
|
||||
return HttpScheme.HTTPS.toString();
|
||||
|
||||
return StringUtil.toString(_raw,_scheme,_authority-_scheme-1,_encoding);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAuthority()
|
||||
{
|
||||
if (_authority==_path)
|
||||
return null;
|
||||
return StringUtil.toString(_raw,_authority,_path-_authority,_encoding);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHost()
|
||||
{
|
||||
if (_host==_port)
|
||||
return null;
|
||||
return StringUtil.toString(_raw,_host,_port-_host,_encoding);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPort()
|
||||
{
|
||||
if (_port==_path)
|
||||
return -1;
|
||||
return TypeUtil.parseInt(_raw, _port+1, _path-_port-1,10);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPath()
|
||||
{
|
||||
if (_path==_param)
|
||||
return null;
|
||||
return StringUtil.toString(_raw,_path,_param-_path,_encoding);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDecodedPath()
|
||||
{
|
||||
if (_path==_param)
|
||||
return null;
|
||||
return URIUtil.decodePath(_raw,_path,_param-_path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPathAndParam()
|
||||
{
|
||||
if (_path==_query)
|
||||
return null;
|
||||
return StringUtil.toString(_raw,_path,_query-_path,_encoding);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCompletePath()
|
||||
{
|
||||
if (_path==_end)
|
||||
return null;
|
||||
return StringUtil.toString(_raw,_path,_end-_path,_encoding);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getParam()
|
||||
{
|
||||
if (_param==_query)
|
||||
return null;
|
||||
return StringUtil.toString(_raw,_param+1,_query-_param-1,_encoding);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getQuery()
|
||||
{
|
||||
if (_query==_fragment)
|
||||
return null;
|
||||
return StringUtil.toString(_raw,_query+1,_fragment-_query-1,_encoding);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasQuery()
|
||||
{
|
||||
return (_fragment>_query);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFragment()
|
||||
{
|
||||
if (_fragment==_end)
|
||||
return null;
|
||||
return StringUtil.toString(_raw,_fragment+1,_end-_fragment-1,_encoding);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decodeQueryTo(MultiMap parameters)
|
||||
{
|
||||
if (_query==_fragment)
|
||||
return;
|
||||
UrlEncoded.decodeTo(StringUtil.toString(_raw,_query+1,_fragment-_query-1,_encoding),parameters,_encoding);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decodeQueryTo(MultiMap parameters, String encoding)
|
||||
throws UnsupportedEncodingException
|
||||
{
|
||||
if (_query==_fragment)
|
||||
return;
|
||||
|
||||
if (encoding==null)
|
||||
encoding=_encoding;
|
||||
UrlEncoded.decodeTo(StringUtil.toString(_raw,_query+1,_fragment-_query-1,encoding),parameters,encoding);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
if (_rawString==null)
|
||||
_rawString= StringUtil.toString(_raw,_scheme,_end-_scheme,_encoding);
|
||||
return _rawString;
|
||||
}
|
||||
|
||||
public void writeTo(Utf8StringBuffer buf)
|
||||
{
|
||||
buf.getStringBuffer().append(toString());
|
||||
}
|
||||
|
||||
}
|
|
@ -26,8 +26,8 @@ import org.eclipse.jetty.util.resource.Resource;
|
|||
*/
|
||||
public interface HttpContent
|
||||
{
|
||||
ByteBuffer getContentType();
|
||||
ByteBuffer getLastModified();
|
||||
String getContentType();
|
||||
String getLastModified();
|
||||
ByteBuffer getIndirectBuffer();
|
||||
ByteBuffer getDirectBuffer();
|
||||
Resource getResource();
|
||||
|
@ -41,17 +41,17 @@ public interface HttpContent
|
|||
public class ResourceAsHttpContent implements HttpContent
|
||||
{
|
||||
final Resource _resource;
|
||||
final ByteBuffer _mimeType;
|
||||
final String _mimeType;
|
||||
final int _maxBuffer;
|
||||
|
||||
public ResourceAsHttpContent(final Resource resource, final ByteBuffer mimeType)
|
||||
public ResourceAsHttpContent(final Resource resource, final String mimeType)
|
||||
{
|
||||
_resource=resource;
|
||||
_mimeType=mimeType;
|
||||
_maxBuffer=-1;
|
||||
}
|
||||
|
||||
public ResourceAsHttpContent(final Resource resource, final ByteBuffer mimeType, int maxBuffer)
|
||||
public ResourceAsHttpContent(final Resource resource, final String mimeType, int maxBuffer)
|
||||
{
|
||||
_resource=resource;
|
||||
_mimeType=mimeType;
|
||||
|
@ -60,14 +60,14 @@ public interface HttpContent
|
|||
|
||||
/* ------------------------------------------------------------ */
|
||||
@Override
|
||||
public ByteBuffer getContentType()
|
||||
public String getContentType()
|
||||
{
|
||||
return _mimeType;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
@Override
|
||||
public ByteBuffer getLastModified()
|
||||
public String getLastModified()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -534,6 +534,12 @@ public class HttpFields implements Iterable<HttpFields.Field>
|
|||
_names.put(name, field);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------- */
|
||||
public void put(HttpHeader header, HttpHeaderValue value)
|
||||
{
|
||||
put(header,value.toString());
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------- */
|
||||
/**
|
||||
* Set a field.
|
||||
|
@ -601,6 +607,12 @@ public class HttpFields implements Iterable<HttpFields.Field>
|
|||
_names.put(name, field);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------- */
|
||||
public void add(HttpHeader header, HttpHeaderValue value) throws IllegalArgumentException
|
||||
{
|
||||
add(header,value.toString());
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------- */
|
||||
/**
|
||||
* Add to or set a field. If the field is allowed to have multiple values, add will add multiple
|
||||
|
@ -699,6 +711,19 @@ public class HttpFields implements Iterable<HttpFields.Field>
|
|||
}
|
||||
|
||||
|
||||
/* -------------------------------------------------------------- */
|
||||
/**
|
||||
* Sets the value of an long field.
|
||||
*
|
||||
* @param name the field name
|
||||
* @param value the field long value
|
||||
*/
|
||||
public void putLongField(HttpHeader name, long value)
|
||||
{
|
||||
String v = Long.toString(value);
|
||||
put(name, v);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------- */
|
||||
/**
|
||||
* Sets the value of an long field.
|
||||
|
@ -713,6 +738,19 @@ public class HttpFields implements Iterable<HttpFields.Field>
|
|||
}
|
||||
|
||||
|
||||
/* -------------------------------------------------------------- */
|
||||
/**
|
||||
* Sets the value of a date field.
|
||||
*
|
||||
* @param name the field name
|
||||
* @param date the field date value
|
||||
*/
|
||||
public void putDateField(HttpHeader name, long date)
|
||||
{
|
||||
String d=formatDate(date);
|
||||
put(name, d);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------- */
|
||||
/**
|
||||
* Sets the value of a date field.
|
||||
|
|
|
@ -15,6 +15,7 @@ package org.eclipse.jetty.http;
|
|||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URI;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
import org.eclipse.jetty.util.MultiMap;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
|
@ -55,6 +56,7 @@ public class HttpURI
|
|||
QUERY=9,
|
||||
ASTERISK=10;
|
||||
|
||||
final Charset _charset;
|
||||
boolean _partial=false;
|
||||
byte[] _raw=__empty;
|
||||
String _rawString;
|
||||
|
@ -70,11 +72,14 @@ public class HttpURI
|
|||
int _end;
|
||||
boolean _encoded=false;
|
||||
|
||||
final Utf8StringBuilder _utf8b = new Utf8StringBuilder(64);
|
||||
|
||||
public HttpURI()
|
||||
{
|
||||
_charset = URIUtil.__CHARSET;
|
||||
}
|
||||
|
||||
public HttpURI(Charset charset)
|
||||
{
|
||||
_charset = charset;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -84,6 +89,7 @@ public class HttpURI
|
|||
public HttpURI(boolean parsePartialAuth)
|
||||
{
|
||||
_partial=parsePartialAuth;
|
||||
_charset = URIUtil.__CHARSET;
|
||||
}
|
||||
|
||||
public HttpURI(String raw)
|
||||
|
@ -91,25 +97,35 @@ public class HttpURI
|
|||
_rawString=raw;
|
||||
byte[] b = raw.getBytes();
|
||||
parse(b,0,b.length);
|
||||
_charset = URIUtil.__CHARSET;
|
||||
}
|
||||
|
||||
public HttpURI(byte[] raw,int offset, int length)
|
||||
{
|
||||
parse2(raw,offset,length);
|
||||
_charset = URIUtil.__CHARSET;
|
||||
}
|
||||
|
||||
public HttpURI(URI uri)
|
||||
{
|
||||
parse(uri.toASCIIString());
|
||||
_charset = URIUtil.__CHARSET;
|
||||
}
|
||||
|
||||
public void parse(String raw)
|
||||
{
|
||||
byte[] b = raw.getBytes();
|
||||
byte[] b = StringUtil.getBytes(raw);
|
||||
parse2(b,0,b.length);
|
||||
_rawString=raw;
|
||||
}
|
||||
|
||||
public void parseConnect(String raw)
|
||||
{
|
||||
byte[] b = StringUtil.getBytes(raw);
|
||||
parseConnect(b,0,b.length);
|
||||
_rawString=raw;
|
||||
}
|
||||
|
||||
public void parse(byte[] raw,int offset, int length)
|
||||
{
|
||||
_rawString=null;
|
||||
|
@ -167,7 +183,7 @@ public class HttpURI
|
|||
{
|
||||
case '/':
|
||||
{
|
||||
throw new IllegalArgumentException("No closing ']' for " + StringUtil.toString(_raw,offset,length,URIUtil.__CHARSET));
|
||||
throw new IllegalArgumentException("No closing ']' for " + new String(_raw,offset,length,_charset));
|
||||
}
|
||||
case ']':
|
||||
{
|
||||
|
@ -386,7 +402,7 @@ public class HttpURI
|
|||
{
|
||||
case '/':
|
||||
{
|
||||
throw new IllegalArgumentException("No closing ']' for " + StringUtil.toString(_raw,offset,length,URIUtil.__CHARSET));
|
||||
throw new IllegalArgumentException("No closing ']' for " + new String(_raw,offset,length,_charset));
|
||||
}
|
||||
case ']':
|
||||
{
|
||||
|
@ -484,13 +500,6 @@ public class HttpURI
|
|||
_portValue=TypeUtil.parseInt(_raw, _port+1, _path-_port-1,10);
|
||||
}
|
||||
|
||||
private String toUtf8String(int offset,int length)
|
||||
{
|
||||
_utf8b.reset();
|
||||
_utf8b.append(_raw,offset,length);
|
||||
return _utf8b.toString();
|
||||
}
|
||||
|
||||
public String getScheme()
|
||||
{
|
||||
if (_scheme==_authority)
|
||||
|
@ -510,21 +519,21 @@ public class HttpURI
|
|||
_raw[_scheme+4]=='s' )
|
||||
return HttpScheme.HTTPS.toString();
|
||||
|
||||
return toUtf8String(_scheme,_authority-_scheme-1);
|
||||
return new String(_raw,_scheme,_authority-_scheme-1,_charset);
|
||||
}
|
||||
|
||||
public String getAuthority()
|
||||
{
|
||||
if (_authority==_path)
|
||||
return null;
|
||||
return toUtf8String(_authority,_path-_authority);
|
||||
return new String(_raw,_authority,_path-_authority,_charset);
|
||||
}
|
||||
|
||||
public String getHost()
|
||||
{
|
||||
if (_host==_port)
|
||||
return null;
|
||||
return toUtf8String(_host,_port-_host);
|
||||
return new String(_raw,_host,_port-_host,_charset);
|
||||
}
|
||||
|
||||
public int getPort()
|
||||
|
@ -536,7 +545,7 @@ public class HttpURI
|
|||
{
|
||||
if (_path==_param)
|
||||
return null;
|
||||
return toUtf8String(_path,_param-_path);
|
||||
return new String(_raw,_path,_param-_path,_charset);
|
||||
}
|
||||
|
||||
public String getDecodedPath()
|
||||
|
@ -575,39 +584,36 @@ public class HttpURI
|
|||
}
|
||||
|
||||
if (bytes==null)
|
||||
return toUtf8String(_path,length);
|
||||
|
||||
_utf8b.reset();
|
||||
_utf8b.append(bytes,0,n);
|
||||
return _utf8b.toString();
|
||||
return new String(_raw,_path,length,_charset);
|
||||
return new String(bytes,0,n,_charset);
|
||||
}
|
||||
|
||||
public String getPathAndParam()
|
||||
{
|
||||
if (_path==_query)
|
||||
return null;
|
||||
return toUtf8String(_path,_query-_path);
|
||||
return new String(_raw,_path,_query-_path,_charset);
|
||||
}
|
||||
|
||||
public String getCompletePath()
|
||||
{
|
||||
if (_path==_end)
|
||||
return null;
|
||||
return toUtf8String(_path,_end-_path);
|
||||
return new String(_raw,_path,_end-_path,_charset);
|
||||
}
|
||||
|
||||
public String getParam()
|
||||
{
|
||||
if (_param==_query)
|
||||
return null;
|
||||
return toUtf8String(_param+1,_query-_param-1);
|
||||
return new String(_raw,_param+1,_query-_param-1,_charset);
|
||||
}
|
||||
|
||||
public String getQuery()
|
||||
{
|
||||
if (_query==_fragment)
|
||||
return null;
|
||||
return toUtf8String(_query+1,_fragment-_query-1);
|
||||
return new String(_raw,_query+1,_fragment-_query-1,_charset);
|
||||
}
|
||||
|
||||
public String getQuery(String encoding)
|
||||
|
@ -626,15 +632,14 @@ public class HttpURI
|
|||
{
|
||||
if (_fragment==_end)
|
||||
return null;
|
||||
return toUtf8String(_fragment+1,_end-_fragment-1);
|
||||
return new String(_raw,_fragment+1,_end-_fragment-1,_charset);
|
||||
}
|
||||
|
||||
public void decodeQueryTo(MultiMap parameters)
|
||||
{
|
||||
if (_query==_fragment)
|
||||
return;
|
||||
_utf8b.reset();
|
||||
UrlEncoded.decodeUtf8To(_raw,_query+1,_fragment-_query-1,parameters,_utf8b);
|
||||
UrlEncoded.decodeUtf8To(_raw,_query+1,_fragment-_query-1,parameters);
|
||||
}
|
||||
|
||||
public void decodeQueryTo(MultiMap parameters, String encoding)
|
||||
|
@ -646,7 +651,7 @@ public class HttpURI
|
|||
if (encoding==null || StringUtil.isUTF8(encoding))
|
||||
UrlEncoded.decodeUtf8To(_raw,_query+1,_fragment-_query-1,parameters);
|
||||
else
|
||||
UrlEncoded.decodeTo(toUtf8String(_query+1,_fragment-_query-1),parameters,encoding);
|
||||
UrlEncoded.decodeTo(new String(_raw,_query+1,_fragment-_query-1,_charset),parameters,encoding);
|
||||
}
|
||||
|
||||
public void clear()
|
||||
|
@ -661,7 +666,7 @@ public class HttpURI
|
|||
public String toString()
|
||||
{
|
||||
if (_rawString==null)
|
||||
_rawString=toUtf8String(_scheme,_end-_scheme);
|
||||
_rawString=new String(_raw,_scheme,_end-_scheme,_charset);
|
||||
return _rawString;
|
||||
}
|
||||
|
||||
|
|
|
@ -66,6 +66,12 @@ public enum HttpVersion
|
|||
return _version;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public boolean is(String s)
|
||||
{
|
||||
return _string.equalsIgnoreCase(s);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
@Override
|
||||
public String toString()
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
package org.eclipse.jetty.http;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
@ -56,12 +57,16 @@ public class MimeTypes
|
|||
/* ------------------------------------------------------------ */
|
||||
private final String _string;
|
||||
private final ByteBuffer _buffer;
|
||||
private final Charset _charset;
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
Type(String s)
|
||||
{
|
||||
_string=s;
|
||||
_buffer=BufferUtil.toBuffer(s);
|
||||
|
||||
int i=s.toLowerCase().indexOf("charset=");
|
||||
_charset=(i>0)?Charset.forName(s.substring(i+8)):null;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -70,6 +75,12 @@ public class MimeTypes
|
|||
return _buffer.asReadOnlyBuffer();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public Charset getCharset()
|
||||
{
|
||||
return _charset;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public boolean is(String s)
|
||||
{
|
||||
|
@ -86,7 +97,7 @@ public class MimeTypes
|
|||
|
||||
/* ------------------------------------------------------------ */
|
||||
private static final Logger LOG = Log.getLogger(MimeTypes.class);
|
||||
private final static StringMap<MimeTypes.Type> CACHE= new StringMap<MimeTypes.Type>(true);
|
||||
public final static StringMap<MimeTypes.Type> CACHE= new StringMap<MimeTypes.Type>(true);
|
||||
private final static StringMap<ByteBuffer> TYPES= new StringMap<ByteBuffer>(true);
|
||||
private final static Map<String,ByteBuffer> __dftMimeMap = new HashMap<String,ByteBuffer>();
|
||||
private final static Map<String,String> __encodings = new HashMap<String,String>();
|
||||
|
@ -234,16 +245,16 @@ public class MimeTypes
|
|||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public static String getCharsetFromContentType(ByteBuffer value)
|
||||
public static String getCharsetFromContentType(String value)
|
||||
{
|
||||
int i=value.position();
|
||||
int end=value.limit();
|
||||
int end=value.length();
|
||||
int state=0;
|
||||
int start=0;
|
||||
boolean quote=false;
|
||||
int i=0;
|
||||
for (;i<end;i++)
|
||||
{
|
||||
byte b = value.get(i);
|
||||
char b = value.charAt(i);
|
||||
|
||||
if (quote && state!=10)
|
||||
{
|
||||
|
@ -300,4 +311,96 @@ public class MimeTypes
|
|||
|
||||
return __encodings.get(value);
|
||||
}
|
||||
|
||||
public static String getContentTypeWithoutCharset(String value)
|
||||
{
|
||||
int end=value.length();
|
||||
int state=0;
|
||||
int start=0;
|
||||
boolean quote=false;
|
||||
int i=0;
|
||||
StringBuilder builder=null;
|
||||
for (;i<end;i++)
|
||||
{
|
||||
char b = value.charAt(i);
|
||||
|
||||
if ('"'==b)
|
||||
{
|
||||
if (quote)
|
||||
{
|
||||
quote=false;
|
||||
}
|
||||
else
|
||||
{
|
||||
quote=true;
|
||||
}
|
||||
|
||||
switch(state)
|
||||
{
|
||||
case 11:
|
||||
builder.append(b);break;
|
||||
case 10:
|
||||
break;
|
||||
case 9:
|
||||
builder=new StringBuilder();
|
||||
builder.append(value,0,start+1);
|
||||
state=10;
|
||||
break;
|
||||
default:
|
||||
start=i;
|
||||
state=0;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (quote)
|
||||
{
|
||||
if (builder!=null && state!=10)
|
||||
builder.append(b);
|
||||
continue;
|
||||
}
|
||||
|
||||
switch(state)
|
||||
{
|
||||
case 0:
|
||||
if (';'==b)
|
||||
state=1;
|
||||
else if (' '!=b)
|
||||
start=i;
|
||||
break;
|
||||
|
||||
case 1: if ('c'==b) state=2; else if (' '!=b) state=0; break;
|
||||
case 2: if ('h'==b) state=3; else state=0;break;
|
||||
case 3: if ('a'==b) state=4; else state=0;break;
|
||||
case 4: if ('r'==b) state=5; else state=0;break;
|
||||
case 5: if ('s'==b) state=6; else state=0;break;
|
||||
case 6: if ('e'==b) state=7; else state=0;break;
|
||||
case 7: if ('t'==b) state=8; else state=0;break;
|
||||
case 8: if ('='==b) state=9; else if (' '!=b) state=0; break;
|
||||
|
||||
case 9:
|
||||
if (' '==b)
|
||||
break;
|
||||
builder=new StringBuilder();
|
||||
builder.append(value,0,start+1);
|
||||
state=10;
|
||||
break;
|
||||
|
||||
case 10:
|
||||
if (';'==b)
|
||||
{
|
||||
builder.append(b);
|
||||
state=11;
|
||||
}
|
||||
break;
|
||||
case 11:
|
||||
if (' '!=b)
|
||||
builder.append(b);
|
||||
}
|
||||
}
|
||||
if (builder==null)
|
||||
return value;
|
||||
return builder.toString();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
package org.eclipse.jetty.http;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
|
@ -46,7 +49,46 @@ public class MimeTypesTest
|
|||
MimeTypes mimetypes = new MimeTypes();
|
||||
ByteBuffer contentType = mimetypes.getMimeByExtension(filename);
|
||||
String prefix = "MimeTypes.getMimeByExtension(" + filename + ")";
|
||||
Assert.assertNotNull(prefix,contentType);
|
||||
Assert.assertEquals(prefix,expectedMimeType,BufferUtil.toString(contentType));
|
||||
assertNotNull(prefix,contentType);
|
||||
assertEquals(prefix,expectedMimeType,BufferUtil.toString(contentType));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCharsetFromContentType()
|
||||
{
|
||||
assertEquals("abc",MimeTypes.getCharsetFromContentType("foo/bar;charset=abc;some=else"));
|
||||
assertEquals("abc",MimeTypes.getCharsetFromContentType("foo/bar;charset=abc"));
|
||||
assertEquals("abc",MimeTypes.getCharsetFromContentType("foo/bar ; charset = abc"));
|
||||
assertEquals("abc",MimeTypes.getCharsetFromContentType("foo/bar ; charset = abc ; some=else"));
|
||||
assertEquals("abc",MimeTypes.getCharsetFromContentType("foo/bar;other=param;charset=abc;some=else"));
|
||||
assertEquals("abc",MimeTypes.getCharsetFromContentType("foo/bar;other=param;charset=abc"));
|
||||
assertEquals("abc",MimeTypes.getCharsetFromContentType("foo/bar other = param ; charset = abc"));
|
||||
assertEquals("abc",MimeTypes.getCharsetFromContentType("foo/bar other = param ; charset = abc ; some=else"));
|
||||
assertEquals("abc",MimeTypes.getCharsetFromContentType("foo/bar other = param ; charset = abc"));
|
||||
assertEquals("abc",MimeTypes.getCharsetFromContentType("foo/bar other = param ; charset = \"abc\" ; some=else"));
|
||||
assertEquals(null,MimeTypes.getCharsetFromContentType("foo/bar"));
|
||||
assertEquals("UTF-8",MimeTypes.getCharsetFromContentType("foo/bar;charset=uTf8"));
|
||||
assertEquals("UTF-8",MimeTypes.getCharsetFromContentType("foo/bar;other=\"charset=abc\";charset=uTf8"));
|
||||
assertEquals("UTF-8",MimeTypes.getCharsetFromContentType("text/html;charset=utf-8"));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testContentTypeWithoutCharset()
|
||||
{
|
||||
assertEquals("foo/bar;some=else",MimeTypes.getContentTypeWithoutCharset("foo/bar;charset=abc;some=else"));
|
||||
assertEquals("foo/bar",MimeTypes.getContentTypeWithoutCharset("foo/bar;charset=abc"));
|
||||
assertEquals("foo/bar",MimeTypes.getContentTypeWithoutCharset("foo/bar ; charset = abc"));
|
||||
assertEquals("foo/bar;some=else",MimeTypes.getContentTypeWithoutCharset("foo/bar ; charset = abc ; some=else"));
|
||||
assertEquals("foo/bar;other=param;some=else",MimeTypes.getContentTypeWithoutCharset("foo/bar;other=param;charset=abc;some=else"));
|
||||
assertEquals("foo/bar;other=param",MimeTypes.getContentTypeWithoutCharset("foo/bar;other=param;charset=abc"));
|
||||
assertEquals("foo/bar ; other = param",MimeTypes.getContentTypeWithoutCharset("foo/bar ; other = param ; charset = abc"));
|
||||
assertEquals("foo/bar ; other = param;some=else",MimeTypes.getContentTypeWithoutCharset("foo/bar ; other = param ; charset = abc ; some=else"));
|
||||
assertEquals("foo/bar ; other = param",MimeTypes.getContentTypeWithoutCharset("foo/bar ; other = param ; charset = abc"));
|
||||
assertEquals("foo/bar ; other = param;some=else",MimeTypes.getContentTypeWithoutCharset("foo/bar ; other = param ; charset = \"abc\" ; some=else"));
|
||||
assertEquals("foo/bar",MimeTypes.getContentTypeWithoutCharset("foo/bar"));
|
||||
assertEquals("foo/bar",MimeTypes.getContentTypeWithoutCharset("foo/bar;charset=uTf8"));
|
||||
assertEquals("foo/bar;other=\"charset=abc\"",MimeTypes.getContentTypeWithoutCharset("foo/bar;other=\"charset=abc\";charset=uTf8"));
|
||||
assertEquals("text/html",MimeTypes.getContentTypeWithoutCharset("text/html;charset=utf-8"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -756,7 +756,7 @@ public abstract class AbstractHttpConnection extends AbstractConnection
|
|||
|
||||
if (version==null)
|
||||
{
|
||||
_request.setProtocol(HttpVersion.HTTP_0_9);
|
||||
_request.setHttpVersion(HttpVersion.HTTP_0_9);
|
||||
_version=HttpVersion.HTTP_0_9_ORDINAL;
|
||||
}
|
||||
else
|
||||
|
@ -766,7 +766,7 @@ public abstract class AbstractHttpConnection extends AbstractConnection
|
|||
throw new HttpException(HttpStatus.BAD_REQUEST_400,null);
|
||||
_version = HttpVersion.CACHE.getOrdinal(version);
|
||||
if (_version <= 0) _version = HttpVersion.HTTP_1_0_ORDINAL;
|
||||
_request.setProtocol(version.toString());
|
||||
_request.setHttpVersion(version.toString());
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
|
|
|
@ -62,25 +62,28 @@ public class AsyncContinuation implements AsyncContext, Continuation
|
|||
// COMPLETING UNCOMPLETED UNCOMPLETED
|
||||
// UNCOMPLETED COMPLETED
|
||||
// COMPLETED
|
||||
private static final int __IDLE=0; // Idle request
|
||||
private static final int __DISPATCHED=1; // Request dispatched to filter/servlet
|
||||
private static final int __ASYNCSTARTED=2; // Suspend called, but not yet returned to container
|
||||
private static final int __REDISPATCHING=3;// resumed while dispatched
|
||||
private static final int __ASYNCWAIT=4; // Suspended and parked
|
||||
private static final int __REDISPATCH=5; // Has been scheduled
|
||||
private static final int __REDISPATCHED=6; // Request redispatched to filter/servlet
|
||||
private static final int __COMPLETING=7; // complete while dispatched
|
||||
private static final int __UNCOMPLETED=8; // Request is completable
|
||||
private static final int __COMPLETED=9; // Request is complete
|
||||
|
||||
public enum State {
|
||||
IDLE, // Idle request
|
||||
DISPATCHED, // Request dispatched to filter/servlet
|
||||
ASYNCSTARTED, // Suspend called, but not yet returned to container
|
||||
REDISPATCHING,// resumed while dispatched
|
||||
ASYNCWAIT, // Suspended and parked
|
||||
REDISPATCH, // Has been scheduled
|
||||
REDISPATCHED, // Request redispatched to filter/servlet
|
||||
COMPLETING, // complete while dispatched
|
||||
UNCOMPLETED, // Request is completable
|
||||
COMPLETED // Request is complete
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
protected AbstractHttpConnection _connection;
|
||||
protected ServerConnection _connection;
|
||||
private List<AsyncListener> _lastAsyncListeners;
|
||||
private List<AsyncListener> _asyncListeners;
|
||||
private List<ContinuationListener> _continuationListeners;
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
private int _state;
|
||||
private State _state;
|
||||
private boolean _initial;
|
||||
private boolean _resumed;
|
||||
private boolean _expired;
|
||||
|
@ -93,12 +96,12 @@ public class AsyncContinuation implements AsyncContext, Continuation
|
|||
/* ------------------------------------------------------------ */
|
||||
protected AsyncContinuation()
|
||||
{
|
||||
_state=__IDLE;
|
||||
_state=State.IDLE;
|
||||
_initial=true;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
protected void setConnection(final AbstractHttpConnection connection)
|
||||
protected void setConnection(final ServerConnection connection)
|
||||
{
|
||||
synchronized(this)
|
||||
{
|
||||
|
@ -203,10 +206,10 @@ public class AsyncContinuation implements AsyncContext, Continuation
|
|||
{
|
||||
switch(_state)
|
||||
{
|
||||
case __ASYNCSTARTED:
|
||||
case __REDISPATCHING:
|
||||
case __COMPLETING:
|
||||
case __ASYNCWAIT:
|
||||
case ASYNCSTARTED:
|
||||
case REDISPATCHING:
|
||||
case COMPLETING:
|
||||
case ASYNCWAIT:
|
||||
return true;
|
||||
|
||||
default:
|
||||
|
@ -222,8 +225,8 @@ public class AsyncContinuation implements AsyncContext, Continuation
|
|||
{
|
||||
switch(_state)
|
||||
{
|
||||
case __ASYNCSTARTED:
|
||||
case __ASYNCWAIT:
|
||||
case ASYNCSTARTED:
|
||||
case ASYNCWAIT:
|
||||
return true;
|
||||
|
||||
default:
|
||||
|
@ -239,10 +242,10 @@ public class AsyncContinuation implements AsyncContext, Continuation
|
|||
{
|
||||
switch(_state)
|
||||
{
|
||||
case __REDISPATCH:
|
||||
case __REDISPATCHED:
|
||||
case __REDISPATCHING:
|
||||
case __COMPLETING:
|
||||
case REDISPATCH:
|
||||
case REDISPATCHED:
|
||||
case REDISPATCHING:
|
||||
case COMPLETING:
|
||||
return true;
|
||||
|
||||
default:
|
||||
|
@ -266,18 +269,7 @@ public class AsyncContinuation implements AsyncContext, Continuation
|
|||
{
|
||||
synchronized (this)
|
||||
{
|
||||
return
|
||||
((_state==__IDLE)?"IDLE":
|
||||
(_state==__DISPATCHED)?"DISPATCHED":
|
||||
(_state==__ASYNCSTARTED)?"ASYNCSTARTED":
|
||||
(_state==__ASYNCWAIT)?"ASYNCWAIT":
|
||||
(_state==__REDISPATCHING)?"REDISPATCHING":
|
||||
(_state==__REDISPATCH)?"REDISPATCH":
|
||||
(_state==__REDISPATCHED)?"REDISPATCHED":
|
||||
(_state==__COMPLETING)?"COMPLETING":
|
||||
(_state==__UNCOMPLETED)?"UNCOMPLETED":
|
||||
(_state==__COMPLETED)?"COMPLETE":
|
||||
("UNKNOWN?"+_state))+
|
||||
return _state+
|
||||
(_initial?",initial":"")+
|
||||
(_resumed?",resumed":"")+
|
||||
(_expired?",expired":"");
|
||||
|
@ -297,9 +289,9 @@ public class AsyncContinuation implements AsyncContext, Continuation
|
|||
|
||||
switch(_state)
|
||||
{
|
||||
case __IDLE:
|
||||
case IDLE:
|
||||
_initial=true;
|
||||
_state=__DISPATCHED;
|
||||
_state=State.DISPATCHED;
|
||||
if (_lastAsyncListeners!=null)
|
||||
_lastAsyncListeners.clear();
|
||||
if (_asyncListeners!=null)
|
||||
|
@ -311,15 +303,15 @@ public class AsyncContinuation implements AsyncContext, Continuation
|
|||
}
|
||||
return true;
|
||||
|
||||
case __COMPLETING:
|
||||
_state=__UNCOMPLETED;
|
||||
case COMPLETING:
|
||||
_state=State.UNCOMPLETED;
|
||||
return false;
|
||||
|
||||
case __ASYNCWAIT:
|
||||
case ASYNCWAIT:
|
||||
return false;
|
||||
|
||||
case __REDISPATCH:
|
||||
_state=__REDISPATCHED;
|
||||
case REDISPATCH:
|
||||
_state=State.REDISPATCHED;
|
||||
return true;
|
||||
|
||||
default:
|
||||
|
@ -340,8 +332,8 @@ public class AsyncContinuation implements AsyncContext, Continuation
|
|||
{
|
||||
switch(_state)
|
||||
{
|
||||
case __DISPATCHED:
|
||||
case __REDISPATCHED:
|
||||
case DISPATCHED:
|
||||
case REDISPATCHED:
|
||||
_resumed=false;
|
||||
_expired=false;
|
||||
|
||||
|
@ -353,7 +345,7 @@ public class AsyncContinuation implements AsyncContext, Continuation
|
|||
_event._path=null;
|
||||
}
|
||||
|
||||
_state=__ASYNCSTARTED;
|
||||
_state=State.ASYNCSTARTED;
|
||||
List<AsyncListener> recycle=_lastAsyncListeners;
|
||||
_lastAsyncListeners=_asyncListeners;
|
||||
_asyncListeners=recycle;
|
||||
|
@ -397,37 +389,37 @@ public class AsyncContinuation implements AsyncContext, Continuation
|
|||
{
|
||||
switch(_state)
|
||||
{
|
||||
case __REDISPATCHED:
|
||||
case __DISPATCHED:
|
||||
_state=__UNCOMPLETED;
|
||||
case REDISPATCHED:
|
||||
case DISPATCHED:
|
||||
_state=State.UNCOMPLETED;
|
||||
return true;
|
||||
|
||||
case __IDLE:
|
||||
case IDLE:
|
||||
throw new IllegalStateException(this.getStatusString());
|
||||
|
||||
case __ASYNCSTARTED:
|
||||
case ASYNCSTARTED:
|
||||
_initial=false;
|
||||
_state=__ASYNCWAIT;
|
||||
_state=State.ASYNCWAIT;
|
||||
scheduleTimeout(); // could block and change state.
|
||||
if (_state==__ASYNCWAIT)
|
||||
if (_state==State.ASYNCWAIT)
|
||||
return true;
|
||||
else if (_state==__COMPLETING)
|
||||
else if (_state==State.COMPLETING)
|
||||
{
|
||||
_state=__UNCOMPLETED;
|
||||
_state=State.UNCOMPLETED;
|
||||
return true;
|
||||
}
|
||||
_initial=false;
|
||||
_state=__REDISPATCHED;
|
||||
_state=State.REDISPATCHED;
|
||||
return false;
|
||||
|
||||
case __REDISPATCHING:
|
||||
case REDISPATCHING:
|
||||
_initial=false;
|
||||
_state=__REDISPATCHED;
|
||||
_state=State.REDISPATCHED;
|
||||
return false;
|
||||
|
||||
case __COMPLETING:
|
||||
case COMPLETING:
|
||||
_initial=false;
|
||||
_state=__UNCOMPLETED;
|
||||
_state=State.UNCOMPLETED;
|
||||
return true;
|
||||
|
||||
default:
|
||||
|
@ -444,18 +436,18 @@ public class AsyncContinuation implements AsyncContext, Continuation
|
|||
{
|
||||
switch(_state)
|
||||
{
|
||||
case __ASYNCSTARTED:
|
||||
_state=__REDISPATCHING;
|
||||
case ASYNCSTARTED:
|
||||
_state=State.REDISPATCHING;
|
||||
_resumed=true;
|
||||
return;
|
||||
|
||||
case __ASYNCWAIT:
|
||||
case ASYNCWAIT:
|
||||
dispatch=!_expired;
|
||||
_state=__REDISPATCH;
|
||||
_state=State.REDISPATCH;
|
||||
_resumed=true;
|
||||
break;
|
||||
|
||||
case __REDISPATCH:
|
||||
case REDISPATCH:
|
||||
return;
|
||||
|
||||
default:
|
||||
|
@ -479,8 +471,8 @@ public class AsyncContinuation implements AsyncContext, Continuation
|
|||
{
|
||||
switch(_state)
|
||||
{
|
||||
case __ASYNCSTARTED:
|
||||
case __ASYNCWAIT:
|
||||
case ASYNCSTARTED:
|
||||
case ASYNCWAIT:
|
||||
cListeners=_continuationListeners;
|
||||
aListeners=_asyncListeners;
|
||||
break;
|
||||
|
@ -527,8 +519,8 @@ public class AsyncContinuation implements AsyncContext, Continuation
|
|||
{
|
||||
switch(_state)
|
||||
{
|
||||
case __ASYNCSTARTED:
|
||||
case __ASYNCWAIT:
|
||||
case ASYNCSTARTED:
|
||||
case ASYNCWAIT:
|
||||
if (_continuation)
|
||||
dispatch();
|
||||
else
|
||||
|
@ -552,16 +544,16 @@ public class AsyncContinuation implements AsyncContext, Continuation
|
|||
{
|
||||
switch(_state)
|
||||
{
|
||||
case __DISPATCHED:
|
||||
case __REDISPATCHED:
|
||||
case DISPATCHED:
|
||||
case REDISPATCHED:
|
||||
throw new IllegalStateException(this.getStatusString());
|
||||
|
||||
case __ASYNCSTARTED:
|
||||
_state=__COMPLETING;
|
||||
case ASYNCSTARTED:
|
||||
_state=State.COMPLETING;
|
||||
return;
|
||||
|
||||
case __ASYNCWAIT:
|
||||
_state=__COMPLETING;
|
||||
case ASYNCWAIT:
|
||||
_state=State.COMPLETING;
|
||||
dispatch=!_expired;
|
||||
break;
|
||||
|
||||
|
@ -604,8 +596,8 @@ public class AsyncContinuation implements AsyncContext, Continuation
|
|||
{
|
||||
switch(_state)
|
||||
{
|
||||
case __UNCOMPLETED:
|
||||
_state=__COMPLETED;
|
||||
case UNCOMPLETED:
|
||||
_state=State.COMPLETED;
|
||||
cListeners=_continuationListeners;
|
||||
aListeners=_asyncListeners;
|
||||
break;
|
||||
|
@ -661,11 +653,11 @@ public class AsyncContinuation implements AsyncContext, Continuation
|
|||
{
|
||||
switch(_state)
|
||||
{
|
||||
case __DISPATCHED:
|
||||
case __REDISPATCHED:
|
||||
case DISPATCHED:
|
||||
case REDISPATCHED:
|
||||
throw new IllegalStateException(getStatusString());
|
||||
default:
|
||||
_state=__IDLE;
|
||||
_state=State.IDLE;
|
||||
}
|
||||
_initial = true;
|
||||
_resumed=false;
|
||||
|
@ -690,71 +682,19 @@ public class AsyncContinuation implements AsyncContext, Continuation
|
|||
/* ------------------------------------------------------------ */
|
||||
protected void scheduleDispatch()
|
||||
{
|
||||
EndPoint endp=_connection.getEndPoint();
|
||||
if (!endp.isBlocking())
|
||||
{
|
||||
((AsyncEndPoint)endp).asyncDispatch();
|
||||
}
|
||||
_connection.asyncDispatch();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
protected void scheduleTimeout()
|
||||
{
|
||||
EndPoint endp=_connection.getEndPoint();
|
||||
if (_timeoutMs>0)
|
||||
{
|
||||
if (endp.isBlocking())
|
||||
{
|
||||
synchronized(this)
|
||||
{
|
||||
_expireAt = System.currentTimeMillis()+_timeoutMs;
|
||||
long wait=_timeoutMs;
|
||||
while (_expireAt>0 && wait>0 && _connection.getServer().isRunning())
|
||||
{
|
||||
try
|
||||
{
|
||||
this.wait(wait);
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
LOG.ignore(e);
|
||||
}
|
||||
wait=_expireAt-System.currentTimeMillis();
|
||||
}
|
||||
|
||||
if (_expireAt>0 && wait<=0 && _connection.getServer().isRunning())
|
||||
{
|
||||
expired();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
((AsyncEndPoint)endp).scheduleTimeout(_event._timeout,_timeoutMs);
|
||||
}
|
||||
}
|
||||
_connection.scheduleTimeout(_event._timeout,_timeoutMs);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
protected void cancelTimeout()
|
||||
{
|
||||
EndPoint endp=_connection.getEndPoint();
|
||||
if (endp.isBlocking())
|
||||
{
|
||||
synchronized(this)
|
||||
{
|
||||
_expireAt=0;
|
||||
this.notifyAll();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
final AsyncEventState event=_event;
|
||||
if (event!=null)
|
||||
{
|
||||
((AsyncEndPoint)endp).cancelTimeout(event._timeout);
|
||||
}
|
||||
}
|
||||
_connection.cancelTimeout(_event._timeout);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -762,7 +702,7 @@ public class AsyncContinuation implements AsyncContext, Continuation
|
|||
{
|
||||
synchronized (this)
|
||||
{
|
||||
return _state==__COMPLETING;
|
||||
return _state==State.COMPLETING;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -771,7 +711,7 @@ public class AsyncContinuation implements AsyncContext, Continuation
|
|||
{
|
||||
synchronized (this)
|
||||
{
|
||||
return _state==__UNCOMPLETED;
|
||||
return _state==State.UNCOMPLETED;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -780,7 +720,7 @@ public class AsyncContinuation implements AsyncContext, Continuation
|
|||
{
|
||||
synchronized (this)
|
||||
{
|
||||
return _state==__COMPLETED;
|
||||
return _state==State.COMPLETED;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -792,10 +732,10 @@ public class AsyncContinuation implements AsyncContext, Continuation
|
|||
{
|
||||
switch(_state)
|
||||
{
|
||||
case __ASYNCSTARTED:
|
||||
case __REDISPATCHING:
|
||||
case __REDISPATCH:
|
||||
case __ASYNCWAIT:
|
||||
case ASYNCSTARTED:
|
||||
case REDISPATCHING:
|
||||
case REDISPATCH:
|
||||
case ASYNCWAIT:
|
||||
return true;
|
||||
|
||||
default:
|
||||
|
@ -812,10 +752,10 @@ public class AsyncContinuation implements AsyncContext, Continuation
|
|||
{
|
||||
switch(_state)
|
||||
{
|
||||
case __IDLE:
|
||||
case __DISPATCHED:
|
||||
case __UNCOMPLETED:
|
||||
case __COMPLETED:
|
||||
case IDLE:
|
||||
case DISPATCHED:
|
||||
case UNCOMPLETED:
|
||||
case COMPLETED:
|
||||
return false;
|
||||
|
||||
default:
|
||||
|
|
|
@ -14,14 +14,24 @@
|
|||
package org.eclipse.jetty.server;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InterruptedIOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.eclipse.jetty.http.HttpException;
|
||||
import org.eclipse.jetty.http.HttpGenerator;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
import org.eclipse.jetty.http.HttpGenerator.Action;
|
||||
import org.eclipse.jetty.io.AsyncEndPoint;
|
||||
import org.eclipse.jetty.io.Connection;
|
||||
import org.eclipse.jetty.io.EndPoint;
|
||||
import org.eclipse.jetty.io.EofException;
|
||||
import org.eclipse.jetty.io.nio.AsyncConnection;
|
||||
import org.eclipse.jetty.io.nio.SelectChannelEndPoint;
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
||||
|
@ -183,4 +193,104 @@ public class AsyncHttpConnection extends AbstractHttpConnection implements Async
|
|||
_parser.setPersistent(false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
ByteBuffer header=null;
|
||||
ByteBuffer chunk=null;
|
||||
ByteBuffer buffer=null;
|
||||
/* ------------------------------------------------------------ */
|
||||
private void write(ByteBuffer content) throws IOException
|
||||
{
|
||||
if (!_generator.isComplete())
|
||||
throw new EofException();
|
||||
|
||||
try
|
||||
{
|
||||
while(BufferUtil.hasContent(content))
|
||||
{
|
||||
|
||||
// Generate
|
||||
Action action=BufferUtil.hasContent(content)?null:Action.COMPLETE;
|
||||
|
||||
/* System.err.printf("generate(%s,%s,%s,%s,%s)@%s%n",
|
||||
BufferUtil.toSummaryString(header),
|
||||
BufferUtil.toSummaryString(chunk),
|
||||
BufferUtil.toSummaryString(buffer),
|
||||
BufferUtil.toSummaryString(content),
|
||||
action,gen.getState());*/
|
||||
HttpGenerator.Result result=_generator.generate(header,chunk,buffer,content,action);
|
||||
/*System.err.printf("%s (%s,%s,%s,%s,%s)@%s%n",
|
||||
result,
|
||||
BufferUtil.toSummaryString(header),
|
||||
BufferUtil.toSummaryString(chunk),
|
||||
BufferUtil.toSummaryString(buffer),
|
||||
BufferUtil.toSummaryString(content),
|
||||
action,gen.getState());*/
|
||||
|
||||
switch(result)
|
||||
{
|
||||
case NEED_HEADER:
|
||||
header=BufferUtil.allocate(2048);
|
||||
break;
|
||||
|
||||
case NEED_BUFFER:
|
||||
buffer=BufferUtil.allocate(8192);
|
||||
break;
|
||||
|
||||
case NEED_CHUNK:
|
||||
header=null;
|
||||
chunk=BufferUtil.allocate(HttpGenerator.CHUNK_SIZE);
|
||||
break;
|
||||
|
||||
case FLUSH:
|
||||
{
|
||||
Future<Integer> future = getEndPoint().flush(header,chunk,buffer);
|
||||
future.get(getMaxIdleTime(),TimeUnit.MILLISECONDS);
|
||||
break;
|
||||
}
|
||||
case FLUSH_CONTENT:
|
||||
{
|
||||
Future<Integer> future = getEndPoint().flush(header,chunk,content);
|
||||
future.get(getMaxIdleTime(),TimeUnit.MILLISECONDS);
|
||||
break;
|
||||
}
|
||||
case OK:
|
||||
break;
|
||||
case SHUTDOWN_OUT:
|
||||
getEndPoint().shutdownOutput();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
catch(final TimeoutException e)
|
||||
{
|
||||
throw new InterruptedIOException(e.toString())
|
||||
{
|
||||
{
|
||||
this.initCause(e);
|
||||
}
|
||||
};
|
||||
}
|
||||
catch (final InterruptedException e)
|
||||
{
|
||||
throw new InterruptedIOException(e.toString())
|
||||
{
|
||||
{
|
||||
this.initCause(e);
|
||||
}
|
||||
};
|
||||
}
|
||||
catch (final ExecutionException e)
|
||||
{
|
||||
throw new IOException(e.toString())
|
||||
{
|
||||
{
|
||||
this.initCause(e);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -14,22 +14,23 @@
|
|||
package org.eclipse.jetty.server;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import javax.servlet.ServletInputStream;
|
||||
|
||||
import org.eclipse.jetty.http.HttpParser;
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
|
||||
|
||||
public class HttpInput extends ServletInputStream
|
||||
{
|
||||
protected final AbstractHttpConnection _connection;
|
||||
protected final HttpParser _parser;
|
||||
protected final ServerConnection _connection;
|
||||
private ByteBuffer _content;
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public HttpInput(AbstractHttpConnection connection)
|
||||
public HttpInput(ServerConnection connection)
|
||||
{
|
||||
_connection=connection;
|
||||
_parser=(HttpParser)connection.getParser();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -40,9 +41,10 @@ public class HttpInput extends ServletInputStream
|
|||
public int read() throws IOException
|
||||
{
|
||||
int c=-1;
|
||||
ByteBuffer content=_parser.blockForContent(_connection.getMaxIdleTime());
|
||||
if (content!=null)
|
||||
c= 0xff & content.get();
|
||||
if (BufferUtil.isEmpty(_content))
|
||||
_content=_connection.blockForContent();
|
||||
if (BufferUtil.hasContent(_content))
|
||||
c= 0xff & _content.get();
|
||||
return c;
|
||||
}
|
||||
|
||||
|
@ -54,9 +56,13 @@ public class HttpInput extends ServletInputStream
|
|||
public int read(byte[] b, int off, int len) throws IOException
|
||||
{
|
||||
int l=-1;
|
||||
ByteBuffer content=_parser.blockForContent(_connection.getMaxIdleTime());
|
||||
if (content!=null)
|
||||
l= content.get(b, off, len);
|
||||
if (BufferUtil.isEmpty(_content))
|
||||
_content=_connection.blockForContent();
|
||||
if (BufferUtil.hasContent(_content))
|
||||
{
|
||||
l=Math.min(len,_content.remaining());
|
||||
_content.get(b,off,l);
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
|
@ -64,7 +70,11 @@ public class HttpInput extends ServletInputStream
|
|||
@Override
|
||||
public int available() throws IOException
|
||||
{
|
||||
return _parser.available();
|
||||
if (BufferUtil.isEmpty(_content))
|
||||
_content=_connection.getContent();
|
||||
if (BufferUtil.hasContent(_content))
|
||||
return _content.remaining();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -44,12 +44,8 @@ import org.eclipse.jetty.util.ByteArrayOutputStream2;
|
|||
*/
|
||||
public class HttpOutput extends ServletOutputStream
|
||||
{
|
||||
protected final AbstractHttpConnection _connection;
|
||||
protected final HttpGenerator _generator;
|
||||
private final ServerConnection _connection;
|
||||
private boolean _closed;
|
||||
ByteBuffer header=null;
|
||||
ByteBuffer chunk=null;
|
||||
ByteBuffer buffer=null;
|
||||
|
||||
// These are held here for reuse by Writer
|
||||
String _characterEncoding;
|
||||
|
@ -58,22 +54,15 @@ public class HttpOutput extends ServletOutputStream
|
|||
ByteArrayOutputStream2 _bytes;
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public HttpOutput(AbstractHttpConnection connection)
|
||||
public HttpOutput(ServerConnection connection)
|
||||
{
|
||||
_connection=connection;
|
||||
_generator=(HttpGenerator)connection.getGenerator();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public int getMaxIdleTime()
|
||||
{
|
||||
return _connection.getMaxIdleTime();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public boolean isWritten()
|
||||
{
|
||||
return _generator.getContentWritten()>0;
|
||||
return _connection.getContentWritten()>0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -109,7 +98,10 @@ public class HttpOutput extends ServletOutputStream
|
|||
@Override
|
||||
public void write(byte[] b, int off, int len) throws IOException
|
||||
{
|
||||
write(ByteBuffer.wrap(b,off,len));
|
||||
if (_closed)
|
||||
throw new IOException("Closed");
|
||||
|
||||
_connection.write(ByteBuffer.wrap(b,off,len));
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -119,7 +111,10 @@ public class HttpOutput extends ServletOutputStream
|
|||
@Override
|
||||
public void write(byte[] b) throws IOException
|
||||
{
|
||||
write(ByteBuffer.wrap(b));
|
||||
if (_closed)
|
||||
throw new IOException("Closed");
|
||||
|
||||
_connection.write(ByteBuffer.wrap(b));
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -128,106 +123,12 @@ public class HttpOutput extends ServletOutputStream
|
|||
*/
|
||||
@Override
|
||||
public void write(int b) throws IOException
|
||||
{
|
||||
write(ByteBuffer.wrap(new byte[]{(byte)b}));
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
private void write(ByteBuffer content) throws IOException
|
||||
{
|
||||
if (_closed)
|
||||
throw new IOException("Closed");
|
||||
if (!_generator.isComplete())
|
||||
throw new EofException();
|
||||
|
||||
try
|
||||
{
|
||||
while(BufferUtil.hasContent(content))
|
||||
{
|
||||
|
||||
// Generate
|
||||
Action action=BufferUtil.hasContent(content)?null:Action.COMPLETE;
|
||||
|
||||
/* System.err.printf("generate(%s,%s,%s,%s,%s)@%s%n",
|
||||
BufferUtil.toSummaryString(header),
|
||||
BufferUtil.toSummaryString(chunk),
|
||||
BufferUtil.toSummaryString(buffer),
|
||||
BufferUtil.toSummaryString(content),
|
||||
action,gen.getState());*/
|
||||
HttpGenerator.Result result=_generator.generate(header,chunk,buffer,content,action);
|
||||
/*System.err.printf("%s (%s,%s,%s,%s,%s)@%s%n",
|
||||
result,
|
||||
BufferUtil.toSummaryString(header),
|
||||
BufferUtil.toSummaryString(chunk),
|
||||
BufferUtil.toSummaryString(buffer),
|
||||
BufferUtil.toSummaryString(content),
|
||||
action,gen.getState());*/
|
||||
|
||||
switch(result)
|
||||
{
|
||||
case NEED_HEADER:
|
||||
header=BufferUtil.allocate(2048);
|
||||
break;
|
||||
|
||||
case NEED_BUFFER:
|
||||
buffer=BufferUtil.allocate(8192);
|
||||
break;
|
||||
|
||||
case NEED_CHUNK:
|
||||
header=null;
|
||||
chunk=BufferUtil.allocate(HttpGenerator.CHUNK_SIZE);
|
||||
break;
|
||||
|
||||
case FLUSH:
|
||||
{
|
||||
Future<Integer> future = _connection.getEndPoint().flush(header,chunk,buffer);
|
||||
future.get(getMaxIdleTime(),TimeUnit.MILLISECONDS);
|
||||
break;
|
||||
_connection.write(ByteBuffer.wrap(new byte[]{(byte)b}));
|
||||
}
|
||||
case FLUSH_CONTENT:
|
||||
{
|
||||
Future<Integer> future = _connection.getEndPoint().flush(header,chunk,content);
|
||||
future.get(getMaxIdleTime(),TimeUnit.MILLISECONDS);
|
||||
break;
|
||||
}
|
||||
case OK:
|
||||
break;
|
||||
case SHUTDOWN_OUT:
|
||||
_connection.getEndPoint().shutdownOutput();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
catch(final TimeoutException e)
|
||||
{
|
||||
throw new InterruptedIOException(e.toString())
|
||||
{
|
||||
{
|
||||
this.initCause(e);
|
||||
}
|
||||
};
|
||||
}
|
||||
catch (final InterruptedException e)
|
||||
{
|
||||
throw new InterruptedIOException(e.toString())
|
||||
{
|
||||
{
|
||||
this.initCause(e);
|
||||
}
|
||||
};
|
||||
}
|
||||
catch (final ExecutionException e)
|
||||
{
|
||||
throw new IOException(e.toString())
|
||||
{
|
||||
{
|
||||
this.initCause(e);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/*
|
||||
|
|
|
@ -17,7 +17,6 @@ import java.io.IOException;
|
|||
import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
|
||||
import org.eclipse.jetty.http.AbstractGenerator;
|
||||
import org.eclipse.jetty.util.ByteArrayOutputStream2;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
|
||||
|
@ -38,7 +37,6 @@ public class HttpWriter extends Writer
|
|||
private static final int WRITE_UTF8 = 2;
|
||||
|
||||
final HttpOutput _out;
|
||||
final AbstractGenerator _generator;
|
||||
int _writeMode;
|
||||
int _surrogate;
|
||||
|
||||
|
@ -46,7 +44,6 @@ public class HttpWriter extends Writer
|
|||
public HttpWriter(HttpOutput out)
|
||||
{
|
||||
_out=out;
|
||||
_generator=_out._generator;
|
||||
_surrogate=0; // AS lastUTF16CodePoint
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,10 @@ import java.io.InputStream;
|
|||
import java.io.InputStreamReader;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketAddress;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.Charset;
|
||||
import java.security.Principal;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
@ -114,52 +117,44 @@ import org.eclipse.jetty.util.log.Logger;
|
|||
*
|
||||
*
|
||||
*/
|
||||
public class Request implements HttpServletRequest, HttpGenerator.RequestInfo
|
||||
public class Request implements HttpServletRequest
|
||||
{
|
||||
public static final String __MULTIPART_CONFIG_ELEMENT = "org.eclipse.multipartConfig";
|
||||
private static final Logger LOG = Log.getLogger(Request.class);
|
||||
|
||||
private static final String __ASYNC_FWD = "org.eclipse.asyncfwd";
|
||||
private static final Collection __defaultLocale = Collections.singleton(Locale.getDefault());
|
||||
private static final Collection<Locale> __defaultLocale = Collections.singleton(Locale.getDefault());
|
||||
private static final int __NONE = 0, _STREAM = 1, __READER = 2;
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public static Request getRequest(HttpServletRequest request)
|
||||
{
|
||||
if (request instanceof Request)
|
||||
return (Request)request;
|
||||
private ServerConnection _connection;
|
||||
private HttpFields _fields;
|
||||
private final AsyncContinuation _async = new AsyncContinuation();
|
||||
|
||||
return AbstractHttpConnection.getCurrentConnection().getRequest();
|
||||
}
|
||||
protected final AsyncContinuation _async = new AsyncContinuation();
|
||||
private boolean _asyncSupported = true;
|
||||
private volatile Attributes _attributes;
|
||||
private Authentication _authentication;
|
||||
private MultiMap<String> _baseParameters;
|
||||
private String _characterEncoding;
|
||||
protected AbstractHttpConnection _connection;
|
||||
private ContextHandler.Context _context;
|
||||
private boolean _newContext;
|
||||
private String _contextPath;
|
||||
private CookieCutter _cookies;
|
||||
private boolean _cookiesExtracted = false;
|
||||
private DispatcherType _dispatcherType;
|
||||
private boolean _dns = false;
|
||||
private EndPoint _endp;
|
||||
private boolean _handled = false;
|
||||
private int _inputState = __NONE;
|
||||
private HttpMethod _httpMethod;
|
||||
private String _method;
|
||||
private MultiMap<String> _parameters;
|
||||
private boolean _paramsExtracted;
|
||||
private String _pathInfo;
|
||||
private int _port;
|
||||
private String _protocol = HttpVersion.HTTP_1_1.toString();
|
||||
private HttpVersion _httpVersion = HttpVersion.HTTP_1_1;
|
||||
private String _queryEncoding;
|
||||
private String _queryString;
|
||||
private BufferedReader _reader;
|
||||
private String _readerEncoding;
|
||||
private String _remoteAddr;
|
||||
private String _remoteHost;
|
||||
private InetSocketAddress _remote;
|
||||
private Object _requestAttributeListeners;
|
||||
private String _requestedSessionId;
|
||||
private boolean _requestedSessionIdFromCookie = false;
|
||||
|
@ -179,15 +174,13 @@ public class Request implements HttpServletRequest, HttpGenerator.RequestInfo
|
|||
|
||||
private MultiPartInputStream _multiPartInputStream; //if the request is a multi-part mime
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public Request()
|
||||
{
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public Request(AbstractHttpConnection connection)
|
||||
public Request(ServerConnection connection)
|
||||
{
|
||||
setConnection(connection);
|
||||
_connection = connection;
|
||||
_fields=_connection.getRequestFields();
|
||||
_async.setConnection(connection);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -208,7 +201,7 @@ public class Request implements HttpServletRequest, HttpGenerator.RequestInfo
|
|||
public void extractParameters()
|
||||
{
|
||||
if (_baseParameters == null)
|
||||
_baseParameters = new MultiMap(16);
|
||||
_baseParameters = new MultiMap<String>(16);
|
||||
|
||||
if (_paramsExtracted)
|
||||
{
|
||||
|
@ -267,10 +260,10 @@ public class Request implements HttpServletRequest, HttpGenerator.RequestInfo
|
|||
}
|
||||
else
|
||||
{
|
||||
Number size = (Number)_connection.getConnector().getServer()
|
||||
Number size = (Number)_connection.getServer()
|
||||
.getAttribute("org.eclipse.jetty.server.Request.maxFormContentSize");
|
||||
maxFormContentSize = size == null?200000:size.intValue();
|
||||
Number keys = (Number)_connection.getConnector().getServer().getAttribute("org.eclipse.jetty.server.Request.maxFormKeys");
|
||||
Number keys = (Number)_connection.getServer().getAttribute("org.eclipse.jetty.server.Request.maxFormKeys");
|
||||
maxFormKeys = keys == null?1000:keys.intValue();
|
||||
}
|
||||
|
||||
|
@ -339,7 +332,7 @@ public class Request implements HttpServletRequest, HttpGenerator.RequestInfo
|
|||
public Object getAttribute(String name)
|
||||
{
|
||||
if ("org.eclipse.jetty.io.EndPoint.maxIdleTime".equalsIgnoreCase(name))
|
||||
return new Long(getConnection().getEndPoint().getMaxIdleTime());
|
||||
return new Long(_connection.getMaxIdleTime());
|
||||
|
||||
Object attr = (_attributes == null)?null:_attributes.getAttribute(name);
|
||||
if (attr == null && Continuation.ATTRIBUTE.equals(name))
|
||||
|
@ -407,7 +400,7 @@ public class Request implements HttpServletRequest, HttpGenerator.RequestInfo
|
|||
/**
|
||||
* @return Returns the connection.
|
||||
*/
|
||||
public AbstractHttpConnection getConnection()
|
||||
public ServerConnection getConnection()
|
||||
{
|
||||
return _connection;
|
||||
}
|
||||
|
@ -418,16 +411,7 @@ public class Request implements HttpServletRequest, HttpGenerator.RequestInfo
|
|||
*/
|
||||
public int getContentLength()
|
||||
{
|
||||
return (int)_connection.getRequestFields().getLongField(HttpHeader.CONTENT_LENGTH.toString());
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public long getContentRead()
|
||||
{
|
||||
if (_connection == null || _connection.getParser() == null)
|
||||
return -1;
|
||||
|
||||
return ((HttpParser)_connection.getParser()).getContentRead();
|
||||
return (int)_fields.getLongField(HttpHeader.CONTENT_LENGTH.toString());
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -436,7 +420,7 @@ public class Request implements HttpServletRequest, HttpGenerator.RequestInfo
|
|||
*/
|
||||
public String getContentType()
|
||||
{
|
||||
return _connection.getRequestFields().getStringField(HttpHeader.CONTENT_TYPE);
|
||||
return _fields.getStringField(HttpHeader.CONTENT_TYPE);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -468,7 +452,7 @@ public class Request implements HttpServletRequest, HttpGenerator.RequestInfo
|
|||
|
||||
_cookiesExtracted = true;
|
||||
|
||||
Enumeration enm = _connection.getRequestFields().getValues(HttpHeader.COOKIE.toString());
|
||||
Enumeration enm = _fields.getValues(HttpHeader.COOKIE.toString());
|
||||
|
||||
// Handle no cookies
|
||||
if (enm != null)
|
||||
|
@ -492,7 +476,7 @@ public class Request implements HttpServletRequest, HttpGenerator.RequestInfo
|
|||
*/
|
||||
public long getDateHeader(String name)
|
||||
{
|
||||
return _connection.getRequestFields().getDateField(name);
|
||||
return _fields.getDateField(name);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -507,7 +491,7 @@ public class Request implements HttpServletRequest, HttpGenerator.RequestInfo
|
|||
*/
|
||||
public String getHeader(String name)
|
||||
{
|
||||
return _connection.getRequestFields().getStringField(name);
|
||||
return _fields.getStringField(name);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -516,7 +500,7 @@ public class Request implements HttpServletRequest, HttpGenerator.RequestInfo
|
|||
*/
|
||||
public Enumeration getHeaderNames()
|
||||
{
|
||||
return _connection.getRequestFields().getFieldNames();
|
||||
return _fields.getFieldNames();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -525,7 +509,7 @@ public class Request implements HttpServletRequest, HttpGenerator.RequestInfo
|
|||
*/
|
||||
public Enumeration getHeaders(String name)
|
||||
{
|
||||
Enumeration e = _connection.getRequestFields().getValues(name);
|
||||
Enumeration e = _fields.getValues(name);
|
||||
if (e == null)
|
||||
return Collections.enumeration(Collections.EMPTY_LIST);
|
||||
return e;
|
||||
|
@ -558,17 +542,9 @@ public class Request implements HttpServletRequest, HttpGenerator.RequestInfo
|
|||
*/
|
||||
public int getIntHeader(String name)
|
||||
{
|
||||
return (int)_connection.getRequestFields().getLongField(name);
|
||||
return (int)_fields.getLongField(name);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/*
|
||||
* @see javax.servlet.ServletRequest#getLocalAddr()
|
||||
*/
|
||||
public String getLocalAddr()
|
||||
{
|
||||
return _endp == null?null:_endp.getLocalAddr();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/*
|
||||
|
@ -576,7 +552,7 @@ public class Request implements HttpServletRequest, HttpGenerator.RequestInfo
|
|||
*/
|
||||
public Locale getLocale()
|
||||
{
|
||||
Enumeration enm = _connection.getRequestFields().getValues(HttpHeader.ACCEPT_LANGUAGE.toString(),HttpFields.__separators);
|
||||
Enumeration<String> enm = _fields.getValues(HttpHeader.ACCEPT_LANGUAGE.toString(),HttpFields.__separators);
|
||||
|
||||
// handle no locale
|
||||
if (enm == null || !enm.hasMoreElements())
|
||||
|
@ -613,14 +589,14 @@ public class Request implements HttpServletRequest, HttpGenerator.RequestInfo
|
|||
public Enumeration getLocales()
|
||||
{
|
||||
|
||||
Enumeration enm = _connection.getRequestFields().getValues(HttpHeader.ACCEPT_LANGUAGE.toString(),HttpFields.__separators);
|
||||
Enumeration<String> enm = _fields.getValues(HttpHeader.ACCEPT_LANGUAGE.toString(),HttpFields.__separators);
|
||||
|
||||
// handle no locale
|
||||
if (enm == null || !enm.hasMoreElements())
|
||||
return Collections.enumeration(__defaultLocale);
|
||||
|
||||
// sort the list in quality order
|
||||
List acceptLanguage = HttpFields.qualityList(enm);
|
||||
List<String> acceptLanguage = HttpFields.qualityList(enm);
|
||||
|
||||
if (acceptLanguage.size() == 0)
|
||||
return Collections.enumeration(__defaultLocale);
|
||||
|
@ -650,21 +626,24 @@ public class Request implements HttpServletRequest, HttpGenerator.RequestInfo
|
|||
return Collections.enumeration(LazyList.getList(langs));
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/*
|
||||
* @see javax.servlet.ServletRequest#getLocalAddr()
|
||||
*/
|
||||
public String getLocalAddr()
|
||||
{
|
||||
InetSocketAddress local=_connection.getLocalAddress();
|
||||
return local.getAddress().getHostAddress();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/*
|
||||
* @see javax.servlet.ServletRequest#getLocalName()
|
||||
*/
|
||||
public String getLocalName()
|
||||
{
|
||||
if (_endp == null)
|
||||
return null;
|
||||
if (_dns)
|
||||
return _endp.getLocalHost();
|
||||
|
||||
String local = _endp.getLocalAddr();
|
||||
if (local != null && local.indexOf(':') >= 0)
|
||||
local = "[" + local + "]";
|
||||
return local;
|
||||
InetSocketAddress local=_connection.getLocalAddress();
|
||||
return local.getHostString();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -673,7 +652,8 @@ public class Request implements HttpServletRequest, HttpGenerator.RequestInfo
|
|||
*/
|
||||
public int getLocalPort()
|
||||
{
|
||||
return _endp == null?0:_endp.getLocalPort();
|
||||
InetSocketAddress local=_connection.getLocalAddress();
|
||||
return local.getPort();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -712,7 +692,7 @@ public class Request implements HttpServletRequest, HttpGenerator.RequestInfo
|
|||
/*
|
||||
* @see javax.servlet.ServletRequest#getParameterNames()
|
||||
*/
|
||||
public Enumeration getParameterNames()
|
||||
public Enumeration<String> getParameterNames()
|
||||
{
|
||||
if (!_paramsExtracted)
|
||||
extractParameters();
|
||||
|
@ -768,7 +748,16 @@ public class Request implements HttpServletRequest, HttpGenerator.RequestInfo
|
|||
*/
|
||||
public String getProtocol()
|
||||
{
|
||||
return _protocol;
|
||||
return _httpVersion.toString();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/*
|
||||
* @see javax.servlet.ServletRequest#getProtocol()
|
||||
*/
|
||||
public HttpVersion getHttpVersion()
|
||||
{
|
||||
return _httpVersion;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -843,9 +832,10 @@ public class Request implements HttpServletRequest, HttpGenerator.RequestInfo
|
|||
*/
|
||||
public String getRemoteAddr()
|
||||
{
|
||||
if (_remoteAddr != null)
|
||||
return _remoteAddr;
|
||||
return _endp == null?null:_endp.getRemoteAddr();
|
||||
InetSocketAddress remote=_remote;
|
||||
if (remote==null)
|
||||
remote=_connection.getRemoteAddress();
|
||||
return remote==null?"":remote.getAddress().getHostAddress();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -854,15 +844,10 @@ public class Request implements HttpServletRequest, HttpGenerator.RequestInfo
|
|||
*/
|
||||
public String getRemoteHost()
|
||||
{
|
||||
if (_dns)
|
||||
{
|
||||
if (_remoteHost != null)
|
||||
{
|
||||
return _remoteHost;
|
||||
}
|
||||
return _endp == null?null:_endp.getRemoteHost();
|
||||
}
|
||||
return getRemoteAddr();
|
||||
InetSocketAddress remote=_remote;
|
||||
if (remote==null)
|
||||
remote=_connection.getRemoteAddress();
|
||||
return remote==null?"":remote.getHostString();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -871,7 +856,10 @@ public class Request implements HttpServletRequest, HttpGenerator.RequestInfo
|
|||
*/
|
||||
public int getRemotePort()
|
||||
{
|
||||
return _endp == null?0:_endp.getRemotePort();
|
||||
InetSocketAddress remote=_remote;
|
||||
if (remote==null)
|
||||
remote=_connection.getRemoteAddress();
|
||||
return remote==null?0:remote.getPort();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -1020,7 +1008,7 @@ public class Request implements HttpServletRequest, HttpGenerator.RequestInfo
|
|||
return _serverName;
|
||||
|
||||
// Return host from header field
|
||||
String hostPort = _connection.getRequestFields().getStringField(HttpHeader.HOST);
|
||||
String hostPort = _fields.getStringField(HttpHeader.HOST);
|
||||
if (hostPort != null)
|
||||
{
|
||||
loop: for (int i = hostPort.length(); i-- > 0;)
|
||||
|
@ -1042,7 +1030,7 @@ public class Request implements HttpServletRequest, HttpGenerator.RequestInfo
|
|||
try
|
||||
{
|
||||
if (_connection != null)
|
||||
_connection._generator.sendError(HttpStatus.BAD_REQUEST_400,"Bad Host header",null,true);
|
||||
_connection.sendError(HttpStatus.BAD_REQUEST_400,"Bad Host header",null,true);
|
||||
}
|
||||
catch (IOException e1)
|
||||
{
|
||||
|
@ -1099,7 +1087,10 @@ public class Request implements HttpServletRequest, HttpGenerator.RequestInfo
|
|||
if (_serverName != null && _uri != null)
|
||||
_port = _uri.getPort();
|
||||
else
|
||||
_port = _endp == null?0:_endp.getLocalPort();
|
||||
{
|
||||
InetSocketAddress local = _connection.getLocalAddress();
|
||||
_port = local == null?0:local.getPort();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1202,19 +1193,6 @@ public class Request implements HttpServletRequest, HttpGenerator.RequestInfo
|
|||
return _timeStamp;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Get Request TimeStamp
|
||||
*
|
||||
* @return The time that the request was received.
|
||||
*/
|
||||
public ByteBuffer getTimeStampBuffer()
|
||||
{
|
||||
if (_timeStampBuffer == null && _timeStamp > 0)
|
||||
_timeStampBuffer = HttpFields.__dateCache.formatBuffer(_timeStamp);
|
||||
return _timeStampBuffer;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @return Returns the uri.
|
||||
|
@ -1405,7 +1383,7 @@ public class Request implements HttpServletRequest, HttpGenerator.RequestInfo
|
|||
_method = null;
|
||||
_pathInfo = null;
|
||||
_port = 0;
|
||||
_protocol = HttpVersion.HTTP_1_1.toString();
|
||||
_httpVersion = HttpVersion.HTTP_1_1;
|
||||
_queryEncoding = null;
|
||||
_queryString = null;
|
||||
_requestedSessionId = null;
|
||||
|
@ -1429,6 +1407,7 @@ public class Request implements HttpServletRequest, HttpGenerator.RequestInfo
|
|||
_savedNewSessions.clear();
|
||||
_savedNewSessions=null;
|
||||
_multiPartInputStream = null;
|
||||
_remote=null;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -1524,17 +1503,6 @@ public class Request implements HttpServletRequest, HttpGenerator.RequestInfo
|
|||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
else if ("org.eclipse.jetty.io.EndPoint.maxIdleTime".equalsIgnoreCase(name))
|
||||
{
|
||||
try
|
||||
{
|
||||
getConnection().getEndPoint().setMaxIdleTime(Integer.valueOf(value.toString()));
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_attributes == null)
|
||||
|
@ -1598,8 +1566,7 @@ public class Request implements HttpServletRequest, HttpGenerator.RequestInfo
|
|||
|
||||
// check encoding is supported
|
||||
if (!StringUtil.isUTF8(encoding))
|
||||
// noinspection ResultOfMethodCallIgnored
|
||||
"".getBytes(encoding);
|
||||
Charset.forName(encoding);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -1615,10 +1582,6 @@ public class Request implements HttpServletRequest, HttpGenerator.RequestInfo
|
|||
// final so we can safely call this from constructor
|
||||
protected final void setConnection(AbstractHttpConnection connection)
|
||||
{
|
||||
_connection = connection;
|
||||
_async.setConnection(connection);
|
||||
_endp = connection.getEndPoint();
|
||||
_dns = connection.getResolveNames();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -1627,7 +1590,7 @@ public class Request implements HttpServletRequest, HttpGenerator.RequestInfo
|
|||
*/
|
||||
public void setContentType(String contentType)
|
||||
{
|
||||
_connection.getRequestFields().put(HttpHeader.CONTENT_TYPE,contentType);
|
||||
_fields.put(HttpHeader.CONTENT_TYPE,contentType);
|
||||
|
||||
}
|
||||
|
||||
|
@ -1696,11 +1659,18 @@ public class Request implements HttpServletRequest, HttpGenerator.RequestInfo
|
|||
* @param method
|
||||
* The method to set.
|
||||
*/
|
||||
public void setMethod(String method)
|
||||
public void setMethod(HttpMethod httpMethod, String method)
|
||||
{
|
||||
_httpMethod=httpMethod;
|
||||
_method = method;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public boolean isHead()
|
||||
{
|
||||
return HttpMethod.HEAD==_httpMethod;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @param parameters
|
||||
|
@ -1725,12 +1695,12 @@ public class Request implements HttpServletRequest, HttpGenerator.RequestInfo
|
|||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @param protocol
|
||||
* @param version
|
||||
* The protocol to set.
|
||||
*/
|
||||
public void setProtocol(String protocol)
|
||||
public void setHttpVersion(HttpVersion version)
|
||||
{
|
||||
_protocol = protocol;
|
||||
_httpVersion = version;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -1763,19 +1733,9 @@ public class Request implements HttpServletRequest, HttpGenerator.RequestInfo
|
|||
* @param addr
|
||||
* The address to set.
|
||||
*/
|
||||
public void setRemoteAddr(String addr)
|
||||
public void setRemoteAddr(InetSocketAddress addr)
|
||||
{
|
||||
_remoteAddr = addr;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @param host
|
||||
* The host to set.
|
||||
*/
|
||||
public void setRemoteHost(String host)
|
||||
{
|
||||
_remoteHost = host;
|
||||
_remote = addr;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
|
|
@ -53,11 +53,7 @@ public class Response implements HttpServletResponse
|
|||
{
|
||||
private static final Logger LOG = Log.getLogger(Response.class);
|
||||
|
||||
|
||||
public static final int
|
||||
NONE=0,
|
||||
STREAM=1,
|
||||
WRITER=2;
|
||||
public enum Output {NONE,STREAM,WRITER}
|
||||
|
||||
/**
|
||||
* If a header name starts with this string, the header (stripped of the prefix)
|
||||
|
@ -72,24 +68,68 @@ public class Response implements HttpServletResponse
|
|||
*/
|
||||
public final static String HTTP_ONLY_COMMENT="__HTTP_ONLY__";
|
||||
|
||||
private final AbstractHttpConnection _connection;
|
||||
private final ServerConnection _connection;
|
||||
private final HttpFields _fields;
|
||||
private int _status=SC_OK;
|
||||
private String _reason;
|
||||
private Locale _locale;
|
||||
private String _mimeType;
|
||||
private MimeTypes.Type _mimeType;
|
||||
private String _characterEncoding;
|
||||
private boolean _explicitEncoding;
|
||||
private String _contentType;
|
||||
private volatile int _outputState;
|
||||
private Output _outputState;
|
||||
private PrintWriter _writer;
|
||||
private long _contentLength;
|
||||
|
||||
|
||||
private final HttpGenerator.ResponseInfo _info = new HttpGenerator.ResponseInfo()
|
||||
{
|
||||
@Override
|
||||
public HttpVersion getHttpVersion()
|
||||
{
|
||||
return _connection.getRequest().getHttpVersion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpFields getHttpFields()
|
||||
{
|
||||
return _fields;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getContentLength()
|
||||
{
|
||||
return _contentLength;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHead()
|
||||
{
|
||||
return _connection.getRequest().isHead();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStatus()
|
||||
{
|
||||
return _status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getReason()
|
||||
{
|
||||
return _reason;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public Response(AbstractHttpConnection connection)
|
||||
public Response(ServerConnection connection)
|
||||
{
|
||||
_connection=connection;
|
||||
_fields=connection.getResponseFields();
|
||||
}
|
||||
|
||||
|
||||
|
@ -104,10 +144,9 @@ public class Response implements HttpServletResponse
|
|||
_locale=null;
|
||||
_mimeType=null;
|
||||
_characterEncoding=null;
|
||||
_explicitEncoding=false;
|
||||
_contentType=null;
|
||||
_writer=null;
|
||||
_outputState=NONE;
|
||||
_outputState=Output.NONE;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -116,7 +155,7 @@ public class Response implements HttpServletResponse
|
|||
*/
|
||||
public void addCookie(HttpCookie cookie)
|
||||
{
|
||||
_connection.getResponseFields().addSetCookie(cookie);
|
||||
_fields.addSetCookie(cookie);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -139,7 +178,7 @@ public class Response implements HttpServletResponse
|
|||
comment=null;
|
||||
}
|
||||
}
|
||||
_connection.getResponseFields().addSetCookie(cookie.getName(),
|
||||
_fields.addSetCookie(cookie.getName(),
|
||||
cookie.getValue(),
|
||||
cookie.getDomain(),
|
||||
cookie.getPath(),
|
||||
|
@ -156,7 +195,7 @@ public class Response implements HttpServletResponse
|
|||
*/
|
||||
public boolean containsHeader(String name)
|
||||
{
|
||||
return _connection.getResponseFields().containsKey(name);
|
||||
return _fields.containsKey(name);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -300,7 +339,7 @@ public class Response implements HttpServletResponse
|
|||
setHeader(HttpHeader.CONTENT_TYPE,null);
|
||||
setHeader(HttpHeader.CONTENT_LENGTH,null);
|
||||
|
||||
_outputState=NONE;
|
||||
_outputState=Output.NONE;
|
||||
setStatus(code,message);
|
||||
|
||||
if (message==null)
|
||||
|
@ -319,7 +358,7 @@ public class Response implements HttpServletResponse
|
|||
if (context!=null)
|
||||
error_handler=context.getContextHandler().getErrorHandler();
|
||||
if (error_handler==null)
|
||||
error_handler = _connection.getConnector().getServer().getBean(ErrorHandler.class);
|
||||
error_handler = _connection.getServer().getBean(ErrorHandler.class);
|
||||
if (error_handler!=null)
|
||||
{
|
||||
request.setAttribute(Dispatcher.ERROR_STATUS_CODE,new Integer(code));
|
||||
|
@ -407,7 +446,7 @@ public class Response implements HttpServletResponse
|
|||
public void sendProcessing() throws IOException
|
||||
{
|
||||
if (_connection.isExpecting102Processing() && !isCommitted())
|
||||
((HttpGenerator)_connection.getGenerator()).send1xx(HttpStatus.PROCESSING_102);
|
||||
_connection.send1xx(HttpStatus.PROCESSING_102);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -477,7 +516,7 @@ public class Response implements HttpServletResponse
|
|||
public void setDateHeader(String name, long date)
|
||||
{
|
||||
if (!_connection.isIncluding())
|
||||
_connection.getResponseFields().putDateField(name, date);
|
||||
_fields.putDateField(name, date);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -487,7 +526,7 @@ public class Response implements HttpServletResponse
|
|||
public void addDateHeader(String name, long date)
|
||||
{
|
||||
if (!_connection.isIncluding())
|
||||
_connection.getResponseFields().addDateField(name, date);
|
||||
_fields.addDateField(name, date);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -503,14 +542,14 @@ public class Response implements HttpServletResponse
|
|||
if (_connection.isIncluding())
|
||||
return;
|
||||
|
||||
_connection.getResponseFields().put(name, value);
|
||||
_fields.put(name, value);
|
||||
|
||||
if (HttpHeader.CONTENT_LENGTH==name)
|
||||
{
|
||||
if (value==null)
|
||||
_connection._generator.setContentLength(-1);
|
||||
_contentLength=-1l;
|
||||
else
|
||||
_connection._generator.setContentLength(Long.parseLong(value));
|
||||
_contentLength=Long.parseLong(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -531,13 +570,13 @@ public class Response implements HttpServletResponse
|
|||
else
|
||||
return;
|
||||
}
|
||||
_connection.getResponseFields().put(name, value);
|
||||
_fields.put(name, value);
|
||||
if (HttpHeader.CONTENT_LENGTH.is(name))
|
||||
{
|
||||
if (value==null)
|
||||
_connection._generator.setContentLength(-1);
|
||||
_contentLength=-1l;
|
||||
else
|
||||
_connection._generator.setContentLength(Long.parseLong(value));
|
||||
_contentLength=Long.parseLong(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -546,7 +585,7 @@ public class Response implements HttpServletResponse
|
|||
/* ------------------------------------------------------------ */
|
||||
public Collection<String> getHeaderNames()
|
||||
{
|
||||
final HttpFields fields=_connection.getResponseFields();
|
||||
final HttpFields fields=_fields;
|
||||
return fields.getFieldNamesCollection();
|
||||
}
|
||||
|
||||
|
@ -555,7 +594,7 @@ public class Response implements HttpServletResponse
|
|||
*/
|
||||
public String getHeader(String name)
|
||||
{
|
||||
return _connection.getResponseFields().getStringField(name);
|
||||
return _fields.getStringField(name);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -563,7 +602,7 @@ public class Response implements HttpServletResponse
|
|||
*/
|
||||
public Collection<String> getHeaders(String name)
|
||||
{
|
||||
final HttpFields fields=_connection.getResponseFields();
|
||||
final HttpFields fields=_fields;
|
||||
Collection<String> i = fields.getValuesCollection(name);
|
||||
if (i==null)
|
||||
return Collections.EMPTY_LIST;
|
||||
|
@ -584,9 +623,14 @@ public class Response implements HttpServletResponse
|
|||
return;
|
||||
}
|
||||
|
||||
_connection.getResponseFields().add(name, value);
|
||||
_fields.add(name, value);
|
||||
if (HttpHeader.CONTENT_LENGTH.is(name))
|
||||
_connection._generator.setContentLength(Long.parseLong(value));
|
||||
{
|
||||
if (value==null)
|
||||
_contentLength=-1l;
|
||||
else
|
||||
_contentLength=Long.parseLong(value);
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -597,9 +641,9 @@ public class Response implements HttpServletResponse
|
|||
{
|
||||
if (!_connection.isIncluding())
|
||||
{
|
||||
_connection.getResponseFields().putLongField(name, value);
|
||||
_fields.putLongField(name, value);
|
||||
if (HttpHeader.CONTENT_LENGTH.is(name))
|
||||
_connection._generator.setContentLength(value);
|
||||
_contentLength=value;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -611,9 +655,9 @@ public class Response implements HttpServletResponse
|
|||
{
|
||||
if (!_connection.isIncluding())
|
||||
{
|
||||
_connection.getResponseFields().addLongField(name, value);
|
||||
_fields.add(name, Integer.toString(value));
|
||||
if (HttpHeader.CONTENT_LENGTH.is(name))
|
||||
_connection._generator.setContentLength(value);
|
||||
_contentLength=value;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -673,24 +717,24 @@ public class Response implements HttpServletResponse
|
|||
*/
|
||||
public ServletOutputStream getOutputStream() throws IOException
|
||||
{
|
||||
if (_outputState!=NONE && _outputState!=STREAM)
|
||||
if (_outputState==Output.WRITER)
|
||||
throw new IllegalStateException("WRITER");
|
||||
|
||||
ServletOutputStream out = _connection.getOutputStream();
|
||||
_outputState=STREAM;
|
||||
_outputState=Output.STREAM;
|
||||
return out;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public boolean isWriting()
|
||||
{
|
||||
return _outputState==WRITER;
|
||||
return _outputState==Output.WRITER;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public boolean isOutputing()
|
||||
{
|
||||
return _outputState!=NONE;
|
||||
return _outputState!=Output.NONE;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -699,7 +743,7 @@ public class Response implements HttpServletResponse
|
|||
*/
|
||||
public PrintWriter getWriter() throws IOException
|
||||
{
|
||||
if (_outputState!=NONE && _outputState!=WRITER)
|
||||
if (_outputState==Output.STREAM)
|
||||
throw new IllegalStateException("STREAM");
|
||||
|
||||
/* if there is no writer yet */
|
||||
|
@ -719,71 +763,10 @@ public class Response implements HttpServletResponse
|
|||
/* construct Writer using correct encoding */
|
||||
_writer = _connection.getPrintWriter(encoding);
|
||||
}
|
||||
_outputState=WRITER;
|
||||
_outputState=Output.WRITER;
|
||||
return _writer;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/*
|
||||
* @see javax.servlet.ServletResponse#setCharacterEncoding(java.lang.String)
|
||||
*/
|
||||
public void setCharacterEncoding(String encoding)
|
||||
{
|
||||
if (_connection.isIncluding())
|
||||
return;
|
||||
|
||||
if (this._outputState==0 && !isCommitted())
|
||||
{
|
||||
_explicitEncoding=true;
|
||||
|
||||
if (encoding==null)
|
||||
{
|
||||
// Clear any encoding.
|
||||
if (_characterEncoding!=null)
|
||||
{
|
||||
_characterEncoding=null;
|
||||
_connection.getResponseFields().put(HttpHeader.CONTENT_TYPE,_mimeType);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// No, so just add this one to the mimetype
|
||||
_characterEncoding=encoding;
|
||||
if (_contentType!=null)
|
||||
{
|
||||
int i0=_contentType.indexOf(';');
|
||||
if (i0<0)
|
||||
{
|
||||
_contentType=null;
|
||||
|
||||
if (_contentType==null)
|
||||
{
|
||||
_contentType = _mimeType+";charset="+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= ");
|
||||
_connection.getResponseFields().put(HttpHeader.CONTENT_TYPE,_contentType);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int i1=_contentType.indexOf("charset=",i0);
|
||||
if (i1<0)
|
||||
{
|
||||
_contentType = _contentType+";charset="+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= ");
|
||||
}
|
||||
else
|
||||
{
|
||||
int i8=i1+8;
|
||||
int i2=_contentType.indexOf(" ",i8);
|
||||
if (i2<0)
|
||||
_contentType=_contentType.substring(0,i8)+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= ");
|
||||
else
|
||||
_contentType=_contentType.substring(0,i8)+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= ")+_contentType.substring(i2);
|
||||
}
|
||||
_connection.getResponseFields().put(HttpHeader.CONTENT_TYPE,_contentType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/*
|
||||
|
@ -796,16 +779,18 @@ public class Response implements HttpServletResponse
|
|||
// if the getHandling committed the response!
|
||||
if (isCommitted() || _connection.isIncluding())
|
||||
return;
|
||||
_connection._generator.setContentLength(len);
|
||||
_contentLength=len;
|
||||
if (len>=0)
|
||||
{
|
||||
_connection.getResponseFields().putLongField(HttpHeader.CONTENT_LENGTH, len);
|
||||
if (_connection._generator.isAllContentWritten())
|
||||
_fields.putLongField(HttpHeader.CONTENT_LENGTH.toString(), (long)len);
|
||||
if (_connection.isAllContentWritten())
|
||||
{
|
||||
if (_outputState==WRITER)
|
||||
switch(_outputState)
|
||||
{
|
||||
case WRITER:
|
||||
_writer.close();
|
||||
else if (_outputState==STREAM)
|
||||
{
|
||||
break;
|
||||
case STREAM:
|
||||
try
|
||||
{
|
||||
getOutputStream().close();
|
||||
|
@ -830,8 +815,45 @@ public class Response implements HttpServletResponse
|
|||
// if the getHandling committed the response!
|
||||
if (isCommitted() || _connection.isIncluding())
|
||||
return;
|
||||
_connection._generator.setContentLength(len);
|
||||
_connection.getResponseFields().putLongField(HttpHeader.CONTENT_LENGTH, len);
|
||||
_contentLength=len;
|
||||
_fields.putLongField(HttpHeader.CONTENT_LENGTH.toString(), len);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/*
|
||||
* @see javax.servlet.ServletResponse#setCharacterEncoding(java.lang.String)
|
||||
*/
|
||||
public void setCharacterEncoding(String encoding)
|
||||
{
|
||||
if (_connection.isIncluding())
|
||||
return;
|
||||
|
||||
if (_outputState==Output.NONE && !isCommitted())
|
||||
{
|
||||
if (encoding==null)
|
||||
{
|
||||
// Clear any encoding.
|
||||
if (_characterEncoding!=null)
|
||||
{
|
||||
_characterEncoding=null;
|
||||
if (_contentType!=null)
|
||||
{
|
||||
_contentType=MimeTypes.getContentTypeWithoutCharset(_contentType);
|
||||
_fields.put(HttpHeader.CONTENT_TYPE,_contentType);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// No, so just add this one to the mimetype
|
||||
_characterEncoding=encoding;
|
||||
if (_contentType!=null)
|
||||
{
|
||||
_contentType=MimeTypes.getContentTypeWithoutCharset(_contentType)+";charset="+encoding;
|
||||
_fields.put(HttpHeader.CONTENT_TYPE,_contentType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -843,159 +865,29 @@ public class Response implements HttpServletResponse
|
|||
if (isCommitted() || _connection.isIncluding())
|
||||
return;
|
||||
|
||||
// Yes this method is horribly complex.... but there are lots of special cases and
|
||||
// as this method is called on every request, it is worth trying to save string creation.
|
||||
//
|
||||
|
||||
if (contentType==null)
|
||||
{
|
||||
if (_locale==null)
|
||||
_characterEncoding=null;
|
||||
_mimeType=null;
|
||||
_contentType=null;
|
||||
_connection.getResponseFields().remove(HttpHeader.CONTENT_TYPE);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Look for encoding in contentType
|
||||
int i0=contentType.indexOf(';');
|
||||
|
||||
if (i0>0)
|
||||
{
|
||||
// we have content type parameters
|
||||
|
||||
// Extract params off mimetype
|
||||
_mimeType=contentType.substring(0,i0).trim();
|
||||
MimeTypes.Type mime_type=MimeTypes.CACHE.get(_mimeType);
|
||||
|
||||
// Look for charset
|
||||
int i1=contentType.indexOf("charset=",i0+1);
|
||||
if (i1>=0)
|
||||
{
|
||||
_explicitEncoding=true;
|
||||
int i8=i1+8;
|
||||
int i2 = contentType.indexOf(' ',i8);
|
||||
|
||||
if (_outputState==WRITER)
|
||||
{
|
||||
// strip the charset and ignore;
|
||||
if ((i1==i0+1 && i2<0) || (i1==i0+2 && i2<0 && contentType.charAt(i0+1)==' '))
|
||||
{
|
||||
if (mime_type!=null)
|
||||
{
|
||||
CachedBuffer content_type = mime_type.getAssociate(_characterEncoding);
|
||||
if (content_type!=null)
|
||||
{
|
||||
_contentType=content_type.toString();
|
||||
_connection.getResponseFields().put(HttpHeader.CONTENT_TYPE,content_type);
|
||||
}
|
||||
else
|
||||
{
|
||||
_contentType=_mimeType+";charset="+_characterEncoding;
|
||||
_connection.getResponseFields().put(HttpHeader.CONTENT_TYPE,_contentType);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_contentType=_mimeType+";charset="+_characterEncoding;
|
||||
_connection.getResponseFields().put(HttpHeader.CONTENT_TYPE,_contentType);
|
||||
}
|
||||
}
|
||||
else if (i2<0)
|
||||
{
|
||||
_contentType=contentType.substring(0,i1)+";charset="+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= ");
|
||||
_connection.getResponseFields().put(HttpHeader.CONTENT_TYPE,_contentType);
|
||||
}
|
||||
else
|
||||
{
|
||||
_contentType=contentType.substring(0,i1)+contentType.substring(i2)+";charset="+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= ");
|
||||
_connection.getResponseFields().put(HttpHeader.CONTENT_TYPE,_contentType);
|
||||
}
|
||||
}
|
||||
else if ((i1==i0+1 && i2<0) || (i1==i0+2 && i2<0 && contentType.charAt(i0+1)==' '))
|
||||
{
|
||||
// The params are just the char encoding
|
||||
mime_type=MimeTypes.CACHE.get(_mimeType);
|
||||
_characterEncoding = QuotedStringTokenizer.unquote(contentType.substring(i8));
|
||||
|
||||
if (mime_type!=null)
|
||||
{
|
||||
CachedBuffer content_type = mime_type.getAssociate(_characterEncoding);
|
||||
if (content_type!=null)
|
||||
{
|
||||
_contentType=content_type.toString();
|
||||
_connection.getResponseFields().put(HttpHeader.CONTENT_TYPE,content_type);
|
||||
_fields.remove(HttpHeader.CONTENT_TYPE);
|
||||
}
|
||||
else
|
||||
{
|
||||
_contentType=contentType;
|
||||
_connection.getResponseFields().put(HttpHeader.CONTENT_TYPE,_contentType);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_contentType=contentType;
|
||||
_connection.getResponseFields().put(HttpHeader.CONTENT_TYPE,_contentType);
|
||||
}
|
||||
}
|
||||
else if (i2>0)
|
||||
{
|
||||
_characterEncoding = QuotedStringTokenizer.unquote(contentType.substring(i8,i2));
|
||||
_contentType=contentType;
|
||||
_connection.getResponseFields().put(HttpHeader.CONTENT_TYPE,_contentType);
|
||||
}
|
||||
else
|
||||
{
|
||||
_characterEncoding = QuotedStringTokenizer.unquote(contentType.substring(i8));
|
||||
_contentType=contentType;
|
||||
_connection.getResponseFields().put(HttpHeader.CONTENT_TYPE,_contentType);
|
||||
}
|
||||
}
|
||||
else // No encoding in the params.
|
||||
{
|
||||
mime_type=null;
|
||||
_contentType=_characterEncoding==null?contentType:contentType+";charset="+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= ");
|
||||
_connection.getResponseFields().put(HttpHeader.CONTENT_TYPE,_contentType);
|
||||
}
|
||||
}
|
||||
else // No params at all
|
||||
{
|
||||
_mimeType=contentType;
|
||||
_cachedMimeType=MimeTypes.CACHE.get(_mimeType);
|
||||
_mimeType=MimeTypes.CACHE.get(contentType);
|
||||
String charset=_mimeType==null?MimeTypes.getCharsetFromContentType(contentType):_mimeType.getCharset().toString();
|
||||
|
||||
if (_characterEncoding!=null)
|
||||
if (charset!=null)
|
||||
_characterEncoding=charset;
|
||||
else if (_characterEncoding!=null)
|
||||
{
|
||||
if (_cachedMimeType!=null)
|
||||
{
|
||||
CachedBuffer content_type = _cachedMimeType.getAssociate(_characterEncoding);
|
||||
if (content_type!=null)
|
||||
{
|
||||
_contentType=content_type.toString();
|
||||
_connection.getResponseFields().put(HttpHeader.CONTENT_TYPE,content_type);
|
||||
}
|
||||
else
|
||||
{
|
||||
_contentType=_mimeType+";charset="+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= ");
|
||||
_connection.getResponseFields().put(HttpHeader.CONTENT_TYPE,_contentType);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_contentType=contentType+";charset="+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= ");
|
||||
_connection.getResponseFields().put(HttpHeader.CONTENT_TYPE,_contentType);
|
||||
}
|
||||
}
|
||||
else if (_cachedMimeType!=null)
|
||||
{
|
||||
_contentType=_cachedMimeType.toString();
|
||||
_connection.getResponseFields().put(HttpHeader.CONTENT_TYPE,_cachedMimeType);
|
||||
}
|
||||
else
|
||||
{
|
||||
_contentType=contentType;
|
||||
_connection.getResponseFields().put(HttpHeader.CONTENT_TYPE,_contentType);
|
||||
}
|
||||
_contentType=contentType+";charset="+_characterEncoding;
|
||||
_mimeType=null;
|
||||
}
|
||||
|
||||
_fields.put(HttpHeader.CONTENT_TYPE,_contentType);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1005,9 +897,9 @@ public class Response implements HttpServletResponse
|
|||
*/
|
||||
public void setBufferSize(int size)
|
||||
{
|
||||
if (isCommitted() || getContentCount()>0)
|
||||
if (isCommitted())
|
||||
throw new IllegalStateException("Committed or content written");
|
||||
_connection.getGenerator().increaseContentBufferSize(size);
|
||||
_connection.increaseContentBufferSize(size);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -1016,7 +908,7 @@ public class Response implements HttpServletResponse
|
|||
*/
|
||||
public int getBufferSize()
|
||||
{
|
||||
return _connection.getGenerator().getContentBufferSize();
|
||||
return _connection.getContentBufferSize();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -1039,7 +931,7 @@ public class Response implements HttpServletResponse
|
|||
_status=200;
|
||||
_reason=null;
|
||||
|
||||
HttpFields response_fields=_connection.getResponseFields();
|
||||
HttpFields response_fields=_fields;
|
||||
|
||||
response_fields.clear();
|
||||
String connection=_connection.getRequestFields().getStringField(HttpHeader.CONNECTION);
|
||||
|
@ -1048,22 +940,22 @@ public class Response implements HttpServletResponse
|
|||
String[] values = connection.split(",");
|
||||
for (int i=0;values!=null && i<values.length;i++)
|
||||
{
|
||||
CachedBuffer cb = HttpHeaderValue.CACHE.get(values[0].trim());
|
||||
HttpHeaderValue cb = HttpHeaderValue.CACHE.get(values[0].trim());
|
||||
|
||||
if (cb!=null)
|
||||
{
|
||||
switch(cb.getOrdinal())
|
||||
switch(cb)
|
||||
{
|
||||
case HttpHeaderValue.CLOSE_ORDINAL:
|
||||
response_fields.put(HttpHeader.CONNECTION,HttpHeaderValue.CLOSE);
|
||||
case CLOSE:
|
||||
response_fields.put(HttpHeader.CONNECTION,HttpHeaderValue.CLOSE.toString());
|
||||
break;
|
||||
|
||||
case HttpHeaderValue.KEEP_ALIVE_ORDINAL:
|
||||
if (HttpVersion.HTTP_1_0.equalsIgnoreCase(_connection.getRequest().getProtocol()))
|
||||
response_fields.put(HttpHeader.CONNECTION,HttpHeaderValue.KEEP_ALIVE);
|
||||
case KEEP_ALIVE:
|
||||
if (HttpVersion.HTTP_1_0.is(_connection.getRequest().getProtocol()))
|
||||
response_fields.put(HttpHeader.CONNECTION,HttpHeaderValue.KEEP_ALIVE.toString());
|
||||
break;
|
||||
case HttpHeaderValue.TE_ORDINAL:
|
||||
response_fields.put(HttpHeader.CONNECTION,HttpHeaderValue.TE);
|
||||
case TE:
|
||||
response_fields.put(HttpHeader.CONNECTION,HttpHeaderValue.TE.toString());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1080,7 +972,7 @@ public class Response implements HttpServletResponse
|
|||
resetBuffer();
|
||||
|
||||
_writer=null;
|
||||
_outputState=NONE;
|
||||
_outputState=Output.NONE;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -1091,7 +983,7 @@ public class Response implements HttpServletResponse
|
|||
{
|
||||
if (isCommitted())
|
||||
throw new IllegalStateException("Committed");
|
||||
_connection.getGenerator().resetBuffer();
|
||||
_connection.resetBuffer();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -1114,9 +1006,9 @@ public class Response implements HttpServletResponse
|
|||
return;
|
||||
|
||||
_locale = locale;
|
||||
_connection.getResponseFields().put(HttpHeader.CONTENT_LANGUAGE,locale.toString().replace('_','-'));
|
||||
_fields.put(HttpHeader.CONTENT_LANGUAGE,locale.toString().replace('_','-'));
|
||||
|
||||
if (_explicitEncoding || _outputState!=0 )
|
||||
if (_outputState!=Output.NONE )
|
||||
return;
|
||||
|
||||
if (_connection.getRequest().getContext()==null)
|
||||
|
@ -1124,31 +1016,8 @@ public class Response implements HttpServletResponse
|
|||
|
||||
String charset = _connection.getRequest().getContext().getContextHandler().getLocaleEncoding(locale);
|
||||
|
||||
if (charset!=null && charset.length()>0)
|
||||
{
|
||||
_characterEncoding=charset;
|
||||
|
||||
/* get current MIME type from Content-Type header */
|
||||
String type=getContentType();
|
||||
if (type!=null)
|
||||
{
|
||||
_characterEncoding=charset;
|
||||
int semi=type.indexOf(';');
|
||||
if (semi<0)
|
||||
{
|
||||
_mimeType=type;
|
||||
_contentType= type += ";charset="+charset;
|
||||
}
|
||||
else
|
||||
{
|
||||
_mimeType=type.substring(0,semi);
|
||||
_contentType= _mimeType += ";charset="+charset;
|
||||
}
|
||||
|
||||
_cachedMimeType=MimeTypes.CACHE.get(_mimeType);
|
||||
_connection.getResponseFields().put(HttpHeader.CONTENT_TYPE,_contentType);
|
||||
}
|
||||
}
|
||||
if (charset!=null && charset.length()>0 && _characterEncoding==null)
|
||||
setCharacterEncoding(charset);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -1191,21 +1060,10 @@ public class Response implements HttpServletResponse
|
|||
_connection.completeResponse();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------- */
|
||||
/**
|
||||
* @return the number of bytes actually written in response body
|
||||
*/
|
||||
public long getContentCount()
|
||||
{
|
||||
if (_connection==null || _connection.getGenerator()==null)
|
||||
return -1;
|
||||
return _connection.getGenerator().getContentWritten();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public HttpFields getHttpFields()
|
||||
{
|
||||
return _connection.getResponseFields();
|
||||
return _fields;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -1213,7 +1071,7 @@ public class Response implements HttpServletResponse
|
|||
public String toString()
|
||||
{
|
||||
return "HTTP/1.1 "+_status+" "+ (_reason==null?"":_reason) +System.getProperty("line.separator")+
|
||||
_connection.getResponseFields().toString();
|
||||
_fields.toString();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
|
|
@ -335,7 +335,7 @@ public class Server extends HandlerWrapper implements Attributes
|
|||
* or after the entire request has been received (for short requests of known length), or
|
||||
* on the dispatch of an async request.
|
||||
*/
|
||||
public void handle(AbstractHttpConnection connection) throws IOException, ServletException
|
||||
public void handle(ServerConnection connection) throws IOException, ServletException
|
||||
{
|
||||
final String target=connection.getRequest().getPathInfo();
|
||||
final Request request=connection.getRequest();
|
||||
|
@ -357,7 +357,7 @@ public class Server extends HandlerWrapper implements Attributes
|
|||
* or after the entire request has been received (for short requests of known length), or
|
||||
* on the dispatch of an async request.
|
||||
*/
|
||||
public void handleAsync(AbstractHttpConnection connection) throws IOException, ServletException
|
||||
public void handleAsync(ServerConnection connection) throws IOException, ServletException
|
||||
{
|
||||
final AsyncContinuation async = connection.getRequest().getAsyncContinuation();
|
||||
final AsyncContinuation.AsyncEventState state = async.getAsyncEventState();
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,45 +0,0 @@
|
|||
// ========================================================================
|
||||
// Copyright (c) 2008-2009 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
|
||||
package org.eclipse.jetty.server;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.net.URLDecoder;
|
||||
import java.net.URLEncoder;
|
||||
|
||||
import org.eclipse.jetty.http.EncodedHttpURI;
|
||||
import org.junit.Test;
|
||||
|
||||
public class EncodedHttpURITest
|
||||
{
|
||||
@Test
|
||||
public void testNonURIAscii() throws Exception
|
||||
{
|
||||
String url = "http://www.foo.com/ma\u00F1ana";
|
||||
byte[] asISO = url.getBytes("ISO-8859-1");
|
||||
new String(asISO, "ISO-8859-1");
|
||||
|
||||
//use a non UTF-8 charset as the encoding and url-escape as per
|
||||
//http://www.w3.org/TR/html40/appendix/notes.html#non-ascii-chars
|
||||
String s = URLEncoder.encode(url, "ISO-8859-1");
|
||||
EncodedHttpURI uri = new EncodedHttpURI("ISO-8859-1");
|
||||
|
||||
//parse it, using the same encoding
|
||||
uri.parse(s);
|
||||
|
||||
//decode the url encoding
|
||||
String d = URLDecoder.decode(uri.getCompletePath(), "ISO-8859-1");
|
||||
assertEquals(url, d);
|
||||
}
|
||||
}
|
|
@ -21,12 +21,13 @@ import static org.junit.Assert.fail;
|
|||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.eclipse.jetty.http.HttpURI;
|
||||
import org.eclipse.jetty.io.ByteArrayBuffer;
|
||||
import org.eclipse.jetty.util.MultiMap;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.junit.Test;
|
||||
|
||||
public class HttpURITest
|
||||
|
@ -270,8 +271,9 @@ public class HttpURITest
|
|||
{
|
||||
try
|
||||
{
|
||||
ByteArrayBuffer buf = new ByteArrayBuffer(connect_tests[i][0]);
|
||||
uri.parseConnect(buf.array(),2,buf.length()-4);
|
||||
byte[] buf = connect_tests[i][0].getBytes(StringUtil.__UTF8);
|
||||
|
||||
uri.parseConnect(buf,2,buf.length-4);
|
||||
assertEquals("path"+i,connect_tests[i][1]+":"+connect_tests[i][2],uri.getPath());
|
||||
assertEquals("host"+i,connect_tests[i][1],uri.getHost());
|
||||
assertEquals("port"+i,Integer.parseInt(connect_tests[i][2]),uri.getPort());
|
||||
|
@ -282,4 +284,24 @@ public class HttpURITest
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNonURIAscii() throws Exception
|
||||
{
|
||||
String url = "http://www.foo.com/ma\u00F1ana";
|
||||
byte[] asISO = url.getBytes("ISO-8859-1");
|
||||
new String(asISO, "ISO-8859-1");
|
||||
|
||||
//use a non UTF-8 charset as the encoding and url-escape as per
|
||||
//http://www.w3.org/TR/html40/appendix/notes.html#non-ascii-chars
|
||||
String s = URLEncoder.encode(url, "ISO-8859-1");
|
||||
HttpURI uri = new HttpURI(Charset.forName("ISO-8859-1"));
|
||||
|
||||
//parse it, using the same encoding
|
||||
uri.parse(s);
|
||||
|
||||
//decode the url encoding
|
||||
String d = URLDecoder.decode(uri.getCompletePath(), "ISO-8859-1");
|
||||
assertEquals(url, d);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
package org.eclipse.jetty.util;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
|
||||
|
||||
|
@ -38,7 +39,7 @@ public class URIUtil
|
|||
public static final String HTTPS_COLON="https:";
|
||||
|
||||
// Use UTF-8 as per http://www.w3.org/TR/html40/appendix/notes.html#non-ascii-chars
|
||||
public static final String __CHARSET=System.getProperty("org.eclipse.jetty.util.URI.charset",StringUtil.__UTF8);
|
||||
public static final Charset __CHARSET=Charset.forName(System.getProperty("org.eclipse.jetty.util.URI.charset",StringUtil.__UTF8));
|
||||
|
||||
private URIUtil()
|
||||
{}
|
||||
|
@ -221,15 +222,7 @@ public class URIUtil
|
|||
|
||||
if (b>0)
|
||||
{
|
||||
String s;
|
||||
try
|
||||
{
|
||||
s=new String(bytes,0,b,__CHARSET);
|
||||
}
|
||||
catch (UnsupportedEncodingException e)
|
||||
{
|
||||
s=new String(bytes,0,b);
|
||||
}
|
||||
String s=new String(bytes,0,b,__CHARSET);
|
||||
s.getChars(0,s.length(),chars,n);
|
||||
n+=s.length();
|
||||
b=0;
|
||||
|
@ -243,15 +236,7 @@ public class URIUtil
|
|||
|
||||
if (b>0)
|
||||
{
|
||||
String s;
|
||||
try
|
||||
{
|
||||
s=new String(bytes,0,b,__CHARSET);
|
||||
}
|
||||
catch (UnsupportedEncodingException e)
|
||||
{
|
||||
s=new String(bytes,0,b);
|
||||
}
|
||||
String s=new String(bytes,0,b,__CHARSET);
|
||||
s.getChars(0,s.length(),chars,n);
|
||||
n+=s.length();
|
||||
}
|
||||
|
@ -295,8 +280,8 @@ public class URIUtil
|
|||
}
|
||||
|
||||
if (bytes==null)
|
||||
return StringUtil.toString(buf,offset,length,__CHARSET);
|
||||
return StringUtil.toString(bytes,0,n,__CHARSET);
|
||||
return new String(buf,offset,length,__CHARSET);
|
||||
return new String(bytes,0,n,__CHARSET);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -265,22 +265,11 @@ public class UrlEncoded extends MultiMap implements Cloneable
|
|||
* @param offset the offset within raw to decode from
|
||||
* @param length the length of the section to decode
|
||||
* @param map the {@link MultiMap} to populate
|
||||
* @param buffer the buffer to decode into
|
||||
*/
|
||||
public static void decodeUtf8To(byte[] raw,int offset, int length, MultiMap map)
|
||||
{
|
||||
decodeUtf8To(raw,offset,length,map,new Utf8StringBuilder());
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------- */
|
||||
/** Decoded parameters to Map.
|
||||
* @param raw the byte[] containing the encoded parameters
|
||||
* @param offset the offset within raw to decode from
|
||||
* @param length the length of the section to decode
|
||||
* @param map the {@link MultiMap} to populate
|
||||
* @param buffer the buffer to decode into
|
||||
*/
|
||||
public static void decodeUtf8To(byte[] raw,int offset, int length, MultiMap map,Utf8StringBuilder buffer)
|
||||
{
|
||||
Utf8StringBuilder buffer = new Utf8StringBuilder();
|
||||
synchronized(map)
|
||||
{
|
||||
String key = null;
|
||||
|
|
Loading…
Reference in New Issue