Explain the routing code calling signature for ESPAsyncWebServer - esp32

Here is one of the routes in my ESP32 app that is for ESPAsyncWebServer to interpret:
// Route to delete the data log file
server.on("/deletedata", HTTP_GET, [](AsyncWebServerRequest *request) {
request->send(SPIFFS, "/index.html", "text/html", false, processor);
DeleteFile(data_logfile);
});
Having had examples to inform me, my initial set of routes is working fine. But I am expanding with new pages and want to more fully understand what the method params are actually doing. For example, what is the full signature of request->send()? In particular, the second parameter ("/index.html") ? This is the origin file of the request as it turns out, but I don't understand why that is needed. Also, what is "processor"? The other params I understand pretty well. "DeleteFile(data_logfile);" calls a method in the ESP32 code that carries out the action indicated by the HTTP /deletedata request.
ESPAsyncWebServer works great but isn't that well-documented (that I can find).

request-send() accepts a file system type, a route to a page in the file system, a content type for the handled page, a flag indicating that the client should download that file or not and a processor function which will be called as the page gets send out to the client.
The processor function will be called as soon as the send() function finds a pair of two signal characters which is default to "%" in the asyncWebserver's case.
It is used for building a dynamic webpage with templates. If you have let's say an index.html file with templates, you can replace your template parameters with values using the Processor function.
Here is an example:
Index.html Page:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Example page</title>
</head>
<body>
<h1> %variableFromESP% </h1>
</body>
</html>
ESP endpoint:
/*
This processor function will be called if the server finds
something between two controll characters.
In this case: %variableFromESP%.
This processor function is used to replace this character
with whatever value.
*/
String processor( const String& var ){
if( var == "variableFromESP" ){
return "Hello World";
}
return "";
}
// Using LittleFs as a file system, a testPage.html route,text/html type
// do not download this file, and passing the processor function.
server.on("/testPage", HTTP_GET, [](AsyncWebServerRequest *request) {
request->send(LittleFs, "/testPage.html", "text/html", false, processor);
});

Related

Refused to frame '' because it violates the following Content Security Policy directive: "frame-src *" Trying to set for tel: explicity here

I'm currently trying to build a click to dial link in the browser as an Outlook Addin. I'm getting the error:
Refused to frame '' because it violates the following Content Security Policy directive: "frame-src *". Note that '*' matches only URLs with network schemes ('http', 'https', 'ws', 'wss'), or URLs whose scheme matches `self`'s scheme. tel:' must be added explicitely. [https://localhost:44371/]
I've set the meta tags a bunch of different ways trying to explicitly state the tel scheme that they mention. For instance:
<meta http-equiv="Content-Security-Policy" content="frame-src 'self' tel:">
I've tried about 20 different variations on this. I've also noticed that many people are saying something about changing the HTTP response headers, but I'm not sure exactly how to do this or even why it would be needed.
I'm working on Visual Studio using a template from their own program. Because I'm testing this out on my own computer, I've also tried to whitelist my own localhost. Still nothing.
Here is the html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta http-equiv="Content-Security-Policy" content="frame-src 'self' tel:">
<title>standard_item_properties</title>
<script src="https://appsforoffice.microsoft.com/lib/1/hosted/office.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" media="all" href="default_entities.css" />
<script type="text/javascript" src="MicrosoftAjax.js"></script>
<script src="CallFunctionFile.js" type="text/javascript"></script>
<!-- Use the CDN reference to Office.js. -->
<script type="text/javascript" src="default_entities.js"></script>
</head>
<body>
<!-- NOTE: The body is empty on purpose. Since this is invoked via a button, there is no UI to render. -->
<div id="container">
<div><a id="tel-link">Make Call from Phone</a></div>
</div>
</body>
</html>
and here is the javascript:
// Global variables
let item;
let myEntities;
// The initialize function is required for all add-ins.
Office.initialize = function () {
const mailbox = Office.context.mailbox;
// Obtains the current item.
item = mailbox.item;
// Reads all instances of supported entities from the subject
// and body of the current item.
myEntities = item.getEntities();
JSON.stringify(myEntities.phoneNumbers[0].originalPhoneString));
// Checks for the DOM to load using the jQuery ready function.
window.addEventListener('DOMContentLoaded', (event) => {
// After the DOM is loaded, app-specific code can run.
});
let a = document.getElementById("tel-link");
a.href = "tel:" + encodeURIComponent(myEntities.phoneNumbers[0].originalPhoneString);
}

