Manage zip from http get response - javascript

I have this problem:
I need to download a zip file from a server, this zip contains .xod and .png.
I'm using Angular js, java spring, to overcome the cross domain problem, my htt.get angular call java spring controller and it make a true get call.
I have to download zip -> return this zip to angular, unzip it, extract file and save it inside IndexedDB.
this is my angular code:
var req = {
method: 'GET',
url: CONTEXT_PATH+"/services/data/"+meetingId,
headers: {
'Content-Type': undefined
}
}
$http(req).then(function(data){
console.log("rest call done!");
console.log(data);
});
this is java spring code:
#RequestMapping(value="/data/{meetingId}", method = RequestMethod.GET)
public Buffer getMeeting(#PathVariable(value="meetingId") String meetingId) {
byte[] file = new byte[2048];
Buffer buf =null;
try {
String url = getContentServer()+"/data?username="+getUsername()+"&password="+getPassword()+"&id="+meetingId;
logger.info("start Rest template");
RestTemplate templ = new RestTemplate();
file = templ.getForObject(url, byte[].class);
logger.info("PRE BUF");
buf = ByteBuffer.wrap(file);
logger.info("POST BUF");
} catch (Exception e) {
String msg = "Error retrieving meeting list";
logger.error(msg, e);
}
logger.info("file zip --> "+file.length);
logger.info("buf --> "+buf+" -- buf.array --> "+ buf.array());
return buf;
}
this is console.log:
Object {data: "UEsDBBQACAAIAA5IpkgAAAAAAAAAAAAAAAAJAAAAMTYwMzQucG…AcqwpAGxvZ28ucG5nUEsFBgAAAAAIAAgAuwEAAMa/KQAAAA==", status: 200, config: Object, statusText: "OK"}
I don't know I can decode this buffer and extract files inside it client side.
Thanks.

I searched a little to try to find a solution. My doubt is: The data you save in the dataBase is blob type or it's ok if you just save the path of the file?
Because I think is better to do that in server side. I love work in server side and the less I can in client. So searching for a java class which controls zip files I found this:
https://docs.oracle.com/javase/7/docs/api/java/util/zip/ZipFile.html
And I wrote (without testing so it might be modified a little) this code server side:
Enumeration<E> listEntries = zip.entries()
for (listEntries; listEntries.hasMoreElements();) {
ZipEntry item = getEntry(listEntries.nextElement().toString())
InputStream fileStream = getInputStream(item)
}
With that InputStream you can return the list of the name of the files uncompressed or a hashmap, arraylist or just list of the streams and/or its fileName or whatever you need.
List<String> fileNames
or
HashMap<String, Object> filesStreams
for example.
Just I'm not very familiar with spring. It is posible to return a List or you have to return a Buffer? If you have to return a buffer tell me and I'll find another solution. ;)

Related

Upload password protected file to server

