output buffers
This commit is contained in:
parent
8195154e4c
commit
af29d51536
Binary file not shown.
@ -509,9 +509,30 @@ FastCGIServer::process_write_request(Connection& connection, RequestID id,
|
||||
}
|
||||
if ((request.in_closed || request.status != 0) &&
|
||||
!request.output_closed) {
|
||||
|
||||
request.out =
|
||||
var_dump(request.header, "", "\r\n") +
|
||||
var_dump(request.set_cookies, "", "\r\n") +
|
||||
"\r\n";
|
||||
|
||||
for(auto obs : request.ob_stack)
|
||||
{
|
||||
request.out += obs->str();
|
||||
delete obs;
|
||||
}
|
||||
request.ob_stack.clear();
|
||||
|
||||
write_data(connection.output_buffer, id, request.out, FCGI_STDOUT);
|
||||
write_data(connection.output_buffer, id, request.err, FCGI_STDERR);
|
||||
|
||||
request.time_end = microtime();
|
||||
printf("(r) pid:%i\t%s\t%0.6fs\t%0.1fkB\n",
|
||||
my_pid,
|
||||
request.params["REQUEST_URI"].c_str(),
|
||||
request.time_end - request.time_start,
|
||||
(f32)(request.out.length()/1024)
|
||||
);
|
||||
|
||||
FCGI_EndRequestRecord complete;
|
||||
bzero(&complete, sizeof(complete));
|
||||
complete.header.version = FCGI_VERSION_1;
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
String process_html_literal(Request* context, SharedUnit* su, String content)
|
||||
{
|
||||
String pc;
|
||||
String HT_START = "context->print(R\"(";
|
||||
String HT_START = "print(R\"(";
|
||||
String HT_END = ")\");";
|
||||
|
||||
u8 mode = 0;
|
||||
@ -63,7 +63,7 @@ String process_html_literal(Request* context, SharedUnit* su, String content)
|
||||
{
|
||||
pc.append(
|
||||
HT_END +
|
||||
"echo(html_escape( " +
|
||||
"print(html_escape( " +
|
||||
code_buffer +
|
||||
" )); " +
|
||||
HT_START
|
||||
@ -299,17 +299,17 @@ void compiler_invoke(Request* context, String file_name, DTree& call_param)
|
||||
if(!su)
|
||||
{
|
||||
printf("Error loading unit %s\n", file_name.c_str());
|
||||
context->print("Error loading unit: "+file_name);
|
||||
print("Error loading unit: "+file_name);
|
||||
}
|
||||
else if(!su->on_render)
|
||||
{
|
||||
context->header["Content-Type"] = "text/plain";
|
||||
context->print("Compiler error: "+su->compiler_messages);
|
||||
print("Compiler error: "+su->compiler_messages);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(su->compiler_messages.length() > 0)
|
||||
context->print(su->compiler_messages);
|
||||
print(su->compiler_messages);
|
||||
else
|
||||
{
|
||||
String prev_wd = get_cwd();
|
||||
|
||||
@ -184,14 +184,14 @@ String json_encode(DTree t)
|
||||
String json_decode_String(String s, u32& i, char termination_char)
|
||||
{
|
||||
String result;
|
||||
//echo("json_decode_String " + s.substr(i) + "\n");
|
||||
//print("json_decode_String " + s.substr(i) + "\n");
|
||||
while(i < s.length())
|
||||
{
|
||||
char c = s[i];
|
||||
if(c == termination_char)
|
||||
{
|
||||
i += 1;
|
||||
//echo("json_decode_String = " + result + "\n");
|
||||
//print("json_decode_String = " + result + "\n");
|
||||
return(result);
|
||||
}
|
||||
else if(c == '\\')
|
||||
@ -289,7 +289,7 @@ DTree json_decode_value(String s, u32& i)
|
||||
String value = "";
|
||||
json_consume_space(s, i);
|
||||
char c = s[i];
|
||||
//echo("json_decode_value " + s.substr(i) + "\n");
|
||||
//print("json_decode_value " + s.substr(i) + "\n");
|
||||
if(c == '"' || c == '\'') // String value
|
||||
{
|
||||
result.type = 'S';
|
||||
@ -329,7 +329,7 @@ DTree json_decode_map(String s, u32& i)
|
||||
result.type = 'M';
|
||||
String key = "";
|
||||
json_consume_space(s, i);
|
||||
//echo("json_decode_map " + s.substr(i) + "\n");
|
||||
//print("json_decode_map " + s.substr(i) + "\n");
|
||||
while(i < s.length())
|
||||
{
|
||||
char c = s[i];
|
||||
@ -352,7 +352,7 @@ DTree json_decode_map(String s, u32& i)
|
||||
i += 1;
|
||||
DTree v = json_decode_value(s, i);
|
||||
//result._map[key] = json_decode_value(s, i);
|
||||
//echo("KV " + key + " = " + to_String(v) + "\n");
|
||||
//print("KV " + key + " = " + to_String(v) + "\n");
|
||||
//printf("map add %s (%c) \n", key.c_str(), s[i]);
|
||||
result._map[key] = v;
|
||||
}
|
||||
@ -372,4 +372,28 @@ DTree json_decode(String s)
|
||||
return(json_decode_value(s, i));
|
||||
}
|
||||
|
||||
void ob_start()
|
||||
{
|
||||
context->ob_start();
|
||||
}
|
||||
|
||||
void ob_close()
|
||||
{
|
||||
delete context->ob;
|
||||
context->ob_stack.pop_back();
|
||||
if(context->ob_stack.size() == 0)
|
||||
ob_start();
|
||||
}
|
||||
|
||||
String ob_get()
|
||||
{
|
||||
return(context->ob->str());
|
||||
}
|
||||
|
||||
String ob_get_close()
|
||||
{
|
||||
String result = context->ob->str();
|
||||
ob_close();
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
@ -24,3 +24,8 @@ DTree json_decode(String s);
|
||||
|
||||
String var_dump(StringMap map, String prefix = "", String postfix = "\n");
|
||||
String var_dump(StringList slist, String prefix = "", String postfix = "\n");
|
||||
|
||||
void ob_start();
|
||||
void ob_clear();
|
||||
String ob_get_clear();
|
||||
String ob_get();
|
||||
|
||||
@ -247,7 +247,7 @@ u64 socket_connect(String host, short port)
|
||||
auto sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if(sockfd < 0)
|
||||
{
|
||||
echo("SOCKET ERROR (could not open socket)\n");
|
||||
print("SOCKET ERROR (could not open socket)\n");
|
||||
perror("SOCKET ERROR ");
|
||||
return(0);
|
||||
}
|
||||
@ -259,7 +259,7 @@ u64 socket_connect(String host, short port)
|
||||
|
||||
if(connect(sockfd, (struct sockaddr*) &addr, sizeof(addr)) < 0)
|
||||
{
|
||||
echo("SOCKET ERROR (could not connect to address " + String(host) + ":" + std::to_string(port) + ")\n");
|
||||
print("SOCKET ERROR (could not connect to address " + String(host) + ":" + std::to_string(port) + ")\n");
|
||||
perror("SOCKET ERROR ");
|
||||
return(0);
|
||||
}
|
||||
@ -438,3 +438,4 @@ void on_child_exit(int sig)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -50,9 +50,10 @@ void Request::invoke(String file_name, DTree& call_param)
|
||||
compiler_invoke(this, file_name, call_param);
|
||||
}
|
||||
|
||||
void Request::print(String s)
|
||||
void Request::ob_start()
|
||||
{
|
||||
out.append(s);
|
||||
ob_stack.push_back(new std::ostringstream());
|
||||
ob = ob_stack.back();
|
||||
}
|
||||
|
||||
Request::~Request()
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
#include <sstream>
|
||||
|
||||
typedef unsigned char u8;
|
||||
typedef signed char s8;
|
||||
@ -17,6 +18,30 @@ typedef long long s64;
|
||||
|
||||
typedef std::string String;
|
||||
|
||||
String operator+(String lhs, u64 rhs) {
|
||||
return(lhs + std::to_string(rhs));
|
||||
}
|
||||
|
||||
String operator+(String lhs, u32 rhs) {
|
||||
return(lhs + std::to_string(rhs));
|
||||
}
|
||||
|
||||
String operator+(String lhs, s64 rhs) {
|
||||
return(lhs + std::to_string(rhs));
|
||||
}
|
||||
|
||||
String operator+(String lhs, s32 rhs) {
|
||||
return(lhs + std::to_string(rhs));
|
||||
}
|
||||
|
||||
String operator+(String lhs, f64 rhs) {
|
||||
return(lhs + std::to_string(rhs));
|
||||
}
|
||||
|
||||
String operator+(String lhs, f32 rhs) {
|
||||
return(lhs + std::to_string(rhs));
|
||||
}
|
||||
|
||||
#define DEBUG_MEMORY_OFF;
|
||||
#define NO_GLOBAL_ARENA_ALLOCATOR;
|
||||
|
||||
@ -105,9 +130,6 @@ void operator delete(void * p) throw()
|
||||
}
|
||||
#endif
|
||||
|
||||
//#define to_String(a) std::to_String(a)
|
||||
#define echo(s) context->print(s)
|
||||
|
||||
typedef std::map<String, String> StringMap;
|
||||
typedef std::vector<String> StringList;
|
||||
|
||||
@ -217,13 +239,21 @@ struct Request {
|
||||
MemoryArena* request_arena;
|
||||
|
||||
String in;
|
||||
std::vector<std::ostringstream*> ob_stack;
|
||||
std::ostringstream* ob;
|
||||
String out;
|
||||
String err;
|
||||
|
||||
bool is_finished = false;
|
||||
|
||||
f64 time_init;
|
||||
f64 time_start;
|
||||
f64 time_end;
|
||||
|
||||
struct Stats {
|
||||
u32 bytes_written;
|
||||
} stats;
|
||||
|
||||
struct Resources {
|
||||
std::vector<u64> sockets;
|
||||
std::vector<void*> mysql_connections;
|
||||
@ -231,7 +261,9 @@ struct Request {
|
||||
|
||||
void invoke(String file_name);
|
||||
void invoke(String file_name, DTree& call_param);
|
||||
void print(String s);
|
||||
|
||||
void ob_start();
|
||||
|
||||
~Request();
|
||||
|
||||
};
|
||||
@ -239,3 +271,11 @@ struct Request {
|
||||
typedef Request FastCGIRequest;
|
||||
|
||||
Request* context;
|
||||
|
||||
#include <iostream>
|
||||
|
||||
template <typename... Ts>
|
||||
void print(Ts... args)
|
||||
{
|
||||
((*context->ob << args), ...);
|
||||
}
|
||||
|
||||
@ -12,6 +12,8 @@ int handle_request(FastCGIRequest& request) {
|
||||
// standard input stream.
|
||||
request.request_arena = request_arena;
|
||||
request.time_init = microtime();
|
||||
request.ob_start(); // this one is for the headers
|
||||
request.ob_start(); // this one is for the content
|
||||
if (request.params.count("REQUEST_URI"))
|
||||
return 0; // OK, continue processing
|
||||
else
|
||||
@ -70,12 +72,6 @@ int handle_complete(FastCGIRequest& request) {
|
||||
request.invoke(request.params["SCRIPT_FILENAME"]);
|
||||
switch_to_system_alloc();
|
||||
|
||||
String headers =
|
||||
var_dump(request.header, "", "\r\n") +
|
||||
var_dump(request.set_cookies, "", "\r\n") +
|
||||
"\r\n";
|
||||
request.out = headers + request.out;
|
||||
|
||||
for( auto &f : request.uploaded_files)
|
||||
{
|
||||
unlink(f.tmp_name);
|
||||
@ -86,14 +82,6 @@ int handle_complete(FastCGIRequest& request) {
|
||||
|
||||
cleanup_mysql_connections();
|
||||
|
||||
request.time_end = microtime();
|
||||
printf("(r) pid:%i\t%s\t%0.6fs\t%0.1fkB\n",
|
||||
my_pid,
|
||||
request.params["REQUEST_URI"].c_str(),
|
||||
request.time_end - request.time_start,
|
||||
(f32)(request.out.length()/1024)
|
||||
);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -14,13 +14,13 @@ RENDER()
|
||||
|
||||
set_cookie("test-cookie-1", "test-value-1", time() + 30*60);
|
||||
set_cookie("test-cookie-2", "test-value-2", time() + 30*60*24);
|
||||
echo(var_dump(context->set_cookies));
|
||||
print(var_dump(context->set_cookies));
|
||||
|
||||
?></pre>
|
||||
Get
|
||||
<pre><?
|
||||
|
||||
echo(var_dump(context->cookies));
|
||||
print(var_dump(context->cookies));
|
||||
|
||||
?></pre>
|
||||
Params
|
||||
|
||||
@ -16,16 +16,16 @@ RENDER()
|
||||
<pre><?
|
||||
|
||||
t.set("String test");
|
||||
echo(String("String test: ") + t.to_string()+"\n");
|
||||
print(String("String test: ") + t.to_string()+"\n");
|
||||
|
||||
t.set(true);
|
||||
echo(String("bool test: ") + t.to_string()+"\n");
|
||||
print(String("bool test: ") + t.to_string()+"\n");
|
||||
|
||||
t.set(1234.5678);
|
||||
echo(String("float test: ") + t.to_string()+"\n");
|
||||
print(String("float test: ") + t.to_string()+"\n");
|
||||
|
||||
t.set(&t);
|
||||
echo(String("pointer test: ") + t.to_string()+"\n");
|
||||
print(String("pointer test: ") + t.to_string()+"\n");
|
||||
|
||||
?></pre>
|
||||
|
||||
@ -43,7 +43,7 @@ RENDER()
|
||||
t["g"]["x"]["y2"] = &t;
|
||||
t["g"]["x"]["y3"] = time();
|
||||
t["g"]["x"]["y4"] = "Ünicödä";
|
||||
echo(var_dump(t));
|
||||
print(var_dump(t));
|
||||
|
||||
?></pre>
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
void test_output()
|
||||
{
|
||||
echo("hello from include!");
|
||||
print("hello from include!");
|
||||
}
|
||||
|
||||
@ -26,8 +26,8 @@ RENDER()
|
||||
<li><a href="fileio.uce">File I/O</a></li>
|
||||
</ul>
|
||||
<pre><?
|
||||
echo("Worker PID: "+std::to_string(my_pid)+"\n");
|
||||
echo("Parent PID: "+std::to_string(parent_pid)+" \n");
|
||||
print("Worker PID: ", my_pid, "\n");
|
||||
print("Parent PID: ", parent_pid, " \n");
|
||||
?></pre>
|
||||
<pre><?= (var_dump(p)) ?></pre>
|
||||
</>
|
||||
|
||||
@ -29,14 +29,14 @@ RENDER()
|
||||
t["l"] = context->params;
|
||||
|
||||
String j;
|
||||
echo(j = json_encode(t));
|
||||
print(j = json_encode(t));
|
||||
|
||||
?></pre>
|
||||
|
||||
Parsed:
|
||||
|
||||
<pre><?
|
||||
echo(var_dump(
|
||||
print(var_dump(
|
||||
json_decode(j)
|
||||
));
|
||||
?></pre>
|
||||
@ -44,7 +44,7 @@ RENDER()
|
||||
Compare:
|
||||
|
||||
<pre><?
|
||||
echo(var_dump(
|
||||
print(var_dump(
|
||||
t
|
||||
));
|
||||
?></pre>
|
||||
|
||||
@ -17,7 +17,7 @@ RENDER()
|
||||
|
||||
auto sfd = memcache_connect();
|
||||
|
||||
echo(memcache_command(sfd, "stats"));
|
||||
print(memcache_command(sfd, "stats"));
|
||||
|
||||
?></pre>
|
||||
|
||||
@ -27,9 +27,9 @@ RENDER()
|
||||
|
||||
memcache_set(sfd, "test_key", "test_value");
|
||||
memcache_set(sfd, "test_key2", "test_value2");
|
||||
echo("raw:: "+memcache_command(sfd, "get test_key")+"\n");
|
||||
echo("get:: "+memcache_get(sfd, "test_key")+"\n");
|
||||
echo("multiple::\n"+var_dump(memcache_get_multiple(sfd, {"test_key", "test_key2"}))+"\n");
|
||||
print("raw:: "+memcache_command(sfd, "get test_key")+"\n");
|
||||
print("get:: "+memcache_get(sfd, "test_key")+"\n");
|
||||
print("multiple::\n"+var_dump(memcache_get_multiple(sfd, {"test_key", "test_key2"}))+"\n");
|
||||
|
||||
?></pre>
|
||||
|
||||
|
||||
@ -21,11 +21,11 @@ RENDER()
|
||||
MySQL con;
|
||||
if(con.connect("localhost", "root", ""))
|
||||
{
|
||||
echo("connection established\n");
|
||||
echo("error: "+con.error()+"\n");
|
||||
echo("quotation test: "+con.escape("‘\"' or 1=1;–.")+"\n");
|
||||
echo("query parse: "+con.parse_query_parameters(query, params)+"\n");
|
||||
echo(var_dump(con.query("SHOW DATABASES")));
|
||||
print("connection established\n");
|
||||
print("error: "+con.error()+"\n");
|
||||
print("quotation test: "+con.escape("‘\"' or 1=1;–.")+"\n");
|
||||
print("query parse: "+con.parse_query_parameters(query, params)+"\n");
|
||||
print(var_dump(con.query("SHOW DATABASES")));
|
||||
con.query("USE mysql");
|
||||
|
||||
?></pre>
|
||||
@ -34,7 +34,7 @@ RENDER()
|
||||
|
||||
<pre><?
|
||||
|
||||
echo(var_dump(con.query("SELECT * FROM user")));
|
||||
print(var_dump(con.query("SELECT * FROM user")));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -18,17 +18,17 @@ RENDER()
|
||||
if(action == "start")
|
||||
{
|
||||
session_start();
|
||||
echo("action: starting session");
|
||||
print("action: starting session");
|
||||
}
|
||||
else if(action == "store")
|
||||
{
|
||||
context->session["stored-value"] = make_session_id();
|
||||
echo("action: storing value "+context->session["stored-value"]);
|
||||
print("action: storing value "+context->session["stored-value"]);
|
||||
}
|
||||
else if(action == "destroy")
|
||||
{
|
||||
session_destroy();
|
||||
echo("action: destroying session");
|
||||
print("action: destroying session");
|
||||
}
|
||||
|
||||
<>
|
||||
@ -40,9 +40,9 @@ RENDER()
|
||||
Info
|
||||
<pre><?
|
||||
|
||||
echo(var_dump(context->cookies));
|
||||
echo("SESSION:\n");
|
||||
echo(var_dump(context->session));
|
||||
print(var_dump(context->cookies));
|
||||
print("SESSION:\n");
|
||||
print(var_dump(context->session));
|
||||
|
||||
?></pre>
|
||||
Params
|
||||
|
||||
27
test/string.uce
Normal file
27
test/string.uce
Normal file
@ -0,0 +1,27 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
RENDER()
|
||||
{
|
||||
DTree t;
|
||||
|
||||
<>
|
||||
<link rel="stylesheet" href='style.css'></link>
|
||||
<h1>
|
||||
<a href="index.uce">UCE Test</a>:
|
||||
Strings
|
||||
</h1>
|
||||
|
||||
<pre style="white-space: pre-wrap"><?
|
||||
|
||||
print(String("!") + 60*60*24);
|
||||
|
||||
?></pre>
|
||||
|
||||
Params
|
||||
<pre><?= var_dump(context->params) ?></pre>
|
||||
</>
|
||||
|
||||
}
|
||||
@ -10,7 +10,7 @@ RENDER()
|
||||
Working Directory
|
||||
</h1>
|
||||
<pre><?
|
||||
echo("Base WD: " + get_cwd() + "\n");
|
||||
print("Base WD: " + get_cwd() + "\n");
|
||||
context->invoke("test2/working-dir-test.uce");
|
||||
?></pre>
|
||||
<pre><?= var_dump(context->params) ?></pre>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user