Magic number for plain text file - magic-numbers

After googling, I found that Magic numbers can be used to identify the content type of a file.
In my program, I would like to validate the file content type on server side.
My client side code :
<form action="/Home/Index" method="post" enctype="multipart/form-data">
<input type="file" id="inputFile" value="" onchange="readFileContent(this)" />
<input type="submit" value="Submit" />
</form>
function readFileContent(input) {
if (input.files && input.files[0]) {
reader = new FileReader();
reader.onload = function (e) {
var xhr = new XMLHttpRequest();
xhr.open('POST', '/Home/CheckFileType', true);
xhr.setRequestHeader("Content-Type", "multipart/form-data");
xhr.setRequestHeader('X-File-Name', input.files[0].name);
xhr.setRequestHeader('X-File-Type', input.files[0].type);
xhr.setRequestHeader('X-File-Size', input.files[0].size);
xhr.send(input.files[0]);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
alert(xhr.responseText);
}
}
};
reader.readAsText(input.files[0]);
}
}
And this is my server side code :
[HttpPost]
public JsonResult CheckFileType()
{
string fileType = Request.Headers["X-File-Type"];
byte[] buffer = new byte[Request.InputStream.Length];
Request.InputStream.Read(buffer, 0, Convert.ToInt32(Request.InputStream.Length));
object result = new { status = "finished" };
return Json(result, JsonRequestBehavior.AllowGet);
}
What is the magic number for a plain-text or .txt file

Magic numbers in the context discussed here are often used to indicate what kind of data is in a binary file. A program that parses a file can look at the magic number and then know what to do with the rest of the file. For example, the magic number for all Java .class files (not source files) is 0xCAFEBABE. At runtime when the classloader loads a class it will look at those first 4 bytes and if they aren't 0xCAFEBABE, the class loader will not treat the file as a valid Java class file. If you were defining your own file type for some software you were writing or expected others to write, you could define your own magic number or numbers. When software created files of your type it would be that software's responsibility to write the appropriate magic number in the file. The software that reads the files could use that magic number to help decide what to do.
Magic numbers do not make sense for plain text files. If you write a magic number to the file, it would no longer be a plain text file. It would be a file that follows your format which might be a magic number followed by a bunch of plain text. If that is what you want, then do it. I don't know what your app is doing but conceivably that might make sense as long as you know the files will always be read and written by your own software (or other software which is compliant with your magic number expectations).
I hope that helps.

Related

Validating a text input to use only lower cases and numbers 0 to 9 when a link is clicked

I am making a simple web app that reads short URLs from a specific domain and then opens the short URL in the existing Internet browser. The functionality is already working but I am a bit confused on how to move forward in adding input validations to make the system more self service. I would like to validate a text input field which is not using a form. I want the text field to support only small case and numbers 0 to 9. I've found some solutions here in forum but I am not capable of fully integrating the offered solutions because most of them use forms and my programming skill is beginner's level. My input field uses the link anchor and looks like this:
<input type="text" id="keyword" placeholder="Small letters only" />
<a class="btn" href="http://mysite.com" id="domain"></a>
I need to add the following functions in my jquery script:
When the link is clicked, the script will check if the character string provided in "keyword" are lowercase and numbers only. if user inputs a character other than lowercase letters and numbers, alert message pops up "Invalid character detected. Try again".
If no input was provided when the link is clicked, alert message pops up "Provide an input." .
When the input is valid, the script below is run.
Thank you for your assistance.
$(function()
{
$('#domain').click( function()
{
window.location = $(this).attr('href') + '/' + $('#keyword').val();
return false;
}
});
});
You can use Regular Expressions for this validation.
$(function {
$('#domain').click( function() {
var val = $('#keyword').val();
if (val == '') { /* popup time */ }
var regexp = new RegExp("[a-z0-9]+");
if (regexp.match(val)) { /* Redirect */ }
else { /* invalid characters */ }
})
});

AJAX file upload in Play Framework 2.1 RC1 delivers an empty file