I am running a Python HTTP server that host a captive portal. Basically I'm trying to upload a password protected file to the server.
Right now I am able to upload files to the server with JavaScript and FileReader. This is how I do it:
var file_cli_cert = document.getElementById(id="exa_cli_cert").files[0];
const xmlhttp1 = new XMLHttpRequest();
let name = file_cert.name;
let reader = new FileReader();
reader.readAsText(file_cert);
xmlhttp1.open("POST", '/load/cert');
reader.onload = function(){
xmlhttp1.send(name +"&CERT="+reader.result);
With non-password protected files this works well.
For password protected files my idea is to get the file and the password to access to the data. The problem is that I don't know how to access to password protected files in JS and i think it's not possible. So right now i am wondering how to send the file and the password to the server and access the file data there.
If I send the file object with XMLHttpRequest.send(), on the server side I get the object in string format.
To read the POST message, in the server side, I do:
ctype, pdict = cgi.parse_header(self.headers['content-type'])
content_len = int(self.headers.get('Content-length'))
post_body = self.rfile.read(content_len) #read credentials
self.send_response(201)
self.end_headers()
if self.path.endswith('/load/cert'): #if user loads a certificate
post_body = post_body.decode()
post_body = post_body.split("&CERT=") #split name and file content
name_cert = post_body[0]
file_content = post_body[1]
f = open("./certs/"+name_cert, "w")
f.write(file_content)
f.close()
I'm a newbie at this and I have been looking for a solution for hours. Any help will be appreciated.
No python expert but reading a encrypted file as Text with FileReader could be problematic as it could lead to some data loss when encoding it as text. You should rather be reading it as binary using reader.readAsArrayBuffer()
But there is no need to read the content of the file into memory and allocate memory, just upload the blob/file directly to the server and it will take care of sending the data from the disc to the network without touching the main javascript thread without any text transformation.
const [ file ] = document.querySelector('#exa_cli_cert').files
fetch('/load/cert', {
method: 'POST',
body: file,
headers: {
'x-file-name': file.name
}
})
.then(r => r.arrayBuffer())

How to download gzip file using AngularJS from REST API response? It works with REST API

Here is my problem -
The response data is a binary representation of a tar.gz file.
These data are generated from the following Java code (A REST Endpoint logic ) from the server:
public ResponseEntity<InputStreamResource> downloadLogs(String nodeName, String storagePoolName){
ResponseEntity<InputStreamResource> responseEntity = null;
File initialFile2 = new File("C:\\Users\\Admin\\Downloads\\logs\\pz_logs_temp.tar.gz");
InputStream targetStream = FileUtils.openInputStream(initialFile2);
//Preparing Response
InputStreamResource resource = new InputStreamResource(targetStream);
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.add(HttpHeaders.CONTENT_DISPOSITION, "attachment");
responseHeaders.add("filename", String.format("%s.tar.gz",nodeName));
responseEntity = ResponseEntity.ok()
.headers(responseHeaders)
.contentType(MediaType.APPLICATION_OCTET_STREAM)
.body(resource);
return responseEntity;
}
This is the picture on the Java Script side:
This is how the data looks in console:
This is a response headers
The code generates a tar.gz file and downloads it.
However, the generated file is not a valid tar.gz file. I could not open it.
I think I am missing something on the Java Script side.

Upload Image to DB using Spring Boot and React : Error parsing HTTP request header

Here I m implementing the image upload to database using Spring Boot and React. I have encountered Error parsing HTTP request header error.
Error:
Error parsing HTTP request header
java.lang.IllegalArgumentException: Invalid character found in method
name
[0x160x030x010x020x000x010x000x010xfc0x030x030x1f0xc4T0x880xe1T0x070x00[Ua0xf40x8b0x0a0x900x8c<}0xe20xf70x080xa90xdaO0xb3U0xc7g0xaf0xfb30xa8].
HTTP method names must be tokens
React
doit=(e)=>{
e.preventDefault();
let imagefile = document.querySelector('#input');
let formData = new FormData();
formData.append("image", imagefile.files[0]);
return axios.post('https://localhost:8080/fileupload', "image",formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
});
}
<form encType='multipart/form-data'>
<input id="input" type='file' accept="image/*"/>
<button onClick={this.doit} type='submit'>Submit</button>
</form>
Spring Boot
#PostMapping("/fileupload",consumes = MediaType.MULTIPART_FORM_DATA_VALUE))
public String fileUpload(#RequestParam("name") String name, #RequestParam MultipartFile file) {
try {
byte[] image = file.getBytes();
MyModel model = new MyModel(name, image);
int saveImage = myService.saveImage(model);
if (saveImage == 1) {
return "success";
} else {
return "error";
}
} catch (Exception e) {
return "error";
}
}
So actually this problem has to do with just the way you are sending over the file. Images and videos are not the same as json data. They are long strings of numbers or encoded text that create visual masterpieces on the screen. I don't understand all of it yet basically what you need to do is get the file location. like if use a file picker api and it lets you choose something to upload, and you can store that info in a variable that is what 'file' is
then use javascript's built in fetch method.
const genFunction = async (file) =>{
const response = await fetch(file)
const blob = await response.blob();
// then you need to send that blob to the server
try {
const result = await requestToServer(
//configuration stuff
contentType:'image/jpg' // specify that you are sending a image
// or whatever file type somehow
)
console.log(request) } catch (e) { ... } }
lol they did not teach me how to do this at coding bootcamp or whatever, I didnt realize there are more types and things to do for so long. I figured out how to make it work with Amplify storage, and react native if anyone needs that just ask a question and i'll provide a solution for that.
this guy talks allot about best method to convert stuff to the format you actually need it to be. and the solution that i provided is the slowest, but easy to understand.
http://eugeneware.com/software-development/converting-base64-datauri-strings-into-blobs-or-typed-array
Also you should checkout out:
https://docs.mongodb.com/manual/core/gridfs/
Store images in a MongoDB database //basically the same question
https://javabeat.net/mongodb-gridfs-tutorial/
I have made this mistake before I didn't know how to solve it, my help told me to start storing images on AWS s3 which is not what I was asking. I hope you figure it out.

Import excel file using angular and convert that excel sheet data in array using REST API in .net core [duplicate]

I am trying to create an API that will accept the representation of an Excel file from the client. I wish to return a List<List<string>> as JSON array after processing the first sheet. However, I cannot write the file to disk, and all processing must happen in-memory. What are the ways in which this can be achieved?
I've tried referring to various solutions on the internet but all of them involve writing the file to disk and then using that file for further processing. I'm open to solutions that involve
Accepting base-64 representation of the file from the POST request body
Accepting file as part of multipart/form-data request
Any other standard request formats that accept files
The only condition is that the API should return a JSON array representation of the spreadsheet.
Here I am sending a file as part of multipart/form-data request to the API which written in .NET core.
which support .xlsx , .xls and .csv format
use ExcelDataReader and ExcelDataReader.DataSet NuGet packages for reading excel and convert in the dataset.
Here one problem i faced and solution in .NET core.
By default, ExcelDataReader throws a NotSupportedException "No data is available for encoding 1252." on .NET Core.
To fix, add a dependency to the package System.Text.Encoding.CodePages and then add code to register the code page in starting of API
System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
This is required to parse strings in binary BIFF2-5 Excel documents encoded with DOS-era code pages. These encodings are registered by default in the full .NET Framework, but not on .NET Core.
public ActionResult ExcelOrCsvToArray()
{
if (Request.Form.Files.Count > 0)
{
IFormFile file = Request.Form.Files[0];
string fileName = file.FileName;
string fileContentType = file.ContentType;
System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
Stream stream = file.OpenReadStream();
try
{
if (fileName.EndsWith(".csv"))
{
using (var reader = ExcelReaderFactory.CreateCsvReader(stream))
{
var result = SetAsDataSet(reader);
DataTable table = result.Tables[0];
return new OkObjectResult(table);
}
}
else
{
using (var reader = ExcelReaderFactory.CreateReader(stream))
{
var result = SetAsDataSet(reader);
DataTable table = result.Tables[0];
return new OkObjectResult(table);
}
}
}
catch (Exception e)
{
return new BadRequestObjectResult(e);
}
}
else
{
return new BadRequestResult();
}
}
private DataSet SetAsDataSet(IExcelDataReader reader)
{
var result = reader.AsDataSet(new ExcelDataSetConfiguration()
{
ConfigureDataTable = (_) => new ExcelDataTableConfiguration()
{
UseHeaderRow = true,
}
});
return result;
}

Save Word document (.docx) using Office.js API to back-end server

I'm having some troubles saving a byte array (fetched from a Microsoft Office's task pane using Office.js) to a Word document file (on the server side). This is what I'm doing:
I'm getting the content of the Word document using this library
JavaScript
$('#push').click(function () {
$.when(OffQuery.getContent({ sliceSize: 1000000 }, function (j, data, result, file, opt) {
// ...nothing interesting here
})).then(function (finalByteArray, file, opt) {
// (1) this line is changed...see the answer
var fileContent = Base64.encode(finalByteArray); //encode the byte array into base64 string.
$.ajax({
url: '/webcontext/api/v1/documents',
// (2) missing setting (see the answer)
data: fileContent,
type: 'POST'
}).then(function () {
// updateStatus('Done sending contents into server...');
});
}).progress(function(j, chunkOfData, result, file, opt){
// ...nothing interesting here
});
Then in a Spring controller I'm doing this:
Java / Spring
#RequestMapping(method = RequestMethod.POST) // As OOXML
public void create(#RequestBody String fileContent, HttpServletRequest request) throws Exception { // TODO
LOGGER.debug("{} {}", request.getMethod(), request.getRequestURI());
//LOGGER.debug("fileContent: {}", fileContent);
try {
val base64 = Base64.decodeBase64(fileContent); // From Apache Commons Codecs
FileUtils.writeByteArrayToFile(new File("assets/tests/output/some_file.docx"), base64);
} catch (IOException e) {
LOGGER.error("Crash! Something went wrong here while trying to save that...this is why: ", e);
}
}
...but the file is getting saved as-is; basically is saving the byte array into the file as a text document.
Am I missing something? Do you have any clues? Somebody that has worked with Office.js, Task Panes and things like that?
Thanks in advance...
UPDATE 1
Turns out that the finalByteArray is getting converted into a Base64 string (fileContent), but when I try to do the reverse operation in Java is not working...if somebody has done that before, please let me know. I have tried:
The sample in this Mozilla page
Unibabel
base64-js
...on the Java side (to decode the Base64 String into a byte array):
The default Base64 encoder/decoder
The Base64 Apache codec
Actually, I found the error. It was on the client side. There is a function included in the Office.js SDK that does the conversion between the byte array into a Base64 string ― although I'm not sure if it's shipped with all versions, I'm using Office.js SDK 1.1.
So I changed the conversion to:
var fileContent = OSF.OUtil.encodeBase64(finalByteArray);
...and in the AJAX call I added the contentType setting:
$.ajax({
//...
contentType: 'application/octet-stream',
// ...
type: 'POST'
}).finish(function () {
// ...
});
By setting the content type correctly I was able to post "the right content" to the server.
Even if I do the correct Base64 conversion without setting the correct
Content Type, the received data in the Spring controller is
different (larger in this case) than the one reported in the client
side.
I hope this may help someone else in the future. The examples in the Microsoft Web are quite clear, but for some reason "there is always something different between environments".
There is no obvious error in your code, except (as commented) that I don't know why you cut off the last character from your code.
Why don't you use a javascript debugger like Firebug and a remote Java debugger for your Webserver to check every step in your processing and control the content of the various variables (Javascript fileContent, Java fileContent, Java base64) to find out where the error creeps in.

Categories