Exemplo n.º 1
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;
}
Exemplo n.º 2
0
void ftpServerSendData(FtpServerContext *context, FtpClientConnection *connection)
{
   error_t error;
   size_t n;

   //Any data waiting for transmission?
   if(connection->bufferLength > 0)
   {
      //Send more data
      error = socketSend(connection->dataSocket, connection->buffer +
         connection->bufferPos, connection->bufferLength, &n, 0);

      //Failed to send data?
      if(error != NO_ERROR && error != ERROR_TIMEOUT)
      {
         //Close the data connection
         ftpServerCloseDataConnection(connection);

         //Release previously allocated resources
         if(connection->file != NULL)
         {
            fsCloseFile(connection->file);
            connection->file = NULL;
         }
         if(connection->dir != NULL)
         {
            fsCloseDir(connection->dir);
            connection->dir = NULL;
         }

         //Back to idle state
         connection->controlState = FTP_CONTROL_STATE_IDLE;

         //Transfer status
         strcpy(connection->response, "451 Transfer aborted\r\n");
         //Debug message
         TRACE_DEBUG("FTP server: %s", connection->response);

         //Number of bytes in the response buffer
         connection->responseLength = strlen(connection->response);
         connection->responsePos = 0;

         //Exit immediately
         return;
      }

      //Advance data pointer
      connection->bufferPos += n;
      //Number of bytes still available in the buffer
      connection->bufferLength -= n;
   }

   //Empty transmission buffer?
   if(connection->bufferLength == 0)
   {
      //File transfer in progress?
      if(connection->controlState == FTP_CONTROL_STATE_RETR)
      {
         //Read more data
         error = fsReadFile(connection->file,
            connection->buffer, FTP_SERVER_BUFFER_SIZE, &n);

         //End of stream?
         if(error)
         {
            //Close file
            fsCloseFile(connection->file);
            connection->file = NULL;

            //Wait for all the data to be transmitted and acknowledged
            connection->dataState = FTP_DATA_STATE_WAIT_ACK;

            //Exit immediately
            return;
         }
      }
      //Directory listing in progress?
      else if(connection->controlState == FTP_CONTROL_STATE_LIST)
      {
         uint_t perm;
         time_t currentTime;
         time_t modified;
         char_t *path;
         FsDirEntry dirEntry;

         //Read a new entry in the directory
         error = fsReadDir(connection->dir, &dirEntry);

         //End of stream?
         if(error)
         {
            //Close directory
            fsCloseDir(connection->dir);
            connection->dir = NULL;

            //Wait for all the data to be transmitted and acknowledged
            connection->dataState = FTP_DATA_STATE_WAIT_ACK;

            //Exit immediately
            return;
         }

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

         //Get the pathname of the directory being listed
         strcpy(path, connection->path);
         //Retrieve the full pathname
         pathCombine(path, dirEntry.name, FTP_SERVER_MAX_PATH_LEN);
         pathCanonicalize(path);

         //Get permissions for the specified file
         perm = ftpServerGetFilePermissions(context, connection, path);

         //Enforce access rights
         if(perm & FTP_FILE_PERM_LIST)
         {
            //Format links, owner, group and size fields
            n = sprintf(connection->buffer, "----------   1 owner    group    %10" PRIu32,
               dirEntry.size);

            //Check whether the current entry is a directory
            if(dirEntry.attributes & FS_FILE_ATTR_DIRECTORY)
               connection->buffer[0] = 'd';

            //Read access?
            if(perm & FTP_FILE_PERM_READ)
            {
               connection->buffer[1] = 'r';
               connection->buffer[4] = 'r';
               connection->buffer[7] = 'r';
            }
            //Write access
            if(perm & FTP_FILE_PERM_WRITE)
            {
               connection->buffer[2] = 'w';
               connection->buffer[5] = 'w';
               connection->buffer[8] = 'w';
            }

            //Get current time
            currentTime = getCurrentUnixTime();
            //Get modification time
            modified = convertDateToUnixTime(&dirEntry.modified);

            //Check whether the modification time is within the previous 180 days
            if(currentTime > modified && currentTime < (modified + FTP_SERVER_180_DAYS))
            {
               //The format of the date/time field is Mmm dd hh:mm
               n += sprintf(connection->buffer + n, " %s %02" PRIu8 " %02" PRIu8 ":%02" PRIu8,
                  months[MIN(dirEntry.modified.month, 12)], dirEntry.modified.day,
                  dirEntry.modified.hours, dirEntry.modified.minutes);
            }
            else
            {
               //The format of the date/time field is Mmm dd  yyyy
               n += sprintf(connection->buffer + n, " %s %02" PRIu8 "  %04" PRIu16,
                  months[MIN(dirEntry.modified.month, 12)], dirEntry.modified.day,
                  dirEntry.modified.year);
            }

            //Append filename
            n += sprintf(connection->buffer + n, " %s\r\n", dirEntry.name);
            //Debug message
            TRACE_DEBUG("FTP server: %s", connection->buffer);
         }
         else
         {
            //Insufficient access rights
            n = 0;
         }
      }
      //Invalid state?
      else
      {
         //The FTP server has encountered a critical error
         ftpServerCloseConnection(context, connection);
         //Exit immediately
         return;
      }

      //Number of bytes in the buffer
      connection->bufferPos = 0;
      connection->bufferLength = n;
   }
}
Exemplo n.º 3
0
errc tapLoadFile(tFileSystemDirEntry *dir)
{
    unsigned long addr, targetAddr;
    unsigned char pole[3];
    unsigned char *ind;
    unsigned char data[512];
    unsigned char state;
    unsigned int block_length, min;
    unsigned int memInd, sector;
    errc err;

    targetAddr = 0x80000;
   
    sector=0;
    
    state = 0;

    addr = 0;
    //prenesu snapshot do pameti. (dir->size)
    while (addr < (dir->size)) {

        //vypocitam si index do pole s daty. Pole je velke 512 bajtu
        memInd = addr & 0x1FF; 

        //prectu odpovidajici sektor v souboru
        if (memInd == 0) {
            if ((err = fsReadFile(dir->cluster, sector, data)) != ERR_OK) return err;
            sector++;
            dmaSetDestAddr(targetAddr);
            dmaSetConfig(DMA_INC_DST | DMA_INC_SRC);

        }

        switch(state) {
            //DATA BLOCK
            case 0: //DATA LENGTH lsb
                block_length = data[memInd];
                addr++;
                state = 1;
                break;
            case 1: //DATA LENGTH msb
                block_length |= (((unsigned int)data[memInd]) << 8);
                addr++;
                state = 2;
                break;
            //TAPE DATA
            case 2: //TAPE DATA
                min = 512 - memInd; 
                min = (block_length > min ? min : block_length);
                //nastavim DMA radic
                dmaSetSrcAddr(swAddr2hwAddr(((unsigned long)data)+memInd)); 
                dmaTransfer(min);
                targetAddr += min;
                block_length -= min;
                addr += min;
                if (block_length==0) state = 0;
                break;
        }
    }

    //pripravim ukazatel DMA na zacatek tape dat. ROMka pak muze cist kazetu pekne od zacatku    
    dmaSetSrcAddr(0x80000);
    dmaSetConfig(DMA_INC_SRC);
    
    //spustim aplikaci
    ind = pole;
    ind += taskSetPC(ind,0,0);
    ind--;
    taskRun(ind,pole);

    return ERR_OK;
}
Exemplo n.º 4
0
void play_from_file(INT choose,INT ch)
{
	INT		hFile;
	INT		nReadBytes;
	INT		nTime0;
	INT 	nErr;
	INT8	bAsciiFileName [20];
	INT8	bUnicodeFileName [40];
	INT		ntemp,nVol=20 ;
	INT 	nSPToggle=0;
	INT 	nHPToggle=0;

	_uPcmQHead = _uPcmQTail = 0;

	strcpy(bAsciiFileName , "c:\\record.pcm");

	fsAsciiToUnicode(bAsciiFileName, bUnicodeFileName, TRUE);
	hFile = fsOpenFile(bUnicodeFileName, NULL, OP_READ);
	if (hFile < 0)
	{
		printf("Can't open playback file0x%x!\n",hFile);
		//return;
	}
#if defined (TEST_WM8978)
	/* for eCos version audio lib*/
#if 0	
	if (choose==32000)//8.192Mhz
	{
		outpw(REG_APLLCON, 0x6529);
		outpw(REG_CLKDIV0, (inpw(REG_CLKDIV0) & 0xFF0FFFFF) | 0x500000);
	}
	else if (choose%8000==0 || choose%12000==0){//12.288Mhz
		outpw(REG_APLLCON, 0x6529);
		outpw(REG_CLKDIV0, (inpw(REG_CLKDIV0) & 0xFF0FFFFF) | 0x300000);
	}
	else if (choose%11025==0){//11.289Mhz
		outpw(REG_APLLCON, 0x652f);
		outpw(REG_CLKDIV0, (inpw(REG_CLKDIV0) & 0xFF0FFFFF) | 0x400000);
	}
#else
	if (choose%8000==0 || choose%12000==0){//24.576Mhz
		outpw(REG_APLLCON, 0x6529);
		outpw(REG_CLKDIV0, (inpw(REG_CLKDIV0) & 0xFF0FFFFF) | 0x100000);
	}
	else if (choose%11025==0){//22.579Mhz
		outpw(REG_APLLCON, 0x642d);
		outpw(REG_CLKDIV0, (inpw(REG_CLKDIV0) & 0xFF0FFFFF) | 0x200000);
	}
#endif	
#endif

	/* read PCM data to PCM buffer */
	printf("Read %d KB to PCM data buffer...\n", PCM_QUEUE_LEN/1024);
	
	nErr = fsReadFile(hFile, _pucPcmQueue, 256*1024, &nReadBytes);
	if (nErr<0)
		printf("err num=%d\n",nErr);
	//memset(_pucPcmQueue,0,PCM_QUEUE_LEN);

	printf("OK\n");
	
	audioStartPlay(play_callback, choose, ch);
	//tiaic31StartPlay(play_callback, choose, channels,format);
		
	audioSetPlayVolume(nVol,nVol);
	
	
		
	ntemp = nTime0 = sysGetTicks(TIMER1);
	
	
	while (1)
	{
		if (sysGetTicks(TIMER1) - nTime0 >= 100)
		{
			nTime0 = sysGetTicks(TIMER1);
			printf("H=%d, T=%d\n", _uPcmQHead/1024, _uPcmQTail/1024);
			
		}

		if ((_uPcmQTail > _uPcmQHead) ||
			((_uPcmQTail < _uPcmQHead) && (_uPcmQHead - _uPcmQTail > 64*1024)))
		{
			fsReadFile(hFile, &_pucPcmQueue[_uPcmQTail], 64*1024, &nReadBytes);
			
			if (nReadBytes > 0)
				_uPcmQTail = (_uPcmQTail + nReadBytes) % PCM_QUEUE_LEN;
			if (sysGetTicks(TIMER1) - ntemp >=1000)
				break;
		}
		
		if (inpb(REG_COM_LSR) & 0x01)			/* check key press */
		{
			CHAR  cmd = inpb(REG_COM_RX);
			if (cmd=='1')
			{
				if (--nVol<=0)
					nVol=0;
				audioSetPlayVolume(nVol,nVol);
				printf("vol=%d\n",nVol);
			}else if (cmd=='2')
			{
				if (++nVol>=31)
					nVol=31;
				audioSetPlayVolume(nVol,nVol);
				printf("vol=%d\n",nVol);
			}else if (cmd=='3')
			{
				if (nSPToggle)
				{
					audioSelectOutputPath(OUT_PATH_SP,TRUE);
					nSPToggle = 0;
				}else
				{
					audioSelectOutputPath(OUT_PATH_SP,FALSE);
					nSPToggle = 1;
				}
				
					
			}
			else if (cmd=='4')
			{
				if (nHPToggle)
				{
					audioSelectOutputPath(OUT_PATH_HP,TRUE);
					nHPToggle = 0;
				}else
				{
					audioSelectOutputPath(OUT_PATH_HP,FALSE);
					nHPToggle = 1;
				}
			}
		}
		

	}
	fsCloseFile(hFile);
	
	audioStopPlay();

}
Exemplo n.º 5
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;
}
Exemplo n.º 6
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;
}