⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 httpform.cxx

📁 sloedgy open sip stack source code
💻 CXX
📖 第 1 页 / 共 5 页
字号:
/*
 * httpform.cxx
 *
 * Forms using HTTP user interface.
 *
 * Portable Windows Library
 *
 * Copyright (c) 1993-2002 Equivalence Pty. Ltd.
 *
 * The contents of this file are subject to the Mozilla Public License
 * Version 1.0 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
 * the License for the specific language governing rights and limitations
 * under the License.
 *
 * The Original Code is Portable Windows Library.
 *
 * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
 *
 * Contributor(s): ______________________________________.
 *
 * $Log: httpform.cxx,v $
 * Revision 1.2  2007/06/17 02:49:35  joegenbaclor
 * Introduced Global lock to PHTTPConfig
 *
 * Revision 1.1  2006/06/29 04:18:02  joegenbaclor
 * *** empty log message ***
 *
 * Revision 1.49  2004/04/24 06:27:56  rjongbloed
 * Fixed GCC 3.4.0 warnings about PAssertNULL and improved recoverability on
 *   NULL pointer usage in various bits of code.
 *
 * Revision 1.48  2004/04/03 08:22:20  csoutheren
 * Remove pseudo-RTTI and replaced with real RTTI
 *
 * Revision 1.47  2003/03/24 04:31:03  robertj
 * Added function to set and get strings from PConfig in correct format for
 *   use with HTTP form array contsructs.
 *
 * Revision 1.46  2002/11/22 06:20:26  robertj
 * Added extra space around data entry fields.
 * Added borders around arrays and composite fields.
 * Added multi-line data entry for HTTPStringField > 128 characters.
 *
 * Revision 1.45  2002/11/06 22:47:25  robertj
 * Fixed header comment (copyright etc)
 *
 * Revision 1.44  2002/10/10 04:43:44  robertj
 * VxWorks port, thanks Martijn Roest
 *
 * Revision 1.43  2002/07/17 08:44:58  robertj
 * Added links back to page and home page on accepted data html.
 * Fixed display of validation error text if page not accepted.
 *
 * Revision 1.42  2001/10/10 08:07:48  robertj
 * Fixed large memory leak of strings when doing POST to a form.
 *
 * Revision 1.41  2001/05/16 06:03:14  craigs
 * Changed to allow access to absolute registry paths from within subforms
 *
 * Revision 1.40  2001/02/07 04:44:47  robertj
 * Added ability to use check box to add/delete fields from arrays.
 *
 * Revision 1.39  2001/01/08 04:13:23  robertj
 * Fixed bug with skipping every second option in determining the selected
 *   option in a SELECT field. No longer requires a </option> to work.
 *
 * Revision 1.38  2000/12/20 02:23:39  robertj
 * Fixed variable array size value (caused extra blank entry ever commit).
 *
 * Revision 1.37  2000/12/18 12:13:08  robertj
 * Fixed bug in auto-generated HTML in fixed size arrays, should not have add/delete box.
 *
 * Revision 1.36  2000/12/18 11:41:01  robertj
 * Fixed bug in auto-generated HTML in non-array composite fields
 *
 * Revision 1.35  2000/12/18 07:14:30  robertj
 * Added ability to have fixed length array fields.
 * Fixed regular expressions so can have single '-' in field name.
 * Fixed use of non-array subforprefix based compsite fields.
 *
 * Revision 1.34  2000/12/12 07:21:35  robertj
 * Added ability to expand fields based on regex into repeated chunks of HTML.
 *
 * Revision 1.33  2000/11/02 21:55:28  craigs
 * Added extra constructor
 *
 * Revision 1.32  2000/09/05 09:52:24  robertj
 * Fixed bug in HTTP form updating SELECT fields from registry.
 *
 * Revision 1.31  2000/06/19 11:35:01  robertj
 * Fixed bug in setting current value of options in select form fields.
 *
 * Revision 1.30  1999/02/10 13:19:45  robertj
 * Fixed PConfig update problem when POSTing to the form. Especiall with arrays.
 *
 * Revision 1.29  1998/11/30 04:51:57  robertj
 * New directory structure
 *
 * Revision 1.28  1998/11/14 11:11:06  robertj
 * PPC GNU compiler compatibility.
 *
 * Revision 1.27  1998/10/01 09:05:11  robertj
 * Fixed bug in nested composite field names, array indexes not being set correctly.
 *
 * Revision 1.26  1998/09/23 06:22:11  robertj
 * Added open source copyright license.
 *
 * Revision 1.25  1998/08/20 05:51:06  robertj
 * Fixed bug where substitutions did not always occur if near end of macro block.
 * Improved internationalisation. Allow HTML override of strings in macros.
 *
 * Revision 1.24  1998/08/09 11:25:51  robertj
 * GNU C++ warning removal.
 *
 * Revision 1.23  1998/08/09 10:35:11  robertj
 * Changed array control so can have language override.
 *
 * Revision 1.22  1998/07/24 06:56:05  robertj
 * Fixed case significance problem in HTTP forms.
 * Improved detection of VALUE= fields with and without quotes.
 *
 * Revision 1.21  1998/03/20 03:16:43  robertj
 * Fixed bug in beaing able to reset a check box field.
 *
 * Revision 1.20  1998/02/03 06:26:09  robertj
 * Fixed propagation of inital values in arrays subfields.
 * Fixed problem where hidden fields were being relaced with default values from PHTTPForm.
 *
 * Revision 1.19  1998/01/26 02:49:17  robertj
 * GNU support.
 *
 * Revision 1.18  1998/01/26 01:51:37  robertj
 * Fixed uninitialised variable.
 *
 * Revision 1.17  1998/01/26 00:25:25  robertj
 * Major rewrite of HTTP forms management.
 *
 * Revision 1.16  1997/12/18 05:06:51  robertj
 * Added missing braces to kill GNU compiler warning.
 *
 * Revision 1.15  1997/10/10 10:43:43  robertj
 * Fixed bug in password encryption, missing string terminator.
 *
 * Revision 1.14  1997/08/28 12:48:29  robertj
 * Changed array fields to allow for reordering.
 *
 * Revision 1.13  1997/08/21 12:44:10  robertj
 * Fixed bug in HTTP form array size field.
 * Fixed bug where section list was only replacing first instance of macro.
 *
 * Revision 1.12  1997/08/09 07:46:52  robertj
 * Fixed problems with value of SELECT fields in form
 *
 * Revision 1.11  1997/08/04 10:41:13  robertj
 * Fixed bug in new section list page for names with special characters in them.
 *
 * Revision 1.10  1997/07/26 11:38:20  robertj
 * Support for overridable pages in HTTP service applications.
 *
 * Revision 1.9  1997/07/14 11:49:51  robertj
 * Put "Add" and "Keep" on check boxes in array fields.
 *
 * Revision 1.8  1997/07/08 13:12:29  robertj
 * Major HTTP form enhancements for lists and arrays of fields.
 *
 * Revision 1.7  1997/06/08 04:47:27  robertj
 * Adding new llist based form field.
 *
 * Revision 1.6  1997/04/12 02:07:26  robertj
 * Fixed boolean check boxes being more flexible on string values.
 *
 * Revision 1.5  1997/04/01 06:00:53  robertj
 * Changed PHTTPConfig so if section empty string, does not write PConfig parameters.
 *
 * Revision 1.4  1996/10/08 13:10:34  robertj
 * Fixed bug in boolean (checkbox) html forms, cannot be reset.
 *
 * Revision 1.3  1996/09/14 13:09:31  robertj
 * Major upgrade:
 *   rearranged sockets to help support IPX.
 *   added indirect channel class and moved all protocols to descend from it,
 *   separating the protocol from the low level byte transport.
 *
 * Revision 1.2  1996/08/08 13:34:10  robertj
 * Removed redundent call.
 *
 * Revision 1.1  1996/06/28 12:56:20  robertj
 * Initial revision
 *
 */

