Error code:500 received in HttpsURLConnection - java

I am sending a HttpsURLConnection request to a server which requires a basic auth with it. I have provided the authorization value and verified it as well. But I'm getting a Http status 500: Internal Server error. Here is my code:
public String httptest(String url, File f, String username, String password) throws Exception {
// Task attachments endpoint
HttpsURLConnection connection = (HttpsURLConnection) new URL(url).openConnection();
// Set basic auth header
String apiKey = username + ":" + password;
String basicAuth = "Basic " + new String(new Base64().encode(apiKey.getBytes()));
connection.setRequestProperty("Authorization", basicAuth);
connection.setRequestMethod("POST");
connection.setRequestProperty("Connection", "Keep-Alive");
logger.info("basicAuth: " + basicAuth);
// Indicate a POST request
connection.setDoOutput(true);
// A unique boundary to use for the multipart/form-data
String boundary = Long.toHexString(System.currentTimeMillis());
String fboundary = "----WebKitFormBoundary" + boundary + "u0gW";
connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + fboundary);
// Construct the body of the request
logger.info("boundary: " + fboundary);
PrintWriter writer = null;
try {
writer = new PrintWriter(new OutputStreamWriter(connection.getOutputStream(), "UTF-8"));
String fileName = f.getName();
String ffname = fileName.substring(fileName.lastIndexOf("\\")+1);
writer.append("--" + fboundary).append(LINE_FEED);
writer.append("Content-Disposition: multipart/form-data; name=\"file\"; filename=\"" + ffname + "\"").append(LINE_FEED);
writer.append("Content-Type: application/x-zip-compressed").append(LINE_FEED);
writer.append(LINE_FEED);
logger.info("fileName: " + fileName);
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(new FileInputStream(f), "UTF-8"));
for (String line; (line = reader.readLine()) != null; ) {
writer.append(line).append(LINE_FEED);
}
} finally {
if (reader != null) try {
reader.close();
} catch (IOException logOrIgnore) {
}
}
writer.append(LINE_FEED);
writer.append("----" + fboundary).append(LINE_FEED);
writer.append(LINE_FEED);
writer.flush();
writer.close();
} catch (Exception e) {
System.out.append("Exception writing file" + e);
} finally {
if (writer != null) writer.close();
}
logger.info("ResponseCode: " + connection.getResponseCode());
//System.out.println(connection.getResponseCode()); // Should be 200
return connection.getResponseMessage();
}
When I send the same request through postman client, It works fine. Here are the headers from the postman request:
Authorization: Basic c2dveWFsQHF1YXJrLmNvbTpRdWFyazEyMw==
Cache-Control: no-cache Postman-Token:
d6fac5f0-e844-9bac-2bce-51580fdd5557 Content-Type:
multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
----WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-data; name="file"; filename="Tiger522.zip" Content-Type:
application/x-zip-compressed
----WebKitFormBoundary7MA4YWxkTrZu0gW
Please tell me what to do?

I can see two possible errors:
As StephaneM pointed out: The content-disposition of the file upload must be "form-data", not "multipart/form-data":
writer.append("Content-Disposition: form-data; name=\"file\";
filename=\"" + ffname + "\"").append(LINE_FEED);
You specify "Content-Type: application/x-zip-compressed" for the file upload. This means zip format. You are however just writing a file in there, using InputStreamReader. This does not seem to be a zip format that you are writing.

Related

android multipart/form-data POST get 400 error

I should send text/image files to one website using POST method.
But, I couldn't get 200 code after my MainActivity.
my code block
String crlf = "\r\n";
String twoHyphens = "--";
String boundary = "*****";
System.out.println("[Request] routine is started.");
URL url = new URL(_url);
urlConn = (HttpURLConnection) url.openConnection();
// [2-1]. urlConn setting
urlConn.setDoInput(true);
urlConn.setDoOutput(true);
urlConn.setUseCaches(false);
urlConn.setRequestMethod("POST"); // URL method : POST.
urlConn.setRequestProperty("Connection", "keep-alive");
urlConn.setRequestProperty("Cache-Control", "no-cache");
urlConn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
// [2-2]. parameter send and read data
OutputStream os = urlConn.getOutputStream();
DataOutputStream request = new DataOutputStream(os);
// Write key and values
// 1. Access Key
request.writeBytes(twoHyphens + boundary + crlf);
request.writeBytes("Content-Disposition: form-data; name=\"accessKey\"" + crlf);
request.writeBytes("Content-Type: application/json" + crlf);
request.writeBytes(crlf);
request.writeBytes(accessKey + crlf);
// 2. Image data
request.writeBytes(twoHyphens + boundary + crlf);
request.writeBytes("Content-Disposition: form-data; name=\"files\"" + crlf);
request.writeBytes("Content-Type: image/jpeg" + crlf);
request.writeBytes(crlf);
request.write(imageBytes);
request.writeBytes(crlf);
request.writeBytes(twoHyphens + boundary + twoHyphens + crlf);
request.flush();
request.close();
int response_code = urlConn.getResponseCode();
System.out.println("Connection response code : [" + response_code + "]");
I think my DataOutputStream code is not bad, but I get 400 error:
I/System.out: [Request] routine is started.
D/EGL_emulation: app_time_stats: avg=45.59ms min=8.56ms max=670.08ms count=23
I/System.out: Connection response code : [400]
I/System.out: [doInBackground] output : Response Code : 400
I/System.out: [onPostExecute] routine is started.
I/System.out: [onPostExecute] output : Response Code : 400
What's wrong?

How can Upload a file to Sharepoint?

private void uploadDocToSharePoint(String token, Resource resource, String folderName) {
try {
String uploadUrl = Utils.SHARE_POINT_DOMAIN + "_api/web/getfolderbyserverrelativeurl('" + folderName + "')/files/add(url='" + resource.getFilename() + "', overwrite=true)";
URL url = new URL(uploadUrl);
HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
// Set Header
httpConn.setDoOutput(true);
httpConn.setDoOutput(true);
httpConn.setRequestMethod("POST");
httpConn.setRequestProperty("Authorization", "Bearer " + token);
httpConn.setRequestProperty("accept", "application/json; odata=verbose");
httpConn.setRequestProperty("Content-Type", "application/xml");
OutputStream os = httpConn.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os, StandardCharsets.UTF_8);
osw.write("Just Some Text");
osw.flush();
osw.close();
os.close(); //don't forget to close the OutputStream
httpConn.connect();
System.out.println(httpConn.getResponseCode());
System.out.println(httpConn.getResponseMessage());
String result;
BufferedInputStream bis = new BufferedInputStream(httpConn.getInputStream());
ByteArrayOutputStream buf = new ByteArrayOutputStream();
int result2 = bis.read();
while(result2 != -1) {
buf.write((byte) result2);
result2 = bis.read();
}
result = buf.toString();
System.out.println(result);
} catch (Exception e) {
System.out.println("Error while reading file: " + e.getMessage());
}
}
httpConn.getResponseCode() is 400 and httpConn.getResponseMessage() is Bad Request.
I have tested this request with the URL generated in this class on Postman.
it works correctly.
so I am sure about url and token is correct.
It creates an Empty file successfully.
But as I mentioned the response status is 400 and Bad Request.
I am not sure what is wrong with the following class
Sharepoint guide here
My class copied from here
screenshot here
Pls follow Sharepoint guide here

JAVA HttpsConnection POST send image and text

