ExtJS PHP/MySQL backend connector error - javascript

exactly the same problem than on this post
follow carefully the documentation (official)
https://docs.sencha.com/extjs/6.5.3/guides/backend_connectors/direct/mysql_php.html
did not understand how to solve it
edit
here is a screenshot of firefox console
api.php (the file where the error is)
(took from ext js documentation and sdk examples)
<?php
require('config.php');
header('Content-Type: text/javascript');
$API = get_extdirect_api('api');
# convert API config to Ext Direct spec
$actions = array();
foreach($API as $aname=>&$a){
$methods = array();
foreach($a['methods'] as $mname=>&$m){
if (isset($m['len'])) {
$md = array(
'name'=>$mname,
'len'=>$m['len']
);
} else {
$md = array(
'name'=>$mname,
'params'=>$m['params']
);
}
if(isset($m['formHandler']) && $m['formHandler']){
$md['formHandler'] = true;
}
if (isset($m['metadata'])) {
$md['metadata'] = $m['metadata'];
}
$methods[] = $md;
}
$actions[$aname] = $methods;
}
$cfg = array(
'url'=>'data/direct/router.php',
'type'=>'remoting',
'actions'=>$actions
);
echo 'var Ext = Ext || {}; Ext.REMOTING_API = ';
echo json_encode($cfg);
echo ';';
?>
app.json edited part as asked in the tutorial i linked
"js": [
{
"path": "${framework.dir}/build/ext-all-rtl-debug.js"
},
{
"path": "php/api.php",
"remote": true
},
{
"path": "app.js",
"bundle": true
}
],
application.js
/**
* The main application class. An instance of this class is created by app.js when it
* calls Ext.application(). This is the ideal place to handle application launch and
* initialization details.
*/
Ext.define('DirectApp.Application', {
extend: 'Ext.app.Application',
name: 'DirectApp',
quickTips: false,
platformConfig: {
desktop: {
quickTips: true
}
},
launch: function () {
Ext.direct.Manager.addProvider(Ext.REMOTING_API);
},
onAppUpdate: function () {
Ext.Msg.confirm('Application Update', 'This application has an update, reload?',
function (choice) {
if (choice === 'yes') {
window.location.reload();
}
}
);
}
});
index.html
<!DOCTYPE HTML>
<html manifest="">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=10, user-scalable=yes">
<title>DirectApp</title>
<!-- The line below must be kept intact for Sencha Cmd to build your application -->
<script id="microloader" data-app="70f32dd6-f700-4939-bc96-3af4f1c9798b" type="text/javascript" src="bootstrap.js"></script>
</head>
<body></body>
</html>
here is the router took from sdk examples as i say you can do it in the tutorial
<?php
require('config.php');
class BogusAction {
public $action;
public $method;
public $data;
public $tid;
}
$isForm = false;
$isUpload = false;
if(isset($HTTP_RAW_POST_DATA)){
header('Content-Type: text/javascript');
$data = json_decode($HTTP_RAW_POST_DATA);
}else if(isset($_POST['extAction'])) { // form post
$isForm = true;
$isUpload = $_POST['extUpload'] == 'true';
$data = new BogusAction();
$data->action = $_POST['extAction'];
$data->method = $_POST['extMethod'];
$data->tid = isset($_POST['extTID']) ? $_POST['extTID'] : null; // not set for upload
$data->data = array($_POST, $_FILES);
}else if (($data = file_get_contents('php://input')) !== '') {
$data = json_decode($data);
}else{
die('Invalid request.');
}
function doRpc($cdata){
$API = get_extdirect_api('router');
try {
if(!isset($API[$cdata->action])){
throw new Exception('Call to undefined action: ' . $cdata->action);
}
$action = $cdata->action;
$a = $API[$action];
doAroundCalls($a['before'], $cdata);
$method = $cdata->method;
$mdef = $a['methods'][$method];
if(!$mdef){
throw new Exception("Call to undefined method: $method on action $action");
}
doAroundCalls($mdef['before'], $cdata);
$r = array(
'type'=>'rpc',
'tid'=>$cdata->tid,
'action'=>$action,
'method'=>$method
);
require_once("classes/$action.php");
$o = new $action();
if (isset($mdef['len'])) {
$params = isset($cdata->data) && is_array($cdata->data) ? $cdata->data : array();
} else {
$params = array($cdata->data);
}
array_push($params, $cdata->metadata);
$r['result'] = call_user_func_array(array($o, $method), $params);
doAroundCalls($mdef['after'], $cdata, $r);
doAroundCalls($a['after'], $cdata, $r);
}
catch(Exception $e){
$r['type'] = 'exception';
$r['message'] = $e->getMessage();
$r['where'] = $e->getTraceAsString();
}
return $r;
}
function doAroundCalls(&$fns, &$cdata, &$returnData=null){
if(!$fns){
return;
}
if(is_array($fns)){
foreach($fns as $f){
$f($cdata, $returnData);
}
}else{
$fns($cdata, $returnData);
}
}
$response = null;
if(is_array($data)){
$response = array();
foreach($data as $d){
$response[] = doRpc($d);
}
}else{
$response = doRpc($data);
}
if($isForm && $isUpload){
echo '<html><body><textarea>';
echo json_encode($response);
echo '</textarea></body></html>';
}else{
echo json_encode($response);
}
?>
QueryDatabase.php (sql request php file)
<?php
class QueryDatabase {
private $_db;
protected $_result;
public $results;
public function __construct() {
$this->_db = new mysqli(MY CREDENTIALS);
$_db = $this->_db;
if ($_db->connect_error) {
die('Connection Error: ' . $_db->connect_error);
}
return $_db;
}
public function getResults($params) {
$_db = $this->_db;
$_result = $_db->query("SELECT name,email,phone FROM heroes") or
die('Connection Error: ' . $_db->connect_error);
$results = array();
while ($row = $_result->fetch_assoc()) {
array_push($results, $row);
}
$this->_db->close();
return $results;
}
}
and finally config.php file
<?php
function get_extdirect_api() {
$API = array(
'QueryDatabase' => array(
'methods' => array(
'getResults' => array(
'len' => 1
)
)
)
);
return $API;
}
edit2
here is full network tab from firefox screenshots
edit 3
here is api.php details from network tab
answer
headers
stack trace
here is the configuration file sencha.cfg which is configuration of the minimal web server provided my sencha CMD
# sencha.cfg
#
# This is the main configuration file for Sencha Cmd. The properties defined in
# this file are used to initialize Sencha Cmd and should be edited with some
# caution.
#
# On previous versions, this file provided a way to specify the cmd.jvm.* properties
# to control the execution of the JVM. To accommodate all possible execution scenarios
# support for these properties has been removed in favor of using the _JAVA_OPTIONS
# environment variable.
#
#------------------------------------------------------------------------------
# This indicates the platform that Cmd is installed on. This is used for
# platform specific package management.
#
# Possible values: windows, osx, linux, linux-x64
#
# cmd.platform=
#------------------------------------------------------------------------------
# This is the Sencha Cmd version.
#
# THIS PROPERTY SHOULD NOT BE MODIFIED.
cmd.version=6.5.3.6
#------------------------------------------------------------------------------
# This indicates the level of backwards compatibility provided. That is to say,
# apps requiring versions between cmd.minver and cmd.version (inclusive) should
# be able to use this version.
#
# THIS PROPERTY SHOULD NOT BE MODIFIED.
cmd.minver=3.0.0.0
#------------------------------------------------------------------------------
# The folder for the local package repository. By default, this folder is shared
# by all versions of Sencha Cmd. In other words, upgrading Sencha Cmd does not
# affect the local repository.
repo.local.dir=${cmd.dir}/../repo
#------------------------------------------------------------------------------
# This is the default port to use for the Sencha Cmd Web Server.
cmd.web.port=1841
#------------------------------------------------------------------------------
# Java System Properties
#
# By setting any "system.*" properties you can set Java System Properties. For
# general information on these, see:
#
# http://docs.oracle.com/javase/tutorial/essential/environment/sysprop.html
#
#------------------------------------------------------------------------------
# Proxy Settings
#
# The primary reason to set Java System Properties is to handle HTTP Proxies.
# By default, Java uses "http.proxy*" properties to configure HTTP proxies, but
# the "java.net.useSystemProxies" option can be enabled to improve the use of
# system-configured proxy settings based on your platform. If this setting does
# not work for your proxy server setup, try disabling this setting by commenting
# it out and enabling the other settings. See also this information on proxy
# setup:
#
# http://docs.oracle.com/javase/6/docs/technotes/guides/net/proxies.html
#
# NOTE: If you find that you need to adjust these settings, you may want to do
# so in a "sencha.cfg" file one folder above this folder. The settings in that
# file override these settings, so be sure to only copy the settings you need
# to that location. The advantage to putting these settings in that location is
# that they will not be "lost" as you upgrade Cmd.
system.java.net.useSystemProxies=true
# These are the legacy options that come in to play when the above is commented
# out:
#system.http.proxyHost=proxy.mycompany.com
#system.http.proxyPort=80
#system.http.proxyUser=username
#system.http.proxyPassword=password
#------------------------------------------------------------------------------
# Merge Tool Settings
#
# To enable use of a visual merge tool to resolve merge conflicts, set the
# following property to the desired merge tool path:
#
# cmd.merge.tool=p4merge
#
# Next, to configure the arguments for the merge tool, set this property:
#
# cmd.merge.tool.args={base} {user} {generated} {out}
#
# Alternatively, the arguments for several merge tools are defined below and can
# be used in your configuration for simplicity/clarity like so:
#
# cmd.merge.tool.args=${cmd.merge.tool.args.sourcegear}
#
# NOTE: the cmd.merge.tool.args property is split on spaces *then* the tokens
# are replaced by actual files names. This avoids the need to quote arguments to
# handle spaces in paths.
#
# NOTE: Some merge tools (like SmartSynchronize) do not accept the output file
# separately so there is no way to know if the merge was completed. In this case,
# the base file is where the result is written so Cmd just copies the content of
# that file back as the result.
#
# You can add the appropriate lines to customize your Cmd configuration. See
# below for details.
# The arguments for p4merge, see below for download:
# http://www.perforce.com/product/components/perforce-visual-merge-and-diff-tools
cmd.merge.tool.args.p4merge={base} {user} {generated} {out}
# SourceGear (http://www.sourcegear.com/diffmerge/index.html)
cmd.merge.tool.args.sourcegear=--merge --result={out} {user} {base} {generated}
# kdiff3 (http://sourceforge.net/projects/kdiff3/files/kdiff3/)
cmd.merge.tool.args.kdiff3={base} {user} {generated} -o {out}
# Syntevo SmartSynchronize 3 (http://www.syntevo.com/smartsynchronize/index.html).
cmd.merge.tool.args.smartsync={user} {generated} {base}
# TortoiseMerge (part of TortoiseSVN - see http://tortoisesvn.net).
cmd.merge.tool.args.tortoise=-base:{base} -theirs:{generated} -mine:{user} -merged:{out}
# AraxisMerge (see http://www.araxis.com/merge-overview.html):
cmd.merge.tool.args.araxis=-wait -merge -3 -a1 {base} {user} {generated} {out}
# The address where Sencha Inspector is located
inspector.address=http://localhost:1839/
# this variable references a json file containing unicode code points to be
# printed in escaped form during code generation.
cmd.unicode.escapes=${cmd.dir}/unicode-escapes.json
#------------------------------------------------------------------------------
# Customizing Configuration
#
# Customization can be handled any of these ways:
#
# 1. Place customizations in this file (ideally at the bottom) and they will
# configure this instance of Sencha Cmd.
#
# 2. Create a "sencha.cfg" file in the folder above this instance of Sencha Cmd
# to be shared by all installed versions.
#
# 3. Create a "~/.sencha/cmd/sencha.cfg" file. On Windows, the "~" maps to your
# %HOMEDRIVE%%HOMEPATH% folder (e.g., "C:\Users\Me").
#
# Your personal settings take priority over common settings (item #2) which both
# take priority of instance settings (this file).
thank you

