How to use Perfect(Swift) under a VirtualHost(Apach)? - apache

I have Apache on Ubuntu OS. My Ubuntu use amazon Lightsail. I set up a VirtualHost for use the Perfect web server like this
<Location "/PerfectTemplate">
ProxyPass http://localhost:8182
ProxyPassReverse http://localhost:8182
</Location>
I was trying POST actions from HTML, but programs refer to Apache
var try_post_action = """
<form action="./tow" method="post">
//<form action="/tow" method="post">
First name: <input type="text" name="fname"><br>
Last name: <input type="text" name="lname"><br>
<input type="submit" value="Submit">
</form>
"""

The following Apache conf snippet
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) - [L,NS,H=perfect-handler]
and swift file
import PerfectHTTP
import PerfectHTTPServer
func handler(request: HTTPRequest, response: HTTPResponse) {
response.setHeader(.contentType, value: "text/html")
response.appendBody(string: """
<form action="./PerfectTemplate/test" method="get">
First name: <input type="text" name="fname"><br>
Last name: <input type="text" name="lname"><br>
<input type="submit" value="Submit">
</form>
""")
response.completed()
}
let confData = [
"servers": [
[
"name":"localhost",
"port":8182,
"routes":[
["method":"get", "uri":"/", "handler":handler],
["method":"get", "uri":"/test", "handler":handler],
["method":"get", "uri":"/**", "handler":PerfectHTTPServer.HTTPHandler.staticFiles,
"documentRoot":"./webroot",
"allowResponseFilters":true]
],
"filters":[
[
"type":"response",
"priority":"high",
"name":PerfectHTTPServer.HTTPFilter.contentCompression,
]
]
]
]
]
do {
try HTTPServer.launch(configurationData: confData)
} catch {
fatalError("\(error)")
}

Related

How to fix that URL query params are not working via the web share target API in vuejs pwa?

I'm building a new PWA in VueJS and have registered the app as a Share Target in my manifest.json (https://developers.google.com/web/updates/2018/12/web-share-target). Now my code works if I put the query params directly in the URL via the browser address bar (e.g. "/#/page-edit?url=https://google.com/&title=Google&description=SearchEngine"), but it doesn't work if I sent it via the Web Share Target API.
I have already tried a range of different manifest settings, but I'm not sure if my manifest settings are wrong or my code (e.g., tried both method "GET" and "POST", etc).
Current Manifest:
{
"name": "...",
"short_name": "...",
"icons": [],
"start_url": "/",
"display": "standalone",
"orientation": "portrait",
"background_color": "...",
"theme_color": "...",
"share_target": {
"action": "/#/page-edit",
"method": "GET",
"enctype": "application/x-www-form-urlencoded",
"params": {
"title": "title",
"text": "description",
"url": "url"
}
}
}
Current Vue view:
I have removed most of the not important code. As you can see I load the query data in two ways at the moment:
1. As data defaults, e.g., 'url': this.$route.query.url || null
2. As a variable in a <p>, e.g. {{ this.$route.query.url }}
<template>
<form class="modal-view">
<div class="field">
<label for="url" class="label">URL / link</label>
<div class="control">
<input id="url" v-model="url" class="input" type="url" placeholder="https://..." >
</div>
<p><strong>url query:</strong> {{ this.$route.query.url }}</p>
</div>
<div class="field">
<label for="title" class="label">Title</label>
<div class="control">
<input id="title" v-model="title" class="input" type="text" placeholder="The greatest article" >
</div>
<p><strong>title query:</strong> {{ this.$route.query.title }}</p>
</div>
<div class="field">
<label for="description" class="label">Description</label>
<div class="control">
<input id="description" v-model="description" class="input" type="text" placeholder="The greatest article" >
</div>
<p><strong>description query:</strong> {{ this.$route.query.description }}</p>
</div>
<hr class="is-small has-no-line">
<div class="field is-grouped is-grouped-right">
<div class="control">
<button #click.prevent="createPage" class="button is-primary is-fullwidth is-family-secondary">Submit</button>
</div>
</div>
</form>
</template>
<script>
import ...
export default {
name: 'page-edit',
computed: {},
data () {
return {
// Initialize default form values
'url': this.$route.query.url || null,
'title': this.$route.query.title || null,
'description': this.$route.query.description || null
}
},
mounted () {},
methods: {
createPage () {},
}
}
</script>
So what I would expect is that the query params can also be read if shared via the Web Share Target API, but at this point, it doesn't show anything this way. But good to mention again, it does all work if I simply change the query params in the browser address bar (that's also why I'm confused).
End result should look like
Edits
Edit 1
Have been playing around a bit more, and now found out that if I use window.location.href that it shows the following:
https://appurl.com/?title=xxx&description=xxx#/page-edit
I.e. it puts the query params in the wrong position?
Edit 2
Might be related to this Vue Router issue: Hash mode places # at incorrect location in URL if current query parameters exist on page load
Edit 3
Somehow fixed it with (I think)
const router = new Router({
mode: 'history'
And removing the # from the action in share_target
To fix it I have done the following things:
Added the following in the router, which resulted in removing the # from all URLs
const router = new Router({
mode: 'history'
Removed the # from the share_target.action in the manifest
Somehow fixed it all!

Upload file using angular material 5

I tried to upload file (angular 5) using angular material 5.
app.component.html
<mat-horizontal-stepper [linear]="isLinear" #stepper="matHorizontalStepper">
<mat-step [stepControl]="firstFormGroup">
<form [formGroup]="firstFormGroup">
<ng-template matStepLabel>Upload your audio file</ng-template>
<mat-form-field>
<input matInput
style="display: none"
type="file" (change)="onFileSelected($event)"
#fileInput name ="file" formControlName="firstCtrl" required>
<button mat-button (click)="fileInput.click()" >Select File</button>
</mat-form-field>
<div>
<button mat-button matStepperNext>Next</button>
</div>
</form>
app.component.ts
export class AppComponent {
selectedFile: File=null;
isLinear = true;
firstFormGroup: FormGroup;
secondFormGroup: FormGroup;
constructor(private _formBuilder: FormBuilder, private http: HttpClient) {}
ngOnInit() {
this.firstFormGroup = this._formBuilder.group({
firstCtrl: ['', Validators.required]
});
this.secondFormGroup = this._formBuilder.group({
secondCtrl: ['', Validators.required]
});
}
But I got this error
ERROR Error: Input type "file" isn't supported by matInput.
knowing this code worked well without angular material. Any issue?
I had the same problem,
Try doing this,
<button mat-raised-button (click)="openInput()">Select File to Upload</button>
<input id="fileInput" hidden type="file" (change)="fileChange($event.target.files)" name="file" accept=".csv,.xlsv">
openInput(){
document.getElementById("fileInput").click();
}
What above code does is creates simply a Material button and call openInput() method which later on replaces that button to below HTML code
<input id="fileInput" hidden type="file" >
This worked for me.
Happy Coding ☻
Faster solution would be to use
https://github.com/danialfarid/ng-file-upload :
<md-button class='md-raised md-primary' id='uploadFile' ngf-multiple='true' ngf-select='upload($files, $file, $event)'
type='file'>
Upload File
else you would have to go to a custom code like this:
<label class="md-secondary md-raised md-button" md-ink-ripple for="input-file">
<span>Select File to upload</span>
</label>
<input type="file" ngf-select ng-model="input-file" name="input-file" id="input-file">
EDITED:
In your HTML:
<input #file type="file" nbButton multiple (change)="upload(file.files)" />
then in your component:
upload(files: any) {
this.yourServiceToUploadFiles.uploadFile(files).subscribe(
(response: any) => { .......})}
and then in your service:
uploadFile(files: any[]): Observable<HttpResponse<Blob>> {
if (files.length === 0) {
return;
}
const formData = new FormData();
for (const file of files) {
formData.append(file.name, file);
}
return this.http.post(`${apiUrl}/yourServiceEndPoint`, formData, {
observe: "response",
responseType: "blob"
});
}

XAMPP delete and put requests on localhost doesn't work

I have this code on a page
<td>
<form method="DatabasePost" action=".../admin/users/1" accept-charset="UTF-8">
<input name="_method" type="hidden" value="DELETE">
<input name="_token" type="hidden" value="EMyKLKBmQjBUz63XqSRRqH06Mw0PwzikT5EkJZyc">
<input type="submit" value="Delete">
</form>
</td>
Generated by Blade in v.4.2. Laravel; yet in browser's Network developer tools I still recieve a GET request. What am I doing wrong? Do I have to enable these requests (delete/put) in Apache or something? I have this
<Directory />
AllowOverride All
<Limit GET HEAD POST PUT DELETE OPTIONS>
Order Allow,Deny
Allow from all
</Limit>
in apache's httpd.conf and this
<Limit GET POST PUT DELETE>
Allow from all
</Limit>
in .htaccess file but nothing seems to work..
On DELETE request #destroy method should be called in Laravel's controller but #show (GET request route) is called instead.
EDIT:
routes.php
Route::resource('admin/users', 'App\Controllers\Admin\UserController');
console command php artisan routes does in fact show all routes
Your form should be as follows (assume it is blade file):
<form method="post" action="{{url('admin/users/1')}}">
<input name="_method" type="hidden" value="DELETE">
<input name="_token" type="hidden" value="{{csrf_token()}}">
<input type="submit" value="Delete">
</form>

Unable to call 'onSuccess' or 'onFailure' of adapter invocation

I have an adapter which retrieves a JSON object, but strangely everything works fine if the form uses only button, but if I put <input type="text"> then WL.Client.invokeProcedure's callbacks ('onSuccess' or 'onFailure') or not called...
Adapter Code:
intranetId="my-email-address";
var invocationData = {
adapter : 'RoleAdapter',
procedure : 'getRoles',
parameters : [intranetId,"role"]
};
WL.Client.invokeProcedure(invocationData, {
onSuccess : function(res){ console.log('win', res); },
onFailure : function(res){ console.log('fail', res); }
HTML Form:
<div id="welcome">
<form action="#welcome2" onsubmit="getRole()">
<input type="text" id="userId">
<br/>
<input type="password" name = "password">
<br/>
<input type="submit" value="Login">
</form>
</div>
I am able to get value of userId, and even if I hardcode it in getRole() same problem...
edit:
On changing the html form to this
<div id="welcome">
<form action="#welcome2" onsubmit="return getRole()">
<input type="submit" value="go">
</form>
</div>
I tried debugging, but cudnt get anything.
edit2:
I fixed it!
So basically, In html form you cannot add 'name' property to an input element when you are using with worklight. Don't know why it is so..
This worked for me...
Full example here: https://stackoverflow.com/a/17852974/1530814
index.html
<form onsubmit="submitName()">
First name: <input type="text" id="firstname"/><br>
Last name: <input type="text" id="lastname"/><br>
<input type="submit" value="Submit Name"/>
</form>
main.js
function wlCommonInit(){
}
function submitName() {
var invocationData = {
adapter : 'exampleAdapter',
procedure : "showParameters",
parameters : [$('#firstname').val(),$('#lastname').val()]
};
var options = {
onSuccess : success,
onFailure : failure
};
WL.Client.invokeProcedure(invocationData, options);
}
function success() {
alert ("success");
}
function failure(res) {
alert ("failure");
}

Controllers Not Calling Action

i have a controller name UserController in application/controllers
the base folder is zend-login and there are 3 sub folder 1= application 2 = library 3=web_root
problem is here!! when ever i hit http://localhost/zend_login/web_root/user/login or http://localhost/zend_login/web_root/user/register
i get this error Error 404 Object not found! both the file are there in a folder
<?php
require_once 'Zend/Controller/Action.php';
class UserController extends Zend_Controller_Action{
public function indexAction(){
$this->view->assign('name', 'xainee');
$this->view->assign('title', 'Hello');
}
public function loginAction(){
$request = $this->getRequest();
$this->view->assign('action', $request->getParam());
$this->view->assign('title', 'Login Form');
$this->view->assign('username', 'User Name');
$this->view->assign('password', 'Password');
}
public function registerAction(){
$request = $this->getRequest();
$this->view->assign('action',"process");
$this->view->assign('title','Member Registration');
$this->view->assign('label_fname','First Name');
$this->view->assign('label_lname','Last Name');
$this->view->assign('label_uname','User Name');
$this->view->assign('label_pass','Password');
$this->view->assign('label_submit','Register');
$this->view->assign('description','Please enter this form completely:');
}
}
?>
action for this is here views/scripts/user/register.phtml and
views/scripts/user/login.phtml
this is register.phtml
<?php include "header.phtml"; ?>
<h1><?=$this->escape($this->title);?></h1>
<div id="description">
<?=$this->escape($this->description);?>
</div>
<form name="register" method="post" action="<?=$this->escape($this->action)?>">
<table>
<tr>
<td><?=$this->escape($this->label_fname)?></td>
<td><input type="text" name="first_name"></td>
</tr>
<tr>
<td><?=$this->escape($this->label_lname)?></td>
<td><input type="text" name="last_name"></td>
</tr>
<tr>
<td><?=$this->escape($this->label_uname)?></td>
<td><input type="text" name="user_name"></td>
</tr>
<tr>
<td><?=$this->escape($this->label_pass)?></td>
<td><input type="password" name="password"></td>
</tr>
</table>
<input type="submit" name="submit" value="<?=$this->escape($this->label_submit);?>">
</form>
<?php include "footer.phtml"; ?>
recommended .htaccess is
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ index.php [NC,L]