•HTTP Server/THTTPServer.cp

//  THTTPServer.cp - Macintosh OpenTransport Network HTTP Server class object
// 
// Apple Macintosh Developer Technical Support
// Written by:  Vinne Moscaritolo
//
//  Copyright (work in progress)  Apple Computer, Inc All rights reserved.
//
// You may incorporate this sample code into your applications without
// restriction, though the sample code has been provided "AS IS" and the
// responsibility for its operation is 100% yours.  However, what you are
// not permitted to do is to redistribute the source as "DSC Sample Code"
// after having made changes. If you're going to re-distribute the source,
// we require that you make it clear in the source that the code was
// descended from Apple Sample Code, but that you've made changes.
// 
 
#include <Resources.h>
#include <OSUtils.h>
#include <strstream.h>
#include <iomanip.h>
 
#include "THTTPServer.h"
#include "TGMT.h"
#include "TAddrInet.h"
 
 
//Get Flagship name
Boolean  GetFlagshipName( char str[] );
Boolean  GetFlagshipName( char str[] )
{
    Handle h ;  
    if(h = GetResource('STR ',-16413));             // get flagship name
    else if(h = GetResource('STR ',-16096));        // get user name
    else { str[0] = '\0'; return false;}
 
    HLock(h);
    strncpy(str,*h +1, **h);
    str[**h] = '\0';
    HUnlock(h);
 
    return true;
}
 
// ---------------------------------------------------------------------------
//   THTTPServerApp
// ---------------------------------------------------------------------------
//  Default Constructor
 
THTTPServerApp::THTTPServerApp()
{
        
    GetFlagshipName(fDescriptor.GetServiceName());  // ***** fix this latter
    fDescriptor.Unstream( "????" );
 
    fServer = new THTTPServer();
    fServer->Open( &fDescriptor);
}
 
// ---------------------------------------------------------------------------
//   ~TNetworkServerApp
// ---------------------------------------------------------------------------
//  Destructor
 
THTTPServerApp::~THTTPServerApp()
{
    if(fServer) delete fServer;
};
 
// ---------------------------------------------------------------------------
//   THTTPServerApp::Start()
// ---------------------------------------------------------------------------
//  
 
void THTTPServerApp::Start()
{
// handle any specific startup issues.      
 
    TNetworkServerApp::Start();     // call the inherited Start
}
 
 
// ---------------------------------------------------------------------------
//   THTTPServer
// ---------------------------------------------------------------------------
//  Default Constructor
 
THTTPServer::THTTPServer()
{
}
 
// ---------------------------------------------------------------------------
//   ~THTTPServer
// ---------------------------------------------------------------------------
//  Destructor
 
THTTPServer::~THTTPServer()
{
 
};
 
// ---------------------------------------------------------------------------
//   THTTPServer:: Factory()
// ---------------------------------------------------------------------------
//  Factory
 
TNetworkSession* THTTPServer:: SessionFactory()
{
    return  new THTTPSession(this);
}
 
 
// ---------------------------------------------------------------------------
//   THTTPSession
// ---------------------------------------------------------------------------
//  Default Constructor
 
THTTPSession::THTTPSession(THTTPServer* theServer): TNetworkSession(theServer)
{
}
 
// ---------------------------------------------------------------------------
//   ~THTTPSession
// ---------------------------------------------------------------------------
//  Destructor
 
THTTPSession::~THTTPSession()
{
 
};
 
void dumpInterfaceInfo (ostream &os, EndpointRef  ep);
void dumpPortInfo(ostream &os, EndpointRef  ep);
 
#define CRLF "\r\n"
 
 
// ---------------------------------------------------------------------------
//  THTTPSession::Run
// ---------------------------------------------------------------------------
//  THTTP Session thread
 
void* THTTPSession::Run()
{
    TNetworkIOStream&  nio   = GetStreamRef();
    TGmt        currentTime;
    
 
// record time
    currentTime.Now();
     
        
// send Reply
 
// header
    nio << "HTTP/1.0 200 OK" << CRLF;
    nio << "MIME-Version: 1.0" << CRLF;
    nio << "Content-type: text/html" << CRLF;
    nio << "Date: " << currentTime << CRLF;
    nio << "Server: Knucklehead /1.0" << CRLF;
    nio <<  CRLF;
 
// body
    TNetworkEndpointDescriptor* epd = fServer->GetEPD();
    TAddrInet addr  =  &fCallInfo.addr ;
    TAcceptorInfo stats;
    
    nio << "<HEAD>";
//  nio << "<META HTTP-EQUIV=\"Refresh\" CONTENT=0>";
    nio << "<TITLE>Test Page</TITLE></HEAD><BODY>";
    nio << "<H2>Vinnie's OpenTransport HTTP Test Server</H2>";
    
    nio << "<Table BORDER=0 CELLSPACING=2 CELLPADDING=0><b>"; 
    nio << "<b>Server Info: </b>"; 
    nio << "<TR><TD><b>Name:</b></TD><TD>" << epd->GetServiceName() << "</TD></TR>";
    nio << "<TR><TD><b>Date:</b></TD><TD>" << currentTime << "</TD></TR>";
        if( fServer->GetStats(&stats)){
        nio << "<TR><TD><b>Active Sessions:</b></TD><TD>" << stats.fActiveSessions << "</TD></TR>";
        nio << "<TR><TD><b>Free:</b></TD><TD>" << stats.fFreeSessions << "</TD></TR>";
        nio << "<TR><TD><b>Accepted:</b></TD><TD>" << stats.fAcceptedSessions << "</TD></TR>";
        nio << "<TR><TD><b>Rejected:</b></TD><TD>" << stats.fRejectedSessions << "</TD></TR>";
        nio << "<TR><TD><b>Up Time:</b></TD><TD>" << (int) (stats.fUpTime / 60) << " min </TD></TR>";
        nio << "<TR><TD><b>Client:</b></TD><TD>" << addr << "</TD></TR>";
        nio << "<TR><TD><b>StackSpace:</b></TD><TD>" << StackSpace() << "</TD></TR>";
        
        
            };
    nio << "</Table><p>" << flush;
    
    dumpInterfaceInfo(nio, fEndPoint);
    nio << "</BODY>\r\n" << CRLF ;
    nio << CRLF << flush ;
 
 
    int cntr = 16;
    while(cntr--) {
            Yield();
        }
     
     return nil;
}
 
 
 
 
        
    static char* busNames[] =
    {
        "Unknown",
        "MthrBrd",
        "NuBus",
        "PCI",
        "GeoPort",
        "PCMCIA",
        "Bus6",
        "Bus7",
        "Bus8",
        "Bus9",
        "Bus10",
        "Bus11",
        "Bus12",
        "Bus13",
        "Bus14",
        "Bus15"
    };
 
    static char* MACtypes[] = {
                "<<unknown type(0)>>",
                "ADEV Devices",
                "MDEV Devices",
                "LocalTalk Devices",
                "IRTalk Devices",
                "TokenRing Devices",
                "ISDN Devices",
                "ATM Devices",
                "SMDS Devices",
                "Serial Devices",
                "Ethernet Devices",
                "SLIP Devices",
                "PPP Devices",
                "Modem Devices",
                "100MB Ethernet Devices",
                "FDDI Devices",
                "ATM LANE Devices",
                "ATM SNAP Devices"
                };
 
void dumpPortInfo(ostream &os, EndpointRef  ep)
{
//  OTPortRef           port;
    OTPortRecord        portInfo;
    int                 index = 0;
    
//  port = ::OTGetProviderPortRef(ep); // doesnt work yet
//  if( ::OTFindPortByRef(&portInfo, port) ){   
        os << "<TR></TR>";
    if ( ::OTGetIndexedPort(&portInfo, index) ) {
        UInt16 dev = ::OTGetDeviceTypeFromPortRef(portInfo.fRef);
        UInt16 Bus = ::OTGetBusTypeFromPortRef(portInfo.fRef);
        os << "<TR><TD><b>Port " << index << "</b></TD></TR>";
        os << "<TR><TD>Name:</TD><TD>" << portInfo.fPortName << "</TD></TR>";
        os << "<TR><TD>Bus:</TD><TD> " << MACtypes[dev] << "</TD></TR>";
        os << "<TR><TD>Module:</TD><TD>" << portInfo.fModuleName << "</TD></TR>";
        os << "<TR><TD>Bus:</TD><TD> " << busNames[Bus] << "</TD></TR>";
        if( portInfo.fSlotID[0] ) os << "<TR><TD>SlotInfo:</TD><TD>" << portInfo.fSlotID << "</TD></TR>";
        if( portInfo.fResourceInfo[0] )  os << "<TR><TD>ResourceInfo:</TD><TD>" << portInfo.fResourceInfo << "</TD></TR>";
        os << "<TR><TD>Flags:</TD><TD>";
            if( portInfo.fInfoFlags & kOTPortIsDLPI) os << "DLPI ";
            if( portInfo.fInfoFlags & kOTPortIsTPI) os <<  "TPI ";
            if( portInfo.fInfoFlags & kOTPortCanYield) os << "Can-Yield ";
            if( portInfo.fInfoFlags & kOTPortIsSystemRegistered) os << "System  ";
            if( portInfo.fInfoFlags & kOTPortIsAlias) os << "Alias  ";
        os << "</TD></TR>";
    };
    
}
void dumpInterfaceInfo (ostream &os, EndpointRef  ep)
{
InetInterfaceInfo   info;
int     index = 0;
char    buf[32];
 
    while ( ! ::OTInetGetInterfaceInfo( &info, index) )
        {
            os << "<Table BORDER=0 CELLSPACING=2 CELLPADDING=0><b>"; 
                if(index == kDefaultInetInterface)  os <<  "Default"; else   os << "Provider: " << index;  os << "</b> ";
            ::OTInetHostToString( info.fAddress, buf);              os <<  "<TR><TD>Address:</TD><TD>" << buf << "</TD></TR>";
            ::OTInetHostToString( info.fNetmask, buf);              os <<  "<TR><TD>NetMask:</TD><TD>" << buf << "</TD></TR>";
            ::OTInetHostToString( info.fBroadcastAddr, buf);        os <<  "<TR><TD>Broadcast:</TD><TD>" << buf << "</TD></TR>";
            ::OTInetHostToString( info.fDefaultGatewayAddr, buf);   os <<  "<TR><TD>Gateway:</TD><TD>" << buf << "</TD></TR>";
            ::OTInetHostToString( info.fAddress, buf);              os <<  "<TR><TD>DNS:</TD><TD>" << buf << "</TD></TR>";
            os << "<TR><TD>Domain:</TD><TD>" << info.fDomainName << "</TD></TR>";
            dumpPortInfo(os,ep);
            os << "</Table><p>";
            index++;
    };
}