Tuesday, May 14, 2013

HTTPBuilder Requests with Local SSL Certificate in Grails

HTTPBuilder APIs for Groovy which is a wrapper for Apache's HTTPClient allows to make HTTP/HTTPS requests from JVM. Making HTTP requests are pretty straight forward. However, HTTPS requests to local server running a self-signed SSL certificate involves a bit of work.

HTTPBuilder APIs are available to grails as a plugin, called rest. To install the plugin go to the grails project directory and run
grails install-plugin rest
1. Run the grails application with HTTPS.
2. Access the home page over HTTPS which will display a security warning. If you are using Firefox, choose 'View' in the 'Add Security Exception' dialog to view the SSL certificate. From the details tab, choose 'Export' and save as X.509 Certificate (PEM) with file name, say 'localhost' which will be saved as 'localhost.crt'.
3. Now we have to import the certificate to the Java keystore. From terminal (cmd), navigate to the location where the certificate is saved and type the following command:
keytool -importcert -alias "subdomain.your-website-domain.com" -file localhost.crt -keystore truststore.jks -storepass password1234
4. Copy the truststore.jks file created in step 3 to grails-app/conf folder.
5. RestConnector is a simple example which can be used for HTTP request. We will modify the class to support HTTPS requests.
//RestConnector.groovy
import grails.converters.JSON

import groovyx.net.http.HTTPBuilder
import groovyx.net.http.ContentType
import groovyx.net.http.Method
import org.apache.http.impl.client.DefaultRedirectStrategy
import org.apache.http.impl.cookie.BasicClientCookie

import java.security.KeyStore
import org.apache.http.conn.scheme.Scheme
import org.apache.http.conn.ssl.SSLSocketFactory
import org.apache.http.HttpRequest
import org.apache.http.HttpResponse
import org.apache.http.protocol.HttpContext

import javax.servlet.http.HttpServletResponse
import javax.servlet.http.Cookie

import groovyx.net.http.Method
import groovyx.net.http.ContentType
import groovyx.net.http.HTTPBuilder
import groovyx.net.http.HttpResponseDecorator

class RestConnector {
    private String baseUrl
    private HTTPBuilder httpBuilder
    private List<string> cookies

    RestConnector(String url) {
        this.baseUrl = url
        this.httpBuilder = initializeHttpBuilder()
        this.cookies = []
    }

    public def request(Method method, ContentType contentType, String url, Map<String, Serializable> params) {
        debug("Send $method request to ${this.baseUrl}$url: $params")

        // import the key from the keystore
        def keyStore = KeyStore.getInstance(KeyStore.defaultType)
        getClass().getResource( "/truststore.jks").withInputStream {
            keyStore.load(it, "password1234".toCharArray())
        }
        SSLSocketFactory sf = new SSLSocketFactory(keyStore)
        sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER)
        httpBuilder.client.connectionManager.schemeRegistry.register(new Scheme("https", sf, 443))

        httpBuilder.request(method, contentType) { request ->
            uri.path = url
            //uri.query = params
            headers['Cookie'] = cookies.join(';')
            requestContentType = ContentType.URLENC
            // sample params
            body = ['username': "${params.username}", 'password': "${params.password}", 'otherParams': "${params.otherExampleParams}"]
            headers.'Connection' = params['Connection']
            headers.'Cookie' = params['Cookie']
            println("::Cookie: -> " + params['Cookie'])
            headers.'Host' = params['Host']
            headers.'X-Requested-With' = params['X-Requested-With']
            headers.'Origin' = params['Origin']
        }
    }

    private HTTPBuilder initializeHttpBuilder() {
        def httpBuilder = new HTTPBuilder(baseUrl)

        httpBuilder.handler.success = { HttpResponseDecorator resp, reader ->
            resp.getHeaders('Set-Cookie').each {
                //[Set-Cookie: JSESSIONID=E68D4799D4D6282F0348FDB7E8B88AE9; Path=/frontoffice/; HttpOnly]
                String cookie = it.value.split(';')[0]
                debug("Adding cookie to collection: $cookie")
                cookies.add(cookie)
            }
            if (resp.status == 302) {
                println('302 detected')
                return ['status': 'redirect', 'response': resp]
            }
            debug("Resp: ${resp}")
            debug("Reader: ${reader}")
            return ['status': 'ok', 'result': reader]
        }

        // Enable to follow redirect requests
        /*httpBuilder.client.setRedirectStrategy(new DefaultRedirectStrategy() {
            @Override
            boolean isRedirected(HttpRequest request, HttpResponse response, HttpContext context) {
                def redirected = super.isRedirected(request, response, context)
                return redirected || response.getStatusLine().getStatusCode() == 302
            }
        })*/
        return httpBuilder
    }

    private debug(String message) {
        System.out.println(message) //for Gradle
    }
}
6. Using the above class in a grails controller:
//ExampleController.groovy
// ..imports
class ExampleController {
    def index() {
        String serverName = request.getServerName()
        String serverUrl = "https://${serverName}"
        RestConnector restConnector = new RestConnector(serverUrl)  //some https url here
        def result = restConnector.request(Method.POST, ContentType.JSON, "${serverUrl}", ['username': "${username}", 'password': "${password}", 'otherParam': "${otherParam}"])
        if (result.status == "redirect") {
            def resp = result.response
            def heads = resp.getHeaders()
            redirect(uri: 'redirect-uri-here')
        } else if (result.status == "ok") {
            render (result.result as JSON)
        }
    }
}
●๋•‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗●๋•

Sunday, April 14, 2013

Atheros: Share Internet Connection via WiFi in XP

