Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle JSON post and get requests #382

Merged
merged 22 commits into from
May 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
0451363
set autoload namespace
mudhoney May 28, 2024
daa083d
request params implementation and index.php to handle exceptions
mudhoney May 28, 2024
0ee7eb0
tests for request with mockphpstream handler
mudhoney May 28, 2024
3d2fc8b
add content-type header to cors allowed headers
mudhoney May 28, 2024
efd5616
client states now using JSON post
mudhoney May 28, 2024
26203e2
default cors allowed methods, and remove pr/pre function added before
mudhoney May 28, 2024
b5f2d85
mark some of the tests as integration tests, will be handled later
mudhoney May 28, 2024
d9e9176
Add PUT, PATCH to acam
dgarciabriseno May 28, 2024
8f1784d
fix conflict when rebasing
mudhoney May 28, 2024
c8ccf97
Print container logs
dgarciabriseno May 22, 2024
1a3cced
always print docker logs
dgarciabriseno May 22, 2024
626589a
Update CI
dgarciabriseno May 28, 2024
c811d30
fix more conflict php.yml
mudhoney May 28, 2024
a9b0b0f
set autoload namespace
mudhoney May 28, 2024
ba19c8f
request params implementation and index.php to handle exceptions
mudhoney May 28, 2024
1f525cd
tests for request with mockphpstream handler
mudhoney May 28, 2024
247b33f
add content-type header to cors allowed headers
mudhoney May 28, 2024
5ff8bc8
client states now using JSON post
mudhoney May 28, 2024
bbb1a6d
default cors allowed methods, and remove pr/pre function added before
mudhoney May 28, 2024
c8f3994
mark some of the tests as integration tests, will be handled later
mudhoney May 28, 2024
515e318
fix merge conflict
mudhoney May 28, 2024
046eb8c
fix screenshot thing with observation time
mudhoney May 29, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@
"url": "https://github.com/dgarciabriseno/device-detector.git"
}
],
"autoload": {
"psr-4": {
"Helioviewer\\Api\\": "src/"
}
},
"require": {
"helioviewer/event-interface": "v0.1.0",
"matomo/device-detector": "dev-master"
Expand Down
30 changes: 21 additions & 9 deletions docroot/index.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<?php

/**
* Helioviewer Web Server
*
Expand All @@ -21,31 +22,42 @@
* web-client install to connect with)
* = Add getPlugins method to JHelioviewer module (empty function for now)
*/
require_once __DIR__.'/../vendor/autoload.php';
require_once '../src/Config.php';
require_once '../src/Helper/ErrorHandler.php';

use Helioviewer\Api\Request\RequestParams;
use Helioviewer\Api\Request\RequestException;

$config = new Config('../settings/Config.ini');
date_default_timezone_set('UTC');
register_shutdown_function('shutdownFunction');


if ( array_key_exists('docs', $_GET) ) {
printAPIDocs();
exit;
}

try {
// Parse request and its variables
$params = RequestParams::collect();
} catch (RequestException $re) {

// For now, accept GET or POST requests for any API endpoint
if ( isset($_REQUEST['action']) ) {
if ($_SERVER['REQUEST_METHOD'] == 'GET') {
$params = $_GET;
}
else {
$params = $_POST;
}
// Set the content type to JSON
header('Content-Type: application/json');

// Set the HTTP status code
http_response_code($re->getCode());

echo json_encode([
'success' => false,
'message' => $re->getMessage(),
]);
exit;
}



// Redirect to API Documentation if no API request is being made.
if ( !isset($params) || !loadModule($params) ) {
header('Location: '.HV_WEB_ROOT_URL.'/docs/v2/');
Expand Down
2 changes: 1 addition & 1 deletion settings/Config.Example.ini
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ client_url = http://helioviewer.org

; CORS
;acao_url[] = ''
acam = 'GET'
acam = 'GET, POST, PUT, PATCH, OPTIONS'

[executables]
; Location of the kdu_merge binary to be used during JPX image generation.
Expand Down
2 changes: 2 additions & 0 deletions src/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ public function __construct($file) {

header("Access-Control-Allow-Origin: ".$_SERVER['HTTP_ORIGIN']);
header("Access-Control-Allow-Methods: ".$this->config['acam']);
header("Access-Control-Allow-Headers: Content-Type");

}

}
Expand Down
2 changes: 1 addition & 1 deletion src/Helper/EventInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ public static function GetEvents(DateTimeInterface $start, DateInterval $length,
return Events::GetFromSource($sources, $start, $length, $observationTime);
}
}
}
}
6 changes: 4 additions & 2 deletions src/Image/Composite/HelioviewerCompositeImage.php
Original file line number Diff line number Diff line change
Expand Up @@ -611,9 +611,11 @@ private function _addEventLayer($imagickImage) {
// Collect events from all data sources.
$hek = new Event_HEKAdapter();
$event_categories = $hek->getNormalizedEvents($this->date, Array());
$startDate = new DateTimeImmutable($this->date);

$observationTime = new DateTimeImmutable($this->date);
$startDate = $observationTime->sub(new DateInterval("PT12H"));
$length = new DateInterval("P1D");
$event_categories = array_merge($event_categories, Helper_EventInterface::GetEvents($startDate, $length, $this->date));
$event_categories = array_merge($event_categories, Helper_EventInterface::GetEvents($startDate, $length, $observationTime));

// Lay down all relevant event REGIONS first
$allowedFRMs = $this->events->toArray();
Expand Down
4 changes: 2 additions & 2 deletions src/Module/WebClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -653,7 +653,7 @@ public function saveWebClientState() {

try {

$state_key = $client_state->upsert($this->_params['state']);
$state_key = $client_state->upsert($this->_params['json']);

return $this->_sendResponse(200, 'OK', $state_key);

Expand Down Expand Up @@ -1508,7 +1508,7 @@ public function validate() {

case 'saveWebClientState':
$expected = array(
'required' => array('state'),
'required' => array('json'),
);
break;

Expand Down
21 changes: 21 additions & 0 deletions src/Request/RequestException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php declare(strict_types=1);

namespace Helioviewer\Api\Request;

/**
* Collect our request parameters and merge them
*/
class RequestException extends \Exception
{
/**
* Construct request exception exception.
* @param string $message exception message to throw.
* @param int $code The Exception code.
*/
public function __construct(string $message = "", int $code = 0, ?Throwable $previous = null)
{
parent::__construct($message, $code, $previous);
}
}


68 changes: 68 additions & 0 deletions src/Request/RequestParams.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php declare(strict_types=1);

namespace Helioviewer\Api\Request;
/**
* Collect our request parameters and merge them
*/
class RequestParams
{
private array $params = [];

public function __construct()
{
// Initialize with GET parameters
$this->params = $_GET;

// Handle POST PUT PATCH requests
if (in_array($_SERVER['REQUEST_METHOD'], ['POST', 'PUT', 'PATCH'])) {

// Merge POST parameters
$this->params = array_merge($this->params, $_POST);

// Determine the content type of the request
$content_type = $_SERVER['CONTENT_TYPE'] ?? '';

// If the content type is JSON, handle JSON input
if('application/json' === $content_type) {
$this->params['json'] = $this->handleJsonInput();
}

}

}

/**
* A static function to collect request params
*/
public static function collect(): array
{
$request_params = new RequestParams();
return $request_params->getParams();
}


/**
* Handle JSON input from the request body
*/
protected function handleJsonInput() : mixed
{
$json = file_get_contents('php://input');
$json_data = json_decode($json, true);

// Check for JSON parsing errors
if (json_last_error() !== JSON_ERROR_NONE) {
throw new RequestException(json_last_error_msg(), 400);
}

return $json_data;
}

/**
* Get params from request params
*/
public function getParams(): array
{
return $this->params;
}

}
7 changes: 6 additions & 1 deletion tests/unit_tests/movies/reQueueMovieTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ private function _markMovieAsProcessing($movie) {
* the movie is already there
*/
public function testRequeueMovie_MovieExists() {
$this->markTestSkipped("Need to fix this test");
$this->markTestSkipped("Integration Tests to be handled later");
// Queue the test movie
$result = $this->_queueTestMovie();
// Build the test movie
Expand All @@ -93,6 +93,7 @@ public function testRequeueMovie_MovieExists() {
* @runInSeparateProcess
*/
public function testRequeueMovie_Force() {
$this->markTestSkipped("Integration Tests to be handled later");
// Queue the test movie
$result = $this->_queueTestMovie();
// Build the test movie
Expand All @@ -114,6 +115,7 @@ public function testRequeueMovie_Force() {
* Helper function so the test can be run with both force = true & false
*/
public function _testRequeueMovie_MovieProcessing($force) {
$this->markTestSkipped("Integration Tests to be handled later");
// Queue the test movie
$result = $this->_queueTestMovie();
// Build the test movie
Expand Down Expand Up @@ -144,6 +146,7 @@ public function _testRequeueMovie_MovieProcessing($force) {
* @runInSeparateProcess
*/
public function testRequeueMovie_MovieProcessing() {
$this->markTestSkipped("Integration Tests to be handled later");
$this->_testRequeueMovie_MovieProcessing(false);
}

Expand All @@ -153,13 +156,15 @@ public function testRequeueMovie_MovieProcessing() {
* @runInSeparateProcess
*/
public function testRequeueMovie_MovieProcessing_Force() {
$this->markTestSkipped("Integration Tests to be handled later");
$this->_testRequeueMovie_MovieProcessing(true);
}

/**
* Issue #262 - When mp4 creation fails, movie can't be requeued
*/
public function testRequeueMovie_262() {
$this->markTestSkipped("Integration Tests to be handled later");
// Queue the test movie
$result = $this->_queueTestMovie();
// Get the movie ID as an integer
Expand Down
68 changes: 68 additions & 0 deletions tests/unit_tests/request/MockPhpStream.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php

class MockPhpStream {

protected $index = 0;
protected $length = null;
protected $data = 'hello world';

public $context;

function __construct(){
if(file_exists($this->buffer_filename())){
$this->data = file_get_contents($this->buffer_filename());
} else{
$this->data = '';
}

$this->index = 0;
$this->length = strlen($this->data);
}

protected function buffer_filename(){
return sys_get_temp_dir().'\php_input_temp.txt';
}

function stream_open($path, $mode, $options, &$opened_path)
{
return true;
}

function stream_close(){
}

function stream_stat(){
return [];
}

function stream_flush(){
return true;
}

function stream_read($count){
if(is_null($this->length) === TRUE){
$this->length = strlen($this->data);
}
$length = min($count, $this->length - $this->index);
$data = substr($this->data, $this->index);
$this->index = $this->index + $length;
return $data;
}

function stream_eof(){
return ($this->index >= $this->length ? TRUE : FALSE);
}

function stream_write($data){
return file_put_contents($this->buffer_filename(), $data);
}

function unlink(){
if(file_exists($this->buffer_filename())){
unlink($this->buffer_filename());
}
$this->data = '';
$this->index = 0;
$this->length = 0;
}
}
Loading
Loading