Java application with httpServer hangs for 45 seconds before exiting - java

I have been playing around with Java httpServer class a little bit. When I run my test application it will get to the last line (a println) in main about right a way, but then it sits there for about 45 secs before closing the application. Why does it do that and is there a way to make it so it ends faster? Thanks
public class TestTester
{
public static void main(String[] args) throws IOException {
InetSocketAddress addr = new InetSocketAddress("127.0.0.1", 8780);
HttpServer server = HttpServer.create(addr, 0);
server.createContext("/", new MyHandler());
server.setExecutor(Executors.newCachedThreadPool());
server.start();
URL url = new URL("http://localhost:8780/test");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
InputStreamReader(connection.getInputStream()));
// print out the response headers
System.out.println("\nHttp Response Headers");
for (int i=0; ; i++)
{
String headerName = connection.getHeaderFieldKey(i);
String headerValue = connection.getHeaderField(i);
if (headerName == null && headerValue == null) {
// No more headers
break;
}
else if (headerName == null) {
System.out.println( " " + headerValue);
}
else
System.out.println( " " + headerName + ": " + headerValue );
}
connection.disconnect();
server.stop(0);
System.out.println("Stopped Server.");
} // end main()
}
class MyHandler implements HttpHandler {
#Override
public void handle(HttpExchange exchange) throws IOException
{
System.out.println("===Enter MyHandler===");
System.out.println("Http Request Header:");
// print out the request methode and url
System.out.println( " " + exchange.getRequestMethod() + " "
+ exchange.getRequestURI() + " " + exchange.getProtocol());
// print out the request headers
Headers requestHeaders = exchange.getRequestHeaders();
for (String name : requestHeaders.keySet() )
{
List<String> values = requestHeaders.get(name);
for ( String value : values )
{
System.out.println( " " + name + ": " + value);
}
}
// print out the request body if any
BufferedReader in = new BufferedReader(new InputStreamReader(exchange.getRequestBody()));
String sCurrentLine;
System.out.println( "\nHttp Request Body:");
if ( ! in.ready() )
System.out.println( " No Request Body");
else
{
while ((sCurrentLine = in.readLine()) != null) {
System.out.println(" " + sCurrentLine);
}
}
// set up and send response
String requestMethod = exchange.getRequestMethod();
if (requestMethod.equalsIgnoreCase("GET"))
{
Headers responseHeaders = exchange.getResponseHeaders();
responseHeaders.set("Content-Type", "text/html");
exchange.sendResponseHeaders(200, 0);
OutputStream responseBody = exchange.getResponseBody();
responseBody.write("<!DOCTYPE html><html><body><h1>My Response Header</h1><p>And some sample data.</p></body></html>".getBytes());
responseBody.close();
}
exchange.close();
} // end public void handle()
} // end class

I did find something that seems to work although I am not sure if it is the correct way to be handling this. This is not extensively tested, but it does make it shutdown faster.
I replaced:
server.setExecutor(Executors.newCachedThreadPool());
With:
ExecutorService excu = Executors.newCachedThreadPool();
server.setExecutor(excu);
Then just before the server.stop(0); I added excu.shutdown();

Related

HttpServletRequestWrapper not working in Spring MVC

