Magnolia-cms fckeditor: Content-disposition:attachment for uploaded files - fckeditor

Is it possible to set content-disposition to "attachment" for files uploaded via fckeditor ?

I don't think so. Only for resources in DMS.

Actually I just figure out a work around; adding a servlet filter that alters http header attribute content-disposition to attachment and that's it!
here is a the code snippet:
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
StringBuffer fileName = new StringBuffer();
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
StringBuffer extension = new StringBuffer(
FilenameUtils.getExtension(req.getRequestURL().toString()));
log.debug("--***-- File extension : " + extension.toString());
if (extension.toString().equalsIgnoreCase("pdf")
|| extension.toString().equalsIgnoreCase(".pdf")) {
fileName.append(FilenameUtils.getBaseName(req.getRequestURL()
.toString()));
log.debug("--***-- PDF file name : " + fileName.toString());
resp.addHeader("Content-Disposition", "attachment; filename="
+ fileName);
}
chain.doFilter(request, resp);
}

Related

"multipart config was not present on Servlet" when trying to upload a file with JAX-RS class

I have the following JAX-RS class to upload a file from a browser (implemented in Wildfly 14). Problem is I get the error multipart config was not present on Servlet. Since I annotated the class with #Consumes({ MediaType.MULTIPART_FORM_DATA }) I'm not sure what is missing. How to fix this problem?
#Produces({ MediaType.APPLICATION_JSON })
#Consumes({ MediaType.MULTIPART_FORM_DATA })
public class FileUploadService {
#Context
private HttpServletRequest request;
#POST
#Path("/upload")
public Response processUpload() throws IOException, ServletException {
String path = "/mypath";
for (Part part : request.getParts()) {
String fileName = getFileName(part);
String fullPath = path + File.separator + fileName;
// delete file if exists
java.nio.file.Path path2 = FileSystems.getDefault().getPath(fullPath);
Files.deleteIfExists(path2);
// get file input stream
InputStream fileContent = part.getInputStream();
byte[] buffer = new byte[fileContent.available()];
fileContent.read(buffer);
File targetFile = new File(fullPath);
// write output file
OutputStream outStream = new FileOutputStream(targetFile);
outStream.write(buffer);
outStream.close();
}
return Response.ok("OK").build();
}
private String getFileName(Part part) {
for (String content : part.getHeader("content-disposition").split(";")) {
if (content.trim().startsWith("filename"))
return content.substring(content.indexOf("=") + 2, content.length() - 1);
}
return "";
}
}

How to send file name with NanoHttpd Response

I've successfully achieved file transfer over local network using NanoHttpd. However, I'm unable to send the file name in NanoHttpd Response. The received files have a default name like this: localhost_8080. I tried to attach file name in response header using Content-disposition, but my file transfer failed all together. What am I doing wrong? Here is my implementation:
private class WebServer extends NanoHTTPD {
String MIME_TYPE;
File file;
public WebServer() {
super(PORT);
}
#Override
public Response serve(String uri, Method method,
Map<String, String> header, Map<String, String> parameters,
Map<String, String> files) {
try {
file=new File(fileToStream);
fis = new FileInputStream(file);
bis = new BufferedInputStream(fis);
MIME_TYPE= URLConnection.guessContentTypeFromName(file.getName());
} catch (IOException ioe) {
Log.w("Httpd", ioe.toString());
}
NanoHTTPD.Response res=new NanoHTTPD.Response(Status.OK, MIME_TYPE, bis);
res.addHeader("Content-Disposition: attachment; filename=", file.getName());
return res;
}
}
Thanks for your help!
You need to specify the response, the MIME type, and the stream of bytes to be sent. After that you just add a header with the file name of the file since its a http method.
Here is a sample code that solves the problem
#Override
public Response serve(String uri, Method method,
Map<String, String> header, Map<String, String> parameters,
Map<String, String> files) {
FileInputStream fis = null;
try {
fis = new FileInputStream(fileName);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
NanoHTTPD.Response res = new NanoHTTPD.Response(Response.Status.OK, "application/vnd.android.package-archive", fis);
res.addHeader("Content-Disposition", "attachment; filename=\""+fileName+"\"");
return res;
}

Stripe Authentication

I am not able to authenticate in stripe.com - using Basic Authentication
public class Str extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter pw=response.getWriter();
pw.println("Hello World");
HttpClient client= new HttpClient();
String req="https://api.stripe.com/";
client.getParams().setAuthenticationPreemptive(true);
client.getState().setCredentials(new AuthScope(req, 443, null), new UsernamePasswordCredentials("<api-key>"));
client.getHostConfiguration().setHost(req, 443, "https");
PostMethod post= new PostMethod("https://api.stripe.com/v1/charges/");
//post.addParameter("id", "<id>");
int status=client.executeMethod(post);
pw.println(status);
}
}
i am presenting my code...where i hv used HTTP Basic Auth to provide the users credentials to stripe.com
Try: new UsernamePasswordCredentials("<api-key>", "")
Hope this will help you.
Here API_KEY means secrete key
HttpResponse httpResponse;
String request ='card[number]='+card_name+'&card[exp_year]='+card_exp_year+'&card[exp_month]='+card_exp_month+'&card[cvc]='+card_cvv+'&amount='+amount+ '&currency='+currency;
Http httpObject = new Http();
HttpRequest httpRequest = new HttpRequest();
httpRequest.setEndpoint(sHttpEndPoint);
httpRequest.setMethod('POST');
Blob headerValue = Blob.valueOf(API_KEY + ':');
String authorizationHeader = 'BASIC ' +
EncodingUtil.base64Encode(headerValue);
httpRequest.setHeader('Authorization', authorizationHeader);
httpRequest.setBody(request);
httpResponse = httpObject.send(httpRequest);

