Exemplo n.º 1
0
/* ****************************************************************************
*
* xmlParse - 
*
* This function is called once (actually it is not that simple) for each node in
* the tree that the XML parser has built for us.
* 
*
* In the node '<contextValue>', isCompoundValuePath returns TRUE.
* Under "<contextValue>", we have either a simple string or a Compound Value Tree.
* In the case of a "simple string" the value of the current node is NON EMPTY,
* and as the node is treated already in the previous call to 'treat()', no further action is needed.
*
* If a node is NOT TREATED and it is NOT a compound, a parse error is issued
*/
void xmlParse
(
   ConnectionInfo*     ciP,
   xml_node<>*         father,
   xml_node<>*         node,
   const std::string&  indentation,
   const std::string&  fatherPath,
   XmlNode*            parseVector,
   ParseData*          parseDataP
)
{
  std::string  value            = wsStrip(node->value());
  std::string  name             = wsStrip(node->name());
  std::string  path             = fatherPath + "/" + name;
  bool         treated          = treat(node, path, parseVector, parseDataP);

  if (isCompoundValuePath(path.c_str()) && (value == "") && (node->first_node() != NULL))
  {
    //
    // Count children (to avoid false compounds because of just en empty sttribute value)
    // 
    xml_node<>* child    = node->first_node();
    int         children = 0;
    while (child != NULL)
    {
      if (child->name()[0] != 0)
        ++children;
      child = child->next_sibling();
    }
    
    if (children == 0) // NOT a compound value
      return;

    eatCompound(ciP, NULL, node, "");
    compoundValueEnd(ciP, parseDataP);
    return;
  }
  else  if (treated == false)
  {
    ciP->httpStatusCode = SccBadRequest;
    if (ciP->answer == "")
      ciP->answer = std::string("Unknown XML field: '") + name.c_str() + "'";
    LM_W(("ERROR: '%s', PATH: '%s'   ", ciP->answer.c_str(), fatherPath.c_str()));
    return;
  }

  // Recursive calls for all children of this node
  xml_node<>* child = node->first_node();
  while (child != NULL)
  {
    if ((child != NULL) && (child->name() != NULL) && (onlyWs(child->name()) == false))
      xmlParse(ciP, node, child, indentation + "  ", path, parseVector, parseDataP);

    child = child->next_sibling();
  }
}
Exemplo n.º 2
0
/* ****************************************************************************
*
* eatCompound - consume the compound tree
*
* Three types of tree nodes here (4 actually);
*   - toplevel node
*   - leaf
*   - object node
*   - vector node
*/
void eatCompound(ConnectionInfo* ciP, orion::CompoundValueNode* containerP, xml_node<>* node, std::string indent)
{
  if (containerP == NULL) // toplevel)
  {
    std::string xmlAttribute = xmlTypeAttributeGet(node);
    
    if (xmlAttribute == "vector")
      containerP = new CompoundValueNode(orion::CompoundValueNode::Vector);
    else if (xmlAttribute =="")
      containerP = new CompoundValueNode(orion::CompoundValueNode::Struct);
    else
    {
      ciP->httpStatusCode = SccBadRequest;
      ciP->answer = std::string("Bad value for XML attribute 'type' for '") + node->name() + "': '" + xmlAttribute + "'";
      LM_W(("ERROR: '%s'", ciP->answer.c_str()));
      return;
    }
    ciP->compoundValueRoot = containerP;
  }
  else
  {
    std::string value = wsStrip(node->value());
    std::string name  = wsStrip(node->name());

    if (value == "")  // Object OR Vector
    {
      std::string xmlAttribute = xmlTypeAttributeGet(node);
    
      if (xmlAttribute == "vector")
        containerP = containerP->add(orion::CompoundValueNode::Vector, name);
      else if (xmlAttribute == "")
        containerP = containerP->add(orion::CompoundValueNode::Struct, name);
      else
      {
        ciP->httpStatusCode = SccBadRequest;
        ciP->answer = std::string("Bad value for XML attribute 'type' for '") + name + "': '" + xmlAttribute + "'";
        LM_W(("ERROR: '%s'", ciP->answer.c_str()));
        return;
      }
    }
    else // String
      containerP->add(orion::CompoundValueNode::Leaf, name, value);
  }

  xml_node<>* child = node->first_node();
  while (child != NULL)
  {
    if (child->name()[0] != 0)
      eatCompound(ciP, containerP, child, indent + "  ");
    child = child->next_sibling();
  }
}
Exemplo n.º 3
0
/* ****************************************************************************
*
* string2coords - 
*/
bool string2coords(std::string s, double& latitude, double& longitude)
{
  char* initial = strdup(s.c_str());
  char* cP      = initial;
  char* comma;
  char* number1;
  char* number2;

  cP = wsStrip(cP);

  comma = strchr(cP, ',');
  if (comma == NULL)
  {
    free(initial);
    return false;
  }
  *comma = 0;
  ++comma;

  number1 = cP;
  number2 = comma;

  number1 = wsStrip(number1);
  number2 = wsStrip(number2);

  std::string err;
  double oldLatitude = latitude;
  double oldLongitude = longitude;
  latitude = atoF(number1, err);
  if (err.length() > 0) {
     latitude = oldLatitude; 
     free(initial);
     return false;
  }
  else {
     longitude = atoF(number2, err);
     if (err.length() > 0) {
         /* Rollback latitude */
         latitude = oldLatitude;
         longitude = oldLongitude;
         free(initial);
         return false;
     }
  }

  free(initial);
  return true;
}
Exemplo n.º 4
0
/* ****************************************************************************
*
* servicePathSplit - 
*/
int servicePathSplit(ConnectionInfo* ciP)
{
  int servicePaths = stringSplit(ciP->servicePath, ',', ciP->servicePathV);

  if (servicePaths == 0)
  {
    /* In this case the result is a 0 length vector */
    return 0;
  }

  if (servicePaths > 10)
  {
    OrionError e(SccBadRequest, "too many service paths - a maximum of ten service paths is allowed");
    ciP->answer = e.render(ciP->outFormat, "");
    return -1;
  }

  for (int ix = 0; ix < servicePaths; ++ix)
  {
    ciP->servicePathV[ix] = std::string(wsStrip((char*) ciP->servicePathV[ix].c_str()));    
    ciP->servicePathV[ix] = removeTrailingSlash(ciP->servicePathV[ix]);

    LM_T(LmtServicePath, ("Service Path %d: '%s'", ix, ciP->servicePathV[ix].c_str()));
  }

  for (int ix = 0; ix < servicePaths; ++ix)
  {
    int s;

    if ((s = servicePathCheck(ciP, ciP->servicePathV[ix].c_str())) != 0)
      return s;
  }

  return 0;
}
Exemplo n.º 5
0
/* ****************************************************************************
*
* servicePathSplit - 
*/
int servicePathSplit(ConnectionInfo* ciP)
{
#if 0
  //
  // Special case: empty service-path 
  //
  // FIXME P4: We're not sure what this 'fix' really fixes.
  //           Must implement a functest to reproduce this situation.
  //           And, if that is not possible, just remove the whole thing
  //
  if ((ciP->httpHeaders.servicePathReceived == true) && (ciP->servicePath == ""))
  {
    OrionError e(SccBadRequest, "empty service path");
    ciP->answer = e.render(ciP, "");
    alarmMgr.badInput(clientIp, "empty service path");
    return -1;
  }
#endif

  int servicePaths = stringSplit(ciP->servicePath, ',', ciP->servicePathV);

  if (servicePaths == 0)
  {
    /* In this case the result is a vector with an empty string */
    ciP->servicePathV.push_back("");
    return 0;
  }

  if (servicePaths > SERVICE_PATH_MAX_COMPONENTS)
  {
    OrionError e(SccBadRequest, "too many service paths - a maximum of ten service paths is allowed");
    ciP->answer = e.render(ciP, "");
    return -1;
  }

  for (int ix = 0; ix < servicePaths; ++ix)
  {
    std::string stripped = std::string(wsStrip((char*) ciP->servicePathV[ix].c_str()));

    ciP->servicePathV[ix] = removeTrailingSlash(stripped);

    // This was previously a LM_T trace, but we have "promoted" it to INFO due to it is needed to check logs in a .test case (case 0392 service_path_http_header.test)
    LM_I(("Service Path %d: '%s'", ix, ciP->servicePathV[ix].c_str()));
  }

  for (int ix = 0; ix < servicePaths; ++ix)
  {
    int s;

    if ((s = servicePathCheck(ciP, ciP->servicePathV[ix].c_str())) != 0)
    {
      return s;
    }
  }

  return 0;
}
/* ****************************************************************************
*
* reference - 
*/
static int reference(xml_node<>* node, ParseData* reqDataP)
{
  std::string  ref      = node->value();
  char*        stripped = wsStrip((char*) ref.c_str());

  LM_T(LmtParse, ("Got a reference: '%s'", stripped));

  reqDataP->scar.res.reference.set(stripped);
  return 0;
}
Exemplo n.º 7
0
/* ****************************************************************************
*
* servicePathSplit - 
*/
int servicePathSplit(ConnectionInfo* ciP)
{
#if 0
  //
  // Special case: empty service-path 
  //
  // FIXME P4: We're not sure what this 'fix' really fixes.
  //           Must implement a functest to reproduce this situation.
  //           And, if that is not possible, just remove the whole thing
  //
  if ((ciP->httpHeaders.servicePathReceived == true) && (ciP->servicePath == ""))
  {
    OrionError e(SccBadRequest, "empty service path");
    ciP->answer = e.render(ciP->outFormat, "");
    LM_W(("Bad Input (empty service path)"));
    return -1;
  }
#endif

  int servicePaths = stringSplit(ciP->servicePath, ',', ciP->servicePathV);

  if (servicePaths == 0)
  {
    /* In this case the result is a 0 length vector */
    return 0;
  }

  if (servicePaths > 10)
  {
    OrionError e(SccBadRequest, "too many service paths - a maximum of ten service paths is allowed");
    ciP->answer = e.render(ciP->outFormat, "");
    return -1;
  }

  for (int ix = 0; ix < servicePaths; ++ix)
  {
    ciP->servicePathV[ix] = std::string(wsStrip((char*) ciP->servicePathV[ix].c_str()));    
    ciP->servicePathV[ix] = removeTrailingSlash(ciP->servicePathV[ix]);

    LM_T(LmtServicePath, ("Service Path %d: '%s'", ix, ciP->servicePathV[ix].c_str()));
  }

  for (int ix = 0; ix < servicePaths; ++ix)
  {
    int s;

    if ((s = servicePathCheck(ciP, ciP->servicePathV[ix].c_str())) != 0)
      return s;
  }

  return 0;
}
Exemplo n.º 8
0
/* ****************************************************************************
*
* wantedOutputSupported - 
*/
static Format wantedOutputSupported(const std::string& acceptList, std::string* charsetP)
{
  std::vector<std::string>  vec;
  char*                     copy;

  if (acceptList.length() == 0) 
  {
    /* HTTP RFC states that a missing Accept header must be interpreted as if the client is
     * accepting any type */
    copy = strdup("*/*");
  }
  else 
  {
    copy = strdup((char*) acceptList.c_str());
  }
  char*  cP   = copy;

  do
  {
     char* comma;

     comma = strstr(cP, ",");
     if (comma != NULL)
     {
        *comma = 0;
        
        cP = wsStrip(cP);
        vec.push_back(cP);
        cP = comma;
        ++cP;
     }
     else
     {
        cP = wsStrip(cP);
        if (*cP != 0)
        {
           vec.push_back(cP);
        }
        *cP = 0;
     }

  } while (*cP != 0);

  free(copy);

  bool xml  = false;
  bool json = false;

  for (unsigned int ix = 0; ix < vec.size(); ++ix)
  {
     char* s;

     //
     // charset embedded in 'Accept' header?
     // We read it but we don't do anything with it ...
     //
     if ((s = strstr((char*) vec[ix].c_str(), ";")) != NULL)
     {
        *s = 0;
        ++s;
        s = wsStrip(s);
        if (strncmp(s, "charset=", 8) == 0)
        {
           s = &s[8];
           s = wsStrip(s);

           if (charsetP != NULL)
              *charsetP = s;
        }
     }

     std::string format = vec[ix].c_str();
     if (format == "*/*")              xml  = true;
     if (format == "*/xml")            xml  = true;
     if (format == "application/*")    xml  = true;
     if (format == "application/xml")  xml  = true;
     if (format == "application/json") json = true;
     if (format == "*/json")           json = true;
     
     if ((acceptTextXml == true) && (format == "text/xml"))  xml = true;

     //
     // Resetting charset
     //
     if (charsetP != NULL)
        *charsetP = "";
  }

  if (xml == true)
    return XML;
  else if (json == true)
    return JSON;

  LM_W(("Bad Input (no valid 'Accept-format' found)"));
  return NOFORMAT;
}
Exemplo n.º 9
0
/* ****************************************************************************
*
* wantedOutputSupported - 
*/
static MimeType wantedOutputSupported(const std::string& apiVersion, const std::string& acceptList, std::string* charsetP)
{
  std::vector<std::string>  vec;
  char*                     copy;

  if (acceptList.length() == 0) 
  {
    /* HTTP RFC states that a missing Accept header must be interpreted as if the client is accepting any type */
    copy = strdup("*/*");
  }
  else 
  {
    copy = strdup((char*) acceptList.c_str());
  }
  char*  cP   = copy;

  do
  {
     char* comma;

     comma = strstr(cP, ",");
     if (comma != NULL)
     {
        *comma = 0;
        
        cP = wsStrip(cP);
        vec.push_back(cP);
        cP = comma;
        ++cP;
     }
     else
     {
        cP = wsStrip(cP);
        if (*cP != 0)
        {
           vec.push_back(cP);
        }
        *cP = 0;
     }

  } while (*cP != 0);

  free(copy);

  bool json = false;
  bool text = true;

  for (unsigned int ix = 0; ix < vec.size(); ++ix)
  {
     char* s;

     //
     // charset embedded in 'Accept' header?
     // We read it but we don't do anything with it ...
     //
     if ((s = strstr((char*) vec[ix].c_str(), ";")) != NULL)
     {
        *s = 0;
        ++s;
        s = wsStrip(s);
        if (strncmp(s, "charset=", 8) == 0)
        {
           s = &s[8];
           s = wsStrip(s);

           if (charsetP != NULL)
              *charsetP = s;
        }
     }

     std::string mimeType = vec[ix].c_str();
     if (mimeType == "*/*")              { json = true; text=true;}
     if (mimeType == "application/*")    { json = true; }
     if (mimeType == "application/json") { json = true; }
     if (mimeType == "*/json")           { json = true; }
     if (mimeType == "text/plain")       { text = true; }

     //
     // Resetting charset
     //
     if (charsetP != NULL)
     {
       *charsetP = "";
     }
  }

  if (apiVersion == "v2")
  {
    if (json == true)
    {
      return JSON;
    }
    else if (text)
    {
      return TEXT;
    }
  }
  else
  {
    if (json == true)
    {
      return JSON;
    }
  }

  alarmMgr.badInput(clientIp, "no valid 'Accept-format' found");
  return NOMIMETYPE;
}
Exemplo n.º 10
0
/* ****************************************************************************
*
* eatCompound - consume the compound tree
*
* Three types of tree nodes here (4 actually);
*   - toplevel node
*   - string
*   - object node
*   - vector node
*/
void eatCompound(ConnectionInfo* ciP, orion::CompoundValueNode* containerP, xml_node<>* node, const std::string& indent)
{
  if (containerP == NULL)  // toplevel
  {
    std::string xmlAttribute = xmlTypeAttributeGet(node);

    if (xmlAttribute == "vector")
    {
      containerP = new CompoundValueNode(orion::CompoundValueNode::Vector);
    }
    else if (xmlAttribute =="")
    {
      containerP = new CompoundValueNode(orion::CompoundValueNode::Object);
    }
    else
    {
      ciP->httpStatusCode = SccBadRequest;

      ciP->answer = std::string("Bad value for XML attribute /type/ for /") +
        node->name() + "/: " + xmlAttribute;

      LM_W(("Bad Input (%s)", ciP->answer.c_str()));

      return;
    }

    ciP->compoundValueRoot = containerP;
  }
  else
  {
    std::string value = wsStrip(node->value());
    std::string name  = wsStrip(node->name());

    if (value == "")   // Object OR Vector
    {
      std::string xmlAttribute = xmlTypeAttributeGet(node);

      if (xmlAttribute == "vector")
      {
        containerP = containerP->add(orion::CompoundValueNode::Vector, name);
      }
      else if (xmlAttribute == "")
      {
        containerP = containerP->add(orion::CompoundValueNode::Object, name);
      }
      else
      {
        ciP->httpStatusCode = SccBadRequest;
        ciP->answer = std::string("Bad value for XML attribute /type/ for /") + name + "/: " + xmlAttribute;
        LM_W(("Bad Input (%s)", ciP->answer.c_str()));

        return;
      }
    }
    else  // String
    {
      if (forbiddenChars(value.c_str()) == true)
      {
        LM_E(("Found a forbidden value in '%s'", value.c_str()));
        ciP->httpStatusCode = SccBadRequest;
        ciP->answer = std::string("Illegal value for XML attribute");
        return;
      }

      containerP->add(orion::CompoundValueNode::String, name, value);
    }
  }

  xml_node<>* child = node->first_node();
  while (child != NULL)
  {
    if (child->name()[0] != 0)
    {
      eatCompound(ciP, containerP, child, indent + "  ");
    }

    child = child->next_sibling();
  }
}
Exemplo n.º 11
0
/* ****************************************************************************
*
* versionParse -
*/
bool versionParse(const std::string& version, int& mayor, int& minor, std::string& bugFix)
{
  char*  copy = strdup(version.c_str());
  char*  s    = wsStrip(copy);
  char*  dotP;


  //
  // mayor number
  //
  dotP = strchr(s, '.');
  if (dotP == NULL)
  {
    free(copy);
    return false;
  }

  *dotP = 0;
  ++dotP;

  s = wsStrip(s);
  mayor = atoi(s);
  if (strspn(s, "0123456789") != strlen(s))
  {
    free(copy);
    return false;
  }
  s = dotP;


  //
  // minor number
  // If no dot is found, no bugFix 'version' is present.
  // Just zero the 'bugFix' and keep the remaining string in minor.
  //
  bool bugFixEmpty = false;

  dotP = strchr(s, '.');
  if (dotP != NULL)
  {
    *dotP = 0;
    ++dotP;
  }
  else
  {
    bugFix = "";
    bugFixEmpty = true;
  }

  s = wsStrip(s);
  minor = atoi(s);
  if (strspn(s, "0123456789") != strlen(s))
  {
    free(copy);
    return false;
  }

  if (bugFixEmpty == true)
  {
    free(copy);
    return true;
  }

  s = dotP;



  //
  // bugfix
  //
  s = wsStrip(s);
  bugFix = s;

  free(copy);
  return true;
}
Exemplo n.º 12
0
/* ****************************************************************************
*
* string2coords - 
*/
bool string2coords(const std::string& s, double& latitude, double& longitude)
{
  char*  initial = strdup(s.c_str());
  char*  cP      = initial;
  char*  comma;
  char*  number1;
  char*  number2;
  bool   ret = true;

  cP    = wsStrip(cP);

  comma = strchr(cP, ',');
  if (comma == NULL)
  {
    free(initial);
    return false;
  }
  *comma = 0;
  ++comma;

  number1 = cP;
  number2 = comma;

  number1 = wsStrip(number1);
  number2 = wsStrip(number2);

  std::string  err;
  double       oldLatitude  = latitude;
  double       oldLongitude = longitude;

  latitude                  = atoF(number1, &err);

  if (err.length() > 0)
  {
    latitude = oldLatitude;
    LM_W(("Bad Input (bad latitude value in coordinate string '%s')", initial));
    ret = false;
  }
  else
  {
    longitude = atoF(number2, &err);

    if (err.length() > 0)
    {
      /* Rollback latitude */
      latitude = oldLatitude;
      longitude = oldLongitude;
      LM_W(("Bad Input (bad longitude value in coordinate string '%s')", initial));
      ret = false;
    }
  }

  if ((latitude > 90) || (latitude < -90))
  {
    LM_W(("Bad Input (bad value for latitude '%s')", initial));
    ret = false;
  }
  else if ((longitude > 180) || (longitude < -180))
  {
    LM_W(("Bad Input (bad value for longitude '%s')", initial));
    ret = false;
  }

  free(initial);
  return ret;
}