I guess you are also following the guide and using the sencha app watch and getting the php code returning back to you. I found this answer on a Sencha forum that the web server that the sencha cmd provides doesn't support php is just a basic HTTP web server.

I was looking at the exact same thing today and came across the post....
For anyone else looking for the problem this is how i fixed it. Basically you have to get the posted data in a slightly different manner... looks at the first comment in the code below
<?php
require('config.php');
class BogusAction {
public $action;
public $method;
public $data;
public $tid;
}
$isForm = false;
$isUpload = false;
// different way to get the data that is posted to the URL
$postData = file_get_contents('php://input');
if (isset($postData)) {
header('Content-Type: text/javascript');
$data = json_decode($postData);
}
else if (isset($HTTP_RAW_POST_DATA)) {
header('Content-Type: text/javascript');
$data = json_decode($HTTP_RAW_POST_DATA);
}
else if(isset($_POST['extAction'])){ // form post
$isForm = true;
$isUpload = $_POST['extUpload'] == 'true';
$data = new BogusAction();
$data->action = $_POST['extAction'];
$data->method = $_POST['extMethod'];
$data->tid = isset($_POST['extTID']) ? $_POST['extTID'] : null;
$data->data = array($_POST, $_FILES);
}
else {
die('Invalid request min .');
}
function doRpc($cdata){
$API = get_extdirect_api('router');
try {
if (!isset($API[$cdata->action])) {
throw new Exception('Call to undefined action: ' . $cdata->action);
}
$action = $cdata->action;
$a = $API[$action];
$method = $cdata->method;
$mdef = $a['methods'][$method];
if (!$mdef){
throw new Exception("Call to undefined method: $method " .
"in action $action");
}
$r = array(
'type'=>'rpc',
'tid'=>$cdata->tid,
'action'=>$action,
'method'=>$method
);
require_once("classes/$action.php");
$o = new $action();
if (isset($mdef['len'])) {
$params = isset($cdata->data) && is_array($cdata->data) ? $cdata->data : array();
}
else {
$params = array($cdata->data);
}
$r['result'] = call_user_func_array(array($o, $method), $params);
}
catch(Exception $e){
$r['type'] = 'exception';
$r['message'] = $e->getMessage();
$r['where'] = $e->getTraceAsString();
}
return $r;
}
$response = null;
if (is_array($data)) {
$response = array();
foreach($data as $d){
$response[] = doRpc($d);
}
}
else{
$response = doRpc($data);
}
if ($isForm && $isUpload){
echo '<html><body><textarea>';
echo json_encode($response);
echo '</textarea></body></html>';
}
else{
echo json_encode($response);
}
?>

