public function testFragmentsOverride()
 {
     $negotiator = new PjaxResponseNegotiator(array('alpha' => function () {
         return 'alpha response';
     }, 'beta' => function () {
         return 'beta response';
     }));
     $request = new SS_HTTPRequest('GET', '/');
     $request->addHeader('X-Pjax', 'alpha');
     $request->addHeader('Accept', 'text/json');
     $response = $negotiator->setFragmentOverride(array('beta'))->respond($request);
     $json = json_decode($response->getBody());
     $this->assertFalse(isset($json->alpha));
     $this->assertObjectHasAttribute('beta', $json);
 }
 protected function genRequest($accept = null, $method = 'GET')
 {
     $req = new SS_HTTPRequest($method, '/');
     if ($accept) {
         $req->addHeader('Accept', $accept);
     }
     return $req;
 }
	function testSelectsFragmentByHeader() {
		$negotiator = new PjaxResponseNegotiator(array(
			'default' => function() {return 'default response';},
			'myfragment' => function() {return 'myfragment response';},
		));
		$request = new SS_HTTPRequest('GET', '/');
		$request->addHeader('X-Pjax', 'myfragment');
		$this->assertEquals('myfragment response', $negotiator->respond($request));
	}
 public function testIsAjax()
 {
     $req = new SS_HTTPRequest('GET', '/', array('ajax' => 0));
     $this->assertFalse($req->isAjax());
     $req = new SS_HTTPRequest('GET', '/', array('ajax' => 1));
     $this->assertTrue($req->isAjax());
     $req = new SS_HTTPRequest('GET', '/');
     $req->addHeader('X-Requested-With', 'XMLHttpRequest');
     $this->assertTrue($req->isAjax());
 }
 protected function genRequest($accept = null, $body = '')
 {
     $req = new SS_HTTPRequest('POST', '/');
     if ($accept) {
         $req->addHeader('Content-Type', $accept);
     }
     if ($body) {
         $req->setBody($body);
     }
     return $req;
 }
 /**
  * Test a URL request, returning a response object. This method is the counterpart of
  * Director::direct() that is used in functional testing. It will execute the URL given, and
  * return the result as an SS_HTTPResponse object.
  *
  * @uses getControllerForURL() The rule-lookup logic is handled by this.
  * @uses Controller::run() Handles the page logic for a Director::direct() call.
  *
  * @param string $url The URL to visit.
  * @param array $postVars The $_POST & $_FILES variables.
  * @param array|Session $session The {@link Session} object representing the current session.
  * By passing the same object to multiple  calls of Director::test(), you can simulate a persisted
  * session.
  * @param string $httpMethod The HTTP method, such as GET or POST.  It will default to POST if
  * postVars is set, GET otherwise. Overwritten by $postVars['_method'] if present.
  * @param string $body The HTTP body.
  * @param array $headers HTTP headers with key-value pairs.
  * @param array|Cookie_Backend $cookies to populate $_COOKIE.
  * @param HTTP_Request $request The {@see HTTP_Request} object generated as a part of this request.
  *
  * @return SS_HTTPResponse
  *
  * @throws SS_HTTPResponse_Exception
  */
 public static function test($url, $postVars = null, $session = array(), $httpMethod = null, $body = null, $headers = array(), $cookies = array(), &$request = null)
 {
     Config::nest();
     Injector::nest();
     // These are needed so that calling Director::test() does not muck with whoever is calling it.
     // Really, it's some inappropriate coupling and should be resolved by making less use of statics.
     $oldReadingMode = Versioned::get_reading_mode();
     $getVars = array();
     if (!$httpMethod) {
         $httpMethod = $postVars || is_array($postVars) ? "POST" : "GET";
     }
     if (!$session) {
         $session = Injector::inst()->create('Session', array());
     }
     $cookieJar = $cookies instanceof Cookie_Backend ? $cookies : Injector::inst()->createWithArgs('Cookie_Backend', array($cookies ?: array()));
     // Back up the current values of the superglobals
     $existingRequestVars = isset($_REQUEST) ? $_REQUEST : array();
     $existingGetVars = isset($_GET) ? $_GET : array();
     $existingPostVars = isset($_POST) ? $_POST : array();
     $existingSessionVars = isset($_SESSION) ? $_SESSION : array();
     $existingCookies = isset($_COOKIE) ? $_COOKIE : array();
     $existingServer = isset($_SERVER) ? $_SERVER : array();
     $existingRequirementsBackend = Requirements::backend();
     Config::inst()->update('Cookie', 'report_errors', false);
     Requirements::set_backend(Injector::inst()->create('Requirements_Backend'));
     // Set callback to invoke prior to return
     $onCleanup = function () use($existingRequestVars, $existingGetVars, $existingPostVars, $existingSessionVars, $existingCookies, $existingServer, $existingRequirementsBackend, $oldReadingMode) {
         // Restore the super globals
         $_REQUEST = $existingRequestVars;
         $_GET = $existingGetVars;
         $_POST = $existingPostVars;
         $_SESSION = $existingSessionVars;
         $_COOKIE = $existingCookies;
         $_SERVER = $existingServer;
         Requirements::set_backend($existingRequirementsBackend);
         // These are needed so that calling Director::test() does not muck with whoever is calling it.
         // Really, it's some inappropriate coupling and should be resolved by making less use of statics
         Versioned::set_reading_mode($oldReadingMode);
         Injector::unnest();
         // Restore old CookieJar, etc
         Config::unnest();
     };
     if (strpos($url, '#') !== false) {
         $url = substr($url, 0, strpos($url, '#'));
     }
     // Handle absolute URLs
     if (parse_url($url, PHP_URL_HOST)) {
         $bits = parse_url($url);
         // If a port is mentioned in the absolute URL, be sure to add that into the HTTP host
         if (isset($bits['port'])) {
             $_SERVER['HTTP_HOST'] = $bits['host'] . ':' . $bits['port'];
         } else {
             $_SERVER['HTTP_HOST'] = $bits['host'];
         }
     }
     // Ensure URL is properly made relative.
     // Example: url passed is "/ss31/my-page" (prefixed with BASE_URL), this should be changed to "my-page"
     $url = self::makeRelative($url);
     $urlWithQuerystring = $url;
     if (strpos($url, '?') !== false) {
         list($url, $getVarsEncoded) = explode('?', $url, 2);
         parse_str($getVarsEncoded, $getVars);
     }
     // Replace the super globals with appropriate test values
     $_REQUEST = ArrayLib::array_merge_recursive((array) $getVars, (array) $postVars);
     $_GET = (array) $getVars;
     $_POST = (array) $postVars;
     $_SESSION = $session ? $session->inst_getAll() : array();
     $_COOKIE = $cookieJar->getAll(false);
     Injector::inst()->registerService($cookieJar, 'Cookie_Backend');
     $_SERVER['REQUEST_URI'] = Director::baseURL() . $urlWithQuerystring;
     $request = new SS_HTTPRequest($httpMethod, $url, $getVars, $postVars, $body);
     if ($headers) {
         foreach ($headers as $k => $v) {
             $request->addHeader($k, $v);
         }
     }
     // Pre-request filtering
     // @see issue #2517
     $model = DataModel::inst();
     $output = Injector::inst()->get('RequestProcessor')->preRequest($request, $session, $model);
     if ($output === false) {
         $onCleanup();
         throw new SS_HTTPResponse_Exception(_t('Director.INVALID_REQUEST', 'Invalid request'), 400);
     }
     // TODO: Pass in the DataModel
     $result = Director::handleRequest($request, $session, $model);
     // Ensure that the result is an SS_HTTPResponse object
     if (is_string($result)) {
         if (substr($result, 0, 9) == 'redirect:') {
             $response = new SS_HTTPResponse();
             $response->redirect(substr($result, 9));
             $result = $response;
         } else {
             $result = new SS_HTTPResponse($result);
         }
     }
     $output = Injector::inst()->get('RequestProcessor')->postRequest($request, $result, $model);
     if ($output === false) {
         $onCleanup();
         throw new SS_HTTPResponse_Exception("Invalid response");
     }
     // Return valid response
     $onCleanup();
     return $result;
 }
