Application Outline
I'm trying to build an application that backs up a folder and uploads it to a server, on online backup storage.
The Problem (or at least I think it is...)
I have the HTTP request within a NSData object, and I'm writing it to an NSOutputStream but when its finished writing and the NSInputStream comes into play I get the wrong response from the server. I thought it must be my request data within the NSData object but then I write that to file. I then compared it to a 1,000,000% (must state that this request is DEFINITELY working) working request that I had written to file using a PERL script, compared the two requests and they were IDENTICAL in every way. I even tried the request I outputted from COCOA into the PERL script and it worked perfectly, so I know the problem lies with the coding of my NSOutputStream.
I logged all the data being sent at each buffer when writing to the NSOutputStream and it does go through right till the end of data till there's no more bytes left, so its got to be sending all of it. It just seems to be the response from the server.
Solution???
I dont want to use the NSURL option because it doesn't really allow a delegate to track the progress of the upload, it basically says connection open, recieved and closed. I need help, considering this is main function of my application I can't go any further with my design or coding of my project till this is resolved.
Code
Thanks for any help in advance
I'm trying to build an application that backs up a folder and uploads it to a server, on online backup storage.
The Problem (or at least I think it is...)
I have the HTTP request within a NSData object, and I'm writing it to an NSOutputStream but when its finished writing and the NSInputStream comes into play I get the wrong response from the server. I thought it must be my request data within the NSData object but then I write that to file. I then compared it to a 1,000,000% (must state that this request is DEFINITELY working) working request that I had written to file using a PERL script, compared the two requests and they were IDENTICAL in every way. I even tried the request I outputted from COCOA into the PERL script and it worked perfectly, so I know the problem lies with the coding of my NSOutputStream.
I logged all the data being sent at each buffer when writing to the NSOutputStream and it does go through right till the end of data till there's no more bytes left, so its got to be sending all of it. It just seems to be the response from the server.
Solution???
I dont want to use the NSURL option because it doesn't really allow a delegate to track the progress of the upload, it basically says connection open, recieved and closed. I need help, considering this is main function of my application I can't go any further with my design or coding of my project till this is resolved.
Code
Code:
- (void)start {
NSURL * uploadURL;
NSHost * uploadHost;
uploadURL = [NSURL URLWithString:uploadServer];
uploadHost = [NSHost hostWithName:[uploadURL host]];
[NSStream getStreamsToHost:uploadHost
port:80
inputStream:&inputStream
outputStream:&outputStream];
[inputStream retain];
[outputStream retain];
[inputStream setDelegate:self];
[outputStream setDelegate:self];
[inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop]
forMode:NSDefaultRunLoopMode];
[outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop]
forMode:NSDefaultRunLoopMode];
[inputStream open];
[outputStream open];
}
Code:
- (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)eventCode {
//NSLog(@"stream:handleEvent: is invoked...");
if (stream == outputStream) {
//NSLog(@"output stream: active!");
switch (eventCode) {
case NSStreamEventHasSpaceAvailable:
{
// get the range of data to send
// put it into the buffer
// send it
// increase the next range
unsigned int data_length = [uploadData length];
unsigned int length = ((data_length - byteIndex >= 1024) ? 1024 : (data_length-byteIndex));
NSRange dataRange = NSMakeRange(byteIndex, length);
uint8_t buffer[length];
[uploadData getBytes:buffer
range:dataRange];
[uploadedData appendBytes:buffer
length:length];
length = (NSInteger)[(NSOutputStream *)stream write:(const uint8_t *)buffer
maxLength:(NSUInteger)length];
byteIndex += length;
NSLog(@"Sent %i of %i.", byteIndex, data_length);
break;
}
case NSStreamEventErrorOccurred:
{
NSLog(@"output stream: (ERROR) %@", [[stream streamError] localizedDescription]);
[stream close];
[stream release];
stream = nil;
break;
}
case NSStreamEventEndEncountered:
case NSStreamEventOpenCompleted:
default:
break;
}
}
else if ( stream == inputStream ) {
NSLog(@"input stream: active!");
switch (eventCode) {
case NSStreamEventHasBytesAvailable:
{
if( ! responseData ) {
responseData = [[NSMutableData data] retain];
}
uint8_t buf[1024];
unsigned int len = 0;
len = [(NSInputStream *)stream read:buf maxLength:1024];
if (len) {
[responseData appendBytes:(const void *)buf
length:len];
// bytesRead is an instance variable of type NSNumber.
[bytesDownloaded setIntValue:[bytesDownloaded intValue]+len];
} else {
NSLog(@"no buffer!");
}
break;
}
case NSStreamEventEndEncountered:
{
NSLog(@"input stream: finished downloading");
NSString * str = [[NSString alloc] initWithData:responseData
encoding:NSISOLatin1StringEncoding];
NSLog(@"%@", str);
}
default:
break;
}
}
}
Thanks for any help in advance