How to view data retrieved in the controller in the view?

I'm trying to retrieve data in my controller using sqlsrv database connection and I want to view the result in my test.blade.php
public function index()
{
$cout_achat = DB::table('[DWH_SOVAC_PROD_KIT_LIFE_CYCLE]')
->select( DB::raw('SUM([MONTANT_LC]) as cout_achat'))
->get();
return view('test', ['test' => $cout_achat]);
}
and the code in the view
<html lang="{{ config('app.locale') }}">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Laravel</title>
<!-- Fonts -->
<link href="https://fonts.googleapis.com/css?family=Raleway:100,600"
rel="stylesheet" type="text/css">
</head>
<body>
echo {{$cout_achat}};
</body>
</html>
but when I try to access myapp/test I get : ** Use of undefined constant test - assumed 'test' (this will throw an Error in a future version of PHP) (View: C:\wamp64\www\projetSovac\resources\views\test.blade.php) –**
About 404 the route you have provided is completely ok, can you please tell us how you are calling this route.
And please double check any typo in controller name.
Now I would like to talk about some improvement in your code
First of all is that when you return the view like this in your controller
return view('test', ['test' => $cout_achat]);
The $cout_achat will be available with name $test in your blade file. So you should try to use the same naming convention like
return view('test', ['cout_achat' => $cout_achat]);
Or simple you can use compact() laravels helper function like this
return view('test', compact(cout_achat));
It will automatically pass $cout_achat in blade.
Now for echoing the variable in balde you don't need to use echo explicitly like
echo {{$cout_achat}};
You can echo variables like
{{$cout_achat}}
Anything else will be handled automatically by blade compiler.
Hope this will help.

Get Raw Html From the controller Spring thymeleaf

I have a controller that create model attribute and passes to the view "partial.html" to generate output
partial.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Home page</title>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
</head>
<body>
<p>
<span th:text="'Today is: ' + ${message}"></span>
</p>
</body>
</html>
and inside a controller method
model.addAttribute("message", search);
How to do I get Htlm Output to a string inside controller method?
like this
String htmlOutput="from partial.html";
Let's say you have a HTML file with two variable name and todayDate.
You want to process it and want to store it in a string / database / AWS S3.
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
</head>
<body>
<p>Hello</p>
<p th:text="${name}"></p>
<p th:text="${todayDate}"></p>
</body>
</html>
Your HTML file location is src/main/resources/templates/home.html
By using the below function you can get the final processed HTML as:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<p>Hello</p>
<p>Manoj</p>
<p>30 November 2019</p>
</body>
</html>
import org.thymeleaf.context.Context;
#GetMapping("/")
public void process() {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver();
templateResolver.setPrefix("templates/");
templateResolver.setCacheable(false);
templateResolver.setSuffix(".html");
templateResolver.setTemplateMode("HTML");
// https://github.com/thymeleaf/thymeleaf/issues/606
templateResolver.setForceTemplateMode(true);
templateEngine.setTemplateResolver(templateResolver);
Context ctx = new Context();
SimpleDateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy");
Calendar cal = Calendar.getInstance();
ctx.setVariable("todayDate", dateFormat.format(cal.getTime()));
ctx.setVariable("name", "Manoj");
final String result = templateEngine.process("home", ctx);
System.out.println("result:" + result);
}
If you're using the usual Spring MVC approach, as Joanna says you're doing things in the wrong order. The Controller creates the model and specifies the view, and then after that the view is rendered by the Thymeleaf template that uses the model.
If, on the other hand, you're trying to render Thymeleaf templates yourself (rather than sending them to the user's browser directly, maybe for use in HTML email or to store prerendered pages in a database or something), then you'd need to create your own Thymeleaf Template Engine to use. Refer to the "Creating and configuring the Template Engine" section of the documentation for details. You can create your own Engine, and then use its process method to get the result of the template to put into a variable for further use.
You may looking for this, getting directly the result HTML, just ignore the email part of the post.
Then, you can create this:
final Context ctx = new Context(locale);
ctx.setVariable("name", recipientName);
ctx.setVariable("subscriptionDate", new Date());
ctx.setVariable("hobbies", Arrays.asList("Cinema", "Sports", "Music"));
ctx.setVariable("imageResourceName", imageResourceName);
// so that we can reference it from HTML
final String htmlContent = this.templateEngine.process("html/email-inlineimage.html", ctx);
So you have the htmlContext of rendered thymeleaf template (with vars)
Once the control goes out to view processor (JSP/Thymeleaf etc), it will not be coming back to controller. You will be able to get the raw html response in a customFilter, but not in the Controller.