Scala/Play gurus out there.
I'm trying to upload a file using AJAX, in Play 2.1 (RC1). For the client part I'm using eldarion/bootstrap-ajax and everything seems to be fine, except that the uploaded file is empty.
The front-end snippet:
...
<form action="#routes.Campaigns.upload" method="post" class="form ajax replaceable" data-replace=".replaceable">
<input type="file" name="picture">
<p><input class="btn" type="submit"></p>
</form>
...
Note that I had to use the explicit <form> tag instead of the #form helper, due to the fact that the required css class (data-replace) contains a dash, and therefore can not be used as a Symbol. But anyway. The called action in the controller looks like this:
def upload = Action(parse.temporaryFile) {
request =>
Logger.info("Trying to upload a file")
val resultString = try {
val file = new File("/tmp/picture")
request.body.moveTo(file, true)
"file has been uploaded"
} catch {
case e: Exception => "an error has occurred while uploading the file"
}
val jsonResponse = Json.toJson(
Map("html" -> Json.toJson("<p>" + resultString + "</p>")
)
)
Ok(jsonResponse)
}
I'm aware that as my development goes forward the file name should be more intelligently set, but for the moment being, /tmp/picture is for me as good a name as any other one.
The JSON response gets generated (with the "file has been uploaded" message within), and is sent back to the browser as the payload of the 200 response. The JSON is received and correctly used to modify the page (in this case, merely removing the very uploading form).
But the file, although appearing in the right moment and in the right place, is always empty:
larsson:tmp bruno$ ls -l /tmp/picture
-rw-r--r-- 1 bruno staff 0 7 Jan 03:07 /tmp/picture
That's specially strange, in my opinion, because the uploading code which uses a traditional multipart/form-data form, with no AJAX whatsoever, and an Action with parse.multipartFormData as a parameter, instead of parse.temporaryFile, works finely.
Any help will be very appreciated. Thanks in advance.
I don't know bootstrap-ajax, anyway if it hasn't dedicated support for uploading files via AJAX (and I didn't find any info about that possibility in its readme file) it will NOT send files with AJAX.
Reason: In standard JavaScript uploading files with AJAX is not possible due the security limits and there are some techniques to workaround this, mainly using iFrames, however I can't see nothing similar in the code of bootstrap-ajax so probably you need to modify it or use other solution.
Solution: There are some AJAX file uploaders, which works good with HTML5 ie. jQuery File Upload, which offers ajax upload, multi-file uploads, drag file to the drop zone etc.
In general HTML5 supports file uploads better than earlier versions of HTML, so you can build uploader easily without need of using additional plugins, take a look to this topic. As you can see it delivers possibilities to validate some data BEFORE the upload and also offers progress bars.
I'm currently trying to implement something like this and I got a first version working. This is how I do it:
In my Controller I define a method for uploading files. In my case I use Action.async since I save stuff to my MongoDB with reactivemongo. I have removed that code so that it do not complicate this example.
What I do in this example is that I upload a csv file, save it to disk and then produce the first row back as a string to the user. In real life the method produces a list back so that user is able to choose which column represent what an so on.
I use mighty csv for csv parsing. GREAT LIB!
Application:
def upload = Action.async(parse.multipartFormData) {
implicit request =>
val result = uploadForm.bindFromRequest().fold(
errorForm => Future(BadRequest(views.html.index(errorForm))),
form => {
import java.io.File
request.body.file("csvFile").map {
csv =>
val path = current.configuration.getString("csv.job.new.file.path").getOrElse("")
val name = DateTime.now().getMillis + ".csv"
csv.ref.moveTo(new File(path + name))
val settings = CSVReaderSettings.Standard(linesToSkip = form.linesToSkip)
val rows: Iterator[Array[String]] = CSVReader(path + name)(settings)
val firstRow = rows.next()
val test = firstRow match {
case xs if xs.size == 0 || xs.size == 1 => xs.mkString
case xs if xs.size > 1 => xs.mkString(", ")
}
Future(Ok(test))
}.getOrElse(Future(BadRequest("ahadasda")))
}
)
result
}
routes:
POST /upload #controllers.Application.upload
I use # before the controllers because I use DI with guice for my service classes.
Since we will use javascript for uploading we need to define our jsRoutes:
jsRoutes:
def javascriptRoutes = Action {
implicit request =>
import routes.javascript._
Ok(
Routes.javascriptRouter("jsRoutes")(
Application.upload
)
).as("text/javascript")
}
Remember to import in your template where you want to use the routes:
<script type="text/javascript" src="#routes.Application.javascriptRoutes"></script>
<script src="#routes.Assets.at("javascripts/app.js")#Messages("js.version")" type="text/javascript" ></script>
In my view template I have a regular helper form. There is some css style stuff I do to
change the looks and feel of the upload button and file chooser. But the input fields
are there.
index.scala.html:
<div class="csvContainer">
#helper.form(action = routes.Application.upload, 'enctype -> "multipart/form-data", 'id -> "csvUpload") {
#Messages("upload.row.skip")
#inputText(uploadForm("linesToSkip"), 'class -> "hidden")
<div style="position:relative;">
<div id="csvFile" style="position:absolute;">
#Messages("upload.choose")
</div>
<input id="uploadFile" type="file" name="csvFile" style="opacity:0; z-index:1;" onchange="document.getElementById('csvFile').innerHTML = this.value;" />
</div>
<p>
<input type="submit" value="#Messages("upload.submit")">
</p>
}
</div>
In app.js is where the ajax magic happens, remember I have not implemented any validation or cool html5 stuff yet as the progressbar and other handlers, described in besiors link.
I use regular JQuery.
app.js:
$('#uploadFile').change(function(){
var name = $(this).val().split("\\");
console.log(name[2]);
$('#csvFile').text(name[2]);
});
$('#csvFile').click(function(){
$('#uploadFile').click();
});
$("#csvUpload").submit(function(e) {
e.preventDefault();
var formData = new FormData();
formData.append('csvFile', $( '#uploadFile' )[0].files[0]);
formData.append('linesToSkip', $( "#linesToSkip").val());
jsRoutes.controllers.Application.upload().ajax({
data: formData,
processData: false,
contentType: false,
cache: false,
type: 'POST',
success: function(data){
alert(data);
}
});
});
I have removed a lot of code to simplify this example and I hope that I have not forgotten anything. Hope this helps!

