Dailymotion upload error "no content" - java

I'm developping a web application capable of upload video on Dailymotion all was find during 1 years and i have seen an error recently occuring when i upload a video on Dailymotion.
{
"error": "missing content"
"seal": "540f4ad5a0f9c6a7e85a46be98361581"
}
I use java and the lib "org.apache.http" for doing my call on dailymotion.
my code look like this :
Path temp = Files.createTempFile(multipartFile.getName(), "." + suffix);
multipartFile.transferTo(temp.toFile());
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
builder.addPart(multipartFile.getOriginalFilename(), new FileBody(temp.toFile(),
ContentType.APPLICATION_OCTET_STREAM, multipartFile.getOriginalFilename()));
httpPost.setEntity(builder.build());
try (CloseableHttpClient httpclient = HttpClients.createDefault();
CloseableHttpResponse response = httpclient.execute(httpPost);) {
HttpEntity entity = response.getEntity();
ObjectMapper mapper = new ObjectMapper();
DailymotionUploadVideoResponse dmUploadResponse = mapper.readValue(entity.getContent(),
DailymotionUploadVideoResponse.class);
// Delete temp file after upload
Files.deleteIfExists(temp);
if (dmUploadResponse.getError() != null) {
throw new DailymotionJsonException(dmUploadResponse.getError().getMessage());
}
EntityUtils.consume(entity);
response.close();
POST on url retrieve by dailymotion :
http://upload-12.dc3.dailymotion.com/upload?uuid=035e365c5b2355616e381f43c1b2b391&seal=edad1d3ad9e348c65e975582571e5815
Header of the POST request :
Content-Disposition:
form-data;
name="2015-07-16-192550-1.webm";
filename="2015-07-16-192550-1.webm",
Content-Type: application/octet-stream,
Content-Transfer-Encoding: binary
I don't understand why i'm doing wrong.
I test via curl and i have the same error.
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryImx1443wQZZBF0Fb
Content-Length: 1398401
Source message
POST /upload?uuid=035e365c5b2355616e381f43c1b2b391&seal=edad1d3ad9e348c65e975582571e5815 HTTP/1.1
HOST: upload-12.dc3.dailymotion.com
content-type: multipart/form-data; boundary=----WebKitFormBoundaryImx1443wQZZBF0Fb
content-length: 1398401
------WebKitFormBoundaryImx1443wQZZBF0Fb
Content-Disposition: form-data; name="2015-07-16-192550-1.webm"; filename="2015-07-16-192550-1.webm"
Content-Type: video/webm

API dailymotion have changed, change the code
builder.addPart(multipartFile.getOriginalFilename(), new FileBody(temp.toFile(),
ContentType.APPLICATION_OCTET_STREAM, multipartFile.getOriginalFilename()));
by :
builder.addPart("file", new FileBody(temp.toFile(),
ContentType.APPLICATION_OCTET_STREAM, multipartFile.getOriginalFilename()));

Related

HTTP/1.1 400 Bad Request using base64 encoding in java

I am using http request. I have two image to call api. Image are base64encoding..but in postman it is working fine. It is not working in my java code..it shows bellow error
response = HTTP/1.1 400 Bad Request [Server: nginx/1.14.0 (Ubuntu), Date: Fri, 13 Nov 2020 09:24:20 GMT, Content-Type: application/json; charset=utf-8, Content-Length: 3866, Connection: keep-alive, X-Powered-By: Express, Access-Control-Allow-Origin: *, Access-Control-Expose-Headers: Origin, X-Requested-With, Content-Type, Accept, x-auth-token, x-login-token, x-verification-token, ETag: W/"f1a-xqn4nWVQUqRNj8g2mv5av6fbTrg"]
statusCode = 400
Postman header image
Postman body
I have used bellow code..
byte[] photo1=null;
byte[] photo2=null;
String base64encodedString = Base64.getEncoder().encodeToString(photo1);
String base64encodedString2 = Base64.getEncoder().encodeToString(photo2);
try {
DefaultHttpClient httpclient = new DefaultHttpClient(new BasicHttpParams());
HttpPost httppost = new HttpPost("url");
JSONObject jsonObject = new JSONObject();
try {
jsonObject.put("photo", base64encodedString);
jsonObject.put("nidFront", base64encodedString2);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("jsonObject = " + jsonObject);
StringEntity params = new StringEntity(String.valueOf(jsonObject));
httppost.addHeader("content-type", "application/json");
httppost.setHeader("x-auth-token", token);
httppost.setEntity(params);
HttpResponse response = httpclient.execute(httppost);
int statusCode = response.getStatusLine().getStatusCode();
System.out.println("statusCode = " + statusCode);
Please help me what is wrong in code

Sending multipart/mixed request with Jersey Client

I want to dialogue with this API service programmatically using Jersey (https://eclipse-ee4j.github.io/jersey/)
here's the Rest Controller implementation in Spring:
#PostMapping(
value = "/api/my-endpoint",
consumes = MediaType.MULTIPART_MIXED_VALUE)
public void enrichInvoice(#RequestPart("metadata") Map<String, Object> request,
#RequestPart("human") MultipartFile humanFile) {
log.info(String.format("received request:%n%s", request));
}
my client implementation would be like this
...
final Client client = ClientBuilder.newClient(new ClientConfig()
.register(MultiPartFeature.class)
.register(JacksonFeature.class)
);
final FileDataBodyPart filePart = new FileDataBodyPart("human",myFile()));
final BodyPart metadata = new BodyPart().entity(voBuilder.generateMetadata());
final MultiPart multiPartEntity = new MultiPart();
multiPartEntity.bodyPart(metadata, MediaType.APPLICATION_JSON_TYPE);
multiPartEntity.bodyPart(filePart);
final WebTarget target = client
.target("http://localhost:8080/api/my-endpoint");
final Entity<MultiPart> entity = Entity
.entity(multiPartEntity, multiPartEntity.getMediaType());
log.info(entity.toString());
final Response response = target
.request()
.post(entity);
log.info(String.format("%s", response.readEntity(String.class)));
response.close();
...
But i keep getting this error:
Resolved [org.springframework.web.multipart.support.MissingServletRequestPartException: Required request part 'metadata' is not present]
which is because the metadata part has to be named "metadata". and I cannot find a way to name it using BodyPart. I also tried using FormDataBodyPart to build the metadata
FormDataBodyPart metadataBodyPart = new FormDataBodyPart("metadata", metadata,
MediaType.APPLICATION_JSON_TYPE);
but with the same result.
Can you help me figure out what am I missing in the bodyPart definition?
Thanks
EDIT: here's the http request sent from my client implementation
Content-Type: multipart/mixed;boundary=Boundary_1_1972899462_1597045386454
User-Agent: Jersey/2.29 (HttpUrlConnection 11.0.8)
MIME-Version: 1.0
Host: localhost:8080
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive
Content-Length: 765
--Boundary_1_1972899462_1597045386454
Content-Type: application/json
{"value":"key"}
--Boundary_1_1972899462_1597045386454
Content-Type: application/octet-stream
Content-Disposition: form-data; filename="file.zip"; modification-date="Wed, 05 Aug 2020 16:52:52 GMT"; size=0; name="human"
--Boundary_1_1972899462_1597045386454--
]
The solution, even if not optimal, was to treat the metadata as a text file
final Path tempFile = Files.createTempFile("prefix", "suffix");
File fileMetadata = Files.write(tempFile.toAbsolutePath(), JsonUtils.toString(metadata).getBytes());
final FileDataBodyPart metadataBodyPart = new FileDataBodyPart(
"metadata",
fileMetadata,
MediaType.APPLICATION_JSON_TYPE);
final FileDataBodyPart human = new FileDataBodyPart("human", new File(humanReadableFile.getFileKey()));
try (final MultiPart multiPartEntity = new MultiPart()) {
multiPartEntity.bodyPart(metadataBodyPart);
multiPartEntity.bodyPart(human);
final Response response = client
.target("http://localhost:8080/api/my-endpoint")
.request()
.post(Entity.entity(multiPartEntity, multiPartEntity.getMediaType()));
log.debug(String.valueOf(response.getStatus()));
log.debug(response.readEntity(String.class));
}
In this way the request body has to parts named "metadata" and "human" as requested by the controller implementation and still maintain the multipart/mixed content-type.

Setting HTTP headers on RESTeasy requests with attachments

I'm using RESTeasy 3.x to submit a REST request with an attachment to a third party service. They've asked that the request have the following headers set:
Accept: application/json
Content-Disposition: attachment; filename="attamentFilename"
Content-Type: application/octet-stream
My first attempt was simply to add the headers as I've seen done with Authorization header like this:
protected Response getResponse(final String url, final String filename, final InputStream attachment) {
ResteasyWebTarget target = resteasyClient.target(url);
MultipartFormDataOutput output = new MultipartFormDataOutput();
output.addFormData("attachment", attachment, MediaType.APPLICATION_OCTET_STREAM_TYPE);
Response response = target.request()
.header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON)
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM_TYPE)
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=\"" + filename + "\"")
.post(Entity.entity(output, MediaType.MULTIPART_FORM_DATA));
if (response.getStatus() != 200) {
throw new RuntimeException("Failed : HTTP error code : " + response.getStatus());
}
return response;
}
But, when I debugged from the server side the headers weren't being set as expected. I also tried a ClientRequestFilter, but again the headers weren't quite what I needed.
I've managed to get something close to what I need by using addFormData like this:
protected Response getResponse(final String url, final String filename, final InputStream attachment) {
ResteasyWebTarget target = resteasyClient.target(url);
MultipartFormDataOutput output = new MultipartFormDataOutput();
output.addFormData("attachment", attachment, MediaType.APPLICATION_OCTET_STREAM_TYPE, filename);
Response response = target.request()
.post(Entity.entity(output, MediaType.MULTIPART_FORM_DATA));
if (response.getStatus() != 200) {
throw new RuntimeException("Failed : HTTP error code : " + response.getStatus());
}
return response;
}
This produces two of the three headers I need:
Content-Disposition: form-data; name="attachment"; filename="attamentFilename"
Content-Type: application/octet-stream
I'm assuming MultipartFormDataOutput is discarding the headers I try to set and building its own, and that I can't use the .header method for all types of requests. Does this sound right?

Translate POSTMAN code into Java

I am trying to implement (in java) POSTMAN preview of POST request. it uses boundary and content-disposition, i am not so much familiar with boundary and content disposition implementation in java. I think experts can help me out from this problem, thanks in advance.
POST /etap-cgi/cgiunl.exe HTTP/1.1
Host: unl.ru
X-Auth-Token: 5dc347210229bd8b9565d213f0d4f80f738970083d03a8e73a0d5f649019272e
Cache-Control: no-cache
----WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="conversion"
true
----WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="language"
en
----WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="data"
aar partasi nah
----WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="outputmode"
text
----WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="coding"
utf-8
----WebKitFormBoundaryE19zNvXGzXaLvS5C
I have tried but it says'
Fatal error in process of translation
Here is my implementation in java.
HttpClient httpclient = new DefaultHttpClient();
try {
// url parameters
MultipartEntityBuilder multipartEntity = MultipartEntityBuilder
.create();
multipartEntity.addTextBody("conversion", "ture",
ContentType.TEXT_PLAIN);
multipartEntity.addTextBody("language", "en",
ContentType.TEXT_PLAIN);
multipartEntity.addTextBody("data", "example",
ContentType.TEXT_PLAIN);
multipartEntity.addTextBody("outputmode", "text",
ContentType.TEXT_PLAIN);
multipartEntity.addTextBody("coding", "utf-8",
ContentType.TEXT_PLAIN);
multipartEntity
.setBoundary("----WebKitFormBoundaryE19zNvXGzXaLvS5C");
HttpEntity multiPart = multipartEntity.build();
HttpPost httpPost = new HttpPost(
url);
httpPost.setEntity(multiPart);
httpPost.setHeader("Content-Disposition", "form-data");
// get response after execution
HttpResponse response = httpclient.execute(httpPost);
// get response entities
HttpEntity resEntity = response.getEntity();
if (resEntity != null) {
System.out.println("Response content length: "
+ resEntity.getContentLength());
String responseBody = EntityUtils.toString(resEntity);
System.out.println("Data: " + responseBody);
}
EntityUtils.consume(resEntity);
} catch (Exception err) {
System.err.println(err.toString());
} finally {
// close connection
httpclient.getConnectionManager().shutdown();
}
I have solved my problem by myself with uploading a file instead of multi-part string, here is the soln with the boundary param without "WebKitFormBoundary" characters. hope this will helpful for someone.
public String httpOperation(String conversion, String fileName) {
HttpClient httpclient = new DefaultHttpClient();
try {
// url parameters
MultipartEntityBuilder multipartEntity = MultipartEntityBuilder
.create();
// add html tags param
multipartEntity.addTextBody("conversion", conversion,
ContentType.TEXT_PLAIN);
multipartEntity.addTextBody("language", EN, ContentType.TEXT_PLAIN);
multipartEntity.addTextBody("outputmode", TEXT,
ContentType.TEXT_PLAIN);
multipartEntity.addTextBody("coding", UTF, ContentType.TEXT_PLAIN);
// add files as attachments
multipartEntity.addPart("sourcefile", new FileBody(new File(
fileName), ContentType.TEXT_PLAIN, "filename"));
multipartEntity.setBoundary(PARAM_BOUNDARY);
HttpEntity postEntity = multipartEntity.build();
HttpPost httpPost = new HttpPost(URL);
httpPost.setHeader("Content-Disposition", "form-data;");
httpPost.setEntity(postEntity);
// get response after execution
HttpResponse response = httpclient.execute(httpPost);
// get response entities
HttpEntity resEntity = response.getEntity();
if (resEntity != null) {
#SuppressWarnings("deprecation")
String responseBody = EntityUtils.toString(resEntity,
HTTP.UTF_8);
// print output
if (conversion.equals(TRUE)) {
extractResponse(responseBody.toString());
// System.out.println(responseBody.toString());
result = responseBody.toString();
} else {
// System.out.println(responseBody.toString());
result = responseBody.toString();
}
}
EntityUtils.consume(resEntity);
} catch (Exception err) {
System.err.println(err.toString());
} finally {
// close connection
httpclient.getConnectionManager().shutdown();
}
return result;
}
Here is the POSTMAN build preview
POST /url/ HTTP/1.1
Host: unl.ru
X-Auth-Token: 5dc347210229bd8b9565d213f0d4f80f738970083d03a8e73a0d5f649019272e
Cache-Control: no-cache
----WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="conversion"
false
----WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="language"
en
----WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="sourcefile"; filename="conversion.txt"
Content-Type: text/plain
----WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="outputmode"
text
----WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="coding"
utf-8
----WebKitFormBoundaryE19zNvXGzXaLvS5C

Uploading file in a https url in post method - java.io.IOException: Error writing to server - Java

I have to upload a binary image file to the server using multi-part, I open the connection to the https url and write diretly to to the outputstream. I have tried the SSLSocket, apache http client, but in all ways I get the error message, java.io.IOException: Error writing to server. I have to write post params with the multi-part binary file. The code is given below, where am I failing to see the mistake in this code below? And, I have given the sample data to write the data to the connection. I would be glad if anyone could give some idea how to do this with apache http client, which I do not know.
example packet data
header part
--------------
--aabbaabbaabbxx
Content-Disposition: form-data; name="to"
<recipient>
--aabbaabbaabbxx
Content-Disposition: form-data; name="from"
<sender>
--aabbaabbaabbxx
Content-Disposition: form-data; name="file"; filename="<file_hash>.jpg"
Content-Type: image/jpeg
footer
-----------
--aabbaabbaabbxx--
Are these request parameters?
-----------------------------
POST <full_url>
Content-Type: multipart/form-data; boundary=aabbaabbaabbxx
Host: <host_name>
User-Agent: <agent>
Content-Length: <file_size>
The code
final URL uri = new URL(uploadUrl);
String boundary = "aabbaabbaabbxx";
HttpURLConnection connection = (HttpURLConnection) uri.openConnection();
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setInstanceFollowRedirects(false);
connection.setAllowUserInteraction(false);
connection.setRequestMethod("POST");
connection.setUseCaches(false);
OutputStream writer = null;
try {
writer = connection.getOutputStream();
// post
writer.write(MessageFormat
.format("POST {0}\r\n", uploadUrl)
.getBytes("UTF-8"));
writer.write(MessageFormat
.format("Content-Type: multipart/form-data; boundary={0}\r\n",
boundary).getBytes("UTF-8"));
writer.write(MessageFormat.format("Host: {0}\r\n",uri.getHost()).getBytes("UTF-8"));
writer.write(MessageFormat.format("User-Agent: {0}\r\n",Constants.UserAgent).getBytes("UTF-8"));
writer.write(MessageFormat.format("Content-Length: {0}\r\n\r\n",clength).getBytes("UTF-8"));
// header
writer.write(("--" + boundary).getBytes("UTF-8"));
writer.write("Content-Disposition: form-data; name=\"to\"\r\n\r\n".getBytes("UTF-8"));
writer.write(MessageFormat.format("{0}\r\n", to).getBytes("UTF-8"));
writer.write(MessageFormat.format("--{0}\r\n", boundary).getBytes("UTF-8"));
writer.write("Content-Disposition: form-data; name=\"from\"\r\n\r\n".getBytes("UTF-8"));
writer.write(MessageFormat.format("{0}\r\n",this.phoneNumber).getBytes("UTF-8"));
writer.write(MessageFormat.format("--{0}\r\n", boundary).getBytes("UTF-8"));
writer.write(MessageFormat.format("Content-Disposition: form-data; name=\"file\"; filename=\"{0}\"\r\n",hashname).getBytes("UTF-8"));
writer.write(MessageFormat.format("Content-Type: {0}\r\n\r\n", contenttype).getBytes("UTF-8"));
// file data
InputStream is = null;
try {
is = new FileInputStream(path);
int data = 0;
while ((data = is.read()) != -1) {
writer.write(data);
}
} finally {
if (is != null) {
try {
is.close();
} catch (IOException logOrIgnore) {
}
}
}
// footer
writer.write(("--" + boundary + "--").getBytes("UTF-8"));
writer.flush();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (writer != null) {
writer.close();
}
}
Exception
java.io.IOException: Error writing to server
at sun.net.www.protocol.http.HttpURLConnection.writeRequests(HttpURLConnection.java:468)
at sun.net.www.protocol.http.HttpURLConnection.writeRequests(HttpURLConnection.java:480)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1070)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:234)
You can find the basic example for a "chunk encoded POST" on the Apache HttpClient example page.
For the form-based post you also need org.apache.httpcomponents:httpmime:4.3.2
With that you get the org.apache.http.entity.mime.MultipartEntityBuilder which you can use like so:
MultipartEntityBuilder meb = MultipartEntityBuilder.create();
meb.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
meb.addPart("to", new StringBody("The recipient", ContentType.TEXT_PLAIN));
meb.addPart("from", new StringBody("The sender", ContentType.TEXT_PLAIN));
FileBody fb = new FileBody(new File("path/to/your/file"), ContentType.create("image/jpeg"));
meb.addPart("file", fb);
meb.addPart("footer", new StringBody("The footer", ContentType.TEXT_PLAIN));
httppost.setEntity(meb.build());
That should help you on your way.

Categories