How do I upload a file, from a browser, using the Lua programming language?
I'm using the Orbit web framework
This sample comes straight from the orbit sample pages/test.op.
<form method="POST" enctype="multipart/form-data" action="test.op">
<input type="file" name="file">
<input type="submit" value="Upload">
</form>
$lua{[[
local f = web.input.file
upload = {}
if f then
local name = f.name
local bytes = f.contents
local dest = io.open(web.real_path .. "/" .. name, "wb")
if dest then
dest:write(bytes)
dest:close()
upload[1] = name
end
end
]]}
You can easily adapt this to a normal orbit post handler. You can also take a look at how I used it in my library project, but it's way more complicated than your typical usage I guess.
Related
This question already has answers here:
About Karate UI Test Automation, How can I upload files when I use karate-chrome?
(2 answers)
Closed 1 year ago.
Related the issue: Can upload / download files at Karate Driver?, Could you please help me to create the karate Ui code for upload excel PDF in this structure:
<div class="col-sm-6">
<div class="form-group shiny-input-container">
<label>Faça o upload do seu arquivo</label>
<div class="input-group">
<label class="input-group-btn">
<span class="btn btn-default btn-file">
Browse...
<input id="file_input" name="file_input" type="file" style="display: none;" data-shinyjs-resettable-id="file_input" data-shinyjs-resettable-type="File" data-shinyjs-resettable-value="" class="shinyjs-resettable shiny-bound-input">
</span>
</label>
<input type="text" class="form-control" placeholder="No file selected" readonly="readonly">
</div>
<div id="file_input_progress" class="progress progress-striped active shiny-file-input-progress">
<div class="progress-bar"></div>
</div>
</div>
</div>
I tried to use this source code below without success:
* def uri = 'http://the-internet.herokuapp.com/upload'
* def uploadSelector = '#file-upload'
* def submitSelector = '#file-submit'
# this function is for getting the full path of a file that is necessary to use with selenium sendKeys method when
# a file. I agree with the fact that every folder in Karate would contain the files used within the feature. Nevertheless
# having it results in a duplication of files if a lot of features use the same files. In this example I put the file in a
# separate folder. Maybe a Karate builtin function for retrieving the full path of a file in this specific case would be
# useful
* def fullPathFile =
"""
function(arg) {
return Java.type('examples.Utility').getFullPath(arg);
}
"""
* def pdfFile = fullPathFile('files/pdf-test.pdf')
Given driver uri
And waitFor(uploadSelector).input(pdfFile)
When submit().click(submitSelector)
And delay(5000)
Then match driver.text('#content > div > h3') == 'File Uploaded!'
And match driver.text('#uploaded-files') contains 'pdf-test.pdf'
EDIT: first read this answer: https://stackoverflow.com/a/61904351/143475 - because the Chrome native integration supports driver.inputFile() which is available in 0.9.6.RC4
File upload is a well-known hard problem to solve in browser automation. We will need some contributions from the community, but here is a demo I just experimented with using Karate Robot: https://github.com/intuit/karate/tree/develop/karate-robot
Feature:
Scenario:
* driver 'http://the-internet.herokuapp.com/upload'
* robot { app: '^Chrome', highlight: true }
* robot.click('choose-file.png')
* robot.input('/Users/pthomas3/Desktop')
* robot.input(Key.ENTER)
* robot.click('file-name.png')
* robot.input(Key.ENTER)
* delay(1000)
* click('#file-submit')
* delay(2000)
* screenshot()
You can see a video of the execution here: https://twitter.com/ptrthomas/status/1253373486384295936
The other options I can think of:
a) Use Karate's API testing capabilities to perform a multipart file upload: https://github.com/intuit/karate#multipart-file - this is actually in most cases sufficient to "complete" the flow you have. For example for this exact same flow you see above, it looks like this:
* url 'http://the-internet.herokuapp.com/upload'
* multipart file file = { read: 'billie.png', filename: 'billie.png', contentType: 'image/png' }
* method post
And typically you may need to add a cookie or two, which you can easily pass from the browser to the API test / HTTP client.
b) The other option is something I haven't tried yet, you can "fake" the part of the UI that does the file-upload and replace it with something else, if it can get you forward in your flow. Refer this: https://twitter.com/KarateDSL/status/1248996522357739521
This question already has answers here:
About Karate UI Test Automation, How can I upload files when I use karate-chrome?
(2 answers)
Closed 1 year ago.
Related the issue: Can upload / download files at Karate Driver?, Could you please help me to create the karate Ui code for upload excel PDF in this structure:
<div class="col-sm-6">
<div class="form-group shiny-input-container">
<label>Faça o upload do seu arquivo</label>
<div class="input-group">
<label class="input-group-btn">
<span class="btn btn-default btn-file">
Browse...
<input id="file_input" name="file_input" type="file" style="display: none;" data-shinyjs-resettable-id="file_input" data-shinyjs-resettable-type="File" data-shinyjs-resettable-value="" class="shinyjs-resettable shiny-bound-input">
</span>
</label>
<input type="text" class="form-control" placeholder="No file selected" readonly="readonly">
</div>
<div id="file_input_progress" class="progress progress-striped active shiny-file-input-progress">
<div class="progress-bar"></div>
</div>
</div>
</div>
I tried to use this source code below without success:
* def uri = 'http://the-internet.herokuapp.com/upload'
* def uploadSelector = '#file-upload'
* def submitSelector = '#file-submit'
# this function is for getting the full path of a file that is necessary to use with selenium sendKeys method when
# a file. I agree with the fact that every folder in Karate would contain the files used within the feature. Nevertheless
# having it results in a duplication of files if a lot of features use the same files. In this example I put the file in a
# separate folder. Maybe a Karate builtin function for retrieving the full path of a file in this specific case would be
# useful
* def fullPathFile =
"""
function(arg) {
return Java.type('examples.Utility').getFullPath(arg);
}
"""
* def pdfFile = fullPathFile('files/pdf-test.pdf')
Given driver uri
And waitFor(uploadSelector).input(pdfFile)
When submit().click(submitSelector)
And delay(5000)
Then match driver.text('#content > div > h3') == 'File Uploaded!'
And match driver.text('#uploaded-files') contains 'pdf-test.pdf'
EDIT: first read this answer: https://stackoverflow.com/a/61904351/143475 - because the Chrome native integration supports driver.inputFile() which is available in 0.9.6.RC4
File upload is a well-known hard problem to solve in browser automation. We will need some contributions from the community, but here is a demo I just experimented with using Karate Robot: https://github.com/intuit/karate/tree/develop/karate-robot
Feature:
Scenario:
* driver 'http://the-internet.herokuapp.com/upload'
* robot { app: '^Chrome', highlight: true }
* robot.click('choose-file.png')
* robot.input('/Users/pthomas3/Desktop')
* robot.input(Key.ENTER)
* robot.click('file-name.png')
* robot.input(Key.ENTER)
* delay(1000)
* click('#file-submit')
* delay(2000)
* screenshot()
You can see a video of the execution here: https://twitter.com/ptrthomas/status/1253373486384295936
The other options I can think of:
a) Use Karate's API testing capabilities to perform a multipart file upload: https://github.com/intuit/karate#multipart-file - this is actually in most cases sufficient to "complete" the flow you have. For example for this exact same flow you see above, it looks like this:
* url 'http://the-internet.herokuapp.com/upload'
* multipart file file = { read: 'billie.png', filename: 'billie.png', contentType: 'image/png' }
* method post
And typically you may need to add a cookie or two, which you can easily pass from the browser to the API test / HTTP client.
b) The other option is something I haven't tried yet, you can "fake" the part of the UI that does the file-upload and replace it with something else, if it can get you forward in your flow. Refer this: https://twitter.com/KarateDSL/status/1248996522357739521
I have been trying simple image upload using lua and Openresty web framework. I found many solutions like
lua-resty-upload
lua-resty-post
Using lua-resty-post I got the form data now how do I upload it?
local resty_post = require 'resty.post'
local cjson = require 'cjson'
local post = resty_post:new()
local m = post:read()
ngx.say(cjson.encode(m))
As I'm new to lua I don't understand which one to use.
My requirement is very simple, I need a file attribute and want to upload on some place like in php move_uploaded_file. Is there any simple way to upload a file?
Found the solution. Using lua-resty-post.
upload.html
<form action="/uploadimage" method="post" enctype="multipart/form-data">
<input type="file" name="upload" accept="image/*">
<button>Upload</button>
</form>
nginx.conf
location /uploadimage {
content_by_lua_file image.lua;
}
image.lua
local resty_post = require "resty.post"
local post = resty_post:new({
path = "/my/path", -- path upload file will be saved
name = function(name, field) -- overide name with user defined function
return name.."_"..field
end
})
local m = post:read()
I am programming a server side script on an Apache machine with cgi. I am using C for the cgi programming. I am a total noob and learning from online examples(I must say except the basics I didn't come across more web sources for detailed learning!).
I am having a simple HTML page where the username(input) is added to a list which is a file I have in my system and then the updated list should be displayed in the SAME PAGE.
I am not able to "print" the results of both the script and http link on the same page so therefore in the code below, you will only see buttons. Please help.
Here is what I have:
Html:
<html>
<head><title>Home</title></head>
<body>
<h1>REGISTER</h1>
<form action= "/cgi-bin/mycgi.cgi" name ="create user" method ="get">
Enter name:<input type="text" name="user">
<br>
<input type="submit" value="add">
</form>
<FORM action="http://localhost:8000/getusers/" method="get">
<P>
<input value="Display Users" type="submit">
</P>
</FORM>
</body>
Here is the cgi Code:
#include<stdio.h>
#include<string.h>
int main(){
char *tmpStr;
char *user;
printf("Content-Type:text/html\n\n");
printf("<html><head><title></title></head><body>");
tmpStr = getenv("QUERY_STRING");
while(tmpStr && *tmpStr != '='){
tmpStr++;
}
user = tmpStr+1,
printf("Adding %s to User Database",user);
//system("wget http://localhost:8000/newuser/");//call script to add user?
printf("</body></html>");
return 0;//return user?
}
Could you please tell me how I can realize these? How can I display the user list without opening a new html site? Also in the above C code, I have to call the link "http://localhost:8000/newuser/" which returns a success or failure value. How can I return it to the parent form?
Thanks.
You could add an iframe to your html:
<iframe id="theiframe" name="theiframe"></iframe>
And then setting the target of your form to the iframe:
<form action= "/cgi-bin/mycgi.cgi" name ="create user" method ="get" target="theiframe">
Anyway, it is not clear to me if the updated list should be displayed when you click on the first or second button.
Yes I am using Classic ASP, not by choice I am supporting a Legacy application. Objective: I need to have a form page that submits to another .asp page that will upload the file and store it on the server in a certain directory such as "/uploads". I'm not real familiar with asp or asp.net so I am very new to this. I've created a test prototype:
Form page:
<!DOCTYPE html>
<head>
<title>Test upload</title>
</head>
<body>
<form action="process.asp" method="post" enctype="multipart/form-data">
<p>Filename: <input type="text" name="filename" size="50" /></p>
<p><input type="file" name="file" /><input type="submit" value="Upload file" /></p>
</form>
</body>
</html>
Processing page:
<%
Set fs = Server.CreateObject("Scripting.FileSystemObject")
Set tfolder = fs.GetSpecialFolder(2)
tname = fs.GetTempName
'Declare variables
Dim fileSize
Dim filename
Dim file
Dim fileType
Dim p
Dim newPath
'Assign variables
fileSize = Request.TotalBytes
fileName = Request.form("filename")
file = request.form("file")
fileType = fs.GetExtensionName(file)
fileOldPath = tfolder
newPath = Server.MapPath("/uploads/")
fs.MoveFile fileOrigPath, newPath
set fs = nothing
%>
The problem is that everytime I try to upload or run the script I get this error:
Microsoft VBScript runtime error '800a0035'
File not found
/tbird/fileUpload/process.asp, line 25
Obviously I'm not mapping correctly to the file and I think the major reason I am getting stuck is that in the first parameter of the MoveFile method I am not mapping to the file correctly. Can anyone tell me how I should be referencing the file or if I am doing it wrong?
Thanks in advance I would really appreciate the help I've searched all over and everything I find related to classic asp and uploading files are classes that you can purchase and I don't want to do that.
Have a look at a solution like Pure ASP Upload, it should help you. In classic ASP, you cannot directly access Request.Form when data is sent in multipart/form-data, so you have the choice of using a third party component like ASPUpload or a ASP class that does the work of parsing the request for you and exposing methods to save the file.
When moving files you must also specify the file names.
Change:
fs.MoveFile fileOrigPath, newPath
To:
fs.MoveFile fileOrigPath & fileName, newPath & fileName
Assuming "fileName" is the correct variable for the file name and not "file" variable above.