Thursday, September 8, 2016

JavaMail, SSL and TLS

For my current project I've had to research the Java Mail api for reading pop3 mail boxes through secure connections, so I thought I'd write a bit about this to save someone else's frustrations.

Currently, SSLv3 is widely unsupported by commercial applications as it is insecure, and it is by default disabled in the JRE. If you need to enable it, comment the line "jdk.tls.disabledAlgorithms=SSLv3" in the java.security file under JRE/lib/security.

TLS 1.0 is the most supported as it is deemed the most secure. TLS 1.1 and 1.2 have more limited support.

This is how you read a pop3 mailbox using TLS:

Properties props = new Properties();

props.put("mail.pop3s.host", "myhost");
props.put("mail.pop3s.port", "995");

props.put("mail.pop3s.ssl.protocols", "TLSv1 TLSv1.1 TLSv1.2");

props.put("mail.pop3s.ssl.enable", "true");
// Add your host here if you want more security; this is enough for testing.
props.put("mail.pop3s.ssl.trust", "*"); 

Session emailSession = Session.getInstance(props);

Store store = emailSession.getStore("pop3s");
store.connect("username", "password");

store.close();


I've tested this successfully with hMailServer using TLS 1.0, 1.1 and 1.2.

If you get that dreaded "PKIX path building failed" exception while connecting, you need to create a self-signed certificate for your server, import it there and add it to your JRE keystore. Trusted authority certificates should work by default (like Google). There's plenty of resources online how to do this so I won't cover it here, just Google how to create self-signed cert using OpenSSL and how to import certificates with java keytool.

Friday, April 27, 2012

Asynchronous file upload with JQuery

Uploading files from a web page without having to reload the page, e.g. asynchronous file uploading, can be achived using AJAX. I used this in a project of mine and thought I'd write about it since it took some time to get it right.

I used the Blueimp JQuery File Upload widget. Out of box, it enables sending multiple files via one upload widget, a very nice UI and other neat features. Since I had no need for the built-in UI, I grabbed the basic plugin version and built my own UI from that. I also needed to have several upload widgets created on dynamic content. Out of box, the basic version works so that when a file is chosen its immediately uploaded, which isn't what I wanted so I also extended the plugin with programmatic uploading.

Basically you need two files, jquery.fileupload.js and also the jquery.iframe-transport.js that you can find in one of the packages from the Blueimp project site. Add those two to your page's header:


<head>
   <script src="fileupload.js" type="text/javascript"></script>
   < script src="jquery.iframe-transport.js"></script>
</head>

For the purposes of this post, I'm using a simple case of an intranet with dynamic content where you need to upload files into items on the page.

Let's assume you have a page that fetches data from a database and creates a list. I'm using Java for this example:


<%
for (int i = 0; i < myItems.size(); i++) {
Item item = myItems.get(i);
%>
Upload file for: <%=item.getName()%><br><br>
<input class="myFileClass" id="myFile_<%=item.getId()%>" type="file" name="theFile"><br /><br />

<div id="uploadButtonLayer_<%=item.getId()%>"><input type="button" class="uploadButton" id="uploadButton_<%=item.getId()%>" value="Upload"></div>
<div id="uploadProgressLayer_<%=item.getId()%>" style="display:none"></div>
<%
}
%>

Lets break this down. We loop through whatever items. First, create a file input element that will be used for the Blueimp plugin's widget. The elements needs an explicit ID, which we generate from the items' IDs. Also, to identify all the input fields give them a class that we can reference from JQuery (myFileClass).

Next we add a layer for the submit button and the progress. Each also need an explicit ID, again generated from the items' IDs.

To the button layer, insert a simple button, again with an explicit ID.

Next, the JQuery part, comments included:



// Create a widget from each input element
$('.myFileClass').fileupload({
// The file parameter name that is passed to the handler page
paraName: 'image',
// URL for the page handling the post
url: 'some_handler_page',
// Format for return value from the handle rpage
dataType: 'json',
// Limit selected files 1
maxNumberOfFiles: 1,
// If true, replaced the input element, which means the selected file's name won't be displayed.
replaceFileInput: false,
// Event handler for when a file is selected. We override it here so it won't be immediately uploaded
add: function(e, data) {
// Here we grab the ID of the item this upload widget belongs to (myFile_xxxx)
var id = $(e.target).attr('id').substring(7, $(e.target).attr('id').length);
// Pass the ID to the handler page as a parameter
$(this).fileupload('option', { formData: { 'itemId':id } });

// Now, bind a click handler to the item's upload button
$('#uploadButton_' + id).on('click', function() {
// Grab the ID from the upload button again (uploadButton_xxxx)
id = $(this).attr('id').substring(13, $(this).attr('id').length);
// Hide the upload button so that user won't click it more than once for this upload
$('#fileUploadButton_' + id).hide();
// Show the progress layer. Get a 'loader.gif' of your own if you want some nice animation :)
$('#fileUploadProgress_' + id).show().html('<img src="/img/loader.gif">&nbsp;&nbsp;Uploading, please wait ...');
// Submit the data.
// JQuery stores the data in the context of this widget and it's button, so that even though
// there are multiple widgets and buttons on the page, the correct data is submitted.
data.submit();
// Unbind the click event from the button. If not unbound and the user sends another file through
// the same widget, the previous file will also be sent
$(this).unbind('click');
});
},
// Basic AJAX success event that fires when the handler page is ready and returns something.
// For this example, the handler page returns JSON data containing the ID of the item
success: function(data) {
// Show the upload button
$('#uploadButtonLayer_' + data.id).show();
// Hide the progress layer
$('#uploadProgressLayer_' + data.id).hide();
},
// Progress event that fires every 100 milliseconds or so
// Used to calculate upload progress
progress: function(e, data) {
// Grab the ID of the item from the event (the widget is the target)
var id = $(e.target).attr('id').substring(7, $(e.target).attr('id').length);
// Calculate progress
var progress = parseInt(data.loaded / data.total * 100, 10);
// Update the text on the layer.
$('#uploadProgressLayer_' + id).html('<img src="/img/loader.gif">&nbsp;&nbsp;' + progress + '%');
}
});

If you need help or more detailed explanation please leave a comment and I'll try to answer asap.

Coding of the upload handler page is up to you. It's language dependent anyway :)






URL encoding in Java

Encoding URLs in Java is quite trivial. However, too often I see people using the URLEncoder class for this. This is WRONG.

The URLEncoder class is used for encoding form data into xxx-form-urlencoded -format. Even though very poorly named, it does say this in the Javadocs ;)

The proper class for URL encoding is the URI class.

Lets assume we have an URL such as http://www.somedomain.com/shop/Blue Widgets

If you encode this with the URLEncoder class, you get:

http%3A%2F%2Fwww.somedomain.com%2FBlue+Widgets

Unreadable and incorrectly encoded. Reserved characters such as : and / should not be encoded. Also, the URLEncoder encodes empty space as "+" even though it should be encoded as "%20".

With the URI class, you get:

http://www.somedomain.com/Blue%20Widgets

Which is correct.

To construct as simple URL like the example above with the URI class:

URI myURI = new URI("http", "www.somedomain.com", "/Blue Widgets");

And to get the URL in an encoded format:

String url = myUri.toASCIIString();


JBoss and UTF-8 character encoding

Often you might face problems with character encoding, either in page content, form data or URL params. Data stored to or retrieved from a database doesn't show correct characters, submitted form data and query parameters are shown incorrectly.

Usually it's recommended to use UTF-8 encoding wherever possible. Here's how to set up JBoss so that it really really uses UTF-8 everywhere.

First of all, in your JSP/JSF pages set the HTTPRequest encoding as follows:

<%
   request.setCharacterEncoding("UTF-8");
%>

I usually also set the encoding via a JSP tag just to make sure:

