HTTP Request nachbauen - Verständnis

Hallo :slight_smile:
ich versuche gerade meinen FIFA Ultimate Team Client upzudaten.
Hat bisher mal alles funktioniert aber habe lange das Programm nicht mehr genutzt und es hat sich wohl einiges getan beim Ablauf.
Ich baue die HTTP Anfragen, die die WebApp entsendet, in meinem Java Programm einfach nach.
Nur verstehe ich die Anfrage irgendwie nicht mehr.
Es scheitert zurzeit am Login.
Zunächst gehe ich auf folgende URL: http://www.easports.com/de/fifa/football-club/ultimate-team
Werde dann aber im Browser schon auf : http://www.easports.com/de/fifa/football-club/login? weitergeleitet.
Naja soweit so gut:
Wenn ich mich mit der zweiten Adresse im Browser einlogge und die HTTP-Abfragen in FireFox mitlese, sehe ich, dass sich zunächst zu :
200 OK
verbunden wird

So und ab dort fangen die Probleme an.
Dort steht im HTTP Header unter anderem redirectURL=
Also nehme ich mal an, dass wenn man versucht die /authenticate/login URL aufzurufen, weitergeleitet wird an die URL die dort in der redirectURL definiert ist (Sind sogar mehrere) Unter anderem ist dort die Adresse zu besagtem UltimateTeam spiel und benutzername und Passwort in der URL angehängt.
Versuche ich mich nun über mein Java Programm, unter Beachtung der benötigten Cookies, an diese Adresse zu verbinden, kommt dabei nichts heraus(FileNotFoundException und im Browser kriege ich einen 404-Error)
Kurz gesagt, ich kann irgendwie den Ablauf nicht nachvollziehen wie der Login sich gerade verhält, früher war es ohne irgendwelche Weiterleitungen.

Hier nochmal der Header:


https://www.easports.com/de/fifa/football-club/services/authenticate/login

POST /de/fifa/football-club/services/authenticate/login HTTP/1.1
Host: www.easports.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:22.0) Gecko/20100101 Firefox/22.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: de-de,de;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://www.easports.com/de/fifa/football-club/login?redirectUrl=http://www.easports.com/de/fifa/football-club/ultimate-team
Cookie: EASW_KEY=a7fd90d9-447f-48a2-b9d7-302bf0b6462c; easf_sess_com=e0d0014c63fbf36edb5176f94cbedb45:6fe98d21344d938359266b90e2738dd5414a3dbd; __utma=242180630.159915374.1377330295.1377330628.1377330628.1; __utmb=242180630.1.10.1377330628; __utmc=242180630; __utmz=242180630.1377330628.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); s_sivo=DE%3AEASFW%3ANONE; s_cc=true; s_ria=flash%2011%7Csilverlight%20not%20detected; s_pv=EMEA%3ADE%3ASPORTS%3AEAC%3AMKT%3ANONE%3AEASFW%3ANONE%3ALOGIN; s_nr1=1377330627868-NEW; s_sq=%5B%5BB%5D%5D; s_ppv=44; _chartbeat2=5v18d6k04kywmzuu.1377329905385.1377330628701.1; PHPSESSID=fa46jou2jhphja7af9o6gkc074; optimizelySegments=%7B%22172316047%22%3A%22ff%22%2C%22265568016%22%3A%22true%22%2C%22172207507%22%3A%22false%22%2C%22172202804%22%3A%22direct%22%2C%22172174479%22%3A%22none%22%7D; optimizelyEndUserId=oeu1377330295093r0.6058830804443761; optimizelyBuckets=%7B%7D; utag_main=_st:1377332426675$ses_id:1377330625303%3Bexp-session; _ga=GA1.2.159915374.1377330295; easports_sess_com=730f1cd11e9f5a3af7d356b15ac2e7a0:e37135eac2c8148fbc24e1867c7daa25c8032147
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 553
redirectUrl=http%3A%2F%2Fwww.easports.com%2Fde%2Ffifa%2Ffootball-club%2Fultimate-team&failureUrl=http%3A%2F%2Fwww.easports.com%2Fde%2Ffifa%2Ffootball-club%2Flogin%3Ffailed%3Dtrue%26redirectUrl%3Dhttp%253A%252F%252Fwww.easports.com%252Fde%252Ffifa%252Ffootball-club%252Fultimate-team&captchaFailureUrl=http%3A%2F%2Fwww.easports.com%2Fde%2Ffifa%2Ffootball-club%2Flogin%3Ffailed%3Dtrue%26redirectUrl%3Dhttp%253A%252F%252Fwww.easports.com%252Fde%252Ffifa%252Ffootball-club%252Fultimate-team&email=HIER_STEHT_DIE_EMAIL&password=UND_HIER_DAS_PASSWORT&stay-signed=ON
HTTP/1.1 302 Moved Temporarily
Date: Sat, 24 Aug 2013 07:50:39 GMT
Server: EASW
Cache-Control: max-age=0, no-cache, no-store
Location: http://www.easports.com/de/fifa/football-club/ultimate-team
Content-Encoding: gzip
Vary: Accept-Encoding
Content-Type: text/html;charset=utf-8
Set-Cookie: EASW_KEY=a7fd90d9-447f-48a2-b9d7-302bf0b6462c; Domain=www.easports.com; Expires=Sat, 24-Aug-13 09:50:38 GMT; Path=/; HttpOnly
Set-Cookie: EASF_PERSIST=2a2bd283-2009-6e2b-5a15-8c1927fded76; Domain=www.easports.com; Expires=Sun, 08-Sep-2013 07:50:38 GMT; Path=/
nnCoection: close
Transfer-Encoding: chunked

Kurz gesagt: Was passiert dort eigentlich, wenn ich im Browser auf Login klicke :slight_smile:
Ich habe es ja schon mal geschafft nachzubauen, allerdings verstehe ich gerade eben nur nicht, was ich eigentlich nachbauen muss xD

Ich hoffe ich konnte mein Problem erklären :slight_smile:
Vielen Dank für die Hilfe im Vorraus

nimm dir einfach wireshark und bau den kompletten request nach

bei youtube gehts ähnlich lustig zu

um von youtube.com über den button login wieder auf youtube.com zu landen hat man mal eben bis zu 9 requests, mal den initial, final und login-request nicht mitgezählt

das ganze sieht dann so aus

import java.net.*;
import java.util.*;
import java.util.regex.*;
public class YouTubeLogin
{
 private static HashMap<String, String> cookies=new HashMap<String, String>();
 public static void main(String[] args) throws Exception
 {
  System.out.println(getAuthToken(args[0], args[1]));
 }
 public static String getAuthToken(String user, String pass) throws Exception
 {
  String ytContent=getContent("http://www.youtube.com");
  Pattern pattern=Pattern.compile("<a.*?href=\"(.+?)\".*?>Anmelden.*?");
  Matcher matcher=pattern.matcher(ytContent);
  String loginURL;
  if(matcher.find())
  {
   loginURL=matcher.group(1).replace("&", "&");
  }
  else
  {
   throw new NullPointerException("loginURL == null");
  }
  
  String loginContent=getContent(loginURL);
  pattern=Pattern.compile("(?s)(<form.+?form>)");
  matcher=pattern.matcher(loginContent);
  String formContent;
  if(matcher.find())
  {
   formContent=matcher.group(1);
  }
  else
  {
   throw new NullPointerException("formContent == null");
  }
  ArrayList<String> tagList=parseForm(formContent);
  String postData=createPostData(tagList);
  
  pattern=Pattern.compile("action=\"(.+?)\"");
  matcher=pattern.matcher(formContent);
  String authURL;
  if(matcher.find())
  {
   authURL=matcher.group(1);
  }
  else
  {
   throw new NullPointerException("authURL == null");
  }
  StringBuilder sb=new StringBuilder();
  sb.append("Email=");
  sb.append(URLEncoder.encode(user, "UTF-8"));
  String email=sb.toString();
  sb=new StringBuilder();
  sb.append("Passwd=");
  sb.append(URLEncoder.encode(pass, "UTF-8"));
  String passwd=sb.toString();
  postData=postData.replace("Email=", email).replace("Passwd=", passwd);
  
  String authContent=postContent(authURL, postData);
  String checkContent=getContent(authContent);
  String movedContent=getContent(checkContent);
  String accountContent=getContent(movedContent);
  accountContent=accountContent.replace("'", "\"");
  pattern=Pattern.compile("url=\"(.+?)\"");
  matcher=pattern.matcher(accountContent);
  String redirectURL;
  if(matcher.find())
  {
   redirectURL=matcher.group(1).replace("%3B", ";").replace("&", "&").replace("&", "&");
  }
  else
  {
   throw new NullPointerException("redirectURL == null");
  }
  String redirectContent=getContent(redirectURL);
  String linkContent=getContent(redirectContent);
  return createCookieString();
 }
 private static String postContent(String url, String postData) throws Exception
 {
  HttpURLConnection con=(HttpURLConnection)(new URL(url)).openConnection();
  con.setRequestMethod("POST");
  con.setDoOutput(true);
  con.setDoInput(true);
  con.setUseCaches(false);
  con.setInstanceFollowRedirects(false);
  con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
  con.setRequestProperty("Cookie", createCookieString());
  con.connect();
  DataOutputStream out=new DataOutputStream(con.getOutputStream());
  out.writeBytes(postData);
  out.flush();
  out.close();
  handleCookies(con.getHeaderFields());
  InputStream in=con.getInputStream();
  ByteArrayOutputStream baos=new ByteArrayOutputStream();
  int b=0;
  byte[] buf=new byte[0x100000];
  while((b=in.read(buf))!=-1)
  {
   baos.write(buf, 0, b);
  }
  in.close();
  if((con.getResponseCode()&300)==300)
  {
   return con.getHeaderField("Location");
  }
  return baos.toString();
 }
 private static String createPostData(ArrayList<String> tagList) throws Exception
 {
  HashMap<String, String> postMap=new HashMap<String, String>();
  for(String tag : tagList)
  {
   Pattern pattern=Pattern.compile("name=\"(.+?)\"");
   Matcher matcher=pattern.matcher(tag);
   if(matcher.find())
   {
    String name=matcher.group(1);
    pattern=Pattern.compile("value=\"(.+?)\"");
    matcher=pattern.matcher(tag);
    if(matcher.find())
    {
     String value=matcher.group(1);
     postMap.put(name, value);
    }
    else
    {
     postMap.put(name, "");
    }
   }
  }
  Set<String> names=postMap.keySet();
  StringBuilder sb=new StringBuilder();
  for(String name : names)
  {
   sb.append(URLEncoder.encode(name, "UTF-8"));
   sb.append("=");
   sb.append(URLEncoder.encode(postMap.get(name), "UTF-8"));
   sb.append("&");
  }
  String post=sb.toString();
  return post.substring(0, post.lastIndexOf("&"));
 }
 private static ArrayList<String> parseForm(String formContent) throws Exception
 {
  Pattern pattern=Pattern.compile("(?s)(<.+?>)");
  Matcher matcher=pattern.matcher(formContent);
  ArrayList<String> tagList=new ArrayList<String>();
  while(matcher.find())
  {
   if(matcher.group(1).contains("input"))
   {
    tagList.add(matcher.group(1).replaceAll("[\\s{2](file://\\s{2),}", " "));
   }
  }
  return tagList;
 }
 private static String getContent(String url) throws Exception
 {
  HttpURLConnection con=(HttpURLConnection)(new URL(url)).openConnection();
  con.setRequestMethod("GET");
  con.setDoOutput(false);
  con.setDoInput(true);
  con.setUseCaches(false);
  con.setInstanceFollowRedirects(false);
  con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
  con.setRequestProperty("Cookie", createCookieString());
  con.connect();
  handleCookies(con.getHeaderFields());
  InputStream in=con.getInputStream();
  ByteArrayOutputStream baos=new ByteArrayOutputStream();
  int b=0;
  byte[] buf=new byte[0x100000];
  while((b=in.read(buf))!=-1)
  {
   baos.write(buf, 0, b);
  }
  in.close();
  if((con.getResponseCode()&300)==300)
  {
   return con.getHeaderField("Location");
  }
  return baos.toString();
 }
 private static String createCookieString() throws Exception
 {
  StringBuilder sb=new StringBuilder();
  Set<String> names=cookies.keySet();
  for(String name : names)
  {
   String value=cookies.get(name);
   sb.append(name);
   sb.append("=");
   sb.append(value);
   sb.append("; ");
  }
  String cookie=sb.toString();
  return cookie.length()==0 ? "" : cookie.substring(0, cookie.lastIndexOf(";"));
 }
 private static void handleCookies(Map<String, List<String>> headerMap) throws Exception
 {
  Set<String> headerNames=headerMap.keySet();
  for(String headerName : headerNames)
  {
   List<String> headers=headerMap.get(headerName);
   if("Set-Cookie".equals(headerName))
   {
    for(String header : headers)
    {
     String name=header.substring(0, header.indexOf("="));
     String value=header.substring(header.indexOf("=")+1, header.indexOf(";"));
     cookies.put(name, value);
    }
   }
  }
 }
}```
 
ich weis , kann man noch optimieren, aber so läufts halt
 
 
für die entsprechende seite kann man sicher auch was passendes bauen, bräuchte man aber login-daten für

sry für doppel-post , aber :

könnte mal irgendjemand dem parser beibringen innerhalb von code-tags KEINE URL-tags einzubauen ? so schwer kanns doch nicht sein , n flag das open-code-tag gefunden wurde und dann erst wieder togglen wenn das passende close-code-tag gefunden wurden, und im url-parser einfach ein if auf das flag

Hab jetzt mal die Anfrage mit Wireshark mitgelesen, aber werde dadurch irgendwie nicht schlauer.
Komisch finde ich auch, dass im Cookie ein EASW-Key übergeben werden soll, aber in der SetCookie Location genau jener EASW-Key erst gesetzt wird.
Das sehe ich wenn ich im HTTP-Bereich auf die Cookiezeile rechtsklicke und Follow TCP Stream anklicke.
Hab mit Wireshark auch noch nie gearbeitet, hast du da vielleicht Tipps zur Herangehensweise?
Bekomme ich übrigens auch die ungekürzte Fassung der Cookiezeile?
Denn da steht truncated voran.

Vielen Dank aber schon mal für die Hilfe :slight_smile: