Exemplo n.º 1
0
error_t ssiProcessExecCommand(HttpConnection *connection, const char_t *tag, size_t length)
{
   char_t *separator;
   char_t *attribute;
   char_t *value;

   //First, check whether CGI is supported by the server
   if(connection->settings->cgiCallback == NULL)
      return ERROR_INVALID_TAG;

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

   //Skip the SSI exec 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, "cgi") && strcasecmp(attribute, "cmd") && strcasecmp(attribute, "cmd_argument"))
      return ERROR_INVALID_TAG;
   //Check the length of the CGI parameter
   if(strlen(value) > HTTP_SERVER_CGI_PARAM_MAX_LEN)
      return ERROR_INVALID_TAG;

   //The scratch buffer may be altered by the user-defined callback.
   //So the CGI parameter must be copied prior to function invocation
   strcpy(connection->cgiParam, value);

   //Invoke user-defined callback
   return connection->settings->cgiCallback(connection, connection->cgiParam);
}
Exemplo n.º 2
0
void httpParseContentTypeField(HttpConnection *connection, char_t *value)
{
#if (HTTP_SERVER_MULTIPART_TYPE_SUPPORT == ENABLED)
   size_t n;
   char_t *p;
   char_t *token;

   //Retrieve type
   token = strtok_r(value, "/", &p);
   //Any parsing error?
   if(token == NULL) return;

   //The boundary parameter makes sense only for the multipart content-type
   if(!strcasecmp(token, "multipart"))
   {
      //Skip subtype
      token = strtok_r(NULL, ";", &p);
      //Any parsing error?
      if(token == NULL) return;

      //Retrieve parameter name
      token = strtok_r(NULL, "=", &p);
      //Any parsing error?
      if(token == NULL) return;

      //Trim whitespace characters
      token = strTrimWhitespace(token);

      //Check parameter name
      if(!strcasecmp(token, "boundary"))
      {
         //Retrieve parameter value
         token = strtok_r(NULL, ";", &p);
         //Any parsing error?
         if(token == NULL) return;

         //Trim whitespace characters
         token = strTrimWhitespace(token);
         //Get the length of the boundary string
         n = strlen(token);

         //Check the length of the boundary string
         if(n < HTTP_SERVER_BOUNDARY_MAX_LEN)
         {
            //Copy the boundary string
            strncpy(connection->request.boundary, token, n);
            //Properly terminate the string
            connection->request.boundary[n] = '\0';

            //Save the length of the boundary string
            connection->request.boundaryLength = n;
         }
      }
   }
#endif
}
Exemplo n.º 3
0
void WordGenerator (CXMLElement *pCmdLine)
{
    int i;

    //	Load input file

    CString sFilespec = pCmdLine->GetAttribute(CONSTLIT("input"));
    if (sFilespec.IsBlank())
    {
        printf("ERROR: input filename expected.\n");
        return;
    }

    CFileReadBlock InputFile(sFilespec);
    if (InputFile.Open() != NOERROR)
    {
        printf("ERROR: Unable to open file: %s\n", sFilespec.GetASCIIZPointer());
        return;
    }

    //	"Novel" means that we only generate words that are not
    //	in the input file.

    bool bNovelWordsOnly = pCmdLine->GetAttributeBool(NOVEL_ATTRIB);

    //	Build up a word generator

    CMarkovWordGenerator Generator;
    TMap<CString, DWORD> InputWords;

    //	Read each line of the file

    char *pPos = InputFile.GetPointer(0);
    char *pEndPos = pPos + InputFile.GetLength();
    while (pPos < pEndPos)
    {
        //	Skip whitespace

        while (pPos < pEndPos && (strIsWhitespace(pPos) || *pPos < ' '))
            pPos++;

        //	Parse the line

        char *pStart = pPos;
        while (pPos < pEndPos && *pPos != '\r' && *pPos != '\n' && *pPos >= ' ')
            pPos++;

        CString sWord(pStart, pPos - pStart);

        //	Add the word to the generator

        if (!sWord.IsBlank())
        {
            Generator.AddSample(strTrimWhitespace(sWord));

            //	If we are looking for novel words we need to keep a map
            //	of all words in the input file.

            if (bNovelWordsOnly)
                InputWords.Insert(sWord);
        }
    }

    //	If we have a count, then output a list of random words

    int iCount;
    if (pCmdLine->FindAttributeInteger(COUNT_ATTRIB, &iCount))
    {
        if (iCount > 0)
        {
            TArray<CString> Result;
            Generator.GenerateUnique(iCount, &Result);

            for (i = 0; i < Result.GetCount(); i++)
                if (InputWords.Find(Result[i]))
                {
                    Result.Delete(i);
                    i--;
                }

            Result.Sort();

            for (i = 0; i < Result.GetCount(); i++)
                printf("%s\n", Result[i].GetASCIIZPointer());
        }
    }

    //	Otherwise, output the generator as XML

    else
    {
        CMemoryWriteStream Output;
        if (Output.Create() != NOERROR)
        {
            printf("ERROR: Out of memory.\n");
            return;
        }

        if (Generator.WriteAsXML(&Output) != NOERROR)
        {
            printf("ERROR: Unable to output generator as XML.\n");
            return;
        }

        Output.Write("\0", 1);
        printf(Output.GetPointer());
    }
}
Exemplo n.º 4
0
void httpParseAuthField(HttpConnection *connection, char_t *value)
{
   char_t *p;
   char_t *token;

   //Retrieve the authentication scheme
   token = strtok_r(value, " \t", &p);

   //Any parsing error?
   if(token == NULL)
   {
      //Exit immediately
      return;
   }
#if (HTTP_SERVER_BASIC_AUTH_SUPPORT == ENABLED)
   //Basic access authentication?
   else if(!strcasecmp(token, "Basic"))
   {
      error_t error;
      size_t n;
      char_t *separator;

      //Use the relevant authentication scheme
      connection->request.auth.mode = HTTP_AUTH_MODE_BASIC;
      //Retrieve the credentials
      token = strtok_r(NULL, " \t", &p);

      //Any parsing error?
      if(token != NULL)
      {
         //Decrypt the Base64 encoded string
         error = base64Decode(token, strlen(token), token, &n);

         //Successful decoding?
         if(!error)
         {
            //Properly terminate the string
            token[n] = '\0';
            //Check whether a separator is present
            separator = strchr(token, ':');

            //Separator found?
            if(separator != NULL)
            {
               //Split the line
               *separator = '\0';

               //Save user name
               strSafeCopy(connection->request.auth.user,
                  token, HTTP_SERVER_USERNAME_MAX_LEN);

               //Point to the password
               token = separator + 1;
               //Save password
               connection->request.auth.password = token;
            }
         }
      }

      //Debug message
      TRACE_DEBUG("Authorization header:\r\n");
      TRACE_DEBUG("  username: %s\r\n", connection->request.auth.user);
      TRACE_DEBUG("  password: %s\r\n", connection->request.auth.password);
   }
#endif
#if (HTTP_SERVER_DIGEST_AUTH_SUPPORT == ENABLED)
   //Digest access authentication?
   else if(!strcasecmp(token, "Digest"))
   {
      size_t n;
      char_t *separator;
      char_t *name;

      //Use the relevant authentication scheme
      connection->request.auth.mode = HTTP_AUTH_MODE_DIGEST;
      //Get the first parameter
      token = strtok_r(NULL, ",", &p);

      //Parse the Authorization field
      while(token != NULL)
      {
         //Check whether a separator is present
         separator = strchr(token, '=');

         //Separator found?
         if(separator != NULL)
         {
            //Split the string
            *separator = '\0';

            //Get field name and value
            name = strTrimWhitespace(token);
            value = strTrimWhitespace(separator + 1);

            //Retrieve the length of the value field
            n = strlen(value);

            //Discard the surrounding quotes
            if(n > 0 && value[n - 1] == '\"')
               value[n - 1] = '\0';
            if(value[0] == '\"')
               value++;

            //Check parameter name
            if(!strcasecmp(name, "username"))
            {
               //Save user name
               strSafeCopy(connection->request.auth.user,
                  value, HTTP_SERVER_USERNAME_MAX_LEN);
            }
            else if(!strcasecmp(name, "realm"))
            {
               //Save realm
               connection->request.auth.realm = value;
            }
            else if(!strcasecmp(name, "nonce"))
            {
               //Save nonce parameter
               connection->request.auth.nonce = value;
            }
            else if(!strcasecmp(name, "uri"))
            {
               //Save uri parameter
               connection->request.auth.uri = value;
            }
            else if(!strcasecmp(name, "qop"))
            {
               //Save qop parameter
               connection->request.auth.qop = value;
            }
            else if(!strcasecmp(name, "nc"))
            {
               //Save nc parameter
               connection->request.auth.nc = value;
            }
            else if(!strcasecmp(name, "cnonce"))
            {
               //Save cnonce parameter
               connection->request.auth.cnonce = value;
            }
            else if(!strcasecmp(name, "response"))
            {
               //Save response parameter
               connection->request.auth.response = value;
            }
            else if(!strcasecmp(name, "opaque"))
            {
               //Save opaque parameter
               connection->request.auth.opaque = value;
            }

            //Get next parameter
            token = strtok_r(NULL, ",", &p);
         }
      }

      //Debug message
      TRACE_DEBUG("Authorization header:\r\n");
      TRACE_DEBUG("  username: %s\r\n", connection->request.auth.user);
      TRACE_DEBUG("  realm: %s\r\n", connection->request.auth.realm);
      TRACE_DEBUG("  nonce: %s\r\n", connection->request.auth.nonce);
      TRACE_DEBUG("  uri: %s\r\n", connection->request.auth.uri);
      TRACE_DEBUG("  qop: %s\r\n", connection->request.auth.qop);
      TRACE_DEBUG("  nc: %s\r\n", connection->request.auth.nc);
      TRACE_DEBUG("  cnonce: %s\r\n", connection->request.auth.cnonce);
      TRACE_DEBUG("  response: %s\r\n", connection->request.auth.response);
      TRACE_DEBUG("  opaque: %s\r\n", connection->request.auth.opaque);
   }
#endif
   else
   {
      //The specified authentication scheme is not supported
      return;
   }

#if (HTTP_SERVER_BASIC_AUTH_SUPPORT == ENABLED || HTTP_SERVER_DIGEST_AUTH_SUPPORT == ENABLED)
   //The Authorization header has been found
   connection->request.auth.found = TRUE;

   //Invoke user-defined callback, if any
   if(connection->settings->authCallback != NULL)
   {
      //Check whether the access to the specified URI is authorized
      connection->status = connection->settings->authCallback(connection,
         connection->request.auth.user, connection->request.uri);
   }
   else
   {
      //Access to the specified URI is allowed
      connection->status = HTTP_ACCESS_ALLOWED;
   }
#endif
}
Exemplo n.º 5
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;
   }
}
Exemplo n.º 6
0
error_t httpReadHeader(HttpConnection *connection)
{
   error_t error;
   size_t length;
   char_t *token;
   char_t *p;
   char_t *s;

   //Set the maximum time the server will wait for an HTTP
   //request before closing the connection
   error = socketSetTimeout(connection->socket, HTTP_SERVER_IDLE_TIMEOUT);
   //Any error to report?
   if(error) return error;

   //Read the first line of the request
   error = httpReceive(connection, connection->buffer,
      HTTP_SERVER_BUFFER_SIZE - 1, &length, SOCKET_FLAG_BREAK_CRLF);
   //Unable to read any data?
   if(error) return error;

   //Revert to default timeout
   error = socketSetTimeout(connection->socket, HTTP_SERVER_TIMEOUT);
   //Any error to report?
   if(error) return error;

   //Properly terminate the string with a NULL character
   connection->buffer[length] = '\0';
   //Debug message
   TRACE_INFO("%s", connection->buffer);

   //The Request-Line begins with a method token
   token = strtok_r(connection->buffer, " \r\n", &p);
   //Unable to retrieve the method?
   if(!token) return ERROR_INVALID_REQUEST;

   //The Method token indicates the method to be performed on the
   //resource identified by the Request-URI
   error = strSafeCopy(connection->request.method, token, HTTP_SERVER_METHOD_MAX_LEN);
   //Any error to report?
   if(error) return ERROR_INVALID_REQUEST;

   //The Request-URI is following the method token
   token = strtok_r(NULL, " \r\n", &p);
   //Unable to retrieve the Request-URI?
   if(!token) return ERROR_INVALID_REQUEST;

   //Check whether a query string is present
   s = strchr(token, '?');

   //Query string found?
   if(s != NULL)
   {
      //Split the string
      *s = '\0';

      //Save the Request-URI
      error = httpDecodePercentEncodedString(token,
         connection->request.uri, HTTP_SERVER_URI_MAX_LEN);
      //Any error to report?
      if(error)
         return ERROR_INVALID_REQUEST;

      //Check the length of the query string
      if(strlen(s + 1) > HTTP_SERVER_QUERY_STRING_MAX_LEN)
         return ERROR_INVALID_REQUEST;

      //Save the query string
      strcpy(connection->request.queryString, s + 1);
   }
   else
   {
      //Save the Request-URI
      error = httpDecodePercentEncodedString(token,
         connection->request.uri, HTTP_SERVER_URI_MAX_LEN);
      //Any error to report?
      if(error)
         return ERROR_INVALID_REQUEST;

      //No query string
      connection->request.queryString[0] = '\0';
   }

   //Redirect to the default home page if necessary
   if(!strcasecmp(connection->request.uri, "/"))
      strcpy(connection->request.uri, connection->settings->defaultDocument);

   //Clean the resulting path
   pathCanonicalize(connection->request.uri);

   //The protocol version is following the Request-URI
   token = strtok_r(NULL, " \r\n", &p);

   //HTTP version 0.9?
   if(!token)
   {
      //Save version number
      connection->request.version = HTTP_VERSION_0_9;
      //Persistent connections are not supported
      connection->request.keepAlive = FALSE;
   }
   //HTTP version 1.0?
   else if(!strcasecmp(token, "HTTP/1.0"))
   {
      //Save version number
      connection->request.version = HTTP_VERSION_1_0;
      //By default connections are not persistent
      connection->request.keepAlive = FALSE;
   }
   //HTTP version 1.1?
   else if(!strcasecmp(token, "HTTP/1.1"))
   {
      //Save version number
      connection->request.version = HTTP_VERSION_1_1;
      //HTTP 1.1 makes persistent connections the default
      connection->request.keepAlive = TRUE;
   }
   //HTTP version not supported?
   else
   {
      return ERROR_INVALID_REQUEST;
   }

   //Default value for properties
   connection->request.chunkedEncoding = FALSE;
   connection->request.contentLength = 0;

   //HTTP 0.9 does not support Full-Request
   if(connection->request.version >= HTTP_VERSION_1_0)
   {
      //Local variables
      char_t firstChar;
      char_t *separator;
      char_t *name;
      char_t *value;

      //This variable is used to decode header fields that span multiple lines
      firstChar = '\0';

      //Parse the header fields of the HTTP request
      while(1)
      {
         //Decode multiple-line header field
         error = httpReadHeaderField(connection, connection->buffer,
            HTTP_SERVER_BUFFER_SIZE, &firstChar);
         //Any error to report?
         if(error) return error;

         //Debug message
         TRACE_DEBUG("%s", connection->buffer);

         //An empty line indicates the end of the header fields
         if(!strcmp(connection->buffer, "\r\n"))
            break;

         //Check whether a separator is present
         separator = strchr(connection->buffer, ':');

         //Separator found?
         if(separator != NULL)
         {
            //Split the line
            *separator = '\0';

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

            //Connection field found?
            if(!strcasecmp(name, "Connection"))
            {
               //Check whether persistent connections are supported or not
               if(!strcasecmp(value, "keep-alive"))
                  connection->request.keepAlive = TRUE;
               else if(!strcasecmp(value, "close"))
                  connection->request.keepAlive = FALSE;
            }
            //Transfer-Encoding field found?
            else if(!strcasecmp(name, "Transfer-Encoding"))
            {
               //Check whether chunked encoding is used
               if(!strcasecmp(value, "chunked"))
                  connection->request.chunkedEncoding = TRUE;
            }
            //Content-Type field found?
            else if(!strcasecmp(name, "Content-Type"))
            {
               //Parse Content-Type field
               httpParseContentTypeField(connection, value);
            }
            //Content-Length field found?
            else if(!strcasecmp(name, "Content-Length"))
            {
               //Get the length of the body data
               connection->request.contentLength = atoi(value);
            }
            //Authorization field found?
            else if(!strcasecmp(name, "Authorization"))
            {
               //Parse Authorization field
               httpParseAuthField(connection, value);
            }
         }
      }
   }

   //Prepare to read the HTTP request body
   if(connection->request.chunkedEncoding)
   {
      connection->request.byteCount = 0;
      connection->request.firstChunk = TRUE;
      connection->request.lastChunk = FALSE;
   }
   else
   {
      connection->request.byteCount = connection->request.contentLength;
   }

   //The request header has been successfully parsed
   return NO_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;
}
Exemplo n.º 8
0
void CGTextArea::PaintText (CG32bitImage &Dest, const RECT &rcRect)