Cannot Load the HTML through HtmlAgilityPack

I try to parse HTML using HtmlAgilityPack using simple doc.load method by passing the URL, but it comes with the following result how can I resolve this issue?
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="Content-Script-Type" content="text/javascript">
<script type="text/javascript">
function setCookie(c_name, value, expiredays) {
var exdate = new Date();
exdate.setDate(exdate.getDate()+expiredays);
document.cookie = c_name + "=" + escape(value) + ((expiredays==null) ? "" : ";
expires=" + exdate.toGMTString()) + ";path=/"; }
function getHostUri()
{ var loc = document.location; return loc.toString(); }
setCookie('YPF8827340282Jdskjhfiw_928937459182JAX666', '202.142.170.42', 10);
setCookie('DOAReferrer', document.referrer, 10); location.href = getHostUri();
</script>
</head>
<body>
<noscript>This site requires JavaScript and Cookies to be enabled. Please change your browser settings or upgrade your browser.</noscript>
</body></html>
This site requires JavaScript and Cookies to be enabled.
Please change your browser settings or upgrade your
browser.
This Message says it all, the side needs javascript to be loaded, and HtmlAgilityPack is no JavascriptEngine!
The Load Method of the HtmlDocument can not interpret and execute Javascript-Code it´s just a simple "Download"-Function for static HTML-Sites.
What you could try to do is, with Firebug (or something else) check which HttpRequest are made to get the content, and this Requests you have to recreate in C# to get the HTML you want!
Here are some similar Questions:
Running Scripts in HtmlAgilityPack
C# - Get JavaScript variable value using HTMLAgilityPack
Calling javascript function from HtmlAgilityPack

Javascript and character encoding

In my ASP.NET MVC 3 project, I have set the character encoding in my master page
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
then, in my view, I have
<script type="text/javascript" charset='UTF-8'>
$(function () {
$('#my-btn').click(function () {
$(this).val('#MyProject.Resources.OrderButton');
});
});
</script>
what gives me the value Zamów onstead of Zamów. The resource file's first line is:
<?xml version="1.0" encoding="utf-8"?>
Any ideas how to fix it ?
The correct way to pass server side values to javascript variables is the following:
var value = #Html.Raw(Json.Encode(MyProject.Resources.OrderButton);
$(this).val(value);
This will output code which is completely safe and correctly encoded to be passed to a javascript function. This will also properly handle cases where your string contains characters such as ', new lines, ... which would have broken your javascript code.
And you should not care whether some characters are HTML or whatever encoded. The important thing is that they will be correctly encoded for a browser or an HTML compliant client to correctly consume.

Resources