001: package net.sf.borg.model.db.remote.http;
002:
003: import java.io.ByteArrayOutputStream;
004: import java.io.InputStream;
005:
006: import net.sf.borg.common.Warning;
007: import net.sf.borg.model.db.remote.IRemoteProxy;
008: import net.sf.borg.model.db.remote.IRemoteProxyProvider;
009:
010: import org.apache.commons.httpclient.Credentials;
011: import org.apache.commons.httpclient.HttpClient;
012: import org.apache.commons.httpclient.HttpState;
013: import org.apache.commons.httpclient.HttpStatus;
014: import org.apache.commons.httpclient.UsernamePasswordCredentials;
015: import org.apache.commons.httpclient.auth.AuthScheme;
016: import org.apache.commons.httpclient.auth.CredentialsNotAvailableException;
017: import org.apache.commons.httpclient.auth.CredentialsProvider;
018: import org.apache.commons.httpclient.cookie.CookiePolicy;
019: import org.apache.commons.httpclient.methods.PostMethod;
020: import org.apache.commons.httpclient.methods.StringRequestEntity;
021: import org.apache.commons.httpclient.params.HttpClientParams;
022: import org.apache.commons.httpclient.protocol.Protocol;
023: import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;
024:
025: public class HTTPRemoteProxy implements IRemoteProxy {
026: static {
027: ProtocolSocketFactory psf = new EasySSLProtocolSocketFactory();
028: Protocol.registerProtocol("https", new Protocol("https", psf,
029: 8443));
030: }
031:
032: public HTTPRemoteProxy(String url) {
033: this .url = url;
034:
035: httpclient = new HttpClient();
036:
037: HttpClientParams params = httpclient.getParams();
038: params.setParameter(CredentialsProvider.PROVIDER, prompter);
039: params.setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);
040: }
041:
042: public String execute(String strXml, IRemoteProxyProvider provider)
043: throws Exception {
044: PostMethod post = new PostMethod(url);
045: post.setRequestEntity(new StringRequestEntity(strXml));
046: post.setRequestHeader("Content-type",
047: "text/xml; charset=ISO-8859-1");
048: post.setDoAuthentication(true);
049:
050: if (httpState != null)
051: httpclient.setState(httpState);
052: // restore any previous state, which should include credentials
053:
054: prompter.init(provider);
055:
056: try {
057: int result = httpclient.executeMethod(post);
058:
059: if (result != HttpStatus.SC_OK)
060: throw new Warning(HttpStatus.getStatusText(result));
061:
062: httpState = httpclient.getState();
063: // remember any cookies (i.e. session id) for subsequent
064: // invocations
065:
066: InputStream istr = post.getResponseBodyAsStream();
067: ByteArrayOutputStream ostr = new ByteArrayOutputStream();
068:
069: try {
070: int n;
071: while ((n = istr.read()) != -1)
072: ostr.write(n);
073: } finally {
074: istr.close();
075: ostr.close();
076: }
077:
078: return new String(ostr.toByteArray());
079: /*
080: return post.getResponseBodyAsString();
081: */
082: } finally {
083: post.releaseConnection();
084: }
085: }
086:
087: // private //
088: private String url;
089: private HttpClient httpclient;
090: private HttpState httpState;
091: private AuthPrompter prompter = new AuthPrompter();
092:
093: /////////////////////////////////////////////////////////////////
094: // inner class AuthPrompter
095:
096: private class AuthPrompter implements CredentialsProvider {
097: // CredendialsProvider overrides
098: public Credentials getCredentials(final AuthScheme authscheme,
099: final String host, int port, boolean proxy)
100: throws CredentialsNotAvailableException {
101: if (authscheme == null)
102: return null;
103:
104: // If we've got cached credentials and our current invocation
105: // count is positive, it means that our previous login attempt
106: // failed and that our credentials are bad. Nuke them.
107: if (invokeCount > 0)
108: creds = null;
109:
110: if (invokeCount > 2)
111: throw new CredentialsNotAvailableException();
112:
113: ++invokeCount;
114:
115: if (creds == null)
116: creds = proxyProvider.getCredentials();
117:
118: return new UsernamePasswordCredentials(creds.getUsername(),
119: creds.getPassword());
120: }
121:
122: // "internal" //
123: AuthPrompter() {
124: }
125:
126: final void init(IRemoteProxyProvider provider) {
127: this .proxyProvider = provider;
128: invokeCount = 0;
129: }
130:
131: // private //
132: private IRemoteProxyProvider proxyProvider;
133: private int invokeCount;
134: private IRemoteProxyProvider.Credentials creds;
135: }
136:
137: // end inner class AuthPrompter
138: /////////////////////////////////////////////////////////////////
139: }
|