Related

Sentry.io JavaScript tunnel on Laravel route?

The issue:
Because of issues with the JavaScript code loading I am trying to integrate sentry with the tunnel option. This would prevent the blocking, if a user has an ad-blocker enabled.
https://docs.sentry.io/platforms/javascript/troubleshooting/#using-the-tunnel-option
Now they provide an example code for this tunnel in their documentation:
<?php
// Change $host appropriately if you run your own Sentry instance.
$host = "sentry.io";
// Set $known_project_ids to an array with your Sentry project IDs which you
// want to accept through this proxy.
$known_project_ids = array( );
$envelope = stream_get_contents(STDIN);
$pieces = explode("\n", $envelope, 2);
$header = json_decode($pieces[0], true);
if (isset($header["dsn"])) {
$dsn = parse_url($header["dsn"]);
$project_id = intval(trim($dsn["path"], "/"));
if (in_array($project_id, $known_project_ids)) {
$options = array(
'http' => array(
'header' => "Content-type: application/x-sentry-envelope\r\n",
'method' => 'POST',
'content' => $envelope
)
);
echo file_get_contents(
"https://$host/api/$project_id/envelope/",
false,
stream_context_create($options));
}
}
In the app.php, the layout file of my project, I am calling the JavaScript Sentry like this:
<script src="{{ asset('/assets/js/app.js') }}" crossorigin="anonymous"></script>
My question:
What I don't understand is how to integrate this into the web.php as a route. So it gets called everytime an JavaScript error occured.
You should be able to define a route like this:
Route::post('/sentry-tunnel', function (Request $request) {
// Change $host appropriately if you run your own Sentry instance.
$host = "sentry.io";
// Set $known_project_ids to an array with your Sentry project IDs which you
// want to accept through this proxy.
$known_project_ids = [];
$envelope = $request->getContent();
$pieces = explode("\n", $envelope, 2);
$header = json_decode($pieces[0], true);
if (isset($header['dsn'])) {
$dsn = parse_url($header['dsn']);
$project_id = intval(trim($dsn['path'], '/'));
if (in_array($project_id, $known_project_ids)) {
return Http::withBody($envelope, "application/x-sentry-envelope")
->post("https://$host/api/$project_id/envelope/");
}
}
});
And then call the URL '/sentry-tunnel' from your JavaScript. Don't forget to add your project ID and credentials if necessary.

