POST
This commit is contained in:
Binary file not shown.
+2
-1
@@ -22,7 +22,8 @@ LIBS="-ldl -lm -lpthread "
|
|||||||
SRCFLAGS="-D EXEC_NAME=\"$GF\" -D PLATFORM_NAME=\"linux\""
|
SRCFLAGS="-D EXEC_NAME=\"$GF\" -D PLATFORM_NAME=\"linux\""
|
||||||
|
|
||||||
echo "Compliling executable..."
|
echo "Compliling executable..."
|
||||||
time -p $COMPILER src/linux_fastcgi.cpp $SRCFLAGS $FLAGS $LIBS -o bin/$GF.$BUILDMODE.linux.bin
|
#time -p
|
||||||
|
$COMPILER src/linux_fastcgi.cpp $SRCFLAGS $FLAGS $LIBS -o bin/$GF.$BUILDMODE.linux.bin 2>&1
|
||||||
|
|
||||||
if [ $? -eq 0 ]
|
if [ $? -eq 0 ]
|
||||||
then
|
then
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ protected:
|
|||||||
bool close_socket;
|
bool close_socket;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::map<std::string, std::string> Pairs;
|
typedef StringMap Pairs;
|
||||||
|
|
||||||
std::vector<int> listen_sockets;
|
std::vector<int> listen_sockets;
|
||||||
std::vector<std::string> listen_unlink;
|
std::vector<std::string> listen_unlink;
|
||||||
|
|||||||
+22
-15
@@ -1,6 +1,6 @@
|
|||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
|
|
||||||
#define RENDER() extern "C" void render()
|
#define RENDER() extern "C" void render()
|
||||||
|
|
||||||
typedef void (*call_handler)();
|
typedef void (*call_handler)();
|
||||||
typedef void (*request_handler)(Request* request);
|
typedef void (*request_handler)(Request* request);
|
||||||
@@ -30,12 +30,12 @@ string process_html_literal(string content, string file_name)
|
|||||||
string pc;
|
string pc;
|
||||||
string HT_START = "context->print(R\"(";
|
string HT_START = "context->print(R\"(";
|
||||||
string HT_END = ")\");";
|
string HT_END = ")\");";
|
||||||
|
|
||||||
u8 mode = 0;
|
u8 mode = 0;
|
||||||
bool inside_quote = false;
|
bool inside_quote = false;
|
||||||
string code_buffer = "";
|
string code_buffer = "";
|
||||||
bool is_field = false;
|
bool is_field = false;
|
||||||
|
|
||||||
for(u32 i = 0; i < content.length(); i++)
|
for(u32 i = 0; i < content.length(); i++)
|
||||||
{
|
{
|
||||||
char c = content[i];
|
char c = content[i];
|
||||||
@@ -53,10 +53,10 @@ string process_html_literal(string content, string file_name)
|
|||||||
if(is_field)
|
if(is_field)
|
||||||
{
|
{
|
||||||
pc.append(
|
pc.append(
|
||||||
HT_END +
|
HT_END +
|
||||||
"echo(html_escape( " +
|
"echo(html_escape( " +
|
||||||
code_buffer +
|
code_buffer +
|
||||||
" )); " +
|
" )); " +
|
||||||
HT_START
|
HT_START
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -67,7 +67,7 @@ string process_html_literal(string content, string file_name)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
code_buffer.append(1, c);
|
code_buffer.append(1, c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(!inside_quote && c == '<' && content[i+1] == '?')
|
else if(!inside_quote && c == '<' && content[i+1] == '?')
|
||||||
@@ -85,11 +85,11 @@ string process_html_literal(string content, string file_name)
|
|||||||
}
|
}
|
||||||
mode = 1;
|
mode = 1;
|
||||||
}
|
}
|
||||||
else if(c == '\"')
|
/*else if(c == '\"')
|
||||||
{
|
{
|
||||||
inside_quote = !inside_quote;
|
inside_quote = !inside_quote;
|
||||||
pc.append(1, c);
|
pc.append(1, c);
|
||||||
}
|
}*/
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pc.append(1, c);
|
pc.append(1, c);
|
||||||
@@ -115,7 +115,7 @@ string preprocess(string content, string file_name)
|
|||||||
if(end_pos != string::npos)
|
if(end_pos != string::npos)
|
||||||
{
|
{
|
||||||
u32 len = token.length() + 3 + end_pos - i;
|
u32 len = token.length() + 3 + end_pos - i;
|
||||||
html_buffer.append(content.substr(i, len));
|
html_buffer.append(content.substr(i, len - (token.length() == 0 ? 3 : 0)));
|
||||||
i += len - 1;
|
i += len - 1;
|
||||||
pc.append(process_html_literal(html_buffer, file_name));
|
pc.append(process_html_literal(html_buffer, file_name));
|
||||||
}
|
}
|
||||||
@@ -128,17 +128,24 @@ string preprocess(string content, string file_name)
|
|||||||
else if(mode == 1)
|
else if(mode == 1)
|
||||||
{
|
{
|
||||||
if(isspace(c) || c == '>')
|
if(isspace(c) || c == '>')
|
||||||
|
{
|
||||||
mode = 2;
|
mode = 2;
|
||||||
|
if(token.length() > 0)
|
||||||
|
html_buffer.append(1, c);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
token.append(1, c);
|
token.append(1, c);
|
||||||
html_buffer.append(1, c);
|
html_buffer.append(1, c);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if(!inside_quote && c == '<' && isalpha(content[i+1]))
|
else if(!inside_quote && c == '<' && (content[i+1] == '>' || isalpha(content[i+1])))
|
||||||
{
|
{
|
||||||
mode = 1;
|
mode = 1;
|
||||||
token = "";
|
token = "";
|
||||||
html_buffer = "";
|
html_buffer = "";
|
||||||
html_buffer.append(1, c);
|
if(content[i+1] != '>')
|
||||||
|
html_buffer.append(1, c);
|
||||||
}
|
}
|
||||||
else if(c == '\"')
|
else if(c == '\"')
|
||||||
{
|
{
|
||||||
@@ -203,7 +210,7 @@ SharedUnit* compile_shared_unit(string file_name)
|
|||||||
|
|
||||||
printf("(i) compiled unit %s\n", file_name.c_str());
|
printf("(i) compiled unit %s\n", file_name.c_str());
|
||||||
|
|
||||||
load_shared_unit(su);
|
load_shared_unit(su);
|
||||||
|
|
||||||
return(su);
|
return(su);
|
||||||
}
|
}
|
||||||
@@ -241,7 +248,7 @@ void invoke(Request* req, string file_name)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
su->on_setup(req);
|
su->on_setup(req);
|
||||||
su->on_render();
|
su->on_render();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -249,4 +256,4 @@ void invoke(Request* req, string file_name)
|
|||||||
void invoke(string file_name)
|
void invoke(string file_name)
|
||||||
{
|
{
|
||||||
return(invoke(context, file_name));
|
return(invoke(context, file_name));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ string implode(StringList l, string delim = "\n")
|
|||||||
string html_escape(string s)
|
string html_escape(string s)
|
||||||
{
|
{
|
||||||
string result;
|
string result;
|
||||||
|
|
||||||
for(u32 i = 0; i < s.length(); i++)
|
for(u32 i = 0; i < s.length(); i++)
|
||||||
{
|
{
|
||||||
char c = s[i];
|
char c = s[i];
|
||||||
@@ -111,4 +111,21 @@ string html_escape(f64 a)
|
|||||||
u64 int_val(string s, u32 base = 10)
|
u64 int_val(string s, u32 base = 10)
|
||||||
{
|
{
|
||||||
return(strtoll(s.c_str(), 0, base));
|
return(strtoll(s.c_str(), 0, base));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string nibble(string div, string& haystack)
|
||||||
|
{
|
||||||
|
auto pos = haystack.find(div);
|
||||||
|
if(pos == string::npos)
|
||||||
|
{
|
||||||
|
auto result = haystack;
|
||||||
|
haystack.clear();
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto result = haystack.substr(0, pos);
|
||||||
|
haystack.erase(0, pos+div.length());
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+2
-1
@@ -5,6 +5,7 @@ struct Settings {
|
|||||||
string LIT_ESC = "3d5b5_1";
|
string LIT_ESC = "3d5b5_1";
|
||||||
string CONTENT_TYPE = "text/html; charset=utf-8";
|
string CONTENT_TYPE = "text/html; charset=utf-8";
|
||||||
string SOCKET_PATH = "/run/uce.sock";
|
string SOCKET_PATH = "/run/uce.sock";
|
||||||
|
string TMP_UPLOAD = "/tmp";
|
||||||
u32 LISTEN_PORT = 9993;
|
u32 LISTEN_PORT = 9993;
|
||||||
|
|
||||||
} Config;
|
} Config;
|
||||||
|
|||||||
@@ -110,3 +110,8 @@ time_t file_mtime(string file_name)
|
|||||||
return(info.st_mtime);
|
return(info.st_mtime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void unlink(string file_name)
|
||||||
|
{
|
||||||
|
remove(file_name.c_str());
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
//#include <unordered_map>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@@ -32,5 +33,11 @@ typedef long long s64;
|
|||||||
typedef std::map<string, string> StringMap;
|
typedef std::map<string, string> StringMap;
|
||||||
typedef std::vector<string> StringList;
|
typedef std::vector<string> StringList;
|
||||||
|
|
||||||
|
struct UploadedFile {
|
||||||
|
string file_name;
|
||||||
|
string tmp_name;
|
||||||
|
u32 size;
|
||||||
|
};
|
||||||
|
|
||||||
#include "dtree.h"
|
#include "dtree.h"
|
||||||
|
|
||||||
|
|||||||
+7
-3
@@ -6,14 +6,18 @@
|
|||||||
#include "uri.h"
|
#include "uri.h"
|
||||||
|
|
||||||
struct FastCGIRequest {
|
struct FastCGIRequest {
|
||||||
|
|
||||||
StringMap params;
|
StringMap params;
|
||||||
|
StringMap get;
|
||||||
|
StringMap post;
|
||||||
|
std::vector<UploadedFile> uploaded_files;
|
||||||
|
|
||||||
StringMap header;
|
StringMap header;
|
||||||
URI uri;
|
|
||||||
|
|
||||||
std::string in;
|
std::string in;
|
||||||
std::string out;
|
std::string out;
|
||||||
std::string err;
|
std::string err;
|
||||||
|
|
||||||
f64 time_init;
|
f64 time_init;
|
||||||
f64 time_start;
|
f64 time_start;
|
||||||
f64 time_end;
|
f64 time_end;
|
||||||
|
|||||||
@@ -137,6 +137,7 @@ struct URI {
|
|||||||
result[URI::decode(key)] = URI::decode(value);
|
result[URI::decode(key)] = URI::decode(value);
|
||||||
key = "";
|
key = "";
|
||||||
value = "";
|
value = "";
|
||||||
|
is_key = true;
|
||||||
}
|
}
|
||||||
else if(is_key)
|
else if(is_key)
|
||||||
{
|
{
|
||||||
@@ -153,6 +154,48 @@ struct URI {
|
|||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static StringMap parse_multipart(string q, string boundary, std::vector<UploadedFile>& uploaded_files)
|
||||||
|
{
|
||||||
|
StringMap result;
|
||||||
|
|
||||||
|
auto i = boundary.length();
|
||||||
|
while(i < q.length())
|
||||||
|
{
|
||||||
|
auto end_pos = q.find(boundary, i);
|
||||||
|
if(end_pos != string::npos)
|
||||||
|
{
|
||||||
|
string field = q.substr(i, end_pos - i);
|
||||||
|
nibble(":", field);
|
||||||
|
string ftype = trim(nibble(";", field));
|
||||||
|
if(ftype == "form-data")
|
||||||
|
{
|
||||||
|
nibble("=\"", field);
|
||||||
|
string field_name = nibble("\"", field);
|
||||||
|
result[field_name] = field.substr(4, field.length()-6);
|
||||||
|
}
|
||||||
|
else if(ftype == "attachment")
|
||||||
|
{
|
||||||
|
nibble("=\"", field);
|
||||||
|
UploadedFile f;
|
||||||
|
f.tmp_name = Config.TMP_UPLOAD + to_string(rand());
|
||||||
|
f.file_name = nibble("\"", field);
|
||||||
|
string bin = field.substr(4, field.length()-6);
|
||||||
|
f.size = bin.length();
|
||||||
|
file_put_contents(f.tmp_name, bin);
|
||||||
|
uploaded_files.push_back(f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// we're done
|
||||||
|
end_pos = q.length();
|
||||||
|
}
|
||||||
|
i = end_pos + boundary.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
static string decode(string q)
|
static string decode(string q)
|
||||||
{
|
{
|
||||||
string result;
|
string result;
|
||||||
|
|||||||
+26
-10
@@ -11,9 +11,6 @@ int handle_request(FastCGIRequest& request) {
|
|||||||
// server receives all parameters. There may be more data coming on the
|
// server receives all parameters. There may be more data coming on the
|
||||||
// standard input stream.
|
// standard input stream.
|
||||||
request.time_init = microtime();
|
request.time_init = microtime();
|
||||||
request.out.reserve(128 * 1024);
|
|
||||||
request.in.reserve(128 * 1024);
|
|
||||||
request.err.reserve(128 * 1024);
|
|
||||||
if (request.params.count("REQUEST_URI"))
|
if (request.params.count("REQUEST_URI"))
|
||||||
return 0; // OK, continue processing
|
return 0; // OK, continue processing
|
||||||
else
|
else
|
||||||
@@ -42,20 +39,39 @@ int handle_complete(FastCGIRequest& request) {
|
|||||||
// event occurs when the parameters and standard input streams are
|
// event occurs when the parameters and standard input streams are
|
||||||
// both closed, and thus the request is complete.
|
// both closed, and thus the request is complete.
|
||||||
request.time_start = microtime();
|
request.time_start = microtime();
|
||||||
|
|
||||||
request.header["Content-Type"] = Config.CONTENT_TYPE;
|
request.header["Content-Type"] = Config.CONTENT_TYPE;
|
||||||
request.uri = URI::parse(request.params["REQUEST_URI"]);
|
request.get = URI::parse_query(request.params["QUERY_STRING"]);
|
||||||
request.uri.parts["scheme"] = request.params["REQUEST_SCHEME"];
|
|
||||||
request.uri.parts["method"] = request.params["REQUEST_METHOD"];
|
string ct_info = request.params["CONTENT_TYPE"];
|
||||||
request.uri.parts["host"] = request.params["HTTP_HOST"];
|
string ct_type = nibble(";", ct_info);
|
||||||
|
|
||||||
|
if(request.params["REQUEST_METHOD"] == "POST")
|
||||||
|
{
|
||||||
|
if(ct_type == "multipart/form-data")
|
||||||
|
{
|
||||||
|
nibble("boundary=", ct_info);
|
||||||
|
request.post = URI::parse_multipart(request.in, string("--")+ct_info, request.uploaded_files);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
request.post = URI::parse_query(request.in);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
invoke(&request, request.params["SCRIPT_FILENAME"]);
|
invoke(&request, request.params["SCRIPT_FILENAME"]);
|
||||||
|
|
||||||
string headers = var_dump(request.header, "", "\r\n") + "\r\n";
|
string headers = var_dump(request.header, "", "\r\n") + "\r\n";
|
||||||
request.out = headers + request.out;
|
request.out = headers + request.out;
|
||||||
|
|
||||||
|
for( auto &f : request.uploaded_files)
|
||||||
|
{
|
||||||
|
unlink(f.tmp_name);
|
||||||
|
}
|
||||||
|
|
||||||
request.time_end = microtime();
|
request.time_end = microtime();
|
||||||
printf("(r) %s\t%0.6fs\t%0.1fkB\n",
|
printf("(r) %s\t%0.6fs\t%0.1fkB\n",
|
||||||
request.params["REQUEST_URI"].c_str(),
|
request.params["REQUEST_URI"].c_str(),
|
||||||
request.time_end - request.time_start,
|
request.time_end - request.time_start,
|
||||||
(f32)(request.out.length()/1024)
|
(f32)(request.out.length()/1024)
|
||||||
);
|
);
|
||||||
|
|||||||
+16
-2
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
|
|
||||||
RENDER()
|
void show_stuff()
|
||||||
{
|
{
|
||||||
//context->header["Content-Type"] = "text/plain";
|
//context->header["Content-Type"] = "text/plain";
|
||||||
//echo(to_string(time())+"\n");
|
//echo(to_string(time())+"\n");
|
||||||
@@ -8,7 +8,7 @@ RENDER()
|
|||||||
<html>
|
<html>
|
||||||
Mwahahaaha <?= time() ?>
|
Mwahahaaha <?= time() ?>
|
||||||
<div>hello world: <?= context->params["HTTP_HOST"] ?></div>
|
<div>hello world: <?= context->params["HTTP_HOST"] ?></div>
|
||||||
<pre style="background:rgba(0,0,0,0.1);max-height: 200px; overflow: auto;">
|
<pre>
|
||||||
Display the date using any or all of the following elements:
|
Display the date using any or all of the following elements:
|
||||||
|
|
||||||
%a: abbreviated day name (i.e. mon, tue, wed)
|
%a: abbreviated day name (i.e. mon, tue, wed)
|
||||||
@@ -174,3 +174,17 @@ Lifewire is part of the Dotdash publishing family.
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RENDER()
|
||||||
|
{
|
||||||
|
|
||||||
|
<html>
|
||||||
|
<link rel="stylesheet" href='style.css?v=1'></link>
|
||||||
|
<h1>
|
||||||
|
<a href="index.uce">UCE Test</a>:
|
||||||
|
Index
|
||||||
|
</h1>
|
||||||
|
<? show_stuff(); ?>
|
||||||
|
<pre><?= var_dump(context->params) ?></pre>
|
||||||
|
</html>
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
|
||||||
|
|
||||||
|
RENDER()
|
||||||
|
{
|
||||||
|
|
||||||
|
<html>
|
||||||
|
<link rel="stylesheet" href='style.css?v=1'></link>
|
||||||
|
<h1>
|
||||||
|
<a href="index.uce">UCE Test</a>:
|
||||||
|
Index
|
||||||
|
</h1>
|
||||||
|
<ul>
|
||||||
|
<li><a href="hello.uce">Hello</a></li>
|
||||||
|
<li><a href="post.uce">Form Post</a></li>
|
||||||
|
<li><a href="post-multipart.uce">Form Multipart Post</a></li>
|
||||||
|
</ul>
|
||||||
|
<pre><?= var_dump(context->params) ?></pre>
|
||||||
|
</html>
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
|
||||||
|
void show_form()
|
||||||
|
{
|
||||||
|
|
||||||
|
<form action="?" method="post" enctype="multipart/form-data">
|
||||||
|
<div>
|
||||||
|
<label>Some text:</label>
|
||||||
|
<input type="text" name="fühld" value="<?= context->post["fühld"] ?>"/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label>Some multiline text:</label>
|
||||||
|
<textarea name="field2"><?= context->post["field2"] ?></textarea>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<input type="submit" value="Submit Form"/>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
RENDER()
|
||||||
|
{
|
||||||
|
|
||||||
|
<>
|
||||||
|
<link rel="stylesheet" href='style.css?v=1'></link>
|
||||||
|
<h1>
|
||||||
|
<a href="index.uce">UCE Test</a>:
|
||||||
|
Multipart-Encoded Form POST
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
<? show_form(); ?>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<label>Parsed POST fields</label>
|
||||||
|
<pre><?= var_dump(context->post) ?></pre>
|
||||||
|
|
||||||
|
<label>Raw POST content</label>
|
||||||
|
<pre><?= context->in ?></pre>
|
||||||
|
|
||||||
|
<label>CGI Params</label>
|
||||||
|
<pre><?= var_dump(context->params) ?></pre>
|
||||||
|
</>
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
|
||||||
|
void show_form()
|
||||||
|
{
|
||||||
|
|
||||||
|
<form action="?" method="post">
|
||||||
|
<div>
|
||||||
|
<label>Some text:</label>
|
||||||
|
<input type="text" name="field" value="<?= context->post["field"] ?>"/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label>Some multiline text:</label>
|
||||||
|
<textarea name="field2"><?= context->post["field2"] ?></textarea>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<input type="submit" value="Submit Form"/>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
RENDER()
|
||||||
|
{
|
||||||
|
|
||||||
|
<html>
|
||||||
|
<link rel="stylesheet" href='style.css?v=1'></link>
|
||||||
|
<h1>
|
||||||
|
<a href="index.uce">UCE Test</a>:
|
||||||
|
Form POST
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
<? show_form(); ?>
|
||||||
|
|
||||||
|
<label>Parsed POST fields</label>
|
||||||
|
<pre><?= var_dump(context->post) ?></pre>
|
||||||
|
|
||||||
|
<label>Raw POST content</label>
|
||||||
|
<pre><?= context->in ?></pre>
|
||||||
|
|
||||||
|
<label>CGI Params</label>
|
||||||
|
<pre><?= var_dump(context->params) ?></pre>
|
||||||
|
</html>
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
* {
|
||||||
|
font-family: inherit;
|
||||||
|
font-size: inherit;
|
||||||
|
box-sizing: inherit;
|
||||||
|
color: inherit;
|
||||||
|
line-height: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: yellow;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 200%;
|
||||||
|
padding-top: 8px;
|
||||||
|
padding-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
max-width: 1024px;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
font-family: Tahoma, Helvetica, Arial;
|
||||||
|
font-size: 1.2em;
|
||||||
|
box-sizing: border-box;
|
||||||
|
background: #24f;
|
||||||
|
color: white;
|
||||||
|
line-height: 150%;
|
||||||
|
}
|
||||||
|
|
||||||
|
form > div, label {
|
||||||
|
display: block;
|
||||||
|
padding-top: 8px;
|
||||||
|
padding-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input, textarea {
|
||||||
|
background: rgba(0,0,0,0.2);
|
||||||
|
border: 2px solid rgba(255,255,255,0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=submit], button {
|
||||||
|
padding: 8px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=submit]:hover, button:hover {
|
||||||
|
color: yellow;
|
||||||
|
background: rgba(0,0,0,0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=text], textarea {
|
||||||
|
padding: 8px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=text]:hover, textarea:hover {
|
||||||
|
background: rgba(0,0,0,0.25);
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea {
|
||||||
|
height: 20%;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
height: 20%;
|
||||||
|
overflow: auto;
|
||||||
|
padding. 8px;
|
||||||
|
border: 2px solid rgba(0,0,0,0.2);
|
||||||
|
background: rgba(100,100,100,0.15);
|
||||||
|
}
|
||||||
@@ -15,13 +15,15 @@ Library
|
|||||||
Bugs
|
Bugs
|
||||||
=================================
|
=================================
|
||||||
- shell_escape()
|
- shell_escape()
|
||||||
- Include Path
|
- include path
|
||||||
|
- current request working directory
|
||||||
|
- preprocessor
|
||||||
|
- nested tags
|
||||||
|
|
||||||
|
|
||||||
Framework
|
Framework
|
||||||
=================================
|
=================================
|
||||||
- DTree
|
- DTree
|
||||||
- POST
|
|
||||||
- File Upload
|
- File Upload
|
||||||
- Proxy mode
|
- Proxy mode
|
||||||
- WebSockets
|
- WebSockets
|
||||||
|
|||||||
Reference in New Issue
Block a user