home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Borland / Borland C++ V5.02 / ISAPIEXT.PAK / ISAPIEXT.H < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-06  |  11.6 KB  |  339 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectWindows
  3. // Copyright (c) 1997 by Borland International, All Rights Reserved
  4. // written by Michael Sawczyn
  5. //----------------------------------------------------------------------------
  6. #ifndef TIsapiExtension_H
  7. #define TIsapiExtension_H
  8.  
  9. #include <httpext.h>
  10. #include <cstring.h>
  11. #include <classlib/thread.h>
  12. #include <iostream.h>
  13. #include <vector>
  14.  
  15. // convenience macros that allow embedded HTML tags to be streamed to the
  16. // user's browser.
  17. #define HEAD(s)         "<HEAD>" << s << "</HEAD>\n"
  18. #define TITLE(s)        "<TITLE>" << s << "</TITLE>\n"
  19. #define H1(s)           "<H1>" << s << "</H1>\n"
  20. #define H2(s)           "<H2>" << s << "</H2>\n"
  21. #define H3(s)           "<H3>" << s << "</H3>\n"
  22. #define H4(s)           "<H4>" << s << "</H4>\n"
  23. #define H5(s)           "<H5>" << s << "</H5>\n"
  24. #define H6(s)           "<H6>" << s << "</H6>\n"
  25. #define P(s)            "<P>" << s << "</P>\n"
  26. #define PRE(s)          "<PRE>" << s << "</PRE>\n"
  27. #define ADDRESS(s)      "<ADDRESS>" << s << "</ADDRESS>\n"
  28. #define DIRLIST(s)      "<DIR>" << s << "</DIR>\n"
  29. #define MENULIST(s)     "<MENU>" << s << "</MENU>\n"
  30. #define BULLETLIST(s)   "<UL>" << s << "</UL>\n"
  31. #define NUMBERLIST(s)   "<OL>" << s << "</OL>\n"
  32. #define LISTITEM(s)     "<LI>" << s << "</LI>\n"
  33. #define DEFN_LIST(s)    "<DL>\n" << s << "</DL>\n"
  34. #define DEFN_ITEM(t,d)  "<DT>" << t << "</DT>\n<DD>" << d << "</DD>\n"
  35. #define BEGINBODY       "<BODY>\n"
  36. #define ENDBODY         "</BODY>\n"
  37.  
  38. class TIsapiExtension;
  39.  
  40. // the stream buffer for the browser member of TIsapiExtension. Allows
  41. // output to be streamed to the user
  42. class TIsapiStreambuf : public streambuf
  43. {
  44. public:
  45.    TIsapiStreambuf(TIsapiExtension* aParent);
  46.    virtual ~TIsapiStreambuf();
  47.  
  48.    void        SetParent(TIsapiExtension* aParent);
  49.    virtual int overflow(int);
  50.    virtual int sync();
  51. protected:
  52. private:
  53.    // kept private to prevent accidental use
  54.    TIsapiStreambuf(const TIsapiStreambuf&);
  55.    TIsapiStreambuf& operator = (const TIsapiStreambuf&);
  56.  
  57.    static uint bufsize;
  58.    TIsapiExtension* Parent;
  59.    char* isapibuf;
  60. };
  61.  
  62. class TIsapiStream : public ostream
  63. {
  64.    friend class TIsapiExtension;
  65. public:
  66.    TIsapiStream(TIsapiExtension* parent);
  67.    virtual ~TIsapiStream();
  68.  
  69.    int sync();
  70.  
  71. protected:
  72. private:
  73.    void SetParent(TIsapiExtension* parent);
  74.  
  75.    // private to prevent accidental use
  76.    TIsapiStream();
  77.    TIsapiStream(const TIsapiStream&);
  78.    TIsapiStream& operator = (const TIsapiStream&);
  79. };
  80.  
  81. struct TFormVariable
  82. {
  83.    string Name;
  84.    string  Value;
  85.  
  86.    TFormVariable(string& name, string& value);
  87.    TFormVariable();
  88.    TFormVariable(const TFormVariable& v);
  89.    TFormVariable& operator=(const TFormVariable& v);
  90. };
  91.  
  92.  
  93. //Operation class for an ISAPI DLL. Represents the working object that
  94. //encapsulates the function of the server extension application.
  95. //
  96. //Various virtual functions are provided, and at the very least the program
  97. //should derive from this class and override the Run function to perform the
  98. //custom functionality for the extension.
  99.  
  100. class TIsapiExtension
  101. {
  102.    friend class TIsapiStreambuf;
  103. public:
  104.  
  105.    // modulename: the human readable name of the ISAPI application.
  106.    // If NULL is passed, the name of the application will be "IIS Extension"
  107.    TIsapiExtension(const char *modulename);
  108.    ~TIsapiExtension();
  109.  
  110.    // used to pass the pointer to the work object to the C functions that
  111.    // communicate with the server. Could have used a global pointer here and
  112.    // namespace'd it (and in fact did in an earlier version), but decided on a
  113.    // static pointer instead. Six of one, half dozen of the other ...
  114.  
  115.    static TIsapiExtension *GetIsapiInstance();
  116.  
  117.    // Called internally by the server communication routines to set information
  118.    // within the object.
  119.    void SetControlBlock(EXTENSION_CONTROL_BLOCK* lpEcb);
  120.  
  121.    // This is where the work is done. By default, simply informs the server
  122.    // that all processing proceeded normally, but does nothing.
  123.    //
  124.    // Override this function to perform any custom processing.
  125.    //
  126.    // This function is already threadsafe; it is surrounded by a critical
  127.    // section and cannot be entered by multiple threads.
  128.    //
  129.    // Output: Returns the success value (see TIsapiResult).
  130.    virtual DWORD Run();
  131.  
  132.    // Called when the server has requested that the ISAPI DLL unloads.
  133.    //
  134.    // Should return true if ok to unload, false otherwise. If ok to unload,
  135.    // Cleanup will be called next.
  136.    //
  137.    // Note: At times, the server may not make this request, but instead make
  138.    // a demand that the DLL unload. In this case, CanUnload will not be called,
  139.    // but instead Cleanup will be called directly.
  140.    virtual bool CanUnload();
  141.  
  142.    // Called when ISAPI DLL is about to unload.
  143.    //
  144.    // Any termination functions can be written here."] */
  145.    virtual void Cleanup();
  146.  
  147.    // Should return the human-readable name of the ISAPI extension.
  148.    // If not overridden, the default is "IIS Extension"
  149.     virtual const char *GetAppName();
  150.  
  151.    // This sends a complete HTTP server response header including the status,
  152.    // server version, message time, and MIME version. It then sends the <HTML>
  153.    // tag to begin the document.
  154.    //
  155.    // Applications can override this function if they wish to send other
  156.    // than textual data, using the appropriate header format for the type of
  157.    // data to be sent.
  158.    //
  159.    // If overridden, the ISAPI application should append other HTTP headers
  160.    // such as the content type and content length, followed by an
  161.    // extra \r\n
  162.    virtual bool SendHeader(const char *tags = NULL);
  163.  
  164.    // Sends ending html information. By default, just sends </HTML>. Can override
  165.    // to provide increased functionality, but should still finish with either a
  166.    // call to TIsapiExtension::SendFooter or simply send the </HTML> tag to
  167.    // the browser.
  168.    virtual void SendFooter();
  169.  
  170.    // clears the browser stream. A double dispatch mechanism for convenience
  171.    void flush();
  172.  
  173.    // returns the information the derived class has requested be placed
  174.    // in the event log
  175.    const char *GetLogInfo();
  176.  
  177.    // sets data that will later be written to the event log
  178.    void SetLogInfo(const char *info);
  179.  
  180.    // Returns a null-terminated string containing the query information. This
  181.    // is equivalent to the CGI variable QUERY_STRING.
  182.    const char *GetQueryString();
  183.  
  184.    // The total number of bytes to be received from the client.
  185.    // This is equivalent to the CGI variable CONTENT_LENGTH.
  186.  
  187.    // If this value is -1, then there are 4 gigabytes or more of available data.
  188.    int GetTotalBytesReceived();
  189.  
  190.    // returns a variable, either a system variable (eg., REMOTE_HOST,
  191.    // REMOTE_ADDR, etc.) or a form variable
  192.    bool GetVariable(const char *varName, char *buffer, DWORD bufferlen);
  193.  
  194.    // Returns data that has been sent by the server. Can be NULL.
  195.    string GetVariable(const char *varName);
  196.  
  197.    // Returns data that has been sent by the server. Can be NULL.
  198.    bool    GetData(char **data);
  199.  
  200.    // This sends the data specified by the URL to the client as if the client
  201.    // had requested that URL. The null-terminated URL pointed to by url must
  202.    // be on the server and must not specify protocol information (that is,
  203.    // it must begin with a "/"). No further processing is required after
  204.    // this call.
  205.    bool    SendFromURL(const char *url);
  206.  
  207.    // This function requests that the server convert the logical path
  208.    // (specified by the url parameter) to a server-specific physical path,
  209.    // which is returned in path. Only pathsize characters will be written,
  210.    // so the path array should be at least _MAX_PATH in size.
  211.    bool    GetPhysicalPath(const char *url, char *path, int pathsize);
  212.  
  213.    // This sends a 302 (URL Redirect) message to the client. No further
  214.    // processing is needed after the call. This operation is similar to
  215.    // specifying "URI: <URL>" in a CGI script header. The url variable should
  216.    // point to a null-terminated string of URL.
  217.    bool    RedirectToURL(const char *url);
  218.  
  219.    // Stream that can be used to write information to the user's browser.
  220.    TIsapiStream& browser;
  221.  
  222.    // Used to provide thread safety.
  223.    static TCriticalSection cs;
  224. protected:
  225.    enum TIsapiResult
  226.    {
  227.       Success = HSE_STATUS_SUCCESS,    // The ISAPI application has finished processing. The
  228.                                        // server can disconnect and free up allocated resources.
  229.  
  230.       KeepConnection = HSE_STATUS_SUCCESS_AND_KEEP_CONN,
  231.                                        // The ISAPI application has finished processing and the
  232.                                        // server should wait for the next HTTP request if the
  233.                                        // client supports persistent connections. The application
  234.                                        // should return this only if it was able to send the
  235.                                        // correct content length header to the client. The server
  236.                                        // is not required to keep the session open. The
  237.                                        // application should return this value only if it has
  238.                                        // sent a connection: a keep-alive header to the client.
  239.  
  240.       Pending = HSE_STATUS_PENDING,    // The ISAPI application has queued the request for
  241.                                        // processing and will notify the server when it has
  242.                                        // finished. See HSE_REQ_DONE_WITH_SESSION under the
  243.                                        // ServerSupportFunction function.
  244.  
  245.       Error = HSE_STATUS_ERROR         // The ISAPI application has encountered an error while
  246.                                        // processing the request. The server can disconnect and
  247.                                        // free up allocated resources.
  248.    };
  249.  
  250.    // Holds various information about the connection with the server.
  251.    EXTENSION_CONTROL_BLOCK *ecb;
  252.  
  253.    // Used to ensure only one instance of this object is active at any
  254.    // given time.
  255.    static TIsapiExtension *gInstance;
  256.  
  257.    // these strip the form variables from either the parameter string
  258.    // (for GET calls) or the input stream (for POST calls). DLL does not need
  259.    // to know or care which type of call was made.
  260.    void    GetFVsFromString(const char *s);
  261.    void    GetFVsFromStream();
  262.  
  263.    // converts %xx hex values to char values
  264.    unsigned char dd2c(char d1, char d2);
  265.  
  266. private:
  267.    bool DefaultHeader;
  268.    // Holds the data obtained from the server.
  269.    char   *data;
  270.    // Human-readable name of the ISAPI server extension.
  271.    string  name;
  272.    char    LogInfo[HSE_LOG_BUFFER_LEN];
  273.    std::vector<TFormVariable> FormVariables;
  274. };
  275.  
  276.  
  277. inline
  278. void TIsapiStreambuf::SetParent(TIsapiExtension* aParent)
  279. {
  280.    Parent = aParent;
  281. }
  282.  
  283. inline
  284. int TIsapiStream::sync()
  285. {
  286.    return bp->sync();
  287. }
  288.  
  289. inline
  290. void TIsapiStream::SetParent(TIsapiExtension* parent)
  291. {
  292.    dynamic_cast<TIsapiStreambuf*>(bp)->SetParent(parent);
  293. }
  294.  
  295. inline
  296. TIsapiExtension* TIsapiExtension::GetIsapiInstance()
  297. {
  298.    return gInstance;
  299. }
  300.  
  301. inline
  302. void TIsapiExtension::flush()
  303. {
  304.    browser.flush();
  305. }
  306.  
  307. inline
  308. const char* TIsapiExtension::GetLogInfo()
  309. {
  310.    return LogInfo;
  311. }
  312.  
  313. inline
  314. const char *TIsapiExtension::GetAppName()
  315. {
  316.    return name.c_str();
  317. }
  318.  
  319. inline
  320. const char* TIsapiExtension::GetQueryString()
  321. {
  322.    if (ecb)
  323.       return ecb->lpszQueryString;
  324.  
  325.    return "";
  326. }
  327.  
  328. inline
  329. int TIsapiExtension::GetTotalBytesReceived()
  330. {
  331.    if (ecb)
  332.       return ecb->cbTotalBytes;
  333.  
  334.    return 0;
  335. }
  336.  
  337.  
  338. #endif
  339.