void PrintHTTPHeader( HTTPHeader_t *inHeader )
{ 
  char temp[20];
  //(void)inHeader; // Fix warning when debug=0
  //http_utils_log("Header:\n %s", inHeader->buf);
  //http_utils_log("Length: %d", (int)inHeader->len);
  strncpy(temp, inHeader->methodPtr, 8);
  http_utils_log("Method: %s", temp);
  strncpy(temp, inHeader->urlPtr, 20);
  http_utils_log("URL: %s", temp);
  strncpy(temp, inHeader->protocolPtr, 8);
  http_utils_log("Protocol: %s", temp);
  http_utils_log("Status Code: %d", inHeader->statusCode);
  http_utils_log("ChannelID: %d", inHeader->channelID);
  http_utils_log("Content length: %lld", inHeader->contentLength);
  http_utils_log("Persistent: %s", YesOrNo( inHeader->persistent ));
}
Esempio n. 2
0
int SocketReadHTTPHeader( int inSock, HTTPHeader_t *inHeader )
{
    int        err =0;
    char *          buf;
    char *          dst;
    char *          lim;
    char *          end;
    size_t          len;
    ssize_t         n;
    const char *    value;
    size_t          valueSize;

    buf = inHeader->buf;
    dst = buf + inHeader->len;
    lim = buf + sizeof( inHeader->buf );
    for( ;; )
    {
        // If there's data from a previous read, move it to the front to search it first.
        len = inHeader->extraDataLen;
        if( len > 0 )
        {
            require_action( len <= (size_t)( lim - dst ), exit, err = kParamErr );
            memmove( dst, inHeader->extraDataPtr, len );
            inHeader->extraDataLen = 0;
        }
        else
        {
            //do
            //{
                n = read( inSock, dst, (size_t)( lim - dst ) );
            //    err = map_socket_value_errno( inSock, n >= 0, n );
            //}   while( err == EINTR );
            if(      n  > 0 ) len = (size_t) n;
            else  { err = kConnectionErr; goto exit; }
            //else goto exit;
        }
        dst += len;
        inHeader->len += len;
        
        if(findHeader( inHeader,  &end ))
            break ;
    }

    inHeader->len = (size_t)( end - buf );
    err = HTTPHeaderParse( inHeader );
    require_noerr( err, exit );
    inHeader->extraDataLen = (size_t)( dst - end );
    if(inHeader->extraDataPtr) {
        free((uint8_t *)inHeader->extraDataPtr);
        inHeader->extraDataPtr = 0;
    }

    if(inHeader->otaDataPtr) {
        free((uint8_t *)inHeader->otaDataPtr);
        inHeader->otaDataPtr = 0;
    }

    err = HTTPGetHeaderField( inHeader->buf, inHeader->len, "Content-Type", NULL, NULL, &value, &valueSize, NULL );
    
    if(err == kNoErr && strnicmpx( value, valueSize, kMIMEType_MXCHIP_OTA ) == 0){
        http_utils_log("Receive OTA data!");        
        err = PlatformFlashInitialize();
        require_noerr(err, exit);
        err = PlatformFlashWrite(&flashStorageAddress, (uint32_t *)end, inHeader->extraDataLen);
        require_noerr(err, exit);
    }else{
        inHeader->extraDataPtr = calloc(inHeader->contentLength, sizeof(uint8_t));
        require_action(inHeader->extraDataPtr, exit, err = kNoMemoryErr);
        memcpy((uint8_t *)inHeader->extraDataPtr, end, inHeader->extraDataLen);
        err = kNoErr;
    }

exit:
    return err;
}
Esempio n. 3
0
int SocketReadHTTPHeader( int inSock, HTTPHeader_t *inHeader )
{
  int        err =0;
  char *          buf;
  char *          dst;
  char *          lim;
  char *          end;
  size_t          len;
  ssize_t         n;
  const char *    value;
  size_t          valueSize;
  
  buf = inHeader->buf;
  dst = buf + inHeader->len;
  lim = buf + sizeof( inHeader->buf );
  for( ;; )
  {
    if(findHeader( inHeader,  &end ))
      break ;
    n = read( inSock, dst, (size_t)( lim - dst ) );
    if(      n  > 0 ) len = (size_t) n;
    else  { err = kConnectionErr; goto exit; }
    dst += len;
    inHeader->len += len;
  }
  
  inHeader->len = (size_t)( end - buf );
  err = HTTPHeaderParse( inHeader );
  require_noerr( err, exit );
  inHeader->extraDataLen = (size_t)( dst - end );
  if(inHeader->extraDataPtr) {
    free((uint8_t *)inHeader->extraDataPtr);
    inHeader->extraDataPtr = 0;
  }
  
  if(inHeader->otaDataPtr) {
    free((uint8_t *)inHeader->otaDataPtr);
    inHeader->otaDataPtr = 0;
  }
  
  /* For MXCHIP OTA function, store extra data to OTA data temporary */
  err = HTTPGetHeaderField( inHeader->buf, inHeader->len, "Content-Type", NULL, NULL, &value, &valueSize, NULL );

  if(err == kNoErr && strnicmpx( value, valueSize, kMIMEType_MXCHIP_OTA ) == 0){
#ifdef MICO_FLASH_FOR_UPDATE  
    http_utils_log("Receive OTA data!");        
    err = MicoFlashInitialize( MICO_FLASH_FOR_UPDATE );
    require_noerr(err, exit);
    err = MicoFlashWrite(MICO_FLASH_FOR_UPDATE, &flashStorageAddress, (uint8_t *)end, inHeader->extraDataLen);
    require_noerr(err, exit);
#else
    http_utils_log("OTA flash memory is not existed!");
    err = kUnsupportedErr;
#endif
    goto exit;
  }

  /* For chunked extra data without content length */
  if(inHeader->chunkedData == true){
    inHeader->chunkedDataBufferLen = (inHeader->extraDataLen > 256)? inHeader->extraDataLen:256;
    inHeader->chunkedDataBufferPtr = calloc(inHeader->chunkedDataBufferLen, sizeof(uint8_t)); //Make extra data buffer larger than chunk length
    require_action(inHeader->chunkedDataBufferPtr, exit, err = kNoMemoryErr);
    memcpy((uint8_t *)inHeader->chunkedDataBufferPtr, end, inHeader->extraDataLen);
    inHeader->extraDataPtr = inHeader->chunkedDataBufferPtr;
    return kNoErr;
  }

  /* Extra data with content length */
  if (inHeader->contentLength != 0){ //Content length >0, create a memory buffer (Content length) and store extra data
    size_t copyDataLen = (inHeader->contentLength >= inHeader->extraDataLen)? inHeader->contentLength:inHeader->extraDataLen;
    inHeader->extraDataPtr = calloc(copyDataLen , sizeof(uint8_t));
    require_action(inHeader->extraDataPtr, exit, err = kNoMemoryErr);
    memcpy((uint8_t *)inHeader->extraDataPtr, end, copyDataLen);
    err = kNoErr;
  } /* Extra data without content length, data is ended by conntection close */
  else if(inHeader->extraDataLen != 0){ //Content length =0, but extra data length >0, create a memory buffer (1500)and store extra data
    inHeader->dataEndedbyClose = true;
    inHeader->extraDataPtr = calloc(1500, sizeof(uint8_t));
    require_action(inHeader->extraDataPtr, exit, err = kNoMemoryErr);
    memcpy((uint8_t *)inHeader->extraDataPtr, end, inHeader->extraDataLen);
    err = kNoErr;
  }
  else
    return kNoErr;
  
exit:
  return err;
}
Esempio n. 4
0
OSStatus SocketReadHTTPBody( int inSock, HTTPHeader_t *inHeader )
{
  OSStatus err = kParamErr;
  ssize_t readResult;
  int selectResult;
  fd_set readSet;
  const char *    value;
  size_t          valueSize;
  size_t    lastChunkLen, chunckheaderLen; 
  char *nextPackagePtr;
#ifdef MICO_FLASH_FOR_UPDATE
  bool writeToFlash = false;
#endif
  
  require( inHeader, exit );
  
  err = kNotReadableErr;
  
  FD_ZERO( &readSet );
  FD_SET( inSock, &readSet );

  /* Chunked data, return after receive one chunk */
  if( inHeader->chunkedData == true ){
    /* Move next chunk to chunked data buffer header point */
    lastChunkLen = inHeader->extraDataPtr - inHeader->chunkedDataBufferPtr + inHeader->contentLength;
    if(inHeader->contentLength) lastChunkLen+=2;  //Last chunck data has a CRLF tail
    memmove( inHeader->chunkedDataBufferPtr, inHeader->chunkedDataBufferPtr + lastChunkLen, inHeader->chunkedDataBufferLen - lastChunkLen  );
    inHeader->extraDataLen -= lastChunkLen;

    while ( findChunkedDataLength( inHeader->chunkedDataBufferPtr, inHeader->extraDataLen, &inHeader->extraDataPtr ,"%llu", &inHeader->contentLength ) == false){
      require_action(inHeader->extraDataLen < inHeader->chunkedDataBufferLen, exit, err=kMalformedErr );

      selectResult = select( inSock + 1, &readSet, NULL, NULL, NULL );
      require( selectResult >= 1, exit ); 

      readResult = read( inSock, inHeader->extraDataPtr, (size_t)( inHeader->chunkedDataBufferLen - inHeader->extraDataLen ) );

      if( readResult  > 0 ) inHeader->extraDataLen += readResult;
      else { err = kConnectionErr; goto exit; }
    }

    chunckheaderLen = inHeader->extraDataPtr - inHeader->chunkedDataBufferPtr;

    if(inHeader->contentLength == 0){ //This is the last chunk
      while( findCRLF( inHeader->extraDataPtr, inHeader->extraDataLen - chunckheaderLen, &nextPackagePtr ) == false){ //find CRLF
        selectResult = select( inSock + 1, &readSet, NULL, NULL, NULL );
        require( selectResult >= 1, exit ); 

        readResult = read( inSock,
                          (uint8_t *)( inHeader->extraDataPtr + inHeader->extraDataLen - chunckheaderLen ),
                          256 - inHeader->extraDataLen ); //Assume chunk trailer length is less than 256 (256 is the min chunk buffer, maybe dangerous

        if( readResult  > 0 ) inHeader->extraDataLen += readResult;
        else { err = kConnectionErr; goto exit; }
      }

      err = kNoErr;
      goto exit;
    }
    else{
      /* Extend chunked data buffer */
      if( inHeader->chunkedDataBufferLen < inHeader->contentLength + chunckheaderLen + 2){
        inHeader->chunkedDataBufferLen = inHeader->contentLength + chunckheaderLen + 256;
        inHeader->chunkedDataBufferPtr = realloc(inHeader->chunkedDataBufferPtr, inHeader->chunkedDataBufferLen);
        require_action(inHeader->extraDataPtr, exit, err = kNoMemoryErr);
      }

      /* Read chunked data */
      while ( inHeader->extraDataLen < inHeader->contentLength + chunckheaderLen + 2 ){
        selectResult = select( inSock + 1, &readSet, NULL, NULL, NULL );
        require( selectResult >= 1, exit ); 

        readResult = read( inSock,
                          (uint8_t *)( inHeader->extraDataPtr + inHeader->extraDataLen - chunckheaderLen),
                          ( inHeader->contentLength - (inHeader->extraDataLen - chunckheaderLen) + 2 ));
        
        if( readResult  > 0 ) inHeader->extraDataLen += readResult;
        else { err = kConnectionErr; goto exit; }
      } 
      
      if( *(inHeader->extraDataPtr + inHeader->contentLength) != '\r' ||
         *(inHeader->extraDataPtr + inHeader->contentLength +1 ) != '\n'){
           err = kMalformedErr; 
           goto exit;
         }
    }
  }

  /* We has extra data but total length is not clear, store them to 1500 bytes buffer 
     return when connection is disconnected by remote server */
  if( inHeader->dataEndedbyClose == true){ 
    if(inHeader->contentLength == 0) { //First read body, return using data received by SocketReadHTTPHeader
      inHeader->contentLength = inHeader->extraDataLen;
    }else{
      selectResult = select( inSock + 1, &readSet, NULL, NULL, NULL );
      require( selectResult >= 1, exit ); 
      
      readResult = read( inSock,
                        (uint8_t*)( inHeader->extraDataPtr ),
                        1500 );
      if( readResult  > 0 ) inHeader->contentLength = readResult;
      else { err = kConnectionErr; goto exit; }
    }
    err = kNoErr;
    goto exit;
  }
  
  /* We has extra data and we has a predefined buffer to store the total extra data
     return when all data has received*/
  while ( inHeader->extraDataLen < inHeader->contentLength )
  {
    selectResult = select( inSock + 1, &readSet, NULL, NULL, NULL );
    require( selectResult >= 1, exit );
    
    
    err = HTTPGetHeaderField( inHeader->buf, inHeader->len, "Content-Type", NULL, NULL, &value, &valueSize, NULL );
    require_noerr(err, exit);
    if( strnicmpx( value, valueSize, kMIMEType_MXCHIP_OTA ) == 0 ){
#ifdef MICO_FLASH_FOR_UPDATE  
      writeToFlash = true;
      inHeader->otaDataPtr = calloc(OTA_Data_Length_per_read, sizeof(uint8_t)); 
      require_action(inHeader->otaDataPtr, exit, err = kNoMemoryErr);
      if((inHeader->contentLength - inHeader->extraDataLen)<OTA_Data_Length_per_read){
        readResult = read( inSock,
                          (uint8_t*)( inHeader->otaDataPtr ),
                          ( inHeader->contentLength - inHeader->extraDataLen ) );
      }else{
        readResult = read( inSock,
                          (uint8_t*)( inHeader->otaDataPtr ),
                          OTA_Data_Length_per_read);
      }
      
      if( readResult  > 0 ) inHeader->extraDataLen += readResult;
      else { err = kConnectionErr; goto exit; }
      
      err = MicoFlashWrite(MICO_FLASH_FOR_UPDATE, &flashStorageAddress, (uint8_t *)inHeader->otaDataPtr, readResult);
      require_noerr(err, exit);
      
      free(inHeader->otaDataPtr);
      inHeader->otaDataPtr = 0;
#else
      http_utils_log("OTA flash memory is not existed, !");
      err = kUnsupportedErr;
#endif
    }else{
      readResult = read( inSock,
                        (uint8_t*)( inHeader->extraDataPtr + inHeader->extraDataLen ),
                        ( inHeader->contentLength - inHeader->extraDataLen ) );
      
      if( readResult  > 0 ) inHeader->extraDataLen += readResult;
      else { err = kConnectionErr; goto exit; }
    }
  }  
  err = kNoErr;
  
exit:
  if(err != kNoErr) inHeader->len = 0;
  if(inHeader->otaDataPtr) {
    free(inHeader->otaDataPtr);
    inHeader->otaDataPtr = 0;
  }
#ifdef MICO_FLASH_FOR_UPDATE
  if(writeToFlash == true) MicoFlashFinalize(MICO_FLASH_FOR_UPDATE);
#endif
  return err;
}