SOL9 Sample: SolWebServer

SOL9 2.0 Samples

1 Screenshot


2 Source code

/*
 * SolWebServer.cpp 
 * Copyright (c) 2015 Antillia.com TOSHIYUKI ARAI. ALL RIGHTS RESERVED. 
 */


//2008/07/10 Directory::isExistent -> Directory::exists
// 2008/12/26 Removed cgi related lines. 
// 2012/07/03 Modified to catch an IException which can be thrown from HTTPListener.
// 2012/07/03 Modified to reshape statusBar in size method.

#define _WINSOCK_DEPRECATED_NO_WARNINGS 

#include <sol\ApplicationView.h>
#include <sol\ScrolledRichText.h>
#include <sol\Static.h>
#include <sol\Font.h>
#include <sol\Thread.h>
#include <sol\FolderTreeDialog.h>
#include <sol\SocketStream.h>
#include <sol\CriticalSection.h>
#include <sol\Profile.h>
#include <sol\String.h>
#include "ServerSettingDialog.h"

#include <sol\MessageFont.h>
#include <sol\FileVersionDialog.h>

#include <sol\Directory.h>

#include "HTTPListener.h"
#include "HTTPCommunicator.h"
#include "resource.h"

namespace SOL {

class SolWebServer :public ApplicationView {
private:
  String        version;
  MessageFont      font;
    HTTPListener*    thread;
  int          sizeArray[3];
  ScrolledRichText  text;

  String          docRoot;
  unsigned short    port;

  Profile        profile;
  ServerSettingDialog    serverSettingDialog;
  
  FileVersionDialog  fileVersion;

