/*
* Copyright (c) 2000-2001 Sun Microsystems, Inc. All Rights Reserved.
*/
import java.lang.*;
import java.io.*;
import java.util.*;
import javax.microedition.io.*;
import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;
/**
* A simple network client.
*
* This MIDlet shows a simple use of the HTTP
* networking interface. It opens a HTTP POST
* connection to a server, authenticates using
* HTTP Basic Authentication and writes a string
* to the connection. It then reads the
* connection and displays the results.
*/
public class NetClientMIDlet extends MIDlet
implements CommandListener {
private Display display; // handle to the display
private Form mainScr; // main screen
private Command cmdOK; // OK command
private Command cmdExit; // EXIT command
private Form dataScr; // for display of results
/**
* Constructor.
*
* Create main screen and commands. Main
* screen shows simple instructions.
*/
public NetClientMIDlet() {
display = Display.getDisplay(this);
mainScr = new Form("NetClient");
mainScr.append("Hit OK to make network connection");
mainScr.append(" ");
mainScr.append("Hit EXIT to quit");
cmdOK = new Command("OK", Command.OK, 1);
cmdExit = new Command("Exit", Command.EXIT, 1);
mainScr.addCommand(cmdOK);
mainScr.addCommand(cmdExit);
mainScr.setCommandListener(this);
}
/**
* Called by the system to start our MIDlet.
* Set main screen to be displayed.
*/
protected void startApp() {
display.setCurrent(mainScr);
}
/**
* Called by the system to pause our MIDlet.
* No actions required by our MIDLet.
*/
protected void pauseApp() {}
/**
* Called by the system to end our MIDlet.
* No actions required by our MIDLet.
*/
protected void destroyApp(boolean unconditional) {}
/**
* Gets data from server.
*
* Open a connection to the server, set a
* user and password to use, send data, then
* read the data from the server.
*/
private void genDataScr() {
ConnectionManager h = new ConnectionManager();
// Set message to send, user, password
h.setMsg("Esse quam videri");
h.setUser("book");
h.setPassword("bkpasswd");
byte[] data = h.Process();
// create data screen
dataScr = new Form("Data Screen");
dataScr.addCommand(cmdOK);
dataScr.addCommand(cmdExit);
dataScr.setCommandListener(this);
if (data == null || data.length == 0) {
// tell user no data was returned
dataScr.append("No Data Returned!");
} else {
// loop trough data and extract strings
// (delimited by '\n' characters
StringBuffer sb = new StringBuffer();
for (int i = 0; i < data.length; i++) {
if (data[i] == (byte)'\n') {
dataScr.append(sb.toString());
sb.setLength(0);
} else {
sb.append((char)data[i]);
}
}
}
display.setCurrent(dataScr);
}
/**
* This method implements a state machine that drives
* the MIDlet from one state (screen) to the next.
*/
public void commandAction(Command c,
Displayable d) {
if (c == cmdOK) {
if (d == mainScr) {
genDataScr();
} else {
display.setCurrent(mainScr);
}
} else if (c == cmdExit) {
destroyApp(false);
notifyDestroyed();
}
}
}
/*
* Copyright (c) 2000-2001 Sun Microsystems, Inc. All Rights Reserved.
*/
/**
* This class encodes a user name and password
* in the format (base 64) that HTTP Basic
* Authorization requires.
*/
class BasicAuth {
// make sure no one can instantiate this class
private BasicAuth() {}
// conversion table
private static byte[] cvtTable = {
(byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E',
(byte)'F', (byte)'G', (byte)'H', (byte)'I', (byte)'J',
(byte)'K', (byte)'L', (byte)'M', (byte)'N', (byte)'O',
(byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T',
(byte)'U', (byte)'V', (byte)'W', (byte)'X', (byte)'Y',
(byte)'Z',
(byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e',
(byte)'f', (byte)'g', (byte)'h', (byte)'i', (byte)'j',
(byte)'k', (byte)'l', (byte)'m', (byte)'n', (byte)'o',
(byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t',
(byte)'u', (byte)'v', (byte)'w', (byte)'x', (byte)'y',
(byte)'z',
(byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4',
(byte)'5', (byte)'6', (byte)'7', (byte)'8', (byte)'9',
(byte)'+', (byte)'/'
};
/**
* Encode a name/password pair appropriate to
* use in an HTTP header for Basic Authentication.
* name the user's name
* passwd the user's password
* returns String the base64 encoded name:password
*/
static String encode(String name,
String passwd) {
byte input[] = (name + ":" + passwd).getBytes();
byte[] output = new byte[((input.length / 3) + 1) * 4];
int ridx = 0;
int chunk = 0;
/**
* Loop through input with 3-byte stride. For
* each 'chunk' of 3-bytes, create a 24-bit
* value, then extract four 6-bit indices.
* Use these indices to extract the base-64
* encoding for this 6-bit 'character'
*/
for (int i = 0; i < input.length; i += 3) {
int left = input.length - i;
// have at least three bytes of data left
if (left > 2) {
chunk = (input[i] << 16)|
(input[i + 1] << 8) |
input[i + 2];
output[ridx++] = cvtTable[(chunk&0xFC0000)>>18];
output[ridx++] = cvtTable[(chunk&0x3F000) >>12];
output[ridx++] = cvtTable[(chunk&0xFC0) >> 6];
output[ridx++] = cvtTable[(chunk&0x3F)];
} else if (left == 2) {
// down to 2 bytes. pad with 1 '='
chunk = (input[i] << 16) |
(input[i + 1] << 8);
output[ridx++] = cvtTable[(chunk&0xFC0000)>>18];
output[ridx++] = cvtTable[(chunk&0x3F000) >>12];
output[ridx++] = cvtTable[(chunk&0xFC0) >> 6];
output[ridx++] = '=';
} else {
// down to 1 byte. pad with 2 '='
chunk = input[i] << 16;
output[ridx++] = cvtTable[(chunk&0xFC0000)>>18];
output[ridx++] = cvtTable[(chunk&0x3F000) >>12];
output[ridx++] = '=';
output[ridx++] = '=';
}
}
return new String(output);
}
}
/*
* Copyright (c) 2000-2001 Sun Microsystems, Inc. All Rights Reserved.
*/
/**
* Manages network connection.
*
* This class established an HTTP POST connection
* to a server defined by baseurl.
* It sets the following HTTP headers:
* User-Agent: to CLDC and MIDP version strings
* Accept-Language: to microedition.locale or
* to "en-US" if that is null
* Content-Length: to the length of msg
* Content-Type: to text/plain
* Authorization: to "Basic" + the base 64 encoding of
* user:password
*/
class ConnectionManager {
private HttpConnection con;
private InputStream is;
private OutputStream os;
private String ua;
private final String baseurl =
"http://127.0.0.1:8080/Book/netserver";
private String msg;
private String user;
private String password;
/**
* Set the message to send to the server
*/
void setMsg(String s) {
msg = s;
}
/**
* Set the user name to use to authenticate to server
*/
void setUser(String s) {
user = s;
}
/**
* Set the password to use to authenticate to server
*/
void setPassword(String s) {
password = s;
}
/**
* Open a connection to the server
*/
private void open() throws IOException {
int status = -1;
String url = baseurl;
String auth = null;
is = null;
os = null;
con = null;
// Loop until we get a connection (in case of redirects)
while (con == null) {
con = (HttpConnection)Connector.open(url);
con.setRequestMethod(HttpConnection.POST);
con.setRequestProperty("User-Agent", ua);
String locale =
System.getProperty("microedition.locale");
if (locale == null) {
locale = "en-US";
}
con.setRequestProperty("Accept-Language", locale);
con.setRequestProperty("Content-Length",
"" + msg.length());
con.setRequestProperty("Content-Type", "text/plain");
con.setRequestProperty("Accept", "text/plain");
if (user != null && password != null) {
con.setRequestProperty("Authorization",
"Basic " +
BasicAuth.encode(user,
password));
}
// Open connection and write message
os = con.openOutputStream();
os.write(msg.getBytes());
os.close();
os = null;
// check status code
status = con.getResponseCode();
switch (status) {
case HttpConnection.HTTP_OK:
// Success!
break;
case HttpConnection.HTTP_TEMP_REDIRECT:
case HttpConnection.HTTP_MOVED_TEMP:
case HttpConnection.HTTP_MOVED_PERM:
// Redirect: get the new location
url = con.getHeaderField("location");
os.close();
os = null;
con.close();
con = null;
break;
default:
// Error: throw exception
os.close();
con.close();
throw new IOException("Response status not OK:"+
status);
}
}
is = con.openInputStream();
}
/**
* Constructor
* Set up HTTP User-Agent header string to be the
* CLDC and MIDP version.
*/
ConnectionManager() {
ua = "Profile/" +
System.getProperty("microedition.profiles") +
" Configuration/" +
System.getProperty("microedition.configuration");
}
/**
* Process an HTTP connection request
*/
byte[] Process() {
byte[] data = null;
try {
open();
int n = (int)con.getLength();
if (n != 0) {
data = new byte[n];
int actual = is.read(data);
}
} catch (IOException ioe) {
} finally {
try {
if (con != null) {
con.close();
}
if (os != null) {
os.close();
}
if (is != null) {
is.close();
}
} catch (IOException ioe) {}
return data;
}
}
}
|