From 72fac7f0e38edd6294bccbd7809d541435ec48d0 Mon Sep 17 00:00:00 2001 From: cxl Date: Wed, 13 Oct 2010 20:00:18 +0000 Subject: [PATCH] .uppdev git-svn-id: svn://ultimatepp.org/upp/trunk@2784 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- uppdev/AccessKey/main.cpp | 2 +- uppdev/ArrayCtrlMargin/main.cpp | 3 +- uppdev/ScgiHello/ScgiHello.cpp | 87 ++++++++++++++++++++++++++++ uppdev/ScgiHello/ScgiHello.upp | 14 +++++ uppdev/ScgiHello/htdocs/index.html | 21 +++++++ uppdev/ScgiHello/init | 5 ++ uppdev/ScgiHello/lighttpd.conf | 27 +++++++++ uppdev/ScgiServer/ScgiServer.cpp | 82 ++++++++++++++++++++++++++ uppdev/ScgiServer/ScgiServer.h | 38 ++++++++++++ uppdev/ScgiServer/ScgiServer.upp | 9 +++ uppdev/ScgiServer/init | 4 ++ uppdev/ToolTipCrash/ToolTipCrash.upp | 9 +++ uppdev/ToolTipCrash/main.cpp | 53 +++++++++++++++++ 13 files changed, 352 insertions(+), 2 deletions(-) create mode 100644 uppdev/ScgiHello/ScgiHello.cpp create mode 100644 uppdev/ScgiHello/ScgiHello.upp create mode 100644 uppdev/ScgiHello/htdocs/index.html create mode 100644 uppdev/ScgiHello/init create mode 100644 uppdev/ScgiHello/lighttpd.conf create mode 100644 uppdev/ScgiServer/ScgiServer.cpp create mode 100644 uppdev/ScgiServer/ScgiServer.h create mode 100644 uppdev/ScgiServer/ScgiServer.upp create mode 100644 uppdev/ScgiServer/init create mode 100644 uppdev/ToolTipCrash/ToolTipCrash.upp create mode 100644 uppdev/ToolTipCrash/main.cpp diff --git a/uppdev/AccessKey/main.cpp b/uppdev/AccessKey/main.cpp index 9b8e04aeb..a83760a3a 100644 --- a/uppdev/AccessKey/main.cpp +++ b/uppdev/AccessKey/main.cpp @@ -18,5 +18,5 @@ AccessKey::AccessKey() GUI_APP_MAIN { Ctrl::AddFlags(Ctrl::AKD_CONSERVATIVE); - AccessKey().Run(); + AccessKey().Run(Accept()); } diff --git a/uppdev/ArrayCtrlMargin/main.cpp b/uppdev/ArrayCtrlMargin/main.cpp index 2527e1905..58e641e0d 100644 --- a/uppdev/ArrayCtrlMargin/main.cpp +++ b/uppdev/ArrayCtrlMargin/main.cpp @@ -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"); } diff --git a/uppdev/ScgiHello/ScgiHello.cpp b/uppdev/ScgiHello/ScgiHello.cpp new file mode 100644 index 000000000..d87233957 --- /dev/null +++ b/uppdev/ScgiHello/ScgiHello.cpp @@ -0,0 +1,87 @@ +#include +#include + +#include + +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 &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(); +} diff --git a/uppdev/ScgiHello/ScgiHello.upp b/uppdev/ScgiHello/ScgiHello.upp new file mode 100644 index 000000000..5118d6c83 --- /dev/null +++ b/uppdev/ScgiHello/ScgiHello.upp @@ -0,0 +1,14 @@ +description "Hello World as a SCGI Server\377"; + +uses + Core, + ScgiServer; + +file + htdocs/index.html, + lighttpd.conf, + ScgiHello.cpp; + +mainconfig + "" = ""; + diff --git a/uppdev/ScgiHello/htdocs/index.html b/uppdev/ScgiHello/htdocs/index.html new file mode 100644 index 000000000..b534a7acf --- /dev/null +++ b/uppdev/ScgiHello/htdocs/index.html @@ -0,0 +1,21 @@ + +ScgiHello + +

Hello World

+ + + +

Hello via POST form

+
+Name: + + + + +
+ + + diff --git a/uppdev/ScgiHello/init b/uppdev/ScgiHello/init new file mode 100644 index 000000000..c6391c920 --- /dev/null +++ b/uppdev/ScgiHello/init @@ -0,0 +1,5 @@ +#ifndef _ScgiHello_icpp_init_stub +#define _ScgiHello_icpp_init_stub +#include "Core/init" +#include "ScgiServer/init" +#endif diff --git a/uppdev/ScgiHello/lighttpd.conf b/uppdev/ScgiHello/lighttpd.conf new file mode 100644 index 000000000..dcbf26ad0 --- /dev/null +++ b/uppdev/ScgiHello/lighttpd.conf @@ -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 + )) +) diff --git a/uppdev/ScgiServer/ScgiServer.cpp b/uppdev/ScgiServer/ScgiServer.cpp new file mode 100644 index 000000000..7c3917021 --- /dev/null +++ b/uppdev/ScgiServer/ScgiServer.cpp @@ -0,0 +1,82 @@ +#include + +#include +#include + +#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(); + } + } +} diff --git a/uppdev/ScgiServer/ScgiServer.h b/uppdev/ScgiServer/ScgiServer.h new file mode 100644 index 000000000..e4fabf975 --- /dev/null +++ b/uppdev/ScgiServer/ScgiServer.h @@ -0,0 +1,38 @@ +#ifndef _ScgiServer_ScgiServer_h +#define _ScgiServer_ScgiServer_h + +#include + +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 serverVars; + dword clientIP; + bool hasPostData; + +private: + typedef ScgiServer CLASSNAME; +}; + +#endif + diff --git a/uppdev/ScgiServer/ScgiServer.upp b/uppdev/ScgiServer/ScgiServer.upp new file mode 100644 index 000000000..7fe4d275e --- /dev/null +++ b/uppdev/ScgiServer/ScgiServer.upp @@ -0,0 +1,9 @@ +description "Simple Common Gateway Interface\377"; + +uses + Web; + +file + ScgiServer.cpp, + ScgiServer.h; + diff --git a/uppdev/ScgiServer/init b/uppdev/ScgiServer/init new file mode 100644 index 000000000..c76cba3eb --- /dev/null +++ b/uppdev/ScgiServer/init @@ -0,0 +1,4 @@ +#ifndef _ScgiServer_icpp_init_stub +#define _ScgiServer_icpp_init_stub +#include "Web/init" +#endif diff --git a/uppdev/ToolTipCrash/ToolTipCrash.upp b/uppdev/ToolTipCrash/ToolTipCrash.upp new file mode 100644 index 000000000..5872304d3 --- /dev/null +++ b/uppdev/ToolTipCrash/ToolTipCrash.upp @@ -0,0 +1,9 @@ +uses + CtrlLib; + +file + main.cpp; + +mainconfig + "" = "GUI"; + diff --git a/uppdev/ToolTipCrash/main.cpp b/uppdev/ToolTipCrash/main.cpp new file mode 100644 index 000000000..48671f9eb --- /dev/null +++ b/uppdev/ToolTipCrash/main.cpp @@ -0,0 +1,53 @@ +#include +using namespace Upp; +#define IMAGECLASS Imgs +#define IMAGEFILE +#include + +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(); +}