org.eclipse.jetty.http.HttpURI Maven / Gradle / Ivy
//
// ========================================================================
// Copyright (c) 1995-2015 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 java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import org.eclipse.jetty.util.MultiMap;
import org.eclipse.jetty.util.TypeUtil;
import org.eclipse.jetty.util.URIUtil;
import org.eclipse.jetty.util.UrlEncoded;
/* ------------------------------------------------------------ */
/** Http URI.
* Parse a HTTP URI from a string or byte array. Given a URI
* http://user@host:port/path/info;param?query#fragment
* this class will split it into the following undecoded optional elements:
* - {@link #getScheme()} - http:
* - {@link #getAuthority()} - //name@host:port
* - {@link #getHost()} - host
* - {@link #getPort()} - port
* - {@link #getPath()} - /path/info
* - {@link #getParam()} - param
* - {@link #getQuery()} - query
* - {@link #getFragment()} - fragment
*
*
* Any parameters will be returned from {@link #getPath()}, but are excluded from the
* return value of {@link #getDecodedPath()}. If there are multiple parameters, the
* {@link #getParam()} method returns only the last one.
*/
public class HttpURI
{
private enum State {
START,
HOST_OR_PATH,
SCHEME_OR_PATH,
HOST,
IPV6,
PORT,
PATH,
PARAM,
QUERY,
FRAGMENT,
ASTERISK};
private String _scheme;
private String _host;
private int _port;
private String _path;
private String _param;
private String _query;
private String _fragment;
String _uri;
String _decodedPath;
/* ------------------------------------------------------------ */
/**
* Construct a normalized URI.
* Port is not set if it is the default port.
* @param scheme the URI scheme
* @param host the URI hose
* @param port the URI port
* @param path the URI path
* @param param the URI param
* @param query the URI query
* @param fragment the URI fragment
* @return the normalized URI
*/
public static HttpURI createHttpURI(String scheme, String host, int port, String path, String param, String query, String fragment)
{
if (port==80 && HttpScheme.HTTP.is(scheme))
port=0;
if (port==443 && HttpScheme.HTTPS.is(scheme))
port=0;
return new HttpURI(scheme,host,port,path,param,query,fragment);
}
/* ------------------------------------------------------------ */
public HttpURI()
{
}
/* ------------------------------------------------------------ */
public HttpURI(String scheme, String host, int port, String path, String param, String query, String fragment)
{
_scheme = scheme;
_host = host;
_port = port;
_path = path;
_param = param;
_query = query;
_fragment = fragment;
}
/* ------------------------------------------------------------ */
public HttpURI(HttpURI uri)
{
this(uri._scheme,uri._host,uri._port,uri._path,uri._param,uri._query,uri._fragment);
}
/* ------------------------------------------------------------ */
public HttpURI(String uri)
{
parse(uri);
parse(State.START,uri,0,uri.length());
}
/* ------------------------------------------------------------ */
public HttpURI(URI uri)
{
_uri=null;
_scheme=uri.getScheme();
_host=uri.getHost();
_port=uri.getPort();
_path=uri.getRawPath();
_decodedPath=uri.getPath();
int p=_path.lastIndexOf(';');
if (p>=0)
_param=_path.substring(p+1);
_query=uri.getRawQuery();
_fragment=uri.getFragment();
_decodedPath=null;
}
/* ------------------------------------------------------------ */
public HttpURI(String scheme, String host, int port, String pathQuery)
{
_uri=null;
_scheme=scheme;
_host=host;
_port=port;
parse(State.PATH,pathQuery,0,pathQuery.length());
}
/* ------------------------------------------------------------ */
public void parse(String uri)
{
clear();
_uri=uri;
parse(State.START,uri,0,uri.length());
}
/* ------------------------------------------------------------ */
public void parse(String uri, int offset, int length)
{
clear();
int end=offset+length;
_uri=uri.substring(offset,end);
parse(State.START,uri,offset,end);
}
/* ------------------------------------------------------------ */
private void parse(State state, final String uri, final int offset, final int end)
{
boolean encoded=false;
int m=offset;
int p=0;
for (int i=offset; i0;
}
/* ------------------------------------------------------------ */
public String getFragment()
{
return _fragment;
}
/* ------------------------------------------------------------ */
public void decodeQueryTo(MultiMap parameters)
{
if (_query==_fragment)
return;
UrlEncoded.decodeUtf8To(_query,parameters);
}
/* ------------------------------------------------------------ */
public void decodeQueryTo(MultiMap parameters, String encoding) throws UnsupportedEncodingException
{
decodeQueryTo(parameters,Charset.forName(encoding));
}
/* ------------------------------------------------------------ */
public void decodeQueryTo(MultiMap parameters, Charset encoding) throws UnsupportedEncodingException
{
if (_query==_fragment)
return;
if (encoding==null || StandardCharsets.UTF_8.equals(encoding))
UrlEncoded.decodeUtf8To(_query,parameters);
else
UrlEncoded.decodeTo(_query,parameters,encoding);
}
/* ------------------------------------------------------------ */
public void clear()
{
_uri=null;
_scheme=null;
_host=null;
_port=-1;
_path=null;
_param=null;
_query=null;
_fragment=null;
_decodedPath=null;
}
/* ------------------------------------------------------------ */
public boolean isAbsolute()
{
return _scheme!=null && _scheme.length()>0;
}
/* ------------------------------------------------------------ */
@Override
public String toString()
{
if (_uri==null)
{
StringBuilder out = new StringBuilder();
if (_scheme!=null)
out.append(_scheme).append(':');
if (_host!=null)
out.append("//").append(_host);
if (_port>0)
out.append(':').append(_port);
if (_path!=null)
out.append(_path);
if (_query!=null)
out.append('?').append(_query);
if (_fragment!=null)
out.append('#').append(_fragment);
if (out.length()>0)
_uri=out.toString();
else
_uri="";
}
return _uri;
}
/* ------------------------------------------------------------ */
public boolean equals(Object o)
{
if (o==this)
return true;
if (!(o instanceof HttpURI))
return false;
return toString().equals(o.toString());
}
/* ------------------------------------------------------------ */
public void setScheme(String scheme)
{
_scheme=scheme;
_uri=null;
}
/* ------------------------------------------------------------ */
/**
* @param host the host
* @param port the port
*/
public void setAuthority(String host, int port)
{
_host=host;
_port=port;
_uri=null;
}
/* ------------------------------------------------------------ */
/**
* @param path the path
*/
public void setPath(String path)
{
_uri=null;
_path=path;
_decodedPath=null;
}
/* ------------------------------------------------------------ */
public void setPathQuery(String path)
{
_uri=null;
_path=null;
_decodedPath=null;
_param=null;
_fragment=null;
if (path!=null)
parse(State.PATH,path,0,path.length());
}
/* ------------------------------------------------------------ */
public void setQuery(String query)
{
_query=query;
_uri=null;
}
/* ------------------------------------------------------------ */
public URI toURI() throws URISyntaxException
{
return new URI(_scheme,null,_host,_port,_path,_query==null?null:UrlEncoded.decodeString(_query),_fragment);
}
/* ------------------------------------------------------------ */
public String getPathQuery()
{
if (_query==null)
return _path;
return _path+"?"+_query;
}
/* ------------------------------------------------------------ */
public String getAuthority()
{
if (_port>0)
return _host+":"+_port;
return _host;
}
}