Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > .NET Frameworks (точка нет фреймворки) > Общие вопросы .NET
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 04.10.2010, 13:43   #1
BOBAH13
Android Developer
Старожил Подтвердите свой е-майл
 
Аватар для BOBAH13
 
Регистрация: 19.02.2007
Сообщений: 3,708
По умолчанию HttpWebRequest uploading at once

Привет всем.
Стоит цель создать uploader для youtube. В принципе все уже работает как часы (ну не считая privacy issue). Но есть проблема, дело в том, что когда запрашиваю RequestStream, и начинаю в него писать (по сути загружать) данные, то цикл записи из файла и POST данных, происходит за считанные секунды, видимо записывается в буфер, и только после запроса GetResponse, поток останавливается, видимо пока загрузятся данные и вернется response от youtube сервиса, либо ошибка.

Вопрос в том, как заставить RequestStream сразу после Write загружать данные в веб, а не в буфер. Находил многие решения, типа метода Flush(), или же в false свой-во AllowWriteStreamBuffering или SendChunked с не установленным ContentLength, но ничего не помогло. А оставлять так, нет смысла, т.к. функцию отмены загрузки и прогресс загрузки не сделать вообще в таком случае. Вот код как я все сделал, прошу помощи. Я исключил некоторые классы, для сериализации и других мелочей, они роли в вопросе не имеют.

Код:
public delegate void UploadVideoProgressCallback(object sender, long uploaded, long size, out bool cancel);
        public Entry UploadVideo(string FileName, string Title, string Description, 
Categories? Category, Privacy? Privacy, string Keywords, 
UploadVideoProgressCallback Progress)
        {
            const string LineTerm = "\r\n";
            const string BoundaryHeader = "--END_OF_PART";
            const string Boundary = "--" + BoundaryHeader;
            const int Timeout = 1000 * 60 * 5;

            var Header = new StringBuilder();
            Header.Append(Boundary + LineTerm + "Content-Type: application/atom+xml; charset=UTF-8" + LineTerm + LineTerm);
            Header.Append("<?xml version=\"1.0\"?><entry xmlns=\"http://www.w3.org/2005/Atom\" ");
            Header.Append("xmlns:media=\"http://search.yahoo.com/mrss/\" xmlns:yt=\"http://gdata.youtube.com/schemas/2007\">");

            Header.AppendFormat("<media:group><media:title type=\"plain\">{0}</media:title>", Title);
            Header.AppendFormat("<media:description type=\"plain\">{0}</media:description>", Description);
            if (Category.HasValue)
            {
                Header.AppendFormat("<media:category scheme=\"http://gdata.youtube.com/schemas/2007/categories.cat\">{0}</media:category>", 
Category.Value.ToString());
            }
            Header.AppendFormat("<media:keywords>{0}</media:keywords>", Keywords);
            Header.Append("</media:group></entry>" + LineTerm);
            Header.Append(Boundary + LineTerm + "Content-Type: video/*" + LineTerm + 
"Content-Transfer-Encoding: binary" + LineTerm + LineTerm);

            var FileInfo = new FileInfo(FileName);
            var postContents = Encoding.UTF8.GetBytes(Header.ToString());
            var postFooter = Encoding.UTF8.GetBytes(LineTerm + Boundary + "--");

            System.Net.ServicePointManager.Expect100Continue = false;
            var Request = (HttpWebRequest)WebRequest.Create(string.Format("http://uploads.gdata.youtube.com/feeds/api/users/{0}/uploads", 
Username));
            Request.Method = "POST";
            Request.ContentType = string.Format("multipart/related; boundary={0};", BoundaryHeader);
            Request.ContentLength = postContents.Length + FileInfo.Length + postFooter.Length;
            Request.Headers.Add("Authorization", "GoogleLogin auth=" + Auth);
            Request.Headers.Add("X-GData-Client", ClientID);
            Request.Headers.Add("X-GData-Key", "key=" + DeveloperKey);
            Request.Headers.Add("Slug", Path.GetFileName(FileName));
            Request.Timeout = Timeout;

            using (var RequestStream = Request.GetRequestStream())
            {
                RequestStream.WriteTimeout = Timeout;
                RequestStream.Write(postContents, 0, postContents.Length);

                var bytesSoFar = 0;
                var bytesRead = 0;
                var buffer = new byte[1024];
                var cancel = false;

                using (var fs = FileInfo.OpenRead())
                {
                    while ((bytesRead = fs.Read(buffer, 0, buffer.Length)) > 0)
                    {
                        bytesSoFar += bytesRead;
                        RequestStream.Write(buffer, 0, bytesRead);

                        Thread.Sleep(1);
 
                        if (Progress is UploadVideoProgressCallback)
                        {
                            Progress(this, bytesSoFar, fs.Length, out cancel);
                            if (cancel)
                            {
                                throw new YoutubeException("Video uploading has been canceled");
                            }
                        }
                    }
                }
                RequestStream.Write(postFooter, 0, postFooter.Length);
            }
            var res = (HttpWebResponse)Request.GetResponse();
            ...}
BOBAH13 вне форума Ответить с цитированием
Старый 05.10.2010, 16:03   #2
m0nax
Форумчанин
 
Аватар для m0nax
 
Регистрация: 25.09.2009
Сообщений: 525
По умолчанию

в http 1.0 в любом случае данные передаются цельным блоком насколько я помню
а вот в 1.1 уже сделали режим chunked или как-то так, думаю куда-то в эту сторону надо копать

может сам ютуб его не поддерживает раз не помогло..

Последний раз редактировалось m0nax; 05.10.2010 в 16:08. Причина: дочитал вопрос )
m0nax вне форума Ответить с цитированием
Старый 05.10.2010, 17:15   #3
BOBAH13
Android Developer
Старожил Подтвердите свой е-майл
 
Аватар для BOBAH13
 
Регистрация: 19.02.2007
Сообщений: 3,708
По умолчанию

Цитата:
Сообщение от m0nax Посмотреть сообщение
в http 1.0 в любом случае данные передаются цельным блоком насколько я помню
а вот в 1.1 уже сделали режим chunked или как-то так, думаю куда-то в эту сторону надо копать

может сам ютуб его не поддерживает раз не помогло..
Спасибо за ответ. Но знаете, у них в API написан пример (шаблон) запроса
Код:
POST /resumable/feeds/api/users/default/uploads HTTP/1.1
Host: uploads.gdata.youtube.com
Authorization: AuthSub token="<authentication_token>"
GData-Version: 2
X-GData-Key: key=<developer_key>
Content-Length: <content_length>
Content-Type: application/atom+xml; charset=UTF-8
Slug: <video_filename>

API_XML_request
Как видим, они держат http 1.1. Но как быть уверенным в том, что я использую 1.1 в своем запросе? Пока как я понимаю, это и так по умолчанию установлено в 1.1, или я не прав?
BOBAH13 вне форума Ответить с цитированием
Старый 05.10.2010, 17:28   #4
m0nax
Форумчанин
 
Аватар для m0nax
 
Регистрация: 25.09.2009
Сообщений: 525
По умолчанию

Можно для надежности вручную установить
Код:
Request.ProtocolVersion = new Version(1, 1);
и неизвестно насколько поможет этот SendChunked, ведь все равно не дают указать когда и по сколько отправлять...

Последний раз редактировалось m0nax; 05.10.2010 в 17:31.
m0nax вне форума Ответить с цитированием
Старый 05.10.2010, 17:44   #5
BOBAH13
Android Developer
Старожил Подтвердите свой е-майл
 
Аватар для BOBAH13
 
Регистрация: 19.02.2007
Сообщений: 3,708
По умолчанию

Боюсь уже и так 1.1 установлен
BOBAH13 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
VB.NET HttpWebRequest reyn90 Помощь студентам 9 27.03.2010 05:06
HttpWebRequest и Cookie d9m0n Общие вопросы .NET 1 23.12.2009 11:38
Cookie & HttpWebRequest & авторизация Geniy00 Общие вопросы .NET 0 29.11.2009 21:03
Проблема с HttpWebRequest и HttpWebResponse 3dgraph Общие вопросы .NET 2 15.07.2009 11:20
HttpWebRequest и HttpWebResponse Bbo Общие вопросы .NET 1 14.05.2009 15:51