Say that your computer (running Windows XP) is connected to internet via LAN and you wanted to the connection to other devices via WiFi.
1. Goto control panel -> Network Connections.
2. Right-click on the Local Area Connection and choose Properties.
3. In the Advanced Tab under the Internet Connection Sharing, enable "Allow other users to connect through this computer's internet connection".

The next part is to create an adhoc wifi connection. My netbook comes with an Atheros wireless network adapter. So I am using Atheros Client Utility to configure wireless connections. You may use Windows XP's default tool as well.
1. Open Atheros Client Utility.
2. Under Profile Management tab, click New.
3. Fill in the profile name and give an name for identifying the wifi connection under the SSID1.
4. In the Advanced tab, change network type to Ad-Hoc.
5. In the Security tab, choose Pre-Shared Key (Static WEP) and click Configure.
6. In the popup menu, choose ASCII Text for Key Entry and give a password in the Encryption Keys section for WEP Key 1 (one would be enough). Depending on the chosen WEP Key Size, the length of the key varies.
7. Click Ok and finish the configurations.
8. Back in the Profile Management, choose the currently created profile and click Activate.

Now you can connect to the internet via the newly created Ad-Hoc WiFi connection. To connecting to the network, you need to enter the same password given for the WEP key in step 6 above.
●๋•‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗●๋•

Tuesday, April 2, 2013

Immediately-Invoked Function Expression (IIFE) in Groovy & JavaScript

Immediately invoked function expressions are anonymous function blocks executed soon at the end of the block giving the return value. IIFEs are very common in JavaScript.
// IIFE in js
(function(arg) {
    if (arg === 1)
        return "one";
    else
        return "not one";
})(1);
In Groovy the same thing can be done using anonymous blocks which the language names as 'closure'. It is not the lexical closure that we are talking about, though it can be. The 'Closure' in Groovy is just a block of code.
Anyway we can have an IIFE in groovy using blocks and invoking it at the end of the block as shown below. Since the evaluated value is returned, we can omit the return statement.
// IIFE in Groovy
{arg ->
    if (arg == 1)
        "one"
    else
        "not one"
}(1)
●๋•‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗●๋•

Thursday, March 7, 2013

Bookmarks Organizer Google Chrome Extension

Bookmarks Organizer Google Chrome Extension helps us in keeping the bookmarks sorted. By default Chrome does not sort bookmarks by title. This extension monitors for newly added or moved bookmarks and auto arranges them in ascending order by title. There is a reorder button to manually order the whole bookmark, which can be used initially after installation. The only down side is that there is API restriction on the number of bookmarks that can be reordered (moved) per min, per hour and the number is a bit low.
This extension is available at Chrome Web Store. The code is licensed under GNU GPL v3 and is available at the github repository.
●๋•‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗●๋•

Monday, March 4, 2013

Copy Files with Excludes

The cp command does not have an excludes option. One way to copy files ignores some files or directories is to create a tarball. The tar command has an exclude option. The exclude patterns can be mentioned in a separate file and passed in to the tar command.
# Directory Structure
BO
│   .git
│   .gitignore
│   books.html
│   book.js
│   build.sh
│   buildExcludes
│   main.js
│   manifest.json
│
├───bin
│   └───BO
│       │   books.html
│       │   books.js
│       │   main.js
│       │   manifest.json
│       │
│       └───res
│           └───icons
│                   bo-128.png
│                   bo-16.png
│                   bo-256.png
│                   bo-32.png
│                   bo-48.png
│                   bo-512.png
│                   bo-64.png
│
└───res
    └───icons
            bo-128.png
            bo-16.png
            bo-256.png
            bo-32.png
            bo-48.png
            bo-512.png
            bo-64.png
            bo.fla
In the above directory structure, I want to copy certain file to bin/BO but ignore others like .git, fla files in the res/icons directory, the build scripts etc. For that first create an file say buildExcludes with the exclude pattern.
Content of the exclude file is given below.
.git
.gitignore
bin
res/icons/*.fla
build.sh
buildExcludes
Create the tar, deflate to the destination directory and delete the tar once done.
tar -cvf bo.tar * -X buildExcludes  #create tar
tar -xvf bo.tar -C bin/BO/          #deflate to destination directory
rm -f bo.tar                        #cleanup
●๋•‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗●๋•

Wednesday, February 20, 2013

Get Timestamp for the Present Day in Java

// Snippet for getting timestamp in milliseconds for the present day with time taken as 00:00:00
// Eg: ts for '2013-02-19'
public long getTsForToday() {
    Calendar cal = Calendar.getInstance();
    int year = cal.get(cal.YEAR);
    int month = cal.get(cal.MONTH);
    int date = cal.get(cal.DATE);
    cal.clear();
    cal.set(Calendar.YEAR, year);
    cal.set(Calendar.MONTH, month);
    cal.set(Calendar.DATE, date);
    return cal.getTimeInMillis();
}
●๋•‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗●๋•

Tuesday, February 19, 2013

Inject Service Class into src/groovy Classes

The groovy classes placed in the src/groovy folder does not have dependency injection by default. However we can manually inject service classes into the normal groovy classes.
package com.example.ExampleClass

import org.codehaus.groovy.grails.web.context.ServletContextHolder
import org.codehaus.groovy.grails.web.servlet.GrailsApplicationAttributes

class ExampleClass {
    def context = ServletContextHolder.servletContext.getAttribute(GrailsApplicationAttributes.APPLICATION_CONTEXT)
    def exampleService = context.exampleService //service injection
}
●๋•‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗●๋•