#ifdef __GNUC__
#pragma implementation "httpform.h"
#endif

#include <ptlib.h>
#include <ptclib/httpform.h>
#include <ptclib/cypher.h>


//////////////////////////////////////////////////////////////////////////////
// PHTTPField

PHTTPField::PHTTPField(const char * nam, const char * titl, const char * hlp)
  : baseName(nam), fullName(nam),
    title(titl != NULL ? titl : nam),
    help(hlp != NULL ? hlp : "")
{
  notInHTML = TRUE;
}


PObject::Comparison PHTTPField::Compare(const PObject & obj) const
{
  PAssert(PIsDescendant(&obj, PHTTPField), PInvalidCast);
  return fullName.Compare(((const PHTTPField &)obj).fullName);
}


void PHTTPField::SetName(const PString & newName)
{
  fullName = newName;
}


const PHTTPField * PHTTPField::LocateName(const PString & name) const
{
  if (fullName == name)
    return this;

  return NULL;
}


void PHTTPField::SetHelp(const PString & hotLinkURL,
                         const PString & linkText)
{
  help = "<A HREF=\"" + hotLinkURL + "\">" + linkText + "</A>\r\n";
}


void PHTTPField::SetHelp(const PString & hotLinkURL,
                         const PString & imageURL,
                         const PString & imageText)
{
  help = "<A HREF=\"" + hotLinkURL + "\"><IMG SRC=\"" +
             imageURL + "\" ALT=\"" + imageText + "\" ALIGN=absmiddle></A>\r\n";
}