I am trying to send a text and a image via HTTP POST and I always get a 400 error. I would like to use it to send a image via Telegram bot and I am using the code provided in this answer with a text and bite parameters https://stackoverflow.com/a/2793153/1970613 with small modifications.
What could be the error ?
String param = "chat_id=mi_id&photo=";
String charset = "UTF-8";
String request = "https://api.telegram.org/bot-botCOde/sendPhoto";
URL url = new URL( request );
File binaryFile = new File("/home/joseantonio/imagen.jpg");
String CRLF = "\r\n"; // Line separator required by multipart/form-data.
String boundary = Long.toHexString(System.currentTimeMillis());
HttpURLConnection conn= (HttpURLConnection) url.openConnection();
conn.setDoOutput( true );
conn.setInstanceFollowRedirects( false );
conn.setRequestMethod( "POST" );
conn.setRequestProperty( "charset", "utf-8");
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
conn.setUseCaches( false );
try {
OutputStream output = conn.getOutputStream();
PrintWriter writer = new PrintWriter(new OutputStreamWriter(output, charset), true);
writer.append("--" + boundary).append(CRLF);
writer.append("Content-Disposition: form-data; name=\"param\"").append(CRLF);
writer.append("Content-Type: text/plain; charset=" + charset).append(CRLF);
writer.append(CRLF).append(param).append(CRLF).flush();
writer.append("--" + boundary).append(CRLF);
writer.append("Content-Disposition: form-data; name=\"binaryFile\"; filename=\"" + binaryFile.getName() + "\"").append(CRLF);
writer.append("Content-Type: image/jpg").append(CRLF);
writer.append("Content-Transfer-Encoding: binary").append(CRLF);
writer.append(CRLF).flush();
Files.copy(binaryFile.toPath(), output);
output.flush(); // Important before continuing with writer!
writer.append(CRLF).flush(); // CRLF is important! It indicates end of boundary.
// End of multipart/form-data.
writer.append("--" + boundary + "--").append(CRLF).flush();
int responseCode2 = conn.getResponseCode();
System.out.println("\nSending 'GET' request to URL : " + request);
System.out.println("Response Code : " + responseCode2);```
I believe the fact that you are using https url is the cause of the error you are getting. You need to handle things a little different when you are submitting to an https url. See an example here

GAE sending post request with multipart/form-data, file from blobstore with SSL

I want to upload a file from the blobstore to a service called Wisita.
Here is the documentation for the upload API :
http://wistia.com/doc/upload-api
Here is my code so far (I think i might missing the ssl option)
FileService fileService = FileServiceFactory.getFileService();
AppEngineFile binaryFile = fileService.getBlobFile(new BlobKey("my blob key"));
String param = "api_password=" + URLEncoder.encode("my wisita key", "UTF-8") +
"&project_id=" + URLEncoder.encode("folder_id", "UTF-8");
String charset = "UTF-8";
String boundary = Long.toHexString(System.currentTimeMillis()); // Just generate some unique random value.
String CRLF = "\r\n"; // Line separator required by multipart/form-data.
URLConnection connection = new URL("https://upload.wistia.com/").openConnection();
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
PrintWriter writer = null;
try {
OutputStream output = connection.getOutputStream();
writer = new PrintWriter(new OutputStreamWriter(output, charset), true); // true = autoFlush, important!
// Send normal param.
writer.append("--" + boundary).append(CRLF);
writer.append("Content-Disposition: form-data; name=\"param\"").append(CRLF);
writer.append("Content-Type: text/plain; charset=" + charset).append(CRLF);
writer.append(CRLF);
writer.append(param).append(CRLF).flush();
// Send binary file.
writer.append("--" + boundary).append(CRLF);
writer.append("Content-Disposition: form-data; name=\"binaryFile\"; filename=\"" + binaryFile.getNamePart() + "\"").append(CRLF);
writer.append("Content-Type: " + URLConnection.guessContentTypeFromName(binaryFile.getNamePart())).append(CRLF);
writer.append("Content-Transfer-Encoding: binary").append(CRLF);
writer.append(CRLF).flush();
InputStream input = null;
try {
FileReadChannel ch = fileService.openReadChannel(binaryFile, true);
input = Channels.newInputStream(ch);
byte[] buffer = new byte[1024];
for (int length = 0; (length = input.read(buffer)) > 0;) {
output.write(buffer, 0, length);
}
output.flush(); // Important! Output cannot be closed. Close of writer will close output as well.
} finally {
if (input != null) try { input.close(); } catch (IOException logOrIgnore) {}
}
writer.append(CRLF).flush(); // CRLF is important! It indicates end of binary boundary.
// End of multipart/form-data.
writer.append("--" + boundary + "--").append(CRLF);
//resp part
InputStream responseStream = new BufferedInputStream(connection.getInputStream());
BufferedReader responseStreamReader = new BufferedReader(new InputStreamReader(responseStream));
String line = "";
StringBuilder stringBuilder = new StringBuilder();
while ((line = responseStreamReader.readLine()) != null)
{
stringBuilder.append(line).append("\n");
}
responseStreamReader.close();
String response = stringBuilder.toString();
resp.getWriter().write(response);
} finally {
if (writer != null) writer.close();
}
I got a 500 error with this code
Thank you for your question. As a reference it solved the issue I was having doing a similar task.
The first change I made to my code was to set both the doOutput and the doInput to true (not just the doOutput). I'm not sure if that makes a difference, since I believe true is the default.
con.setDoOutput(true);
con.setDoInput(true);
Are you sure your content is being encoded correctly? I used the same setup and configuration you have, but instead of using a PrintWriter, I just called write and passed it the bytes from my String and bytes from my File contents:
connection.getOutputStream().write("Content-Disposition blah...".getBytes());
connection.getOutputStream().write(fileContentsByteArray);
connection.flush();
I then just read the data I needed back from my web service by reading from the connection's input stream like this:
FileOutputStream out = new FileOutputStream("received.bin");
InputStream in = connection.getInputStream();
byte[] buffer = new byte[1024];
int len;
while ((len = in.read(buffer)) != -1) {
out.write(buffer, 0, len);
}
out.close();
How about change passing normal parameters?
Before:
param=..api_password...project_id...;
// Send normal param.
writer.append("--" + boundary).append(CRLF);
writer.append("Content-Disposition: form-data; name=\"param\"").append(CRLF);
writer.append("Content-Type: text/plain; charset=" + charset).append(CRLF);
writer.append(CRLF);
writer.append(param).append(CRLF).flush();
After:
// Send normal param.
writer.append("--" + boundary).append(CRLF);
writer.append("Content-Disposition: form-data; name=\"api_password\"").append(CRLF);
writer.append("Content-Type: text/plain; charset=" + charset).append(CRLF);
writer.append(CRLF);
writer.append(api_password).append(CRLF).flush();
// Send normal param.
writer.append("--" + boundary).append(CRLF);
writer.append("Content-Disposition: form-data; name=\"project_id\"").append(CRLF);
writer.append("Content-Type: text/plain; charset=" + charset).append(CRLF);
writer.append(CRLF);
writer.append(project_id).append(CRLF).flush();

HttpURLConnection POST, conn.getOutputStream() throwing Exception

I want to make a POST by using HttpURLConnection.
I am trying this in 2 ways, but I always get an excetion when doing: conn.getOutputStream();
The exception I get in both cases is:
java.net.SocketException: Operation timed out: connect:could be due to
invalid address
function1:
public void makePost(String title, String comment, File file) {
try {
URL servlet = new URL("http://" + "www.server.com/daten/web/test/testupload.nsf/upload?CreateDocument");
HttpURLConnection conn=(HttpURLConnection)servlet.openConnection();
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);
String boundary = "---------------------------7d226f700d0";
conn.setRequestProperty("Content-type","multipart/form-data; boundary=" + boundary);
//conn.setRequestProperty("Referer", "http://127.0.0.1/index.jsp");
conn.setRequestProperty("Cache-Control", "no-cache");
OutputStream os = conn.getOutputStream(); //exception throws here!
DataOutputStream out = new DataOutputStream(os);
out.writeBytes("--" + boundary + "\r\n");
writeParam(INPUT_TITLE, title, out, boundary);
writeParam(INPUT_COMMENT, comment, out, boundary);
writeFile(INPUT_FILE, file.getName(), out, boundary);
out.flush();
out.close();
InputStream stream = conn.getInputStream();
BufferedInputStream in = new BufferedInputStream(stream);
int i = 0;
while ((i = in.read()) != -1) {
System.out.write(i);
}
in.close();
} catch (Exception e) {
e.printStackTrace();
}
}
or function 2:
public void makePost2(String title, String comment, File file) {
File binaryFile = file;
String boundary = Long.toHexString(System.currentTimeMillis()); // Just generate some unique random value.
URLConnection connection = null;
try {
connection = new URL("http://" + "www.server.com/daten/web/test/testupload.nsf/upload?CreateDocument").openConnection();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
PrintWriter writer = null;
try {
OutputStream output = connection.getOutputStream(); //exception throws here
writer = new PrintWriter(new OutputStreamWriter(output, CHARSET), true); // true = autoFlush, important!
// Send normal param.
writer.println("--" + boundary);
writer.println("Content-Disposition: form-data; name=\""+ INPUT_TITLE +"\"");
writer.println("Content-Type: text/plain; charset=" + CHARSET);
writer.println();
writer.println(title);
// Send binary file.
writer.println("--" + boundary);
writer.println("Content-Disposition: form-data; name=\""+ INPUT_FILE +"\"; filename=\"" + binaryFile.getName() + "\"");
writer.println("Content-Type: " + URLConnection.guessContentTypeFromName(binaryFile.getName()));
writer.println("Content-Transfer-Encoding: binary");
writer.println();
InputStream input = null;
try {
input = new FileInputStream(binaryFile);
byte[] buffer = new byte[1024];
for (int length = 0; (length = input.read(buffer)) > 0;) {
output.write(buffer, 0, length);
}
output.flush(); // Important! Output cannot be closed. Close of writer will close output as well.
} catch (IOException e) {
e.printStackTrace();
} finally {
if (input != null) try { input.close(); } catch (IOException logOrIgnore) {}
}
writer.println(); // Important! Indicates end of binary boundary.
// End of multipart/form-data.
writer.println("--" + boundary + "--");
} catch (IOException e) {
e.printStackTrace();
} finally {
if (writer != null) writer.close();
}
}
The URL simply cannot be reached. Either the URL is wrong, or the DNS server couldn't resolve the hostname. Try a simple connect with a well-known URL to exclude one and other, e.g.
InputStream response = new URL("http://stackoverflow.com").openStream();
// Consume response.
Update as per the comments, you're required to use a proxy server for HTTP connections. You need to configure that in the Java side as well. Add the following lines before any attempt to connect to an URL.
System.setProperty("http.proxyHost", "proxy.example.com");
System.setProperty("http.proxyPort", "8080");
It suffices to do this only once during runtime.
See also:
Java guides - Networking and proxies
Without establishing the connection (which in this case requires 1 more step to be performed ie connect), transfer is not possible. connect() should be called after the connection is configured (ie after being done with the set***() on the connection).
What is missing is:
conn.connect();

Categories