Comparar commits
8 Commits
| Autor | SHA1 | Data | |
|---|---|---|---|
| f951cb8d88 | |||
| 2a3225ecd0 | |||
| 65cfdabb76 | |||
| 25a26c6bd7 | |||
| 3effbfe5d1 | |||
| 3a708166b8 | |||
| 3c17422435 | |||
| d3f23f393f |
@@ -926,13 +926,6 @@ c_PDO::c_PDO(Class* cb) : ExtObjectData(cb) {
|
||||
c_PDO::~c_PDO() {
|
||||
}
|
||||
|
||||
void c_PDO::sweep() {
|
||||
// PDOConnection is not sweepable, so clean it up manually.
|
||||
static_assert(!std::is_base_of<Sweepable, PDOConnection>::value,
|
||||
"Remove the call to reset() below.");
|
||||
m_dbh.detach();
|
||||
}
|
||||
|
||||
void c_PDO::t___construct(const String& dsn, const String& username /* = null_string */,
|
||||
const String& password /* = null_string */,
|
||||
CArrRef options /* = null_array */) {
|
||||
@@ -2642,10 +2635,6 @@ c_PDOStatement::~c_PDOStatement() {
|
||||
m_row.reset();
|
||||
}
|
||||
|
||||
void c_PDOStatement::sweep() {
|
||||
// No resources allocated outside HHVM's control
|
||||
}
|
||||
|
||||
Variant c_PDOStatement::t_execute(CArrRef params /* = null_array */) {
|
||||
SYNC_VM_REGS_SCOPED();
|
||||
strcpy(m_stmt->error_code, PDO_ERR_NONE);
|
||||
|
||||
@@ -112,9 +112,9 @@ extern const int64_t q_PDO$$MYSQL_ATTR_IGNORE_SPACE;
|
||||
// class PDO
|
||||
|
||||
FORWARD_DECLARE_CLASS(PDO);
|
||||
class c_PDO : public ExtObjectData, public Sweepable {
|
||||
class c_PDO : public ExtObjectData {
|
||||
public:
|
||||
DECLARE_CLASS(PDO)
|
||||
DECLARE_CLASS_NO_SWEEP(PDO)
|
||||
|
||||
// need to implement
|
||||
public: c_PDO(Class* cls = c_PDO::classof());
|
||||
@@ -152,9 +152,9 @@ class c_PDO : public ExtObjectData, public Sweepable {
|
||||
// class PDOStatement
|
||||
|
||||
FORWARD_DECLARE_CLASS(PDOStatement);
|
||||
class c_PDOStatement : public ExtObjectData, public Sweepable {
|
||||
class c_PDOStatement : public ExtObjectData {
|
||||
public:
|
||||
DECLARE_CLASS(PDOStatement)
|
||||
DECLARE_CLASS_NO_SWEEP(PDOStatement)
|
||||
|
||||
// need to implement
|
||||
public: c_PDOStatement(Class* cls = c_PDOStatement::classof());
|
||||
|
||||
@@ -72,6 +72,12 @@ PDOConnection::PDOConnection()
|
||||
PDOConnection::~PDOConnection() {
|
||||
}
|
||||
|
||||
void PDOConnection::sweep() {
|
||||
assert(!is_persistent);
|
||||
def_stmt_ctor_args.asTypedValue()->m_type = KindOfNull;
|
||||
delete this;
|
||||
}
|
||||
|
||||
void PDOConnection::persistentSave() {
|
||||
String serialized = f_serialize(def_stmt_ctor_args);
|
||||
serialized_def_stmt_ctor_args = string(serialized.data(), serialized.size());
|
||||
|
||||
@@ -235,7 +235,7 @@ class PDOStatement;
|
||||
typedef SmartResource<PDOStatement> sp_PDOStatement;
|
||||
|
||||
/* represents a connection to a database */
|
||||
class PDOConnection : public ResourceData {
|
||||
class PDOConnection : public SweepableResourceData {
|
||||
public:
|
||||
static const char *PersistentKey;
|
||||
|
||||
@@ -259,6 +259,7 @@ public:
|
||||
PDOConnection();
|
||||
virtual ~PDOConnection();
|
||||
virtual bool create(CArrRef options) = 0;
|
||||
virtual void sweep();
|
||||
|
||||
CLASSNAME_IS("PDOConnection")
|
||||
// overriding ResourceData
|
||||
|
||||
@@ -114,6 +114,15 @@ bool PDOSqliteConnection::create(CArrRef options) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void PDOSqliteConnection::sweep() {
|
||||
for (auto& udf : m_udfs) {
|
||||
udf->func.asTypedValue()->m_type = KindOfNull;
|
||||
udf->step.asTypedValue()->m_type = KindOfNull;
|
||||
udf->fini.asTypedValue()->m_type = KindOfNull;
|
||||
}
|
||||
PDOConnection::sweep();
|
||||
}
|
||||
|
||||
bool PDOSqliteConnection::support(SupportedMethod method) {
|
||||
return method != MethodCheckLiveness;
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ public:
|
||||
PDOSqliteConnection();
|
||||
virtual ~PDOSqliteConnection();
|
||||
virtual bool create(CArrRef options);
|
||||
virtual void sweep();
|
||||
|
||||
int handleError(const char *file, int line, PDOStatement *stmt = nullptr);
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "hphp/runtime/server/fastcgi/fastcgi-transport.h"
|
||||
#include "hphp/runtime/server/fastcgi/fastcgi-server.h"
|
||||
#include "hphp/runtime/server/transport.h"
|
||||
#include "hphp/runtime/base/runtime-error.h"
|
||||
#include "folly/io/IOBuf.h"
|
||||
#include "folly/io/IOBufQueue.h"
|
||||
#include "thrift/lib/cpp/async/TAsyncTransport.h"
|
||||
@@ -27,6 +28,8 @@
|
||||
#include "hphp/util/timer.h"
|
||||
#include "folly/MoveWrapper.h"
|
||||
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
|
||||
using folly::IOBuf;
|
||||
using folly::IOBufQueue;
|
||||
using folly::io::Cursor;
|
||||
@@ -47,6 +50,10 @@ const char *FastCGITransport::getUrl() {
|
||||
return m_requestURI.c_str();
|
||||
}
|
||||
|
||||
const std::string FastCGITransport::getDocumentRoot() {
|
||||
return m_documentRoot;
|
||||
}
|
||||
|
||||
const char *FastCGITransport::getRemoteHost() {
|
||||
return m_remoteHost.c_str();
|
||||
}
|
||||
@@ -127,7 +134,48 @@ const char *FastCGITransport::getServerObject() {
|
||||
return m_serverObject.c_str();
|
||||
}
|
||||
|
||||
std::string FastCGITransport::unmangleHeader(const std::string& name) {
|
||||
if (!boost::istarts_with(name, "HTTP_")) {
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string ret;
|
||||
bool is_upper = true;
|
||||
for (auto& c : name.substr(5)) {
|
||||
if (c == '_') {
|
||||
ret += '-';
|
||||
is_upper = true;
|
||||
} else {
|
||||
ret += is_upper ? toupper(c) : tolower(c);
|
||||
is_upper = false;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string FastCGITransport::mangleHeader(const std::string& name) {
|
||||
std::string ret;
|
||||
for (auto& c : name) {
|
||||
if (c == '-') {
|
||||
ret += '_';
|
||||
} else {
|
||||
ret += toupper(c);
|
||||
}
|
||||
}
|
||||
return "HTTP_" + ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Passed an HTTP header like "Cookie" or "Cache-Control"
|
||||
**/
|
||||
std::string FastCGITransport::getHeader(const char *name) {
|
||||
return getRawHeader(mangleHeader(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Passed a FastCGI mangled header like "HTTP_COOKIE" or "HTTP_CACHE_CONTROL"
|
||||
**/
|
||||
std::string FastCGITransport::getRawHeader(const std::string& name) {
|
||||
if (m_requestHeaders.count(name) && m_requestHeaders[name].size()) {
|
||||
return m_requestHeaders[name][0];
|
||||
} else {
|
||||
@@ -136,7 +184,12 @@ std::string FastCGITransport::getHeader(const char *name) {
|
||||
}
|
||||
|
||||
void FastCGITransport::getHeaders(HeaderMap &headers) {
|
||||
headers = m_requestHeaders;
|
||||
for (auto& pair : m_requestHeaders) {
|
||||
auto key = unmangleHeader(pair.first);
|
||||
if (!key.empty()) {
|
||||
headers[key] = pair.second;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FastCGITransport::addHeaderImpl(const char *name, const char *value) {
|
||||
@@ -225,6 +278,7 @@ const std::string FastCGITransport::k_remotePortKey = "REMOTE_PORT";
|
||||
const std::string FastCGITransport::k_methodKey = "REQUEST_METHOD";
|
||||
const std::string FastCGITransport::k_httpVersionKey = "HTTP_VERSION";
|
||||
const std::string FastCGITransport::k_contentLengthKey = "CONTENT_LENGTH";
|
||||
const std::string FastCGITransport::k_documentRoot = "DOCUMENT_ROOT";
|
||||
|
||||
void FastCGITransport::onHeader(std::unique_ptr<folly::IOBuf> key_chain,
|
||||
std::unique_ptr<folly::IOBuf> value_chain) {
|
||||
@@ -288,12 +342,14 @@ void FastCGITransport::handleHeader(const std::string& key,
|
||||
} catch (std::out_of_range&) {
|
||||
m_requestSize = 0;
|
||||
}
|
||||
} else if (compareKeys(key, k_documentRoot)) {
|
||||
m_documentRoot = value + "/";
|
||||
}
|
||||
}
|
||||
|
||||
void FastCGITransport::onHeadersComplete() {
|
||||
m_serverObject = getHeader("SCRIPT_NAME");
|
||||
std::string queryString = getHeader("QUERY_STRING");
|
||||
m_serverObject = getRawHeader("SCRIPT_NAME");
|
||||
std::string queryString = getRawHeader("QUERY_STRING");
|
||||
if (!queryString.empty()) {
|
||||
m_serverObject += "?" + queryString;
|
||||
}
|
||||
|
||||
@@ -49,6 +49,7 @@ public:
|
||||
virtual const char *getUrl() override;
|
||||
virtual const char *getRemoteHost() override;
|
||||
virtual uint16_t getRemotePort() override;
|
||||
virtual const std::string getDocumentRoot() override;
|
||||
|
||||
virtual const void *getPostData(int &size) override;
|
||||
virtual bool hasMorePostData() override;
|
||||
@@ -87,6 +88,15 @@ private:
|
||||
typedef std::map<std::string, std::vector<std::string>> ResponseHeaders;
|
||||
|
||||
void handleHeader(const std::string& key, const std::string& value);
|
||||
std::string getRawHeader(const std::string& name);
|
||||
/*
|
||||
* HTTP_IF_MODIFIED_SINCE -> If-Unmodified-Since
|
||||
*/
|
||||
std::string unmangleHeader(const std::string& name);
|
||||
/*
|
||||
* If-Unmodified-Since -> HTTP_IF_MODIFIED_SINCE
|
||||
*/
|
||||
std::string mangleHeader(const std::string& name);
|
||||
|
||||
static bool compareKeys(const std::string& key,
|
||||
const std::string& other_key);
|
||||
@@ -101,6 +111,7 @@ private:
|
||||
static const std::string k_methodKey;
|
||||
static const std::string k_httpVersionKey;
|
||||
static const std::string k_contentLengthKey;
|
||||
static const std::string k_documentRoot;
|
||||
|
||||
FastCGIConnection* m_connection;
|
||||
int m_id;
|
||||
@@ -108,6 +119,7 @@ private:
|
||||
std::unique_ptr<folly::IOBuf> m_currBody;
|
||||
HeaderMap m_requestHeaders;
|
||||
std::string m_requestURI;
|
||||
std::string m_documentRoot;
|
||||
std::string m_remoteHost;
|
||||
uint16_t m_remotePort;
|
||||
Method m_method;
|
||||
|
||||
@@ -323,24 +323,9 @@ bool HttpProtocol::PrepareCookieVariable(Variant& cookie,
|
||||
}
|
||||
|
||||
void HttpProtocol::CopyHeaderVariables(Variant& server,
|
||||
const HeaderMap& headers,
|
||||
bool normalize) {
|
||||
const HeaderMap& headers) {
|
||||
static std::atomic<int> badRequests(-1);
|
||||
|
||||
if (!normalize) {
|
||||
for (HeaderMap::const_iterator iter = headers.begin();
|
||||
iter != headers.end();
|
||||
++iter) {
|
||||
const vector<string> &values = iter->second;
|
||||
for (unsigned int i = 0; i < values.size(); i++) {
|
||||
String key = string_replace(f_strtoupper(iter->first), s_dash,
|
||||
s_underscore);
|
||||
server.set(key, String(values[i]));
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<std::string> badHeaders;
|
||||
for (auto const& header : headers) {
|
||||
auto const& key = header.first;
|
||||
@@ -515,15 +500,13 @@ void HttpProtocol::CopyPathInfo(Variant& server,
|
||||
server.set(s_PHP_SELF, r.resolvedURL() + r.origPathInfo());
|
||||
}
|
||||
|
||||
String documentRoot;
|
||||
if (RuntimeOption::ServerType != "fastcgi") {
|
||||
String documentRoot = transport->getDocumentRoot();
|
||||
if (documentRoot.empty()) {
|
||||
// Right now this is just RuntimeOption::SourceRoot but mwilliams wants to
|
||||
// fix it so it is settable, so I'll leave this for now
|
||||
documentRoot = vhost->getDocumentRoot();
|
||||
server.set(s_DOCUMENT_ROOT, documentRoot);
|
||||
} else if (server.asCArrRef().exists(s_DOCUMENT_ROOT)) {
|
||||
CHECK(server[s_DOCUMENT_ROOT].isString());
|
||||
documentRoot = server[s_DOCUMENT_ROOT].toCStrRef();
|
||||
}
|
||||
|
||||
server.set(s_DOCUMENT_ROOT, documentRoot);
|
||||
server.set(s_SCRIPT_FILENAME, r.absolutePath());
|
||||
|
||||
if (r.pathInfo().empty()) {
|
||||
@@ -590,14 +573,10 @@ void HttpProtocol::PrepareServerVariable(Variant& server,
|
||||
// "may" exclude them; this is not what APE does, but it's harmless.
|
||||
HeaderMap headers;
|
||||
transport->getHeaders(headers);
|
||||
if (RuntimeOption::ServerType != "fastcgi") {
|
||||
CopyHeaderVariables(server, headers, true);
|
||||
CopyServerInfo(server, transport, vhost);
|
||||
CopyRemoteInfo(server, transport);
|
||||
CopyAuthInfo(server, transport);
|
||||
} else {
|
||||
CopyHeaderVariables(server, headers, false);
|
||||
}
|
||||
CopyHeaderVariables(server, headers);
|
||||
CopyServerInfo(server, transport, vhost);
|
||||
CopyRemoteInfo(server, transport);
|
||||
CopyAuthInfo(server, transport);
|
||||
|
||||
CopyPathInfo(server, transport, r, vhost);
|
||||
|
||||
|
||||
@@ -59,8 +59,7 @@ public:
|
||||
const SourceRootInfo &sri,
|
||||
const VirtualHost *vhost);
|
||||
static void CopyHeaderVariables(Variant& server,
|
||||
const HeaderMap& headers,
|
||||
bool normalize);
|
||||
const HeaderMap& headers);
|
||||
static void CopyServerInfo(Variant& server,
|
||||
Transport *transport,
|
||||
const VirtualHost *vhost);
|
||||
|
||||
@@ -154,8 +154,7 @@ void HttpRequestHandler::handleRequest(Transport *transport) {
|
||||
vhost->getName().c_str());
|
||||
|
||||
// resolve source root
|
||||
string host = transport->getHeader("Host");
|
||||
SourceRootInfo sourceRootInfo(host.c_str());
|
||||
SourceRootInfo sourceRootInfo(transport);
|
||||
|
||||
if (sourceRootInfo.error()) {
|
||||
sourceRootInfo.handleError(transport);
|
||||
|
||||
@@ -157,8 +157,7 @@ void RPCRequestHandler::handleRequest(Transport *transport) {
|
||||
};
|
||||
|
||||
// resolve source root
|
||||
string host = transport->getHeader("Host");
|
||||
SourceRootInfo sourceRootInfo(host.c_str());
|
||||
SourceRootInfo sourceRootInfo(transport);
|
||||
|
||||
// set thread type
|
||||
switch (m_serverInfo->getType()) {
|
||||
|
||||
@@ -30,12 +30,22 @@ namespace HPHP {
|
||||
IMPLEMENT_THREAD_LOCAL_NO_CHECK(string, SourceRootInfo::s_path);
|
||||
IMPLEMENT_THREAD_LOCAL_NO_CHECK(string, SourceRootInfo::s_phproot);
|
||||
|
||||
SourceRootInfo::SourceRootInfo(const char *host)
|
||||
SourceRootInfo::SourceRootInfo(Transport* transport)
|
||||
: m_sandboxCond(RuntimeOption::SandboxMode ? SandboxCondition::On :
|
||||
SandboxCondition::Off) {
|
||||
s_path.destroy();
|
||||
s_phproot.destroy();
|
||||
|
||||
auto documentRoot = transport->getDocumentRoot();
|
||||
if (!documentRoot.empty()) {
|
||||
// The transport take precedence over the config file
|
||||
m_path = documentRoot;
|
||||
*s_path.getCheck() = documentRoot;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!sandboxOn()) return;
|
||||
auto host = transport->getHeader("Host");
|
||||
Variant matches;
|
||||
Variant r = preg_match(String(RuntimeOption::SandboxPattern.c_str(),
|
||||
RuntimeOption::SandboxPattern.size(),
|
||||
@@ -242,8 +252,7 @@ string SourceRootInfo::parseSandboxServerVariable(const string &format) const {
|
||||
}
|
||||
|
||||
string SourceRootInfo::path() const {
|
||||
if (sandboxOn()) {
|
||||
// Should return RuntimeOption::SourceRoot if m_data is empty?
|
||||
if (sandboxOn() || !m_path.empty()) {
|
||||
return string(m_path.data(), m_path.size());
|
||||
} else {
|
||||
return RuntimeOption::SourceRoot;
|
||||
|
||||
@@ -27,7 +27,7 @@ class Transport;
|
||||
|
||||
class SourceRootInfo {
|
||||
public:
|
||||
explicit SourceRootInfo(const char *host);
|
||||
explicit SourceRootInfo(Transport* transport);
|
||||
SourceRootInfo(const std::string &user, const std::string &sandbox);
|
||||
void createFromUserConfig();
|
||||
void createFromCommonRoot(const String &sandboxName);
|
||||
|
||||
@@ -109,6 +109,8 @@ public:
|
||||
virtual const char *getUrl() = 0;
|
||||
virtual const char *getRemoteHost() = 0;
|
||||
virtual uint16_t getRemotePort() = 0;
|
||||
// The transport can override the virtualhosts' docroot
|
||||
virtual const std::string getDocumentRoot() { return ""; }
|
||||
|
||||
/**
|
||||
* POST request's data.
|
||||
|
||||
@@ -1817,11 +1817,11 @@
|
||||
},
|
||||
{
|
||||
"name": "HPHP_VERSION",
|
||||
"value": "2.3.0"
|
||||
"value": "2.3.2"
|
||||
},
|
||||
{
|
||||
"name": "HHVM_VERSION",
|
||||
"value": "2.3.0"
|
||||
"value": "2.3.2"
|
||||
},
|
||||
{
|
||||
"name": "HTML_ENTITIES",
|
||||
|
||||
@@ -1053,6 +1053,9 @@ class Phar extends RecursiveDirectoryIterator
|
||||
if (strpos($filename, $prefix) === 0) {
|
||||
$entry = substr($filename, strlen($prefix) + 1);
|
||||
if (strlen($entry) > 0) {
|
||||
if ($filename[strlen($prefix)] != '/') {
|
||||
continue;
|
||||
}
|
||||
$next_slash = strpos($entry, '/');
|
||||
if ($next_slash !== false) {
|
||||
$entry = substr($entry, 0, $next_slash);
|
||||
|
||||
@@ -388,7 +388,7 @@ bool TestFastCGIServer::VerifyExchange(const TestMessageExchange& mx,
|
||||
printf("Error while receiving payload\n");
|
||||
result = false;
|
||||
} else if (recv_len.toInt32() < len) {
|
||||
printf("Too little date received\n");
|
||||
printf("Too little data received\n");
|
||||
result = false;
|
||||
} else {
|
||||
CHECK(recv_len.toInt32() == len);
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
class Hello {
|
||||
public function sayHello($name) {
|
||||
return "Hello $name!";
|
||||
}
|
||||
}
|
||||
|
||||
class StackTest extends PHPUnit_Framework_TestCase {
|
||||
public function testTrueIsActuallyTrue() {
|
||||
$stub = $this->getMock('Hello');
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
$argv[] = __DIR__."/phpunit_mock.inc";
|
||||
$arvc += 1;
|
||||
$_SERVER['argv'] = $argv;
|
||||
$_SERVER['argc'] = $argc;
|
||||
|
||||
include __DIR__."/phpunit.phar";
|
||||
@@ -0,0 +1,7 @@
|
||||
PHPUnit 3.7.22 by Sebastian Bergmann.
|
||||
|
||||
.
|
||||
|
||||
Time: %d second%A, Memory: %s
|
||||
|
||||
OK (1 test, 1 assertion)
|
||||
+1
-1
@@ -1 +1 @@
|
||||
HHVM_VERSION(2.3.0)
|
||||
HHVM_VERSION(2.3.2)
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário