public function cannot_route() { $fixture = $this->newFixture(); $req = new HttpScriptletRequest(); $req->setURI(new URL('http://localhost/')); $res = new HttpScriptletResponse(); $fixture->doProcess($req, $res); $this->assertEquals(404, $res->statusCode); $this->assertEquals('{ "message" : "Could not route request to http:\\/\\/localhost\\/" }', $res->getContent()); }
/** * Creates a new request object * * @see xp://scriptlet.HttpScriptlet#_setupRequest * @param string method * @param string url * @param [:string] headers * @return scriptlet.HttpScriptletRequest */ protected function newRequest($method, $url, array $headers) { $u = parse_url($url); isset($u['query']) ? parse_str($u['query'], $params) : ($params = array()); $r = new HttpScriptletRequest(); $r->method = $method; $r->setURI(new URL($u['scheme'] . '://' . $u['host'] . '/' . $u['path'])); $r->setParams($params); $r->setHeaders($headers); return $r; }
/** * Creates a new request object * * @param string method * @param peer.URL url * @return scriptlet.HttpScriptletRequest */ protected function newRequest($method, URL $url) { $q = $url->getQuery(''); $req = new HttpScriptletRequest(); $req->method = $method; $req->env['SERVER_PROTOCOL'] = 'HTTP/1.1'; $req->env['REQUEST_URI'] = $url->getPath('/') . ($q ? '?' . $q : ''); $req->env['QUERY_STRING'] = $q; $req->env['HTTP_HOST'] = $url->getHost(); if ('https' === $url->getScheme()) { $req->env['HTTPS'] = 'on'; } $req->setHeaders(array()); $req->setParams($url->getParams()); return $req; }
/** * Set request's data and try to parse the request body (if available) * * @param string data The request's data */ public function setData($data) { parent::setData($data); try { $this->tree = Tree::fromString($data); } catch (Exception $e) { // Catch exception which occur when request body contains binary // data (e.g. when PUTting files) } }
/** * This method is called to process any request and dispatches * it to on of the do* -methods of the scriptlet. It will also * call the <pre>doCreateSession()</pre> method if necessary. * * @param scriptlet.HttpScriptletRequest request * @param scriptlet.HttpScriptletResponse response * @throws scriptlet.ScriptletException indicating fatal errors */ public function service(HttpScriptletRequest $request, HttpScriptletResponse $response) { $host = $request->getHeader('X-Forwarded-Host', $request->getEnvValue('HTTP_HOST')); $request->setURL($this->_url(('on' == $request->getEnvValue('HTTPS') ? 'https' : 'http') . '://' . substr($host, 0, strcspn($host, ',')) . $request->getEnvValue('REQUEST_URI'))); // Check if this method can be handled. In case it can't, throw a // ScriptletException with the HTTP status code 501 ("Method not // implemented"). The request object will already have all headers // and the request method set when this method is called. if (!($method = $this->handleMethod($request))) { throw new ScriptletException('HTTP method "' . $request->method . '" not supported', HttpConstants::STATUS_METHOD_NOT_IMPLEMENTED); } // Call the request's initialization method $request->initialize(); // Create response object. Answer with the same protocol version that the // user agent sends us with the request. The only versions we should be // getting are 1.0 (some proxies or do this) or 1.1 (any current browser). // Answer with a "HTTP Version Not Supported" statuscode (#505) for any // other protocol version. $response->setURI($request->getURL()); if (2 != sscanf($proto = $request->getEnvValue('SERVER_PROTOCOL'), 'HTTP/%*[1].%[01]', $minor)) { throw new ScriptletException('Unsupported HTTP protocol version "' . $proto . '" - expected HTTP/1.0 or HTTP/1.1', HttpConstants::STATUS_HTTP_VERSION_NOT_SUPPORTED); } $response->version = '1.' . $minor; // Check if a session is present. This is either the case when a session // is already in the URL or if the scriptlet explicetly states it needs // one (by returning TRUE from needsSession()). if ($this->needsSession($request) || $request->getSessionId()) { $request->setSession($this->_session()); $valid = FALSE; try { $this->handleSessionInitialization($request); $valid = $request->session->isValid(); } catch (XPException $e) { // Check if session initialization errors can be handled gracefully // (default: no). If not, throw a HttpSessionInvalidException with // the HTTP status code 503 ("Service temporarily unavailable"). if (!$this->handleSessionInitializationError($request, $response)) { throw new HttpSessionInvalidException('Session initialization failed: ' . $e->getMessage(), HttpConstants::STATUS_SERVICE_TEMPORARILY_UNAVAILABLE, $e); } // Fall through, otherwise } // Check if invalid sessions can be handled gracefully (default: no). // If not, throw a HttpSessionInvalidException with the HTTP status // code 400 ("Bad request"). if (!$valid) { if (!$this->handleInvalidSession($request, $response)) { throw new HttpSessionInvalidException('Session is invalid', HttpConstants::STATUS_BAD_REQUEST); } // Fall through, otherwise } // Call doCreateSession() in case the session is new if ($request->session->isNew()) { $method = 'doCreateSession'; } } // If this scriptlet has an authenticator, run its authenticate() // method. This method may return FALSE to indicate no further // processing is to be done (e.g., in case it redirects to a login // site). Exceptions thrown are wrapped in a ScriptletException // with status code 403 ("Forbidden"). if ($auth = $this->getAuthenticator($request)) { try { $r = $auth->authenticate($request, $response, NULL); } catch (ScriptletException $e) { throw $e; } catch (XPException $e) { throw new ScriptletException('Authentication failed: ' . $e->getMessage(), HttpConstants::STATUS_FORBIDDEN, $e); } if (FALSE === $r) { return; } } // Call method handler and, in case the method handler returns anything // else than FALSE, the response processor. Exceptions thrown from any of // the two methods will result in a ScriptletException with the HTTP // status code 500 ("Internal Server Error") being thrown. try { $r = call_user_func(array($this, $method), $request, $response); if (FALSE !== $r && !is(NULL, $r)) { $response->process(); } } catch (ScriptletException $e) { throw $e; } catch (XPException $e) { throw new ScriptletException('Request processing failed [' . $method . ']: ' . $e->getMessage(), HttpConstants::STATUS_INTERNAL_SERVER_ERROR, $e); } }