//	PaintText
//
//	Paint plain text

	{
	//	Paint the text

	if (m_pFont)
		{
		//	If we haven't justified the text for this size, do it now

		if (m_cxJustifyWidth != RectWidth(rcRect))
			{
			m_cxJustifyWidth = RectWidth(rcRect);
			m_Lines.DeleteAll();
			m_pFont->BreakText(m_sText, m_cxJustifyWidth, &m_Lines, CG16bitFont::SmartQuotes);
			}

		//	Compute the rect within which we draw the text

		RECT rcText = rcRect;
		if (m_bEditable)
			{
			int iVSpacing = (RectHeight(rcRect) - m_pFont->GetHeight()) / 2;
			rcText.left += iVSpacing;
			rcText.right -= iVSpacing;
			rcText.top += iVSpacing;
			rcText.bottom -= iVSpacing;
			}

		//	Clip to text rect

		RECT rcOldClip = Dest.GetClipRect();
		Dest.SetClipRect(rcText);

		//	Figure out how many lines fit in the rect

		int iMaxLineCount = RectHeight(rcText) / m_pFont->GetHeight();

		//	If there are too many lines, and we're editable, start at the end

		int iStart = 0;
		if (m_bEditable && iMaxLineCount < m_Lines.GetCount())
			iStart = m_Lines.GetCount() - iMaxLineCount;

		//	Paint each line

		int x = rcText.left;
		int y = rcText.top;
		for (int i = iStart; i < m_Lines.GetCount(); i++)
			{
			CString sLine = m_Lines[i];

			//	Trim the last space in the line, if necessary

			char *pPos = sLine.GetASCIIZPointer();
			if (sLine.GetLength() > 0 && pPos[sLine.GetLength() - 1] == ' ')
				sLine = strTrimWhitespace(sLine);

			//	Alignment

			int xLine;
			if (m_dwStyles & alignCenter)
				{
				int cxWidth = m_pFont->MeasureText(sLine);
				xLine = x + (RectWidth(rcText) - cxWidth) / 2;
				}
			else if (m_dwStyles & alignRight)
				{
				int cxWidth = m_pFont->MeasureText(sLine);
				xLine = x + (RectWidth(rcRect) - cxWidth);
				}
			else
				xLine = x;

			//	Paint

			if (HasEffects())
				m_pFont->DrawTextEffect(Dest, xLine, y, m_rgbColor, sLine, GetEffectCount(), GetEffects());
			else
				Dest.DrawText(xLine, y, *m_pFont, m_rgbColor, sLine);

			//	Next

			y += m_pFont->GetHeight() + m_cyLineSpacing;
			if (y >= rcText.bottom)
				break;
			}

		//	Paint the cursor

		if (m_bEditable && m_iCursorLine >= iStart)
			{
			int cxPos = (m_iCursorLine < m_Lines.GetCount() ? m_pFont->MeasureText(CString(m_Lines[m_iCursorLine].GetASCIIZPointer(), m_iCursorPos, true)) : 0);
			int y = rcText.top + (m_iCursorLine - iStart) * (m_pFont->GetHeight() + m_cyLineSpacing);
			int x = rcText.left;
			if (m_dwStyles & alignCenter)
				{
				int cxWidth = (m_iCursorLine < m_Lines.GetCount() ? m_pFont->MeasureText(m_Lines[m_iCursorLine]) : 0);
				x += ((RectWidth(rcText) - cxWidth) / 2) + cxPos;
				}
			else if (m_dwStyles & alignRight)
				{
				int cxWidth = (m_iCursorLine < m_Lines.GetCount() ? m_pFont->MeasureText(m_Lines[m_iCursorLine]) : 0);
				x += (RectWidth(rcText) - cxWidth) + cxPos;
				}
			else
				x += cxPos;

			if (((m_iTick / 30) % 2) > 0)
				{
				Dest.Fill(x, y, 2, m_pFont->GetHeight(), RGB_CURSOR);
				}
			}

		//	Restore clip

		Dest.SetClipRect(rcOldClip);
		}
	}
