Outgoing HTTP Request

Written by Bruce Cloutier on Dec 8, 2017 10:23 am

To demonstrate an outgoing HTTP request I am going to use the IP Address Location service that our HoneyPot unit uses. This creates the JSONdatabase used to generate the map at http://honeypot.integpg.com/map.php .

The JANOS Runtime Library does not provide classes to handle different web requests. Perhaps over time we will supply external libraries for that. But, you can easily do that directly. And, it is probably more educational to know how things work at the low level.

The procedure is straight forward.

  1. Establish an outgoing socket. (Lines 19-22)
  2. Issue a minimally formatted HTTP request. (Lines 25-27)
  3. Read the response. (Lines 45-50)
  4. Use the data. (Line 53)
package jtest;
 
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.Socket;
 
public class Main {
    
    public static void main(String[] args) throws Exception {
 
        // IP Address query
        String ipaddr = "50.197.34.75";
        
        // Location services
        String serverHostname = "ip-api.com";
        int port = 80;
 
        // Establish a Socket, get streams, and set a timeout
        Socket dataSocket = new Socket(serverHostname, port);
        DataOutputStream sockout = new DataOutputStream(dataSocket.getOutputStream());
        DataInputStream sockin = new DataInputStream(dataSocket.getInputStream());
        dataSocket.setSoTimeout(5000);
 
        // Issue the HTTP request
        sockout.writeBytes("GET /json/" + ipaddr + " HTTP/1.1\r\n");
        sockout.writeBytes("Host: " + serverHostname + "\r\n");
        sockout.writeBytes("\r\n");
 
        // Process the response header
        int length = 0;
        String response;
        while ((response = sockin.readLine()) != null) {
            
            // Header ends with blank line
            if (response.length() == 0)
                    break;
            
            System.out.println(response);
            if (response.startsWith("Content-Length: ")) 
                length = Integer.parseInt(response.substring(16));
        }
        System.out.println();
 
        // Obtain the entire response (if any)
        response = "";
        if (length > 2) {
            byte[] resp = new byte[length];
            sockin.readFully(resp);
            response = new String(resp, "UTF8");
        }
 
        // Data (should be JSON)
        System.out.println(response);
 
        // Close the Socket
        sockout.close();
        sockin.close();
        dataSocket.close();
    }
        
}
bruce_dev /> jtest
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Type: application/json; charset=utf-8
Date: Fri, 08 Dec 2017 14:01:58 GMT
Content-Length: 321

{"as":"AS7922 Comcast Cable Communications, LLC","city":"Pittsburgh","country":"United States","countryCode":"US","isp":"Comcast Business","lat":40.4406,"lon":-79.9959,"org":"Comcast Business","query":"50.197.34.75","region":"PA","regionName":"Pennsylvania","status":"success","timezone":"America/New_York","zip":"15282"}

bruce_dev />

So you can see that the response is JSON and can be easily used.

If you replace line 53 with Debug.dump(response.getBytes()); which is the new dump method in the library the data can be more easily reviewed.

bruce_dev /> jtest
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Type: application/json; charset=utf-8
Date: Fri, 08 Dec 2017 14:27:52 GMT
Content-Length: 321

 7b 22 61 73 22 3a 22 41-53 37 39 32 32 20 43 6f    {"as":"A S7922.Co
 6d 63 61 73 74 20 43 61-62 6c 65 20 43 6f 6d 6d    mcast.Ca ble.Comm
 75 6e 69 63 61 74 69 6f-6e 73 2c 20 4c 4c 43 22    unicatio ns,.LLC"
 2c 22 63 69 74 79 22 3a-22 50 69 74 74 73 62 75    ,"city": "Pittsbu
 72 67 68 22 2c 22 63 6f-75 6e 74 72 79 22 3a 22    rgh","co untry":"
 55 6e 69 74 65 64 20 53-74 61 74 65 73 22 2c 22    United.S tates","
 63 6f 75 6e 74 72 79 43-6f 64 65 22 3a 22 55 53    countryC ode":"US
 22 2c 22 69 73 70 22 3a-22 43 6f 6d 63 61 73 74    ","isp": "Comcast
 20 42 75 73 69 6e 65 73-73 22 2c 22 6c 61 74 22    .Busines s","lat"
 3a 34 30 2e 34 34 30 36-2c 22 6c 6f 6e 22 3a 2d    :40.4406 ,"lon":-
 37 39 2e 39 39 35 39 2c-22 6f 72 67 22 3a 22 43    79.9959, "org":"C
 6f 6d 63 61 73 74 20 42-75 73 69 6e 65 73 73 22    omcast.B usiness"
 2c 22 71 75 65 72 79 22-3a 22 35 30 2e 31 39 37    ,"query" :"50.197
 2e 33 34 2e 37 35 22 2c-22 72 65 67 69 6f 6e 22    .34.75", "region"
 3a 22 50 41 22 2c 22 72-65 67 69 6f 6e 4e 61 6d    :"PA","r egionNam
 65 22 3a 22 50 65 6e 6e-73 79 6c 76 61 6e 69 61    e":"Penn sylvania
 22 2c 22 73 74 61 74 75-73 22 3a 22 73 75 63 63    ","statu s":"succ
 65 73 73 22 2c 22 74 69-6d 65 7a 6f 6e 65 22 3a    ess","ti mezone":
 22 41 6d 65 72 69 63 61-2f 4e 65 77 5f 59 6f 72    "America /New_Yor
 6b 22 2c 22 7a 69 70 22-3a 22 31 35 32 38 32 22    k","zip" :"15282"
 7d                                                 }

bruce_dev />

By the way, the Lat and Lon returned by these sites varies in accuracy. We use the above as a free service. I believe that some services will provide more precise locations when used in a paid mode. The free data however is just fine when mapped on the globe (http://honeypot.integpg.com/map.php).

On this page