Create dedicate crate for php_escaping.rs
[hiphop-php.git] / hphp / runtime / server / replay-transport.cpp
blobc6403baec213b4a2aa7f062ce8a2f89fda133dd3
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
16 #include "hphp/runtime/server/replay-transport.h"
17 #include <folly/Conv.h>
19 #include "hphp/runtime/base/string-util.h"
20 #include "hphp/runtime/base/zend-functions.h"
21 #include "hphp/runtime/base/zend-string.h"
22 #include "hphp/runtime/base/config.h"
23 #include "hphp/runtime/server/http-protocol.h"
24 #include "hphp/util/process.h"
25 #include "hphp/util/safe-cast.h"
27 namespace HPHP {
28 ///////////////////////////////////////////////////////////////////////////////
30 void ReplayTransport::recordInput(Transport* transport, const char *filename) {
31 assertx(transport);
33 Hdf hdf;
35 char buf[32];
36 snprintf(buf, sizeof(buf), "%" PRId64, (int64_t)getpid());
37 hdf["pid"] = std::string(buf);
38 snprintf(buf, sizeof(buf), "%" PRIx64, (int64_t)Process::GetThreadId());
39 hdf["tid"] = std::string(buf);
40 snprintf(buf, sizeof(buf), "%u", Process::GetThreadPid());
41 hdf["tpid"] = std::string(buf);
43 hdf["cmd"] = static_cast<int>(transport->getMethod());
44 hdf["url"] = transport->getUrl();
45 hdf["remote_host"] = transport->getRemoteHost();
46 hdf["remote_port"] = transport->getRemotePort();
48 auto const& headers = transport->getHeaders();
49 for (auto const& pair : headers) {
50 m_requestHeaders[pair.first] = pair.second;
52 int index = 0;
53 for (HeaderMap::const_iterator iter = m_requestHeaders.begin();
54 iter != m_requestHeaders.end(); ++iter) {
55 for (unsigned int i = 0; i < iter->second.size(); i++) {
56 Hdf header = hdf["headers"][index++];
57 header["name"] = iter->first;
58 header["value"] = iter->second[i];
62 size_t size;
63 const void *data = transport->getPostData(size);
64 if (size) {
65 String encoded = string_uuencode((const char *)data, safe_cast<int>(size));
66 hdf["post"] = encoded.get()->data();
67 } else {
68 hdf["post"] = "";
71 hdf.write(filename);
74 void ReplayTransport::replayInput(const char *filename) {
75 std::string fname = filename;
76 Config::ParseConfigFile(fname, m_ini, m_hdf);
77 replayInputImpl();
80 void ReplayTransport::replayInput(Hdf hdf) {
81 m_hdf.assign(hdf);
82 replayInputImpl();
85 void ReplayTransport::replayInputImpl() {
86 String postData = StringUtil::UUDecode(Config::GetString(m_ini, m_hdf, "post",
87 "", false));
88 m_postData = std::string(postData.data(), postData.size());
89 m_requestHeaders.clear();
90 auto headers_callback = [&](const IniSetting::Map& ini_h, const Hdf& hdf_h,
91 const std::string& /*ini_h_key*/) {
92 m_requestHeaders[Config::GetString(ini_h, hdf_h, "name",
93 "", false)].push_back(
94 Config::GetString(ini_h, hdf_h, "value", "", false)
97 Config::Iterate(headers_callback, m_ini, m_hdf, "headers", false);
100 const char *ReplayTransport::getUrl() {
101 return Config::Get(m_ini, m_hdf, "url", "", false);
104 const char *ReplayTransport::getRemoteHost() {
105 return Config::Get(m_ini, m_hdf, "remote_host", "", false);
107 uint16_t ReplayTransport::getRemotePort() {
108 return Config::GetUInt16(m_ini, m_hdf, "remote_port", 0, false);
111 const void *ReplayTransport::getPostData(size_t &size) {
112 size = m_postData.size();
113 return m_postData.data();
116 Transport::Method ReplayTransport::getMethod() {
117 return (Transport::Method)Config::GetInt32(m_ini, m_hdf, "cmd", false);
120 std::string ReplayTransport::getHeader(const char *name) {
121 assertx(name);
122 if (m_requestHeaders.find(name) != m_requestHeaders.end()) {
123 assertx(!m_requestHeaders[name].empty());
124 return m_requestHeaders[name][0];
126 return "";
129 const HeaderMap& ReplayTransport::getHeaders() {
130 return m_requestHeaders;
133 void ReplayTransport::addHeaderImpl(const char *name, const char *value) {
134 assertx(name && value);
135 m_responseHeaders[name].push_back(value);
138 void ReplayTransport::removeHeaderImpl(const char *name) {
139 assertx(name);
140 m_responseHeaders.erase(name);
143 void ReplayTransport::sendImpl(const void* data, int size, int code,
144 bool /*chunked*/, bool eom) {
145 m_code = code;
147 m_response = "HTTP/1.1 ";
148 m_response += folly::to<std::string>(code);
149 m_response += " ";
150 m_response += HttpProtocol::GetReasonString(m_code);
151 m_response += "\r\n";
153 for (HeaderMap::const_iterator iter = m_responseHeaders.begin();
154 iter != m_responseHeaders.end(); ++iter) {
155 for (unsigned int i = 0; i < iter->second.size(); i++) {
156 m_response += iter->first;
157 m_response += ": ";
158 m_response += iter->second[i];
159 m_response += "\r\n";
163 m_response += "\r\n";
164 m_response.append((const char *)data, size);
165 m_response += "\r\n";
166 if (eom) {
167 onSendEndImpl();
171 ///////////////////////////////////////////////////////////////////////////////