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 ModuleNea 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" %>