How to avoid OutOfMemoryError when uploading a large file using Jersey client

I am using Jersey client for http-based request. It works well if the file is small but run into error when I post a file with size of 700M:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:2786)
at java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:94)
at sun.net.www.http.PosterOutputStream.write(PosterOutputStream.java:61)
at com.sun.jersey.api.client.CommittingOutputStream.write(CommittingOutputStream.java:90)
at com.sun.jersey.core.util.ReaderWriter.writeTo(ReaderWriter.java:115)
at com.sun.jersey.core.provider.AbstractMessageReaderWriterProvider.writeTo(AbstractMessageReaderWriterProvider.java:76)
at com.sun.jersey.core.impl.provider.entity.FileProvider.writeTo(FileProvider.java:103)
at com.sun.jersey.core.impl.provider.entity.FileProvider.writeTo(FileProvider.java:64)
at com.sun.jersey.multipart.impl.MultiPartWriter.writeTo(MultiPartWriter.java:224)
at com.sun.jersey.multipart.impl.MultiPartWriter.writeTo(MultiPartWriter.java:71)
at com.sun.jersey.api.client.RequestWriter.writeRequestEntity(RequestWriter.java:300)
at com.sun.jersey.client.urlconnection.URLConnectionClientHandler._invoke(URLConnectionClientHandler.java:204)
at com.sun.jersey.client.urlconnection.URLConnectionClientHandler.handle(URLConnectionClientHandler.java:147)
at com.sun.jersey.api.client.Client.handle(Client.java:648)
at com.sun.jersey.api.client.WebResource.handle(WebResource.java:680)
at com.sun.jersey.api.client.WebResource.access$200(WebResource.java:74)
at com.sun.jersey.api.client.WebResource$Builder.post(WebResource.java:568)
at TestHttpRequest.main(TestHttpRequest.java:42)
here is my code:
ClientConfig cc = new DefaultClientConfig();
Client client = Client.create(cc);
WebResource resource = client.resource("http://localhost:8080/JerseyWithServletTest/helloworld");
FormDataMultiPart form = new FormDataMultiPart();
File file = new File("E:/CN_WXPPSP3_v312.ISO");
form.field("username", "ljy");
form.field("password", "password");
form.field("filename", file.getName());
form.bodyPart(new FileDataBodyPart("file", file, MediaType.MULTIPART_FORM_DATA_TYPE));
ClientResponse response = resource.type(MediaType.MULTIPART_FORM_DATA).post(ClientResponse.class, form);
You could use streams.Try something like this on the client:
InputStream fileInStream = new FileInputStream(fileName);
String sContentDisposition = "attachment; filename=\"" + fileName.getName()+"\"";
WebResource fileResource = a_client.resource(a_sUrl);
ClientResponse response = fileResource.type(MediaType.APPLICATION_OCTET_STREAM)
.header("Content-Disposition", sContentDisposition)
.post(ClientResponse.class, fileInStream);
with resource like this on the server:
#PUT
#Consumes("application/octet-stream")
public Response putFile(#Context HttpServletRequest a_request,
#PathParam("fileId") long a_fileId,
InputStream a_fileInputStream) throws Throwable
{
// Do something with a_fileInputStream
// etc
In order for your code not to depend on the size of the uploaded file, you need:
Use streams
Define the chuck size of the jersey client. For example:
client.setChunkedEncodingSize(1024);
Server:
#POST
#Path("/upload/{attachmentName}")
#Consumes(MediaType.APPLICATION_OCTET_STREAM)
public void uploadAttachment(#PathParam("attachmentName") String attachmentName, InputStream attachmentInputStream) {
// do something with the input stream
}
Client:
...
client.setChunkedEncodingSize(1024);
WebResource rootResource = client.resource("your-server-base-url");
File file = new File("your-file-path");
InputStream fileInStream = new FileInputStream(file);
String contentDisposition = "attachment; filename=\"" + file.getName() + "\"";
ClientResponse response = rootResource.path("attachment").path("upload").path("your-file-name")
.type(MediaType.APPLICATION_OCTET_STREAM).header("Content-Disposition", contentDisposition)
.post(ClientResponse.class, fileInStream);
Below is the code for uploading a (potentially large) file with chunked transfer encoding (i.e. streams) using Jersey 2.11.
Maven:
<properties>
<jersey.version>2.11</jersey.version>
</properties>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-multipart</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependencies>
Java:
Client client = ClientBuilder.newClient(clientConfig);
client.property(ClientProperties.REQUEST_ENTITY_PROCESSING, "CHUNKED");
WebTarget target = client.target(SERVICE_URI);
InputStream fileInStream = new FileInputStream(inFile);
String contentDisposition = "attachment; filename=\"" + inFile.getName() + "\"";
System.out.println("sending: " + inFile.length() + " bytes...");
Response response = target
.request(MediaType.APPLICATION_OCTET_STREAM_TYPE)
.header("Content-Disposition", contentDisposition)
.header("Content-Length", (int) inFile.length())
.put(Entity.entity(fileInStream, MediaType.APPLICATION_OCTET_STREAM_TYPE));
System.out.println("Response status: " + response.getStatus());
In my case (Jersey 2.23.2) rschmidt13's solution gave this warning:
WARNING: Attempt to send restricted header(s) while the [sun.net.http.allowRestrictedHeaders] system property not set. Header(s) will possibly be ignored.
This can be solved adding the following line:
System.setProperty("sun.net.http.allowRestrictedHeaders", "true");
However I think a cleaner solution can be obtained using the StreamingOutput interface.
I post a complete example hoping it could be useful.
Client (File upload)
WebTarget target = ClientBuilder.newBuilder().build()
.property(ClientProperties.CHUNKED_ENCODING_SIZE, 1024)
.property(ClientProperties.REQUEST_ENTITY_PROCESSING, "CHUNKED")
.target("<your-url>");
StreamingOutput out = new StreamingOutput() {
#Override
public void write(OutputStream output) throws IOException,
WebApplicationException {
try (FileInputStream is = new FileInputStream(file)) {
int available;
while ((available = is.available()) > 0) {
// or use a buffer
output.write(is.read());
}
}
}
};
Response response = target.request().post(Entity.text(out));
Server
#Path("resourcename")
public class MyResource {
#Context
HttpServletRequest request;
#POST
#Path("thepath")
public Response upload() throws IOException, ServletException {
try (InputStream is = request.getInputStream()) {
// ...
}
}
}
If possible, can you split the file you send into smaller parts? This will reduce memory usage, but you need to change the code on both sides of the uploading/downloading code.
If you can't, then your heap space is too low, try increasing it with this JVM parameter. In your application server add/change the Xmx JVM options. For example
-Xmx1024m
to set Max Heap Space to 1Gb
#Consumes("multipart/form-data")
#Produces(MediaType.TEXT_PLAIN + ";charset=utf-8")
public String upload(MultipartFormDataInput input, #QueryParam("videoId") String videoId,
#Context HttpServletRequest a_request) {
String fileName = "";
for (InputPart inputPart : input.getParts()) {
try {
MultivaluedMap<String, String> header = inputPart.getHeaders();
fileName = getFileName(header);
// convert the uploaded file to inputstream
InputStream inputStream = inputPart.getBody(InputStream.class, null);
// write the inputStream to a FileOutputStream
OutputStream outputStream = new FileOutputStream(new File("/home/mh/Téléchargements/videoUpload.avi"));
int read = 0;
byte[] bytes = new byte[1024];
while ((read = inputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, read);
}
System.out.println("Done!");
} catch (IOException e) {
e.printStackTrace();
return "ko";
}
}

GWT: Sending PDF document from server to client

I have an RPC service and one of the method is generating a report using Pentaho Reporting Engine. Report is an PDF file. What I'd like to do, is when user request a report, the report is sent back to him and save dialog or sth pops up. I tried this inside my service method:
Resource res = manager.createDirectly(new URL(reportUrl), MasterReport.class);
MasterReport report = (MasterReport) res.getResource();
report.getParameterValues().put("journalName", "FooBar");
this.getThreadLocalResponse().setContentType("application/pdf");
PdfReportUtil.createPDF(report, this.getThreadLocalResponse().getOutputStream());
But it doesn't work. How it can be done?
I do it a little bit differently. I've got a separate servlet that I use to generate the PDF. On the client, do something like:
Cookies.setCookie(set what ever stuff PDF needs...);
Window.open(GWT.getModuleBaseURL() + "DownloadPDF", "", "");
The servlet, DownloadPDF looks something like this:
public class DownloadPDF extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) {
Cookie[] cookies = request.getCookies();
try {
// get cookies, generate PDF.
// If PDF is generated to to temp file, read it
byte[] bytes = getFile(name);
sendPDF(response, bytes, name);
} catch (Exception ex) {
// do something here
}
}
byte[] getFile(String filename) {
byte[] bytes = null;
try {
java.io.File file = new java.io.File(filename);
FileInputStream fis = new FileInputStream(file);
bytes = new byte[(int) file.length()];
fis.read(bytes);
} catch (Exception e) {
e.printStackTrace();
}
return bytes;
}
void sendPDF(HttpServletResponse response, byte[] bytes, String name) throws IOException {
ServletOutputStream stream = null;
stream = response.getOutputStream();
response.setContentType("application/pdf");
response.addHeader("Content-Type", "application/pdf");
response.addHeader("Content-Disposition", "inline; filename=" + name);
response.setContentLength((int) bytes.length);
stream.write(bytes);
stream.close();
}
}