Skip to content

Commit

Permalink
Merge pull request #12 from square/master
Browse files Browse the repository at this point in the history
sync origin
  • Loading branch information
carck committed Feb 13, 2014
2 parents f109cf3 + 8720ab4 commit 7e10e36
Show file tree
Hide file tree
Showing 35 changed files with 1,665 additions and 687 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,6 @@ public void processConnection() throws Exception {
.handler(spdySocketHandler).build();
openSpdyConnections.put(spdyConnection, Boolean.TRUE);
openClientSockets.remove(socket);
spdyConnection.readConnectionHeader();
return;
}

Expand Down
94 changes: 94 additions & 0 deletions okcurl/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>com.squareup.okhttp</groupId>
<artifactId>parent</artifactId>
<version>2.0.0-SNAPSHOT</version>
</parent>

<artifactId>okcurl</artifactId>
<name>OkCurl</name>

<dependencies>
<dependency>
<groupId>com.squareup.okhttp</groupId>
<artifactId>okhttp</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
</dependency>
<dependency>
<groupId>org.mortbay.jetty.npn</groupId>
<artifactId>npn-boot</artifactId>
</dependency>
<dependency>
<groupId>io.airlift</groupId>
<artifactId>airline</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>

<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>com.squareup.okhttp.curl.Main</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.skife.maven</groupId>
<artifactId>really-executable-jar-maven-plugin</artifactId>
<version>1.1.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>really-executable-jar</goal>
</goals>
</execution>
</executions>
<configuration>
<flags>-Xbootclasspath/p:$0</flags>
</configuration>
</plugin>
</plugins>
</build>
</project>
208 changes: 208 additions & 0 deletions okcurl/src/main/java/com/squareup/okhttp/curl/Main.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
package com.squareup.okhttp.curl;

import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import com.squareup.okhttp.ConnectionPool;
import com.squareup.okhttp.Failure;
import com.squareup.okhttp.Headers;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Protocol;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;
import io.airlift.command.Arguments;
import io.airlift.command.Command;
import io.airlift.command.HelpOption;
import io.airlift.command.Option;
import io.airlift.command.SingleCommand;
import java.io.IOException;
import java.io.InputStream;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import static java.util.concurrent.TimeUnit.SECONDS;

