Ejemplo n.º 1
0
void
HttpRequest::Open (const char *verb, Uri *uri, DownloaderAccessPolicy policy)
{
    Surface *surface;
    Application *application;
    const char *source_location;
    Uri *src_uri = NULL;

    VERIFY_MAIN_THREAD;
    LOG_DOWNLOADER ("HttpRequest::Open (%s, %p = %s, %i)\n", verb, uri, uri == NULL ? NULL : uri->ToString (), policy);

    g_free (this->verb);
    delete original_uri;
    g_free (this->uri);

    this->verb = g_strdup (verb);
    this->original_uri = new Uri (*uri);
    this->uri = uri->ToString ();

    access_policy = policy;

    surface = GetDeployment ()->GetSurface ();
    application = GetDeployment ()->GetCurrentApplication ();

    if (application->IsRunningOutOfBrowser ()) {
        source_location = surface->GetSourceLocation ();
    } else {
        source_location = GetDeployment ()->GetXapLocation ();
        if (source_location == NULL)
            source_location = surface->GetSourceLocation ();
    }

    // FIXME: ONLY VALIDATE IF USED FROM THE PLUGIN
    if (!Downloader::ValidateDownloadPolicy (source_location, uri, policy)) {
        LOG_DOWNLOADER ("HttpRequest::Open (): aborting due to security policy violation\n");
        Failed ("Security Policy Violation");
        Abort ();
        return;
    }

    /* Make the uri we request to the derived http request an absolute uri */
    if (!uri->isAbsolute && source_location) {
        src_uri = new Uri ();
        if (!src_uri->Parse (source_location, true)) {
            Failed ("Could not parse source location");
            delete src_uri;
            return;
        }

        src_uri->Combine (uri);
        g_free (this->uri);
        this->uri = src_uri->ToString ();
        delete src_uri;
        LOG_DOWNLOADER ("HttpRequest::Open (%s, %p = %s, %i) Url was absolutified to '%s' using source location '%s'\n", verb, uri, uri == NULL ? NULL : uri->ToString (), policy, this->uri, source_location);
    }

    OpenImpl ();
}
Ejemplo n.º 2
0
void
HttpRequest::Write (gint64 offset, void *buffer, gint32 length)
{
    gint64 reported_offset = offset;

    VERIFY_MAIN_THREAD;
    LOG_DOWNLOADER ("HttpRequest::Write (%" G_GINT64_FORMAT ", %p, %i) HasHandlers: %i\n", offset, buffer, length, HasHandlers (WriteEvent));

    written_size += length;

    /* write to tmp file */
    if (tmpfile_fd != -1) {
        if (offset != -1 && lseek (tmpfile_fd, offset, SEEK_SET) == -1) {
            printf ("Moonlight: error while seeking to %" G_GINT64_FORMAT " in temporary file '%s': %s\n", offset, tmpfile, strerror (errno));
        } else if (write (tmpfile_fd, buffer, length) != length) {
            printf ("Moonlight: error while writing to temporary file '%s': %s\n", tmpfile, strerror (errno));
        }
    }

    if (HasHandlers (WriteEvent)) {
        if (reported_offset == -1 && ((options & CustomHeaders) == 0)) {
            /* We check if custom headers is required, if so, our creator might have issued a byte range request,
             * in which case written_size isn't related to offset */
            reported_offset = written_size - length;
        }
        Emit (WriteEvent, new HttpRequestWriteEventArgs (buffer, reported_offset, length));
    }

    if (notified_size > 0 && HasHandlers (ProgressChangedEvent))
        Emit (ProgressChangedEvent, new HttpRequestProgressChangedEventArgs (((double) offset + (double) length) / (double) notified_size));
}
Ejemplo n.º 3
0
void
HttpRequest::SetBody (void *body, gint32 length)
{
    VERIFY_MAIN_THREAD;
    LOG_DOWNLOADER ("HttpRequest::SetBody (%p, %i)\n", body, length);
    SetBodyImpl (body, length);
}
Ejemplo n.º 4
0
void
Downloader::SendInternal ()
{
	LOG_DOWNLOADER ("Downloader::SendInternal ()\n");
	
	g_return_if_fail (request != NULL);

	if (!send_queued)
		return;
	
	send_queued = false;
	
	if (completed) {
		// Consumer is re-sending a request which finished successfully.
		NotifyFinished ();
		return;
	}
	
	if (failed_msg != NULL) {
		if (HasHandlers (DownloadFailedEvent)) {
			// Consumer is re-sending a request which failed.
			Emit (DownloadFailedEvent,
			      new ErrorEventArgs (this, DownloadError,
						  MoonError (MoonError::EXCEPTION, 4001, failed_msg)));
		}
		return;
	}
	
	started = true;
	aborted = false;
	
	g_return_if_fail (request != NULL);

	request->Send ();
}
Ejemplo n.º 5
0
void
HttpResponse::SetStatus (gint32 status, const char *status_text)
{
    LOG_DOWNLOADER ("HttpResponse::SetStatus (%i, %s)\n", status, status_text);
    response_status = status;
    g_free (response_status_text);
    response_status_text = g_strdup (status_text);
}
Ejemplo n.º 6
0
void
HttpRequest::NotifySize (gint64 size)
{
    VERIFY_MAIN_THREAD;
    LOG_DOWNLOADER ("HttpRequest::NotifySize (%" G_GINT64_FORMAT ")\n", size);

    this->notified_size = size;
}
Ejemplo n.º 7
0
void
Downloader::SetFilename (const char *fname)
{
	LOG_DOWNLOADER ("Downloader::SetFilename (%s)\n", fname);
	
	g_free (filename);

	filename = g_strdup (fname);
}
Ejemplo n.º 8
0
void
HttpResponse::AppendHeader (const char *header, const char *value)
{
    LOG_DOWNLOADER ("HttpResponse::AppendHeader ('%s', '%s')\n", header, value);
    VERIFY_MAIN_THREAD;

    if (headers == NULL)
        headers = new List ();
    headers->Append (new HttpHeader (header, value));
}
Ejemplo n.º 9
0
void
HttpRequest::Send ()
{
    LOG_DOWNLOADER ("HttpRequest::Send () async send disabled: %i\n", options & DisableAsyncSend);

    if (options & DisableAsyncSend) {
        SendAsync ();
    } else {
        AddTickCall (SendAsyncCallback);
    }
}
Ejemplo n.º 10
0
void
Downloader::Open (const char *verb, const Uri *uri, DownloaderAccessPolicy policy)
{
	LOG_DOWNLOADER ("Downloader::Open (%s, %p)\n", verb, uri);
	
	OpenInitialize ();
	
	request->Open (verb, uri, /* This is probably not right when we use Downloader internally */ NULL, policy);
	if (failed_msg == NULL)
		SetUri (uri);
}
Ejemplo n.º 11
0
void
Downloader::Open (const char *verb, const char *uri, DownloaderAccessPolicy policy)
{
	LOG_DOWNLOADER ("Downloader::Open (%s, %s)\n", verb, uri);
	
	Uri *url = Uri::Create (uri);
	if (url != NULL)
		Open (verb, url, policy);
		
	delete url;
}
Ejemplo n.º 12
0
void
HttpRequest::SendAsync ()
{
    char *templ;

    VERIFY_MAIN_THREAD;
    LOG_DOWNLOADER ("HttpRequest::SendAsync () is_aborted: %i is_completed: %i\n", is_aborted, is_completed);

    if (is_aborted || is_completed)
        return;

    /* create tmp file */
    if ((options & DisableFileStorage) == 0) {
        const char *dir = handler->GetDownloadDir ();
        if (dir == NULL) {
            Failed ("Could not create temporary download directory");
            return;
        }

        templ = g_build_filename (dir, "XXXXXX", NULL);
        tmpfile_fd = g_mkstemp (templ);
        if (tmpfile_fd == -1) {
            char *msg = g_strdup_printf ("Could not create temporary download file %s for url %s\n", templ, GetUri ());
            Failed (msg);
            g_free (msg);
            g_free (templ);
            return;
        }
        tmpfile = templ;
        LOG_DOWNLOADER ("HttpRequest::Send () uri %s is being saved to %s\n", GetUri (), tmpfile);
    } else {
        LOG_DOWNLOADER ("HttpRequest::Send () uri %s is not being saved to disk\n", GetUri ());
    }

#if DEBUG
    GetDeployment ()->AddSource (GetOriginalUri (), tmpfile == NULL ? "Not stored on disk" : tmpfile);
#endif

    SendImpl ();
}
Ejemplo n.º 13
0
void
HttpRequest::Succeeded ()
{
    VERIFY_MAIN_THREAD;
    LOG_DOWNLOADER ("HttpRequest::Succeeded (%s) HasHandlers: %i\n", uri, HasHandlers (StoppedEvent));

    is_completed = true;

    NotifySize (written_size);

    if (HasHandlers (StoppedEvent))
        Emit (StoppedEvent, new HttpRequestStoppedEventArgs (NULL));
}
Ejemplo n.º 14
0
char *
Downloader::GetResponseText (const char *partname, gint64 *size)
{
	LOG_DOWNLOADER ("Downloader::GetResponseText (%s, %p)\n", partname, size);

	TextStream *stream;
	char buffer[4096];
	GByteArray *buf;
	struct stat st;
	ssize_t nread;
	char *data;
	char *path;
	
	if (!(path = GetDownloadedFilename (partname)))
		return NULL;
	
	if (g_stat (path, &st) == -1) {
		g_free (path);
		return NULL;
	}
	
	if (st.st_size > 0) {
		stream = new TextStream ();
		
		if (!stream->OpenFile (path, true)) {
			delete stream;
			g_free (path);
			return NULL;
		}
		
		g_free (path);
		
		buf = g_byte_array_new ();
		while ((nread = stream->Read (buffer, sizeof (buffer))) > 0)
			g_byte_array_append (buf, (const guint8 *) buffer, nread);
		
		*size = buf->len;
		
		g_byte_array_append (buf, (const guint8 *) "", 1);
		data = (char *) buf->data;
		
		g_byte_array_free (buf, false);
		delete stream;
	} else {
		data = g_strdup ("");
		*size = 0;
	}
	
	return data;
}
Ejemplo n.º 15
0
void
Downloader::Send ()
{
	LOG_DOWNLOADER ("Downloader::Send ()\n");

	if (send_queued)
		return;
	
	send_queued = true;
	SetStatusText ("");
	SetStatus (0);
	
	AddTickCall (SendAsync);
}
Ejemplo n.º 16
0
void
HttpRequest::NotifyFinalUri (const char *value)
{
    g_free (final_uri);
    final_uri = g_strdup (value);

    // check if (a) it's a redirection and (b) if it is allowed for the current downloader policy

    if (!CheckRedirectionPolicy (final_uri)) {
        LOG_DOWNLOADER ("HttpRequest::NotifyFinalUri ('%s'): Security Policy Validation failed\n", value);
        Failed ("Security Policy Violation");
        Abort ();
    }
}
Ejemplo n.º 17
0
void
HttpRequest::Failed (const char *msg)
{
    VERIFY_MAIN_THREAD;
    LOG_DOWNLOADER ("HttpRequest::Failed (%s) HasHandlers: %i\n", msg, HasHandlers (StoppedEvent));

    if (is_completed)
        return;

    is_completed = true;

    if (HasHandlers (StoppedEvent))
        Emit (StoppedEvent, new HttpRequestStoppedEventArgs (msg));
}
Ejemplo n.º 18
0
Downloader::Downloader ()
	: DependencyObject (Type::DOWNLOADER)
{
	LOG_DOWNLOADER ("Downloader::Downloader ()\n");
	
	send_queued = false;
	started = false;
	aborted = false;
	completed = false;
	
	filename = NULL;
	failed_msg = NULL;
	unzipdir = NULL;
	unzipped = false;
	request = NULL;
}
Ejemplo n.º 19
0
void
HttpRequest::Abort ()
{
    VERIFY_MAIN_THREAD;
    LOG_DOWNLOADER ("HttpRequest::Abort () is_completed: %i is_aborted: %i original_uri: %s\n", is_completed, is_aborted, original_uri == NULL ? NULL : original_uri->ToString ());

    if (is_completed || is_aborted)
        return;

    is_aborted = true;
    AbortImpl ();

    Failed ("aborted");

    Dispose ();
}
Ejemplo n.º 20
0
void
Downloader::Abort ()
{
	LOG_DOWNLOADER ("Downloader::Abort ()\n");
	
	SetCurrentDeployment ();
	
	if (!aborted && !failed_msg) {
		if (request != NULL) {
			request->RemoveAllHandlers (this);
			request->Abort ();
		}
		SetDownloadProgress (0.0);
		send_queued = false;
		aborted = true;
	}
}
Ejemplo n.º 21
0
const char *
HttpHandler::GetDownloadDir ()
{
    if (download_dir == NULL) {
        char *buf = g_build_filename (g_get_tmp_dir (), "moonlight-downloads.XXXXXX", NULL);
        // create a root temp directory for all files
        download_dir = MakeTempDir (buf);
        if (download_dir == NULL) {
            g_free (buf);
            printf ("Moonlight: Could not create temporary download directory.\n");
        } else {
            GetDeployment ()->TrackPath (download_dir);
            LOG_DOWNLOADER ("HttpHandler::GetDownloadDir (): Created temporary download directory: %s\n", download_dir);
        }
    }

    return download_dir;
}
Ejemplo n.º 22
0
Downloader::~Downloader ()
{
	LOG_DOWNLOADER ("Downloader::~Downloader ()\n");
	
	if (request != NULL) {
		request->RemoveAllHandlers (this);
		request->Dispose ();
		request->unref ();
		request = NULL;
	}
	
	g_free (failed_msg);

	CleanupUnzipDir ();

	if (filename)
		g_free (filename);
}
Ejemplo n.º 23
0
void
HttpRequest::Started (HttpResponse *response)
{
    VERIFY_MAIN_THREAD;
    LOG_DOWNLOADER ("HttpRequest::Started ()\n");

    g_warn_if_fail (response != NULL);
    g_warn_if_fail (this->response == NULL);

    if (this->response != NULL)
        this->response->unref ();
    this->response = response;
    if (this->response != NULL)
        this->response->ref ();

    if (HasHandlers (StartedEvent))
        Emit (StartedEvent);
}
Ejemplo n.º 24
0
void
Downloader::NotifyFailed (const char *msg)
{
	LOG_DOWNLOADER ("Downloader::NotifyFailed (%s)\n", msg);
	
	/* if we've already been notified of failure, no-op */
	if (failed_msg)
		return;
	
	// SetStatus (400);
	// For some reason the status is 0, not updated on errors?
	
	if (HasHandlers (DownloadFailedEvent))
		Emit (DownloadFailedEvent,
		      new ErrorEventArgs (this, DownloadError,
					  MoonError (MoonError::EXCEPTION, 4001, msg)));
	
	failed_msg = g_strdup (msg);
}
Ejemplo n.º 25
0
void
HttpRequest::Dispose ()
{
    HttpResponse *response;

    VERIFY_MAIN_THREAD;
    LOG_DOWNLOADER ("HttpRequest::Dispose () id: %i\n", GetId ());

    if (handler != NULL) {
        handler->unref ();
        handler = NULL;
    }

    response = this->response;
    this->response = NULL;
    if (response != NULL) {
        response->unref ();
        response = NULL;
    }

    g_free (verb);
    verb = NULL;

    delete original_uri;
    original_uri = NULL;

    g_free (uri);
    uri = NULL;

    g_free (final_uri);
    final_uri = NULL;

    g_free (tmpfile);
    tmpfile = NULL;

    if (tmpfile_fd != -1) {
        close (tmpfile_fd);
        tmpfile_fd = -1;
    }

    EventObject::Dispose ();
}
Ejemplo n.º 26
0
bool
Downloader::ValidateDownloadPolicy (const Uri *source_location, const Uri *uri, DownloaderAccessPolicy policy)
{
	bool valid;
	
	/* We should always have a source location */
	g_return_val_if_fail (source_location != NULL, false);

	/* The uri combine rules are complex, so ensure they're already executed when we validate (to not duplicate combining code) */
	if (!uri->IsAbsolute ()) {
		fprintf (stderr, "Moonlight: Can't validate relative uri '%s' - '%s'\n", uri->GetOriginalString (), uri->ToString ());
		return false;
	}
	
	valid = validate_policy (source_location, uri, policy);
	
	LOG_DOWNLOADER ("Downloader::ValidatePolicy ('%s', '%s', %i) => %i\n", source_location->GetOriginalString (), uri->GetOriginalString (), policy, valid);

	return valid;
}
Ejemplo n.º 27
0
HttpRequest::HttpRequest (Type::Kind type, HttpHandler *handler, HttpRequest::Options options)
    : EventObject (type)
{
    VERIFY_MAIN_THREAD;
    LOG_DOWNLOADER ("HttpRequest::HttpRequest (%s, %i) id: %i %s\n", handler->GetTypeName (), options, GetId (), GetTypeName ());
    this->handler = handler;
    this->handler->ref ();
    this->response = NULL;
    this->options = options;
    is_aborted = false;
    is_completed = false;
    verb = NULL;
    uri = NULL;
    original_uri = NULL;
    final_uri = NULL;
    tmpfile = NULL;
    tmpfile_fd = -1;
    notified_size = -1;
    written_size = 0;
    access_policy = (DownloaderAccessPolicy) -1;
}
Ejemplo n.º 28
0
void
HttpResponse::ParseHeaders (const char *input)
{
    const char *ptr;
    const char *start = input;

    VERIFY_MAIN_THREAD;
    LOG_DOWNLOADER ("HttpResponse::ParseHeaders:\n%s\n\n", input);

    if (start == NULL || start [0] == 0)
        return;

    /*
     * Parse status line
     */

    /* Find http version */
    ptr = start;
    while (*ptr != 0 && *ptr != '\n' && *ptr != '\r') {
        if (*ptr == ' ') {
            LOG_DOWNLOADER ("ParseHeaders: header version: %.*s\n", (int) (ptr - start), start);
            break;
        }
        ptr++;
    };
    /* Skip extra spaces */
    while (*ptr == ' ')
        ptr++;
    if (*ptr == '\n' || *ptr == '\r') {
        LOG_DOWNLOADER ("ParseHeaders: invalid status line\n");
        return;
    }

    /* Find status code */
    start = ptr;
    while (*ptr != 0 && *ptr != '\n' && *ptr != '\r') {
        if (*ptr == ' ') {
            response_status = atoi (start);
            LOG_DOWNLOADER ("ParseHeaders: status code: %i\n", response_status);
            break;
        }
        ptr++;
    }
    /* Skip extra spaces */
    while (*ptr == ' ')
        ptr++;
    if (*ptr == '\n' || *ptr == '\r') {
        LOG_DOWNLOADER ("ParseHeaders: invalid status line\n");
        return;
    }
    /* The rest is status text */
    start = ptr;
    while (*ptr != 0) {
        if (*ptr == '\n' || *ptr == '\r') {
            response_status_text = g_strndup (start, ptr - start);
            LOG_DOWNLOADER ("ParseHeaders: status text: %s\n", response_status_text);
            break;
        }
        ptr++;
    }

    start = ptr;


    /*
     * Parse header lines
     */
    char *header = NULL;
    char *value = NULL;

    while (*ptr != 0) {
        if (header == NULL && *ptr == ':') {
            header = g_strndup (start, ptr - start);
            while (*(ptr + 1) == ' ')
                ptr++;
            start = ptr + 1;
        } else if (*ptr == '\n' || *ptr == '\r') {
            if (header != NULL) {
                value = g_strndup (start, ptr - start);
                AppendHeader (header, value);
            }
            start = ptr + 1;
            g_free (header);
            header = NULL;
            g_free (value);
            value = NULL;
        }
        ptr++;
    }

    if (value != NULL && header != NULL)
        AppendHeader (header, value);
    g_free (header);
    g_free (value);
}
Ejemplo n.º 29
0
void
HttpRequest::SetHeader (const char *header, const char *value, bool disable_folding)
{
    LOG_DOWNLOADER ("HttpRequest::SetHeader (%s, %s, %i)\n", header, value, disable_folding);
    SetHeaderImpl (header, value, disable_folding);
}
Ejemplo n.º 30
0
Uri *
Uri::CombineWithSourceLocation (Deployment *deployment, const Uri *base_uri, const Uri *relative_uri, bool allow_escape)
{
	Uri *absolute_dummy;
	Uri *absolute_base;
	Uri *absolute_uri;
	Uri *result;

	LOG_DOWNLOADER ("Uri::CombineWithSourceLocation (%s, %s, %s, %s)\n", deployment->GetSourceLocation (NULL)->ToString (), base_uri ? base_uri->ToString () : NULL, relative_uri->ToString (), allow_escape ? "true" : "false");

	if (allow_escape) {
		absolute_base = Uri::Create (deployment->GetSourceLocation (NULL), base_uri);
		absolute_uri = Uri::Create (absolute_base, relative_uri);

		LOG_DOWNLOADER ("Uri::CombineWithSourceLocation (): absolute base: '%s' absolute uri: '%s'\n", absolute_base->ToString (), absolute_uri->ToString ());

		delete absolute_base;

		result = absolute_uri;
	} else {
		/*
		 * We must combine base_uri and relative_uri, having in mind that base_uri can't get out of the
		 * source location using ".."
		 * So we create a dummy absolute uri (with an empty path), and combine it with the base_uri => absolute_base.
		 * This will remove any ".."'s we don't want.
		 * Then we combine absolute_base with the relative_uri => absolute_uri.
		 * Finally we take the source location and combine it with the path of absolute_uri => result.
		 */
		absolute_dummy = Uri::Create ("http://www.mono-project.com/");
		if (base_uri != NULL && base_uri->GetOriginalString () != NULL) {
			absolute_base = Uri::Create (absolute_dummy, base_uri);
		} else {
			absolute_base = Uri::Clone (absolute_dummy);
		}
		delete absolute_dummy;

		if (absolute_base == NULL)
			return NULL;

		LOG_DOWNLOADER ("Uri::CombineWithSourceLocation (): absolute base uri with dummy root: '%s'\n", absolute_base->ToString ());

		/* Combine the absolute base uri with the uri of the resource */
		absolute_uri = Uri::Create (absolute_base, relative_uri);
		delete absolute_base;

		if (absolute_uri == NULL)
			return NULL;

		LOG_DOWNLOADER ("Uri::CombineWithSourceLocation (): absolute base with dummy root and uri: '%s'\n", absolute_uri->ToString ());

		const char *path = absolute_uri->GetPath ();
		if (path != NULL && path [0] == '/') {
			/* Skip over any '/' so that the absolute uri's path is not resolved against the root of the source location */
			path++;
		}
		result = Uri::Create (deployment->GetSourceLocation (NULL), path);
		delete absolute_uri;

		LOG_DOWNLOADER ("Uri::CombineWithSourceLocation () final uri: '%s' (path: '%s')\n", result->ToString (), path);
	}

	return result;
}