示例#7
0
 /**
  * Test a URL request, returning a response object.
  * 
  * This method is the counterpart of Director::direct() that is used in functional testing.  It will execute the URL given,
  * 
  * @param string $url The URL to visit
  * @param array $postVars The $_POST & $_FILES variables
  * @param Session $session The {@link Session} object representing the current session.  By passing the same object to multiple
  * calls of Director::test(), you can simulate a persisted session.
  * @param string $httpMethod The HTTP method, such as GET or POST.  It will default to POST if postVars is set, GET otherwise.
  *  Overwritten by $postVars['_method'] if present.
  * @param string $body The HTTP body
  * @param array $headers HTTP headers with key-value pairs
  * @param array $cookies to populate $_COOKIE
  * @return SS_HTTPResponse
  * 
  * @uses getControllerForURL() The rule-lookup logic is handled by this.
  * @uses Controller::run() Controller::run() handles the page logic for a Director::direct() call.
  */
 static function test($url, $postVars = null, $session = null, $httpMethod = null, $body = null, $headers = null, $cookies = null)
 {
     // These are needed so that calling Director::test() doesnt muck with whoever is calling it.
     // Really, it's some inappropriate coupling and should be resolved by making less use of statics
     $oldStage = Versioned::current_stage();
     $getVars = array();
     if (!$httpMethod) {
         $httpMethod = $postVars || is_array($postVars) ? "POST" : "GET";
     }
     if (!$session) {
         $session = new Session(null);
     }
     // Back up the current values of the superglobals
     $existingRequestVars = isset($_REQUEST) ? $_REQUEST : array();
     $existingGetVars = isset($_GET) ? $_GET : array();
     $existingPostVars = isset($_POST) ? $_POST : array();
     $existingSessionVars = isset($_SESSION) ? $_SESSION : array();
     $existingCookies = isset($_COOKIE) ? $_COOKIE : array();
     $existingServer = isset($_SERVER) ? $_SERVER : array();
     $existingCookieReportErrors = Cookie::report_errors();
     $existingRequirementsBackend = Requirements::backend();
     Cookie::set_report_errors(false);
     Requirements::set_backend(new Requirements_Backend());
     // Handle absolute URLs
     if (@parse_url($url, PHP_URL_HOST) != '') {
         $bits = parse_url($url);
         $_SERVER['HTTP_HOST'] = $bits['host'];
         $url = Director::makeRelative($url);
     }
     $urlWithQuerystring = $url;
     if (strpos($url, '?') !== false) {
         list($url, $getVarsEncoded) = explode('?', $url, 2);
         parse_str($getVarsEncoded, $getVars);
     }
     // Replace the superglobals with appropriate test values
     $_REQUEST = array_merge((array) $getVars, (array) $postVars);
     $_GET = (array) $getVars;
     $_POST = (array) $postVars;
     $_SESSION = $session ? $session->inst_getAll() : array();
     $_COOKIE = (array) $cookies;
     $_SERVER['REQUEST_URI'] = Director::baseURL() . $urlWithQuerystring;
     $req = new SS_HTTPRequest($httpMethod, $url, $getVars, $postVars, $body);
     if ($headers) {
         foreach ($headers as $k => $v) {
             $req->addHeader($k, $v);
         }
     }
     $result = Director::handleRequest($req, $session);
     // Restore the superglobals
     $_REQUEST = $existingRequestVars;
     $_GET = $existingGetVars;
     $_POST = $existingPostVars;
     $_SESSION = $existingSessionVars;
     $_COOKIE = $existingCookies;
     $_SERVER = $existingServer;
     Cookie::set_report_errors($existingCookieReportErrors);
     Requirements::set_backend($existingRequirementsBackend);
     // These are needed so that calling Director::test() doesnt muck with whoever is calling it.
     // Really, it's some inappropriate coupling and should be resolved by making less use of statics
     Versioned::reading_stage($oldStage);
     return $result;
 }
 public function testCheckRequest()
 {
     $t = new SecurityToken();
     $n = $t->getName();
     $t->setValue(null);
     $r = new SS_HTTPRequest('GET', 'dummy', array($n => 'invalidtoken'));
     $this->assertFalse($t->checkRequest($r), 'Any token is invalid if no token is stored');
     $t->setValue(null);
     $r = new SS_HTTPRequest('GET', 'dummy', array($n => null));
     $this->assertFalse($t->checkRequest($r), 'NULL token is invalid if no token is stored');
     $t->setValue('mytoken');
     $r = new SS_HTTPRequest('GET', 'dummy', array($n => 'invalidtoken'));
     $this->assertFalse($t->checkRequest($r), 'Invalid token returns false');
     $t->setValue('mytoken');
     $r = new SS_HTTPRequest('GET', 'dummy', array($n => 'mytoken'));
     $this->assertTrue($t->checkRequest($r), 'Valid token returns true');
     $t->setValue('mytoken');
     $r = new SS_HTTPRequest('GET', 'dummy');
     $r->addHeader('X-Securityid', 'mytoken');
     $this->assertTrue($t->checkRequest($r), 'Valid token returns true');
     $t->setValue('mytoken');
     $r = new SS_HTTPRequest('GET', 'dummy');
     $r->addHeader('X-Securityid', 'wrongtoken');
     $this->assertFalse($t->checkRequest($r), 'Valid token returns true');
 }
