Rename runtime/base/zend_* to zend-
[hiphop-php.git] / hphp / runtime / server / replay_transport.cpp
blob7a7a6e1e4d966eb1bc5a362b0674ff14c5f29bb3
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-2013 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 +----------------------------------------------------------------------+
17 #include "hphp/runtime/server/replay_transport.h"
18 #include "hphp/runtime/base/string_util.h"
19 #include "hphp/runtime/base/zend-functions.h"
20 #include "hphp/runtime/base/zend-string.h"
21 #include "hphp/util/process.h"
23 namespace HPHP {
24 ///////////////////////////////////////////////////////////////////////////////
26 void ReplayTransport::recordInput(Transport* transport, const char *filename) {
27 assert(transport);
29 Hdf hdf;
31 char buf[32];
32 snprintf(buf, sizeof(buf), "%u", Process::GetProcessId());
33 hdf["pid"] = string(buf);
34 snprintf(buf, sizeof(buf), "%" PRIx64, (int64_t)Process::GetThreadId());
35 hdf["tid"] = string(buf);
36 snprintf(buf, sizeof(buf), "%u", Process::GetThreadPid());
37 hdf["tpid"] = string(buf);
39 hdf["cmd"] = static_cast<int>(transport->getMethod());
40 hdf["url"] = transport->getUrl();
41 hdf["remote_host"] = transport->getRemoteHost();
42 hdf["remote_port"] = transport->getRemotePort();
44 transport->getHeaders(m_requestHeaders);
45 int index = 0;
46 for (HeaderMap::const_iterator iter = m_requestHeaders.begin();
47 iter != m_requestHeaders.end(); ++iter) {
48 for (unsigned int i = 0; i < iter->second.size(); i++) {
49 Hdf header = hdf["headers"][index++];
50 header["name"] = iter->first;
51 header["value"] = iter->second[i];
55 int size;
56 const void *data = transport->getPostData(size);
57 if (size) {
58 int len;
59 char *encoded = string_uuencode((const char *)data, size, len);
60 hdf["post"] = encoded;
61 free(encoded);
62 } else {
63 hdf["post"] = "";
66 hdf.write(filename);
69 void ReplayTransport::replayInput(const char *filename) {
70 m_hdf.open(filename);
71 replayInputImpl();
74 void ReplayTransport::replayInput(Hdf hdf) {
75 m_hdf.assign(hdf);
76 replayInputImpl();
79 void ReplayTransport::replayInputImpl() {
80 String postData = StringUtil::UUDecode(m_hdf["post"].get(""));
81 m_postData = string(postData.data(), postData.size());
82 m_requestHeaders.clear();
83 for (Hdf hdf = m_hdf["headers"].firstChild(); hdf.exists();
84 hdf = hdf.next()) {
85 m_requestHeaders[hdf["name"].get("")].push_back(hdf["value"].get(""));
89 const char *ReplayTransport::getUrl() {
90 return m_hdf["url"].get("");
93 const char *ReplayTransport::getRemoteHost() {
94 return m_hdf["remote_host"].get("");
96 uint16_t ReplayTransport::getRemotePort() {
97 return m_hdf["remote_port"].getUInt16(0);
100 const void *ReplayTransport::getPostData(int &size) {
101 size = m_postData.size();
102 return m_postData.data();
105 Transport::Method ReplayTransport::getMethod() {
106 return (Transport::Method)m_hdf["cmd"].getInt32();
109 std::string ReplayTransport::getHeader(const char *name) {
110 assert(name);
111 if (m_requestHeaders.find(name) != m_requestHeaders.end()) {
112 assert(!m_requestHeaders[name].empty());
113 return m_requestHeaders[name][0];
115 return "";
118 void ReplayTransport::getHeaders(HeaderMap &headers) {
119 headers = m_requestHeaders;
122 void ReplayTransport::addHeaderImpl(const char *name, const char *value) {
123 assert(name && value);
124 m_responseHeaders[name].push_back(value);
127 void ReplayTransport::removeHeaderImpl(const char *name) {
128 assert(name);
129 m_responseHeaders.erase(name);
132 void ReplayTransport::sendImpl(const void *data, int size, int code,
133 bool chunked) {
134 m_code = code;
136 m_response = "HTTP/1.1 ";
137 m_response += boost::lexical_cast<string>(code);
138 m_response += " ";
139 m_response += (m_code == 200 ? "OK" : "Internal Server Error");
140 m_response += "\r\n";
142 for (HeaderMap::const_iterator iter = m_responseHeaders.begin();
143 iter != m_responseHeaders.end(); ++iter) {
144 for (unsigned int i = 0; i < iter->second.size(); i++) {
145 m_response += iter->first;
146 m_response += ": ";
147 m_response += iter->second[i];
148 m_response += "\r\n";
152 m_response += "\r\n";
153 m_response.append((const char *)data, size);
154 m_response += "\r\n";
157 ///////////////////////////////////////////////////////////////////////////////