• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
File Uploading to HTTP server using CFHTTPMessage API fails
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

File Uploading to HTTP server using CFHTTPMessage API fails


  • Subject: File Uploading to HTTP server using CFHTTPMessage API fails
  • From: DEBAPRIO BANIK <email@hidden>
  • Date: Thu, 12 Jan 2012 13:05:28 +0530

Hi All,

I am facing an issue with uploading of file using HTTP file upload. The protocol followed as per the client-server understanding is that, the http request headers for 
upload txn should go first followed by a stream which should contain the data of the request XML followed by the data of the file buffer.

Now, the request headers are reaching and server after reading the headers starts reading the stream. It gets the request XML from the stream as well.
After this, server reads the file data from the stream. After the file upload shows done, i try to download the same file. In the server, i see the file is there and it shows correct size too. 
After i download the file, i find the file is cropped in the end (in case of a jpg file) or some end text is missing(in case of txt file).

According to my project's logic, data is transferred in 8KB chunks. I have verified that the last chunk which is lesser than 8KB is the missing data causing the cropping
of images. I have also verified that the last chunk has valid data in the buffer formed by the fileHandler API.  I am sending a few code snippets which i have used for the write logic. 

Can you identify any particular reason for the last chunk not getting streamed or some junk data getting streamed in place of the last chunk?

Code snippet for creating the writestream:

const UInt8 *uploadBuf;
uploadBuf = (const UInt8*)malloc(totLen);

CFReadStreamRef readStreamForBody = CFReadStreamCreateWithBytesNoCopy(kCFAllocatorDefault, uploadBuf, (CFIndex)totLen, kCFAllocatorNull);
CFReadStreamRef readStreamForUpload = CFReadStreamCreateForStreamedHTTPRequest(kCFAllocatorDefault, messageRef, readStreamForBody);


if (CFReadStreamOpen(readStreamForUpload) == TRUE)
{

CFWriteStreamRef writeStream = CFWriteStreamCreateWithBuffer(kCFAllocatorDefault, (UInt8*)uploadBuf, (CFIndex)totLen);
if ( CFWriteStreamOpen(writeStream) == FALSE)    
{
CFErrorRef streamError = CFWriteStreamCopyError(writeStream);
CFStringRef streamErrorString = CFErrorCopyDescription(streamError);
CFShow(streamErrorString);
CFRelease(streamError);
CFRelease(streamErrorString);

CFWriteStreamClose(writeStream);
CFRelease(writeStream);
writeStream = NULL;
}
else 
{
Boolean hasBytes = FALSE;
CFStreamStatus  streamStatus = CFWriteStreamGetStatus(writeStream);
do
{
while ((hasBytes == FALSE) &&
   ((streamStatus != kCFStreamStatusNotOpen) &&
(streamStatus != kCFStreamStatusAtEnd) &&
(streamStatus != kCFStreamStatusClosed) &&
(streamStatus != kCFStreamStatusError)))

{
CFRunLoopRunInMode (kCFRunLoopDefaultMode, 0.25, false);
hasBytes    = CFWriteStreamCanAcceptBytes(writeStream);
streamStatus    = CFWriteStreamGetStatus(writeStream);
}
}while (hasBytes != TRUE);

Code snippet for saving the writestream:

[self setWriteStreamForFile:writeStream];
[[MyHTTPLastRequestList lastRequestList] setObject:self forKey:[self sessionKey]];

Code snippet for writing the buffer to the writestream:

- (void) write:(const void*)fileBuffer numBytes:(NSUInteger)fileBufSize
{
MyThreadSafeDictionary *lastRequestList = [MyHTTPLastRequestList lastRequestList];
NSString *sessionKey = [self sessionKey];

BOOL noResponse = YES;
while (noResponse)
noResponse = ([lastRequestList objectForKey:sessionKey] == nil);

MyHTTPMessage *httpFileUploadMsg = (MyHTTPMessage*)[lastRequestList objectForKey:sessionKey];
CFIndex totalLen = [httpFileUploadMsg totalLength];
CFIndex sentLen = [httpFileUploadMsg sentLength];
NSData *chunkData = [[[NSData dataWithBytes:fileBuffer length:fileBufSize] retain] autorelease];
sentLen += (CFIndex)fileBufSize;
CFIndex bytesRemaining = totalLen - sentLen;
CFIndex bytesWritten = 0;

CFWriteStreamRef writeStream = [httpFileUploadMsg writeStreamForFile];
if (bytesRemaining > 0)
{
CFWriteStreamRef writeStream = [httpFileUploadMsg writeStreamForFile];
bytesWritten = CFWriteStreamWrite(writeStream, (const UInt8*)[chunkData bytes], (CFIndex)fileBufSize);
[httpFileUploadMsg setSentLength:sentLen];
NSLog(@"Bytes written to stream = %d",(NSInteger)sentLen);
[httpFileUploadMsg setWriteStreamForFile:writeStream];
}
else  
{
@try 
{
bytesWritten = CFWriteStreamWrite(writeStream, (const UInt8*)[chunkData bytes], (CFIndex)fileBufSize);
if (bytesWritten == 0)
{
NSLog(@"ERROR :: Stream Filled to capacity");
}
else if (bytesWritten < 0)
{
NSLog(@"ERROR :: Write failed.");
CFErrorRef streamError = CFWriteStreamCopyError(writeStream);
CFStringRef streamErrorString = CFErrorCopyDescription(streamError);
CFShow(streamErrorString);
CFRelease(streamError);
CFRelease(streamErrorString);
}
else 
{
NSLog(@"Write Success");
}
}
@catch (NSException* localException) 
{
NSLog(@"Exception raised - %@",[localException name]);
[localException raise];
}


NSLog(@"Sending to the server");
CFReadStreamRef readStreamForUpload = [httpFileUploadMsg readStreamForHTTPResponse];
CFStreamStatus  rStreamStatus = CFReadStreamGetStatus(readStreamForUpload);
Boolean parentStreamHasBytes = FALSE;
do
{
while ((parentStreamHasBytes == FALSE) &&
   ((rStreamStatus != kCFStreamStatusNotOpen) &&
(rStreamStatus != kCFStreamStatusAtEnd) &&
(rStreamStatus != kCFStreamStatusClosed) &&
(rStreamStatus != kCFStreamStatusError)))


{
CFRunLoopRunInMode (kCFRunLoopDefaultMode, 0, false);
parentStreamHasBytes    = CFReadStreamHasBytesAvailable(readStreamForUpload);
rStreamStatus    = CFReadStreamGetStatus(readStreamForUpload);
}
}while (parentStreamHasBytes != TRUE);

 _______________________________________________
Do not post admin requests to the list. They will be ignored.
Macnetworkprog mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:

This email sent to email@hidden

  • Follow-Ups:
    • Re: File Uploading to HTTP server using CFHTTPMessage API fails
      • From: Jens Alfke <email@hidden>
  • Prev by Date: Why would CFFileDescriptorCreate return NULL?
  • Next by Date: Re: File Uploading to HTTP server using CFHTTPMessage API fails
  • Previous by thread: Why would CFFileDescriptorCreate return NULL?
  • Next by thread: Re: File Uploading to HTTP server using CFHTTPMessage API fails
  • Index(es):
    • Date
    • Thread