<?php

require_once __DIR__ . '/../framework/core/Core.php';
$request = new SS_HTTPRequest($_SERVER['REQUEST_METHOD'], isset($_GET['url']) ? $_GET['url'] : '', $_GET);
$headers = Director::extract_request_headers($_SERVER);
foreach ($headers as $header => $value) {
    $request->addHeader($header, $value);
}
$container = Injector::inst();
$session = $container->create('Session', array());
if (Session::request_contains_session_id()) {
    $session->inst_start();
}
$container->get('RequestProcessor')->preRequest($request, $session, DataModel::inst());
require_once __DIR__ . '/../framework/main.php';
 /**
  * Checks authentication works with a generated token
  */
 public function testAuthenticate()
 {
     $member = Member::get()->filter(array('Email' => '*****@*****.**'))->first();
     $auth = $this->getAuthenticator();
     $request = new SS_HTTPRequest('GET', 'api/ApiTest_Book/1');
     $auth->resetToken($member->ID);
     $token = $auth->getToken($member->ID);
     $request->addHeader('X-Silverstripe-Apitoken', $token);
     $result = $auth->authenticate($request);
     $this->assertTrue($result, "TokenAuth authentication success should return true");
     $auth->resetToken($member->ID);
     $result = $auth->authenticate($request);
     $this->assertContainsOnlyInstancesOf('RESTfulAPI_Error', array($result), "TokenAuth authentication failure should return a RESTfulAPI_Error");
 }
