function testContentLengthHeader() { $r = new SS_HTTPResponse('123ü'); $this->assertNotNull($r->getHeader('Content-Length'), 'Content-length header is added'); $this->assertEquals(5, $r->getHeader('Content-Length'), 'Header matches actual content length in bytes'); $r->setBody('1234ü'); $this->assertEquals(6, $r->getHeader('Content-Length'), 'Header is updated when body is changed'); }
public function testAddCacheHeaders() { $body = "<html><head></head><body><h1>Mysite</h1></body></html>"; $response = new SS_HTTPResponse($body, 200); $this->assertEmpty($response->getHeader('Cache-Control')); HTTP::set_cache_age(30); HTTP::add_cache_headers($response); $this->assertNotEmpty($response->getHeader('Cache-Control')); // Ensure max-age is zero for development. Config::inst()->update('Director', 'environment_type', 'dev'); $response = new SS_HTTPResponse($body, 200); HTTP::add_cache_headers($response); $this->assertContains('max-age=0', $response->getHeader('Cache-Control')); // Ensure max-age setting is respected in production. Config::inst()->update('Director', 'environment_type', 'live'); $response = new SS_HTTPResponse($body, 200); HTTP::add_cache_headers($response); $this->assertContains('max-age=30', explode(', ', $response->getHeader('Cache-Control'))); $this->assertNotContains('max-age=0', $response->getHeader('Cache-Control')); // Still "live": Ensure header's aren't overridden if already set (using purposefully different values). $headers = array('Vary' => '*', 'Pragma' => 'no-cache', 'Cache-Control' => 'max-age=0, no-cache, no-store'); $response = new SS_HTTPResponse($body, 200); foreach ($headers as $name => $value) { $response->addHeader($name, $value); } HTTP::add_cache_headers($response); foreach ($headers as $name => $value) { $this->assertEquals($value, $response->getHeader($name)); } }
/** * If the last request was a 3xx response, then follow the redirection * * @return SS_HTTPResponse The response given, or null if no redirect occurred */ public function followRedirection() { if ($this->lastResponse->getHeader('Location')) { $url = Director::makeRelative($this->lastResponse->getHeader('Location')); $url = strtok($url, '#'); return $this->get($url); } }
/** * Adds Intercom script tags just before the body */ public function postRequest(SS_HTTPRequest $request, SS_HTTPResponse $response, DataModel $model) { $mime = $response->getHeader('Content-Type'); if (!$mime || strpos($mime, 'text/html') !== false) { $intercomScriptTags = (new intercomScriptTags())->forTemplate(); if ($intercomScriptTags) { $content = $response->getBody(); $content = preg_replace("/(<\\/body[^>]*>)/i", $intercomScriptTags . "\\1", $content); $response->setBody($content); } } }
public function testAddCacheHeaders() { $body = "<html><head></head><body><h1>Mysite</h1></body></html>"; $response = new SS_HTTPResponse($body, 200); $this->assertEmpty($response->getHeader('Cache-Control')); HTTP::set_cache_age(30); HTTP::add_cache_headers($response); $this->assertNotEmpty($response->getHeader('Cache-Control')); Config::inst()->update('Director', 'environment_type', 'dev'); HTTP::add_cache_headers($response); $this->assertContains('max-age=0', $response->getHeader('Cache-Control')); Config::inst()->update('Director', 'environment_type', 'live'); HTTP::add_cache_headers($response); $this->assertContains('max-age=30', explode(', ', $response->getHeader('Cache-Control'))); $this->assertNotContains('max-age=0', $response->getHeader('Cache-Control')); }
/** * Tests whether a redirection has been requested. * @return string If redirect() has been called, it will return the URL redirected to. Otherwise, it will return null; */ function redirectedTo() { return $this->response && $this->response->getHeader('Location'); }
/** * Assert that a response matches the given parameters * * @param int $code HTTP code * @param string $body Body expected for 200 responses * @param SS_HTTPResponse $response */ protected function assertResponseEquals($code, $body, SS_HTTPResponse $response) { $this->assertEquals($code, $response->getStatusCode()); if ($code === 200) { $this->assertFalse($response->isError()); $this->assertEquals($body, $response->getBody()); $this->assertEquals('text/plain', $response->getHeader('Content-Type')); } else { $this->assertTrue($response->isError()); } }
/** * Copied and adjusted from HTTP::add_cache_headers * * @param Object $originator * @param SS_HTTPRequest $request * @param SS_HTTPResponse $response * @param DataModel $model */ public function applyToResponse($originator, SS_HTTPRequest $request, SS_HTTPResponse $response, DataModel $model) { $cacheAge = $this->cacheAge; // Development sites have frequently changing templates; this can get stuffed up by the code // below. if (Director::isDev()) { $cacheAge = 0; } // Populate $responseHeaders with all the headers that we want to build $responseHeaders = array(); if (function_exists('apache_request_headers')) { $requestHeaders = apache_request_headers(); if (isset($requestHeaders['X-Requested-With']) && $requestHeaders['X-Requested-With'] == 'XMLHttpRequest') { $cacheAge = 0; } // bdc: now we must check for DUMB IE6: if (isset($requestHeaders['x-requested-with']) && $requestHeaders['x-requested-with'] == 'XMLHttpRequest') { $cacheAge = 0; } } if ($cacheAge > 0) { $responseHeaders["Cache-Control"] = "max-age=" . $cacheAge . ", must-revalidate, no-transform"; $responseHeaders["Pragma"] = ""; $responseHeaders['Vary'] = $this->vary; } else { if ($response) { // Grab header for checking. Unfortunately HTTPRequest until 3.1 uses a mistyped variant. $contentDisposition = $response->getHeader('Content-disposition'); if (!$contentDisposition) { $contentDisposition = $response->getHeader('Content-Disposition'); } } if ($response && Director::is_https() && strstr($_SERVER["HTTP_USER_AGENT"], 'MSIE') == true && strstr($contentDisposition, 'attachment;') == true) { // IE6-IE8 have problems saving files when https and no-cache are used // (http://support.microsoft.com/kb/323308) // Note: this is also fixable by ticking "Do not save encrypted pages to disk" in advanced options. $responseHeaders["Cache-Control"] = "max-age=3, must-revalidate, no-transform"; $responseHeaders["Pragma"] = ""; } else { $responseHeaders["Cache-Control"] = "no-cache, max-age=0, must-revalidate, no-transform"; } } if (self::$modification_date && $cacheAge > 0) { $responseHeaders["Last-Modified"] = self::gmt_date(self::$modification_date); // Chrome ignores Varies when redirecting back (http://code.google.com/p/chromium/issues/detail?id=79758) // which means that if you log out, you get redirected back to a page which Chrome then checks against // last-modified (which passes, getting a 304) // when it shouldn't be trying to use that page at all because it's the "logged in" version. // By also using and etag that includes both the modification date and all the varies // values which we also check against we can catch this and not return a 304 $etagParts = array(self::$modification_date, serialize($_COOKIE)); $etagParts[] = Director::is_https() ? 'https' : 'http'; if (isset($_SERVER['HTTP_USER_AGENT'])) { $etagParts[] = $_SERVER['HTTP_USER_AGENT']; } if (isset($_SERVER['HTTP_ACCEPT'])) { $etagParts[] = $_SERVER['HTTP_ACCEPT']; } $etag = sha1(implode(':', $etagParts)); $responseHeaders["ETag"] = $etag; // 304 response detection if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) { $ifModifiedSince = strtotime(stripslashes($_SERVER['HTTP_IF_MODIFIED_SINCE'])); // As above, only 304 if the last request had all the same varies values // (or the etag isn't passed as part of the request - but with chrome it always is) $matchesEtag = !isset($_SERVER['HTTP_IF_NONE_MATCH']) || $_SERVER['HTTP_IF_NONE_MATCH'] == $etag; if ($ifModifiedSince >= self::$modification_date && $matchesEtag) { if ($response) { $response->setStatusCode(304); $response->setBody(''); } else { header('HTTP/1.0 304 Not Modified'); die; } } } $expires = time() + $cacheAge; $responseHeaders["Expires"] = self::gmt_date($expires); } if (self::$etag) { $responseHeaders['ETag'] = self::$etag; } // Now that we've generated them, either output them or attach them to the SS_HTTPResponse as appropriate foreach ($responseHeaders as $k => $v) { $response->addHeader($k, $v); } }
public function postRequest(SS_HTTPRequest $request, SS_HTTPResponse $response, DataModel $model) { if (preg_match('/text\\/html/', $response->getHeader('Content-Type'))) { $response->setBody($this->SuppressWhitespace($response->getBody())); } }