예제 #1
0
파일: HTTPUtils.c 프로젝트: Eric2015/MICO
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;
}
예제 #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;
}
예제 #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;

    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;
    }

    /* For chunked extra data without content length */
    if(inHeader->chunkedData == true) {
        inHeader->chunkedDataBufferLen = (inHeader->extraDataLen > READ_LENGTH)? inHeader->extraDataLen:READ_LENGTH;
        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->extraDataLen : inHeader->contentLength;
        if(inHeader->onReceivedDataCallback && (inHeader->onReceivedDataCallback)(inHeader, 0, (uint8_t *)end, copyDataLen, inHeader->userContext)==kNoErr) {
            inHeader->isCallbackSupported = true;
            inHeader->extraDataPtr = calloc(READ_LENGTH, sizeof(uint8_t));
            require_action(inHeader->extraDataPtr, exit, err = kNoMemoryErr);
        } else {
            inHeader->isCallbackSupported = false;
            inHeader->extraDataPtr = calloc(inHeader->contentLength , 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);
    //   (inHeader->onReceivedDataCallback)(inHeader, 0, (uint8_t *)inHeader->extraDataPtr, inHeader->extraDataLen, inHeader->userContext);

    //   err = kNoErr;
    // }
    else
        return kNoErr;

exit:
    return err;
}