2010-05-30 2 views
3

나는 웹 서버에 POST 요청을 프로그래밍 방식으로 보내서 로그인 한 다음 로그인이 필요한 다른 요청을 수행하려고합니다. HttpWebRequest 응답은 HTTP 422를 생성합니다. 왜?

내 코드입니다 : 코드 화재의

//Get Response 
    StreamReader responseStreamReader = new 
    StreamReader(
     request.GetResponse().GetResponseStream()); //WebException: HTTP 422! 
    string content = responseStreamReader.ReadToEnd(); 

이 작품 : 요청

//Send post request 
    var requestStream = request.GetRequestStream(); 

    requestStream.Write(data, 0, data.Length); 
    requestStream.Flush(); 
    requestStream.Close(); 

을 보낸 후

byte[] data = Encoding.UTF8.GetBytes(
    String.Format(
     "login={0}&password={1}&authenticity_token={2}" 
     +"&login_submit=Entra&remember_me=1", 
     HttpUtility.UrlEncode(username), HttpUtility.UrlEncode(password), 
     HttpUtility.UrlEncode(token))); 

    //Create HTTP-request for login 
    HttpWebRequest request = 
      (HttpWebRequest)HttpWebRequest.Create("http://www.xxx.xx/xx/xx"); 

    request.Method = "POST"; 
    request.ContentType = "application/x-www-form-urlencoded"; 
    request.ContentLength = data.Length; 
    request.CookieContainer = new CookieContainer(); 

    request.Accept = "application/xml,application/xhtml+xml,text/html; 
        +"q=0.9,text/plain ;q=0.8,image/png,*/*;q=0.5"; 
    request.Referer = "http://www.garzantilinguistica.it/it/session"; 
    request.Headers.Add("Accept-Language", "de-DE"); 
    request.Headers.Add("Origin", "http://www.xxx.xx"); 
    request.UserAgent = "C#"; 
    request.Headers.Add("Accept-Encoding", "gzip, deflate"); 

... 나는 서버 응답을 얻으려면 서버가 HTTP 422 (의미 론적 오류로 인해 처리 할 수없는 엔터티)로 응답했다는 것을 나타내는 WebException s)

그런 다음 (TCP/IP 스니퍼를 사용하여) 내 프로그램과 브라우저 (올바른 POST 요청을 생성하고 적절한 응답을 얻음)의 요청을 비교했습니다.

(1) 내 프로그램의 요청을 :

POST /it/session HTTP/1.1 
Content-Type: application/x-www-form-urlencoded 
Accept: application/xml,application/xhtml+xml,text/html; 
q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5 
Referer: http://www.garzantilinguistica.it/it/session 
Accept-Language: de-DE 
Origin: http://www.garzantilinguistica.it 
User-Agent: Test 
Accept-Encoding: gzip, deflate 
Host: www.garzantilinguistica.it 
Content-Length: 148 
Expect: 100-continue 
Connection: Keep-Alive 


HTTP/1.1 100 Continue 


login=thespider14%40hotmail.com&password=xxxxx&authenticity_token=4vLgtwP3nFNg4NeuG4MbUnU7sy4z91Wi8WJXH0POFmg%3d&login_submit=Entra&remember_me=1 

(2) 브라우저의 요청 :

POST /it/session HTTP/1.1 
    Host: www.garzantilinguistica.it 
    Referer: http://www.garzantilinguistica.it/it/session 
    Accept: application/xml,application/xhtml+xml,text/html;q=0.9, 
text/plain;q=0.8,image/png,*/*;q=0.5 
    Accept-Language: de-DE 
    Origin: http://www.garzantilinguistica.it 
    User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; de-DE) AppleWebKit/531.22.7 (KHTML, like Gecko) Version/4.0.5 Safari/531.22.7 
    Accept-Encoding: gzip, deflate 
    Content-Type: application/x-www-form-urlencoded 
    Cookie: __utma=244184339.652523587.1275208707.1275208707.1275211298.2; __utmb=244184339.20.10.1275211298; __utmc=244184339; __utmz=244184339.1275208707.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); _garzanti2009_session=BAh7CDoPc2Vzc2lvbl9pZCIlZDg4MWZjNjg2YTRhZWE0NDQ0ZTJmMTU2YWY4ZTQ1NGU6EF9jc3JmX3Rva2VuIjFqRWdLdll3dTYwOTVVTEpNZkt6dG9jUCtaZ0o4V0FnV2V5ZnpuREx6QUlZPSIKZmxhc2hJQzonQWN0aW9uQ29udHJvbGxlcjo6Rmxhc2g6OkZsYXNoSGFzaHsGOgplcnJvciIVbG9naW4gbm9uIHZhbGlkbwY6CkB1c2VkewY7CFQ%3D--4200fa769898dd156faa49e457baf660cf068d08 
    Content-Length: 144 
    Connection: keep-alive 

authenticity_token=jEgKvYwu6095ULJMfKztocP%2BZgJ8WAgWeyfznDLzAIY%3D&login=thespider14%40hotmail.com&password=xxxxxx&remember_me=1&commit=Entra 
HTTP/1.1 302 Found 

누군가의 도움을 내가 없거나 무엇을 주 을하고있는 요청의 일부로 이해하는 수를 브라우저와 내 요청의 차이점은 무엇입니까? 왜 내가 422를 얻는거야?

는 편집 :

나는 브라우저하지 않는 반면 내 요청, 100-계속 값을 가지는 Expect 헤더를 포함 것으로 나타났습니다. request.Expect- 속성을 null""으로 설정했습니다. 그러나 나는 그걸 없앨 수 없었습니다. 어떤 제안? 이것이 모든 악의 근원이 되길 원합니까?

는 편집 :

마지막으로 나는 Expect -header를 제거했습니다. 그러나 도움이되지 않았습니다. 어떤 아이디어? 나는
request.CookieContainer = new CookieContainer(); 

을 설정하여 CookieContainer를 활성화하지만 난 HTTP-추적에서 쿠키 헤더를 볼 수 없습니다. 왜?

+0

첫 번째 HTTP 추적이 올바르다면 (이 게시물의 서식 지정 대상이 아님) 보내는 HTTP 본문을 볼 수 없습니다. 'Content-Length'는 111로 설정되어 있지만 응답 인 'http/1.1 100 Continue'만 보았습니다. '데이터'콘텐츠가 누락되었습니다. 두 번째 HTTP 추적에서 나는 'authentication_token'만 보았고 코드에서는 3 개의 변수를 사용했습니다. 422 코드는 '본문 내용의 잘못된 이스케이프'를 가리 킵니다. 아마 변수 중 하나를 엔티티로 읽으려고합니다. 어떤 기회에 ';' 문자가 문자열에서 이스케이프되지 않았습니까? –

+0

HttpUtility.UrlEncode()를 사용하여 내 변수에 포함 된 문자열을 이스케이프 처리했습니다. 그러나 여전히 성공하지 못했습니다. – Simon

답변

4

좋아, 나는 그것을 가지고있다.

두 가지 문제점이있었습니다.

  1. HTTP 1./ 100 1

    내가

  2. 때문에 쿠키 관련 문제의 422 와 repsonded 서버를 설정하여이 문제를 해결 계속합니다. POST 요청은 에 쿠키 컨테이너를 전송해야하며, 에는 현재 세션 ID의 쿠키가 포함되어 있어야합니다. 이 세션 ID가 이 전송되지 않으면 서버는 에 422로 응답합니다. 세션 ID로 쿠키를 가질 수 있으려면 로그인 페이지에서 간단한 HTTP 요청을 수행해야합니다. 이 요청은 필요한 세션 ID가있는 쿠키 컨테이너를 반환했습니다. 그런 다음 반환 된 쿠키 컨테이너를 POST 요청에 전달했습니다. 이와

//cookie container of previous request 
postRequest.CookieContainer = cookieContainer; 

는 POST 요청이 성공적으로 전송 될 수있는 설정을 선택합니다.

도움 주셔서 감사합니다.

1

=와 @를 올바르게 이스케이프 처리하지 않는 것 같습니다. 그것이 유일한 문제인지 확실하지 않습니다.

시도해 볼 수 있습니다 HttpUtility.UrlEncode.

+0

.NET에서 URL 인코딩을 어떻게 수행합니까? – Simon

+0

고마워요.하지만 여전히 성공은 없습니다. ( – Simon

+0

@ 사이먼, 코드와 출력을 업데이트하십시오. –