I am developing a custom log with Spring MVC to get information from all incoming request. I would like to grab both the request body and response body. The issue is, even if I create a HttpServletRequestWrapper, I cannot forward the request after I process and wrap the request.
Here is my code:
Interceptor
#Component
public class LoggerInterceptor implements HandlerInterceptor{
final static org.apache.log4j.Logger log = Logger.getLogger(LoggerInterceptor.class.getName());
/**
* Executed before actual handler is executed
**/
#Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
long start = System.currentTimeMillis();
MyRequestWrapper requestWrapper = new MyRequestWrapper(request);
SimpleDateFormat f = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss:SSS");
String date = f.format(new Date());
UUID uuid = UUID.randomUUID();
String method = requestWrapper.getMethod();
String uri = requestWrapper.getRequestURI();
String step = "Default Step";
String url = String.valueOf(requestWrapper.getRequestURL());
String serverName = requestWrapper.getServerName();
String reqBody = IOUtils.toString(requestWrapper.getInputStream(), Charset.forName("UTF-8").toString());
CustomHttpResponseWrapper responseWrapper = new CustomHttpResponseWrapper(response);
long end = System.currentTimeMillis() - start;
String status = String.valueOf(responseWrapper.getStatus());
String resBody = new String(responseWrapper.getBaos().toByteArray());
if(step!=null && !step.isEmpty()) {
log.info("INFO " + date + " " + uuid + "\n" +
"ID : " + getCurrentlyDateTime() + "\n" +
"STEP : " + step + "\n" +
"Request URL: " + url + "\n" +
"Host : " + serverName + "\n" +
"Request Body : " + reqBody + "\n" +
"Response Status : " + status + "\n" +
"Response Body : " + resBody + "\n" +
"Response Time : " + end);
}
return true;
}
}
Request Wrapper
public class MyRequestWrapper extends HttpServletRequestWrapper {
private final String body;
public MyRequestWrapper(HttpServletRequest request) throws IOException {
super(request);
StringBuilder stringBuilder = new StringBuilder();
BufferedReader bufferedReader = null;
try {
InputStream inputStream = request.getInputStream();
if (inputStream != null) {
bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
char[] charBuffer = new char[128];
int bytesRead = -1;
while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
stringBuilder.append(charBuffer, 0, bytesRead);
}
} else {
stringBuilder.append("");
}
} catch (IOException ex) {
throw ex;
} finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException ex) {
throw ex;
}
}
}
body = stringBuilder.toString();
}
#Override
public ServletInputStream getInputStream() throws IOException {
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes());
ServletInputStream servletInputStream = new ServletInputStream() {
public int read() throws IOException {
return byteArrayInputStream.read();
}
#Override
public boolean isFinished() {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean isReady() {
// TODO Auto-generated method stub
return false;
}
#Override
public void setReadListener(ReadListener readListener) {
// TODO Auto-generated method stub
}
};
return servletInputStream;
}
#Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(this.getInputStream()));
}
public String getBody() {
return this.body;
}
}
Output
INFO 2022/04/12 10:35:18:578 d00ec778-2a6e-4a72-a0e0-9649c13776eb
ID : 20220412103518
STEP : Default Step
Request URL: http://localhost:8080/com.ihcs.api.mobile/loginNew
Host : localhost
Request Body : {
"username":"P0****",
"sessionid":"*************************",
"password":"********",
"companyCode":"***",
"UniqueId":"**********",
"Manufacturer":"google",
"Brand":"google",
"Model":"*******",
"DeviceId":"*******",
"FcmTokens":"*******",
"UniqueLogin":false
}
Response Status : 200
Response Body :
Response Time : 18
Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: I/O error while reading input message; nested exception is java.io.IOException: Stream closed
I've tried some suggestions from stack overflow but still can't help. Thank you.

littleproxy empty reply from server

