Haen eräältä sivulta tietoa HttpWebRequestilla.
Kirjautuminen tuntuu toimivan hyvin. Ongelmat alkavat haettaessa sivua jossa on kehykset. Itse kehyksillä ei ole mitään tekemistä ongelman kanssa, jos URL on haettu oikein src:stä.
Selaimella voi hakea halutun sivun ilman kehyksiä katsomalla lähdekoodista suora osoite. https://intra.hva.dom/Serv/Dyn/Sup.aspx?maid=8b170d0c-04fe-424c-912a-591fbfb03de5&parentmaid=0c292623-ace1-45b2-bfaa-1c13adc9f5e5&SetFrameTitle=True
<FRAMESET cols='660,*,0' framespacing='2' frameborder='1'> <FRAME src='Dyn/Sup.aspx?maid=8b170d0c-04fe-424c-912a-591fbfb03de5&parentmaid=0c292623-ace1-45b2-bfaa-1c13adc9f5e5&SetFrameTitle=True' name='Left' frameborder='2' bordercolor='#eaeaea' resize='yes' scrolling='auto'> <FRAME src='empty.aspx' name='Right' frameborder='2' bordercolor='#eaeaea' resize='yes' scrolling='auto'> <FRAME src='empty.aspx' name='HiddenFrame' frameborder='0' bordercolor='#eaeaea' resize='yes' scrolling='no'> </FRAMESET>
maid-parametri generoituu joka sessiolle automaattisesti, mutta tuosta kopioimalla saa sivun auki nätisti.
Koodissa luen tuon Frameset-sivun muistiin, ja etsin siitä osoitteen.
' frameset URL. Kirajutumisesta on saatu cookie ja maid-parametri URL = "https://intra.hva.dom/Serv/WrappedFramesetSub.aspx?HiddenFrame=True&LeftWidth=660&left=Dyn/Sup.aspx " & maid 'Uusi haku salasanasuojatulle sivulle httpReq = CType(WebRequest.Create(URL), HttpWebRequest) httpReq.ClientCertificates.Add(certificate) 'Aiemmin hankittu keksi httpReq.CookieContainer = cookie httpReq.AllowAutoRedirect = True 'Luetaan sivu httpReq.KeepAlive = True 'Luetaan sivu response = CType(httpReq.GetResponse(), HttpWebResponse) Str = New StreamReader(response.GetResponseStream()).ReadToEnd() Dim supermaid As String = ExtractMaid(Str ", "Dyn", "'") ' Haetaan haluttu tieto URL = "https://intra.hva.dom/Serv/" & supermaid 'Uusi haku salasanasuojatulle sivulle httpReq = CType(WebRequest.Create(URL), HttpWebRequest) ‘Sivunston vaatima sertti pidetävä mukana httpReq.ClientCertificates.Add(certificate) 'Aiemmin kirjautumisesta saatu keksi httpReq.CookieContainer = cookie 'Ilman tätä tulee Object moved httpReq.AllowAutoRedirect = True 'Luetaan sivu response = CType(httpReq.GetResponse(), HttpWebResponse) Str = New StreamReader(response.GetResponseStream()).ReadToEnd() 'Tallennetaan sivu Console.WriteLine("RequestUri:") Console.WriteLine(httpReq.RequestUri) Console.WriteLine("ResponseUri:") Console.WriteLine(response.ResponseUri)
RequestUri:
https://intra.hva.dom/Serv/Dyn/Sup.aspx?maid=8b170d0c-04fe-424c-912a-591fbfb03de5&parentmaid=0c292623-ace1-45b2-bfaa-1c13adc9f5e5&SetFrameTitle=True
ResponseUri:
https://intra.hva.dom/Serv/MessagePage.aspx?aspxerrorpath=/Serv/Dyn/Sup.aspx
Kuten tuosta näkyy, on Request Uri saanut oikean osoitteen haetusta kehyksestä. Jostain syystä HttpWebRequest silti ohjautuu virhesivulle. En ymmärrä miksi näin tapahtuu tässä, mutta ei manuaalisesti selaimella tehdessä.
Tein koodiin muutoksen, joka hakee etusivun uudelleen epäonnistuneen haun jälkeen. Etusivu tulee edelleen oikein, eli cookie ja maid-parametri ovat edelleen voimassa. Jos RequesteUri:sta ottaa pois maid-parametrin, saa selkeän virheilmoituksen sen puuttumisesta.
Mikä piru tässä nyt mättää?
Arvaan että bugisesti koodattu sovellus serverillä heittää evästeen, joka on virheellinen ja cookiecontainer ei hyväksy sitä sen takia. Selaimet yleensä arpovat myös vialliset evästeet käyttöön.
Katso mitä evästeitä palvelin lähettää ja meneekö ne kaikki takaisin. Itse olen törmännyt tähän mm. erään SAPiin tehdyn extranetin kanssa.
Sanotaanko esimerkiksi että seuraava eväste on epävalidi eikä tartu sellaisenaan CookieContaineriin:
Path=/erp2/
JSESSIONID=(J2EE1232323232)IDas299129das3200End; Version=1; Domain=www.firma.fi; path=/
Siinä nimittäin sanotaan että Version=1, mutta Domain ei ala pisteellä. Jos tuon Version=1 määritteen jättäisi pois, niin se olisi validi eväste. Sinänsä jotenkin koomista että ylipäätään pitää ilmoittaa versio, jos ei osaa sitten implementoida sitä oikein.
Sen sijaan selaimet katsoo tuota virhettä sormien läpi.
Tokihan vika voi olla muukin, vaikea sanoa kun ei voi testata.
Moi K_L!
eräs toinen tapa poimia framesetin osoitteet...
'väännetty SharpDevelop 4.0:lla Imports System Imports System.Threading Imports Microsoft.VisualStudio.OLE.Interop Imports mshtml 'Microsoft.mshtml Module Program 'testi URL... Private baseUrl As String = _ "http://www.elisanet.fi/nea.fi/frametest/" 'index.html Private objMSHTML As New HTMLDocument Private objDocument As IHTMLDocument2 Private ips As IPersistStreamInit = _ CType(objMSHTML, IPersistStreamInit) Sub Main() ips.InitNew objDocument = _ objMSHTML.createDocumentFromUrl(baseUrl, "") While objDocument.readyState <> "complete" 'Huom tuo refernssi System.Windows.Forms System.Windows.Forms.Application.DoEvents Thread.Sleep(100) End While Dim theDoc As HTMLDocument = _ CType(objDocument, HTMLDocument) Dim htmlFrames As IHTMLElementCollection = _ theDoc.getElementsByTagName("frame") If htmlFrames.length > 0 Then For i As Integer = 0 To htmlFrames.length - 1 Dim frameNode As IHTMLDOMNode = _ CType(htmlFrames.item(i),IHTMLDOMNode) Dim AttrColl As IHTMLAttributeCollection = _ CType (frameNode.attributes, IHTMLAttributeCollection) Dim frameUrl As String = String.Empty For Each objItem As IHTMLDOMAttribute2 In AttrColl With objItem If .name = "src" Then If .value.Contains("://") Then frameUrl = .value Else frameUrl = baseUrl + .value 'esim. End If Console.WriteLine(frameUrl) End If End With Next objItem AttrColl = Nothing frameNode = Nothing Next i Else Console.WriteLine("Requested page has no frame elements!") End If htmlFrames = Nothing theDoc = Nothing ips = Nothing objDocument = Nothing objMSHTML = Nothing Console.Write("Press any key to continue . . . ") Console.ReadKey(True) End Sub End Module
Nea kokeilen tuota, jos en saa tätä HttpWebRequest:lla toimimaan.
Hain vastauksesta keksit response.Cookies = httpReq.CookieContainer.GetCookies(httpReq.
Istunnossa on niitä kaksi.
Cookies: 2
Cookie Name: ASP.NET_SessionId
Cookie Version: 0
Cookie Value: ....
Cookie Path: /
Cookie Domain: intra.hva.dom
Cookie expires: 12:00:00 AM
Cookie Name: adAuthCookie
Cookie Version: 0
Cookie Value: .....
Cookie Path: /
Cookie Domain: intra.hva.dom
Cookie expires: 12:00:00 AM
Nämä keksit ovat jokaisessa haussa mukana. http://www.codeproject.com/Articles/49243/
Tutkin sivun avaamista FF:n tamper data lisäplugin avulla. Siinä ei ilmennyt mitään uutta. Alustava testi Selenium IDE:lltä tyssäsi menuvalikkoon.
Moi taas K_L!
testaa oheista viritelmää...
'ConsoleApp Imports System.IO Imports System.Text Imports System.Net Module Program Private baseURL As String = _ "http://aspspider.net/neoweb/Serv/" Sub Main() Dim request As HttpWebRequest = _ CType(WebRequest.Create(baseURL + _ "WrappedFramesetSub.aspx"), HttpWebRequest) Dim response As HttpWebResponse = _ CType(request.GetResponse(), System.Net.HttpWebResponse) Dim content As String = _ New StreamReader(response.GetResponseStream()).ReadToEnd() response.Close() If content.ToUpper.Contains("FRAMESET") Then Dim strArray() As String = content.Split(CType("'", Char)) Dim frameURL As String = String.Empty For i As Integer = 0 To strArray.Length -1 If strArray(i).Contains("Dyn/") Then If strArray(i).Contains("://") Then frameURL = strArray(i) Else frameURL = baseURL + strArray(i) End If Exit For End If Next If frameURL = String.Empty Console.WriteLine("No matching found") GoTo ExitProg End If Dim cookies As CookieContainer = New CookieContainer request = _ CType(WebRequest.Create(frameURL), HttpWebRequest) Dim postData As String = "terve=moro&moro=terve" request.UserAgent = _ "Mozilla/5.0 (Windows; U; Windows NT 5.1; fi; rv:1.9.0.5) " _ + "Gecko/2008120122 Firefox/3.0.5 (.NET CLR 3.5.30729)" request.Method = "POST" request.AllowAutoRedirect = True request.ContentType = "application/x-www-form-urlencoded" request.CookieContainer = cookies request.ContentLength = postData.Length Dim requestStream As Stream = request.GetRequestStream() Dim postBytes As Byte() = _ Encoding.Default.GetBytes(postData) requestStream.Write(postBytes, 0, postBytes.Length) requestStream.Close() postBytes = Nothing cookies = Nothing response = _ CType(request.GetResponse(), HttpWebResponse) response.Close For Each item As Cookie In response.Cookies With item If .Name = "location" Then Console.WriteLine(.Value): Exit For End If End With Next Else Console.WriteLine("Requested page has no frames") End If ExitProg: response = Nothing request = Nothing Console.Write("Press any key to continue . . . ") Console.ReadKey(True) End Sub End Module
<%@ Page Language="VB"%> <%@ Import Namespace="System.Web" %>