Exemplo n.º 9
0
error_t smtpSendCommand(SmtpClientContext *context, const char_t *command,
   uint_t *replyCode, SmtpReplyCallback callback)
{
   error_t error;
   size_t length;
   char_t *line;

   //Any command line to send?
   if(command)
   {
      //Debug message
      TRACE_DEBUG("SMTP client: %s", command);

      //Send the command to the SMTP server
      error = smtpWrite(context, command, strlen(command), SOCKET_FLAG_WAIT_ACK);
      //Failed to send command?
      if(error) return error;
   }

   //Multiline replies are allowed for any command
   while(1)
   {
      //Wait for a response from the server
      error = smtpRead(context, context->buffer,
         SMTP_MAX_LINE_LENGTH - 1, &length, SOCKET_FLAG_BREAK_CRLF);

      //The remote server did not respond as expected?
      if(error) return error;

      //Properly terminate the string with a NULL character
      context->buffer[length] = '\0';
      //Remove all leading and trailing whitespace from the response
      line = strTrimWhitespace(context->buffer);

      //Debug message
      TRACE_DEBUG("SMTP server: %s\r\n", line);

      //Check the length of the response
      if(strlen(line) < 3)
         return ERROR_INVALID_SYNTAX;
      //All replies begin with a three digit numeric code
      if(!isdigit((uint8_t) line[0]) || !isdigit((uint8_t) line[1]) || !isdigit((uint8_t) line[2]))
         return ERROR_INVALID_SYNTAX;
      //A hyphen or a space character must follow the response code
      if(line[3] != '-' && line[3] != ' ' && line[3] != '\0')
         return ERROR_INVALID_SYNTAX;

      //Get the server response code
      *replyCode = strtoul(line, NULL, 10);

      //Any callback function to call?
      if(callback)
      {
         //Invoke callback function to parse the response line
         error = callback(context, line, *replyCode);
         //Check status code
         if(error) return error;
      }

      //A hyphen follows the response code for all but the last line
      if(line[3] != '-') break;
   }

   //Successful processing
   return NO_ERROR;
}
Exemplo n.º 10
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;
}
Exemplo n.º 11
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;
}
Exemplo n.º 12
0
error_t icecastClientConnect(IcecastClientContext *context)
{
   error_t error;
   size_t length;
   IpAddr serverIpAddr;

   //Icecast request template
   const char_t requestTemplate[] =
      "GET /%s HTTP/1.1\r\n"
      "Host: %s\r\n"
      "User-agent: UserAgent\r\n"
      "Icy-MetaData: 1\r\n"
      "Connection: close\r\n"
      "\r\n";

   //The specified Icecast server can be either an IP or a host name
   error = getHostByName(context->settings.interface,
      context->settings.serverName, &serverIpAddr, 1, NULL, 0);
   //Unable to resolve server name?
   if(error) return error;

   //Open a TCP socket
   context->socket = socketOpen(SOCKET_TYPE_STREAM, SOCKET_PROTOCOL_TCP);
   //Failed to open socket?
   if(!context->socket) return ERROR_OUT_OF_RESOURCES;

   //Start of exception handling block
   do
   {
      //Adjust receive timeout
      error = socketSetTimeout(context->socket, ICECAST_CLIENT_TIMEOUT);
      //Any error to report?
      if(error) return error;

      //Connect to the specified Icecast server
      error = socketConnect(context->socket, &serverIpAddr, context->settings.serverPort);
      //Connection with server failed?
      if(error) return error;

      //Format Icecast request
      length = sprintf(context->buffer, requestTemplate,
         context->settings.resource, context->settings.serverName);

      //Debug message
      TRACE_DEBUG(context->buffer);

      //Send Icecast request
      error = socketSend(context->socket, context->buffer,
         length, NULL, SOCKET_FLAG_WAIT_ACK);

      //Failed to send the request?
      if(error) return error;

      //Parse response header
      while(1)
      {
         char_t *separator;
         char_t *property;
         char_t *value;

         //Read a line from the response header
         error = socketReceive(context->socket, context->buffer,
            ICECAST_CLIENT_METADATA_MAX_SIZE, &length, SOCKET_FLAG_BREAK_CRLF);
         //Failed to read data?
         if(error)
            break;

         //Properly terminate the string with a NULL character
         context->buffer[length] = '\0';

         //The end of the header has been reached?
         if(!strcmp(context->buffer, "\r\n"))
            break;

         //Check whether a separator is present
         separator = strchr(context->buffer, ':');

         //Separator found?
         if(separator)
         {
            //Split the line
            *separator = '\0';

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

            //Debug message
            TRACE_INFO("<%s>=<%s>\r\n", property, value);

            //Icy-Metaint property found?
            if(!strcasecmp(property, "Icy-Metaint"))
               context->blockSize = atoi(value);
         }
      }

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

   //Check whether an error occurred
   if(error)
   {
      //Clean up side effects
      socketClose(context->socket);
   }

   //Return status code
   return error;
}
Exemplo n.º 13
0
bool CPlayerDisplay::OnChar (char chChar)

//	OnChar
//
//	Handle character

	{
	if (!m_bEditing)
		return false;

	switch (chChar)
		{
		case SDLK_BACKSPACE:
			{
			if (m_bClearAll)
				m_sEditBuffer = CString();
			else
				{
				if (!m_sEditBuffer.IsBlank())
					m_sEditBuffer = strSubString(m_sEditBuffer, 0, m_sEditBuffer.GetLength() - 1);
				}

			m_bInvalid = true;
			m_bClearAll = false;
			break;
			}

		case SDLK_RETURN:
			{
			m_sEditBuffer = strTrimWhitespace(m_sEditBuffer);
			if (!m_sEditBuffer.IsBlank())
				{
				m_sName = m_sEditBuffer;
				m_pTrans->SetPlayerName(m_sName);
				}

			m_bEditing = false;
			m_bInvalid = true;
			break;
			}

		case SDLK_ESCAPE:
			{
			m_bEditing = false;
			m_bInvalid = true;
			break;
			}

		//	Characters

		default:
			{
			if (!isprint(chChar))
				break;

			if (m_bClearAll)
				m_sEditBuffer = CString(&chChar, 1);
			else
				m_sEditBuffer.Append(CString(&chChar, 1));

			m_bInvalid = true;
			m_bClearAll = false;
			}
		}

	return true;
	}