@Command(name = Main.NAME, description = "A curl for the next-generation web.")
public class Main extends HelpOption implements Runnable, Response.Receiver {
static final String NAME = "okcurl";
static final int DEFAULT_TIMEOUT = -1;

public static void main(String... args) {
SingleCommand.singleCommand(Main.class).parse(args).run();
}

private static String versionString() {
try {
Properties prop = new Properties();
InputStream in = Main.class.getResourceAsStream("/okcurl-version.properties");
prop.load(in);
in.close();
return prop.getProperty("version");
} catch (IOException e) {
throw new AssertionError("Could not load okcurl-version.properties.");
}
}

private static String protocols() {
return Joiner.on(", ").join(Lists.transform(Arrays.asList(Protocol.values()),
new Function<Protocol, String>() {
@Override public String apply(Protocol protocol) {
return protocol.name.utf8();
}
}));
}

@Option(name = { "-X", "--request" }, description = "Specify request command to use",
allowedValues = { "GET", "HEAD" })
public String method = "GET";

@Option(name = { "-H", "--header" }, description = "Custom header to pass to server")
public List<String> headers;

@Option(name = { "-A", "--user-agent" }, description = "User-Agent to send to server")
public String userAgent = NAME + "/" + versionString();

@Option(name = "--connect-timeout", description = "Maximum time allowed for connection (seconds)")
public int connectTimeout = DEFAULT_TIMEOUT;

@Option(name = "--read-timeout", description = "Maximum time allowed for reading data (seconds)")
public int readTimeout = DEFAULT_TIMEOUT;

@Option(name = { "-L", "--location" }, description = "Follow redirects")
public boolean followRedirects;

@Option(name = { "-k", "--insecure" },
description = "Allow connections to SSL sites without certs")
public boolean allowInsecure;

@Option(name = { "-i", "--include" }, description = "Include protocol headers in the output")
public boolean showHeaders;

@Option(name = { "-e", "--referer" }, description = "Referer URL")
public String referer;

@Option(name = { "-V", "--version" }, description = "Show version number and quit")
public boolean version;

@Arguments(title = "url", description = "Remote resource URL")
public String url;

private OkHttpClient client;

@Override public void run() {
if (showHelpIfRequested()) {
return;
}
if (version) {
System.out.println(NAME + " " + versionString());
System.out.println("Protocols: " + protocols());
return;
}

client = getConfiguredClient();
Request request = getConfiguredRequest();
client.enqueue(request, this);

// Immediately begin triggering an executor shutdown so that after execution of the above
// request the threads do not stick around until timeout.
client.getDispatcher().getExecutorService().shutdown();
}

private OkHttpClient getConfiguredClient() {
OkHttpClient client = new OkHttpClient();
client.setFollowProtocolRedirects(followRedirects);
if (connectTimeout != DEFAULT_TIMEOUT) {
client.setConnectTimeout(connectTimeout, SECONDS);
}
if (readTimeout != DEFAULT_TIMEOUT) {
client.setReadTimeout(readTimeout, SECONDS);
}
if (allowInsecure) {
client.setSslSocketFactory(createInsecureSslSocketFactory());
}
// If we don't set this reference, there's no way to clean shutdown persistent connections.
client.setConnectionPool(ConnectionPool.getDefault());
return client;
}

private Request getConfiguredRequest() {
Request.Builder request = new Request.Builder();
request.method(method, null);
request.url(url);
if (headers != null) {
for (String header : headers) {
String[] parts = header.split(":", -1);
request.header(parts[0], parts[1]);
}
}
if (referer != null) {
request.header("Referer", referer);
}
request.header("User-Agent", userAgent);
return request.build();
}

@Override public void onFailure(Failure failure) {
failure.exception().printStackTrace();
close();
}

@Override public boolean onResponse(Response response) throws IOException {
if (showHeaders) {
System.out.println(response.statusLine());
Headers headers = response.headers();
for (int i = 0, count = headers.size(); i < count; i++) {
System.out.println(headers.name(i) + ": " + headers.value(i));
}
System.out.println();
}

Response.Body body = response.body();
byte[] buffer = new byte[1024];
while (body.ready()) {
int c = body.byteStream().read(buffer);
if (c == -1) {
close();
return true;
}

System.out.write(buffer, 0, c);
}
close();
return false;
}

private void close() {
client.getConnectionPool().evictAll(); // Close any persistent connections.
}

private static SSLSocketFactory createInsecureSslSocketFactory() {
try {
SSLContext context = SSLContext.getInstance("TLS");
TrustManager permissive = new X509TrustManager() {
@Override public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}

@Override public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}

@Override public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
context.init(null, new TrustManager[] { permissive }, null);
return context.getSocketFactory();
} catch (Exception e) {
throw new AssertionError(e);
}
}
}
1 change: 1 addition & 0 deletions okcurl/src/main/resources/okcurl-version.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
version=${project.version}
Original file line number Diff line number Diff line change
Expand Up @@ -404,4 +404,17 @@ public static void asciiLowerCase(byte[] bytes) {
public static byte asciiLowerCase(byte c) {
return 'A' <= c && c <= 'Z' ? (byte) (c + 'a' - 'A') : c;
}

public static int reverseBytesShort(short s) {
int i = s & 0xffff;
return (i & 0xff00) >>> 8
| (i & 0x00ff) << 8;
}

public static int reverseBytesInt(int i) {
return (i & 0xff000000) >>> 24
| (i & 0x00ff0000) >>> 8
| (i & 0x0000ff00) << 8
| (i & 0x000000ff) << 24;
}
}
Loading

0 comments on commit 7e10e36

Please sign in to comment.