SSLException:Write error: ssl=0x7f8170c780: I/O error during system call, Connection timed out - okhttp

I use okhttp and retrofit2 to post a audio file,but sometimes the file broken (server side),What is the reason?
File file = new File(path);
RequestBody requestFile = RequestBody.create(MediaType.parse("audio/*"), file);
body = MultipartBody.Part.createFormData("audio_file", file.getName(), requestFile);
HashMap<String,RequestBody> params = new HashMap<>();
params.put("lecture_id",RequestBody.create(MediaType.parse("multipart/form-data"), mId + ""));
params.put("duration",RequestBody.create(MediaType.parse("multipart/form-data"),attachment.getDuration() + ""));
params.put("reply_message_id",RequestBody.create(MediaType.parse("multipart/form-data"),msg.getReplyMsgId() + ""));
Subscription subscription = ApiService.getInstance().sendAudioMessage(body,params).subscribe(new HttpObserver<IMMessage>() {
#Override
protected void onError(ApiException ex) {
CrashReport.postCatchedException(ex);
ToastUtil.showToast(getActivity(),ex.getMsg());
onSendMessageFail(msg);
}
#Override
public void onNext(IMMessage imMessage) {
onSendMessageSuccess(msg);
}
});
mCompositeSubscription.add(subscription);

Related

I want to upload file without using multipart in spring boot, would be great if I could get you valuable suggestions on this

