From dc780087215127b8d17cb196935802d15a3dee27 Mon Sep 17 00:00:00 2001 From: Sven Luethi Date: Mon, 1 Jul 2024 21:29:06 +0200 Subject: [PATCH] new file: software/app.php new file: software/debug.php new file: software/module/report/routes.php new file: software/module/update/routes.php new file: software/public/index.php new file: software/router.php --- software/app.php | 10 +++ software/debug.php | 46 +++++++++++ software/module/report/routes.php | 15 ++++ software/module/update/routes.php | 32 ++++++++ software/public/index.php | 4 + software/router.php | 126 ++++++++++++++++++++++++++++++ 6 files changed, 233 insertions(+) create mode 100644 software/app.php create mode 100644 software/debug.php create mode 100644 software/module/report/routes.php create mode 100644 software/module/update/routes.php create mode 100644 software/public/index.php create mode 100644 software/router.php diff --git a/software/app.php b/software/app.php new file mode 100644 index 0000000..d041e83 --- /dev/null +++ b/software/app.php @@ -0,0 +1,10 @@ + $value) { + if (preg_match('/^HTTP_/',$name)) { + // convert HTTP_HEADER_NAME to Header-Name + $name = strtr(substr($name,5),'_',' '); + $name = ucwords(strtolower($name)); + $name = strtr($name,' ','-'); + + // add to list + $headerList[$name] = $value; + } + } + + return $headerList; + + return []; + } + + public static function execute($targetFile) { + $data = sprintf( + "%s %s %s\n\nHTTP headers:\n", + $_SERVER['REQUEST_METHOD'], + $_SERVER['REQUEST_URI'], + $_SERVER['SERVER_PROTOCOL'] + ); + foreach (self::getHeaderList() as $name => $value) { + $data .= $name . ': ' . $value . "\n"; + } + + $data .= "\nRequest body:\n"; + + file_put_contents( + $targetFile, + $data . file_get_contents('php://input') . "\n" + ); + + //echo("Done!\n\n"); + return true; + } + +} + diff --git a/software/module/report/routes.php b/software/module/report/routes.php new file mode 100644 index 0000000..f23febb --- /dev/null +++ b/software/module/report/routes.php @@ -0,0 +1,15 @@ +get('/report', function($req) { + echo "Nothing to see here!\n"; + http_response_code(200); +}); + +$router->post('/report', function($req) { + echo 'body:' . var_dump($req->getBody()) . "\n"; + DumpHTTPRequestToFile::execute("/tmp/out.txt"); + http_response_code(200); +}); + diff --git a/software/module/update/routes.php b/software/module/update/routes.php new file mode 100644 index 0000000..1d75e3c --- /dev/null +++ b/software/module/update/routes.php @@ -0,0 +1,32 @@ +get('/favicon.ico', function() { + http_response_code(404); +}); + +$router->get('/update', function() { + //(new DumpHTTPRequestToFile)->execute( __DIR__ . '/dumprequest.txt'); + + if ( $_SERVER['HTTP_USER_AGENT'] == 'ESP8266-http-Update' && isset($_SERVER['HTTP_X_ESP8266_SKETCH_MD5']) ) { + $user_agent = $_SERVER['HTTP_USER_AGENT']; + $curr_firmware_md5 = $_SERVER['HTTP_X_ESP8266_SKETCH_MD5']; + $firmware_file = __DIR__ . '/firmware.bin'; + $firmware_md5 = md5_file($firmware_file); + echo "USER_AGENT -> ESP8266-http-Update\n"; + echo 'X_ESP8266_SKETCH_MD5 -> ' . $_SERVER['HTTP_X_ESP8266_SKETCH_MD5'] . "\n"; + echo 'MD5 file hash of ' . $firmware_file . ': ' . $firmware_md5; + if ( $curr_firmware_md5 == $firmware_md5 ) { + http_response_code(204); + } + else { + $fwdata = file_get_contents($firmware_file); + header('Content-Length:' . strlen($fwdata)); + echo $fwdata; + http_response_code(200); + } + return; + } + + http_response_code(400); +}); + diff --git a/software/public/index.php b/software/public/index.php new file mode 100644 index 0000000..0c565c8 --- /dev/null +++ b/software/public/index.php @@ -0,0 +1,4 @@ +request = $request; + } + + function __call($name, $args) + { + list($route, $method) = $args; + + if(!in_array(strtoupper($name), $this->supportedHttpMethods)) + { + $this->invalidMethodHandler(); + } + + $this->{strtolower($name)}[$this->formatRoute($route)] = $method; + } + + /** + * Removes trailing forward slashes from the right of the route. + * @param route (string) + */ + private function formatRoute($route) + { + $result = rtrim($route, '/'); + if ($result === '') + { + return '/'; + } + return $result; + } + + private function invalidMethodHandler() + { + header("{$this->request->serverProtocol} 405 Method Not Allowed"); + } + + private function defaultRequestHandler() + { + header("{$this->request->serverProtocol} 404 Not Found"); + } + + /** + * Resolves a route + */ + function resolve() + { + $methodDictionary = $this->{strtolower($this->request->requestMethod)}; + $formatedRoute = $this->formatRoute($this->request->requestUri); + $method = $methodDictionary[$formatedRoute]; + + if(is_null($method)) + { + $this->defaultRequestHandler(); + return; + } + + echo call_user_func_array($method, array($this->request)); + } + + function __destruct() + { + $this->resolve(); + } +} + +interface IRequest +{ + public function getBody(); +} + +class Request implements IRequest +{ + function __construct() + { + $this->bootstrapSelf(); + } + + private function bootstrapSelf() + { + foreach($_SERVER as $key => $value) + { + $this->{$this->toCamelCase($key)} = $value; + } + } + + private function toCamelCase($string) + { + $result = strtolower($string); + + preg_match_all('/_[a-z]/', $result, $matches); + + foreach($matches[0] as $match) + { + $c = str_replace('_', '', strtoupper($match)); + $result = str_replace($match, $c, $result); + } + + return $result; + } + + public function getBody() + { + if($this->requestMethod === "GET") { return; } + + if($this->requestMethod === "POST") + { + $body = array(); + foreach($_POST as $key => $value) + { + $body[$key] = filter_input(INPUT_POST, $key, FILTER_SANITIZE_SPECIAL_CHARS); + } + + return $body; + } + } +} +