On click echo attribute

I am trying to create a gallery that uses PHP to go through asset folders and serve as sort of an album system. The code below retrieves files as albums :
<?php
include_once("../PhpScript/RetAlbInfo.php");
$files = array_slice(scandir('../Assets/Gallery/'), 2);
for($albflcnt = 0;$albflcnt<count($files);$albflcnt++){
echo "<div style='...'><div class='albm' style='...' onmousedown='gotoalbum();albnm();'></div><p style='...'>".$files[$albflcnt]."</p></div>";
}
?>
The problem is that I cannot find a way to get folder names from each <p> tag and append it to the url so it would show it's sub folder.
you can use glob() with GLOB_ONLYDIR option
<?php
foreach (glob("*.txt") as $filename) {
echo "$filename size " . filesize($filename) . "\n";
}
?>
or
<?php
$dirs = array_filter(glob('*'), 'is_dir');
print_r( $dirs);
?>
You might be wanting a RecursiveDirectoryIterator? Not 100% sure. Here is a basic example. There are portions that may or may not be relevant. This basically builds a bread crumb system of sorts, but there may be parts you are looking for:
<?php
# Create some defines in the root of the website if not already done
# This is your url
define('SITE_URL','http://www.example.com');
# This is the root path
define('BASE_DIR',__DIR__);
# This is where everyour files are stored
define('MEDIA_DIR',__DIR__.'/media/');
/*
** #description This is just a link builder, there may be some functionality you could use here
** #param $path [string] Relative path
** #param $pathStr [string] Absolute path
** #param $append [string | empty] This is just append to whatever page processes this script
*/
function createLinks($path,$pathStr,$append = '/index.php')
{
# Used for the link
$url = SITE_URL.$append;
# Explodes relative path
$arr = array_filter(explode('/',$path));
# Loop through to create break crumb
foreach($arr as $dir) {
$pathStr .= '/'.$dir;
$new[] = '/'.$dir.'';
}
# Return final bread crumb
return implode('',$new);
}
# Decodes the path name, you should probably do a more secure encryption / decription method
function getPathFromRequest($path)
{
return base64_decode(urldecode($path));
}
# Set base absolute path
$core = MEDIA_DIR;
# Process the absolute path
if(!empty($_GET['goto'])) {
$base = str_replace('//','/',getPathFromRequest($_GET['goto']));
if(is_dir($base))
$base = $base.'/';
}
else
$base = $core;
# If is a directory, recurse and show the bread crumbs
if(is_dir($base)){
$skip = RecursiveDirectoryIterator::SKIP_DOTS;
$sFirst = RecursiveIteratorIterator::SELF_FIRST;
$dir = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($base,$skip),$sFirst);
# Loop through the file paths
foreach($dir as $file) {
$fname = $file->__toString();
if(is_file($fname)) {
$abs = str_replace($base,'',$fname);
$useType = (!empty($_GET['goto']))? $base : $core;
echo createLinks($abs,$useType).'<br />';
}
}
}
else {
# Redirect to file if is a file
if(is_file($base)) {
header('Location: '.SITE_URL.'/'.str_replace(BASE_DIR,'',$base));
exit;
}
}
Base view in the browser gives you something like (this is just from a directory I have):
/css/form.css
/css/styles.css
/images/bkg/bkg_white.png
/images/bkg/row_grad01.png
Then html source would look like:
/css/form.css<br />
/css/styles.css<br />
/images/bkg/bkg_white.png<br />
/images/bkg/row_grad01.png<br />
If you were to click the bkg in the 3rd or 4th link, it would display:
/bkg_white.png
/row_grad01.png
Clicking one of those would open the file in the browser. Anyway, you might be interested in some of this, all of it, or none of it! It's hard to guess with out seeing what you currently have vs what you are trying to achieve.