Shall I remove this from application.properties
spring.http.multipart.enabled=true
What should be my approach towards this file upload without using multipart?
This way, I'm able to uploading file using where I'm using multipart.
#RequestMapping(value = "/dog/create/{name}", method = RequestMethod.POST)
public JsonNode dogCreation(HttpServletRequest httpRequest, #RequestParam(value = "picture", required = false) MultipartFile multipartFile,
#PathVariable("name") String name) throws IOException, InterruptedException {
JSONObject response = new JSONObject();
Dog dog = new Dog();
String DOG_IMAGES_BASE_LOCATION = "resource\\images\\dogImages";
try {
File file = new File(DOG_IMAGES_BASE_LOCATION);
if (!file.exists()) {
file.mkdirs();
}
} catch (Exception e) {
e.printStackTrace();
}
dog = dogService.getDogByName(name);
if (dog == null) {
if (!multipartFile.isEmpty()) {
String multipartFileName = multipartFile.getOriginalFilename();
String format = multipartFileName.substring(multipartFileName.lastIndexOf("."));
try {
Path path = Paths.get(DOG_IMAGES_BASE_LOCATION + "/" + name + format);
byte[] bytes = multipartFile.getBytes();
File file = new File(path.toString());
file.createNewFile();
Files.write(path, bytes);
if (file.length() == 0) {
response = utility.createResponse(500, Keyword.ERROR, "Image upload failed");
} else {
String dbPath = path.toString().replace('\\', '/');
dog = new Dog();
dog.setName(name);
dog.setPicture(dbPath);
dog = dogService.dogCreation(dog);
response = utility.createResponse(200, Keyword.SUCCESS, "Image upload successful");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
return objectMapper.readTree(response.toString());
}
I want to do it without using multipart, what would you suggest?
This is what I've done till now to solve this
#RequestMapping(value = "/dog/create/{name}", method = RequestMethod.POST)
public JsonNode dogCreation(HttpServletRequest httpRequest, #RequestParam("picture") String picture,
#PathVariable("name") String name) throws IOException, InterruptedException {
JSONObject response = new JSONObject();
Dog dog = new Dog();
String DOG_IMAGES_BASE_LOCATION = "resource\\images\\dogImages";
try {
File file = new File(DOG_IMAGES_BASE_LOCATION);
if (!file.exists()) {
file.mkdirs();
}
} catch (Exception e) {
e.printStackTrace();
}
dog = dogService.getDogByName(name);
if (dog == null) {
if (!picture.isEmpty()) {
String dogPicture = picture;
byte[] encodedDogPicture = Base64.encodeBase64(dogPicture.getBytes());
String format = dogPicture.substring(picture.lastIndexOf("."));
try {
} catch (Exception e) {
e.printStackTrace();
}
}
}
return objectMapper.readTree(response.toString());
}
I just have to say that this should probably only be used as a workaround.
On your frontend, convert the file to base64 in js:
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function(evt) {
console.log(evt.target.result);
//do POST here - something like this:
$.ajax("/upload64", {
method: "POST",
contentType: "application/text"
data: evt.target.result
}
};
On the server with an example of a decoder - more decoding options here Decode Base64 data in Java
import sun.misc.BASE64Decoder;
#PostMapping("/upload64")
public String uploadBase64(#RequestBody String payload){
BASE64Decoder decoder = new BASE64Decoder();
byte[] decodedBytes = decoder.decodeBuffer(encodedBytes);
//use your bytes
}

Spark-Streaming CustomReceiver Unknown Host Exception

I am new to spark streaming. I want to stream a url online in order to retrieve info from a certain URL, I used the JavaCustomReceiver in order to stream a url.
This is the code I'm using (source)
public class JavaCustomReceiver extends Receiver<String> {
private static final Pattern SPACE = Pattern.compile(" ");
public static void main(String[] args) throws Exception {
SparkConf sparkConf = new SparkConf().setAppName("JavaCustomReceiver");
JavaStreamingContext ssc = new JavaStreamingContext(sparkConf, new Duration(1000));
JavaReceiverInputDStream<String> lines = ssc.receiverStream(
new JavaCustomReceiver("http://stream.meetup.com/2/rsvps", 80));
JavaDStream<String> words = lines.flatMap(new
FlatMapFunction<String, String>() {
#Override
public Iterator<String> call(String x) {
return Arrays.asList(SPACE.split(x)).iterator();
}
});
JavaPairDStream<String, Integer> wordCounts = words.mapToPair(
new PairFunction<String, String, Integer>() {
#Override
public Tuple2<String, Integer> call(String s) {
return new Tuple2<>(s, 1);
}
}).reduceByKey(new Function2<Integer, Integer, Integer>() {
#Override
public Integer call(Integer i1, Integer i2) {
return i1 + i2;
}
});
wordCounts.print();
ssc.start();
ssc.awaitTermination();
}
String host = null;
int port = -1;
public JavaCustomReceiver(String host_, int port_) {
super(StorageLevel.MEMORY_AND_DISK_2());
host = host_;
port = port_;
}
public void onStart() {
new Thread() {
#Override
public void run() {
receive();
}
}.start();
}
public void onStop() {
}
private void receive() {
try {
Socket socket = null;
BufferedReader reader = null;
String userInput = null;
try {
// connect to the server
socket = new Socket(host, port);
reader = new BufferedReader(
new InputStreamReader(socket.getInputStream(), StandardCharsets.UTF_8));
// Until stopped or connection broken continue reading
while (!isStopped() && (userInput = reader.readLine()) != null) {
System.out.println("Received data '" + userInput + "'");
store(userInput);
}
} finally {
Closeables.close(reader, /* swallowIOException = */ true);
Closeables.close(socket, /* swallowIOException = */ true);
}
restart("Trying to connect again");
} catch (ConnectException ce) {
// restart if could not connect to server
restart("Could not connect", ce);
} catch (Throwable t) {
restart("Error receiving data", t);
}
}
}
However, I keep getting a java.net.UnknownHostException
How can I fix this? What is wrong with the code that I'm using ?
After reading the code of the custom receiver referenced, it is clear that it is a TCP receiver that connects to a host:port and not an HTTP receiver that could take an URL. You'll have to change the code to read from an HTTP endpoint.

an integer or string of size 1 is required exception

I was trying a sketch program found online that connects wirelessly to my Raspberry pi using HttpURLConnection.. it's catching the exception "an integer or string of size 1 is required" and i dunno where's the error yet. The program basically sends a character or number when the user hits a button on UI to the webserver running on Raspberry pi. here's a part of the send command:
private void sendCommand(String command) {
final String cmd = command;
AsyncTask task = new AsyncTask() {
private String resp;
#Override
protected Object doInBackground(Object... params) {
try {
resp = Sender.getStringResponseFromGetRequest(
"http://192.168.1.111:8888/" + cmd);
} catch (IOException e) {
resp = e.getMessage();
}
return null;
}
};
}
#Override
protected void onPostExecute(Object result) {
if(!resp.equals("OK")){
Toast.makeText(ctx, resp, Toast.LENGTH_LONG).show();
}
super.onPostExecute(result);
}
};
task.execute();
}
}
and here's the getStringResponse.. Method:
public static String getStringResponseFromGetRequest(String requestUrl)
throws IOException {
URL url1;
URLConnection urlConnection;
DataInputStream inStream;
url1 = new URL(requestUrl);
urlConnection = url1.openConnection();
((HttpURLConnection) urlConnection).setRequestMethod("GET");
urlConnection.setDoInput(true);
urlConnection.setDoOutput(false);
urlConnection.setUseCaches(false);
inStream = new DataInputStream(urlConnection.getInputStream());
return inStream.readLine();
}

Web service request working in old version of android (2.3.3) but not in later versions (4.0.3, 4.3)

While working on an application for android that uses web services I encounterd a bad request (response code 400) message when trying to retrieve some data in android versions 4.0.3 and 4.3. The perculiar thing however is that when sending the same request using the same code but on a device using android version 2.3.3 it works without any problems. I have also tried using httpGet instead of HttpsURLConnection, while this work for all versions it does not provide a solution as I need the added security.
My code is as follows:
private String executeRequest(String urlAddress)
{
String responce = null;
String msg = null;
int error = 0;
try {
URL url = new URL(urlAddress);
HttpsURLConnection connection = (HttpsURLConnection)url.openConnection();
SSLSocketFactory factory = SecureSocketFactory.getSSLSocketFactory();
connection.setSSLSocketFactory(factory);
connection.setHostnameVerifier(new Verifier());
connection.setDoOutput(true);
connection.setDoInput(true);
if (method == RequestMethod.POST)
{
connection.setRequestMethod("POST");
}
msg = connection.getResponseMessage();
error = connection.getResponseCode();
if ("OK".equals(msg))
{
InputStream content = (InputStream) connection.getContent();
responce = convertStreamToString(content);
}
else
{
responce = "Error " + error;
}
connection.disconnect();
} catch (Exception e) {
responce = e.toString();
}
return responce;
}
And the code of SecureSocketFactory.getSSLSocketFactory():
public static SSLSocketFactory getSSLSocketFactory()
throws IOException
{
if(ssf_ == null)
{
javax.net.ssl.KeyManager kms[] = null;
javax.net.ssl.TrustManager tms[] = null;
SSLContext context = null;
try
{
tms = CustomTrustManager.getTrustManagers();
context = SSLContext.getInstance("TLS");
context.init(kms, tms, null);
}
catch(GeneralSecurityException e)
{
IOException io = new IOException(e.getLocalizedMessage());
io.setStackTrace(e.getStackTrace());
throw io;
}
ssf_ = context.getSocketFactory();
}
return ssf_;
}
and the code of CustomTrustManager.getTrustManagers()
static TrustManager[] getTrustManagers(String trustStoreFile, String trustStorePW)
throws NoSuchAlgorithmException, KeyStoreException
{
String alg = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmFact = TrustManagerFactory.getInstance(alg);
tmFact.init((KeyStore)null);
TrustManager tms[] = tmFact.getTrustManagers();
for(int i = 0; i < tms.length; i++)
if(tms[i] instanceof X509TrustManager)
tms[i] = new CustomTrustManager((X509TrustManager)tms[i]);
return tms;
}
static TrustManager[] getTrustManagers()
throws NoSuchAlgorithmException, KeyStoreException
{
return getTrustManagers(null, null);
}
I have looked everywhere, but can't seem to find a solution please help.
I found my error, because do connection.setDoInput(true) it silencly sets my Requestmethod to post in version 4 which gives an error on the server causing it to return bad request.
apparently it does not set this in version 2, which explains why it does work there.
The following execute request method change fixed my code:
private String executeRequest(String urlAddress)
{
String responce = null;
String msg = null;
int error = 0;
try {
URL url = new URL(urlAddress);
HttpsURLConnection connection = (HttpsURLConnection)url.openConnection();
SSLSocketFactory factory = SecureSocketFactory.getSSLSocketFactory();
connection.setSSLSocketFactory(factory);
connection.setHostnameVerifier(new Verifier());
if (method == RequestMethod.POST)
{
connection.setDoOutput(true);
connection.setRequestMethod("POST");
}
else
{
connection.setDoInput(true);
connection.setRequestMethod("GET");
}
msg = connection.getResponseMessage();
error = connection.getResponseCode();
if ("OK".equals(msg))
{
InputStream content = (InputStream) connection.getContent();
responce = convertStreamToString(content);
}
else
{
responce = "Error " + error;
}
connection.disconnect();
} catch (Exception e) {
responce = e.toString();
}
return responce;
}

Proxy Username/Password in Apache HttpClient

I'm looking to perform a GET on the yahoo currency rate service via Apache HttpClient 4.1.2, but I'm getting an UknownHostException when I'm accessing via company firewall. The code works fine when I try it from home(without any proxy config, of course), though.
Also, the URL opens on my browser, but can't be pinged from command prompt.
A sample URL is http://quote.yahoo.com/d/quotes.csv?f=l1&s=USDINR=X
EDIT 2: Here's the complete code I used to connect to the Yahoo finance service:
GetRate.java
public class GetRate {
public static void main(String[] args) {
final String FROM = "USD";
final String TO = "INR";
ArrayList<String> paramsList = new ArrayList<String>();
paramsList.add(FROM + TO);
System.out.println("Tracking "+ TO + " vs. " + FROM + " Exchange Rate...");
try {
double _new = new Double(RestClient.doGet(paramsList));
double _old = _new;
while(true) {
_new = new Double(RestClient.doGet(paramsList));
if(_old != _new)
_old = _new;
Thread.sleep(1000);
}
} catch (HttpException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (URISyntaxException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
RestClient.java
public class RestClient {
public static final int HTTP_OK = 200;
public static final String SERVER_URL = "http://quote.yahoo.com/d/quotes.csv";
public static final String DEFAULT_ENCODING = "UTF-8";
public static String doGet(final ArrayList<String> params) throws HttpException,
IOException, URISyntaxException {
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpConnectionParams
.setConnectionTimeout(httpClient.getParams(), 10000);
httpClient = proxyConfig(httpClient);
HttpHost targetHost = new HttpHost(SERVER_URL);
String urlParams = "?f=l1";
if(!params.isEmpty()) {
for(String param : params) {
String paramString = "s=" + URLEncoder.encode(param, DEFAULT_ENCODING) + "=X";
urlParams += (urlParams.length() > 1) ? ("&" + paramString) : paramString;
}
}
HttpGet httpget = new HttpGet(urlParams);
System.out.println("Final URL: " + httpget.getURI().toString());
HttpResponse response = httpClient.execute(targetHost, httpget);
HttpEntity entity = response.getEntity();
InputStream instream = entity.getContent();
return read(instream);
}
private static String read(InputStream in) throws IOException {
StringBuilder sb = new StringBuilder();
BufferedReader r = new BufferedReader(new InputStreamReader(in), 1000);
for (String line = r.readLine(); line != null; line = r.readLine()) {
sb.append(line + ",");
}
in.close();
return sb.toString().substring(0, sb.length() - 1);
}
/** Proxy config Approach 1 */
private static DefaultHttpClient proxyConfig(DefaultHttpClient httpClient) {
AuthScope auth = new AuthScope("proxy.tcs.com", 8080);
Credentials creds = new UsernamePasswordCredentials("USER_NAME", "PASSWORD");
httpClient.getCredentialsProvider().setCredentials(auth, creds);
return httpClient;
}
} for(String param : params) {
String paramString = "s=" + URLEncoder.encode(param, DEFAULT_ENCODING) + "=X";
urlParams += (urlParams.length() > 1) ? ("&" + paramString) : paramString;
}
}
HttpGet httpget = new HttpGet(urlParams);
HttpResponse response = httpClient.execute(targetHost, httpget);
HttpEntity entity = response.getEntity();
InputStream instream = entity.getContent();
Approach 2: I also tried the following proxy config, but couldn't find out how to add the username/password.
/** Proxy config Approach 2 */
HttpHost proxy = new HttpHost("PROXY_HOST", PROXY_PORT);
httpClient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
Thanks,
Debojit
EDIT 1:
Stacktrace for Approach 1:
java.net.UnknownHostException: http://quote.yahoo.com/d/quotes.csv
at java.net.Inet6AddressImpl.lookupAllHostAddr(Native Method)
at java.net.InetAddress$1.lookupAllHostAddr(Unknown Source)
at java.net.InetAddress.getAddressFromNameService(Unknown Source)
at java.net.InetAddress.getAllByName0(Unknown Source)
at java.net.InetAddress.getAllByName(Unknown Source)
at java.net.InetAddress.getAllByName(Unknown Source)
at org.apache.http.impl.conn.DefaultClientConnectionOperator.resolveHostname(DefaultClientConnectionOperator.java:242)
at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:130)
at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:149)
at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:121)
at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:573)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:425)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:820)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:776)
at ws.client.RestClient.doGet(RestClient.java:48)
at ws.client.GetRate.main(GetRate.java:22)
Stacktrace for Approach 2:
Exception in thread "main" java.lang.NumberFormatException: For input string: "<HEAD><TITLE>Proxy Authorization Required</TITLE></HEAD>,<BODY BGCOLOR="white" FGCOLOR="black"><H1>Proxy Authorization Required</H1><HR>,<FONT FACE="Helvetica,Arial"><B>,Description: Authorization is required for access to this proxy</B></FONT>,<HR>,<!-- default "Proxy Authorization Required" response (407) -->,</BODY>,"
at sun.misc.FloatingDecimal.readJavaFormatString(Unknown Source)
at java.lang.Double.valueOf(Unknown Source)
at java.lang.Double.<init>(Unknown Source)
at ws.client.GetRate.main(GetRate.java:22)
The thing is, I'm not sure where the code is getting the HTML as input, and why.
Are you using "PROXY_HOST" literally for proxy constructor? If so, you have to use the proxy host in your browser configuration. Same for PROXY_PORT.
You will not be able to ping Yahoo from Your company because of the firewall, but you can access through your browser because it is configured to use a proxy server.

Resources