示例#11
0
 /**
  * Test a URL request, returning a response object.
  * 
  * This method is the counterpart of Director::direct() that is used in functional testing.  It will execute the
  * URL given, and return the result as an SS_HTTPResponse object.
  * 
  * @param string $url The URL to visit
  * @param array $postVars The $_POST & $_FILES variables
  * @param Session $session The {@link Session} object representing the current session.  By passing the same
  *                         object to multiple  calls of Director::test(), you can simulate a persisted session.
  * @param string $httpMethod The HTTP method, such as GET or POST.  It will default to POST if postVars is set,
  *                           GET otherwise. Overwritten by $postVars['_method'] if present.
  * @param string $body The HTTP body
  * @param array $headers HTTP headers with key-value pairs
  * @param array $cookies to populate $_COOKIE
  * @param HTTP_Request $request The {@see HTTP_Request} object generated as a part of this request
  * @return SS_HTTPResponse
  * 
  * @uses getControllerForURL() The rule-lookup logic is handled by this.
  * @uses Controller::run() Controller::run() handles the page logic for a Director::direct() call.
  */
 public static function test($url, $postVars = null, $session = null, $httpMethod = null, $body = null, $headers = null, $cookies = null, &$request = null)
 {
     Config::nest();
     // These are needed so that calling Director::test() doesnt muck with whoever is calling it.
     // Really, it's some inappropriate coupling and should be resolved by making less use of statics
     $oldStage = Versioned::current_stage();
     $getVars = array();
     if (!$httpMethod) {
         $httpMethod = $postVars || is_array($postVars) ? "POST" : "GET";
     }
     if (!$session) {
         $session = new Session(null);
     }
     // Back up the current values of the superglobals
     $existingRequestVars = isset($_REQUEST) ? $_REQUEST : array();
     $existingGetVars = isset($_GET) ? $_GET : array();
     $existingPostVars = isset($_POST) ? $_POST : array();
     $existingSessionVars = isset($_SESSION) ? $_SESSION : array();
     $existingCookies = isset($_COOKIE) ? $_COOKIE : array();
     $existingServer = isset($_SERVER) ? $_SERVER : array();
     $existingRequirementsBackend = Requirements::backend();
     Config::inst()->update('Cookie', 'report_errors', false);
     Requirements::set_backend(new Requirements_Backend());
     // Handle absolute URLs
     if (@parse_url($url, PHP_URL_HOST) != '') {
         $bits = parse_url($url);
         $_SERVER['HTTP_HOST'] = $bits['host'];
         $url = Director::makeRelative($url);
     }
     $urlWithQuerystring = $url;
     if (strpos($url, '?') !== false) {
         list($url, $getVarsEncoded) = explode('?', $url, 2);
         parse_str($getVarsEncoded, $getVars);
     }
     // Replace the superglobals with appropriate test values
     $_REQUEST = ArrayLib::array_merge_recursive((array) $getVars, (array) $postVars);
     $_GET = (array) $getVars;
     $_POST = (array) $postVars;
     $_SESSION = $session ? $session->inst_getAll() : array();
     $_COOKIE = (array) $cookies;
     $_SERVER['REQUEST_URI'] = Director::baseURL() . $urlWithQuerystring;
     $request = new SS_HTTPRequest($httpMethod, $url, $getVars, $postVars, $body);
     if ($headers) {
         foreach ($headers as $k => $v) {
             $request->addHeader($k, $v);
         }
     }
     // Pre-request filtering
     // @see issue #2517
     $model = DataModel::inst();
     $output = Injector::inst()->get('RequestProcessor')->preRequest($request, $session, $model);
     if ($output === false) {
         // @TODO Need to NOT proceed with the request in an elegant manner
         throw new SS_HTTPResponse_Exception(_t('Director.INVALID_REQUEST', 'Invalid request'), 400);
     }
     // TODO: Pass in the DataModel
     $result = Director::handleRequest($request, $session, $model);
     // Ensure that the result is an SS_HTTPResponse object
     if (is_string($result)) {
         if (substr($result, 0, 9) == 'redirect:') {
             $response = new SS_HTTPResponse();
             $response->redirect(substr($result, 9));
             $result = $response;
         } else {
             $result = new SS_HTTPResponse($result);
         }
     }
     $output = Injector::inst()->get('RequestProcessor')->postRequest($request, $result, $model);
     if ($output === false) {
         throw new SS_HTTPResponse_Exception("Invalid response");
     }
     // Restore the superglobals
     $_REQUEST = $existingRequestVars;
     $_GET = $existingGetVars;
     $_POST = $existingPostVars;
     $_SESSION = $existingSessionVars;
     $_COOKIE = $existingCookies;
     $_SERVER = $existingServer;
     Requirements::set_backend($existingRequirementsBackend);
     // These are needed so that calling Director::test() doesnt muck with whoever is calling it.
     // Really, it's some inappropriate coupling and should be resolved by making less use of statics
     Versioned::reading_stage($oldStage);
     Config::unnest();
     return $result;
 }
 function testPullRegionWithRenderContext()
 {
     // this is a dirty dirty mess. sorry.
     $req = new SS_HTTPRequest('GET', '/test1');
     $req->addHeader(AjaxHTTPResponse::PULL_HEADER, 'TestProductGroupItem:BUYABLE');
     $req->addHeader('X-Requested-With', 'XMLHttpRequest');
     $ctrl = new Controller();
     $ctrl->pushCurrent();
     $ctrl->setRequest($req);
     $ctrl->setDataModel(DataModel::inst());
     $ctrl->setURLParams(array());
     $ctrl->init();
     $response = $ctrl->getAjaxResponse();
     $response->addRenderContext('BUYABLE', new ArrayData(array('Title' => 'Test Product', 'Link' => '/test-product', 'Price' => 29.99)));
     $data = json_decode($response->getBody(), true);
     $ctrl->popCurrent();
     $this->assertNotEmpty($data[AjaxHTTPResponse::REGIONS_KEY]['TestProductGroupItem']);
 }
 /**
  * Generates a fake request for the field
  * @param {SS_HTTPRequest} $request Source Request to base the fake request off of
  * @param {Widget} $sourceWidget Source widget
  * @param {string} $baseLink Base URL to be truncated off of the form
  * @return {SS_HTTPRequest} Fake HTTP Request used to fool the form field into thinking the request was made to it directly
  */
 protected function getFakeRequest(SS_HTTPRequest $request, Widget $sourceWidget, $baseLink)
 {
     $fieldName = rawurldecode($request->param('FieldName'));
     $objID = preg_replace('/Widget\\[(.*?)\\]\\[(.*?)\\]\\[(.*?)\\]$/', '$2', $fieldName);
     $finalPostVars = array();
     if ($request->isPOST()) {
         $postVars = $request->postVars();
         //Pull the post data for the widget
         if (isset($postVars['Widget'][$this->getName()][$objID])) {
             $finalPostVars = $postVars['Widget'][$this->getName()][$objID];
         } else {
             $finalPostVars = array();
         }
         $finalPostVars = array_merge($finalPostVars, $postVars);
         unset($finalPostVars['Widget']);
         //Workaround for UploadField's and GridFields confusing the request
         $fields = $sourceWidget->getCMSFields();
         $uploadFields = array();
         $gridFields = array();
         foreach ($fields as $field) {
             if ($field instanceof UploadField) {
                 $uploadFields[] = $field->getName();
             } else {
                 if ($field instanceof GridField) {
                     $gridFields[] = $field->getName();
                 }
             }
         }
         //Re-orgazine the upload field data
         if (count($uploadFields)) {
             foreach ($uploadFields as $field) {
                 $formFieldName = 'Widget[' . $this->getName() . '][' . $objID . '][' . $field . ']';
                 $fieldData = array($formFieldName => array('name' => array('Uploads' => array()), 'type' => array('Uploads' => array()), 'tmp_name' => array('Uploads' => array()), 'error' => array('Uploads' => array()), 'size' => array('Uploads' => array())));
                 if (isset($postVars['Widget']['name'][$this->getName()][$objID][$field]['Uploads'])) {
                     for ($i = 0; $i < count($postVars['Widget']['name'][$this->getName()][$objID][$field]['Uploads']); $i++) {
                         $fieldData[$formFieldName]['name']['Uploads'][] = $postVars['Widget']['name'][$this->getName()][$objID][$field]['Uploads'][$i];
                         $fieldData[$formFieldName]['type']['Uploads'][] = $postVars['Widget']['type'][$this->getName()][$objID][$field]['Uploads'][$i];
                         $fieldData[$formFieldName]['tmp_name']['Uploads'][] = $postVars['Widget']['tmp_name'][$this->getName()][$objID][$field]['Uploads'][$i];
                         $fieldData[$formFieldName]['error']['Uploads'][] = $postVars['Widget']['error'][$this->getName()][$objID][$field]['Uploads'][$i];
                         $fieldData[$formFieldName]['size']['Uploads'][] = $postVars['Widget']['size'][$this->getName()][$objID][$field]['Uploads'][$i];
                     }
                 }
                 $finalPostVars = array_merge_recursive($finalPostVars, $fieldData);
             }
         }
         //Reorganize the gridfield data
         if (count($gridFields) && isset($postVars['Widget'][$this->getName()][$objID])) {
             foreach ($gridFields as $field) {
                 $formFieldName = 'Widget[' . $this->getName() . '][' . $objID . '][' . $field . ']';
                 $fieldData = array($formFieldName => $postVars['Widget'][$this->getName()][$objID][$field]);
             }
             $finalPostVars = array_merge_recursive($finalPostVars, $fieldData);
         }
     }
     $headers = $request->getHeaders();
     $request = new SS_HTTPRequest($_SERVER['REQUEST_METHOD'], str_replace(rtrim($baseLink, '/'), '', rtrim($request->getURL(), '/')) . '/', $request->getVars(), $finalPostVars, $request->getBody());
     $request->match('$Action/$ID/$OtherID');
     //Merge in the headers
     foreach ($headers as $header => $value) {
         $request->addHeader($header, $value);
     }
     return $request;
 }