static BOOL FindSpliceBlock(const PRegularExpression & startExpr,
                            const PRegularExpression & endExpr,
                            const PString & text,
                            PINDEX offset,
                            PINDEX & pos,
                            PINDEX & len,
                            PINDEX & start,
                            PINDEX & finish)
{
  start = finish = P_MAX_INDEX;

  if (!text.FindRegEx(startExpr, pos, len, offset))
    return FALSE;

  PINDEX endpos, endlen;
  if (!text.FindRegEx(endExpr, endpos, endlen, pos+len))
    return TRUE;

  start = pos + len;
  finish = endpos - 1;
  len = endpos - pos + endlen;
  return TRUE;
}


static BOOL FindSpliceBlock(const PRegularExpression & startExpr,
                            const PString & text,
                            PINDEX offset,
                            PINDEX & pos,
                            PINDEX & len,
                            PINDEX & start,
                            PINDEX & finish)
{
  static PRegularExpression EndBlock("<?!--#form[ \t\r\n]+end[ \t\r\n]*-->?",
                                     PRegularExpression::Extended|PRegularExpression::IgnoreCase);
  return FindSpliceBlock(startExpr, EndBlock, text, offset, pos, len, start, finish);
}


static BOOL FindSpliceName(const PCaselessString & text,
                           PINDEX start,
                           PINDEX finish,
                           PINDEX & pos,
                           PINDEX & end)
{
  if (text[start+1] != '!') {
    static PRegularExpression NameExpr("name[ \t\r\n]*=[ \t\r\n]*\"[^\"]*\"",
                                       PRegularExpression::Extended|PRegularExpression::IgnoreCase);
    if ((pos = text.FindRegEx(NameExpr, start)) == P_MAX_INDEX)
      return FALSE;

    if (pos >= finish)
      return FALSE;

    pos = text.Find('"', pos) + 1;
    end = text.Find('"', pos) - 1;
  }
  else {
    pos = start + 9;            // Skip over the <!--#form
    while (isspace(text[pos]))  // Skip over blanks
      pos++;
    while (pos < finish && !isspace(text[pos])) // Skip over keyword
      pos++;
    while (isspace(text[pos]))  // Skip over more blanks
      pos++;
    
    end = text.Find("--", pos) - 1;
  }

  return end < finish;
}


static BOOL FindSpliceFieldName(const PString & text,
                            PINDEX offset,
                            PINDEX & pos,
                            PINDEX & len,
                            PString & name)
{
  static PRegularExpression FieldName("<?!--#form[ \t\r\n]+[a-z0-9]+[ \t\r\n]+(-?[^-])+-->?"
                                      "|"
                                      "<[a-z]+[ \t\r\n][^>]*name[ \t\r\n]*=[ \t\r\n]*\"[^\"]*\"[^>]*>",
                                      PRegularExpression::Extended|PRegularExpression::IgnoreCase);
  if (!text.FindRegEx(FieldName, pos, len, offset))
    return FALSE;

  PINDEX nameStart, nameEnd;
  if (!FindSpliceName(text, pos, pos+len-1, nameStart, nameEnd))
    return FALSE;

  name = text(nameStart, nameEnd);
  pos = nameStart;
  len = nameEnd - nameStart + 1;
  return TRUE;
}


static void SpliceAdjust(const PString & str,
                         PString & text,
                         PINDEX pos,
                         PINDEX & len,
                         PINDEX & finish)
{
  text.Splice(str, pos, len);
  PINDEX newLen = str.GetLength();
  if (finish != P_MAX_INDEX)
    finish += newLen - len;
  len = newLen;
}


void PHTTPField::ExpandFieldNames(PString & text, PINDEX start, PINDEX & finish) const
{
  PString name;
  PINDEX pos, len;
  while (start < finish && FindSpliceFieldName(text, start, pos, len, name)) {
    if (pos > finish)
      break;
    if (baseName == name)
      SpliceAdjust(fullName, text, pos, len, finish);
    start = pos + len;
  }
}


static BOOL FindInputValue(const PString & text, PINDEX & before, PINDEX & after)
{
  static PRegularExpression Value("value[ \t\r\n]*=[ \t\r\n]*(\"[^\"]*\"|[^> \t\r\n]+)",
                                  PRegularExpression::Extended|PRegularExpression::IgnoreCase);
  PINDEX pos = text.FindRegEx(Value);
  if (pos == P_MAX_INDEX)
    return FALSE;

  before = text.Find('"', pos);
  if (before != P_MAX_INDEX)
    after = text.Find('"', before+1);
  else {
    before = text.Find('=', pos);
    while (isspace(text[before+1]))
      before++;
    after = before + 1;
    while (text[after] != '\0' && text[after] != '>' && !isspace(text[after]))
      after++;
  }
  return TRUE;
}


PString PHTTPField::GetHTMLInput(const PString & input) const
{
  PINDEX before, after;
  if (FindInputValue(input, before, after))
    return input(0, before) + GetValue(FALSE) + input.Mid(after);

  return "<input value=\"" + GetValue(FALSE) + "\"" + input.Mid(6);
}


static void AdjustSelectOptions(PString & text, PINDEX begin, PINDEX end,
                                const PString & myValue, PStringList & validValues,
                                PINDEX & finishAdjust)
{
  PINDEX start, finish;
  PINDEX pos = begin;
  PINDEX len = 0;
  static PRegularExpression StartOption("<[ \t\r\n]*option[^>]*>",
                                        PRegularExpression::IgnoreCase);
  static PRegularExpression EndOption("<[ \t\r\n]*/?option[^>]*>",
                                      PRegularExpression::Extended|PRegularExpression::IgnoreCase);
  while (FindSpliceBlock(StartOption, EndOption, text, pos+len, pos, len, start, finish) && pos < end) {
    if (start == P_MAX_INDEX)
      start = text.Find('>', pos)+1;
    else {
      // Check for if option was not closed by </option> but another <option>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -