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
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?
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
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
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();
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();