Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include <errno.h> // NOLINT | |
| 6 | |
| 5 #include "bin/dartutils.h" | 7 #include "bin/dartutils.h" |
| 6 | 8 |
| 7 #include "include/dart_api.h" | 9 #include "include/dart_api.h" |
| 8 | 10 |
| 9 #include "platform/assert.h" | 11 #include "platform/assert.h" |
| 10 #include "platform/globals.h" | 12 #include "platform/globals.h" |
| 11 | 13 |
| 12 #include "bin/extensions.h" | 14 #include "bin/extensions.h" |
| 13 #include "bin/directory.h" | 15 #include "bin/directory.h" |
| 14 #include "bin/file.h" | 16 #include "bin/file.h" |
| 15 #include "bin/io_buffer.h" | 17 #include "bin/io_buffer.h" |
| 16 #include "bin/utils.h" | 18 #include "bin/utils.h" |
| 19 #include "bin/socket.h" | |
| 17 | 20 |
| 18 namespace dart { | 21 namespace dart { |
| 19 namespace bin { | 22 namespace bin { |
| 20 | 23 |
| 21 const char* DartUtils::original_working_directory = NULL; | 24 const char* DartUtils::original_working_directory = NULL; |
| 22 const char* DartUtils::kDartScheme = "dart:"; | 25 const char* DartUtils::kDartScheme = "dart:"; |
| 23 const char* DartUtils::kDartExtensionScheme = "dart-ext:"; | 26 const char* DartUtils::kDartExtensionScheme = "dart-ext:"; |
| 24 const char* DartUtils::kAsyncLibURL = "dart:async"; | 27 const char* DartUtils::kAsyncLibURL = "dart:async"; |
| 25 const char* DartUtils::kBuiltinLibURL = "dart:builtin"; | 28 const char* DartUtils::kBuiltinLibURL = "dart:builtin"; |
| 26 const char* DartUtils::kCoreLibURL = "dart:core"; | 29 const char* DartUtils::kCoreLibURL = "dart:core"; |
| 27 const char* DartUtils::kIOLibURL = "dart:io"; | 30 const char* DartUtils::kIOLibURL = "dart:io"; |
| 28 const char* DartUtils::kIOLibPatchURL = "dart:io-patch"; | 31 const char* DartUtils::kIOLibPatchURL = "dart:io-patch"; |
| 29 const char* DartUtils::kUriLibURL = "dart:uri"; | 32 const char* DartUtils::kUriLibURL = "dart:uri"; |
| 33 const char* DartUtils::kHttpScheme = "http:"; | |
| 30 | 34 |
| 31 const char* DartUtils::kIdFieldName = "_id"; | 35 const char* DartUtils::kIdFieldName = "_id"; |
| 32 | 36 |
| 33 uint8_t DartUtils::magic_number[] = { 0xf5, 0xf5, 0xdc, 0xdc }; | 37 uint8_t DartUtils::magic_number[] = { 0xf5, 0xf5, 0xdc, 0xdc }; |
| 34 | 38 |
| 35 static bool IsWindowsHost() { | 39 static bool IsWindowsHost() { |
| 36 #if defined(TARGET_OS_WINDOWS) | 40 #if defined(TARGET_OS_WINDOWS) |
| 37 return true; | 41 return true; |
| 38 #else // defined(TARGET_OS_WINDOWS) | 42 #else // defined(TARGET_OS_WINDOWS) |
| 39 return false; | 43 return false; |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 135 | 139 |
| 136 | 140 |
| 137 bool DartUtils::IsDartSchemeURL(const char* url_name) { | 141 bool DartUtils::IsDartSchemeURL(const char* url_name) { |
| 138 static const intptr_t kDartSchemeLen = strlen(kDartScheme); | 142 static const intptr_t kDartSchemeLen = strlen(kDartScheme); |
| 139 // If the URL starts with "dart:" then it is considered as a special | 143 // If the URL starts with "dart:" then it is considered as a special |
| 140 // library URL which is handled differently from other URLs. | 144 // library URL which is handled differently from other URLs. |
| 141 return (strncmp(url_name, kDartScheme, kDartSchemeLen) == 0); | 145 return (strncmp(url_name, kDartScheme, kDartSchemeLen) == 0); |
| 142 } | 146 } |
| 143 | 147 |
| 144 | 148 |
| 149 bool DartUtils::IsHttpSchemeURL(const char* url_name) { | |
| 150 static const intptr_t kHttpSchemeLen = strlen(kHttpScheme); | |
| 151 return (strncmp(url_name, kHttpScheme, kHttpSchemeLen) == 0); | |
| 152 } | |
| 153 | |
| 154 | |
| 145 bool DartUtils::IsDartExtensionSchemeURL(const char* url_name) { | 155 bool DartUtils::IsDartExtensionSchemeURL(const char* url_name) { |
| 146 static const intptr_t kDartExtensionSchemeLen = strlen(kDartExtensionScheme); | 156 static const intptr_t kDartExtensionSchemeLen = strlen(kDartExtensionScheme); |
| 147 // If the URL starts with "dartext:" then it is considered as a special | 157 // If the URL starts with "dartext:" then it is considered as a special |
| 148 // extension library URL which is handled differently from other URLs. | 158 // extension library URL which is handled differently from other URLs. |
| 149 return | 159 return |
| 150 (strncmp(url_name, kDartExtensionScheme, kDartExtensionSchemeLen) == 0); | 160 (strncmp(url_name, kDartExtensionScheme, kDartExtensionSchemeLen) == 0); |
| 151 } | 161 } |
| 152 | 162 |
| 153 | 163 |
| 154 bool DartUtils::IsDartIOLibURL(const char* url_name) { | 164 bool DartUtils::IsDartIOLibURL(const char* url_name) { |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 226 File* file_stream = reinterpret_cast<File*>(stream); | 236 File* file_stream = reinterpret_cast<File*>(stream); |
| 227 bool bytes_written = file_stream->WriteFully(buffer, num_bytes); | 237 bool bytes_written = file_stream->WriteFully(buffer, num_bytes); |
| 228 ASSERT(bytes_written); | 238 ASSERT(bytes_written); |
| 229 } | 239 } |
| 230 | 240 |
| 231 | 241 |
| 232 void DartUtils::CloseFile(void* stream) { | 242 void DartUtils::CloseFile(void* stream) { |
| 233 delete reinterpret_cast<File*>(stream); | 243 delete reinterpret_cast<File*>(stream); |
| 234 } | 244 } |
| 235 | 245 |
| 246 // Writes string into socket. Spins until socket connects. | |
| 247 static intptr_t SocketWriteString(intptr_t socket, const char* str, | |
| 248 intptr_t len) { | |
| 249 int r; | |
| 250 intptr_t cursor = 0; | |
| 251 do { | |
| 252 r = Socket::Write(socket, &str[cursor], len); | |
| 253 if (r < 0) { | |
| 254 if (errno == ENOTCONN) { | |
|
Ivan Posva
2013/05/24 17:53:43
Spinning is in general not a good idea. Also there
Cutch
2013/05/24 17:59:56
Socket::CreateConnect sets the socket to be non-bl
siva
2013/05/24 23:23:18
I agree the notion of spinning seems contrived.
M
Cutch
2013/05/25 01:37:42
Done.
| |
| 255 // CreateConnect sets the socket to be non-blocking, we may get here | |
| 256 // before the connection has occurred. Spin here. | |
| 257 continue; | |
| 258 } | |
| 259 return cursor; | |
| 260 } | |
| 261 cursor += r; | |
| 262 len -= r; | |
| 263 } while (len > 0); | |
| 264 return cursor; | |
| 265 } | |
| 266 | |
| 267 static uint8_t* SocketReadUntilEOF(intptr_t socket, intptr_t* response_len) { | |
| 268 intptr_t buffer_size = 16 * 1024; | |
|
siva
2013/05/24 23:23:18
const intptr_t kbufferSize = 16 * KB;
to be unifo
Cutch
2013/05/25 01:37:42
Done.
| |
| 269 uint8_t* buffer = reinterpret_cast<uint8_t*>(malloc(buffer_size)); | |
| 270 intptr_t buffer_cursor = 0; | |
| 271 do { | |
| 272 if (buffer_cursor == buffer_size-1) { | |
| 273 // Double buffer size. | |
| 274 buffer_size *= 2; | |
| 275 buffer = reinterpret_cast<uint8_t*>(realloc(buffer, buffer_size)); | |
| 276 } | |
|
siva
2013/05/24 23:23:18
This check for buffer overflow could be at the bot
Cutch
2013/05/25 01:37:42
Done.
| |
| 277 ssize_t bytes_read = read(socket, &buffer[buffer_cursor], | |
| 278 buffer_size-buffer_cursor-1); | |
|
siva
2013/05/24 23:23:18
We normally have a space between operators in our
Cutch
2013/05/25 01:37:42
Done.
| |
| 279 if (bytes_read < 0) { | |
| 280 if (errno == EWOULDBLOCK) { | |
| 281 continue; | |
| 282 } | |
| 283 free(buffer); | |
| 284 return NULL; | |
| 285 } | |
| 286 | |
| 287 buffer_cursor += bytes_read; | |
|
siva
2013/05/24 23:23:18
The increment could be after the if (bytes_read ==
Cutch
2013/05/25 01:37:42
It can't be because I need to add the zero charact
| |
| 288 | |
| 289 if (bytes_read == 0) { | |
| 290 *response_len = buffer_cursor; | |
| 291 buffer[buffer_cursor] = '\0'; | |
| 292 break; | |
| 293 } | |
| 294 } while (true); | |
| 295 return buffer; | |
| 296 } | |
| 297 | |
| 298 static bool HttpGetRequestOkay(const char* response) { | |
| 299 static const char* kOkayReply = "HTTP/1.0 200 OK"; | |
|
siva
2013/05/24 23:23:18
Are we going with HTTP 1.0 and not 1.1
There seem
Cutch
2013/05/25 01:37:42
Yes, we don't need anything from 1.1.
| |
| 300 static const intptr_t kOkayReplyLen = strlen(kOkayReply); | |
| 301 return (strncmp(response, kOkayReply, kOkayReplyLen) == 0); | |
| 302 } | |
| 303 | |
| 304 static const uint8_t* HttpRequestGetPayload(const char* response) { | |
| 305 const char* split = strstr(response, "\r\n\r\n"); | |
| 306 if (split != NULL) { | |
| 307 return reinterpret_cast<const uint8_t*>(split+4); | |
| 308 } | |
| 309 return NULL; | |
| 310 } | |
| 311 | |
| 312 // TODO(iposva): Allocate from the zone instead of leaking error string | |
| 313 // here. On the other hand the binary is about the exit anyway. | |
|
siva
2013/05/24 23:23:18
Is this comment valid for this use case? The binar
Cutch
2013/05/25 01:37:42
I believe what Ivan was saying is that the binary
| |
| 314 #define SET_ERROR_MSG(error_msg, format, ...) \ | |
| 315 intptr_t len = snprintf(NULL, 0, format, __VA_ARGS__); \ | |
| 316 char *msg = reinterpret_cast<char*>(malloc(len + 1)); \ | |
| 317 snprintf(msg, len + 1, format, __VA_ARGS__); \ | |
| 318 *error_msg = msg | |
| 319 | |
| 320 static const uint8_t* HttpGetRequest(const char* domain, const char* path, | |
| 321 int port, intptr_t* response_len, | |
| 322 const char** error_msg) { | |
| 323 OSError* error = NULL; | |
| 324 SocketAddresses* addresses = Socket::LookupAddress(domain, | |
| 325 -1, | |
| 326 &error); | |
| 327 if (addresses == NULL || addresses->count() == 0) { | |
| 328 SET_ERROR_MSG(error_msg, "Unable to resolve %s", domain); | |
| 329 return NULL; | |
| 330 } | |
| 331 int preferred_address = 0; | |
| 332 for (int i = 0; i < addresses->count(); i++) { | |
| 333 SocketAddress* address = addresses->GetAt(i); | |
| 334 if (address->GetType() == SocketAddress::ADDRESS_LOOPBACK_IP_V4) { | |
| 335 preferred_address = i; | |
| 336 break; | |
| 337 } | |
| 338 } | |
| 339 intptr_t tcp_client = Socket::CreateConnect( | |
| 340 addresses->GetAt(preferred_address)->addr(), | |
| 341 port); | |
| 342 if (tcp_client < 0) { | |
| 343 SET_ERROR_MSG(error_msg, "Unable to connect to %s:%d", domain, port); | |
| 344 return NULL; | |
| 345 } | |
| 346 // Send get request. | |
| 347 { | |
| 348 const char* format = | |
| 349 "GET %s HTTP/1.0\r\nUser-Agent: Dart VM\r\nHost: %s\r\n\r\n"; | |
| 350 intptr_t len = snprintf(NULL, 0, format, path, domain); | |
| 351 char* get_request = reinterpret_cast<char*>(malloc(len + 1)); | |
| 352 snprintf(get_request, len + 1, format, path, domain); | |
| 353 intptr_t r = SocketWriteString(tcp_client, get_request, len); | |
| 354 free(get_request); | |
| 355 if (r != len) { | |
| 356 SET_ERROR_MSG(error_msg, "Unable to write to %s:%d", domain, port); | |
| 357 Socket::Close(tcp_client); | |
| 358 return NULL; | |
| 359 } | |
| 360 } | |
| 361 // Consume response. | |
| 362 Socket::SetNonBlocking(tcp_client); | |
| 363 uint8_t* response = SocketReadUntilEOF(tcp_client, response_len); | |
| 364 // Close socket. | |
| 365 Socket::Close(tcp_client); | |
| 366 if (response == NULL) { | |
| 367 SET_ERROR_MSG(error_msg, "Unable to read from %s:%d", domain, port); | |
| 368 return NULL; | |
| 369 } | |
| 370 if (HttpGetRequestOkay(reinterpret_cast<const char*>(response)) == false) { | |
| 371 SET_ERROR_MSG(error_msg, "Invalid HTTP response from %s:%d", domain, port); | |
| 372 free(response); | |
| 373 return NULL; | |
| 374 } | |
| 375 return response; | |
| 376 } | |
| 377 | |
| 378 | |
| 379 Dart_Handle DartUtils::ReadStringFromHttp(const char* script_uri) { | |
| 380 Dart_Handle result; | |
| 381 Dart_Handle uri = NewString(script_uri); | |
| 382 Dart_Handle builtin_lib = | |
| 383 Builtin::LoadAndCheckLibrary(Builtin::kBuiltinLibrary); | |
| 384 Dart_Handle path = PathFromUri(uri, builtin_lib); | |
| 385 Dart_Handle domain = DomainFromUri(uri, builtin_lib); | |
| 386 Dart_Handle port = PortFromUri(uri, builtin_lib); | |
|
siva
2013/05/24 23:23:18
path, domain and port could be Error objects becau
Cutch
2013/05/25 01:37:42
Good catch. Done.
| |
| 387 const char* path_str = NULL; | |
| 388 const char* domain_str = NULL; | |
| 389 int64_t port_int = 0; | |
| 390 result = Dart_StringToCString(path, &path_str); | |
| 391 if (Dart_IsError(result)) { | |
| 392 return result; | |
| 393 } | |
| 394 result = Dart_StringToCString(domain, &domain_str); | |
| 395 if (Dart_IsError(result)) { | |
| 396 return result; | |
| 397 } | |
| 398 if (GetInt64Value(port, &port_int) == false) { | |
| 399 return Dart_Error("Invalid port"); | |
| 400 } | |
| 401 const char* error_msg = NULL; | |
| 402 intptr_t len; | |
| 403 const uint8_t* text_buffer = HttpGetRequest(domain_str, path_str, port_int, | |
| 404 &len, &error_msg); | |
| 405 if (text_buffer == NULL) { | |
| 406 return Dart_Error(error_msg); | |
| 407 } | |
| 408 const uint8_t* payload = HttpRequestGetPayload( | |
| 409 reinterpret_cast<const char*>(text_buffer)); | |
| 410 if (payload == NULL) { | |
| 411 return Dart_Error("Invalid HTTP response."); | |
| 412 } | |
| 413 // Subtract HTTP response from length. | |
| 414 len -= (payload-text_buffer); | |
| 415 ASSERT(len >= 0); | |
| 416 Dart_Handle str = Dart_NewStringFromUTF8(payload, len); | |
| 417 return str; | |
| 418 } | |
| 419 | |
| 236 | 420 |
| 237 static const uint8_t* ReadFileFully(const char* filename, | 421 static const uint8_t* ReadFileFully(const char* filename, |
| 238 intptr_t* file_len, | 422 intptr_t* file_len, |
| 239 const char** error_msg) { | 423 const char** error_msg) { |
| 240 void* stream = DartUtils::OpenFile(filename, false); | 424 void* stream = DartUtils::OpenFile(filename, false); |
| 241 if (stream == NULL) { | 425 if (stream == NULL) { |
| 242 const char* format = "Unable to open file: %s"; | 426 SET_ERROR_MSG(error_msg, "Unable to open file: %s", filename); |
| 243 intptr_t len = snprintf(NULL, 0, format, filename); | |
| 244 // TODO(iposva): Allocate from the zone instead of leaking error string | |
| 245 // here. On the other hand the binary is about the exit anyway. | |
| 246 char* msg = reinterpret_cast<char*>(malloc(len + 1)); | |
| 247 snprintf(msg, len + 1, format, filename); | |
| 248 *error_msg = msg; | |
| 249 return NULL; | 427 return NULL; |
| 250 } | 428 } |
| 251 *file_len = -1; | 429 *file_len = -1; |
| 252 const uint8_t* text_buffer = NULL; | 430 const uint8_t* text_buffer = NULL; |
| 253 DartUtils::ReadFile(&text_buffer, file_len, stream); | 431 DartUtils::ReadFile(&text_buffer, file_len, stream); |
| 254 if (text_buffer == NULL || *file_len == -1) { | 432 if (text_buffer == NULL || *file_len == -1) { |
| 255 *error_msg = "Unable to read file contents"; | 433 *error_msg = "Unable to read file contents"; |
| 256 text_buffer = NULL; | 434 text_buffer = NULL; |
| 257 } | 435 } |
| 258 DartUtils::CloseFile(stream); | 436 DartUtils::CloseFile(stream); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 292 Dart_Handle dart_args[kNumArgs]; | 470 Dart_Handle dart_args[kNumArgs]; |
| 293 dart_args[0] = script_uri; | 471 dart_args[0] = script_uri; |
| 294 dart_args[1] = (IsWindowsHost() ? Dart_True() : Dart_False()); | 472 dart_args[1] = (IsWindowsHost() ? Dart_True() : Dart_False()); |
| 295 return Dart_Invoke(builtin_lib, | 473 return Dart_Invoke(builtin_lib, |
| 296 NewString("_filePathFromUri"), | 474 NewString("_filePathFromUri"), |
| 297 kNumArgs, | 475 kNumArgs, |
| 298 dart_args); | 476 dart_args); |
| 299 } | 477 } |
| 300 | 478 |
| 301 | 479 |
| 480 Dart_Handle DartUtils::PathFromUri(Dart_Handle script_uri, | |
| 481 Dart_Handle builtin_lib) { | |
| 482 const int kNumArgs = 1; | |
| 483 Dart_Handle dart_args[kNumArgs]; | |
| 484 dart_args[0] = script_uri; | |
| 485 return Dart_Invoke(builtin_lib, | |
| 486 NewString("_pathFromHttpUri"), | |
| 487 kNumArgs, | |
| 488 dart_args); | |
| 489 } | |
| 490 | |
| 491 | |
| 492 Dart_Handle DartUtils::DomainFromUri(Dart_Handle script_uri, | |
| 493 Dart_Handle builtin_lib) { | |
| 494 const int kNumArgs = 1; | |
| 495 Dart_Handle dart_args[kNumArgs]; | |
| 496 dart_args[0] = script_uri; | |
| 497 return Dart_Invoke(builtin_lib, | |
| 498 NewString("_domainFromHttpUri"), | |
| 499 kNumArgs, | |
| 500 dart_args); | |
| 501 } | |
| 502 | |
| 503 | |
| 504 Dart_Handle DartUtils::PortFromUri(Dart_Handle script_uri, | |
| 505 Dart_Handle builtin_lib) { | |
| 506 const int kNumArgs = 1; | |
| 507 Dart_Handle dart_args[kNumArgs]; | |
| 508 dart_args[0] = script_uri; | |
| 509 return Dart_Invoke(builtin_lib, | |
| 510 NewString("_portFromHttpUri"), | |
| 511 kNumArgs, | |
| 512 dart_args); | |
| 513 } | |
|
siva
2013/05/24 23:23:18
Seems like these three functions could have been f
Cutch
2013/05/25 01:37:42
Done.
| |
| 514 | |
| 515 | |
| 302 Dart_Handle DartUtils::ResolveUri(Dart_Handle library_url, | 516 Dart_Handle DartUtils::ResolveUri(Dart_Handle library_url, |
| 303 Dart_Handle url, | 517 Dart_Handle url, |
| 304 Dart_Handle builtin_lib) { | 518 Dart_Handle builtin_lib) { |
| 305 const int kNumArgs = 2; | 519 const int kNumArgs = 2; |
| 306 Dart_Handle dart_args[kNumArgs]; | 520 Dart_Handle dart_args[kNumArgs]; |
| 307 dart_args[0] = library_url; | 521 dart_args[0] = library_url; |
| 308 dart_args[1] = url; | 522 dart_args[1] = url; |
| 309 return Dart_Invoke( | 523 return Dart_Invoke( |
| 310 builtin_lib, NewString("_resolveUri"), kNumArgs, dart_args); | 524 builtin_lib, NewString("_resolveUri"), kNumArgs, dart_args); |
| 311 } | 525 } |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 419 } | 633 } |
| 420 | 634 |
| 421 | 635 |
| 422 void DartUtils::WriteMagicNumber(File* file) { | 636 void DartUtils::WriteMagicNumber(File* file) { |
| 423 // Write a magic number and version information into the snapshot file. | 637 // Write a magic number and version information into the snapshot file. |
| 424 bool bytes_written = file->WriteFully(magic_number, sizeof(magic_number)); | 638 bool bytes_written = file->WriteFully(magic_number, sizeof(magic_number)); |
| 425 ASSERT(bytes_written); | 639 ASSERT(bytes_written); |
| 426 } | 640 } |
| 427 | 641 |
| 428 | 642 |
| 643 Dart_Handle DartUtils::LoadScriptHttp(const char* script_uri, | |
| 644 Dart_Handle builtin_lib) { | |
| 645 Dart_Handle uri = NewString(script_uri); | |
| 646 Dart_Handle path = PathFromUri(uri, builtin_lib); | |
| 647 Dart_Handle domain = DomainFromUri(uri, builtin_lib); | |
| 648 Dart_Handle port = PortFromUri(uri, builtin_lib); | |
| 649 const char* path_str = NULL; | |
| 650 const char* domain_str = NULL; | |
| 651 int64_t port_int = 0; | |
| 652 Dart_Handle result; | |
| 653 result = Dart_StringToCString(path, &path_str); | |
| 654 if (Dart_IsError(result)) { | |
| 655 return result; | |
| 656 } | |
| 657 result = Dart_StringToCString(domain, &domain_str); | |
| 658 if (Dart_IsError(result)) { | |
| 659 return result; | |
| 660 } | |
| 661 if (GetInt64Value(port, &port_int) == false) { | |
| 662 return Dart_Error("Invalid port"); | |
| 663 } | |
| 664 const char* error_msg = NULL; | |
| 665 intptr_t len; | |
| 666 const uint8_t* text_buffer; | |
| 667 text_buffer = HttpGetRequest(domain_str, path_str, port_int, &len, | |
| 668 &error_msg); | |
| 669 if (text_buffer == NULL) { | |
| 670 return Dart_Error(error_msg); | |
| 671 } | |
| 672 const uint8_t* payload = HttpRequestGetPayload( | |
| 673 reinterpret_cast<const char*>(text_buffer)); | |
| 674 if (payload == NULL) { | |
| 675 return Dart_Error("Invalid HTTP response."); | |
| 676 } | |
| 677 // Subtract HTTP response from length. | |
| 678 len -= (payload-text_buffer); | |
| 679 ASSERT(len >= 0); | |
| 680 // At this point we have received a valid HTTP 200 reply and | |
| 681 // payload points at the beginning of the script or snapshot. | |
| 682 bool is_snapshot = false; | |
| 683 payload = SniffForMagicNumber(payload, &len, &is_snapshot); | |
| 684 if (is_snapshot) { | |
| 685 return Dart_LoadScriptFromSnapshot(payload, len); | |
| 686 } else { | |
| 687 Dart_Handle source = Dart_NewStringFromUTF8(payload, len); | |
| 688 if (Dart_IsError(source)) { | |
| 689 return source; | |
| 690 } | |
| 691 return Dart_LoadScript(uri, source, 0, 0); | |
| 692 } | |
| 693 } | |
| 694 | |
| 695 | |
| 429 Dart_Handle DartUtils::LoadScript(const char* script_uri, | 696 Dart_Handle DartUtils::LoadScript(const char* script_uri, |
| 430 Dart_Handle builtin_lib) { | 697 Dart_Handle builtin_lib) { |
| 698 if (DartUtils::IsHttpSchemeURL(script_uri)) { | |
| 699 return LoadScriptHttp(script_uri, builtin_lib); | |
| 700 } | |
| 431 Dart_Handle resolved_script_uri; | 701 Dart_Handle resolved_script_uri; |
| 432 resolved_script_uri = ResolveScriptUri(NewString(script_uri), builtin_lib); | 702 resolved_script_uri = ResolveScriptUri(NewString(script_uri), builtin_lib); |
| 433 if (Dart_IsError(resolved_script_uri)) { | 703 if (Dart_IsError(resolved_script_uri)) { |
| 434 return resolved_script_uri; | 704 return resolved_script_uri; |
| 435 } | 705 } |
| 436 Dart_Handle script_path = DartUtils::FilePathFromUri(resolved_script_uri, | 706 Dart_Handle script_path = DartUtils::FilePathFromUri(resolved_script_uri, |
| 437 builtin_lib); | 707 builtin_lib); |
| 438 if (Dart_IsError(script_path)) { | 708 if (Dart_IsError(script_path)) { |
| 439 return script_path; | 709 return script_path; |
| 440 } | 710 } |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 460 return Dart_LoadScript(resolved_script_uri, source, 0, 0); | 730 return Dart_LoadScript(resolved_script_uri, source, 0, 0); |
| 461 } | 731 } |
| 462 } | 732 } |
| 463 | 733 |
| 464 | 734 |
| 465 Dart_Handle DartUtils::LoadSource(CommandLineOptions* url_mapping, | 735 Dart_Handle DartUtils::LoadSource(CommandLineOptions* url_mapping, |
| 466 Dart_Handle library, | 736 Dart_Handle library, |
| 467 Dart_Handle url, | 737 Dart_Handle url, |
| 468 Dart_LibraryTag tag, | 738 Dart_LibraryTag tag, |
| 469 const char* url_string) { | 739 const char* url_string) { |
| 740 bool is_http_scheme_url = DartUtils::IsHttpSchemeURL(url_string); | |
| 470 if (url_mapping != NULL && IsDartSchemeURL(url_string)) { | 741 if (url_mapping != NULL && IsDartSchemeURL(url_string)) { |
| 471 const char* mapped_url_string = MapLibraryUrl(url_mapping, url_string); | 742 const char* mapped_url_string = MapLibraryUrl(url_mapping, url_string); |
| 472 if (mapped_url_string == NULL) { | 743 if (mapped_url_string == NULL) { |
| 473 return Dart_Error("Do not know how to load %s", url_string); | 744 return Dart_Error("Do not know how to load %s", url_string); |
| 474 } | 745 } |
| 475 // We have a URL mapping specified, just read the file that the | 746 // We have a URL mapping specified, just read the file that the |
| 476 // URL mapping specifies and load it. | 747 // URL mapping specifies and load it. |
| 477 url_string = mapped_url_string; | 748 url_string = mapped_url_string; |
| 478 } | 749 } |
| 479 // The tag is either an import or a source tag. | 750 Dart_Handle source; |
| 480 // Read the file and load it according to the specified tag. | 751 if (is_http_scheme_url) { |
| 481 Dart_Handle source = DartUtils::ReadStringFromFile(url_string); | 752 // Read the file over http. |
| 753 source = DartUtils::ReadStringFromHttp(url_string); | |
| 754 } else { | |
| 755 // Read the file. | |
| 756 source = DartUtils::ReadStringFromFile(url_string); | |
| 757 } | |
| 482 if (Dart_IsError(source)) { | 758 if (Dart_IsError(source)) { |
| 483 return source; // source contains the error string. | 759 return source; // source contains the error string. |
| 484 } | 760 } |
| 761 // The tag is either an import or a source tag. | |
| 762 // Load it according to the specified tag. | |
| 485 if (tag == kImportTag) { | 763 if (tag == kImportTag) { |
| 486 // Return library object or an error string. | 764 // Return library object or an error string. |
| 487 return Dart_LoadLibrary(url, source); | 765 return Dart_LoadLibrary(url, source); |
| 488 } else if (tag == kSourceTag) { | 766 } else if (tag == kSourceTag) { |
| 489 return Dart_LoadSource(library, url, source); | 767 return Dart_LoadSource(library, url, source); |
| 490 } | 768 } |
| 491 return Dart_Error("wrong tag"); | 769 return Dart_Error("wrong tag"); |
| 492 } | 770 } |
| 493 | 771 |
| 494 | 772 |
| (...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 807 new CObjectString(CObject::NewString(os_error->message())); | 1085 new CObjectString(CObject::NewString(os_error->message())); |
| 808 CObjectArray* result = new CObjectArray(CObject::NewArray(3)); | 1086 CObjectArray* result = new CObjectArray(CObject::NewArray(3)); |
| 809 result->SetAt(0, new CObjectInt32(CObject::NewInt32(kOSError))); | 1087 result->SetAt(0, new CObjectInt32(CObject::NewInt32(kOSError))); |
| 810 result->SetAt(1, new CObjectInt32(CObject::NewInt32(os_error->code()))); | 1088 result->SetAt(1, new CObjectInt32(CObject::NewInt32(os_error->code()))); |
| 811 result->SetAt(2, error_message); | 1089 result->SetAt(2, error_message); |
| 812 return result; | 1090 return result; |
| 813 } | 1091 } |
| 814 | 1092 |
| 815 } // namespace bin | 1093 } // namespace bin |
| 816 } // namespace dart | 1094 } // namespace dart |
| OLD | NEW |