I am using littleproxy-mitm to proxy requests in java to remote servers, yet I am getting an empty response from curl when trying to make a request through the proxy, regardless if it is http or https:
curl: (52) Empty reply from server
curl: (56) Proxy CONNECT aborted
My code:
HttpProxyServer server =
DefaultHttpProxyServer.bootstrap()
.withPort(PORT)
.withManInTheMiddle(new CertificateSniffingMitmManager())
.withFiltersSource(new HttpFiltersSourceAdapter() {
public HttpFilters filterRequest(HttpRequest originalRequest, ChannelHandlerContext context) {
System.out.println("-----------------------------------------------------");
HttpMethod method = originalRequest.getMethod();
String originalUri = originalRequest.getUri();
System.out.println("CLIENT " + method + " -> " + originalUri);
originalRequest.headers().forEach(entry -> {
System.out.println("-- " + entry.getKey() + ":" + entry.getValue());
});
if (HttpMethod.CONNECT.equals(method) && Objects.nonNull(context) && originalUri.endsWith(":443")) {
String url = "https://" + originalUri.replaceFirst(":443$", "");
context.channel().attr(CONNECTED_URL).set(url);
System.out.println("URL: " + context.channel().attr(CONNECTED_URL).get());
System.out.println("(Manipulating connection request for successful HTTPS: " + originalUri + " -> " + url + ")");
return new HttpFiltersAdapter(originalRequest, context);
}
return new HttpFiltersAdapter(originalRequest) {
#Override
public HttpResponse clientToProxyRequest(HttpObject httpObject) {
if (httpObject instanceof LastHttpContent) {
LastHttpContent copy = ((LastHttpContent) httpObject).copy();
String body = copy.content().toString(StandardCharsets.UTF_8);
System.out.println("-- Content:" + body);
}
return null;
}
#Override
public HttpObject serverToProxyResponse(HttpObject httpObject) {
System.out.println("Server Response");
if (httpObject instanceof HttpResponse) {
HttpResponse response = (HttpResponse) httpObject;
System.out.println("SERVER RESPONSE");
response.headers().forEach(entry -> {
System.out.println("-- " + entry.getKey() + ":" + entry.getValue());
});
}
return httpObject;
}
};
}
})
.start();

(GET http request) How send cookie in the server

I'm trying to send cookies to the server, but it doesn't work. Please tell me thats wrong. Here is my code.
At first, I take cookie in the POST request.
> Map <String, List<String>> headerFields = postRequest.getHeaderFields();
> List<String> cookiesHeader = headerFields.get("Set-Cookie");
Later, in the GET request, i'm send cookie to the server.
getRequest.setRequestProperty("Cookie", cookiesHeader.toString());
Help me. I'm beginner, not judge strictly.
Here all my code.
#Override
protected String doInBackground(Void... params) {
Log.i(TAG, "doInBackground");
String store_id = "";
final String COOKIES_HEADER = "Set-Cookie";
final String COOKIE = "Cookie";
try {
Thread.sleep(4000);
Log.i(TAG, "httpRequest start");
String parametrs = mPhone.getText().toString();
String parametrs2 = mPass.getText().toString();
JSONObject allParams = new JSONObject();
HttpURLConnection postRequest = null;
InputStream inputStream = null;
byte[] data = null;
try {
URL serverUrl = new URL("https://api.fianitlombard.ru/mobile/auth");
postRequest = (HttpURLConnection) serverUrl.openConnection();
postRequest.setReadTimeout(10000 /* milliseconds */);
postRequest.setConnectTimeout(15000 /* milliseconds */);
postRequest.setRequestMethod("POST");
postRequest.setDoInput(true);
postRequest.setDoOutput(true);
postRequest.setRequestProperty("Content-Type", "application/json; charset=utf-8");
postRequest.connect();
allParams.put("phone", parametrs);
allParams.put("password", parametrs2);
Log.i(TAG, "allParams" + allParams);
OutputStream bos = (postRequest.getOutputStream());
bos.write(allParams.toString().getBytes());
String helpInfo = postRequest.getResponseMessage();
Log.i(TAG, "helpInfo =" + helpInfo);
responseCode = postRequest.getResponseCode();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Map<String, List<String>> headerFields = postRequest.getHeaderFields();
List<String> cookiesHeader = headerFields.get(COOKIES_HEADER);
if (responseCode == 200) {
inputStream = postRequest.getInputStream();
byte[] buffer = new byte[8192]; // Такого вот размера буфер
// Далее, например, вот так читаем ответ
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
baos.write(buffer, 0, bytesRead);
}
data = baos.toByteArray();
resultString = new String(data, "UTF-8");
Log.i(TAG, "responseCode = " + responseCode);
Log.i(TAG, "resultCode = " + resultString);
JSONObject jsonObject = new JSONObject(resultString);
store_id = jsonObject.getString("store_id");
Log.i(TAG, "store_id =" + store_id);
bos.close();
baos.close();
postRequest.disconnect();
}
if (responseCode == 403) {
Log.i(TAG, "responseCode = " + responseCode);
}
HttpURLConnection getRequest = null;
try {
URL serverUrl1 = new URL("https://api.fianitlombard.ru/mobile/checksession?version=1.0.8");
URI uri = URI.create("https://api.fianitlombard.ru/mobile/checksession?version=1.0.8");
getRequest = (HttpURLConnection) serverUrl1.openConnection();
getRequest.setReadTimeout(20000 /* milliseconds */);
getRequest.setConnectTimeout(25000 /* milliseconds */);
getRequest.setRequestMethod("GET");
getRequest.setRequestProperty("Content-Type", "application/json; charset=utf-8");
getRequest.setRequestProperty(COOKIE, cookiesHeader.toString());
Log.i(TAG, "Cookie = " + cookiesHeader.toString());
getRequest.connect();
int responceGetCode = getRequest.getResponseCode();
String responceGetInfo = getRequest.getResponseMessage();
Log.i(TAG, "responceGetCode = " + responceGetCode);
Log.i(TAG, "responceGetInfo = " + responceGetInfo);
if (responceGetCode == 200) {
//Все хорошо
}
if (responceGetCode == 400) {
// Устарела версия, нужно обновление
}
if (responceGetCode == 403) {
//Проблемы с авторизацией
} else {
//Что то другое.
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (getRequest != null)
getRequest.disconnect();
}
} catch (IOException e1) {
e1.printStackTrace();
}
if (postRequest != null) {
postRequest.disconnect();
}
Log.i(TAG, "httpRequest end");
}
catch (InterruptedException | JSONException e) {
e.printStackTrace();
}
return store_id;
}
change below line
getRequest.setRequestProperty(COOKIE, cookiesHeader.toString());
to
getRequest.setRequestProperty( COOKIE, cookiesHeader.get( 0 ) );
toString() method of List will return the hashCode() but not the actual values of List
try to use the following method to get the cookie :
String getHeaderField("Set-Cookie")
you set the cookie by using the lists toString method, which will not give you the current cookie representation, but instead a string matching "[var1, var2, var3]"
The server sends the following in its response header to set a cookie field.
Set-Cookie:name=value
If there is a cookie set, then the browser sends the following in its request header.
Cookie:name=value
See the HTTP Cookie article at Wikipedia for more information.

Java Jersey-client header issue

i'm trying to add the following headers to a rest Post call... it works in plain Java but i'm trying to re-write it using the Jersey client library... When I make the post with Jersey I get an error code which isn't listed in the API documentation so i know it must just be a small issue like a missing header... Any idea what i'm doing wrong in the bottom function?
Plain Java add headers function that works:
private void SetDefaultHeaders(HttpURLConnection conn) {
setRequestProperty(conn, "Accept", "*");
setRequestProperty(conn, "Content-Type", "application/x-www-form-urlencoded");
}
Jersey code:
public void logIn(String email, String password) {
if (email != "" && email != null && password != "" && password != null) {
try {
StringBuilder sb = new StringBuilder();
sb.append(Settings.WIFIPLUG_URL);
sb.append("/user_login");
MultivaluedMap<String, String> body = new MultivaluedMapImpl();
body.add("username=", email);
body.add("password=", password);
System.out.println("login url: " + sb.toString());
WebResource webResource = Client.create(new DefaultClientConfig()).resource(sb.toString());
WebResource.Builder builder = webResource.accept("*");
builder.type("application/x-www-form-urlencoded");
ClientResponse response = builder.post(ClientResponse.class, body);
if (response.getStatus() != 200) {
throw new RuntimeException("failed: http error code " + response.getStatus());
}
System.out.println("Response from server: " + response.getEntity(String.class));
} catch (Exception e) {
e.printStackTrace();
}
}
}
Full vanilla java login function:
public String postUserLogin(String username, String password) {
String result = "";
// URL for API to login
String url = "https://wifiplugapi.co.uk:3081/zcloud/api/user_login";
String requestParams = "username=" + username + "&password=" + password;
try {
URL obj = new URL(url);
System.out.println("login url: " + obj);
// Opens the connection
HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();
// Send POST request
con.setDoOutput(true);
con.setDoInput(true);
// Request Headers
con.setRequestMethod("POST");
// Sets all the headers
SetDefaultHeaders(con);
OutputStreamWriter wr = new OutputStreamWriter(con.getOutputStream(), "UTF-8");
wr.write(requestParams);// adds values to the request
wr.flush();
wr.close();
// Handles the response
StringBuilder sb = new StringBuilder();
int responseCode = con.getResponseCode();
if (responseCode == 200) {
// if the request was successful OK = 200
BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream(), "UTF-8"));
String line = null;
while ((line = br.readLine()) != null) {
sb.append(line + "\n");
}
br.close();
// Returns Token
} else {
// If the request was bad, reason will be printed
result = "Error, login request failed";
throw new RuntimeException("Failed : HTTP error code : " + con.getResponseCode());
}
result = sb.toString();
// JSON Parser
JsonParser parser = new JsonParser();
JsonObject resultObj = parser.parse(result).getAsJsonObject();
con.disconnect();
if (resultObj.get("token") != null) {
result = (resultObj.get("token")).toString();
System.out.println("JSONObject Result (token): " + result);
} else {
System.out.println("result = " + result);
}
} catch (Exception e) {
e.printStackTrace();
}
// returns token value in string ie. fdg573gb3789gv923378gy83g3
result = result.replaceAll("\"", "");
return result;
}
You shouldn't have the = in the key when doing body.add. It will be added for you
MultivaluedMap<String, String> body = new MultivaluedMapImpl();
body.add("username=", email); // remove the =
body.add("password=", password); // remove the =