Magento "Headers already sent" after Upgrade

I've searched the web for days but can't find a solution. I upgraded Magento from 1.5 to 1.9 and everything works fine. Except the checkout. On the last step it gets stuck every single time on "submitting order information".
System log says the following (but a minute before the error occurs. In the stuck position I don't get any error)
2016-08-07T22:23:16+00:00 DEBUG (7): HEADERS ALREADY SENT: <pre>[0] /var/www/html/app/code/core/Mage/Core/Controller/Response/Http.php:52
[1] /var/www/html/lib/Zend/Controller/Response/Abstract.php:768
[2] /var/www/html/app/code/core/Mage/Core/Controller/Response/Http.php:84
[3] /var/www/html/app/code/core/Mage/Core/Controller/Varien/Front.php:184
[4] /var/www/html/app/code/core/Mage/Core/Model/App.php:365
[5] /var/www/html/app/Mage.php:684
[6] /var/www/html/index.php:83</pre>
Console on the checkout site:
VK. Startup (background is ready)
prototype.js:5557 Uncaught TypeError: Cannot read property 'get' of undefined_createResponder # prototype.js:5557observe # prototype.js:5636(anonymous function) # (index):896
prototype.js:5557 Uncaught TypeError: Cannot read property 'get' of undefined_createResponder # prototype.js:5557observe # prototype.js:5636(anonymous function) # (index):1033
(index):1 Mixed Content: The page at 'https://www.owndomain.com/checkout/onepage/' was loaded over HTTPS, but requested an insecure script 'http://www.googleadservices.com/pagead/conversion.js'. This request has been blocked; the content must be served over HTTPS.
content.js:37 UA. Wait for background...
Does anybody have an additional idea? I have edited all template files with the formkey tag.
Edit:
The code of the found file:
if (empty ($_POST)) {
header("Location: " . $_SESSION['back_url']);
$this->_redirect(str_replace(Mage::getBaseUrl(), '', $_SESSION['back_url']));
}
$formData = $this->getRequest()->getPost('super_attribute');
$product_id = $this->getRequest()->getPost('pro_id');
$options = $this->getRequest()->getPost('options');
$params = $this->getRequest()->getParams();
//mage::log($params);
$url = $this->getRequest()->getPost('url');
$qty = $this->getRequest()->getPost('qty');
$type = $this->getRequest()->getPost('type');
if (!isset($qty))
$qty = 1;
if (isset($product_id)) {
try {
$request = Mage::app()->getRequest();
$product = Mage::getModel('catalog/product')->load($product_id);
$session = Mage::getSingleton('core/session', array('name' => 'frontend'));
$cart = Mage::helper('checkout/cart')->getCart();
/*
if (isset($formData)){
$arr = array(
'qty' => $qty,
'super_attribute' => $formData,
'options' => $options
);
$cart->addProduct($product, $arr);}
else
$cart->addProduct($product, $qty);
*/
$cart->addProduct($product, $params);
$session->setLastAddedProductId($product->getId());
$session->setCartWasUpdated(true);
$cart->save();
$_cart = Mage::helper('checkout/cart')->getCart();
$_cartcount = 0;
$_cartsubtotal = 0;
$items = $_cart->getItems();
$_SESSION['back_url'] = $url;
$result = $this->getLayout()->createBlock('checkout/cart_sidebar')->setTemplate('ajaxcart/cart/sidebar.phtml')
->addItemRender('simple', 'checkout/cart_item_renderer', 'checkout/cart/sidebar/default.phtml')
->addItemRender('configurable', 'checkout/cart_item_renderer_configurable', 'checkout/cart/sidebar/default.phtml')
->addItemRender('grouped', 'checkout/cart_item_renderer_grouped', 'checkout/cart/sidebar/default.phtml')
->toHtml();
echo $result;
} catch (Exception $e) {
echo 1;
}
} else {
echo 0;
Best,
IT0055

Simultaneous connections on GTK Broadway backed

I'm new to GTK Broadway and I succeeded creating an instance of gedit running under it. I can access the interface using any browser and http://localhost:8080 but I can't open two different tabs on the same address. When I try to connect from another tab, the previous disconnects.
What I wish to do is to create a server running a GTK application on one side and serving this application for multiple users, they will be able to visualize the GUI and what's happening but only one user will be able to interact (I'm working on it).
Edit: I thought about a workaround where the server loads the page with the Websockets and the HTML5 Canvas then acts like a proxy and serves the same content to the clients, the proxy would then handle the incoming input from the clients (and manage the parallel connections). Is it technically possible?
Thanks in advance.
I found this on waybackmachine:
Transparent Proxy for Broadway ( Gtk3 / HTML5 backend )
Fortunately the source code could be recovered on waybackmachine:
#!/usr/bin/perl
#
# Peteris Krumins (peter#catonmat.net)
# http://www.catonmat.net -- good coders code, great reuse
#
# A simple TCP proxy that implements IP-based access control
# Currently the ports are hard-coded, and it proxies
# 0.0.0.0:1080 to localhost:55555.
#
# Written for the article "Turn any Linux computer into SOCKS5
# proxy in one command," which can be read here:
#
# http://www.catonmat.net/blog/linux-socks5-proxy
#
##############################################################
#
# Modified by Dan Kasak ( d.j.kasak.dk#gmail.com )
# http://tesla.duckdns.org
#
# Added some hacks for proxying based on the value in a cookie,
# as a proof-of-concept transparent proxy for Gtk+ / broadway
use warnings;
use strict;
use Data::Dumper;
use IO::Socket;
use IO::Select;
my $ioset = IO::Select->new;
my %socket_map;
my $debug = 0;
sub new_server {
my ($host, $port) = #_;
my $server = IO::Socket::INET->new(
LocalAddr => $host,
LocalPort => $port,
ReuseAddr => 1,
Listen => 100
) || die "Unable to listen on $host:$port: $!";
}
sub close_connection {
my $client = shift;
my $client_ip = client_ip($client);
my $remote = $socket_map{$client};
foreach my $socket ( $client , $remote ) {
if ( ref $socket eq 'ConnectionFuture' ) {
$socket->disconnect;
} else {
$ioset->remove( $socket );
}
}
delete $socket_map{$client};
delete $socket_map{$remote};
$client->close;
$remote->close;
print "Connection from $client_ip closed.\n" if $debug;
}
sub client_ip {
my $client = shift;
return inet_ntoa($client->sockaddr);
}
print "Starting a server on 0.0.0.0:10666\n";
my $server = new_server('0.0.0.0', 10666);
$ioset->add($server);
while (1) {
for my $socket ($ioset->can_read) {
if ($socket == $server) { # $socket is what we're reading from ... $server is our listener. if socket == server, we're reading, and need to create a new target
ConnectionFuture->new( $server );
}
else {
next unless exists $socket_map{$socket};
my $remote = $socket_map{$socket};
my $buffer;
my $read = $socket->sysread($buffer, 4096);
if ($read) {
$remote->syswrite($buffer);
}
else {
close_connection($socket);
}
}
}
}
package ConnectionFuture;
use HTTP::Request;
sub new {
my ( $class, $server ) = #_;
my $self = {
server => $server
};
bless $self, $class;
$self->{client} = $self->{server}->accept;
$socket_map{ $self->{client} } = $self;
$socket_map{ $self->{server} } = $self->{client};
$ioset->add( $self->{client} );
return $self;
}
sub syswrite {
my ( $self, $buffer ) = #_;
if ( ! exists $self->{remote} ) {
my $host = 'localhost';
my $request = HTTP::Request->parse( $buffer );
my $headers = $request->headers;
my $cookies = $headers->{cookie};
print "Cookies:\n" . $cookies . "\n";
my $port;
if ( $cookies =~ /port=(\w*)/ ) {
$port = $1;
} elsif ( $cookies = 'cookie1=test' ) {
$port = 10000;
}
if ( $port ) {
$self->{remote} = IO::Socket::INET->new(
PeerAddr => $host
, PeerPort => $port
) || die "Unable to connect to $host:$port: $!";
$socket_map{ $self->{remote} } = $self->{client};
$ioset->add( $self->{remote} );
}
}
if ( $self->{remote} ) {
$self->{remote}->syswrite( $buffer );
}
}
sub disconnect {
my $self = shift;
$ioset->remove( $self->{client} );
$ioset->remove( $self->{remote} );
}
sub close {
my $self = shift;
$self->{client}->close;
if ( $self->{remote} ) {
$self->{remote}->close;
}
}
1;
Hope it helps
Edited: Fortunately Dan created a github repo, just found it: https://github.com/dankasak/broadway_proxy

Server returning empty response on ajax call probably routing error

I have a simple search input that i want to POST data with an ajax call on click out using jquery on blur. The ajax call is the following code:
$(".ajax").blur(function(){
$.ajax({
type: "POST",
url : "adminController.php",
data : {
searchInput: $(this).val()
},
dataType : "json",
context : $("#searchResults"),
success: function(data)
{
$(this).text(data);
alert(data);
},
error: function (xhr,textStatus,err)
{
console.log("readyState: " + xhr.readyState);
console.log("responseText: "+ xhr.responseText);
console.log("status: " + xhr.status);
console.log("text status: " + textStatus);
console.log("error: " + err);
}
});
});
When the post call is made, i get a redirect (302 found) to my custom 404 page. However, the adminController.php is located correctly when i checked in chrome's console. If I remove the redirecting condition manually I get a 200 ok server response but with empty response. In my adminController.php I have the following code(code after the return in the constructor is not really necessary here): `
class adminController
{
private $postData;
private $errorMessage;
public function __construct()
{
$this->postData=array();
$this->errorMessage='';
session_start();
if(sessionClass::get('Username')== false || loginModel::checkAdmin()== false)
{
header('Location: /Costing/login');
exit();
}
if(($_POST)) {
//$this->handlePostData(); I entered the following
simple code to make sure my json return array is not the issue for my problems
$cars=array("Volvo","BMW","Toyota");
return json_encode($cars);
}
}
public function __destruct(){ }
public function displayPage()
{
$admin = new adminModel();
$nonAdminUsers = $admin->databaseInteract(sqlQueries::getNonAdmin());
$adminView = new adminView();
$adminView = $adminView->createAdminPage($nonAdminUsers);
echo $adminView;
}
private function handlePostData()
{
foreach($_POST as $key => $value)
{
if(!empty($value)) {
$sanitized_value = filter_var($value,FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$sanitized_value = filter_var($sanitized_value,FILTER_SANITIZE_STRING);
$sanitized_value = filter_var($sanitized_value,FILTER_SANITIZE_MAGIC_QUOTES);
$this->postData[$key] = $sanitized_value;
}
else
$this->errorMessage.= $key.' is empty.';
}
if(!empty($this->postData))
{
$admin = new adminModel();
foreach ($this->postData as $key => $value)
{
if($key == 'Seller' || $key == 'Customer' || $key == 'Product')
{
$adminQuery = sqlQueries::searchOrders();
$tempArray['field']=$key;
$tempArray['value']=$value;
$result = $admin->databaseInteract($adminQuery,$tempArray);
$adminView = new adminView($result);
}
else if($key == 'nonAdmins')
{
$adminQuery = sqlQueries::promoteToAdmin();
$tempArray['Username']=$value;
$result = $admin->databaseInteract($adminQuery,$tempArray);
$adminView = new adminView();
$adminView->displayErrors($result);
}
else
{
$tempArray['value']=$value;
$adminQuery = sqlQueries::setConstants($key);
$result = $admin->databaseInteract($adminQuery, $tempArray);
$adminView = new adminView();
$adminView->displayErrors($result);
}
}
}
}
}`
what I am trying to achieve is instead of having a submit button, just post everything on blur and dump the results on the #searchResults div.
I think the problem has to do with my router class. The redirect in the first place on a post request did not seem healthy, so I will paste the code of my router and bootstrap files.
bootstrap.php:
<?php
/**
* #param $className
* bootstrap file for autoload function and router calling
*
*/
function my_autoloader($class) {
if (file_exists(realpath(__DIR__). DIRECTORY_SEPARATOR . $class . '.php'))
include realpath(__DIR__). DIRECTORY_SEPARATOR . $class . '.php';
else if (file_exists(realpath(__DIR__). '\\Classes\\' . $class . '.php'))
include realpath(__DIR__). '\\Classes\\' . $class . '.php';
else if (file_exists(realpath(__DIR__). '\\Classes\\Controller\\' . $class. '.php'))
include realpath(__DIR__). '\\Classes\\Controller\\' . $class. '.php';
else if (file_exists(realpath(__DIR__). '\\Classes\\Model\\' . $class. '.php'))
include realpath(__DIR__). '\\Classes\\Model\\' . $class. '.php';
else if (file_exists(realpath(__DIR__). '\\Classes\\View\\' . $class. '.php'))
include realpath(__DIR__). '\\Classes\\View\\' . $class. '.php';
else
{
$error = new errorController('classNotFound');
}
}
spl_autoload_register('my_autoloader');
$routes = new router();
$routes->add('/home', 'homeController');
$routes->add('/login', 'loginController');
$routes->add('/register', 'registerController');
$routes->add('/index.php', 'homeController');
$routes->add('/invoicing','invoiceController');
$routes->add('/admin','adminController');
$routes->add('/404','errorController');
$routes->submit();
and router.php
class router
{
private $routes = array();
private $method = array();
public function __construct(){}
public function __destruct(){}
/**
* Adds available routes to an array with their methods (strings, anonymous functions, etc.)
*/
public function add($uri, $method = null)
{
$this->routes[] =trim($uri,'/');
if ($method!= null)
$this->method[]= $method;
else
throw new exception();
}
/**
* Matches routes to controller actions.
*/
public function submit()
{
$count=0;
if(isset($_GET['uri'])) {
$uri = $_GET['uri'];
}
else
$uri = '/home';
foreach( $this->routes as $key => $value)
{
if (preg_match("#^$value$#", $uri))
{
if (is_string($this->method[$key]))
{
$userMethod = $this->method[$key];
$display = new $userMethod();
$display->displayPage();
}
else call_user_func($this->method[$key]);
}
else $count++;
}
if($count == sizeof($this->routes))
{
header ('Location: /Costing/404');
exit();
}
}
}
last but not least, my .htaccess
ReWriteEngine On
ReWriteRule ^public/ - [L,NC]
ReWriteBase /Costing/
RewriteCond %(REQUEST_FILENAME) !-f
RewriteCond %(REQUEST_FILENAME) !-d
RewriteRule ^(.+)$ index.php?uri=$1 [QSA,L]
Edit 1: I'm using Xampp and my domain is localhost/Costing/. I tried changing the url to Costing/admin so i got rid of the redirect. But still, unless I remove the dataType = "json" I get empty response back (if i remove json i get back the full html page with the scripts, aka adminView file). Using MVC architecture
Edit 2: I found a way around. Seems like i was right and the routing is causing the issue. So I created an ajaxHandler.php file and placed it outside the Costing directory and edited the ajax url like this: "http:// localhost/ajaxHandler.php". I get a valid response from this file but I can't really work with a file outside the root directory. So I need to change the htaccess. Any ideas are welcome
I found the solution myself, the problem was on htaccess. Basically the lines
RewriteCond %(REQUEST_FILENAME) !-f
RewriteCond %(REQUEST_FILENAME) !-d
Did not allow my urls to ask for files or directories, so anything ending on .php was forbidden. I had to create a folder and place my ajax handling file in there and add an exception like so:
ReWriteRule ^ajax/ - [L,NC]
Now the htaccess allows calls to this file and I can use it properly. I'm not sure this is secure though and I still have no idea why the url Costing/admin didn't work as marian correctly noted. If anyone finds out why it would be great
Aside from your bootstrap.php I do not see any actual executing php code (i.e. index.php).
For a single server side entry point, as it looks like you are working towards, you will want all requests to end up on the entry point with the full route request intact. From this entry point, you can then call the router which will then call the adminController class.
The order of operation then becomes:
Ajax request sent to /admin
Request is directed to the index.php
Index.php fires the bootstrap to load up the autoloader
Index.php calls the router with the incoming path
Router calls the actual AdminController class.
The empty response is likely because the server is only executing the adminController.php which does not appear to echo out anything (the class is never initialized in just that file).

Categories

Resources