| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2005, 2006, 2008 Apple Inc. All rights reserved. | 2 * Copyright (C) 2005, 2006, 2008 Apple Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * | 7 * |
| 8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
| 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 */ | 27 */ |
| 28 | 28 |
| 29 /* originally written by Becky Willrich, additional code by Darin Adler */ | 29 /* originally written by Becky Willrich, additional code by Darin Adler */ |
| 30 | 30 |
| 31 #import "config.h" | 31 #import "config.h" |
| 32 #import "FormDataStreamMac.h" | 32 #import "FormDataStreamMac.h" |
| 33 | 33 |
| 34 #import "Blob.h" | |
| 35 #import "FileSystem.h" | 34 #import "FileSystem.h" |
| 36 #import "FormData.h" | 35 #import "FormData.h" |
| 37 #import "ResourceHandle.h" | 36 #import "ResourceHandle.h" |
| 38 #import "ResourceHandleClient.h" | 37 #import "ResourceHandleClient.h" |
| 39 #import "SchedulePair.h" | 38 #import "SchedulePair.h" |
| 40 #import "WebCoreSystemInterface.h" | 39 #import "WebCoreSystemInterface.h" |
| 41 #import <sys/stat.h> | 40 #import <sys/stat.h> |
| 42 #import <sys/types.h> | 41 #import <sys/types.h> |
| 43 #import <wtf/Assertions.h> | 42 #import <wtf/Assertions.h> |
| 44 #import <wtf/HashMap.h> | 43 #import <wtf/HashMap.h> |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 135 }; | 134 }; |
| 136 | 135 |
| 137 static void closeCurrentStream(FormStreamFields *form) | 136 static void closeCurrentStream(FormStreamFields *form) |
| 138 { | 137 { |
| 139 if (form->currentStream) { | 138 if (form->currentStream) { |
| 140 CFReadStreamClose(form->currentStream); | 139 CFReadStreamClose(form->currentStream); |
| 141 CFReadStreamSetClient(form->currentStream, kCFStreamEventNone, NULL, NUL
L); | 140 CFReadStreamSetClient(form->currentStream, kCFStreamEventNone, NULL, NUL
L); |
| 142 CFRelease(form->currentStream); | 141 CFRelease(form->currentStream); |
| 143 form->currentStream = NULL; | 142 form->currentStream = NULL; |
| 144 #if ENABLE(BLOB_SLICE) | 143 #if ENABLE(BLOB_SLICE) |
| 145 form->currentStreamRangeLength = Blob::toEndOfFile; | 144 form->currentStreamRangeLength = FormDataElement::toEndOfFile; |
| 146 #endif | 145 #endif |
| 147 } | 146 } |
| 148 if (form->currentData) { | 147 if (form->currentData) { |
| 149 fastFree(form->currentData); | 148 fastFree(form->currentData); |
| 150 form->currentData = 0; | 149 form->currentData = 0; |
| 151 } | 150 } |
| 152 } | 151 } |
| 153 | 152 |
| 154 // Return false if we cannot advance the stream. Currently the only possible fai
lure is that the underlying file has been changed since File.slice. | 153 // Return false if we cannot advance the stream. Currently the only possible fai
lure is that the underlying file has been removed or changed since File.slice. |
| 155 static bool advanceCurrentStream(FormStreamFields* form) | 154 static bool advanceCurrentStream(FormStreamFields* form) |
| 156 { | 155 { |
| 157 closeCurrentStream(form); | 156 closeCurrentStream(form); |
| 158 | 157 |
| 159 if (form->remainingElements.isEmpty()) | 158 if (form->remainingElements.isEmpty()) |
| 160 return true; | 159 return true; |
| 161 | 160 |
| 162 // Create the new stream. | 161 // Create the new stream. |
| 163 FormDataElement& nextInput = form->remainingElements.last(); | 162 FormDataElement& nextInput = form->remainingElements.last(); |
| 163 |
| 164 if (nextInput.m_type == FormDataElement::data) { | 164 if (nextInput.m_type == FormDataElement::data) { |
| 165 size_t size = nextInput.m_data.size(); | 165 size_t size = nextInput.m_data.size(); |
| 166 char* data = nextInput.m_data.releaseBuffer(); | 166 char* data = nextInput.m_data.releaseBuffer(); |
| 167 form->currentStream = CFReadStreamCreateWithBytesNoCopy(0, reinterpret_c
ast<const UInt8*>(data), size, kCFAllocatorNull); | 167 form->currentStream = CFReadStreamCreateWithBytesNoCopy(0, reinterpret_c
ast<const UInt8*>(data), size, kCFAllocatorNull); |
| 168 form->currentData = data; | 168 form->currentData = data; |
| 169 } else { | 169 } else { |
| 170 #if ENABLE(BLOB_SLICE) | 170 #if ENABLE(BLOB_SLICE) |
| 171 // Check if the file has been changed or not if required. | 171 // Check if the file has been changed or not if required. |
| 172 if (nextInput.m_expectedFileModificationTime != Blob::doNotCheckFileChan
ge) { | 172 if (nextInput.m_expectedFileModificationTime != FormDataElement::doNotCh
eckFileChange) { |
| 173 time_t fileModificationTime; | 173 time_t fileModificationTime; |
| 174 if (!getFileModificationTime(nextInput.m_filename, fileModificationT
ime) || fileModificationTime != static_cast<time_t>(nextInput.m_expectedFileModi
ficationTime)) | 174 if (!getFileModificationTime(nextInput.m_filename, fileModificationT
ime) || fileModificationTime != static_cast<time_t>(nextInput.m_expectedFileModi
ficationTime)) |
| 175 return false; | 175 return false; |
| 176 } | 176 } |
| 177 #endif | 177 #endif |
| 178 | |
| 179 const String& path = nextInput.m_shouldGenerateFile ? nextInput.m_genera
tedFilename : nextInput.m_filename; | 178 const String& path = nextInput.m_shouldGenerateFile ? nextInput.m_genera
tedFilename : nextInput.m_filename; |
| 180 RetainPtr<CFStringRef> filename(AdoptCF, path.createCFString()); | 179 RetainPtr<CFStringRef> filename(AdoptCF, path.createCFString()); |
| 181 RetainPtr<CFURLRef> fileURL(AdoptCF, CFURLCreateWithFileSystemPath(0, fi
lename.get(), kCFURLPOSIXPathStyle, FALSE)); | 180 RetainPtr<CFURLRef> fileURL(AdoptCF, CFURLCreateWithFileSystemPath(0, fi
lename.get(), kCFURLPOSIXPathStyle, FALSE)); |
| 182 form->currentStream = CFReadStreamCreateWithFile(0, fileURL.get()); | 181 form->currentStream = CFReadStreamCreateWithFile(0, fileURL.get()); |
| 182 if (!form->currentStream) { |
| 183 // The file must have been removed or become unreadable. |
| 184 return false; |
| 185 } |
| 183 #if ENABLE(BLOB_SLICE) | 186 #if ENABLE(BLOB_SLICE) |
| 184 if (nextInput.m_fileStart > 0) { | 187 if (nextInput.m_fileStart > 0) { |
| 185 CFNumberRef position = CFNumberCreate(0, kCFNumberLongLongType, &nex
tInput.m_fileStart); | 188 CFNumberRef position = CFNumberCreate(0, kCFNumberLongLongType, &nex
tInput.m_fileStart); |
| 186 CFReadStreamSetProperty(form->currentStream, kCFStreamPropertyFileCu
rrentOffset, position); | 189 CFReadStreamSetProperty(form->currentStream, kCFStreamPropertyFileCu
rrentOffset, position); |
| 187 } | 190 } |
| 188 form->currentStreamRangeLength = nextInput.m_fileLength; | 191 form->currentStreamRangeLength = nextInput.m_fileLength; |
| 189 #endif | 192 #endif |
| 190 } | 193 } |
| 191 form->remainingElements.removeLast(); | 194 form->remainingElements.removeLast(); |
| 192 | 195 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 215 return true; | 218 return true; |
| 216 } | 219 } |
| 217 | 220 |
| 218 static void* formCreate(CFReadStreamRef stream, void* context) | 221 static void* formCreate(CFReadStreamRef stream, void* context) |
| 219 { | 222 { |
| 220 FormContext* formContext = static_cast<FormContext*>(context); | 223 FormContext* formContext = static_cast<FormContext*>(context); |
| 221 | 224 |
| 222 FormStreamFields* newInfo = new FormStreamFields; | 225 FormStreamFields* newInfo = new FormStreamFields; |
| 223 newInfo->currentStream = NULL; | 226 newInfo->currentStream = NULL; |
| 224 #if ENABLE(BLOB_SLICE) | 227 #if ENABLE(BLOB_SLICE) |
| 225 newInfo->currentStreamRangeLength = Blob::toEndOfFile; | 228 newInfo->currentStreamRangeLength = FormDataElement::toEndOfFile; |
| 226 #endif | 229 #endif |
| 227 newInfo->currentData = 0; | 230 newInfo->currentData = 0; |
| 228 newInfo->formStream = stream; // Don't retain. That would create a reference
cycle. | 231 newInfo->formStream = stream; // Don't retain. That would create a reference
cycle. |
| 229 newInfo->streamLength = formContext->streamLength; | 232 newInfo->streamLength = formContext->streamLength; |
| 230 newInfo->bytesSent = 0; | 233 newInfo->bytesSent = 0; |
| 231 | 234 |
| 232 FormData* formData = formContext->formData; | 235 FormData* formData = formContext->formData; |
| 233 | 236 |
| 234 // Append in reverse order since we remove elements from the end. | 237 // Append in reverse order since we remove elements from the end. |
| 235 size_t size = formData->elements().size(); | 238 size_t size = formData->elements().size(); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 263 return opened; | 266 return opened; |
| 264 } | 267 } |
| 265 | 268 |
| 266 static CFIndex formRead(CFReadStreamRef stream, UInt8* buffer, CFIndex bufferLen
gth, CFStreamError* error, Boolean* atEOF, void* context) | 269 static CFIndex formRead(CFReadStreamRef stream, UInt8* buffer, CFIndex bufferLen
gth, CFStreamError* error, Boolean* atEOF, void* context) |
| 267 { | 270 { |
| 268 FormStreamFields* form = static_cast<FormStreamFields*>(context); | 271 FormStreamFields* form = static_cast<FormStreamFields*>(context); |
| 269 | 272 |
| 270 while (form->currentStream) { | 273 while (form->currentStream) { |
| 271 CFIndex bytesToRead = bufferLength; | 274 CFIndex bytesToRead = bufferLength; |
| 272 #if ENABLE(BLOB_SLICE) | 275 #if ENABLE(BLOB_SLICE) |
| 273 if (form->currentStreamRangeLength != Blob::toEndOfFile && form->current
StreamRangeLength < bytesToRead) | 276 if (form->currentStreamRangeLength != FormDataElement::toEndOfFile && fo
rm->currentStreamRangeLength < bytesToRead) |
| 274 bytesToRead = static_cast<CFIndex>(form->currentStreamRangeLength); | 277 bytesToRead = static_cast<CFIndex>(form->currentStreamRangeLength); |
| 275 #endif | 278 #endif |
| 276 CFIndex bytesRead = CFReadStreamRead(form->currentStream, buffer, bytesT
oRead); | 279 CFIndex bytesRead = CFReadStreamRead(form->currentStream, buffer, bytesT
oRead); |
| 277 if (bytesRead < 0) { | 280 if (bytesRead < 0) { |
| 278 *error = CFReadStreamGetError(form->currentStream); | 281 *error = CFReadStreamGetError(form->currentStream); |
| 279 return -1; | 282 return -1; |
| 280 } | 283 } |
| 281 if (bytesRead > 0) { | 284 if (bytesRead > 0) { |
| 282 error->error = 0; | 285 error->error = 0; |
| 283 *atEOF = FALSE; | 286 *atEOF = FALSE; |
| 284 form->bytesSent += bytesRead; | 287 form->bytesSent += bytesRead; |
| 285 #if ENABLE(BLOB_SLICE) | 288 #if ENABLE(BLOB_SLICE) |
| 286 if (form->currentStreamRangeLength != Blob::toEndOfFile) | 289 if (form->currentStreamRangeLength != FormDataElement::toEndOfFile) |
| 287 form->currentStreamRangeLength -= bytesRead; | 290 form->currentStreamRangeLength -= bytesRead; |
| 288 #endif | 291 #endif |
| 289 | 292 |
| 290 if (!ResourceHandle::didSendBodyDataDelegateExists()) { | 293 if (!ResourceHandle::didSendBodyDataDelegateExists()) { |
| 291 // FIXME: Figure out how to only do this when a ResourceHandleCl
ient is available. | 294 // FIXME: Figure out how to only do this when a ResourceHandleCl
ient is available. |
| 292 DidSendDataCallbackData* data = new DidSendDataCallbackData(stre
am, form->bytesSent, form->streamLength); | 295 DidSendDataCallbackData* data = new DidSendDataCallbackData(stre
am, form->bytesSent, form->streamLength); |
| 293 callOnMainThread(performDidSendDataCallback, data); | 296 callOnMainThread(performDidSendDataCallback, data); |
| 294 } | 297 } |
| 295 | 298 |
| 296 return bytesRead; | 299 return bytesRead; |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 393 | 396 |
| 394 // Precompute the content length so NSURLConnection doesn't use chunked mode
. | 397 // Precompute the content length so NSURLConnection doesn't use chunked mode
. |
| 395 long long length = 0; | 398 long long length = 0; |
| 396 for (size_t i = 0; i < count; ++i) { | 399 for (size_t i = 0; i < count; ++i) { |
| 397 const FormDataElement& element = formData->elements()[i]; | 400 const FormDataElement& element = formData->elements()[i]; |
| 398 if (element.m_type == FormDataElement::data) | 401 if (element.m_type == FormDataElement::data) |
| 399 length += element.m_data.size(); | 402 length += element.m_data.size(); |
| 400 else { | 403 else { |
| 401 #if ENABLE(BLOB_SLICE) | 404 #if ENABLE(BLOB_SLICE) |
| 402 // If we're sending the file range, use the existing range length fo
r now. We will detect if the file has been changed right before we read the file
and abort the operation if necessary. | 405 // If we're sending the file range, use the existing range length fo
r now. We will detect if the file has been changed right before we read the file
and abort the operation if necessary. |
| 403 if (element.m_fileLength != Blob::toEndOfFile) { | 406 if (element.m_fileLength != FormDataElement::toEndOfFile) { |
| 404 length += element.m_fileLength; | 407 length += element.m_fileLength; |
| 405 continue; | 408 continue; |
| 406 } | 409 } |
| 407 #endif | 410 #endif |
| 408 long long fileSize; | 411 long long fileSize; |
| 409 if (getFileSize(element.m_shouldGenerateFile ? element.m_generatedFi
lename : element.m_filename, fileSize)) | 412 if (getFileSize(element.m_shouldGenerateFile ? element.m_generatedFi
lename : element.m_filename, fileSize)) |
| 410 length += fileSize; | 413 length += fileSize; |
| 411 } | 414 } |
| 412 } | 415 } |
| 413 | 416 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 424 &formContext)); | 427 &formContext)); |
| 425 [request setHTTPBodyStream:(NSInputStream *)stream.get()]; | 428 [request setHTTPBodyStream:(NSInputStream *)stream.get()]; |
| 426 } | 429 } |
| 427 | 430 |
| 428 FormData* httpBodyFromStream(NSInputStream* stream) | 431 FormData* httpBodyFromStream(NSInputStream* stream) |
| 429 { | 432 { |
| 430 return getStreamFormDataMap().get((CFReadStreamRef)stream).get(); | 433 return getStreamFormDataMap().get((CFReadStreamRef)stream).get(); |
| 431 } | 434 } |
| 432 | 435 |
| 433 } // namespace WebCore | 436 } // namespace WebCore |
| OLD | NEW |