Toon posts:

[C#.NET] HTTP GET met Range..?

Pagina: 1
Acties:

Onderwerpen


  • NickThissen
  • Registratie: November 2007
  • Laatst online: 23-05 20:03
Hey,

Ik wil een text file van een webserver downloaden met HTTP GET, waarvoor ik momenteel deze code gebruik:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
        public static string DownloadLog(string url)
        {
            var client = CreateWebClient();
            
            var stream = client.OpenRead(url);
            if (stream == null) return string.Empty;

            using (var webReader = new StreamReader(stream))
            {
                string data = string.Empty; 

                // lees data uit en decompress met GZipStream... code weg gelaten

                return data;
            }
        }

        private static WebClient CreateWebClient()
        {
            System.Net.WebClient client;
            client = new System.Net.WebClient();
            client.Headers["User-Agent"] = "Naam van m'n programma"; 
            client.Headers["Accept-Encoding"] = "gzip";
            return client;
        }


Dit werkt prima, het probleem is alleen dat dit bestand 2MB is en elke 5 seconden (ongeveer dan) gedownload gaat worden. Dat tikt toch flink aan kwa bandwidth lijkt me. Nou ja, als het goed is wordt er wel gzip gebruikt dus het zal geen 2MB zijn, maar dan nog.

Feit is dat ik nooit meer dan een bepaald aantal bytes van de file nodig heb, zeg de laatste 5000 bytes ofzo (dit is even een gok, maar het precieze aantal zal ik moeten uitzoeken). Volgens de host van de file zou de Range header van HTTP GET ondersteund zijn, waarmee ik een bepaalde range zou kunnen opvragen, dus zou ik alleen de laatste 5000 bytes kunnen opvragen.

Ik heb zitten zoeken hoe ik dit nu precies doe maar ik kan het nergens vinden. Ik begrijp dat ik de Range header moet opgeven, maar ik snap niet in welk formaat ik dit moet doen.
Ik heb de volgende headers geprobeerd toe te voegen (in de CreateWebClient methode):
C#:
1
2
3
4
5
6
7
8
client.Headers["Accept-Ranges"] = "-5000";
client.Headers["Accept-Ranges"] = "bytes: -5000";
client.Headers["Accept-Ranges"] = "bytes -500";
client.Headers["Range"] = "-5000";
client.Headers["Range"] = "bytes: -5000";
client.Headers["Range"] = "bytes -5000";
client.Headers["Range"] = "bytes=-5000";
client.Headers.Add("Range:bytes=-5000");

(natuurlijk niet allemaal tegelijk, een voor een)
en vast nog wel meer... Ik kan nergens een voorbeeld vinden dat de range header gebruikt in C# dus ik ben gewoon maar wat gaan proberen. Ook de MSDN pagina voor WebClient lijkt nergens iets over ranges te zeggen.

Anyway, welke ik ook probeer, ik krijg gewoon elke keer de volledige file terug. Sommige regels leiden tot een error:
code:
1
2
This header must be modified using the appropriate property.
Parameter name: name

en sommige lijken gewoon niet te werken waarna ik gewoon weer de hele file terug krijg.

Voor zover ik kon vinden klopt de "-5000" wel, als het goed is is het format "start-eind", en door het weglaten van de start byte worden de laatste 5000 bytes opgehaald. Tenminste, dat heb ik hieruit kunnen opmaken.


Doe ik hier nu iets compleet fout? Ik weet vrijwel niets van HTTP GET, wat ik nu heb heb ik vooral uit voorbeeldjes in elkaar gepuzzeld dus ik kan me best voorstellen dat ik iets fundamenteels niet begrijp... Het zou mogelijk moeten zijn om de range header te gebruiken volgens de host, dus hoe kan ik dat implementeren in mijn code?

Bedankt!

[Voor 9% gewijzigd door NickThissen op 28-06-2011 18:43]

Mijn iRacing profiel


  • Snow_King
  • Registratie: April 2001
  • Laatst online: 08:11

Snow_King

Konijn is stoer!

Als het gzip'ed content is gaat het niet werken om alleen de laatste 5000 bytes op te vragen, dat gaat problemen opleveren.

Als client moet je inderdaad de "Range" header sturen, dat doe je dus al goed:

code:
1
Range: bytes=-5000


Weet je zeker dat de webserver terug stuurt: Accept-Ranges: bytes

Dan pas weet je zeker dat de server het ondersteund.

  • NickThissen
  • Registratie: November 2007
  • Laatst online: 23-05 20:03
Ik heb de gzip header weg gehaald en deze header erbij gedaan:
C#:
1
client.Headers["Range"]  = "bytes=-5000";


Nu geeft hij weer deze error:
code:
1
2
This header must be modified using the appropriate property.
Parameter name: name


Als ik de Range header ook weg laat (zodat ik kan zien welke response headers er zijn) dan zit Accept-Ranges er inderdaad niet bij... Ondersteunt de host dan toch geen range header, ook al staat dit meerdere keren aangegeven op hun forum..? Of krijg je die header alleen terug als je ook zelf de range header stuurt?

Mijn iRacing profiel


  • Snow_King
  • Registratie: April 2001
  • Laatst online: 08:11

Snow_King

Konijn is stoer!

Welke host is het? Amazon S3 toevallig? Zij sturen geen Accept-Ranges: bytes, maar zouden het inderdaad wel moeten ondersteunen.

Je kan overigens wel om gzip'ed content vragen zodat de webserver het voor je doet, maar het originele bestand mag NIET compressed zijn.

  • NickThissen
  • Registratie: November 2007
  • Laatst online: 23-05 20:03
Het gaat om de log files van een Call of Duty Black Ops server, de host is dus gameservers.com, maar ik neem aan dat je daar niet zoveel aan hebt... Gzip lijkt wel te werken, als ik de StreamReader gewoon uitlees (ReadToEnd) en de lengte van die string toon dan is het iets van 70.000 karakters lang als ik de gzip header weg laat, en enkel iets van 3.000 karakters als ik de gzip header wel gebruik. Als ik de content dan unzip komt er wel hetzelfde resultaat uit dus het lijkt me dat dat prima werkt. Trouwens wel een behoorlijk verschil, 70.000 en 3.000, misschien is de range wel helemaal niet nodig, vooral niet als ik moet kiezen tussen range of gzip...?

Mijn iRacing profiel


  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Als je even goed in de documentatie had gelezen kun je de "Range" header niet zetten bij de WebClient class

Zie in onderstaande link de Remarks
MSDN: WebClient.Headers Property (System.Net)

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • NickThissen
  • Registratie: November 2007
  • Laatst online: 23-05 20:03
Woy schreef op dinsdag 28 juni 2011 @ 19:35:
Als je even goed in de documentatie had gelezen kun je de "Range" header niet zetten bij de WebClient class

Zie in onderstaande link de Remarks
MSDN: WebClient.Headers Property (System.Net)
Ahhh... dat had ik dus gemist. Bedankt! Ik gebruik de HttpWebRequest class nu om de get uit te voeren en het lijkt te werken, ik kan nu instellen hoeveel van de laatste bytes ik wil krijgen. Gzip kreeg ik nu echter niet aan het werken, maar voor zover ik uit bovenstaande posts begrijp is dat toch niet mogelijk in combinatie met de range header?

Mijn iRacing profiel


  • Snow_King
  • Registratie: April 2001
  • Laatst online: 08:11

Snow_King

Konijn is stoer!

Nee, als het bestand op het filesystem al compressed is gaat het niet. Als jij dmv van de Accept-Encoding header om GZIP of DEFLATE vraagt, dan kan dat zonder problemen.

  • NickThissen
  • Registratie: November 2007
  • Laatst online: 23-05 20:03
Snow_King schreef op dinsdag 28 juni 2011 @ 20:55:
Nee, als het bestand op het filesystem al compressed is gaat het niet. Als jij dmv van de Accept-Encoding header om GZIP of DEFLATE vraagt, dan kan dat zonder problemen.
Voor zover ik begrijp is het bestand niet compressed op de server zelf (hoe kom ik daar achter?), als ik namelijk niets van gzip implementeer dan krijg ik gewoon de tekst terug die ik verwacht. Als ik gzip gebruik en daarna mbv de GzipStream het weer unzip krijg ik diezelfde tekst terug, maar omdat ik nu niet meer de WebClient gebruik kan ik zo snel even niet vinden hoe ik de HttpWebRequest weer gzip laat gebruiken. Ach, het is ook niet nodig denk ik, als ik de range kan instellen is dat goed genoeg :)

Hmm bij nader inzien... Stel dat ik 10.000 bytes ophaal elke 5 seconden. Dat is dus (24*60*60/5) * 10.000 bytes per dag, oftewel zo'n 60 GB per jaar... Dat is toch wel wat veel denk ik. Maar even kijken hoeveel bytes ik precies nodig heb.

[Voor 13% gewijzigd door NickThissen op 28-06-2011 21:07]

Mijn iRacing profiel

Pagina: 1


Tweakers maakt gebruik van cookies

Tweakers plaatst functionele en analytische cookies voor het functioneren van de website en het verbeteren van de website-ervaring. Deze cookies zijn noodzakelijk. Om op Tweakers relevantere advertenties te tonen en om ingesloten content van derden te tonen (bijvoorbeeld video's), vragen we je toestemming. Via ingesloten content kunnen derde partijen diensten leveren en verbeteren, bezoekersstatistieken bijhouden, gepersonaliseerde content tonen, gerichte advertenties tonen en gebruikersprofielen opbouwen. Hiervoor worden apparaatgegevens, IP-adres, geolocatie en surfgedrag vastgelegd.

Meer informatie vind je in ons cookiebeleid.

Sluiten

Toestemming beheren

Hieronder kun je per doeleinde of partij toestemming geven of intrekken. Meer informatie vind je in ons cookiebeleid.

Functioneel en analytisch

Deze cookies zijn noodzakelijk voor het functioneren van de website en het verbeteren van de website-ervaring. Klik op het informatie-icoon voor meer informatie. Meer details

janee

    Relevantere advertenties

    Dit beperkt het aantal keer dat dezelfde advertentie getoond wordt (frequency capping) en maakt het mogelijk om binnen Tweakers contextuele advertenties te tonen op basis van pagina's die je hebt bezocht. Meer details

    Tweakers genereert een willekeurige unieke code als identifier. Deze data wordt niet gedeeld met adverteerders of andere derde partijen en je kunt niet buiten Tweakers gevolgd worden. Indien je bent ingelogd, wordt deze identifier gekoppeld aan je account. Indien je niet bent ingelogd, wordt deze identifier gekoppeld aan je sessie die maximaal 4 maanden actief blijft. Je kunt deze toestemming te allen tijde intrekken.

    Ingesloten content van derden

    Deze cookies kunnen door derde partijen geplaatst worden via ingesloten content. Klik op het informatie-icoon voor meer informatie over de verwerkingsdoeleinden. Meer details

    janee