Xpages download multiple attachments from viewPanel? - download

On an Xpage, I am trying to download selected documents from viewpanel. I am try to use Knut Herrmann's modified script of Naveen Maurya's XSnippet.
I get the following error:
[16A4:000A-0BF8] 08/01/2018 09:18:14 AM HTTP JVM: TEST 01
[16A4:000A-0BF8] 08/01/2018 09:18:14 AM HTTP JVM: A42
[16A4:000A-0BF8] 08/01/2018 09:18:14 AM HTTP JVM: TEST 02
[16A4:000A-0BF8] 08/01/2018 09:18:14 AM HTTP JVM: TEST 03
[16A4:000A-0BF8] 08/01/2018 09:18:14 AM HTTP JVM: com.ibm.xsp.exception.EvaluationExceptionEx: Error while executing JavaScript action expression
[16A4:000A-0BF8] 08/01/2018 09:18:14 AM HTTP JVM: com.ibm.xsp.webapp.FacesServlet$ExtendedServletException: java.lang.IllegalStateException: Can't get a Writer while an OutputStream is already in use
[16A4:000A-0BF8] 08/01/2018 09:18:14 AM HTTP JVM: CLFAD0134E: Exception processing XPage request. For more detailed information, please consult error-log-0.xml located in e:/IBM/Domino/data/domino/workspace/logs
code:
var selectedIds = sessionScope.selectedIds;
print("TEST 01");
for(i=0; i < selectedIds.length; i++) {
print(selectedIds[i]);
var doc:NotesDocument = database.getDocumentByID(selectedIds[i]);
print("TEST 02");
var attachments:java.util.Vector = session.evaluate("#AttachmentNames", doc);
print("TEST 03");
///////////new arrangement
// If there are no attachments then STOP!
if (attachments == null || (attachments.size() == 1 && attachments.get(0).toString().trim().equals(""))) {
print("TEST 04");
this.setRendered(true); // Show the XPage
return;
}
var externalContext:javax.faces.context.ExternalContext = facesContext.getExternalContext();
var response:javax.servlet.http.HttpServletResponse = externalContext.getResponse();
// Get the name of the zip file to be shown in download dialog box
var zipFileName = context.getUrl().getParameter("zipFileName");
if (zipFileName == null || zipFileName.equals("")) {
zipFileName = "AllAttachments.zip";
} else if (!zipFileName.toLowerCase().endsWith(".zip")) {
zipFileName = zipFileName + ".zip";
}
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", -1);
response.setContentType("application/zip");
response.setHeader("Content-Disposition", "attachment; filename=" + zipFileName);
var outStream:java.io.OutputStream = response.getOutputStream();
var zipOutStream:java.util.zip.ZipOutputStream = new java.util.zip.ZipOutputStream(outStream);
var embeddedObj:NotesEmbeddedObject = null;
var bufferInStream:java.io.BufferedInputStream = null;
//////////end new arrangement
// Loop through all the attachments
for (var i = 0; i < attachments.size(); i++) {
embeddedObj = downloadDocument.getAttachment(attachments.get(i).toString());
if (embeddedObj != null) {
bufferInStream = new java.io.BufferedInputStream(embeddedObj.getInputStream());
var bufferLength = bufferInStream.available();
var data = new byte[bufferLength];
bufferInStream.read(data, 0, bufferLength); // Read the attachment data
var entry:java.util.zip.ZipEntry = new java.util.zip.ZipEntry(embeddedObj.getName());
zipOutStream.putNextEntry(entry);
zipOutStream.write(data); // Write attachment into Zip
bufferInStream.close();
embeddedObj.recycle();
}
}
}
downloadDocument.recycle();
zipOutStream.flush();
zipOutStream.close();
outStream.flush();
outStream.close();
facesContext.responseComplete();

Related

PostAsync HttpRequestException: Cannot decode raw data

I'm trying to make a function to upload a file (pdf, docx, xls) to an http API. I've tried with Postman and it worked fine. But when I try from the application, is not working.
private async Task UploadFile()
{
String fileguid = this.noteModel.Fileguid.ToString();
try
{
var file = await CrossFilePicker.Current.PickFile();
if (file == null)
return;
string fileName = file.FileName;
string url = App.apiServer + "web/Token13/" + App.token + "/" + fileguid;
var content = new MultipartFormDataContent();
content.Headers.ContentType.MediaType = "multipart/form-data";
content.Add(new StreamContent(file.GetStream()), "file", fileName);
var httpClient = new HttpClient();
var response = await httpClient.PostAsync(url, content);
String status = response.StatusCode.ToString();
}
catch (Exception ex)
{
System.Console.WriteLine("Exception choosing file: " + ex.ToString());
}
}
I have the following error at line 'var response = await httpClient.PostAsync(url, content);':
2021-02-12 20:03:58.805 Project.iOS[2202:520692] Exception choosing file: System.Net.Http.HttpRequestException: cannot decode raw data --->
Foundation.NSErrorException: Error Domain=NSURLErrorDomain Code=-1015 "cannot decode raw data"
UserInfo={NSLocalizedDescription=cannot decode raw data,
NSErrorFailingURLStringKey=http://ip/appservertest/web/Token13/id,
NSErrorFailingURLKey=http://ip/appservertest/web/Token13/id,
_NSURLErrorRelatedURLSessionTaskErrorKey=(
"LocalDataTask <FD8D1034-CF42-41C8-A214-BE4D87D1D15D>.<1>"
), _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <FD8D1034-CF42-41C8-A214-BE4D87D1D15D>.<1>, NSUnderlyingError=0x282880000 {Error Domain=kCFErrorDomainCFNetwork Code=-1015 "(null)" UserInfo={NSErrorPeerAddressKey=<CFData 0x2805e64e0 [0x1f6084660]>{length = 16, capacity = 16, bytes = 0x100200505991f6e00
000000000000000}}}}
--- End of inner exception stack trace ---
at System.Net.Http.NSUrlSessionHandler.SendAsync (System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) [0x001d4] in /Library/Frameworks/Xamarin.iOS.framework/Versions/14.2.0.12/src/Xamarin.iOS/Foundation/NSUrlSessionHandler.cs:527
at System.Net.Http.HttpClient.FinishSendAsyncBuffered (System.Threading.Tasks.Task`1[TResult] sendTask, System.Net.Http.HttpRequestMessage request, System.Threading.CancellationTokenSource cts, System.Boolean disposeCts) [0x0017e] in /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/src/Xamarin.iOS/external/corefx/src/System.Net.Http/src/System/Net/Http/HttpClient.cs:506
at Project.Views.NotesEdit.UploadFile () [0x0018f] in C:\Repository\Project\Project\Views\NotesEdit.xaml.cs:268
Could you please give me a hint, why is not working?
Thank you in advance!
It seems like you have not completed your header with the MediaTypeHeaderValue. This works for me:
var content = new StreamContent(stream);
content.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
FileName = imageName,
Name = imageName
};
content.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
var multipartContent = new MultipartFormDataContent();
multipartContent.Add(content);
var result = await client.PostAsync(url, multipartContent.Add);

Response status code does not indicate success: '400' ('Bad request')

i want to POST data to API in my android xamarin app using refit i've tested the API at Postman and it's working fine but at android app i'm getting exception Bad request.
Here is my android code i added the interface and the model i don't know what is the problem .
public interface RequestAPI
{
[Post("/request")]
Task<create_request> submit([Body] create_request request);
}
requestAPI= RestService.For<RequestAPI>("http://courier-magconsulting.azurewebsites.net/api");
button.Click += async delegate
{
try
{
create_request request = new create_request();
request.PickUpPhone = "7664554";
request.DownPayment = 89;
request.DeliveryFees = 56.8;
request.Note = "i need a help!";
request.RequestID = 88; // replace the value yourself
request.DekiveryLocationLatitude = 2323;
request.DeliveryLocationLongitude = 232;
request.PickUpLocationLatitude = 898;
request.PickUpLocationLongitude = 1123;
BroadcastType type = new BroadcastType();
type.Name = "All";
type.ID = 60; // replace the value yourself
request.BroadcastType = type;
Cargosize size = new Cargosize();
size.Name = "Small";
size.ID = 1; // replace the value yourself
request.Cargosize = size;
Cargoweight weight = new Cargoweight();
weight.Name = "Large";
weight.ID = 2; // replace the value yourself
request.CargoWeight = weight;
Sender sender_ = new Sender();
sender_.Name = "Ahmad";
sender_.SenderID = 1; // replace the value yourself
sender_.Phone = "8788";
sender_.SocialID = "8787";
sender_.RatingAvg = 5;
SenderStatus status = new SenderStatus();
status.ID = 1;
status.Name = "Active";
sender_.Senderstatus = status;
request.Sender = sender_;
create_request result = await requestAPI.submit(request);
Toast.MakeText(this, "Request created", ToastLength.Long).Show();
}
catch(Exception ex)
{
Toast.MakeText(this, ex.Message, ToastLength.Long).Show();
}
};

Custom HTTPRequestHandler for public file upload

I'm trying to add a HTTPRequestHandler for a public file upload service to wakanda server. Anybody should be able to POST a file to this service without logging in. Unfortunately I get a "403 Forbidden" error on all POST requests made to the HTTPRequestHandler? GET requests work fine but do not not help much in this case ;-)
The intention is to receive the file, process it, and send it back to the client.
Added my request handler as follows:
application.addHttpRequestHandler('^/fileUpload$', './backend/httpRequestHandler/file-upload.js', 'fileUpload');
Any help on how to solve this problem would be much appreciated.
Finally got it to work myself with cURL. Looks like there was some issue with my Postman setup.
cURL command:
curl --form "fileupload=#test.xml" http://localhost:8081/fileUpload
HTTPRequestHandler:
/**
* file upload handler
* #param request {HTTPRequest} http request
* #param response {HTTPResponse} http response
*/
function fileUpload(request, response) {
try {
var counter = 1;
var nameTemp;
var files = [];
var uploadFolder = Folder('/PROJECT/database/data/tmp/');
var result = [];
var newName;
var myBinaryStream;
// create upload folder if not existing
if (!uploadFolder.exists) {
uploadFolder.create();
}
// create file instances
for (var i = 0; i < request.parts.length; i++) {
files.push(new File(uploadFolder.path + request.parts[i].fileName.replace(/\s/g, '_')));
// create result object
result[i] = {};
result[i].name = request.parts[i].fileName;
result[i].type = request.parts[i].mediaType;
result[i].size = request.parts[i].size;
}
// write file content
for (var i = 0; i < files.length; i++) {
counter = 1;
if (!files[i].exists) {
myBinaryStream = BinaryStream(files[i], 'Write');
myBinaryStream.putBlob(request.parts[i].asBlob);
myBinaryStream.close();
} else {
while (files[i].exists) {
nameTemp = files[i].name.replace(/\s/g, '_');
files[i] = new File(uploadFolder.path + files[i].nameNoExt.replace(/\s/g, '_') + counter + '.' + files[i].extension);
newName = files[i].name;
if (files[i].exists) {
files[i] = new File(uploadFolder.path + nameTemp);
}
counter++;
}
myBinaryStream = BinaryStream(files[i], 'Write');
myBinaryStream.putBlob(request.parts[i].asBlob);
myBinaryStream.close();
result[i].name = newName;
}
}
result = JSON.stringify(result);
// add response header
response.contentType = 'application/json';
return result;
} catch (e) {
console.log(e.stack);
return e;
}
}

Ajax , xhr.responseXML.getElementsByTagName() don't worked on chrome and IE but worked on firefox

I'm a ajax beginner. I'm trying to write a simple search suggestion. When I use firefox test It worked, but when I use chrome I got that: Uncaught TypeError: Cannot read property 'getElementsByTagName' of null
I wrote this on the callback function
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
var data = xhr.responseXML;
var x = data.getElementsByTagName("suggestion");
var div = document.getElementById("suggest")
div.innerHTML = "";
showSuggest();
for (var i = 0; i < x.length; i++) {
var result= x[i].firstChild.nodeValue;
div.innerHTML += "<div id='sResult' onmouseover='over(this)' onmouseout='out(this)' onclick='replace(this)' >"
+ result+ "</div>";
}
}
}
and this on Servlet doGet method:
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("test/xml;charset=UTF-8");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Pragma", "no-cache");
String keyword = request.getParameter("keyword");
//get suggestion from db
List<KeyWord> kw = SearchService.suggest(keyword);
PrintWriter pw = response.getWriter();
pw.println("<?xml version='1.0' encoding='UTF-8'?>");
pw.write("<suggestions>");
for(KeyWord k:kw){
pw.write("<suggestion>");
pw.write(k.getContent());
pw.write("</suggestion>");
}
pw.write("</suggestions>");
pw.flush();
pw.close();
}
If response.setContentType("test/xml;charset=UTF-8"); is not a typo in your post then correct it to say response.setContentType("text/xml;charset=UTF-8"); and hopefully IE and Chrome populate responseXML.
Have you tried this
var x = data.documentElement.getElementsByTagName("suggestion");
instead of
var x = data.getElementsByTagName("suggestion");
?

How to modify http response in Firefox extension

Hey i have been able to write an nsIStreamListener listener to listen on responses and get the response text following tutorials at nsitraceablechannel-intercept-http-traffic .But i am unable to modify the response sent to browser.Actually if i return the reponse and sent back to chain it reflects in firebug but not in browser.
What i am guessing is we will have to replace default listener rather than listening in the chain.I cant get any docs anywhere which explains how to do this.
Could anyone give me some insight into this.This is mainly for education purposes.
Thanks in advance
Edit : As of now i have arrived at a little solutions i am able to do this
var old;
function TracingListener() {}
TracingListener.prototype = {
originalListener: null,
receivedData: null, //will be an array for incoming data.
//For the listener this is step 1.
onStartRequest: function (request, context) {
this.receivedData = []; //initialize the array
//Pass on the onStartRequest call to the next listener in the chain -- VERY IMPORTANT
//old.onStartRequest(request, context);
},
//This is step 2. This gets called every time additional data is available
onDataAvailable: function (request, context, inputStream, offset, count) {
var binaryInputStream = CCIN("#mozilla.org/binaryinputstream;1",
"nsIBinaryInputStream");
binaryInputStream.setInputStream(inputStream);
var storageStream = CCIN("#mozilla.org/storagestream;1",
"nsIStorageStream");
//8192 is the segment size in bytes, count is the maximum size of the stream in bytes
storageStream.init(8192, count, null);
var binaryOutputStream = CCIN("#mozilla.org/binaryoutputstream;1",
"nsIBinaryOutputStream");
binaryOutputStream.setOutputStream(storageStream.getOutputStream(0));
// Copy received data as they come.
var data = binaryInputStream.readBytes(count);
this.receivedData.push(data);
binaryOutputStream.writeBytes(data, count);
//Pass it on down the chain
//old.onDataAvailable(request, context,storageStream.newInputStream(0), offset, count);
},
onStopRequest: function (request, context, statusCode) {
try {
//QueryInterface into HttpChannel to access originalURI and requestMethod properties
request.QueryInterface(Ci.nsIHttpChannel);
//Combine the response into a single string
var responseSource = this.receivedData.join('');
//edit data as needed
responseSource = "test";
console.log(responseSource);
} catch (e) {
//standard function to dump a formatted version of the error to console
dumpError(e);
}
var stream = Cc["#mozilla.org/io/string-input-stream;1"]
.createInstance(Ci.nsIStringInputStream);
stream.setData(responseSource, -1);
//Pass it to the original listener
//old.originalListener=null;
old.onStartRequest(channel, context);
old.onDataAvailable(channel, context, stream, 0, stream.available());
old.onStopRequest(channel, context, statusCode);
},
QueryInterface: function (aIID) {
if (aIID.equals(Ci.nsIStreamListener) ||
aIID.equals(Ci.nsISupports)) {
return this;
}
throw components.results.NS_NOINTERFACE;
},
readPostTextFromRequest: function (request, context) {
try {
var is = request.QueryInterface(Ci.nsIUploadChannel).uploadStream;
if (is) {
var ss = is.QueryInterface(Ci.nsISeekableStream);
var prevOffset;
if (ss) {
prevOffset = ss.tell();
ss.seek(Ci.nsISeekableStream.NS_SEEK_SET, 0);
}
// Read data from the stream..
var charset = "UTF-8";
var text = this.readFromStream(is, charset, true);
if (ss && prevOffset == 0)
ss.seek(Ci.nsISeekableStream.NS_SEEK_SET, 0);
return text;
} else {
dump("Failed to Query Interface for upload stream.\n");
}
} catch (exc) {
dumpError(exc);
}
return null;
},
readFromStream: function (stream, charset, noClose) {
var sis = CCSV("#mozilla.org/binaryinputstream;1",
"nsIBinaryInputStream");
sis.setInputStream(stream);
var segments = [];
for (var count = stream.available(); count; count = stream.available())
segments.push(sis.readBytes(count));
if (!noClose)
sis.close();
var text = segments.join("");
return text;
}
}
httpRequestObserver = {
observe: function (request, aTopic, aData) {
if (typeof Cc == "undefined") {
var Cc = components.classes;
}
if (typeof Ci == "undefined") {
var Ci = components.interfaces;
}
if (aTopic == "http-on-examine-response") {
request.QueryInterface(Ci.nsIHttpChannel);
console.log(request.statusCode);
var newListener = new TracingListener();
request.QueryInterface(Ci.nsITraceableChannel);
channel = request;
//newListener.originalListener
//add new listener as default and save old one
old = request.setNewListener(newListener);
old.originalListener = null;
var threadManager = Cc["#mozilla.org/thread-manager;1"]
.getService(Ci.nsIThreadManager);
threadManager.currentThread.dispatch(newListener, Ci.nsIEventTarget.DISPATCH_NORMAL);
}
},
QueryInterface: function (aIID) {
if (typeof Cc == "undefined") {
var Cc = components.classes;
}
if (typeof Ci == "undefined") {
var Ci = components.interfaces;
}
if (aIID.equals(Ci.nsIObserver) ||
aIID.equals(Ci.nsISupports)) {
return this;
}
throw components.results.NS_NOINTERFACE;
},
};
var observerService = Cc["#mozilla.org/observer-service;1"]
.getService(Ci.nsIObserverService);
observerService.addObserver(httpRequestObserver,
"http-on-examine-response", false);
This example works for me on Firefox 34 (current nightly): https://github.com/Noitidart/demo-nsITraceableChannel
I downloaded the xpi, edited bootstrap.js to modify the stream:
132 // Copy received data as they come.
133 var data = binaryInputStream.readBytes(count);
134 data = data.replace(/GitHub/g, "TEST");
135 this.receivedData.push(data);
installed the XPI then reloaded the github page. It read "TEST" in the footer.
The version of code you posted doesn't actually pass the results back to the old listener, so that's the first thing that ought to be changed.
It also may have interacted with Firebug or another extension badly. It's a good idea to try reproducing the problem in a clean profile (with only your extension installed).

Resources