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 |