/** * Handle a single request * * @param string method request method * @param string query query string * @param [:string] headers request headers * @param string data post data * @param peer.Socket socket * @return int */ public function handleRequest($method, $query, array $headers, $data, Socket $socket) { $url = new URL('http://' . (isset($headers['Host']) ? $headers['Host'] : 'localhost') . $query); $port = $url->getPort(-1); $request = $this->scriptlet->request(); $response = $this->scriptlet->response(); // Fill request $request->method = $method; $request->env = $this->env; $request->env['SERVER_PROTOCOL'] = 'HTTP/1.1'; $request->env['REQUEST_URI'] = $query; $request->env['QUERY_STRING'] = substr($query, strpos($query, '?') + 1); $request->env['HTTP_HOST'] = $url->getHost() . (-1 === $port ? '' : ':' . $port); if (isset($headers['Authorization'])) { if (0 === strncmp('Basic', $headers['Authorization'], 5)) { $credentials = explode(':', base64_decode(substr($headers['Authorization'], 6))); $request->env['PHP_AUTH_USER'] = $credentials[0]; $request->env['PHP_AUTH_PW'] = $credentials[1]; } } $request->setHeaders($headers); // Merge POST and GET parameters if (isset($headers['Content-Type']) && 'application/x-www-form-urlencoded' === $headers['Content-Type']) { parse_str($data, $params); $request->setParams(array_merge($url->getParams(), $params)); } else { $request->setParams($url->getParams()); } // Rewire request and response I/O $request->readData = function () use($data) { return new \io\streams\MemoryInputStream($data); }; $response->sendHeaders = function ($version, $statusCode, $headers) use($socket) { $this->sendHeader($socket, $statusCode, '', $headers); }; $response->sendContent = function ($content) use($socket) { $socket->write($content); }; try { $this->scriptlet->service($request, $response); } catch (ScriptletException $e) { $e->printStackTrace(); $this->sendErrorMessage($socket, $e->getStatus(), nameof($e), $e->getMessage()); return $e->getStatus(); } if (!$response->isCommitted()) { $response->flush(); } $response->sendContent(); return $response->statusCode; }
/** * Connect to store using a DSN * * @param string dsn * @return bool success * @see php://imap_open * @throws lang.IllegalArgumentException in case scheme is not recognized * @throws peer.mail.MessagingException */ public function connect($dsn) { $flags = OP_HALFOPEN; // Parse DSN $u = new URL($dsn); $attr = $u->getParams(); // DSN supported? if (false === $this->_supports($u, $attr)) { return false; } // Read-only? if ($u->getParam('open')) { $flags ^= OP_HALFOPEN; } if ($u->getParam('read-only')) { $flags |= OP_READONLY; } $mbx = isset($attr['mbx']) ? $attr['mbx'] : sprintf('{%s:%d/%s}', $u->getHost(), $u->getPort($attr['port']), $u->getParam('proto', $attr['proto'])); // Connect if (false === ($conn = $this->_connect($mbx, @$u->getUser(), @$u->getPassword(), $flags))) { throw new \peer\mail\MessagingException('Connect to "' . $u->getUser() . '@' . $mbx . '" failed', $this->_errors()); } $this->_hdl = [$conn, $mbx]; return true; }
/** * Creates a new request object. Uses the system environment and global * variables to put necessary parameters into place. * * @param string method * @param peer.URL url */ protected function newRequest($method, \peer\URL $url) { $q = $url->getQuery(); $_SERVER['REQUEST_METHOD'] = $method; $_SERVER['SERVER_PROTOCOL'] = 'HTTP/1.1'; $_SERVER['HTTP_HOST'] = $url->getHost(); $_SERVER['REQUEST_URI'] = $url->getPath('/') . ($q ? '?' . $q : ''); $_SERVER['QUERY_STRING'] = $q; if ('https' === $url->getScheme()) { $_SERVER['HTTPS'] = 'on'; } $_REQUEST = $url->getParams(); }
/** * 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 \scriptlet\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; }
public function doCreate() { $req = $this->newRequest('GET', new URL('http://localhost/')); $res = new \scriptlet\HttpScriptletResponse(); $s = newinstance('scriptlet.xml.XMLScriptlet', [], '{ public function needsSession($request) { return true; } }'); $s->service($req, $res); $this->assertEquals(HttpConstants::STATUS_FOUND, $res->statusCode); // Check URL from Location: header contains the session ID with($redirect = new URL(substr($res->headers[0], strlen('Location: ')))); $this->assertEquals('http', $redirect->getScheme()); $this->assertEquals('localhost', $redirect->getHost()); $this->assertEquals(sprintf('/xml/psessionid=%s/static', session_id()), $redirect->getPath()); $this->assertEquals([], $redirect->getParams(), $redirect->getURL()); }