001 package railo.commons.io.res.type.http; 002 003 import java.io.IOException; 004 import java.io.InputStream; 005 import java.net.URL; 006 007 import railo.commons.io.IOUtil; 008 import railo.commons.io.res.ContentType; 009 import railo.commons.io.res.Resource; 010 import railo.commons.io.res.ResourceProvider; 011 import railo.commons.io.res.util.ReadOnlyResourceSupport; 012 import railo.commons.io.res.util.ResourceUtil; 013 import railo.commons.lang.StringUtil; 014 import railo.commons.net.http.HTTPEngine; 015 import railo.commons.net.http.HTTPResponse; 016 import railo.commons.net.http.Header; 017 import railo.runtime.net.proxy.ProxyData; 018 import railo.runtime.net.proxy.ProxyDataImpl; 019 import railo.runtime.op.Caster; 020 021 022 public class HTTPResource extends ReadOnlyResourceSupport { 023 024 private final HTTPResourceProvider provider; 025 private final HTTPConnectionData data; 026 private final String path; 027 private final String name; 028 private HTTPResponse http; 029 030 031 public HTTPResource(HTTPResourceProvider provider, HTTPConnectionData data) { 032 this.provider=provider; 033 this.data=data; 034 035 String[] pathName=ResourceUtil.translatePathName(data.path); 036 this.path=pathName[0]; 037 this.name=pathName[1]; 038 039 } 040 041 private HTTPResponse getHTTPResponse(boolean create) throws IOException { 042 if(create || http==null) { 043 //URL url = HTTPUtil.toURL("http://"+data.host+":"+data.port+"/"+data.path); 044 URL url = new URL(provider.getProtocol(),data.host,data.port,data.path); 045 // TODO Support for proxy 046 ProxyData pd=data.hasProxyData()?data.proxyData:ProxyDataImpl.NO_PROXY; 047 048 http = HTTPEngine.get(url, data.username, data.password, _getTimeout(),HTTPEngine.MAX_REDIRECT,null, data.userAgent, 049 pd, 050 null); 051 } 052 return http; 053 } 054 055 private int getStatusCode() throws IOException { 056 if(http==null) { 057 URL url = new URL(provider.getProtocol(),data.host,data.port,data.path); 058 ProxyData pd=data.hasProxyData()?data.proxyData:ProxyDataImpl.NO_PROXY; 059 return HTTPEngine.head(url, data.username, data.password, _getTimeout(),HTTPEngine.MAX_REDIRECT, 060 null, data.userAgent, 061 pd, 062 null).getStatusCode(); 063 } 064 return http.getStatusCode(); 065 } 066 067 public ContentType getContentType() throws IOException { 068 if(http==null) { 069 URL url = new URL(provider.getProtocol(),data.host,data.port,data.path); 070 ProxyData pd=data.hasProxyData()?data.proxyData:ProxyDataImpl.NO_PROXY; 071 return HTTPEngine.head(url, data.username, data.password, _getTimeout(),HTTPEngine.MAX_REDIRECT, 072 null, data.userAgent, 073 pd, 074 null).getContentType(); 075 } 076 return http.getContentType(); 077 } 078 079 080 081 public boolean exists() { 082 try { 083 provider.read(this); 084 int code = getStatusCode();//getHttpMethod().getStatusCode(); 085 return code!=404; 086 } 087 catch (IOException e) { 088 return false; 089 } 090 } 091 092 public int statusCode() { 093 try { 094 provider.read(this); 095 return getHTTPResponse(false).getStatusCode(); 096 } catch (IOException e) { 097 return 0; 098 } 099 } 100 101 public InputStream getInputStream() throws IOException { 102 //ResourceUtil.checkGetInputStreamOK(this); 103 //provider.lock(this); 104 provider.read(this); 105 HTTPResponse method = getHTTPResponse(true); 106 try { 107 return IOUtil.toBufferedInputStream(method.getContentAsStream()); 108 } 109 catch (IOException e) { 110 //provider.unlock(this); 111 throw e; 112 } 113 } 114 115 @Override 116 public String getName() { 117 return name; 118 } 119 120 @Override 121 public String getParent() { 122 if(isRoot()) return null; 123 return provider.getProtocol().concat("://").concat(data.key()).concat(path.substring(0,path.length()-1)); 124 } 125 126 private boolean isRoot() { 127 return StringUtil.isEmpty(name); 128 } 129 130 @Override 131 public Resource getParentResource() { 132 if(isRoot()) return null; 133 return new HTTPResource(provider, 134 new HTTPConnectionData(data.username,data.password,data.host,data.port,path,data.proxyData,data.userAgent)); 135 } 136 137 @Override 138 public String getPath() { 139 return provider.getProtocol().concat("://").concat(data.key()).concat(path).concat(name); 140 } 141 142 @Override 143 public Resource getRealResource(String realpath) { 144 realpath=ResourceUtil.merge(path.concat(name), realpath); 145 if(realpath.startsWith("../"))return null; 146 return new HTTPResource(provider,new HTTPConnectionData(data.username,data.password,data.host,data.port,realpath,data.proxyData,data.userAgent)); 147 } 148 149 @Override 150 public ResourceProvider getResourceProvider() { 151 return provider; 152 } 153 154 @Override 155 public boolean isAbsolute() { 156 return true; 157 } 158 159 @Override 160 public boolean isDirectory() { 161 return false; 162 } 163 164 @Override 165 public boolean isFile() { 166 return exists(); 167 } 168 169 @Override 170 public boolean isReadable() { 171 return exists(); 172 } 173 174 public long lastModified() { 175 int last=0; 176 try { 177 Header cl=getHTTPResponse(false).getLastHeaderIgnoreCase("last-modified"); 178 if(cl!=null && exists()) last=Caster.toIntValue(cl.getValue(),0); 179 } 180 catch (IOException e) {} 181 return last; 182 } 183 184 public long length() { 185 try { 186 if(!exists()) return 0; 187 return getHTTPResponse(false).getContentLength(); 188 } 189 catch (IOException e) { 190 return 0; 191 } 192 } 193 194 public Resource[] listResources() { 195 return null; 196 } 197 198 public void setProxyData(ProxyData pd) { 199 this.http=null; 200 this.data.setProxyData(pd); 201 } 202 203 public void setUserAgent(String userAgent) { 204 this.http=null; 205 this.data.userAgent=userAgent; 206 } 207 208 public void setTimeout(int timeout) { 209 this.http=null; 210 data.timeout=timeout; 211 } 212 213 214 private int _getTimeout() { 215 return data.timeout<provider.getSocketTimeout()?data.timeout:provider.getSocketTimeout(); 216 } 217 }