jquery - load all text files and display them

I have been using jQuery pretty long time, but I never learned AJAX, so here I come..
we have this code :
$('body').load('hello.txt');
Simple enough, now let's say I have multiple text files (I don't know their names) I want to load,
Can I do that ?
Maybe I need to loop all the text files and load them somehow ?
Thanks in Advance
Assuming you have text files in the server in a specific location you can do this:
HTML markup:
<div id="fileList">
here list of files will be loaded so that user can select which one to load
<div>
<div id="file-content">
content of selected file will be loaded here
<div>
JQuery part :
$.ajax({
url : "FileServer/GetFileNames", // this is just a url that is responsible to return files list
success : function(data){
//here a JSON data including filenames expected
$.each(data,function(i,item){
var $fileHolder = $("<div></div>");
$fileHolder.attr("filename",item.filename).click(function(){
$("#file-content").load($(this).attr("filename"));
}).html(item.filename).appendTo("#fileList");
});
}
});
JSON Structure expected
[
{
filename : "text1.txt"
},
{
filename : "text2.txt"
},
{
filename : "text3.txt"
}
]
implementing file listing in the server side is up to you.
Javascript does not have access to the local file system for obvious
security reasons. This is not possible.
Unless you are trying to loop through files on your server, in which
case you wouldn't want to use jQuery anyway but something like ASP.NET
or PHP or whatever framework you are using.
Foreach file in directory jQuery
UPDATE
Try this out
var files;
$.ajax({
url: "http://homepage/folder",
success: function (txt) {
files = txt.split('<A href="');
}
});
var fList = new Array();
$(files).each(function () {
if (this.indexOf('.txt') > -1) {
fList.push(this);
}
});
for (i = 0; i < fList.length; i++) {
fList[i] = fList[i].split('">')[0];
fList[i] = fList[i].replace('"');
}
for (i = 0; i < fList.length; i++) {
$('#idLoadHere').load(fList[i]);
}
Run FTP list command (there are various ways to do so, Web-Sockets is one..)
A simpler, more common ans secure-solution is a server-side listing of the files, and "cooking" the HTML (meaning- embedding the file-listing within it),
*you can use raw HTML or put it in var statement to be used by JavaScript (for example).
see following answer:
https://stackoverflow.com/a/30949072/257319

knockout.js and Firefox Save Passwords on login form

