Esempio n. 1
0
error_t ssiProcessCommand(HttpConnection *connection,
   const char_t *tag, size_t length, const char_t *uri, uint_t level)
{
   error_t error;

   //Include command found?
   if(length > 7 && !strncasecmp(tag, "include", 7))
   {
      //Process SSI include directive
      error = ssiProcessIncludeCommand(connection, tag, length, uri, level);
   }
   //Echo command found?
   else if(length > 4 && !strncasecmp(tag, "echo", 4))
   {
      //Process SSI echo directive
      error = ssiProcessEchoCommand(connection, tag, length);
   }
   //Exec command found?
   else if(length > 4 && !strncasecmp(tag, "exec", 4))
   {
      //Process SSI exec directive
      error = ssiProcessExecCommand(connection, tag, length);
   }
   //Unknown command?
   else
   {
      //The server is unable to decode the SSI tag
      error = ERROR_INVALID_TAG;
   }

   //Invalid SSI directive?
   if(error == ERROR_INVALID_TAG)
   {
      //Report a warning to the user
      error = httpWriteStream(connection, "Warning: Invalid SSI Tag", 24);
   }

   //Return status code
   return error;
}
Esempio n. 2
0
error_t httpSendResponse(HttpConnection *connection, const char_t *uri)
{
#if (HTTP_SERVER_FS_SUPPORT == ENABLED)
   error_t error;
   uint32_t length;
   size_t n;
   FsFile *file;

   //Retrieve the full pathname
   httpGetAbsolutePath(connection, uri,
      connection->buffer, HTTP_SERVER_BUFFER_SIZE);

   //Retrieve the size of the specified file
   error = fsGetFileSize(connection->buffer, &length);
   //The specified URI cannot be found?
   if(error) return ERROR_NOT_FOUND;

   //Open the file for reading
   file = fsOpenFile(connection->buffer, FS_FILE_MODE_READ);
   //Failed to open the file?
   if(!file) return ERROR_NOT_FOUND;
#else
   error_t error;
   size_t length;
   uint8_t *data;

   //Retrieve the full pathname
   httpGetAbsolutePath(connection, uri,
      connection->buffer, HTTP_SERVER_BUFFER_SIZE);

   //Get the resource data associated with the URI
   error = resGetData(connection->buffer, &data, &length);
   //The specified URI cannot be found?
   if(error) return error;
#endif

   //Format HTTP response header
   connection->response.statusCode = 200;
   connection->response.contentType = mimeGetType(uri);
   connection->response.chunkedEncoding = FALSE;
   connection->response.contentLength = length;

   //Send the header to the client
   error = httpWriteHeader(connection);
   //Any error to report?
   if(error)
   {
#if (HTTP_SERVER_FS_SUPPORT == ENABLED)
      //Close the file
      fsCloseFile(file);
#endif
      //Return status code
      return error;
   }

#if (HTTP_SERVER_FS_SUPPORT == ENABLED)
   //Send response body
   while(length > 0)
   {
      //Limit the number of bytes to read at a time
      n = MIN(length, HTTP_SERVER_BUFFER_SIZE);

      //Read data from the specified file
      error = fsReadFile(file, connection->buffer, n, &n);
      //End of input stream?
      if(error) break;

      //Send data to the client
      error = httpWriteStream(connection, connection->buffer, n);
      //Any error to report?
      if(error) break;

      //Decrement the count of remaining bytes to be transferred
      length -= n;
   }

   //Close the file
   fsCloseFile(file);

   //Successful file transfer?
   if(length == 0 && error == ERROR_END_OF_STREAM)
   {
      //Properly close the output stream
      error = httpCloseStream(connection);
   }
#else
   //Send response body
   error = httpWriteStream(connection, data, length);
   //Any error to report?
   if(error) return error;

   //Properly close output stream
   error = httpCloseStream(connection);
#endif

   //Return status code
   return error;
}
Esempio n. 3
0
error_t httpServerUriNotFoundCallback(HttpConnection *connection,
   const char_t *uri)
{
   error_t error;
   size_t n;
   char_t *buffer;

   //Process data.xml file?
   if(!strcasecmp(uri, "/data.xml"))
   {
      //Point to the scratch buffer
      buffer = connection->buffer + 384;

      //Format XML data
      n = sprintf(buffer, "<data>\r\n");
      n += sprintf(buffer + n, "  <ax>%d</ax>\r\n", ax);
      n += sprintf(buffer + n, "  <ay>%d</ay>\r\n", ay);
      n += sprintf(buffer + n, "  <az>%d</az>\r\n", az);
      n += sprintf(buffer + n, "  <adc>%u</adc>\r\n", adcValue);
      n += sprintf(buffer + n, "  <joystick>%u</joystick>\r\n", joystickState);

      //End of XML data
      n += sprintf(buffer + n, "</data>\r\n");

      //Format HTTP response header
      connection->response.version = connection->request.version;
      connection->response.statusCode = 200;
      connection->response.keepAlive = connection->request.keepAlive;
      connection->response.noCache = TRUE;
      connection->response.contentType = mimeGetType(".xml");
      connection->response.chunkedEncoding = FALSE;
      connection->response.contentLength = n;

      //Send the header to the client
      error = httpWriteHeader(connection);
      //Any error to report?
      if(error) return error;

      //Send response body
      error = httpWriteStream(connection, buffer, n);
      //Any error to report?
      if(error) return error;

      //Properly close output stream
      error = httpCloseStream(connection);
      //Return status code
      return error;
   }
   //Process send_mail.xml file?
   else if(!strcasecmp(uri, "/send_mail.xml"))
   {
      char_t *separator;
      char_t *property;
      char_t *value;
      char_t *p;
      SmtpAuthInfo authInfo;
      SmtpMail mail;
      SmtpMailAddr recipients[4];

      //Initialize structures to zero
      memset(&authInfo, 0, sizeof(authInfo));
      memset(&mail, 0, sizeof(mail));
      memset(recipients, 0, sizeof(recipients));

      //Set the relevant PRNG algorithm to be used
      authInfo.prngAlgo = YARROW_PRNG_ALGO;
      authInfo.prngContext = &yarrowContext;

      //Set email recipients
      mail.recipients = recipients;
      //Point to the scratch buffer
      buffer = connection->buffer;

      //Start of exception handling block
      do
      {
         //Process HTTP request body
         while(1)
         {
            //Read the HTTP request body until an ampersand is encountered
            error = httpReadStream(connection, buffer,
               HTTP_SERVER_BUFFER_SIZE - 1, &n, HTTP_FLAG_BREAK('&'));
            //End of stream detected?
            if(error) break;

            //Properly terminate the string with a NULL character
            buffer[n] = '\0';

            //Remove the trailing ampersand
            if(n > 0 && buffer[n - 1] == '&')
               buffer[--n] = '\0';

            //Decode the percent-encoded string
            httpDecodePercentEncodedString(buffer, buffer, HTTP_SERVER_BUFFER_SIZE);
            //Check whether a separator is present
            separator = strchr(buffer, '=');

            //Separator found?
            if(separator)
            {
               //Split the line
               *separator = '\0';
               //Get property name and value
               property = strTrimWhitespace(buffer);
               value = strTrimWhitespace(separator + 1);

               //Check property name
               if(!strcasecmp(property, "server"))
               {
                  //Save server name
                  authInfo.serverName = strDuplicate(value);
               }
               else if(!strcasecmp(property, "port"))
               {
                  //Save the server port to be used
                  authInfo.serverPort = atoi(value);
               }
               else if(!strcasecmp(property, "userName"))
               {
                  //Save user name
                  authInfo.userName = strDuplicate(value);
               }
               else if(!strcasecmp(property, "password"))
               {
                  //Save password
                  authInfo.password = strDuplicate(value);
               }
               else if(!strcasecmp(property, "useTls"))
               {
                  //Open a secure SSL/TLS session?
                  authInfo.useTls = TRUE;
               }
               else if(!strcasecmp(property, "recipient"))
               {
                  //Split the recipient address list
                  value = strtok_r(value, ", ", &p);

                  //Loop through the list
                  while(value != NULL)
                  {
                     //Save recipient address
                     recipients[mail.recipientCount].name = NULL;
                     recipients[mail.recipientCount].addr = strDuplicate(value);
                     recipients[mail.recipientCount].type = SMTP_RCPT_TYPE_TO;
                     //Get the next item in the list
                     value = strtok_r(NULL, ", ", &p);

                     //Increment the number of recipients
                     if(++mail.recipientCount >= arraysize(recipients))
                        break;
                  }
               }
               else if(!strcasecmp(property, "from"))
               {
                  //Save sender address
                  mail.from.name = NULL;
                  mail.from.addr = strDuplicate(value);
               }
               else if(!strcasecmp(property, "date"))
               {
                  //Save current time
                  mail.dateTime = strDuplicate(value);
               }
               else if(!strcasecmp(property, "subject"))
               {
                  //Save mail subject
                  mail.subject = strDuplicate(value);
               }
               else if(!strcasecmp(property, "body"))
               {
                  //Save mail body
                  mail.body = strDuplicate(value);
               }
            }
         }

         //Propagate exception if necessary
         if(error != ERROR_END_OF_STREAM)
            break;

         //Send mail
         error = smtpSendMail(&authInfo, &mail);

         //Point to the scratch buffer
         buffer = connection->buffer + 384;
         //Format XML data
         n = sprintf(buffer, "<data>\r\n  <status>");

         if(error == NO_ERROR)
            n += sprintf(buffer + n, "Mail successfully sent!\r\n");
         else if(error == ERROR_NAME_RESOLUTION_FAILED)
            n += sprintf(buffer + n, "Cannot resolve SMTP server name!\r\n");
         else if(error == ERROR_AUTHENTICATION_FAILED)
            n += sprintf(buffer + n, "Authentication failed!\r\n");
         else if(error == ERROR_UNEXPECTED_RESPONSE)
            n += sprintf(buffer + n, "Unexpected response from SMTP server!\r\n");
         else
            n += sprintf(buffer + n, "Failed to send mail (error %d)!\r\n", error);

         n += sprintf(buffer + n, "</status>\r\n</data>\r\n");

         //Format HTTP response header
         connection->response.version = connection->request.version;
         connection->response.statusCode = 200;
         connection->response.keepAlive = connection->request.keepAlive;
         connection->response.noCache = TRUE;
         connection->response.contentType = mimeGetType(".xml");
         connection->response.chunkedEncoding = FALSE;
         connection->response.contentLength = n;

         //Send the header to the client
         error = httpWriteHeader(connection);
         //Any error to report?
         if(error) break;

         //Send response body
         error = httpWriteStream(connection, buffer, n);
         //Any error to report?
         if(error) break;

         //Properly close output stream
         error = httpCloseStream(connection);
         //Any error to report?
         if(error) break;

         //End of exception handling block
      } while(0);

      //Free previously allocated memory
      osFreeMem((void *) authInfo.serverName);
      osFreeMem((void *) authInfo.userName);
      osFreeMem((void *) authInfo.password);
      osFreeMem((void *) recipients[0].addr);
      osFreeMem((void *) mail.from.addr);
      osFreeMem((void *) mail.dateTime);
      osFreeMem((void *) mail.subject);
      osFreeMem((void *) mail.body);

      //Return status code
      return error;
   }
   else
   {
      return ERROR_NOT_FOUND;
   }
}
Esempio n. 4
0
error_t httpServerCgiCallback(HttpConnection *connection,
   const char_t *param)
{
   static uint_t pageCounter = 0;
   uint_t length;
   MacAddr macAddr;
#if (IPV4_SUPPORT == ENABLED)
   Ipv4Addr ipv4Addr;
#endif
#if (IPV6_SUPPORT == ENABLED)
   uint_t n;
   Ipv6Addr ipv6Addr;
#endif

   //Underlying network interface
   NetInterface *interface = connection->socket->interface;

   //Check parameter name
   if(!strcasecmp(param, "PAGE_COUNTER"))
   {
      pageCounter++;
      sprintf(connection->buffer, "%u time%s", pageCounter, (pageCounter >= 2) ? "s" : "");
   }
   else if(!strcasecmp(param, "BOARD_NAME"))
   {
      strcpy(connection->buffer, "SAM7SE-EK");
   }
   else if(!strcasecmp(param, "SYSTEM_TIME"))
   {
      systime_t time = osGetSystemTime();
      formatSystemTime(time, connection->buffer);
   }
   else if(!strcasecmp(param, "MAC_ADDR"))
   {
      netGetMacAddr(interface, &macAddr);
      macAddrToString(&macAddr, connection->buffer);
   }
   else if(!strcasecmp(param, "IPV4_ADDR"))
   {
      ipv4GetHostAddr(interface, &ipv4Addr);
      ipv4AddrToString(ipv4Addr, connection->buffer);
   }
   else if(!strcasecmp(param, "SUBNET_MASK"))
   {
      ipv4GetSubnetMask(interface, &ipv4Addr);
      ipv4AddrToString(ipv4Addr, connection->buffer);
   }
   else if(!strcasecmp(param, "DEFAULT_GATEWAY"))
   {
      ipv4GetDefaultGateway(interface, &ipv4Addr);
      ipv4AddrToString(ipv4Addr, connection->buffer);
   }
   else if(!strcasecmp(param, "IPV4_PRIMARY_DNS"))
   {
      ipv4GetDnsServer(interface, 0, &ipv4Addr);
      ipv4AddrToString(ipv4Addr, connection->buffer);
   }
   else if(!strcasecmp(param, "IPV4_SECONDARY_DNS"))
   {
      ipv4GetDnsServer(interface, 1, &ipv4Addr);
      ipv4AddrToString(ipv4Addr, connection->buffer);
   }
#if (IPV6_SUPPORT == ENABLED)
   else if(!strcasecmp(param, "LINK_LOCAL_ADDR"))
   {
      ipv6GetLinkLocalAddr(interface, &ipv6Addr);
      ipv6AddrToString(&ipv6Addr, connection->buffer);
   }
   else if(!strcasecmp(param, "GLOBAL_ADDR"))
   {
      ipv6GetGlobalAddr(interface, 0, &ipv6Addr);
      ipv6AddrToString(&ipv6Addr, connection->buffer);
   }
   else if(!strcasecmp(param, "IPV6_PREFIX"))
   {
      ipv6GetPrefix(interface, 0, &ipv6Addr, &n);
      ipv6AddrToString(&ipv6Addr, connection->buffer);
      length = strlen(connection->buffer);
      sprintf(connection->buffer + length, "/%u", n);
   }
   else if(!strcasecmp(param, "ROUTER"))
   {
      ipv6GetDefaultRouter(interface, 0, &ipv6Addr);
      ipv6AddrToString(&ipv6Addr, connection->buffer);
   }
   else if(!strcasecmp(param, "IPV6_PRIMARY_DNS"))
   {
      ipv6GetDnsServer(interface, 0, &ipv6Addr);
      ipv6AddrToString(&ipv6Addr, connection->buffer);
   }
   else if(!strcasecmp(param, "IPV6_SECONDARY_DNS"))
   {
      ipv6GetDnsServer(interface, 1, &ipv6Addr);
      ipv6AddrToString(&ipv6Addr, connection->buffer);
   }
#endif
   else
   {
      return ERROR_INVALID_TAG;
   }

   //Get the length of the resulting string
   length = strlen(connection->buffer);

   //Send the contents of the specified environment variable
   return httpWriteStream(connection, connection->buffer, length);
}
Esempio n. 5
0
error_t httpServerCgiCallback(HttpConnection *connection,
   const char_t *param)
{
   static uint_t pageCounter = 0;
   uint_t length;
   time_t unixTime;
   DateTime date;

   //Underlying network interface
   NetInterface *interface = connection->socket->interface;

   //Check parameter name
   if(!strcasecmp(param, "PAGE_COUNTER"))
   {
      pageCounter++;
      sprintf(connection->buffer, "%u time%s", pageCounter, (pageCounter >= 2) ? "s" : "");
   }
   else if(!strcasecmp(param, "BOARD_NAME"))
   {
      strcpy(connection->buffer, interface->hostname);
   }
   else if(!strcasecmp(param, "SYSTEM_TIME"))
   {
      memset(&connection->buffer, 0x00, HTTP_SERVER_BUFFER_SIZE );
      //		unixTime = RTC_GetCounter();
      unixTime = 0;
      //Convert Unix timestamp to date
      convertUnixTimeToDate(unixTime, &date);
      formatDate(&date, connection->buffer);

   }
   else if(!strcasecmp(param, "MAC_ADDR"))
   {
      macAddrToString(&interface->macAddr, connection->buffer);
   }
   else if(!strcasecmp(param, "IPV4_ADDR"))
   {
      ipv4AddrToString(interface->ipv4Config.addr, connection->buffer);
   }
   else if(!strcasecmp(param, "SUBNET_MASK"))
   {
      ipv4AddrToString(interface->ipv4Config.subnetMask, connection->buffer);
   }
   else if(!strcasecmp(param, "DEFAULT_GATEWAY"))
   {
      ipv4AddrToString(interface->ipv4Config.defaultGateway, connection->buffer);
   }
   else if(!strcasecmp(param, "IPV4_PRIMARY_DNS"))
   {
      ipv4AddrToString(interface->ipv4Config.dnsServer[0], connection->buffer);
   }
   else if(!strcasecmp(param, "IPV4_SECONDARY_DNS"))
   {
      ipv4AddrToString(interface->ipv4Config.dnsServer[1], connection->buffer);
   }
#if (IPV6_SUPPORT == ENABLED)
   else if(!strcasecmp(param, "LINK_LOCAL_ADDR"))
   {
      ipv6AddrToString(&interface->ipv6Config.linkLocalAddr, connection->buffer);
   }
   else if(!strcasecmp(param, "GLOBAL_ADDR"))
   {
      ipv6AddrToString(&interface->ipv6Config.globalAddr, connection->buffer);
   }
   else if(!strcasecmp(param, "IPV6_PREFIX"))
   {
      ipv6AddrToString(&interface->ipv6Config.prefix, connection->buffer);
      length = strlen(connection->buffer);
      sprintf(connection->buffer + length, "/%u", interface->ipv6Config.prefixLength);
   }
   else if(!strcasecmp(param, "ROUTER"))
   {
      ipv6AddrToString(&interface->ipv6Config.router, connection->buffer);
   }
   else if(!strcasecmp(param, "IPV6_PRIMARY_DNS"))
   {
      ipv6AddrToString(&interface->ipv6Config.dnsServer[0], connection->buffer);
   }
   else if(!strcasecmp(param, "IPV6_SECONDARY_DNS"))
   {
      ipv6AddrToString(&interface->ipv6Config.dnsServer[1], connection->buffer);
   }
#endif
   else
   {
      return ERROR_INVALID_TAG;
   }

   //Get the length of the resulting string
   length = strlen(connection->buffer);

   //Send the contents of the specified environment variable
   return httpWriteStream(connection, connection->buffer, length);
}
error_t httpServerProcessGetConfig(HttpConnection *connection)
{
   error_t error;
   uint_t i;
   size_t n;
   char_t *buffer;
   char_t temp[40];

   //Allocate a memory buffer
   buffer = osAllocMem(2048);
   //Failed to allocate memory?
   if(!buffer) return ERROR_OUT_OF_MEMORY;

   //Format XML data
   n = sprintf(buffer, "<settings>\r\n");

   //Icecast settings
   n += sprintf(buffer + n, "  <icecast>\r\n");
   //Icecast resource
   n += sprintf(buffer + n, "    <url>%s</url>\r\n",
      appSettings.icecast.url);
   //Icecast server port
   n += sprintf(buffer + n, "    <port>%" PRIu16 "</port>\r\n",
      appSettings.icecast.port);
   //End of Icecast settings
   n += sprintf(buffer + n, "  </icecast>\r\n");

   //LAN settings
   n += sprintf(buffer + n, "  <lan>\r\n");
   //MAC address
   n += sprintf(buffer + n, "    <macAddr>%s</macAddr>\r\n",
      macAddrToString(&appSettings.lan.macAddr, temp));
   //Host name
   n += sprintf(buffer + n, "    <hostName>%s</hostName>\r\n",
      appSettings.lan.hostname);
   //Enable DHCP
   n += sprintf(buffer + n, "    <enableDhcp>%u</enableDhcp>\r\n",
      appSettings.lan.enableDhcp);
   //IPv4 host address
   n += sprintf(buffer + n, "    <hostAddr>%s</hostAddr>\r\n",
      ipv4AddrToString(appSettings.lan.hostAddr, temp));
   //Subnet mask
   n += sprintf(buffer + n, "    <subnetMask>%s</subnetMask>\r\n",
      ipv4AddrToString(appSettings.lan.subnetMask, temp));
   //Default gateway
   n += sprintf(buffer + n, "    <defaultGateway>%s</defaultGateway>\r\n",
      ipv4AddrToString(appSettings.lan.defaultGateway, temp));
   //Primary DNS
   n += sprintf(buffer + n, "    <primaryDns>%s</primaryDns>\r\n",
      ipv4AddrToString(appSettings.lan.primaryDns, temp));
   //Secondary DNS
   n += sprintf(buffer + n, "    <secondaryDns>%s</secondaryDns>\r\n",
      ipv4AddrToString(appSettings.lan.secondaryDns, temp));
   //End of LAN settings
   n += sprintf(buffer + n, "  </lan>\r\n");

   //Proxy settings
   n += sprintf(buffer + n, "  <proxy>\r\n");
   //Enable proxy server
   n += sprintf(buffer + n, "    <enable>%u</enable>\r\n",
      appSettings.proxy.enable);
   //Proxy server name
   n += sprintf(buffer + n, "    <name>%s</name>\r\n",
      appSettings.proxy.name);
   //Proxy server port
   n += sprintf(buffer + n, "    <port>%" PRIu16 "</port>\r\n",
      appSettings.proxy.port);
   //End of proxy settings
   n += sprintf(buffer + n, "  </proxy>\r\n");

  //End of settings
   n += sprintf(buffer + n, "</settings>\r\n");

   //Format HTTP response header
   connection->response.version = connection->request.version;
   connection->response.statusCode = 200;
   connection->response.keepAlive = connection->request.keepAlive;
   connection->response.noCache = TRUE;
   connection->response.contentType = mimeGetType(".xml");
   connection->response.chunkedEncoding = FALSE;
   connection->response.contentLength = n;

   //Send the header to the client
   error = httpWriteHeader(connection);

   //Check status code
   if(!error)
   {
      //Send response body
      error = httpWriteStream(connection, buffer, n);
   }

   //Check status code
   if(!error)
   {
      //Properly close output stream
      error = httpCloseStream(connection);
   }

   //Free previously allocated memory
   osFreeMem(buffer);
   //Return status code
   return error;
}
error_t httpServerProcessSetConfig(HttpConnection *connection)
{
   error_t error;
   uint_t i;
   size_t n;
   char_t *p;
   char_t *buffer;
   char_t *separator;
   char_t *property;
   char_t *value;
   Settings *newSettings;

   //Point to the scratch buffer
   buffer = connection->buffer;

   //Allocate a memory buffer to hold the new configuration
   newSettings = osAllocMem(sizeof(Settings));
   //Failed to allocate memory?
   if(!newSettings) return ERROR_OUT_OF_MEMORY;

   //Start of exception handling block
   do
   {
      //Retrieve default settings
      error = getDefaultSettings(newSettings);
      //Any error to report?
      if(error) break;

      //Process HTTP request body
      while(1)
      {
         //Read the HTTP request body until an ampersand is encountered
         error = httpReadStream(connection, buffer,
            HTTP_SERVER_BUFFER_SIZE - 1, &n, HTTP_FLAG_BREAK('&'));
         //End of stream detected?
         if(error) break;

         //Properly terminate the string with a NULL character
         buffer[n] = '\0';

         //Remove the trailing ampersand
         if(n > 0 && buffer[n - 1] == '&')
            buffer[--n] = '\0';

         //Decode the percent-encoded string
         error = httpDecodePercentEncodedString(buffer, buffer, HTTP_SERVER_BUFFER_SIZE);
         //Any error detected?
         if(error) break;

         //Check whether a separator is present
         separator = strchr(buffer, '=');

         //Separator found?
         if(separator)
         {
            //Split the line
            *separator = '\0';
            //Get property name and value
            property = strTrimWhitespace(buffer);
            value = strTrimWhitespace(separator + 1);

            //Debug message
            TRACE_DEBUG("[%s]=%s\r\n", property, value);

            //Icecast settings
            if(!strcasecmp(property, "icecastSettingsUrl"))
            {
               //Check resource length
               if(strlen(value) >= sizeof(newSettings->icecast.url))
               {
                  //Report an error
                  error = ERROR_INVALID_SYNTAX;
                  break;
               }

               //Save resource
               strcpy(newSettings->icecast.url, value);
            }
            else if(!strcasecmp(property, "icecastSettingsPort"))
            {
               //Save Icecast server port
               newSettings->icecast.port = strtoul(value, &p, 10);

               //Invalid port number?
               if(*p != '\0')
               {
                  //Report an error
                  error = ERROR_INVALID_SYNTAX;
                  break;
               }
            }
            //LAN settings
            else if(!strcasecmp(property, "lanSettingsMacAddr"))
            {
               //Save MAC address
               error = macStringToAddr(value, &newSettings->lan.macAddr);
               //Invalid address?
               if(error) break;
            }
            else if(!strcasecmp(property, "lanSettingsHostName"))
            {
               //Check the length of the host name
               if(strlen(value) >= sizeof(newSettings->lan.hostname))
               {
                  //Report an error
                  error = ERROR_INVALID_SYNTAX;
                  break;
               }

               //Save host name
               strcpy(newSettings->lan.hostname, value);
            }
            else if(!strcasecmp(property, "lanSettingsEnableDhcp"))
            {
               //Check flag value
               if(!strcasecmp(value, "off"))
               {
                  //DHCP client is disabled
                  newSettings->lan.enableDhcp = FALSE;
               }
               else if(!strcasecmp(value, "on"))
               {
                  //DHCP client is enabled
                  newSettings->lan.enableDhcp = TRUE;
               }
               else
               {
                  //Invalid value
                  error = ERROR_INVALID_SYNTAX;
                  break;
               }
            }
            else if(!strcasecmp(property, "lanSettingsHostAddr"))
            {
               //Save IPv4 host address
               error = ipv4StringToAddr(value, &newSettings->lan.hostAddr);
               //Invalid address?
               if(error) break;
            }
            else if(!strcasecmp(property, "lanSettingsSubnetMask"))
            {
               //Save subnet mask
               error = ipv4StringToAddr(value, &newSettings->lan.subnetMask);
               //Invalid mask?
               if(error) break;
            }
            else if(!strcasecmp(property, "lanSettingsDefaultGateway"))
            {
               //Save default gateway
               error = ipv4StringToAddr(value, &newSettings->lan.defaultGateway);
               //Invalid address?
               if(error) break;
            }
            else if(!strcasecmp(property, "lanSettingsPrimaryDns"))
            {
               //Save primary DNS
               error = ipv4StringToAddr(value, &newSettings->lan.primaryDns);
               //Invalid address?
               if(error) break;
            }
            else if(!strcasecmp(property, "lanSettingsSecondaryDns"))
            {
               //Save secondary DNS
               error = ipv4StringToAddr(value, &newSettings->lan.secondaryDns);
               //Invalid address?
               if(error) break;
            }
            //Proxy settings
            else if(!strcasecmp(property, "proxySettingsEnable"))
            {
               //Check flag value
               if(!strcasecmp(value, "off"))
               {
                  //Proxy server is disabled
                  newSettings->proxy.enable = FALSE;
               }
               else if(!strcasecmp(value, "on"))
               {
                  //Proxy server is enabled
                  newSettings->proxy.enable = TRUE;
               }
               else
               {
                  //Invalid value
                  error = ERROR_INVALID_SYNTAX;
                  break;
               }
            }
            else if(!strcasecmp(property, "proxySettingsName"))
            {
               //Check the length of proxy server name
               if(strlen(value) >= sizeof(newSettings->proxy.name))
               {
                  //Report an error
                  error = ERROR_INVALID_SYNTAX;
                  break;
               }

               //Save proxy server name
               strcpy(newSettings->proxy.name, value);
            }
            else if(!strcasecmp(property, "proxySettingsPort"))
            {
               //Save proxy server port
               newSettings->proxy.port = strtoul(value, &p, 10);

               //Invalid port number?
               if(*p != '\0')
               {
                  //Report an error
                  error = ERROR_INVALID_SYNTAX;
                  break;
               }
            }
         }
      }

      //Check status code
      if(error == NO_ERROR || error == ERROR_END_OF_STREAM)
      {
         //Commit changes
         appSettings = *newSettings;
         //Write settings to non-volatile memory
         error = saveSettings(newSettings);
      }
      else if(error != ERROR_INVALID_SYNTAX)
      {
         //Propagate exception
         break;
      }

      //Point to the scratch buffer
      buffer = connection->buffer + 384;
      //Format XML data
      n = sprintf(buffer, "<data>\r\n  <status>");

      if(error == ERROR_INVALID_SYNTAX)
         n += sprintf(buffer + n, "Invalid configuration!\r\n");
      else if(error != NO_ERROR)
         n += sprintf(buffer + n, "Failed to save settings to non-volatile memory!\r\n");
      else
         n += sprintf(buffer + n, "Settings successfully saved. Please reboot the board.\r\n");

      //Terminate XML data
      n += sprintf(buffer + n, "</status>\r\n</data>\r\n");

      //Format HTTP response header
      connection->response.version = connection->request.version;
      connection->response.statusCode = 200;
      connection->response.keepAlive = connection->request.keepAlive;
      connection->response.noCache = TRUE;
      connection->response.contentType = mimeGetType(".xml");
      connection->response.chunkedEncoding = FALSE;
      connection->response.contentLength = n;

      //Send the header to the client
      error = httpWriteHeader(connection);
      //Any error to report?
      if(error) break;

      //Send response body
      error = httpWriteStream(connection, buffer, n);
      //Any error to report?
      if(error) break;

      //Properly close output stream
      error = httpCloseStream(connection);
      //Any error to report?
      if(error) break;

      //End of exception handling block
   } while(0);

   //Free previously allocated memory
   osFreeMem(newSettings);
   //Return status code
   return error;
}
Esempio n. 8
0
error_t ssiExecuteScript(HttpConnection *connection, const char_t *uri, uint_t level)
{
   error_t error;
   size_t length;

#if (HTTP_SERVER_FS_SUPPORT == ENABLED)
   bool_t more;
   uint_t pos;
   uint_t n;
   char_t *buffer;
   FsFile *file;
#else
   uint_t i;
   uint_t j;
   char_t *data;
#endif

   //Recursion limit exceeded?
   if(level >= HTTP_SERVER_SSI_MAX_RECURSION)
      return NO_ERROR;

   //Retrieve the full pathname
   httpGetAbsolutePath(connection, uri,
      connection->buffer, HTTP_SERVER_BUFFER_SIZE);

#if (HTTP_SERVER_FS_SUPPORT == ENABLED)
   //Open the file for reading
   file = fsOpenFile(connection->buffer, FS_FILE_MODE_READ);
   //Failed to open the file?
   if(!file) return ERROR_NOT_FOUND;

   //Allocate a memory buffer
   buffer = osAllocMem(HTTP_SERVER_BUFFER_SIZE);
   //Failed to allocate memory?
   if(!buffer)
   {
      //Close the file
      fsCloseFile(file);
      //Report an error
      return ERROR_OUT_OF_MEMORY;
   }
#else
   //Get the resource data associated with the URI
   error = resGetData(connection->buffer, (uint8_t **) &data, &length);
   //The specified URI cannot be found?
   if(error) return error;
#endif

   //Send the HTTP response header before executing the script
   if(!level)
   {
      //Format HTTP response header
      connection->response.statusCode = 200;
      connection->response.contentType = mimeGetType(uri);
      connection->response.chunkedEncoding = TRUE;

      //Send the header to the client
      error = httpWriteHeader(connection);
      //Any error to report?
      if(error)
      {
#if (HTTP_SERVER_FS_SUPPORT == ENABLED)
         //Close the file
         fsCloseFile(file);
         //Release memory buffer
         osFreeMem(buffer);
#endif
         //Return status code
         return error;
      }
   }

#if (HTTP_SERVER_FS_SUPPORT == ENABLED)
   //Point to the beginning of the buffer
   pos = 0;
   length = 0;

   //This flag indicates whether data should be read
   more = TRUE;

   //Parse the specified file
   while(1)
   {
      //Read more data if needed
      if(more)
      {
         //Read data from the specified file
         error = fsReadFile(file, buffer + pos + length,
            HTTP_SERVER_BUFFER_SIZE - (pos + length), &n);

         //End of input stream?
         if(error)
         {
            //Purge data buffer
            error = httpWriteStream(connection, buffer + pos, length);
            //Exit immediately
            break;
         }

         //Adjust the length of the buffer
         length += n;
         //Clear flag
         more = FALSE;
      }

      //Search for any SSI tags
      error = ssiSearchTag(buffer + pos, length, "<!--#", 5, &n);

      //Full match?
      if(error == NO_ERROR)
      {
         //Send the part of the file that precedes the tag
         error = httpWriteStream(connection, buffer + pos, n);
         //Failed to send data?
         if(error) break;

         //Advance data pointer
         pos += n;
         length -= n;

         //Search for the comment terminator
         error = ssiSearchTag(buffer + pos + 5, length - 5, "-->", 3, &n);

         //Full match?
         if(error == NO_ERROR)
         {
            //Advance data pointer over the opening identifier
            pos += 5;
            length -= 5;

            //Process SSI directive
            error = ssiProcessCommand(connection, buffer + pos, n, uri, level);
            //Any error to report?
            if(error) break;

            //Advance data pointer over the SSI tag
            pos += n + 3;
            length -= n + 3;
         }
         //No match or partial match?
         else
         {
            if(pos > 0)
            {
               //Move the remaining bytes to the start of the buffer
               memmove(buffer, buffer + pos, length);
               //Rewind to the beginning of the buffer
               pos = 0;
               //More data are needed
               more = TRUE;
            }
            else
            {
               //Send data to the client
               error = httpWriteStream(connection, buffer + pos, length);
               //Any error to report?
               if(error) break;

               //Rewind to the beginning of the buffer
               pos = 0;
               length = 0;
               //More data are needed
               more = TRUE;
            }
         }
      }
      //Partial match?
      else if(error == ERROR_PARTIAL_MATCH)
      {
         //Send the part of the file that precedes the tag
         error = httpWriteStream(connection, buffer + pos, n);
         //Failed to send data?
         if(error) break;

         //Advance data pointer
         pos += n;
         length -= n;

         //Move the remaining bytes to the start of the buffer
         memmove(buffer, buffer + pos, length);
         //Rewind to the beginning of the buffer
         pos = 0;
         //More data are needed
         more = TRUE;
      }
      //No match?
      else
      {
         //Send data to the client
         error = httpWriteStream(connection, buffer + pos, length);
         //Any error to report?
         if(error) break;

         //Rewind to the beginning of the buffer
         pos = 0;
         length = 0;
         //More data are needed
         more = TRUE;
      }
   }

   //Close the file
   fsCloseFile(file);
   //Release memory buffer
   osFreeMem(buffer);

   //Properly close the output stream
   if(!level && error == NO_ERROR)
      error = httpCloseStream(connection);
#else
   //Parse the specified file
   while(length > 0)
   {
      //Search for any SSI tags
      error = ssiSearchTag(data, length, "<!--#", 5, &i);

      //Opening identifier found?
      if(!error)
      {
         //Search for the comment terminator
         error = ssiSearchTag(data + i + 5, length - i - 5, "-->", 3, &j);
      }

      //Check whether a valid SSI tag has been found?
      if(!error)
      {
         //Send the part of the file that precedes the tag
         error = httpWriteStream(connection, data, i);
         //Failed to send data?
         if(error) return error;

         //Advance data pointer over the opening identifier
         data += i + 5;
         length -= i + 5;

         //Process SSI directive
         error = ssiProcessCommand(connection, data, j, uri, level);
         //Any error to report?
         if(error) return error;

         //Advance data pointer over the SSI tag
         data += j + 3;
         length -= j + 3;
      }
      else
      {
         //Send the rest of the file
         error = httpWriteStream(connection, data, length);
         //Failed to send data?
         if(error) return error;
         //Advance data pointer
         data += length;
         length = 0;
      }
   }

   //Properly close the output stream
   if(!level)
      error = httpCloseStream(connection);
#endif

   //Return status code
   return error;
}
Esempio n. 9
0
error_t ssiProcessEchoCommand(HttpConnection *connection, const char_t *tag, size_t length)
{
   error_t error;
   char_t *separator;
   char_t *attribute;
   char_t *value;

   //Discard invalid SSI directives
   if(length < 4 || length >= HTTP_SERVER_BUFFER_SIZE)
      return ERROR_INVALID_TAG;

   //Skip the SSI echo command (4 bytes)
   memcpy(connection->buffer, tag + 4, length - 4);
   //Ensure the resulting string is NULL-terminated
   connection->buffer[length - 4] = '\0';

   //Check whether a separator is present
   separator = strchr(connection->buffer, '=');
   //Separator not found?
   if(!separator)
      return ERROR_INVALID_TAG;

   //Split the tag
   *separator = '\0';

   //Get attribute name and value
   attribute = strTrimWhitespace(connection->buffer);
   value = strTrimWhitespace(separator + 1);

   //Remove leading simple or double quote
   if(value[0] == '\'' || value[0] == '\"')
      value++;

   //Get the length of the attribute value
   length = strlen(value);

   //Remove trailing simple or double quote
   if(length > 0)
   {
      if(value[length - 1] == '\'' || value[length - 1] == '\"')
         value[length - 1] = '\0';
   }

   //Enforce attribute name
   if(strcasecmp(attribute, "var"))
      return ERROR_INVALID_TAG;

   //Remote address?
   if(!strcasecmp(value, "REMOTE_ADDR"))
   {
      //The IP address of the host making this request
      ipAddrToString(&connection->socket->remoteIpAddr, connection->buffer);
   }
   //Remote port?
   else if(!strcasecmp(value, "REMOTE_PORT"))
   {
      //The port number used by the remote host when making this request
      sprintf(connection->buffer, "%" PRIu16, connection->socket->remotePort);
   }
   //Server address?
   else if(!strcasecmp(value, "SERVER_ADDR"))
   {
      //The IP address of the server for this URL
      ipAddrToString(&connection->socket->localIpAddr, connection->buffer);
   }
   //Server port?
   else if(!strcasecmp(value, "SERVER_PORT"))
   {
      //The port number on this server to which this request was directed
      sprintf(connection->buffer, "%" PRIu16, connection->socket->localPort);
   }
   //Request method?
   else if(!strcasecmp(value, "REQUEST_METHOD"))
   {
      //The method used for this HTTP request
      strcpy(connection->buffer, connection->request.method);
   }
   //Document root?
   else if(!strcasecmp(value, "DOCUMENT_ROOT"))
   {
      //The root directory
      strcpy(connection->buffer, connection->settings->rootDirectory);
   }
   //Document URI?
   else if(!strcasecmp(value, "DOCUMENT_URI"))
   {
      //The URI for this request relative to the root directory
      strcpy(connection->buffer, connection->request.uri);
   }
   //Document name?
   else if(!strcasecmp(value, "DOCUMENT_NAME"))
   {
      //The full physical path and filename of the document requested
      httpGetAbsolutePath(connection, connection->request.uri,
         connection->buffer, HTTP_SERVER_BUFFER_SIZE);
   }
   //Query string?
   else if(!strcasecmp(value, "QUERY_STRING"))
   {
      //The information following the "?" in the URL for this request
      strcpy(connection->buffer, connection->request.queryString);
   }
   //User name?
   else if(!strcasecmp(value, "AUTH_USER"))
   {
#if (HTTP_SERVER_BASIC_AUTH_SUPPORT == ENABLED || HTTP_SERVER_DIGEST_AUTH_SUPPORT == ENABLED)
      //The username provided by the user to the server
      strcpy(connection->buffer, connection->request.auth.user);
#else
      //Basic access authentication is not supported
      connection->buffer[0] = '\0';
#endif
   }
   //GMT time?
   else if(!strcasecmp(value, "DATE_GMT"))
   {
      //The current date and time in Greenwich Mean Time
      connection->buffer[0] = '\0';
   }
   //Local time?
   else if(!strcasecmp(value, "DATE_LOCAL"))
   {
      //The current date and time in the local timezone
      connection->buffer[0] = '\0';
   }
   //Unknown variable?
   else
   {
      //Report an error
      return ERROR_INVALID_TAG;
   }

   //Get the length of the resulting string
   length = strlen(connection->buffer);

   //Send the contents of the specified environment variable
   error = httpWriteStream(connection, connection->buffer, length);
   //Failed to send data?
   if(error) return error;

   //Successful processing
   return NO_ERROR;
}
Esempio n. 10
0
error_t ssiProcessIncludeCommand(HttpConnection *connection,
   const char_t *tag, size_t length, const char_t *uri, uint_t level)
{
   error_t error;
   char_t *separator;
   char_t *attribute;
   char_t *value;
   char_t *path;
   char_t *p;

   //Discard invalid SSI directives
   if(length < 7 || length >= HTTP_SERVER_BUFFER_SIZE)
      return ERROR_INVALID_TAG;

   //Skip the SSI include command (7 bytes)
   memcpy(connection->buffer, tag + 7, length - 7);
   //Ensure the resulting string is NULL-terminated
   connection->buffer[length - 7] = '\0';

   //Check whether a separator is present
   separator = strchr(connection->buffer, '=');
   //Separator not found?
   if(!separator)
      return ERROR_INVALID_TAG;

   //Split the tag
   *separator = '\0';

   //Get attribute name and value
   attribute = strTrimWhitespace(connection->buffer);
   value = strTrimWhitespace(separator + 1);

   //Remove leading simple or double quote
   if(value[0] == '\'' || value[0] == '\"')
      value++;

   //Get the length of the attribute value
   length = strlen(value);

   //Remove trailing simple or double quote
   if(length > 0)
   {
      if(value[length - 1] == '\'' || value[length - 1] == '\"')
         value[length - 1] = '\0';
   }

   //Check the length of the filename
   if(strlen(value) > HTTP_SERVER_URI_MAX_LEN)
      return ERROR_INVALID_TAG;

   //The file parameter defines the included file as relative to the document path
   if(!strcasecmp(attribute, "file"))
   {
      //Allocate a buffer to hold the path to the file to be included
      path = osAllocMem(strlen(uri) + strlen(value) + 1);
      //Failed to allocate memory?
      if(!path) return ERROR_OUT_OF_MEMORY;

      //Copy the path identifying the script file being processed
      strcpy(path, uri);
      //Search for the last slash character
      p = strrchr(path, '/');

      //Remove the filename from the path if applicable
      if(p)
         strcpy(p + 1, value);
      else
         strcpy(path, value);
   }
   //The virtual parameter defines the included file as relative to the document root
   else if(!strcasecmp(attribute, "virtual"))
   {
      //Copy the absolute path
      path = strDuplicate(value);
      //Failed to duplicate the string?
      if(!path) return ERROR_OUT_OF_MEMORY;
   }
   //Unknown parameter...
   else
   {
      //Report an error
      return ERROR_INVALID_TAG;
   }

   //Use server-side scripting to dynamically generate HTML code?
   if(httpCompExtension(value, ".stm") ||
      httpCompExtension(value, ".shtm") ||
      httpCompExtension(value, ".shtml"))
   {
      //SSI processing (Server Side Includes)
      error = ssiExecuteScript(connection, path, level + 1);
   }
   else
   {
#if (HTTP_SERVER_FS_SUPPORT == ENABLED)
      FsFile *file;

      //Retrieve the full pathname
      httpGetAbsolutePath(connection, path,
         connection->buffer, HTTP_SERVER_BUFFER_SIZE);

      //Open the file for reading
      file = fsOpenFile(connection->buffer, FS_FILE_MODE_READ);

      //Successful operation?
      if(file)
      {
         //Send the contents of the requested file
         while(1)
         {
            //Read data from the specified file
            error = fsReadFile(file, connection->buffer, HTTP_SERVER_BUFFER_SIZE, &length);
            //End of input stream?
            if(error) break;

            //Send data to the client
            error = httpWriteStream(connection, connection->buffer, length);
            //Any error to report?
            if(error) break;
         }

         //Close the file
         fsCloseFile(file);

         //Successful file transfer?
         if(error == ERROR_END_OF_STREAM)
            error = NO_ERROR;
      }
      else
      {
         //The specified URI cannot be found
         error = ERROR_NOT_FOUND;
      }
#else
      uint8_t *data;

      //Retrieve the full pathname
      httpGetAbsolutePath(connection, path,
         connection->buffer, HTTP_SERVER_BUFFER_SIZE);

      //Get the resource data associated with the file
      error = resGetData(connection->buffer, &data, &length);

      //Send the contents of the requested file
      if(!error)
         error = httpWriteStream(connection, data, length);
#endif
   }

   //Cannot found the specified resource?
   if(error == ERROR_NOT_FOUND)
      error = ERROR_INVALID_TAG;

   //Release previously allocated memory
   osFreeMem(path);
   //return status code
   return error;
}
Esempio n. 11
0
error_t httpServerCgiCallback(HttpConnection *connection, const char_t *param)
{
   static uint_t pageCounter = 0;
   uint_t length;

   //Underlying network interface
   NetInterface *interface = connection->socket->interface;

   //Check parameter name
   if(!strcasecmp(param, "PAGE_COUNTER"))
   {
      pageCounter++;
      sprintf(connection->buffer, "%u time%s", pageCounter, (pageCounter >= 2) ? "s" : "");
   }
   else if(!strcasecmp(param, "BOARD_NAME"))
   {
      strcpy(connection->buffer, "STM3240G-EVAL");
   }
   else if(!strcasecmp(param, "SYSTEM_TIME"))
   {
      time_t time = osGetTickCount();
      sprintf(connection->buffer, "%lus %03lums", time / 1000, time % 1000);
   }
   else if(!strcasecmp(param, "MAC_ADDR"))
   {
      macAddrToString(&interface->macAddr, connection->buffer);
   }
   else if(!strcasecmp(param, "IPV4_ADDR"))
   {
      ipv4AddrToString(interface->ipv4Config.addr, connection->buffer);
   }
   else if(!strcasecmp(param, "SUBNET_MASK"))
   {
      ipv4AddrToString(interface->ipv4Config.subnetMask, connection->buffer);
   }
   else if(!strcasecmp(param, "DEFAULT_GATEWAY"))
   {
      ipv4AddrToString(interface->ipv4Config.defaultGateway, connection->buffer);
   }
   else if(!strcasecmp(param, "IPV4_PRIMARY_DNS"))
   {
      ipv4AddrToString(interface->ipv4Config.dnsServer[0], connection->buffer);
   }
   else if(!strcasecmp(param, "IPV4_SECONDARY_DNS"))
   {
      ipv4AddrToString(interface->ipv4Config.dnsServer[1], connection->buffer);
   }
#if (IPV6_SUPPORT == ENABLED)
   else if(!strcasecmp(param, "LINK_LOCAL_ADDR"))
   {
      ipv6AddrToString(&interface->ipv6Config.linkLocalAddr, connection->buffer);
   }
   else if(!strcasecmp(param, "GLOBAL_ADDR"))
   {
      ipv6AddrToString(&interface->ipv6Config.globalAddr, connection->buffer);
   }
   else if(!strcasecmp(param, "IPV6_PREFIX"))
   {
      ipv6AddrToString(&interface->ipv6Config.prefix, connection->buffer);
      length = strlen(connection->buffer);
      sprintf(connection->buffer + length, "/%u", interface->ipv6Config.prefixLength);
   }
   else if(!strcasecmp(param, "ROUTER"))
   {
      ipv6AddrToString(&interface->ipv6Config.router, connection->buffer);
   }
   else if(!strcasecmp(param, "IPV6_PRIMARY_DNS"))
   {
      ipv6AddrToString(&interface->ipv6Config.dnsServer[0], connection->buffer);
   }
   else if(!strcasecmp(param, "IPV6_SECONDARY_DNS"))
   {
      ipv6AddrToString(&interface->ipv6Config.dnsServer[1], connection->buffer);
   }
#endif
   else
   {
      return ERROR_INVALID_TAG;
   }

   //Get the length of the resulting string
   length = strlen(connection->buffer);

   //Send the contents of the specified environment variable
   return httpWriteStream(connection, connection->buffer, length);
}