Skip to content

Instantly share code, notes, and snippets.

@kwhinnery
Last active March 12, 2019 01:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kwhinnery/4774243 to your computer and use it in GitHub Desktop.
Save kwhinnery/4774243 to your computer and use it in GitHub Desktop.
package com.twilio;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.concurrent.TimeUnit;
import org.apache.http.Header;
import org.apache.http.HttpConnectionMetrics;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpException;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.ProtocolVersion;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.ManagedClientConnection;
import org.apache.http.conn.routing.HttpRoute;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.message.BasicHttpResponse;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.HttpContext;
import com.google.appengine.api.urlfetch.FetchOptions;
import com.google.appengine.api.urlfetch.HTTPHeader;
import com.google.appengine.api.urlfetch.HTTPMethod;
import com.google.appengine.api.urlfetch.HTTPRequest;
import com.google.appengine.api.urlfetch.HTTPResponse;
import com.google.appengine.api.urlfetch.URLFetchService;
import com.google.appengine.api.urlfetch.URLFetchServiceFactory;
class GAEClientConnection implements ManagedClientConnection {
public GAEClientConnection(ClientConnectionManager cm, HttpRoute route,
Object state) {
this.connManager = cm;
this.route = route;
this.state = state;
this.closed = true;
}
// From interface ManagedClientConnection
@Override
public boolean isSecure() {
return route.isSecure();
}
@Override
public HttpRoute getRoute() {
return route;
}
@Override
public javax.net.ssl.SSLSession getSSLSession() {
return null;
}
@Override
public void open(HttpRoute route, HttpContext context, HttpParams params)
throws IOException {
close();
this.route = route;
// System.err.println(">>>>");
}
@Override
public void tunnelTarget(boolean secure, HttpParams params)
throws IOException {
throw new IOException("tunnelTarget() not supported");
}
@Override
public void tunnelProxy(HttpHost next, boolean secure, HttpParams params)
throws IOException {
throw new IOException("tunnelProxy() not supported");
}
@Override
public void layerProtocol(HttpContext context, HttpParams params)
throws IOException {
throw new IOException("layerProtocol() not supported");
}
@Override
public void markReusable() {
reusable = true;
}
@Override
public void unmarkReusable() {
reusable = false;
}
@Override
public boolean isMarkedReusable() {
return reusable;
}
@Override
public void setState(Object state) {
this.state = state;
}
@Override
public Object getState() {
return state;
}
@Override
public void setIdleDuration(long duration, TimeUnit unit) {
// Do nothing
}
// From interface HttpClientConnection
@Override
public boolean isResponseAvailable(int timeout) throws IOException {
return response != null;
}
@Override
public void sendRequestHeader(HttpRequest request) throws HttpException,
IOException {
try {
HttpHost host = route.getTargetHost();
URI uri = new URI(host.getSchemeName() + "://" + host.getHostName()
+ ((host.getPort() == -1) ? "" : (":" + host.getPort()))
+ request.getRequestLine().getUri());
this.request = new HTTPRequest(uri.toURL(),
HTTPMethod.valueOf(request.getRequestLine().getMethod()),
FetchOptions.Builder.disallowTruncate()
.doNotFollowRedirects());
} catch (URISyntaxException ex) {
throw new IOException("Malformed request URI: " + ex.getMessage(),
ex);
} catch (IllegalArgumentException ex) {
throw new IOException(
"Unsupported HTTP method: " + ex.getMessage(), ex);
}
// System.err.println("SEND: " + this.request.getMethod() + " " +
// this.request.getURL());
for (Header h : request.getAllHeaders()) {
// System.err.println("SEND: " + h.getName() + ": " + h.getValue());
this.request.addHeader(new HTTPHeader(h.getName(), h.getValue()));
}
}
@Override
public void sendRequestEntity(HttpEntityEnclosingRequest request)
throws HttpException, IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
if (request.getEntity() != null) {
request.getEntity().writeTo(baos);
}
this.request.setPayload(baos.toByteArray());
}
@Override
public HttpResponse receiveResponseHeader() throws HttpException,
IOException {
if (this.response == null) {
flush();
}
HttpResponse response = new BasicHttpResponse(new ProtocolVersion(
"HTTP", 1, 1), this.response.getResponseCode(), null);
// System.err.println("RECV: " + response.getStatusLine());
for (HTTPHeader h : this.response.getHeaders()) {
// System.err.println("RECV: " + h.getName() + ": " + h.getValue());
response.addHeader(h.getName(), h.getValue());
}
return response;
}
@Override
public void receiveResponseEntity(HttpResponse response)
throws HttpException, IOException {
if (this.response == null) {
throw new IOException(
"receiveResponseEntity() called on closed connection");
}
ByteArrayEntity bae = new ByteArrayEntity(this.response.getContent());
bae.setContentType(response.getFirstHeader("Content-Type"));
response.setEntity(bae);
response = null;
}
@Override
public void flush() throws IOException {
if (request != null) {
try {
// System.err.println("----");
response = urlFS.fetch(request);
request = null;
} catch (IOException ex) {
ex.printStackTrace();
throw ex;
}
} else {
response = null;
}
}
// From interface HttpConnection
@Override
public void close() throws IOException {
request = null;
response = null;
closed = true;
// System.err.println("<<<<");
}
@Override
public boolean isOpen() {
return request != null || response != null;
}
@Override
public boolean isStale() {
return !isOpen() && !closed;
}
@Override
public void setSocketTimeout(int timeout) {
}
@Override
public int getSocketTimeout() {
return -1;
}
@Override
public void shutdown() throws IOException {
close();
}
@Override
public HttpConnectionMetrics getMetrics() {
return null;
}
// From interface HttpInetConnection
@Override
public InetAddress getLocalAddress() {
return null;
}
@Override
public int getLocalPort() {
return 0;
}
@Override
public InetAddress getRemoteAddress() {
return null;
}
@Override
public int getRemotePort() {
HttpHost host = route.getTargetHost();
return connManager.getSchemeRegistry().getScheme(host)
.resolvePort(host.getPort());
}
// From interface ConnectionReleaseTrigger
@Override
public void releaseConnection() throws IOException {
connManager.releaseConnection(this, Long.MAX_VALUE,
TimeUnit.MILLISECONDS);
}
@Override
public void abortConnection() throws IOException {
unmarkReusable();
shutdown();
}
private ClientConnectionManager connManager;
private HttpRoute route;
private Object state;
private boolean reusable;
private HTTPRequest request;
private HTTPResponse response;
private boolean closed;
private static URLFetchService urlFS = URLFetchServiceFactory
.getURLFetchService();
}
package com.twilio;
import java.net.*;
import java.util.concurrent.TimeUnit;
import org.apache.http.conn.*;
import org.apache.http.params.*;
import org.apache.http.conn.routing.HttpRoute;
import org.apache.http.conn.scheme.*;
public class GAEConnectionManager implements ClientConnectionManager {
@SuppressWarnings("deprecation")
public GAEConnectionManager() {
@SuppressWarnings("deprecation")
SocketFactory no_socket_factory = new SocketFactory() {
public Socket connectSocket(Socket sock, String host, int port,
InetAddress localAddress, int localPort, HttpParams params) {
return null;
}
public Socket createSocket() {
return null;
}
public boolean isSecure(Socket s) {
return false;
}
};
schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new Scheme("http", no_socket_factory, 80));
schemeRegistry.register(new Scheme("https", no_socket_factory, 443));
}
@Override
public SchemeRegistry getSchemeRegistry() {
return schemeRegistry;
}
@Override
public ClientConnectionRequest requestConnection(final HttpRoute route,
final Object state) {
return new ClientConnectionRequest() {
public void abortRequest() {
// Nothing to do
}
public ManagedClientConnection getConnection(long timeout,
TimeUnit tunit) {
return GAEConnectionManager.this.getConnection(route, state);
}
};
}
@Override
public void releaseConnection(ManagedClientConnection conn,
long validDuration, TimeUnit timeUnit) {
}
@Override
public void closeIdleConnections(long idletime, TimeUnit tunit) {
}
@Override
public void closeExpiredConnections() {
}
@Override
public void shutdown() {
}
private ManagedClientConnection getConnection(HttpRoute route, Object state) {
return new GAEClientConnection(this, route, state);
}
private SchemeRegistry schemeRegistry;
}
package com.twilio;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams;
import com.twilio.sdk.TwilioRestClient;
import com.twilio.sdk.resource.factory.SmsFactory;
import com.twilio.sdk.resource.instance.Account;
@SuppressWarnings("serial")
public class TwilioSandboxServlet extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException {
try {
String ACCOUNT_SID = "ACxxx";
String AUTH_TOKEN = "";
// Create a rest client
final TwilioRestClient client = new TwilioRestClient(ACCOUNT_SID,
AUTH_TOKEN);
// GAE Hack!
HttpParams httpParams = new BasicHttpParams();
ClientConnectionManager connectionManager = new GAEConnectionManager();
DefaultHttpClient itsHttpClient = new DefaultHttpClient(connectionManager, httpParams);
client.setHttpclient(itsHttpClient);
// Get the main account (The one we used to authenticate the client)
final Account mainAccount = client.getAccount();
// Send an sms
final SmsFactory smsFactory = mainAccount.getSmsFactory();
final Map<String, String> smsParams = new HashMap<String, String>();
smsParams.put("To", "+16512080532"); // Replace with a valid phone
// number
smsParams.put("From", "+16513566397"); // Replace with a valid phone
// number in your account
smsParams.put("Body", "This is a test message!");
smsFactory.create(smsParams);
} catch (Exception e) {
System.out.println(e);
}
// simple http response
response.setContentType("text/plain");
response.getWriter().println("done.");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment