git-svn-id: svn://ultimatepp.org/upp/trunk@2784 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
cxl 2010-10-13 20:00:18 +00:00
parent bc64e40b89
commit 72fac7f0e3
13 changed files with 352 additions and 2 deletions

View file

@ -18,5 +18,5 @@ AccessKey::AccessKey()
GUI_APP_MAIN
{
Ctrl::AddFlags(Ctrl::AKD_CONSERVATIVE);
AccessKey().Run();
AccessKey().Run(Accept());
}

View file

@ -12,7 +12,8 @@ TestArrayMargin::TestArrayMargin()
{
array.SetRect(0,0,500,100);
Add(array);
array.AddColumn("test").Margin(0).Edit(eString);
array.AddColumn("test");
for(int
array.Add("item 1");
}

View file

@ -0,0 +1,87 @@
#include <Core/Core.h>
#include <Web/Web.h>
#include <ScgiServer/ScgiServer.h>
using namespace Upp;
class App : public ScgiServer {
private:
typedef App CLASSNAME;
void OnAccept();
void OnRequest();
void OnClosed();
void HelloViaGet();
void HelloViaPost();
public:
App(int port = 8787);
};
App::App(int port) : ScgiServer(port)
{
WhenAccepted = THISBACK(OnAccept);
WhenRequest = THISBACK(OnRequest);
WhenClosed = THISBACK(OnClosed);
}
void App::OnAccept()
{
Cout() << "Accepted connection from client " << FormatIP(clientIP) << "\n";
}
void App::HelloViaGet()
{
clientSock.Write(Format("Hello, %s!\r\n", query["NAME"]));
}
void App::HelloViaPost()
{
clientSock.Write(Format("Hello, %s!\r\n", post["NAME"]));
}
void App::OnRequest()
{
clientSock.Write("Content-Type: text/plain\r\n\r\n");
clientSock.Write("Message:\r\n");
//
// Should look at the server variable 'SCRIPT_NAME' to see:
// * /scgi/hello
// * /scgi/hello-form
//
// That method would be used for better application based
// request dispatching vs. HasPostData()
//
if (HasPostData()) {
HelloViaPost();
clientSock.Write("\r\nPost Data:\r\n");
for (int i=0; i < post.GetCount(); i++)
clientSock.Write(Format("%s = '%s'\r\n", post.GetKey(i), post.GetValue(i)));
} else
HelloViaGet();
clientSock.Write("\r\nQuery String:\r\n");
for (int i=0; i < query.GetCount(); i++)
clientSock.Write(Format("%s = '%s'\r\n", query.GetKey(i), query.GetValue(i)));
clientSock.Write("\r\nServer Variables:\r\n");
const Vector<String> &keys = serverVars.GetKeys();
for (int i=0; i < serverVars.GetCount(); i++)
clientSock.Write(Format("'%s' = '%s'\r\n", keys[i], serverVars.Get(keys[i])));
}
void App::OnClosed()
{
Cout() << "Connection with " << FormatIP(clientIP) << " closed\n";
}
CONSOLE_APP_MAIN
{
App app;
app.Run();
}

View file

@ -0,0 +1,14 @@
description "Hello World as a SCGI Server\377";
uses
Core,
ScgiServer;
file
htdocs/index.html,
lighttpd.conf,
ScgiHello.cpp;
mainconfig
"" = "";

View file

@ -0,0 +1,21 @@
<html>
<head><title>ScgiHello</title></head>
<body>
<h1>Hello World</h1>
<ul>
<li><a href="/scgi/hello?name=John">Hello John</a></li>
<li><a href="/scgi/hello?name=Jane">Hello Jane</a></li>
</ul>
<h1>Hello via POST form</h1>
<form method="POST" action="/scgi/hello-form">
Name:
<!-- To show post data, add an additional field -->
<input type="hidden" name="message" value="Hello" />
<input type="text" name="name" />
<input type="submit"/>
</form>
</body>
</html>

5
uppdev/ScgiHello/init Normal file
View file

@ -0,0 +1,5 @@
#ifndef _ScgiHello_icpp_init_stub
#define _ScgiHello_icpp_init_stub
#include "Core/init"
#include "ScgiServer/init"
#endif

View file

@ -0,0 +1,27 @@
# Example LigHTTPD server configuration
#
# Run with: lighttpd -D -f lighttpd.conf
#
# You must also manually execute ScgiHello
#
server.document-root = "./htdocs"
server.port = 3000
server.modules = ( "mod_scgi" )
mimetype.assign = (
".html" => "text/html",
".txt" => "text/plain",
".jpg" => "image/jpeg",
".png" => "image/png"
)
index-file.names = ( "index.html" )
scgi.server= ( "/scgi/" =>
(( "host" => "127.0.0.1",
"port" => 8787,
"check-local" => "disable",
"docroot" => "/" # remote server may use it's own docroot
))
)

View file

@ -0,0 +1,82 @@
#include <signal.h>
#include <Core/Core.h>
#include <Web/Web.h>
#include "ScgiServer.h"
using namespace Upp;
bool run = true;
void sighandler(int sig)
{
run = false;
}
ScgiServer::ScgiServer(int port)
{
this->port = port;
signal(SIGABRT, sighandler);
signal(SIGINT, sighandler);
signal(SIGTERM, sighandler);
}
void ScgiServer::Run()
{
ServerSocket(serverSock, port);
while (run) {
if (serverSock.Accept(clientSock, &clientIP)) {
WhenAccepted();
String sLen = clientSock.ReadUntil(':');
int len = atoi(sLen);
String data;
if (clientSock.IsOpen() && !clientSock.IsEof() && !clientSock.IsError()) {
// len + 1 = data plus the trailing , as in SCGI spec
data = clientSock.ReadCount(len+1, 3000);
}
String key;
int spos = 0;
for (int i=0; i < data.GetCount(); i++) {
if (data[i] == 0) {
if (key.IsEmpty())
key = data.Mid(spos, i-spos);
else {
String value = data.Mid(spos, i-spos);
serverVars.Add(key, value);
key.Clear();
}
spos = i + 1;
}
}
query.SetURL("?" + serverVars.Get("QUERY_STRING"));
hasPostData = false;
if (serverVars.Get("REQUEST_METHOD") == "POST") {
len = atoi(serverVars.Get("CONTENT_LENGTH"));
if (len > 0 && clientSock.IsOpen() && !clientSock.IsEof() &&
!clientSock.IsError())
{
data = clientSock.ReadCount(len, 3000);
post.SetURL("?" + data);
hasPostData = true;
}
}
WhenRequest();
clientSock.Close();
serverVars.Clear();
query.Clear();
WhenClosed();
}
}
}

View file

@ -0,0 +1,38 @@
#ifndef _ScgiServer_ScgiServer_h
#define _ScgiServer_ScgiServer_h
#include <Web/Web.h>
using namespace Upp;
class ScgiServer {
public:
Callback WhenAccepted;
Callback WhenRequest;
Callback WhenClosed;
HttpQuery query;
HttpQuery post;
ScgiServer(int port = 7800);
void Run();
dword ClientIP() { return clientIP; }
Socket ClientSock() { return clientSock; }
bool HasPostData() { return hasPostData; }
protected:
int port;
Socket serverSock, clientSock;
VectorMap<String,String> serverVars;
dword clientIP;
bool hasPostData;
private:
typedef ScgiServer CLASSNAME;
};
#endif

View file

@ -0,0 +1,9 @@
description "Simple Common Gateway Interface\377";
uses
Web;
file
ScgiServer.cpp,
ScgiServer.h;

4
uppdev/ScgiServer/init Normal file
View file

@ -0,0 +1,4 @@
#ifndef _ScgiServer_icpp_init_stub
#define _ScgiServer_icpp_init_stub
#include "Web/init"
#endif

View file

@ -0,0 +1,9 @@
uses
CtrlLib;
file
main.cpp;
mainconfig
"" = "GUI";

View file

@ -0,0 +1,53 @@
#include <CtrlLib/CtrlLib.h>
using namespace Upp;
#define IMAGECLASS Imgs
#define IMAGEFILE <CtrlLib/Ctrl.iml>
#include <Draw/iml.h>
struct Dlg : TopWindow{
Button b;
typedef Dlg CLASSNAME;
Dlg() {
Title("Dialog").Sizeable();
SetRect(0,0,300,200);
Add(b.TopPos(10,20).LeftPos(10,100));
b.SetLabel("OK");
b<<=THISBACK(DoStuffAndExit);
}
void DoStuffAndExit(){
Hide();
Progress p;
p.SetText("Pretending work...");
for(int i=0;i<100;i++){
Sleep(25);
p.Step();
}
Close();
}
};
struct App : TopWindow {
ToolBar tool;
typedef App CLASSNAME;
App() {
Title("My application with bars").Sizeable();
AddFrame(tool);
tool.Set(THISBACK(TBar));
}
void MenuFn() {
Dlg().Execute();
}
void TBar(Bar& bar) {
bar.Add("Function", Imgs::open(), THISBACK(MenuFn));
}
};
GUI_APP_MAIN {
App().Run();
}