Firefox populates a form with my username/password. This is using knockout.js to bind the input but it won't update the values on this kind of populating. Am I missing something say on a page load? When it populates and the user hits submits, the values are blank.
(function (app, $, undefined) {
app.viewModel = app.viewModel || {};
app.login = {};
app.viewModel.login = {
userName: ko.observable(''),
password: ko.observable(''),
returnUrl: ''
};
app.viewModel.login.submit = function () {
sso.login(app.viewModel.login.userName(), app.viewModel.login.password(), app.viewModel.login.returnUrl);
};
app.login.init = function (returnUrl) {
app.viewModel.login.returnUrl = returnUrl;
ko.applyBindings(app.viewModel);
};
})(window.app = window.app || {}, jQuery);
The way that I have dealt with this in the past is to use a wrapper to the value binding that initializes the value from the element's current value.
It would look like (this one is simplified to only work with observables):
ko.bindingHandlers.valueWithInit = {
init: function(element, valueAccessor, allBindingsAccessor, context) {
var observable = valueAccessor();
var value = element.value;
observable(value);
ko.bindingHandlers.value.init(element, valueAccessor, allBindingsAccessor, context);
},
update: ko.bindingHandlers.value.update
};
So, you would use valueWithInit instead of value. You just need to make sure that ko.applyBindings is not called before the autocomplete has been able to do its job.
http://jsfiddle.net/rniemeyer/TeFAX/
I found the solution here not really satisfying. Although the approach is rather interesting, it fails when the user is choosing the account later and the browser does allow to use the stored credentials (e.g. if there are more than one credentials stored). It failed as well when you started typing in the password and deleted to get back to the original password (in Firefox at least).
Additionally, I did not really like the timeout to give the browser time - just not that nice.
My solution:
which isn't really one, but I thought I share nonetheless
Simple update our model manually before doing the login in the submit callback.
Using jQuery, something like self.password($("#password").val()) should do it.
Alternatively, using the existing bindings, triggering a change event seems to work as well - e.g. $("#password").change().
The Pros:
is only for credential fields, so probably a one time thing for your site
is simple and clean - one or two lines at the proper place
seems to always work reliably, no matter what browser, credential setup or usage pattern
The Cons:
breaks again the nice separation Knockout.js provides
is not a solution but rather a workaround
I will stick with that for now because I found it just reliable working. It would be nice to tell Knockout to reevaluate the bindings directly rather than storing the value back manually or triggering it via the change event. But I haven't found anything so far.
Just thinking a bit ahead - the same problem should arise when the browser auto-completes any form (e.g. like an address) - which means means some sort of general function doing the above would be nice (probably calling the change trigger on each input field of the form)
Edit:
Some quick code demonstrating the idea
The HTML:
<form id="myForm" data-bind="submit: login">
Email: <input type="text" data-bind="value: email" /><br/>
Password: <input type="password" data-bind="value: password" /><br/>
<button type="submit">Login</button>
</form>
And the Javascript:
function ViewModel() {
var self = this;
self.email = ko.observable("");
self.password = ko.observable("");
self.login = function() {
$("#myForm").find("input").change();
//Now the observables contain the recent data
alert(ko.mapping.toJSON(self));
};
}

use html5 multiple attribute to trigger multiple single uploads

Sorry for the confusing title.
I have a form-- form1 that has one file input ( with multiple attribute set so that user can select mutiple files). The form doesn't get submitted.
I have another form -- form2 that has a single file input . no mutiple attribute.
Now via javascript i would like to fetch each files from the fileinput from the previous form and then assign the file to the form2's input field and then do an ajax submit.
Once the ajax submit is complete I would like to do the same to 2nd file and then 3rd file and so on.
I don't want to use flash or java applet.
I am fully aware that IE doesn't support multiple attribute
opera can use invalid min max attribute to do the same.
My basic question would be how to fetch the files from the form1 input field and then assisgn it to form2's field ..
Is there a solution for this ?
or is my approach itself incorrect ?
What I want to achieve on UI side ?
The file gets uploaded and server does some processing and returns some data.
so what I want is user can select 10 files but as soon as 1st file is uploaded the output is received.
First : My idea is wrong.
We cannot assign a value via javascript to the input with type = file .
I thought of another idea using the XMLHttpRequest.
here is my code :
<form id="new_picture_form" method="post" enctype="multipart/form-data" action="some url" accept-charset="UTF-8">
<input id="original_input" class="file_hidden" type="file" onchange="handleFiles(this.files);" name="picture[image][]" multiple="multiple">
</form>
<form id="fileinfo" method="post" enctype="multipart/form-data" action="some url">
</form>
<script type="text/javascript">
function handleFiles(files)
{
for (var i = 0; i < files.length; i++) {
FileUpload(files[i])
}
}
function FileUpload(file) {
var data = new FormData(document.getElementById("fileinfo"));
var xhr = new XMLHttpRequest();
this.xhr = xhr;
data.append('some field',"that you want to pass as param ")
data.append('type',"picture")
data.append("picture[image]", file);
xhr.open("POST", "URL",true);
xhr.send(data);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
eval(xhr.responseText) // basically the result from server contains some script
}
}
}
</script>

Resources