Skip to content

Commit

Permalink
Merge pull request #30 from rlustemberg/#29-User-agent-and-session-fix
Browse files Browse the repository at this point in the history
#29 user agent and session fix
  • Loading branch information
AndreaVitale authored Jan 11, 2018
2 parents 1d25647 + 3bd7a37 commit 936d4d9
Show file tree
Hide file tree
Showing 10 changed files with 313 additions and 84 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
.DS_Store

phobeous-build.properties
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ About the enabled `contentMode`, you can learn more about this [here](https://de
| requestHeader | An object used to define extra http request header fields | |
| rounded | Enable or disable the circle transformation that automatically render the image as a perfect circle | Android only |
| timeout | Set timeout for requests | |
| handleCookies | Enable cookie handling for remote images | |

### Extra methods

Expand Down
36 changes: 33 additions & 3 deletions android/android/src/av/imageview/AVImageView.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@
import java.util.List;
import java.util.concurrent.TimeUnit;

import av.imageview.utils.CookiesHelper;

public class AVImageView extends TiUIView {
private static final String LCAT = "AVImageView";

Expand All @@ -71,6 +73,7 @@ public class AVImageView extends TiUIView {
private String brokenImage;
private String contentMode;
private HashMap requestHeader;
private boolean handleCookies;

private RequestListener<String, GlideDrawable> requestListener;

Expand All @@ -79,11 +82,13 @@ public AVImageView(TiViewProxy proxy) {

this.proxy = proxy;

//Setting up default values
//Setting up default values
this.loadingIndicator = true;
this.contentMode = ImageViewModule.CONTENT_MODE_ASPECT_FIT;
this.memoryCache = true;
this.okHttpClient = new OkHttpClient.Builder()

this.handleCookies = true;
this.okHttpClient = new OkHttpClient.Builder() // default timeouts are 5 seconds
.connectTimeout(5, TimeUnit.SECONDS)
.readTimeout(5, TimeUnit.SECONDS)
.build();
Expand Down Expand Up @@ -167,7 +172,9 @@ public void applyPropertyChanges(String key, Object value) {
.readTimeout(TiConvert.toInt(value), TimeUnit.MILLISECONDS)
.build();
}
}
if (d.containsKey("handleCookies"))
this.setHandleCookies(d.getBoolean("handleCookies"));
}

@Override
public void propertyChanged(String key, Object oldValue, Object newValue, KrollProxy proxy) {
Expand Down Expand Up @@ -232,10 +239,25 @@ public void startRequest(String url, Boolean loadingIndicator) {
if (url.startsWith("file://"))
drawableRequest = Glide.with(this.proxy.getActivity().getBaseContext()).load(url);
else
{
if(this.handleCookies)
{
String cookiesString = CookiesHelper.getCookiesStringForURL(url);
if(cookiesString != null && cookiesString.length() > 0)
{
if(this.requestHeader == null)
{
this.requestHeader = new HashMap();
}
this.requestHeader.put("Cookie", cookiesString);
}
}
drawableRequest = Glide
.with(this.proxy.getActivity().getBaseContext())
.using(new StreamModelLoaderWrapper<GlideUrl>(new OkHttpUrlLoader(okHttpClient)))
.load(GlideUrlBuilder.build(url, this.requestHeader));
}


//Handling GIF
if (this.getMimeType(url) != null && this.getMimeType(url) == "image/gif") {
Expand Down Expand Up @@ -397,6 +419,14 @@ synchronized public HashMap getRequestHeader() {
return this.requestHeader;
}

synchronized public void setHandleCookies(boolean handleCookies) {
this.handleCookies = handleCookies;
}

synchronized public boolean getHandleCookies() {
return this.handleCookies;
}

//Utility to create a specific request listener
private class RequestListenerBuilder {
private String LCAT = "RequestListenerBuilder";
Expand Down
14 changes: 13 additions & 1 deletion android/android/src/av/imageview/ImageViewProxy.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

@Kroll.proxy(creatableInModule=ImageViewModule.class, propertyAccessors = {
"defaultImage", "brokenLinkImage", "image", "contentMode", "enableMemoryCache",
"loadingIndicator", "enableMemoryCache", "rounded", "requestHeader"
"loadingIndicator", "enableMemoryCache", "rounded", "requestHeader", "handleCookies"
})
public class ImageViewProxy extends TiViewProxy
{
Expand Down Expand Up @@ -241,4 +241,16 @@ public void setRequestHeader(HashMap requestHeader) {
public void setTimeout(int timeout) {
getView().setTimeout(timeout);
}

@Kroll.getProperty
@Kroll.method
public Boolean getHandleCookies() {
return getView().getHandleCookies();
}

@Kroll.setProperty
@Kroll.method
public void setHandleCookies(Boolean handleCookies) {
getView().setHandleCookies(handleCookies);
}
}
131 changes: 131 additions & 0 deletions android/android/src/av/imageview/utils/CookiesHelper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
package av.imageview.utils;

import java.util.ArrayList;
import java.util.List;
import java.net.URL;
import java.net.HttpCookie;

import ti.modules.titanium.network.NetworkModule;
import org.appcelerator.kroll.common.Log;
/**
* This class is a helper for HTTPCookies handling. It uses Titanium's Cookie Manager
* to get all stored cookies and then iterates over it to get cookies matching
* domain and path.
* TODO: check expiration date
*/
public class CookiesHelper
{
private static final String LCAT = "AVImageView";

public static String getCookiesStringForURL(String urlString)
{
try
{
StringBuffer cookieStringBuffer = new StringBuffer();
HttpCookie[] urlCookies = getHTTPCookiesForURL(urlString);

if(urlCookies != null)
{
for(int i=0;i<urlCookies.length;i++)
{
cookieStringBuffer.append(urlCookies[i].getName());
cookieStringBuffer.append("=");
cookieStringBuffer.append(urlCookies[i].getValue());
if(i+1 < urlCookies.length)
{
cookieStringBuffer.append("; ");
}
}
return cookieStringBuffer.toString();
}
else
{
Log.d(LCAT, "No cookie found for " + urlString);
return null;
}
}
catch(Exception ex)
{
Log.w(LCAT, "Exception getting cookies for URL " + urlString + "\n" + ex.getStackTrace());
return null;
}
}

private static HttpCookie[] getHTTPCookiesForURL(String urlString) throws Exception
{
URL url = new URL(urlString);
String domain = url.getHost();
String path = url.getPath();
Log.d(LCAT, "Getting HTTP Cookies for " + domain);

if (domain == null || domain.length() == 0) {
if (Log.isDebugModeEnabled()) {
Log.e(LCAT, "Unable to get the HTTP cookies. Need to provide a valid domain.");
}
return null;
}
ArrayList<HttpCookie> cookieList = new ArrayList<HttpCookie>();
List<HttpCookie> cookies = NetworkModule.getCookieManagerInstance().getCookieStore().getCookies();
for (HttpCookie cookie : cookies) {
String cookieDomain = cookie.getDomain();
String cookiePath = cookie.getPath();
if (domainMatch(cookieDomain, domain) && pathMatch(cookiePath, path)) {
Log.d(LCAT, "Found cookie " + cookie.getName());
cookieList.add(cookie);
}
}
if (!cookieList.isEmpty()) {
return cookieList.toArray(new HttpCookie[cookieList.size()]);
}
return null;
}

/**
* Helper method to decide whether the domain matches the cookie's domain. If the both domains are null, return true.
* The domain matching follows RFC6265 (http://tools.ietf.org/html/rfc6265#section-5.1.3).
* This method is copied by phobeous from Titanium SDK (ti.modules.titanium.network.NetworkModule.java)
* @param cookieDomain cookie's domain
* @param domain domain to match
* @return true if the domain matches cookieDomain; false otherwise. If the both domains are null, return true.
*/
private static boolean domainMatch(String cookieDomain, String domain)
{
if (cookieDomain == null && domain == null) {
return true;
}
if (cookieDomain == null || domain == null) {
return false;
}

String lower_cookieDomain = cookieDomain.toLowerCase();
String lower_domain = domain.toLowerCase();
if (lower_cookieDomain.startsWith(".")) {
if (lower_domain.endsWith(lower_cookieDomain.substring(1))) {
int cookieLen = lower_cookieDomain.length();
int domainLen = lower_domain.length();
if (domainLen > cookieLen -1) {
// make sure bar.com doesn't match .ar.com
return lower_domain.charAt(domainLen - cookieLen) == '.';
}
return true;
}
return false;
} else {
return lower_domain.equals(lower_cookieDomain);
}
}

// Method grabbed from
// http://www.hccp.org/java-net-cookie-how-to.html
private static boolean pathMatch(String cookiePath, String path) {
if(cookiePath == null) {
return true;
} else if (cookiePath.equals("/")) {
return true;
} else if (path.regionMatches(0, cookiePath, 0, cookiePath.length())) {
return true;
} else {
return false;
}
}
}
25 changes: 20 additions & 5 deletions ios/iphone/.gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
# Ignoring bash utility scripts
*.sh

# Ignoring build
build/
.DS_Store
tmp
bin
build
modules
dist
Index
.apt_generated
build.properties
.svn
.settings
*.pyc
*~.nib/
*.pbxuser
*.perspective
*.perspectivev3
*.xcworkspace/
xcuserdata
*.xcuserstate
*.xcuserdata*
5 changes: 4 additions & 1 deletion ios/iphone/Classes/AvImageviewImageView.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,11 @@
NSString *brokenLinkImagePath;

NSDictionary *requestHeader;

SDWebImageOptions handleCookies;
id imageObject;
BOOL configurationComplete;
NSTimeInterval timeout;

}

-(void)setWidth_:(id)width;
Expand Down
Loading

0 comments on commit 936d4d9

Please sign in to comment.