| Index: runtime/bin/dartutils.cc
|
| diff --git a/runtime/bin/dartutils.cc b/runtime/bin/dartutils.cc
|
| index facccd9e595040a3dd5f5611108cd74e59d1cc50..8134848536699ad253dd8beb5d23fc428dab6fcc 100644
|
| --- a/runtime/bin/dartutils.cc
|
| +++ b/runtime/bin/dartutils.cc
|
| @@ -44,15 +44,6 @@ static bool IsWindowsHost() {
|
| }
|
|
|
|
|
| -static Dart_Handle SingleArgDart_Invoke(Dart_Handle arg, Dart_Handle lib,
|
| - const char* method) {
|
| - const int kNumArgs = 1;
|
| - Dart_Handle dart_args[kNumArgs];
|
| - dart_args[0] = arg;
|
| - return Dart_Invoke(lib, DartUtils::NewString(method), kNumArgs, dart_args);
|
| -}
|
| -
|
| -
|
| const char* DartUtils::MapLibraryUrl(CommandLineOptions* url_mapping,
|
| const char* url_string) {
|
| ASSERT(url_mapping != NULL);
|
| @@ -252,74 +243,12 @@ void DartUtils::CloseFile(void* stream) {
|
| }
|
|
|
|
|
| -// Writes string into socket.
|
| -// Return < 0 indicates an error.
|
| -// Return >= 0 number of bytes written.
|
| -static intptr_t SocketWriteString(intptr_t socket, const char* str,
|
| - intptr_t len) {
|
| - int r;
|
| - intptr_t cursor = 0;
|
| - do {
|
| - r = Socket::Write(socket, &str[cursor], len);
|
| - if (r < 0) {
|
| - return r;
|
| - }
|
| - cursor += r;
|
| - len -= r;
|
| - } while (len > 0);
|
| - ASSERT(len == 0);
|
| - return cursor;
|
| -}
|
| -
|
| -
|
| -static uint8_t* SocketReadUntilEOF(intptr_t socket, intptr_t* response_len) {
|
| - const intptr_t kInitialBufferSize = 16 * KB;
|
| - intptr_t buffer_size = kInitialBufferSize;
|
| - uint8_t* buffer = reinterpret_cast<uint8_t*>(malloc(buffer_size));
|
| - ASSERT(buffer != NULL);
|
| - intptr_t buffer_cursor = 0;
|
| - do {
|
| - int bytes_read = Socket::Read(socket, &buffer[buffer_cursor],
|
| - buffer_size - buffer_cursor - 1);
|
| - if (bytes_read < 0) {
|
| - free(buffer);
|
| - return NULL;
|
| - }
|
| -
|
| - buffer_cursor += bytes_read;
|
| -
|
| - if (bytes_read == 0) {
|
| - *response_len = buffer_cursor;
|
| - buffer[buffer_cursor] = '\0';
|
| - break;
|
| - }
|
| -
|
| - // There is still more data to be read, check that we have room in the
|
| - // buffer for more data.
|
| - if (buffer_cursor == buffer_size - 1) {
|
| - // Buffer is full. Increase buffer size.
|
| - buffer_size *= 2;
|
| - buffer = reinterpret_cast<uint8_t*>(realloc(buffer, buffer_size));
|
| - ASSERT(buffer != NULL);
|
| - }
|
| - } while (true);
|
| - return buffer;
|
| -}
|
| -
|
| -
|
| -static bool HttpGetRequestOkay(const char* response) {
|
| - static const char* kOkayReply = "HTTP/1.0 200 OK";
|
| - static const intptr_t kOkayReplyLen = strlen(kOkayReply);
|
| - return (strncmp(response, kOkayReply, kOkayReplyLen) == 0);
|
| -}
|
| -
|
| -
|
| -static const uint8_t* HttpRequestGetPayload(const char* response) {
|
| - const char* split = strstr(response, "\r\n\r\n");
|
| - if (split != NULL) {
|
| - return reinterpret_cast<const uint8_t*>(split+4);
|
| - }
|
| - return NULL;
|
| +static Dart_Handle SingleArgDart_Invoke(Dart_Handle arg, Dart_Handle lib,
|
| + const char* method) {
|
| + const int kNumArgs = 1;
|
| + Dart_Handle dart_args[kNumArgs];
|
| + dart_args[0] = arg;
|
| + return Dart_Invoke(lib, DartUtils::NewString(method), kNumArgs, dart_args);
|
| }
|
|
|
|
|
| @@ -332,135 +261,93 @@ static const uint8_t* HttpRequestGetPayload(const char* response) {
|
| *error_msg = msg
|
|
|
|
|
| -static const uint8_t* HttpGetRequest(const char* host, const char* path,
|
| - int port, intptr_t* response_len,
|
| - const char** error_msg) {
|
| - OSError* error = NULL;
|
| - SocketAddresses* addresses = Socket::LookupAddress(host, -1, &error);
|
| - if (addresses == NULL || addresses->count() == 0) {
|
| - SET_ERROR_MSG(error_msg, "Unable to resolve %s", host);
|
| - return NULL;
|
| - }
|
| -
|
| - int preferred_address = 0;
|
| - for (int i = 0; i < addresses->count(); i++) {
|
| - SocketAddress* address = addresses->GetAt(i);
|
| - if (address->GetType() == SocketAddress::ADDRESS_LOOPBACK_IP_V4) {
|
| - // Prefer the IP_V4 loop back.
|
| - preferred_address = i;
|
| - break;
|
| - }
|
| - }
|
| -
|
| - RawAddr addr = addresses->GetAt(preferred_address)->addr();
|
| - intptr_t tcp_client = Socket::Create(addr);
|
| - if (tcp_client < 0) {
|
| - SET_ERROR_MSG(error_msg, "Unable to create socket to %s:%d", host, port);
|
| - return NULL;
|
| - }
|
| - Socket::Connect(tcp_client, addr, port);
|
| - if (tcp_client < 0) {
|
| - SET_ERROR_MSG(error_msg, "Unable to connect to %s:%d", host, port);
|
| - return NULL;
|
| - }
|
| - // Send get request.
|
| - {
|
| - const char* format =
|
| - "GET %s HTTP/1.0\r\nUser-Agent: Dart VM\r\nHost: %s\r\n\r\n";
|
| - intptr_t len = snprintf(NULL, 0, format, path, host);
|
| - char* get_request = reinterpret_cast<char*>(malloc(len + 1));
|
| - snprintf(get_request, len + 1, format, path, host);
|
| - intptr_t r = SocketWriteString(tcp_client, get_request, len);
|
| - free(get_request);
|
| - if (r < len) {
|
| - SET_ERROR_MSG(error_msg, "Unable to write to %s:%d - %d", host, port,
|
| - static_cast<int>(r));
|
| - Socket::Close(tcp_client);
|
| - return NULL;
|
| - }
|
| - ASSERT(r == len);
|
| - }
|
| - // Consume response.
|
| - uint8_t* response = SocketReadUntilEOF(tcp_client, response_len);
|
| - // Close socket.
|
| - Socket::Close(tcp_client);
|
| - if (response == NULL) {
|
| - SET_ERROR_MSG(error_msg, "Unable to read from %s:%d", host, port);
|
| - return NULL;
|
| - }
|
| - if (HttpGetRequestOkay(reinterpret_cast<const char*>(response)) == false) {
|
| - SET_ERROR_MSG(error_msg, "Invalid HTTP response from %s:%d", host, port);
|
| - free(response);
|
| - return NULL;
|
| - }
|
| - return response;
|
| -}
|
| -
|
| -
|
| -static Dart_Handle ParseHttpUri(Dart_Handle uri, const char** host_str,
|
| - int64_t* port_int, const char** path_str) {
|
| - ASSERT(host_str != NULL);
|
| - ASSERT(port_int != NULL);
|
| - ASSERT(path_str != NULL);
|
| - Dart_Handle result;
|
| - Dart_Handle builtin_lib =
|
| - Builtin::LoadAndCheckLibrary(Builtin::kBuiltinLibrary);
|
| - Dart_Handle path = DartUtils::PathFromUri(uri, builtin_lib);
|
| - if (Dart_IsError(path)) {
|
| - return path;
|
| - }
|
| - Dart_Handle host = DartUtils::HostFromUri(uri, builtin_lib);
|
| - if (Dart_IsError(host)) {
|
| - return host;
|
| - }
|
| - Dart_Handle port = DartUtils::PortFromUri(uri, builtin_lib);
|
| - if (Dart_IsError(port)) {
|
| - return port;
|
| - }
|
| - result = Dart_StringToCString(path, path_str);
|
| - if (Dart_IsError(result)) {
|
| - return result;
|
| - }
|
| - result = Dart_StringToCString(host, host_str);
|
| +Dart_Handle MakeHttpRequest(Dart_Handle uri, Dart_Handle builtin_lib,
|
| + uint8_t** buffer, intptr_t* buffer_len) {
|
| + const intptr_t HttpResponseCodeOK = 200;
|
| + ASSERT(buffer != NULL);
|
| + ASSERT(buffer_len != NULL);
|
| + ASSERT(!Dart_HasLivePorts());
|
| + SingleArgDart_Invoke(uri, builtin_lib, "_makeHttpRequest");
|
| + // Run until all ports to isolate are closed.
|
| + Dart_Handle result = Dart_RunLoop();
|
| if (Dart_IsError(result)) {
|
| return result;
|
| }
|
| - if (DartUtils::GetInt64Value(port, port_int) == false) {
|
| - return Dart_Error("Invalid port");
|
| + intptr_t responseCode =
|
| + DartUtils::GetIntegerField(builtin_lib, "_httpRequestResponseCode");
|
| + if (responseCode != HttpResponseCodeOK) {
|
| + // Return error.
|
| + Dart_Handle responseStatus =
|
| + Dart_GetField(builtin_lib,
|
| + DartUtils::NewString("_httpRequestStatusString"));
|
| + if (Dart_IsError(responseStatus)) {
|
| + return responseStatus;
|
| + }
|
| + if (Dart_IsNull(responseStatus)) {
|
| + return Dart_Error("HTTP error.");
|
| + }
|
| + return Dart_Error(DartUtils::GetStringValue(responseStatus));
|
| + }
|
| + Dart_Handle response =
|
| + Dart_GetField(builtin_lib, DartUtils::NewString("_httpRequestResponse"));
|
| + if (Dart_IsError(response)) {
|
| + return response;
|
| + }
|
| + if (Dart_IsString(response)) {
|
| + // Received response as string.
|
| + uint8_t* responseString = NULL;
|
| + intptr_t responseStringLength;
|
| + Dart_Handle r = Dart_StringToUTF8(response, &responseString,
|
| + &responseStringLength);
|
| + if (Dart_IsError(r)) {
|
| + *buffer = NULL;
|
| + *buffer_len = 0;
|
| + return r;
|
| + }
|
| + // Get payload as bytes.
|
| + *buffer_len = responseStringLength;
|
| + *buffer = reinterpret_cast<uint8_t*>(malloc(responseStringLength));
|
| + memmove(*buffer, responseString, responseStringLength);
|
| + } else {
|
| + // Received response as list of bytes.
|
| + ASSERT(Dart_IsList(response));
|
| + // Query list length.
|
| + result = Dart_ListLength(response, buffer_len);
|
| + if (Dart_IsError(result)) {
|
| + *buffer_len = 0;
|
| + *buffer = NULL;
|
| + return result;
|
| + }
|
| + // Get payload as bytes.
|
| + *buffer = reinterpret_cast<uint8_t*>(malloc(*buffer_len));
|
| + result = Dart_ListGetAsBytes(response, 0, *buffer, *buffer_len);
|
| + if (Dart_IsError(result)) {
|
| + free(*buffer);
|
| + *buffer_len = 0;
|
| + *buffer = NULL;
|
| + return result;
|
| + }
|
| }
|
| return result;
|
| }
|
|
|
|
|
| -Dart_Handle DartUtils::ReadStringFromHttp(const char* filename) {
|
| - Dart_Handle uri = NewString(filename);
|
| +Dart_Handle DartUtils::ReadStringFromHttp(const char* script_uri) {
|
| + Dart_Handle uri = NewString(script_uri);
|
| if (Dart_IsError(uri)) {
|
| return uri;
|
| }
|
| - const char* host_str = NULL;
|
| - int64_t port_int = 0;
|
| - const char* path_str = NULL;
|
| - Dart_Handle result = ParseHttpUri(uri, &host_str, &port_int,
|
| - &path_str);
|
| + Dart_Handle builtin_lib =
|
| + Builtin::LoadAndCheckLibrary(Builtin::kBuiltinLibrary);
|
| + uint8_t* buffer;
|
| + intptr_t bufferLen;
|
| + Dart_Handle result = MakeHttpRequest(uri, builtin_lib, &buffer, &bufferLen);
|
| if (Dart_IsError(result)) {
|
| return result;
|
| }
|
| - const char* error_msg = NULL;
|
| - intptr_t len;
|
| - const uint8_t* text_buffer = HttpGetRequest(host_str, path_str, port_int,
|
| - &len, &error_msg);
|
| - if (text_buffer == NULL) {
|
| - return Dart_Error(error_msg);
|
| - }
|
| - const uint8_t* payload = HttpRequestGetPayload(
|
| - reinterpret_cast<const char*>(text_buffer));
|
| - if (payload == NULL) {
|
| - return Dart_Error("Invalid HTTP response.");
|
| - }
|
| - // Subtract HTTP response from length.
|
| - len -= (payload-text_buffer);
|
| - ASSERT(len >= 0);
|
| - Dart_Handle str = Dart_NewStringFromUTF8(payload, len);
|
| + Dart_Handle str = Dart_NewStringFromUTF8(buffer,
|
| + bufferLen);
|
| + free(buffer);
|
| return str;
|
| }
|
|
|
| @@ -497,39 +384,30 @@ Dart_Handle DartUtils::ReadStringFromFile(const char* filename) {
|
| }
|
|
|
|
|
| -Dart_Handle DartUtils::SetWorkingDirectory(Dart_Handle builtin_lib) {
|
| - Dart_Handle directory = NewString(original_working_directory);
|
| - return SingleArgDart_Invoke(directory, builtin_lib, "_setWorkingDirectory");
|
| -}
|
| -
|
| -
|
| Dart_Handle DartUtils::ResolveScriptUri(Dart_Handle script_uri,
|
| Dart_Handle builtin_lib) {
|
| - return SingleArgDart_Invoke(script_uri, builtin_lib, "_resolveScriptUri");
|
| + const int kNumArgs = 3;
|
| + Dart_Handle dart_args[kNumArgs];
|
| + dart_args[0] = NewString(original_working_directory);
|
| + dart_args[1] = script_uri;
|
| + dart_args[2] = (IsWindowsHost() ? Dart_True() : Dart_False());
|
| + return Dart_Invoke(builtin_lib,
|
| + NewString("_resolveScriptUri"),
|
| + kNumArgs,
|
| + dart_args);
|
| }
|
|
|
|
|
| Dart_Handle DartUtils::FilePathFromUri(Dart_Handle script_uri,
|
| Dart_Handle builtin_lib) {
|
| - return SingleArgDart_Invoke(script_uri, builtin_lib, "_filePathFromUri");
|
| -}
|
| -
|
| -
|
| -Dart_Handle DartUtils::PathFromUri(Dart_Handle script_uri,
|
| - Dart_Handle builtin_lib) {
|
| - return SingleArgDart_Invoke(script_uri, builtin_lib, "_pathFromHttpUri");
|
| -}
|
| -
|
| -
|
| -Dart_Handle DartUtils::HostFromUri(Dart_Handle script_uri,
|
| - Dart_Handle builtin_lib) {
|
| - return SingleArgDart_Invoke(script_uri, builtin_lib, "_hostFromHttpUri");
|
| -}
|
| -
|
| -
|
| -Dart_Handle DartUtils::PortFromUri(Dart_Handle script_uri,
|
| - Dart_Handle builtin_lib) {
|
| - return SingleArgDart_Invoke(script_uri, builtin_lib, "_portFromHttpUri");
|
| + const int kNumArgs = 2;
|
| + Dart_Handle dart_args[kNumArgs];
|
| + dart_args[0] = script_uri;
|
| + dart_args[1] = (IsWindowsHost() ? Dart_True() : Dart_False());
|
| + return Dart_Invoke(builtin_lib,
|
| + NewString("_filePathFromUri"),
|
| + kNumArgs,
|
| + dart_args);
|
| }
|
|
|
|
|
| @@ -662,38 +540,20 @@ void DartUtils::WriteMagicNumber(File* file) {
|
|
|
| Dart_Handle DartUtils::LoadScriptHttp(Dart_Handle uri,
|
| Dart_Handle builtin_lib) {
|
| - const char* host_str = NULL;
|
| - int64_t port_int = 0;
|
| - const char* path_str = NULL;
|
| - Dart_Handle result = ParseHttpUri(uri, &host_str, &port_int,
|
| - &path_str);
|
| + intptr_t len = 0;
|
| + uint8_t* buffer = NULL;
|
| + Dart_Handle result = MakeHttpRequest(uri, builtin_lib, &buffer, &len);
|
| if (Dart_IsError(result)) {
|
| return result;
|
| }
|
| - const char* error_msg = NULL;
|
| - intptr_t len;
|
| - const uint8_t* text_buffer;
|
| - text_buffer = HttpGetRequest(host_str, path_str, port_int, &len,
|
| - &error_msg);
|
| - if (text_buffer == NULL) {
|
| - return Dart_Error(error_msg);
|
| - }
|
| - const uint8_t* payload = HttpRequestGetPayload(
|
| - reinterpret_cast<const char*>(text_buffer));
|
| - if (payload == NULL) {
|
| - return Dart_Error("Invalid HTTP response.");
|
| - }
|
| - // Subtract HTTP response from length.
|
| - len -= (payload-text_buffer);
|
| - ASSERT(len >= 0);
|
| - // At this point we have received a valid HTTP 200 reply and
|
| - // payload points at the beginning of the script or snapshot.
|
| + const uint8_t* payload = buffer;
|
| bool is_snapshot = false;
|
| payload = SniffForMagicNumber(payload, &len, &is_snapshot);
|
| if (is_snapshot) {
|
| return Dart_LoadScriptFromSnapshot(payload, len);
|
| } else {
|
| Dart_Handle source = Dart_NewStringFromUTF8(payload, len);
|
| + free(buffer);
|
| if (Dart_IsError(source)) {
|
| return source;
|
| }
|
| @@ -704,6 +564,9 @@ Dart_Handle DartUtils::LoadScriptHttp(Dart_Handle uri,
|
|
|
| Dart_Handle DartUtils::LoadScript(const char* script_uri,
|
| Dart_Handle builtin_lib) {
|
| + // Always call ResolveScriptUri because as a side effect it sets
|
| + // the script entry path which is used when automatically resolving
|
| + // package root.
|
| Dart_Handle resolved_script_uri =
|
| ResolveScriptUri(NewString(script_uri), builtin_lib);
|
| if (Dart_IsError(resolved_script_uri)) {
|
| @@ -803,23 +666,6 @@ Dart_Handle DartUtils::PrepareForScriptLoading(const char* package_root,
|
| DART_CHECK_VALID(Dart_Invoke(
|
| async_lib, NewString("_setTimerFactoryClosure"), 1, args));
|
|
|
| -
|
| - if (IsWindowsHost()) {
|
| - result = Dart_Invoke(builtin_lib, NewString("_setWindows"), 0, 0);
|
| - if (Dart_IsError(result)) {
|
| - return result;
|
| - }
|
| - }
|
| -
|
| - if (Dart_IsError(result)) {
|
| - return result;
|
| - }
|
| - // Set current working directory.
|
| - result = SetWorkingDirectory(builtin_lib);
|
| - if (Dart_IsError(result)) {
|
| - return result;
|
| - }
|
| -
|
| // Set up package root if specified.
|
| if (package_root != NULL) {
|
| result = NewString(package_root);
|
|
|