  StatusBar statusBar;


public:
  /**
   * Constructor
   */
  SolWebServer(Application& applet, const TCHAR* name, Args& args)
  :ApplicationView(applet, name, args)
  {
    version = "SolWebServer 1.1";
//  setText((const TCHAR*)version);
    fileVersion.create(this);

    Args ar;
    font.create(9);

    ar.reset();
    text.create(this, _T(""), ar);
    text . setFont(font);
    text . exLimitText(100*SIZE_1KB);  //100KB
    add(text);

    addCallback(XmNmenuCallback, IDM_START, this, 
      (Callback)&SolWebServer::start, NULL);
    addCallback(XmNmenuCallback, IDM_STOP, this, 
      (Callback)&SolWebServer::stop, NULL);
    addCallback(XmNmenuCallback, IDM_CLEAR, this, 
      (Callback)&SolWebServer::clear, NULL);
    addCallback(XmNmenuCallback, IDM_EXIT, this, 
      (Callback)&SolWebServer::terminate, NULL);
    addCallback(XmNmenuCallback, IDM_SETUP, this,
      (Callback)&SolWebServer::setup, NULL);
    addCallback(XmNmenuCallback, IDM_VERSION, this,
      (Callback)&SolWebServer::showVersion, NULL);

    addEventHandler(WM_CLOSE, this, 
      (Handler)&SolWebServer::close, NULL);

    ar.reset();
    statusBar.create(this, _T(""), ar);  

    restorePlacement();

    setProfile(_T("SolWebServer.conf"));

    ar.reset();
    ar.set(XmNwidth, 300);
    ar.set(XmNheight, 200);
    ar.set(XmNstyle, (ulong)WS_THICKFRAME);
    serverSettingDialog.create(this, _T("Server Setting"), ar);
    serverSettingDialog . addOkCallback(this, 
      (Callback)&SolWebServer::updateConfiguration);
    try {
      thread = new HTTPListener(text, getPort(), docRoot);
        thread -> start();
    } catch (...) {
      thread = NULL;
      TCHAR msg[1024];
      _stprintf_s(msg, CountOf(msg), _T("Failed to start HTTPListener.Default setting port=%d documentRoot=%s"),
        getPort(), 
        (const TCHAR*)docRoot);
      showMessageDialog(msg);
    }
  }

public:
  unsigned short  getPort() { return port; }

public:
  String&    getDocumentRoot() { return docRoot; }

public:
  const TCHAR*  getVersion() { return (const TCHAR*)version; }

private:
  void showVersion(Action& action)
  {
    fileVersion.popupAt(action);
  }

private:
  void start(Action& action)
  {
    stop(action);
    try {
      thread = new HTTPListener(this->text, this->port, this->docRoot);
      thread -> start();
    } catch (...) {
      thread = NULL;
      TCHAR msg[1024];
      _stprintf_s(msg, CountOf(msg), _T("Failed to start HTTPListener.Default setting port=%d documentRoot=%s"),
        getPort(), 
        (const TCHAR*)docRoot);
      showMessageDialog(msg);
      return;
    }

    statusBar . setText(0, 0, _T("Running"));
    TCHAR buffer[_MAX_PATH];
    clear(action);

    printf(_T("[SolWebserver restarted]\r\n"));
  
    _stprintf_s(buffer, CountOf(buffer), _T("PORT: %d  DOCUMENT: %s"), port, (const TCHAR*)docRoot);
    statusBar . setText(1, SBT_POPOUT, buffer);
    
  }

private:
  void stop(Action& action)
  {
    if (thread) {
      thread ->stop();
      // 1999.08.23 Added the following line.
      thread -> wait();
      delete thread;
      thread = NULL;
      statusBar . setText(0, 0, _T("Stopped"));

    }
  }

private:
  void setProfile(const TCHAR* file)
  {
    docRoot = _T("");
    port    = 80;

//    profile = new Profile();
    port = (unsigned short)profile.get(_T("SolWebServer"), _T("port"), 80);

    TCHAR doc[_MAX_PATH];
    TCHAR windir[_MAX_PATH];
    ::GetWindowsDirectory(windir, CountOf(windir));
    docRoot = windir;

    profile.get(_T("Document"), _T("root"), windir, doc, CountOf(doc));
    docRoot = doc;

    Printf(_T("Port %d\r\n"), port);
    Printf(_T("Root %s\r\n"), (const TCHAR*)docRoot);

    TCHAR buffer1[100];
    TCHAR buffer2[256];

    _stprintf_s(buffer1, CountOf(buffer1), _T("Running"));
    _stprintf_s(buffer2, CountOf(buffer2), _T("PORT: %d  DOCUMENT: %s"), port, (const TCHAR*)docRoot);
  //  StatusBar* statusbar = getStatusBar();

    statusBar.setParts(2, sizeArray);
    statusBar.setText(0,  0, buffer1);
    statusBar.setText(1, SBT_POPOUT, buffer2);
  }

public:    
  ~SolWebServer()
  {
    delete thread;
  }

private:
  void setup(Action& action)
  {
    POINT p;
    getCursorPos(&p);
    int w, h;
    serverSettingDialog . getSize(w, h);
    serverSettingDialog . reshape(p.x, p.y, w, h);
    serverSettingDialog . setPort(port);
    serverSettingDialog . setDocumentRoot((const TCHAR*)docRoot);

    serverSettingDialog . popup(action);
  }

private:
  void updateConfiguration(Action& action)
  {
    unsigned short p = (unsigned short)serverSettingDialog . getPort();
    TCHAR path1[_MAX_PATH];

    serverSettingDialog . getDocumentRoot(path1, CountOf(path1)-1);

    Directory dir;

    //if (p <=0 || p >65000) {
    if (p <0 || p >65535) {
      showMessageDialog("Error", "Invalid port number.", MB_OK);  

      return;
    }
    //2008/07/10 isExistent -> exists
    if (dir.exists(path1) == False) {
      showMessageDialog("Error", "Document root path does not exist.", MB_OK);  
      return;
    }

    port = p;
    docRoot = path1;

    profile . set(_T("SolWebServer"), _T("port"), port);
    profile . set(_T("Document"), _T("root"), (TCHAR*)docRoot);

    //Printf("PORT: %d  DOCUMENT: %s\r\n", port, (const TCHAR*)docRoot);
    serverSettingDialog . popdown(action);

    //clear(action);
    start(action);
    //append("[SolWebServer restarted]\r\n");
  }

private:
  void clear(Action& action)
  {
    text . clear();
  }

private:
  void terminate(Action& a)
  {
    // 1999.08.14
    if (thread) {
      thread -> stop();

      thread -> kill();
    }
    savePlacement();

    exit(a);
  }

private:
  void append(const TCHAR* string)
  {
    if (text.getTextLength() >=100*SIZE_1KB) {
      text.clear();
    }
    text.append(string);
    text.scrollCaret();
  }

private:
  void printf(const TCHAR* format,...)  
  {
    TCHAR buffer[SIZE_1KB];

    va_list pos;
    va_start(pos, format);
    _vsnprintf_s(buffer, CountOf(buffer), _TRUNCATE, format, pos);

    va_end(pos);

    append(buffer);
  }

private:
  long close(Event& event)
  {
    savePlacement();
    return defaultProc(event);
  }

private:
  //2012/07/03
  long size(Event& event) 
  {
    //ApplicationView::size(event);
    int w, h;
    event.getSize(w, h);
    sizeArray[0] = w/4;
    sizeArray[1] = -1;

    RECT r;
    statusBar.getWindowRect(&r);
    int hh = (r.bottom-r.top);
    statusBar.setParts(2, sizeArray);
    statusBar.reshape(0, h-hh, w, hh);

    text . reshape(0, 0, w,  h-hh);
    return 0;
  }
};

}

// Program entry point!

void  Main(int argc, TCHAR** argv)
{
  const String appClass = "SolWebServer";
  try {
    Application applet(appClass, argc, argv);

    Args args;
    args.set(XmNbackground, (COLOR_BTNFACE+1));

    //args.set(XmNmenuName, name);
    SolWebServer solWebServer(applet, appClass, args);
    solWebServer.realize();
    applet.run();

  } catch(Exception& ex) {
    MessageBox(NULL, _bstr_t(ex.getErrorMessage()), _T("SolWebServer"), MB_OK);

  } catch(...) {
    MessageBox(NULL, _T("Exception:Nonuknown"), _T("SolWebServer"), MB_OK);

  }
}


Last modified: 1 Feb 2017

Copyright (c) 2017 Antillia.com ALL RIGHTS RESERVED.