java.net.SocketException: Unexpected end of file from server
The client sends a query to the server by using an URL. I have a HTTPServer that parses info from the URL. Using that info, the server does some work and then returns the response to the client.
Let's say the URL is:
http://localhost:9090/find?term=healthy&term=cooking&count=3
This works fine. But when count is greater or equal to 4, I get java.net.SocketException.
To debug the error, I print out the URL. System.out.println(input);
When count>=4, the URL gets printed two times in the console. Please help.
private final HttpServer server;
public Server(int port){
server = HttpServer.create(new InetSocketAddress(port), MAX_BACKLOG);
server.createContext("/isbn", new ISBNHandler());
server.createContext("/find", new TitleHandler());
}
static class TitleHandler implements HttpHandler {
public void handle(HttpExchange t) throws IOException {
int count=5;
String input=t.getRequestURI().toASCIIString();//get the URL
System.out.println(input);
//using info from URL to do some work
String response = builder.toString();//StringBuilder
// System.out.println(response);
t.sendResponseHeaders(200, response.getBytes().length);
OutputStream os = t.getResponseBody();
os.write(response.getBytes());
os.close();
}
}
Exception
java.net.SocketException: Unexpected end of file from server at
sun.net.www.http.HttpClient.parseHTTPHeader(Unknown Source) at
sun.net.www.http.HttpClient.parseHTTP(Unknown Source) at
sun.net.www.http.HttpClient.parseHTTPHeader(Unknown Source) at
sun.net.www.http.HttpClient.parseHTTP(Unknown Source) at
sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown
Source) at java.net.HttpURLConnection.getResponseCode(Unknown Source)
at TestHarness.assertJSONResponse(TestHarness.java:101) at
TestHarness.testServer(TestHarness.java:38) at
TestHarness.main(TestHarness.java:25)
TestHarness
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Sample main method with initial acceptance tests to help you along
*/
public class TestHarness {
private static Pattern MAP_PATTERN = Pattern.compile("(['\"])(.*?)\\1:\\s*(['\"])(.*?)\\3");
private static Pattern LIST_PATTERN = Pattern.compile("\\{(.*?)\\}");
public static void main(String[] args) throws IOException {
/*
if (args.length < 1) {
System.out.println("The test harness requires a single parameter: the location of the CSV file to parse");
}
*/
BookServer server = new BookServer(9090, new File("books.csv"));
server.start();
testServer();
server.stop();
}
/**
* Run initial acceptance tests
*/
#SuppressWarnings("unchecked")
private static void testServer() {
assertJSONResponse("Book Test", "http://localhost:9090/isbn/9780470052327",
createMap("isbn", "9780470052327", "title", "Techniques of Healthy Cooking", "author", "Mary Dierdre Donovan", "publisher", "Wiley", "publishedYear", "2007"));
assertJSONResponse("Book Test", "http://localhost:9090/isbn/9780451169525",
createMap("isbn", "9780451169525", "title", "Misery", "author", "Stephen King", "publisher", "Signet", "publishedYear", "1987"));
assertJSONResponse("Query Test", "http://localhost:9090/find?term=healthy&term=cooking&count=4",
Arrays.asList(createMap("isbn", "9780470052327", "title", "Techniques of Healthy Cooking", "author", "Mary Dierdre Donovan", "publisher", "Wiley", "publishedYear", "2007")));
}
/**
* Helper method to convert the vararg parameters into a Map. Assumes alternating key, value, key, value... and calls
* toString on all args
*
* #param args the parameters to put in the map, alternating key ancd value
* #return Map of String representations of the parameters
*/
private static Map<String, String> createMap(Object ... args) {
Map<String, String> map = new HashMap<String, String>();
for (int i=0; i < args.length; i+=2) {
map.put(args[i].toString(), args[i+1].toString());
}
return map;
}
/**
* Parses a JSON list of maps
* NOTE: assumes all keys and values in the nested maps are quoted
*
* #param content the JSON representation
* #return a list of parsed Map content
*/
private static List<Map<String, String>> parseJSONList(CharSequence content) {
List<Map<String, String>> list = new ArrayList<Map<String, String>>();
Matcher m = LIST_PATTERN.matcher(content);
while(m.find()) {
list.add(parseJSONMap(m.group(1)));
}
return list;
}
/**
* Parse JSON encoded content into a Java Map.
* NOTE: Assumes that all elements in the map are quoted
*
* #param content the JSON representation to be parsed
* #return A map of parsed content
*/
private static Map<String, String> parseJSONMap(CharSequence content) {
Map<String, String> map = new HashMap<String, String>();
Matcher m = MAP_PATTERN.matcher(content);
while (m.find()) {
map.put(m.group(2), m.group(4));
}
return map;
}
/**
* Retrieve content from a test URL and assert that its content is the expected. Results will be printed to System.out for convenience
*
* #param testName Name of the test, to be used simply for labelling
* #param urlString The URL to test
* #param expected The content expected at that URL
*/
private static void assertJSONResponse(String testName, String urlString, Object expected) {
try {
URL url = new URL(urlString);
HttpURLConnection con = ((HttpURLConnection)url.openConnection());
if (!assertTest(testName + " - response code", con.getResponseCode(), 200)) return;
StringBuilder b = new StringBuilder();
BufferedReader r = new BufferedReader(new InputStreamReader(con.getInputStream()));
String line;
while((line = r.readLine()) != null) b.append(line);
String result = b.toString();
assertTest(testName + " - content retrieved", !result.isEmpty(), true);
Object parsed = result.trim().startsWith("[") ? parseJSONList(result) : parseJSONMap(result);
assertTest(testName + " - parsed content match", parsed, expected);
} catch (Exception e) {
System.out.println(testName + ": <<<FAILED with Exception>>>");
e.printStackTrace(System.out);
}
}
/**
* Log the results of a test assertion
*
* #param testName Name of the test, to be used simply for labelling
* #param result The result of the operation under test
* #param expected The expected content that the result will be compared against
* #return whether the test was successful
*/
private static boolean assertTest(String testName, Object result, Object expected) {
boolean passed = result.equals(expected);
System.out.println(testName + (passed ? ": <<<PASSED>>>" : String.format(": <<<FAILED>>> expected '%s' but was '%s'", expected, result)));
return passed;
}
}
I fixed the error. The server calls a private sorting function, but I made a bug in the sorting function. The server crashed.
Related
I am trying to import a class of a jar file.
I am able to import every class except one.
Here you can see the jar which contains all the classes I would like to import:
Here you can see the import, missing the HexoskinHTTPClient class:
The class itself looks as follows:
package com.companyname.hexoskin;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.companyname.hexoskin.models.HexoskinDataPoint;
import com.companyname.hexoskin.models.HexoskinRecord;
import com.companyname.hexoskin.models.HexoskinDatatype;
import com.companyname.hexoskin.models.HexoskinUnit;
import kong.unirest.Unirest;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.text.DecimalFormat;
import java.util.*;
class HexoskinHTTPClient {
private String host;
private String[] incompatibleDatatypes = {"8192", "8193", "8194", "1019", "54", "215", "281", "282", "283", "1053", "1049"};
/**
* Constructor
* #param host: The url of the API
*/
HexoskinHTTPClient(String host) {
this.host = host;
}
/**
* https://api.hexoskin.com/docs/resource/record
* #return ArrayList: List of records of type HexoskinRecord
* #throws IOException
*/
ArrayList<HexoskinRecord> getRecordsWithoutDetails() throws IOException {
// Fetch records
String response = Unirest.get(this.host + "record" + "?limit=0")
.basicAuth(HexoskinCredentials.user, HexoskinCredentials.password)
.asString()
.getBody();
// Get records array from response
ObjectMapper objectMapper = new ObjectMapper();
JsonNode records = objectMapper.readTree(response).get("objects");
// Extract relevant properties and create object
ArrayList<HexoskinRecord> hexoskinRecords = new ArrayList<>();
for(int i = 0; i < records.size(); i++) {
HexoskinRecord hexoskinRecord = objectMapper.readValue(records.get(i).toString(), HexoskinRecord.class);
hexoskinRecords.add(hexoskinRecord);
}
return hexoskinRecords;
}
/**
* https://api.hexoskin.com/docs/resource/datatype
* #return ArrayList: List of datatypes of type HexoskinDatatype
* #throws IOException
*/
ArrayList<HexoskinDatatype> getDatatypes() throws IOException, URISyntaxException {
// Fetch records
String response = Unirest.get(this.host + "datatype?limit=0")
.basicAuth(HexoskinCredentials.user, HexoskinCredentials.password)
.asString()
.getBody();
// Get datatypes array from response
ObjectMapper objectMapper = new ObjectMapper();
JsonNode datatypes = objectMapper.readTree(response).get("objects");
// Convert String Array to List
List<String> incompatibleDatatypesAsList = Arrays.asList(incompatibleDatatypes);
// Extract relevant properties and create object
ArrayList<HexoskinDatatype> hexoskinDatatypes = new ArrayList<>();
for(int i = 0; i < datatypes.size(); i++) {
// filter out incompatible types
if (!incompatibleDatatypesAsList.contains(datatypes.get(i).get("id").toString())) {
HexoskinDatatype hexoskinDatatype = objectMapper.readValue(datatypes.get(i).toString(), HexoskinDatatype.class);
// Get the unit id from unit uri
URI uri = new URI(hexoskinDatatype.getUnit());
String[] segments = uri.getPath().split("/");
String id = segments[segments.length - 1];
// Create the unit object
HexoskinUnit hexoskinUnit = this.getUnit(id);
hexoskinDatatype.setUnitObject(hexoskinUnit);
hexoskinDatatypes.add(hexoskinDatatype);
}
}
return hexoskinDatatypes;
}
/**
* https://api.hexoskin.com/docs/resource/unit
* #param unitToFetch: The id of the unit of which data should be fetched
* #return Hashmap: Map of units of type HexoskinUnit
* #throws IOException
*/
HexoskinUnit getUnit(String unitToFetch) throws IOException {
// Fetch records
String response = Unirest.get(this.host + "unit/" + unitToFetch)
.basicAuth(HexoskinCredentials.user, HexoskinCredentials.password)
.asString()
.getBody();
// Get unit from response
ObjectMapper objectMapper = new ObjectMapper();
JsonNode unit = objectMapper.readTree(response);
HexoskinUnit hexoskinUnit = objectMapper.readValue(unit.toString(), HexoskinUnit.class);
return hexoskinUnit;
}
/**
* https://api.hexoskin.com/docs/resource/data/
* #param recordId: The id of the record of which data should be fetched
* #param datatypes: The datatypes to fetch
* #return ArrayList: List of datapoints of type HexoskinDataPoint
* #throws IOException
*/
ArrayList<HexoskinDataPoint> getRecord(String recordId, ArrayList<HexoskinDatatype> datatypes) throws IOException {
String datatypesList = "";
for(int i = 0; i < datatypes.size(); i++) {
datatypesList += datatypes.get(i).getId();
if (i < datatypes.size() - 1) {
datatypesList += ",";
}
}
String response = Unirest.get(this.host + "data?datatype__in=" + datatypesList + "&record=" + recordId + "&limit=0")
.basicAuth(HexoskinCredentials.user, HexoskinCredentials.password)
.asString()
.getBody();
// Get data array from response
ObjectMapper objectMapper = new ObjectMapper();
JsonNode dataPointWrappers = objectMapper.readTree(response).get(0).get("data");
// Extract relevant properties and create object
ArrayList<HexoskinDataPoint> hexoskinDataPoints = new ArrayList<>();
for(int i = 0; i < datatypes.size(); i++) {
JsonNode dataPointWrapper = dataPointWrappers.get(datatypes.get(i).getId());
// Only create data points for entries with subentries
if (dataPointWrapper != null && dataPointWrapper.size() != 0) {
for(int j = 0; j < dataPointWrapper.size(); j++) {
HexoskinDataPoint hexoskinDataPoint = new HexoskinDataPoint(datatypes.get(i).getId());
if (dataPointWrapper.get(j).get(0) != null && !dataPointWrapper.get(j).get(0).toString().equals("null")) {
// Remove decimals which cause scientific notation strings
double secondNumber = Double.parseDouble(dataPointWrapper.get(j).get(0).toString());
DecimalFormat decimalFormat = new DecimalFormat("0");
String timestamp = decimalFormat.format(secondNumber);
hexoskinDataPoint.setTimestamp(timestamp);
} else {
hexoskinDataPoint.setTimestamp("NA");
}
if (dataPointWrapper.get(j).get(1) != null && !dataPointWrapper.get(j).get(1).toString().equals("null")) {
hexoskinDataPoint.setValue(dataPointWrapper.get(j).get(1).toString());
} else {
hexoskinDataPoint.setValue("NA");
}
hexoskinDataPoints.add(hexoskinDataPoint);
}
}
}
return hexoskinDataPoints;
}
/**
* Unirest starts a background event loop and your Java application won’t be able to exit
* until you manually shutdown all the threads.
*/
void destroy() {
Unirest.shutDown();
}
}
Do you have any idea why exactly one class (HexoskinHTTPClient) cannot be found?
As per my understanding "HexoskinHTTPClient" is not public class, this class declared with default package modified that's why this class not visible outside of package. make the class public i think it will work.
I'm trying to develop a XSS Filter. All works fine, but the wrapper is losing the multipart fields.
After the filter, in the controller, when I try to obtain the value of a multipart field always is empty.
I have the following wrapper:
public class XSSRequestWrapperMultipart extends HttpServletRequestWrapper {
/** Constructor. */
public XSSRequestWrapperMultipart(HttpServletRequest aRequest) throws IOException {
super(aRequest);
ServletFileUpload upload = new ServletFileUpload( new DiskFileItemFactory());
try {
List<FileItem> fileItems = upload.parseRequest(aRequest);
convertToMaps(fileItems);
}
catch(FileUploadException ex){
throw new IOException("Cannot parse underlying request: " + ex.toString());
}
}
/**
* Return all request parameter names, for both regular controls and file upload
* controls.
*/
#Override public Enumeration<String> getParameterNames() {
Set<String> allNames = new LinkedHashSet<>();
allNames.addAll(fRegularParams.keySet());
allNames.addAll(fFileParams.keySet());
return Collections.enumeration(allNames);
}
/**
* Return the parameter value. Applies only to regular parameters, not to
* file upload parameters.
*/
#Override public String getParameter(String aName) {
String result = null;
List<String> values = fRegularParams.get(aName);
if(values == null){
//you might try the wrappee, to see if it has a value
}
else if (values.isEmpty()) {
//param name known, but no values present
result = "";
}
else {
//return first value in list
result = values.get(FIRST_VALUE);
}
return result;
}
/**
* Return the parameter values. Applies only to regular parameters,
* not to file upload parameters.
*/
#Override public String[] getParameterValues(String aName) {
String[] result = null;
List<String> values = fRegularParams.get(aName);
if(values != null) {
result = values.toArray(new String[values.size()]);
}
return result;
}
/**
* Return a {#code Map<String, List<String>>} for all regular parameters.
* Does not return any file upload parameters at all.
*/
#Override public Map<String, List<String>> getParameterMap() {
return Collections.unmodifiableMap(fRegularParams);
}
/**
* Return a {#code List<FileItem>}, in the same order as they appear
* in the underlying request.
*/
public List<FileItem> getFileItems(){
return new ArrayList<FileItem>(fFileParams.values());
}
/**
* Return the {#link FileItem} of the given name.
* <P>If the name is unknown, then return <tt>null</tt>.
*/
public FileItem getFileItem(String aFieldName){
return fFileParams.get(aFieldName);
}
// PRIVATE
/** Store regular params only. May be multivalued (hence the List). */
private final Map<String, List<String>> fRegularParams = new LinkedHashMap<>();
/** Store file params only. */
private final Map<String, FileItem> fFileParams = new LinkedHashMap<>();
private static final int FIRST_VALUE = 0;
private void convertToMaps(List<FileItem> aFileItems){
for(FileItem item: aFileItems) {
if ( isFileUploadField(item) ) {
fFileParams.put(item.getFieldName(), item);
}
else {
if( alreadyHasValue(item) ){
addMultivaluedItem(item);
}
else {
addSingleValueItem(item);
}
}
}
}
private boolean isFileUploadField(FileItem aFileItem){
return ! aFileItem.isFormField();
}
private boolean alreadyHasValue(FileItem aItem){
return fRegularParams.get(aItem.getFieldName()) != null;
}
private void addSingleValueItem(FileItem aItem){
List<String> list = new ArrayList<>();
list.add(aItem.getString());
fRegularParams.put(aItem.getFieldName(), list);
}
private void addMultivaluedItem(FileItem aItem){
List<String> values = fRegularParams.get(aItem.getFieldName());
values.add(aItem.getString());
}
}
All relative to the fRegularParams works fine, but the fFileParams always appears as null in the controller.
What can I do to keep the values?
Regards
If you see for fRegularParams, you are touching the getParameter() method of servlet lifecycle.
Here the parameters are already initialized in this phase.
For fFileParams you are trying to get params in constructor, which is too early considering lifecycle of servlet and filters.
Image for your reference:
Solution:
Can you try with method request.getParts() instead?
You can try this approach and override
https://github.com/spring-projects/spring-framework/blob/2f20d6322b7a0fcbbaa80280849e7c31fc78d4a9/spring-web/src/main/java/org/springframework/web/multipart/support/StandardMultipartHttpServletRequest.java#L131
Which internally deals with request parts.
https://github.com/spring-projects/spring-framework/blob/2f20d6322b7a0fcbbaa80280849e7c31fc78d4a9/spring-web/src/main/java/org/springframework/web/multipart/support/StandardMultipartHttpServletRequest.java#L91
Here "might" be your problem:
private boolean isFileUploadField(FileItem aFileItem){
return ! aFileItem.isFormField();
}
It's returning the opposite response of the boolean value (check the !). Remove it and test if that works.
Only if the FileItem.isFormField() that you can get the form parameter data.
private boolean isFileUploadField(FileItem aFileItem){
return aFileItem.isFormField();
}
We are using apache commons mail, specifically the ImageHtmlEmail. We really would like to log every email sent - exactly as it will be sent - in the perfect world it would be something you could paste into sendmail - with all headers and other information included.
This is primarily to troubleshoot some problems we've been having with it turning up as text/plain rather than text/html - but also because it would be nice to have a record of exactly what the system sent out stored in our logs.
So essentially - the dream is a function that would take an ImageHtmlEmail and return a string - as it will be sent. I know I could render it into a string myself, but then I'm bypassing whatever is being done in the library function, which is what we really want to capture. I tried BuildMimeMessage and then getMimeMessage, which I think is probably the correct first step - but that just leaves me with the question of how to turn a mimemessage into a string.
I have a sort of solution - but would love a better one:
/**
* add content of this type
*
* #param builder
* #param content
*/
private static void addContent(final StringBuilder builder, final Object content)
{
try
{
if (content instanceof MimeMultipart)
{
final MimeMultipart multi = (MimeMultipart) content;
for (int i = 0; i < multi.getCount(); i++)
{
addContent(builder, ((MimeMultipart) content).getBodyPart(i));
}
}
else if (content instanceof MimeBodyPart)
{
final MimeBodyPart message = (MimeBodyPart) content;
final Enumeration<?> headers = message.getAllHeaderLines();
while (headers.hasMoreElements())
{
final String line = (String) headers.nextElement();
builder.append(line).append("\n");
}
addContent(builder, message.getContent());
}
else if (content instanceof String)
{
builder.append((String) content).append("\n");
}
else
{
System.out.println(content.getClass().getName());
throw CommonException.notImplementedYet();
}
}
catch (final Exception theException)
{
throw CommonException.insteadOf(theException);
}
}
/**
* get a string from an email
*
* #param email
* #return
*/
public static String fromHtmlEmail(final ImageHtmlEmail email)
{
return fromMimeMessage(email.getMimeMessage());
}
/**
* #param message
* #return a string from a mime message
*/
private static String fromMimeMessage(final MimeMessage message)
{
try
{
message.saveChanges();
final StringBuilder output = new StringBuilder();
final Enumeration<?> headers = message.getAllHeaderLines();
while (headers.hasMoreElements())
{
final String line = (String) headers.nextElement();
output.append(line).append("\n");
}
addContent(output, message.getContent());
return output.toString();
}
catch (final Exception theException)
{
throw CommonException.insteadOf(theException);
}
}
}
For some reason I'm getting null pointer exception. It's downloading the image here and logcat points me to call
public Result call(final String method, final String apiKey, final String... params) {
return call(method, apiKey, map(params));
}
/**
* Performs the web-service call. If the <code>session</code> parameter is
* <code>non-null</code> then an authenticated call is made. If it's
* <code>null</code> then an unauthenticated call is made.<br/>
* The <code>apiKey</code> parameter is always required, even when a valid
* session is passed to this method.
*
* #param method The method to call
* #param apiKey A Last.fm API key
* #param params Parameters
* #param session A Session instance or <code>null</code>
* #return the result of the operation
*/
public Result call(final String method, final String apiKey, Map<String, String> params) {
params = new WeakHashMap<String, String>(params);
InputStream inputStream = null;
// no entry in cache, load from web
if (inputStream == null) {
// fill parameter map with apiKey and session info
params.put(PARAM_API_KEY, apiKey);
try {
final HttpURLConnection urlConnection = openPostConnection(method, params);
inputStream = getInputStreamFromConnection(urlConnection);
if (inputStream == null) {
lastResult = Result.createHttpErrorResult(urlConnection.getResponseCode(),
urlConnection.getResponseMessage());
return lastResult;
}
} catch (final IOException ignored) {
}
}
try {
final Result result = createResultFromInputStream(inputStream);
lastResult = result;
return result;
} catch (final IOException ignored) {
} catch (final SAXException ignored) {
}
return null;
}
It finally cracks at the line "new InputSource(new InputStreamReader(inputStream, "UTF-8")));".
/**
* #param inputStream
* #return
* #throws SAXException
* #throws IOException
*/
private Result createResultFromInputStream(final InputStream inputStream) throws SAXException,
IOException {
final Document document = newDocumentBuilder().parse(
new InputSource(new InputStreamReader(inputStream, "UTF-8")));
final Element root = document.getDocumentElement(); // lfm element
final String statusString = root.getAttribute("status");
final Status status = "ok".equals(statusString) ? Status.OK : Status.FAILED;
if (status == Status.FAILED) {
final Element errorElement = (Element)root.getElementsByTagName("error").item(0);
final int errorCode = Integer.parseInt(errorElement.getAttribute("code"));
final String message = errorElement.getTextContent();
return Result.createRestErrorResult(errorCode, message);
} else {
return Result.createOkResult(document);
}
}
Any ideas? I have no idea what might be wrong. If sufficient info is provided then let me know - I'll get what you need. I'm a beginner. :)
I've writen a program that will login via SSH. This server takes an additional step in that you need to provide it an area code and three digits of a telephone number when it prompts "Destination: ". So, what I'm trying to do is have my terminal wait for the Destination: prompt, give it my six digits, then look at the resulting prompts to see where it went before executing my expect code. There are five possible terminal types after the Destination: prompt, meaning I need to test the returning stream after giving it my six telephone number digits using regex.
Where I'm getting stuck is figuring out the best way to get the Destination: prompt, send it my digits, get the resulting code to execute my regex and if then statements, and then passing it onto one of several classes I'll be making to execute using expect4j from that point on. Should I use an exec shell before moving over to expect, and if so, how do I get my input from it to run regex? Should I send an expect.expect ("Destination: "); followed by an expect.send ("123456");, then get the input to run regex, and if so, how do I get the input from it? (my example code uses a buffer, which gets it's info from the execute method somehow, I don't really understand how it work completely,) or, my last option, should I build two instances of my example code, one that makes the session and ssh channel, sends my telephone digits, gets the input, runs regex, THEN send it to another expect4j class with new variables to run the remaining expect and sends?
IN SHORT: As far as I can tell those are my three options: run an exec shell, run a single expect.expect and expect.send before going into the more complicated list building and such, or running two lists with expect methods, one after the other. Not sure which way to go, and how to get my input back to run the regex.
I've managed to get it to login to one of my five terminal options, examine, and disconnect, and most recently I've built code to login, supply the digits, and read the resulting code with regex to indicate which of my five types it is. I just can't get them to work together.
My code is built off the example found at http://nikunjp.wordpress.com/2011/07/30/remote-ssh-using-jsch-with-expect4j/
package switchoverlay;
import com.jcraft.jsch.ChannelShell;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import expect4j.Closure;
import expect4j.Expect4j;
import expect4j.ExpectState;
import expect4j.matches.Match;
import expect4j.matches.RegExpMatch;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.oro.text.regex.MalformedPatternException;
public class SSHLogin {
static final String controlB = "\u0002";
static final String controlC = "\u0003";
static final String controlV = "\u0016";
static final String cr = "\u0013";
static final String lf = "\u0010";
static final String sp = "\u0032";
String npa = OverlayGUI.tn.substring(1, 4); //Get first three digits from tn
String nxx = OverlayGUI.tn.substring(5, 8); //Get first three digits from tn
String xxxx = OverlayGUI.tn.substring(9, 13); //Get last four digits from tn
private static final int COMMAND_EXECUTION_SUCCESS_OPCODE = -2;
private static String ENTER_CHARACTER = "\r"; //NOT GOOD FOR A GTD5!
private static final int SSH_PORT = 22;
private List<String> loginLstCmds = new ArrayList<String>();
private static String[] switchPromptRegEx = new String[]
{"\r\nDestination: ", //npanxx
"via.{12}\r\n"}; //controlB
private Expect4j expect = null;
private StringBuilder loginBuffer = new StringBuilder();
private String userName;
private String password;
private String host;
/**
*
* #param host
* #param userName
* #param password
*/
public SSHLogin(String host, String userName, String password) {
this.host = host;
this.userName = userName;
this.password = password;
}
/**
*
* #param LoginCmdsToExecute
*/
public String execute(List<String> LoginCmdsToExecute) {
this.loginLstCmds = LoginCmdsToExecute;
Closure closure = new Closure() {
public void run(ExpectState expectState) throws Exception {
loginBuffer.append(expectState.getBuffer());
}
};
List<Match> lstPattern = new ArrayList<Match>();
for (String regexElement : switchPromptRegEx) {
try {
Match mat = new RegExpMatch(regexElement, closure);
lstPattern.add(mat);
} catch (MalformedPatternException e) {
e.printStackTrace();
} catch(Exception e) {
e.printStackTrace();
}
}
try {
expect = SSH();
boolean isSuccess = true;
for(String strCmd : loginLstCmds) {
isSuccess = isSuccess(lstPattern,strCmd);
if (!isSuccess) {
isSuccess = isSuccess(lstPattern,strCmd);
}
}
checkResult(expect.expect(lstPattern));
} catch (Exception ex) {
ex.printStackTrace();
} finally {
testType();
}
return loginBuffer.toString();
}
/**
*
* #param objPattern
* #param strCommandPattern
* #return
*/
private boolean isSuccess(List<Match> objPattern,String strCommandPattern) {
try {
boolean isFailed = checkResult(expect.expect(objPattern));
if (!isFailed) {
expect.send(strCommandPattern);
Thread.sleep( 8000);
//expect.send(ENTER_CHARACTER); //NOT GOOD FOR A GTD5!
return true;
}
return false;
} catch (MalformedPatternException ex) {
ex.printStackTrace();
return false;
} catch (Exception ex) {
ex.printStackTrace();
return false;
}
}
/**
*
* #param hostname
* #param username
* #param password
* #param port
* #return
* #throws Exception
*/
private Expect4j SSH() throws Exception {
JSch jsch = new JSch();
Session session = jsch.getSession(userName, host, SSH_PORT);
if (password != null) {
session.setPassword(password);
}
Hashtable<String,String> config = new Hashtable<String,String>();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.connect(120000);
ChannelShell channel = (ChannelShell) session.openChannel("shell");
channel.connect();
Expect4j expect = new Expect4j(channel.getInputStream(), channel.getOutputStream());
return expect;
}
/**
*
* #param intRetVal
* #return
*/
private boolean checkResult(int intRetVal) {
if (intRetVal == COMMAND_EXECUTION_SUCCESS_OPCODE) {
return true;
}
return false;
}
/**
*
*/
private void testType() {
String lBString = loginBuffer.toString();
System.out.println(lBString);
Pattern gtd5 = Pattern.compile(".*GTD5.*");
Matcher gtd5Matcher = gtd5.matcher(lBString);
if (gtd5Matcher.find()) {
System.out.println("Your switch type is GTD5");
}
Pattern dms10 = Pattern.compile(".*DMS10^0.*");
Matcher dms10Matcher = dms10.matcher(lBString);
if (dms10Matcher.find()) {
System.out.println("Your switch type is DMS10");
}
Pattern dms100 = Pattern.compile(".*DMS100.*");
Matcher dms100Matcher = dms100.matcher(lBString);
if (dms100Matcher.find()) {
System.out.println("Your switch type is DMS100");
}
Pattern ess = Pattern.compile(".*5es.*");
Matcher essMatcher = ess.matcher(lBString);
if (essMatcher.find()) {
System.out.println("Your switch type is 5ESS");
}
Pattern dco = Pattern.compile(".*DCO.*");
Matcher dcoMatcher = dco.matcher(lBString);
if (dcoMatcher.find()) {
System.out.println("Your switch type is DCO");
}
//else { System.out.println("Switch type Error."); }
//SSHGTD5ExamClient runSsh = new SSHGTD5ExamClient(); //pass on to expect4j based on regex for remaining expect and sends?
//if (expect!=null) { //old code for shutting down expect4j
//expect.close();
}
}