<%@page contentType="text/html; charset=UTF-8"%>

Next, add a META tag to your HTML so that the browser (and search engines) also know your encoding:

<head>
   <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
</head>

Is that it ? No. JBoss encodes URL parameters with ISO-8859-1, so you need to tune the server.xml file located under /deploy/jboss-web.sar/. To the <connector> element (for either HTTP or AJP or both) you need to add URIEncoding="UTF-8".

Lastly, if you're using a database such as PostgreSQL, remember to create your database with UTF-8 encoding.


Tuesday, April 12, 2011

Get image width & height with Javascript

Ever needed to get the real dimensions of an image with javascript that works on all browsers, even when the width and height hasn't been explicitly set (either on the img tag or with css) ? Here's how to do it

Include JQuery on your page

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.min.js" type="text/javascript"></script>

Give your image an explicit id:

<img id="someId" src="mypicture.jpg" />

Use this JQuery snippet to get the width and height:

// Our vars holding the width and height
var pic_width, pic_height;

// Load an image into memory, to prevent any css affecting it
var img = $('<img />');

// Bind the image to an onload event
img.bind('load', function() {
  pic_width = this.width;
  pic_height = this.height;
});

// Load the image, onload will fire and store width and height
$(img).attr('src', $('#someId).attr('src'));

The onload event needs to be bound before loading the actual image to make sure it fires.

Sunday, March 27, 2011

Working with JQuery UI icons

First of all, JQuery is total awesomeness. 'nuff said.

Using the icons is not as straightforward as you might think. Basically to use an icon on a page, you need to have the CSS included. Google hosts the themes so you can link to these to save your bandwidth, which is nice. For example if you wanted to use the 'darkness' theme, you need to add this to the <head> part of your page:

<link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.9/themes/ui-darkness/jquery-ui.css" rel="stylesheet" type="text/css" />

The themes contain a lot of nice icons. You can see all of the themes and icons at the JQuery UI Themeroller. To see the class of an icon on the page, simpy mouse over it.

To add an icon on a page (a trashcan in this example), you need to add a <span> element as follows:

<span class="ui-icon ui-icon-trash ui-state-default" title="Whatever mouseover text you want"></span>

This creates the icon surrounded by a rectangle. If you want to use a different icon, simply replace the 'ui-icon-trash' class with the class of the icon you want. If you do not wish to see the rectangle surrounding it, remove the 'ui-state-default' class from it.

First thing you need to know that the icons are block level elements. That means any text or elements following the icon will be placed on a newline. To counter this, you can either place the icon and the following text/whatnot in a table in separate cells, or add an inline float style to the <span>:

<span class="ui-icon ui-icon-trash ui-state-default" title="Whatever mouseover text you want" style="float:left;"></span>

Make it a link

To  make the icon act as a link, you need to bind it to a click event with JQuery. Include the JQuery libs (again from Google) in your header:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.min.js" type="text/javascript"></script>

Now, place the following code to your page's header:

<script type="text/javascript">
  $(function() {
    $('.makeMeALink').click(function() {
      document.location.href = 'someUrl';
    });

  }
</script>

Here we bind the 'makeMeALink' selector to a click event, and make it open the URL 'someUrl' in the current browser window. Replace 'someUrl' with the address you want the link to point to. Now, add the 'makeMeALink' selector to the icon as a class and the icon will function like a link:

<span class="ui-icon ui-icon-trash ui-state-default makeMeALink" title="Whatever mouseover text you want" style="float:left;"></span>

Why do we do it like this, and not just wrap the <span> element in a link tag ? Sure, we could do this also:

<a href="someurl"><span class="ui-icon ui-icon-trash ui-state-default" title="Whatever mouseover text you want" style="float:left;"></span></a>

It pretty much does the same thing, but in case you wanted to reuse the click binding on some other element, or expand the functionality to for example showing a modal confirmation dialog, you need to use the click event binding.

Make it appear as a link

The thing is that users won't actually realize its a link, as putting the cursor over it still shows the default cursor, and the icon does not animate/highhlight or the such to indicate its clickable. We can use JQuery to bind a mouseover event to 'highlight' the icon and change the cursor. Modify the JQuery in the header to look as follows:

<script type="text/javascript">
  $(function() {
    $('.makeMeALink').click(function() {
      document.location.href = 'someUrl';
    });


     $('.hoverAnimation').hover(function() {
      $(this).addClass('ui-state-hover');
    }, function() {
      $(this).removeClass('ui-state-hover');
    });


    $('.changeCursor').hover(function() {
      $(this).css('cursor', 'pointer');
    });

  }
</script>

Basically, we define two hover bindings for the 'hoverAnimation' and 'changeCursor' selectors. The 'hoverAnimation' selector when placed on an element will add the 'ui-state-hover' CSS class to the element when the user puts his/her mouse over it, and removes the class when the mouse moves outside the element. The 'ui-state-hover' class is built in to the JQuery UI themes and will work with any theme.

The 'changeCursor' binding will change the cursor to a pointer when the mouse is placed over the icon, the same way it does when you place your mouse over a link.

Now, add these two selectors to the icon:

<span class="ui-icon ui-icon-trash ui-state-default makeMeALink hoverAnimation changeCursor" title="Whatever mouseover text you want" style="float:left;"></span>

Now you have an icon that acts as a link, changes cursor like a link, and when pointed with a mouse will be highlighted.

Saturday, March 26, 2011

Implementing a visitor counter in Java

If you're running a Java-based site, here's how you can track the number of concurrent visitors on your site. The code can be easily extended to support a variety of functions, for example tracking who of your visitors is currently logged in.

Add this to each of your JSP/JSF files:

 SessionTracker tracker = SessionTracker.getInstance();
 String agent = request.getHeader("user-agent");

 if (agent != null) {

  // Check the user-agent from the request, we don't want to track crawlers. Add as many agents as you like to exclude.
  agent = agent.toLowerCase();
  if (agent.indexOf("googlebot") == -1 && agent.indexOf("msnbot") == -1 && agent.indexOf("slurp") == -1) {

   // Current version of Opera has a bug that causes it to make two requests to a page; the other one does not have a 'cookie' header set, so only regard the 'real' request

   if (agent.toLowerCase().indexOf("opera") != -1) {
    if (request.getHeader("cookie") != null) {
     tracker.trackSession(session);
    }
   } else {
    tracker.trackSession(session);
   }
  }
 } 


And on the page(s) where you wish to print the number of visitors, add:

<%=tracker.getNumberOfSessions()%>

The actual tracking class:

import java.util.*;
import javax.servlet.http.HttpSession;

public class SessionTracker extends Thread {
 private static SessionTracker instance = null;
 private static Hashtable<String, HttpSession> data = null;

 // How long to wait between visitor checks
 private static final int sleep = 60 * 1000;
 // How long a session can be idle until it is not counted
 private static final int reapTime = 10 * 60 * 1000;

 private SessionTracker() {
  data = new Hashtable<String, HttpSession>();
 }

 public static synchronized SessionTracker getInstance() {
  if (instance == null) {
   instance = new SessionTracker();
   instance.start();
  }

  return instance;
 }

 public void trackSession(HttpSession session) {
  data.put(session.getId(), session);
 }

 public int getNumberOfSessions() {
  return data.size();
 }

 public void run() {
  while (true) {
   instance = this;

   Enumeration<String> enu = data.keys();

   while (enu.hasMoreElements()) { 
    String key = enu.nextElement();
    HttpSession session = data.get(key);
 
    long diff = System.currentTimeMillis() - session.getLastAccessedTime();
 
    if (diff > reapTime) {
     data.remove(key);
    }
   }

   synchronized(this) {
    try {
     this.wait(sleep);
    } catch (Exception e) {
     e.printStackTrace();
    }
   }
  }
 }
}