Socket TimeOutException-Connection timed out

I am trying to connect with Tomcat Server(IP address-192.168.1.120 which is stored in Config.java(static variable APP_SERVER_URL)) but it is giving me socket timeout exception .
How to resolve it.Please help.
But when I
public class ShareExternalServer {
public String shareRegIdWithAppServer(Map<String, String> paramsMap) {
String result = "";
try {
URL serverUrl = null;
try {
serverUrl = new URL(Config.APP_SERVER_URL);
} catch (MalformedURLException e) {
Log.e("AppUtil", "URL Connection Error: "
+ Config.APP_SERVER_URL, e);
result = "Invalid URL: " + Config.APP_SERVER_URL;
}
StringBuilder postBody = new StringBuilder();
Iterator<Entry<String, String>> iterator = paramsMap.entrySet()
.iterator();
while (iterator.hasNext()) {
Entry<String, String> param = iterator.next();
postBody.append(param.getKey()).append('=')
.append(param.getValue());
if (iterator.hasNext()) {
postBody.append('&');
}
}
String body = postBody.toString();
Log.d("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&",body);
byte[] bytes = body.getBytes();
HttpURLConnection httpCon = null;
try {
httpCon = (HttpURLConnection) serverUrl.openConnection();
httpCon.setDoOutput(true);
httpCon.setUseCaches(false);
httpCon.setFixedLengthStreamingMode(bytes.length);
httpCon.setRequestMethod("POST");
httpCon.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded;charset=UTF-8");
httpCon.setConnectTimeout(20000);
OutputStream out = httpCon.getOutputStream();
out.write(bytes);
out.close();
int status = httpCon.getResponseCode();
Log.d("$$$$$$$$$$$$$$$$$$",String.valueOf(status));
/* if (status == 200) {
result = "RegId shared with Application Server. RegId: "
+ regId;
} else {
result = "Post Failure." + " Status: " + status+regId;
}*/
} finally {
if (httpCon != null) {
((HttpURLConnection) httpCon).disconnect();
}
}
} catch (IOException e) {
result = "Post Failure. Error in sharing with App Server.";
Log.e("AppUtil", "Error in sharing with App Server: " + e);
}
return result;
}
}

Categories

Resources