在我们的项目中,我们需要通过代理服务器(squid)访问Blob存储。
我们计划使用Microsoft Azure Storage SDK for Java version 2.2.0。 但看起来API并未提供设置代理。 我可以让它通过代理的唯一方法是设置系统属性
System.setProperty("http.proxyHost", "127.0.0.1");
System.setProperty("http.proxyPort", "3128");
但这会影响我的JVM上运行的所有服务,这会损害其他不应通过代理服务器的服务。
查看它看起来的java代码 com.microsoft.azure.storage.core.BaseRequest.createURLConnection(URI,RequestOptions,UriQueryBuilder,OperationContext)。在没有代理的情况下调用java.net.URL.openConnection()。 使用java.net.URL.openConnection(Proxy)可以提供所需的支持吗?
我觉得这不支持吗? 我在这里想念一下吗?
更新:我在azure-storage-java git中打开了issue,我很乐意得到您的输入,因为我想建议一个拉取请求。< / p>
答案 0 :(得分:1)
到目前为止,还没有Java SDK API支持通过代理服务器直接访问Azure存储,因为BaseRequest类在函数“public static HttpConnection createURLConnection(...)”中错过了“url.openConnection(proxy)”。
根据我的经验,有两种方法可以帮助您实现访问功能。
一个是您可以通过java.net.Proxy类使用Azure存储REST API来访问存储服务。
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(host, port));
URLConnection conn = url.openConnection(proxy);
And if you should be authorize proxy user & password, you can do it as the follows:
//Proxy-Authorization: Basic <Base64.encode(user:password)>
String headerKey = "Proxy-Authorization";
String headerValue = "Basic " + Base64.encode(user+":"+password);
conn.setRequestProperty(headerKey, headerValue);
最后一个是您可以修改Azure SDK API, 覆盖Class“BaseRequest” 中的方法“createURLConnection”以实现访问。 GitHub上的Azure Storage SDK v2.2.0项目为https://github.com/Azure/azure-storage-java/tree/v2.2.0/。
注意:
public static HttpURLConnection createURLConnection(final URI uri,final RequestOptions options,UriQueryBuilder builder,final OperationContext opContext, java.net.Proxy proxy )
和
final HttpURLConnection retConnection =(HttpURLConnection)resourceUrl.openConnection( proxy );
public static HttpURLConnection createURLConnection(final URI uri, final RequestOptions options, UriQueryBuilder builder, final OperationContext opContext, java.net.Proxy proxy) throws IOException, URISyntaxException, StorageException {
if (builder == null) {
builder = new UriQueryBuilder();
}
final URL resourceUrl = builder.addToURI(uri).toURL();
final HttpURLConnection retConnection = (HttpURLConnection) resourceUrl.openConnection(proxy);
if (options.getTimeoutIntervalInMs() != null && options.getTimeoutIntervalInMs() != 0) {
builder.add(TIMEOUT, String.valueOf(options.getTimeoutIntervalInMs() / 1000));
}
// Note: ReadTimeout must be explicitly set to avoid a bug in JDK 6.
// In certain cases, this bug causes an immediate read timeout exception to be thrown even if ReadTimeout is not set.
retConnection.setReadTimeout(Utility.getRemainingTimeout(options.getOperationExpiryTimeInMs(), options.getTimeoutIntervalInMs()));
// Note : accept behavior, java by default sends Accept behavior as text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
retConnection.setRequestProperty(Constants.HeaderConstants.ACCEPT, Constants.HeaderConstants.XML_TYPE);
retConnection.setRequestProperty(Constants.HeaderConstants.ACCEPT_CHARSET, Constants.UTF8_CHARSET);
// Note : Content-Type behavior, java by default sends Content-type behavior as application/x-www-form-urlencoded for posts.
retConnection.setRequestProperty(Constants.HeaderConstants.CONTENT_TYPE, Constants.EMPTY_STRING);
retConnection.setRequestProperty(Constants.HeaderConstants.STORAGE_VERSION_HEADER,
Constants.HeaderConstants.TARGET_STORAGE_VERSION);
retConnection.setRequestProperty(Constants.HeaderConstants.USER_AGENT, getUserAgent());
retConnection.setRequestProperty(Constants.HeaderConstants.CLIENT_REQUEST_ID_HEADER,
opContext.getClientRequestID());
return retConnection;
}
顺便说一下,你需要在每个CloudXXXClient(CloudBlobClient等)类中调用上面的方法。
答案 1 :(得分:1)
根据此问题以及由strazh issue-48打开的其他问题,由我打开issue-65后,代理支持在版本4.2.0中进行了改进,请参阅here。
添加了对设置库范围代理的支持。默认代理可以 在OperationContext上设置。
有关完整示例,请参阅JUnits https://github.com/Azure/azure-storage-java/blob/master/microsoft-azure-storage-test/src/com/microsoft/azure/storage/GenericTests.java
查找testDefaultProxy和testProxy
答案 2 :(得分:1)
Azure存储团队已经发布了一个新的SDK(v10),现在通过HttpPipeline支持该代理。您可以通过将管道传递给StorageURL来在所有操作中共享管道,也可以通过将其传递给BlobURL对象在单个Blob中使用。
AnonymousCredentials creds = new AnonymousCredentials();
// Use PipelineOptions to define a retry strategy and a proxy - you can also pass your own HttpClient to this if you like
PipelineOptions po = new PipelineOptions();
// Proxy configuration shown here as a sample
HttpClientConfiguration configuration = new HttpClientConfiguration(
new Proxy(Proxy.Type.HTTP, new InetSocketAddress("localhost", 8888)), false); //pass true if the Proxy endpoint is HTTPS
po.client = HttpClient.createDefault(configuration);
// Create a URI with SAS token, and pass it to the PageBlobURL with an HttpPipeline created by createPipeline method
URL u = new URL("https://myaccount.blob.core.windows.net/mycontainer/myfile?sv=2017-04-17&sr=b&si=14169767-6354-41ed-a99b-c9db8dcc66bc&sig=8NUr%2BSpmRH%2BB2z%2FpQZDPDquTQ7rbgWfE9a6AePLlFT0%3D");
PageBlobURL blobURL = new PageBlobURL(u, PageBlobURL.createPipeline(creds, po));