Migrated to the Apache HttpComponents library
This commit is contained in:
parent
8f55580ed2
commit
63f36b31cc
9 changed files with 111 additions and 76 deletions
5
pom.xml
5
pom.xml
|
@ -59,6 +59,11 @@
|
|||
<artifactId>jdom2</artifactId>
|
||||
<version>2.0.6</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>4.5.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>info.picocli</groupId>
|
||||
<artifactId>picocli</artifactId>
|
||||
|
|
|
@ -32,6 +32,9 @@ To build, run "mvn clean package" in this folder.
|
|||
|
||||
|
||||
This project depends on the following libraries.
|
||||
- Apache HttpComponents
|
||||
https://hc.apache.org/
|
||||
(For JavaDocs, click HttpCore or HttpClient, then again under "Project reports".)
|
||||
- Jackson JSON Processor 2.x
|
||||
http://jackson.codehaus.org/Home
|
||||
(For JavaDocs, look right.)
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
"Disabled XML escaping when reencoding to ensure invalid chars cause an error",
|
||||
"Changed logging framework to SLF4J/Logback",
|
||||
"Changed command line parser to picocli",
|
||||
"Migrated to the Apache HttpComponents library",
|
||||
"Made launcher scripts on OSX find java the recommended way"
|
||||
]
|
||||
},
|
||||
|
|
|
@ -9,6 +9,7 @@ Changelog
|
|||
- Added a Validate warning about FTL 1.5.13 for chars outside windows-1252
|
||||
- Changed logging framework to SLF4J/Logback
|
||||
- Changed command line parser to picocli
|
||||
- Migrated to the Apache HttpComponents library
|
||||
- Made launcher scripts on OSX find java the recommended way
|
||||
|
||||
1.9:
|
||||
|
|
|
@ -26,7 +26,6 @@ public class AutoUpdateInfo {
|
|||
return latestVersion;
|
||||
}
|
||||
|
||||
|
||||
public void setNotice( String s ) {
|
||||
notice = s;
|
||||
}
|
||||
|
@ -35,7 +34,6 @@ public class AutoUpdateInfo {
|
|||
return notice;
|
||||
}
|
||||
|
||||
|
||||
public void putLatestURL( String os, String url ) {
|
||||
latestURLs.put( os, url );
|
||||
}
|
||||
|
@ -44,8 +42,6 @@ public class AutoUpdateInfo {
|
|||
changelog.put( version, changeList );
|
||||
}
|
||||
|
||||
|
||||
|
||||
public Map<String, String> getLatestURLs() {
|
||||
return latestURLs;
|
||||
}
|
||||
|
|
|
@ -12,11 +12,9 @@ import java.util.regex.Pattern;
|
|||
* It is composed of three parts:
|
||||
* - A series of period-separated positive ints.
|
||||
*
|
||||
* - The numbers may be immediately followed by a short
|
||||
* suffix string.
|
||||
* - The numbers may be immediately followed by a short suffix string.
|
||||
*
|
||||
* - Finally, a string comment, separated from the rest
|
||||
* by a space.
|
||||
* - Finally, a string comment, separated from the rest by a space.
|
||||
*
|
||||
* The (numbers + suffix) or comment may appear alone.
|
||||
*
|
||||
|
@ -148,8 +146,6 @@ public class ComparableVersion implements Comparable<ComparableVersion> {
|
|||
|
||||
Matcher m = suffixPtn.matcher( s );
|
||||
if ( m.matches() ) {
|
||||
suffix = s;
|
||||
|
||||
// Matched groups 1 and 2... or 3.
|
||||
|
||||
if ( m.group( 1 ) != null ) {
|
||||
|
|
|
@ -3,7 +3,6 @@ package net.vhati.modmanager.json;
|
|||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -28,10 +27,11 @@ public class JacksonAutoUpdateReader {
|
|||
|
||||
|
||||
public static AutoUpdateInfo parse( File jsonFile ) {
|
||||
AutoUpdateInfo aui = new AutoUpdateInfo();
|
||||
|
||||
Exception exception = null;
|
||||
try {
|
||||
AutoUpdateInfo aui = new AutoUpdateInfo();
|
||||
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
mapper.configure( JsonParser.Feature.ALLOW_SINGLE_QUOTES, true );
|
||||
mapper.setVisibility( PropertyAccessor.FIELD, Visibility.ANY );
|
||||
|
@ -67,6 +67,8 @@ public class JacksonAutoUpdateReader {
|
|||
}
|
||||
aui.putChanges( new ComparableVersion( releaseVersion ), changeList );
|
||||
}
|
||||
|
||||
return aui;
|
||||
}
|
||||
catch ( JsonProcessingException e ) {
|
||||
exception = e;
|
||||
|
@ -76,9 +78,8 @@ public class JacksonAutoUpdateReader {
|
|||
}
|
||||
if ( exception != null ) {
|
||||
log.error( "Failed to parse info about available updates", exception );
|
||||
return null;
|
||||
}
|
||||
|
||||
return aui;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,10 +23,11 @@ public class JacksonCatalogReader {
|
|||
|
||||
|
||||
public static ModDB parse( File jsonFile ) {
|
||||
ModDB modDB = new ModDB();
|
||||
|
||||
Exception exception = null;
|
||||
try {
|
||||
ModDB modDB = new ModDB();
|
||||
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
mapper.configure( JsonParser.Feature.ALLOW_SINGLE_QUOTES, true );
|
||||
mapper.setVisibility( PropertyAccessor.FIELD, Visibility.ANY );
|
||||
|
@ -53,6 +54,8 @@ public class JacksonCatalogReader {
|
|||
modDB.addMod( modInfo );
|
||||
}
|
||||
}
|
||||
|
||||
return modDB;
|
||||
}
|
||||
catch ( JsonProcessingException e ) {
|
||||
exception = e;
|
||||
|
@ -65,6 +68,6 @@ public class JacksonCatalogReader {
|
|||
return null;
|
||||
}
|
||||
|
||||
return modDB;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,10 +10,6 @@ import java.io.InputStreamReader;
|
|||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -21,6 +17,14 @@ import java.util.Map;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.ClientProtocolException;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
|
||||
|
||||
public class URLFetcher {
|
||||
|
||||
|
@ -28,104 +32,129 @@ public class URLFetcher {
|
|||
|
||||
|
||||
/**
|
||||
* Downloads content from a url into a file, if the remote content has changed.
|
||||
* Downloads content from a url to one file, and its ETag to another.
|
||||
*
|
||||
* If the ETag files exists, it will be read to inform the GET request.
|
||||
*
|
||||
* If the content has not changed, the destination file's modified date
|
||||
* will be reset to the present time.
|
||||
*
|
||||
* If the content has changed, it will be written to the file, as will the
|
||||
* new ETag.
|
||||
*
|
||||
* @return true if successfully downloaded, false otherwise
|
||||
*/
|
||||
public static boolean refetchURL( String url, File localFile, File eTagFile ) {
|
||||
String localETag = null;
|
||||
|
||||
log.debug( String.format( "Attempting to download the latest \"%s\".", localFile.getName() ) );
|
||||
log.debug( String.format( "Attempting to download the latest \"%s\"", localFile.getName() ) );
|
||||
if ( eTagFile.exists() ) {
|
||||
// Load the old eTag.
|
||||
InputStream etagIn = null;
|
||||
BufferedReader etagReader = null;
|
||||
try {
|
||||
etagIn = new FileInputStream( eTagFile );
|
||||
BufferedReader br = new BufferedReader( new InputStreamReader( etagIn, "UTF-8" ) );
|
||||
String line = br.readLine();
|
||||
if ( line.length() > 0 )
|
||||
etagReader = new BufferedReader( new InputStreamReader( etagIn, "UTF-8" ) );
|
||||
String line = etagReader.readLine();
|
||||
if ( line.length() > 0 ) {
|
||||
localETag = line;
|
||||
}
|
||||
}
|
||||
catch ( IOException e ) {
|
||||
// Not serious enough to be a real error.
|
||||
log.debug( String.format( "Error reading eTag from \"%s\".", eTagFile.getName() ), e );
|
||||
log.debug( String.format( "Error reading eTag from \"%s\"", eTagFile.getName() ), e );
|
||||
}
|
||||
finally {
|
||||
try {if ( etagReader != null ) etagReader.close();}
|
||||
catch ( IOException e ) {}
|
||||
|
||||
try {if ( etagIn != null ) etagIn.close();}
|
||||
catch ( IOException e ) {}
|
||||
}
|
||||
}
|
||||
|
||||
String remoteETag = null;
|
||||
InputStream urlIn = null;
|
||||
HttpGet request = null;
|
||||
OutputStream localOut = null;
|
||||
String remoteETag = null;
|
||||
|
||||
RequestConfig requestConfig = RequestConfig.custom()
|
||||
.setConnectionRequestTimeout( 5000 )
|
||||
.setConnectTimeout( 5000 )
|
||||
.setSocketTimeout( 10000 )
|
||||
.setRedirectsEnabled( true )
|
||||
.build();
|
||||
|
||||
CloseableHttpClient httpClient = HttpClientBuilder.create()
|
||||
.setDefaultRequestConfig( requestConfig )
|
||||
.disableAuthCaching()
|
||||
.disableAutomaticRetries()
|
||||
.disableConnectionState()
|
||||
.disableCookieManagement()
|
||||
//.setUserAgent( "" )
|
||||
.build();
|
||||
|
||||
try {
|
||||
URLConnection conn = new URL( url ).openConnection();
|
||||
request = new HttpGet( url );
|
||||
|
||||
if ( conn instanceof HttpURLConnection == false ) {
|
||||
log.error( String.format( "Non-Http(s) URL given for fetching: %s", url ) );
|
||||
return false;
|
||||
HttpResponse response = httpClient.execute( request );
|
||||
|
||||
int status = response.getStatusLine().getStatusCode();
|
||||
if ( status >= 200 && status < 300 ) {
|
||||
|
||||
HttpEntity entity = response.getEntity();
|
||||
if ( entity != null ) {
|
||||
localOut = new FileOutputStream( localFile );
|
||||
entity.writeTo( localOut );
|
||||
}
|
||||
HttpURLConnection httpConn = (HttpURLConnection)conn;
|
||||
|
||||
httpConn.setReadTimeout( 10000 );
|
||||
if ( localETag != null )
|
||||
httpConn.setRequestProperty( "If-None-Match", localETag );
|
||||
httpConn.connect();
|
||||
|
||||
int responseCode = httpConn.getResponseCode();
|
||||
|
||||
if ( responseCode == HttpURLConnection.HTTP_NOT_MODIFIED ) {
|
||||
log.debug( String.format( "No need to update \"%s\", the server's copy has not been modified since the previous check", localFile.getName() ) );
|
||||
if ( response.containsHeader( "ETag" ) ) {
|
||||
remoteETag = response.getLastHeader( "ETag" ).getValue();
|
||||
}
|
||||
}
|
||||
else if ( status == 304 ) { // Not modified.
|
||||
log.debug( String.format( "No need to download \"%s\", the server's copy has not been modified", localFile.getName() ) );
|
||||
|
||||
// Update the local file's timestamp as if it had downloaded.
|
||||
localFile.setLastModified( new Date().getTime() );
|
||||
|
||||
return false;
|
||||
}
|
||||
else if ( responseCode == HttpURLConnection.HTTP_OK ) {
|
||||
Map<String, List<String>> headerMap = httpConn.getHeaderFields();
|
||||
List<String> eTagValues = headerMap.get( "ETag" );
|
||||
if ( eTagValues != null && eTagValues.size() > 0 )
|
||||
remoteETag = eTagValues.get( 0 );
|
||||
|
||||
urlIn = httpConn.getInputStream();
|
||||
localOut = new FileOutputStream( localFile );
|
||||
byte[] buf = new byte[4096];
|
||||
int len;
|
||||
while ( (len = urlIn.read(buf)) >= 0 ) {
|
||||
localOut.write( buf, 0, len );
|
||||
}
|
||||
}
|
||||
else {
|
||||
log.error( String.format( "Download request failed for \"%s\": HTTP Code %d (%s)", httpConn.getURL(), responseCode, httpConn.getResponseMessage() ) );
|
||||
throw new ClientProtocolException( "Unexpected response status: "+ status );
|
||||
}
|
||||
}
|
||||
catch ( ClientProtocolException e ) {
|
||||
log.error( "GET request failed for url: "+ request.getURI().toString(), e );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch ( IOException e ) {
|
||||
log.error( String.format( "Error downloading the latest \"%s\"", localFile.getName() ), e );
|
||||
log.error( "Download failed for url: "+ request.getURI().toString(), e );
|
||||
return false;
|
||||
}
|
||||
finally {
|
||||
try {if ( urlIn != null ) urlIn.close();}
|
||||
try {if ( localOut != null ) localOut.close();}
|
||||
catch ( IOException e ) {}
|
||||
|
||||
try {if ( localOut != null ) localOut.close();}
|
||||
try {httpClient.close();}
|
||||
catch ( IOException e ) {}
|
||||
}
|
||||
|
||||
if ( remoteETag != null ) {
|
||||
// Save the new eTag.
|
||||
OutputStream etagOut = null;
|
||||
BufferedWriter etagWriter = null;
|
||||
try {
|
||||
etagOut = new FileOutputStream( eTagFile );
|
||||
BufferedWriter bw = new BufferedWriter( new OutputStreamWriter( etagOut, "UTF-8" ) );
|
||||
bw.append( remoteETag );
|
||||
bw.flush();
|
||||
etagWriter = new BufferedWriter( new OutputStreamWriter( etagOut, "UTF-8" ) );
|
||||
etagWriter.append( remoteETag );
|
||||
etagWriter.flush();
|
||||
}
|
||||
catch ( IOException e ) {
|
||||
log.error( String.format( "Error writing eTag to \"%s\"", eTagFile.getName() ), e );
|
||||
}
|
||||
finally {
|
||||
try {if ( etagWriter != null ) etagWriter.close();}
|
||||
catch ( IOException e ) {}
|
||||
|
||||
try {if ( etagOut != null ) etagOut.close();}
|
||||
catch ( IOException e ) {}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue