0) ? (new String(ch,0,a))+"\n" : "";
// Corps vide ou terminé par un seul '/n'
corps = (new String(corps)).trim().getBytes();
return txtErr;
} // fin norme()
} // fin class RqtRepHttp
/** Enregistre le corps d'une réponse dans un fichier */
class RfxEnregistreCorps implements ActionListener {
EtudeHttp fen;
RfxEnregistreCorps(EtudeHttp f) { fen = f; }
public void actionPerformed(ActionEvent e) {
String nfic=fen.c_ficHtml.getText();
File f= new File(fen.c_ficHtml.getText());
try {
FileOutputStream fic=new FileOutputStream(f);
fic.write(fen.txtFen[fen.cliOuSer].rep.corps);
fic.close();
}
catch(IOException ex){
fen.e_qqinfo.setText("pb avec fichier "+nfic);
EtudeHttp.a("RfxEnregistreCorps, fichier ",ex);
}
}
}
/** Envoie la requête tapée dans l'état 'Je suis CLIENT', récupère et affiche
* le résultat.
*/
class RfxEnvoieRequete implements ActionListener {
EtudeHttp fen;
RfxEnvoieRequete(EtudeHttp f) {fen=f; }
public void actionPerformed(ActionEvent e) {
TxtFen tF=fen.txtFen[fen.CLIENT];
tF.qqinfo = ""; tF.rqt=new RqtRepHttp(); tF.rep=new RqtRepHttp();
Button b=(Button)e.getSource();
if(b.getLabel().equals(fen.txtFen[fen.CLIENT].rqtClient)) {
// On récupère commande, en-tête et corps;
tF.rqt.prem = fen.c_cmd.getText();
tF.rqt.entete = fen.t_entrqt.getText();
tF.rqt.corps = fen.t_corrqt.getText().getBytes();
tF.qqinfo = tF.rqt.norme();
// On récupère machine et port
String machine=fen.c_machine.getText();
String ch_port=fen.c_port.getText();
tF.machine = machine;
int port=0; tF.port = ch_port;
try { port=Integer.parseInt(ch_port); }
catch(Exception exc) {
tF.qqinfo = tF.qqinfo + " | numéro de port incorrect: "+ch_port;
}
// Envoie effectif et affichages
if(tF.qqinfo.length() == 0) {
tF.rep = ReponseHttp.envoieRqt( machine, port, tF.rqt);
tF.qqinfo = tF.rep.msg;
// EtudeHttp.a_(tF.rep.prem); EtudeHttp.a_(tF.rep.entete);
}
else { tF.rep=new RqtRepHttp(); }
}
fen.affRqtRep(fen.CLIENT);
fen.validate();
}
} // fin class RfxEnvoieRequete implements ActionListener
// Partie serveur Http
//////////////////////
/** Création d'un serveur qui écoute sur le port 'p'
*/
class MonServeur extends Thread {
int portEcoute;
ServerSocket ecoute;
// EtudeHttp fen; // pour fournir au traitement de réponse
// Lance un serveur qui va écouter sur p
// MonServeur(int p, EtudeHttp f) throws IOException {
MonServeur(int p) throws IOException {
// fen=f;
portEcoute=p;
ecoute = new ServerSocket(portEcoute);
start();
}
/* Attente des appels clients;
sur un appel: ouvrir une socket, répondre au client(objet ReponseHttp)
*/
public void run() {
try {
while(true) {
Socket socVClient = ecoute.accept();
EtudeHttp.a_("MonServeur: réponse vers:"+
socVClient.getInetAddress()+":"+socVClient.getPort());
// ReponseHttp c = new ReponseHttp(socVClient, fen);
ReponseHttp c = new ReponseHttp(socVClient);
}
}
catch(IOException e){EtudeHttp.a("Traitement client",e); }
}
} // fin class MonServeur extends Thread
class MonServeurF extends MonServeur {
EtudeHttp fen; // pour fournir au traitement de réponse
// Lance un serveur qui va écouter sur p
MonServeurF(int p, EtudeHttp f) throws IOException {
super(p);
fen=f;
}
/* Attente des appels clients;
sur un appel: ouvrir une socket, répondre au client(objet ReponseHttp)
*/
public void run() {
try {
while(true) {
Socket socVClient = ecoute.accept();
EtudeHttp.a_("MonServeur: réponse vers:"+
socVClient.getInetAddress()+":"+socVClient.getPort());
ReponseHttpF c = new ReponseHttpF(socVClient, fen);
}
}
catch(IOException e){EtudeHttp.a("Traitement client",e); }
}
} // fin class MonServeurF extends Thread
/** Traitement d'une réponse à un client */
class ReponseHttp extends Thread {
Socket socSurSeveur;
OutputStream versClient;
BufferedReader depuisClient;
ReponseHttp(Socket cl) {
socSurSeveur=cl;
try {
versClient = socSurSeveur.getOutputStream();
depuisClient = new BufferedReader(
new InputStreamReader(socSurSeveur.getInputStream()));
}
catch(IOException e){EtudeHttp.a("Création flot vers client",e); }
this.start();
}
/** Récupère la requête et y répond
si l'URL est de la forme http://127.0.0.1:8383//machine:80/index.html?a=9
alors le serveur sert de passerelle: il redirige la requête vers
machine:80, intercepte la réponse pour affichage, et la renvoie
au client.
*/
public void run() {
String msgErr="";
RqtRepHttp rqt=new RqtRepHttp(), rep=new RqtRepHttp();
// Récupérer la requête, y répondre ou la faire suivre (cas passerelle)
try {
//
msgErr = recupRqt(depuisClient,rqt);
// on prépare la réponse (corps avant en-tête
// afin de pouvoir connnaître Content-length) et on l'envoie
creeReponse(rqt,rep);
}
catch(IOException e){EtudeHttp.a("Réception depuis client",e); }
finally { try { socSurSeveur.close(); } catch(IOException e){}; }
} // fin run()
static String recupRqt(BufferedReader f, RqtRepHttp rqt) throws IOException {
String msgErr=""; String ligne;
rqt.prem = f.readLine();
// Récupérer l'en-tête
rqt.entete="";
ligne = f.readLine();
if(ligne==null) { msgErr="Requête incorrecte"; }
else { // on cherche l'en-tête
String attLong = "Content-Length: ", attType = "Content-Type: ";
int lgCorps = 0;
boolean estTexte = false;
while (ligne.length() > 0) {
// Attribut longueur ou type
if (ligne.indexOf(attLong) >= 0) {
lgCorps = Integer.parseInt(ligne.substring(attLong.length()));
}
else if (ligne.indexOf(attType) >= 0) {
rqt.typeCorps = ligne.substring(attType.length());
estTexte = ligne.indexOf("text/") >= 0;
}
rqt.entete += ligne + "\n";
ligne = f.readLine();
}
// Récupérer le corps
byte corOct[] = new byte[lgCorps];
for (int i = 0; i < lgCorps; i++)
corOct[i] = (byte) f.read();
rqt.corps = corOct;
}
return msgErr;
} // fin recupRqt
static void creeReponse(RqtRepHttp rqt, RqtRepHttp rep) {
rep.prem="HTTP/1.0 200 OK";
rep.typeCorps="text/html";
rep.corps=("Reponse de Mapomme\n"
+"\n"
+"Merci pour votre appel
du "+EtudeHttp.date()+"
\n"
+"J'ai recu:
"+rqt.prem+"\n"+rqt.entete+"
\n"
+"\n").getBytes();
rep.entete = "Serveur: Mapomme\n"+"Content-Length:"+rep.corps.length+"\n";
rep.msg="";
}
// Partie client Http
/////////////////////
/** Envoie d'une requête vers mac sur le port port et renvoie la réponse rep
Si envoie échoue rep.msg est non vide
*/
public static RqtRepHttp envoieRqt(String mac, int port, RqtRepHttp rqt) {
RqtRepHttp rep= new RqtRepHttp();
Socket uneSoc=null;
int lgCorps=0; boolean estTexte=false;
try{ uneSoc = new Socket(mac,port); }
catch(IOException e){
rep.msg = "Erreur création socket vers "+mac+':'+port;
return rep;
}
try {
// Envoyer la requête, récupérer la réponse
rep.msg="Erreur création flots vers/depuis socket";
PrintStream versServeur = new PrintStream(uneSoc.getOutputStream());
versServeur.print(rqt.prem+"\n"+rqt.entete+"\n"+rqt.corps);
InputStream depuisServeur = uneSoc.getInputStream();
rep.msg="Problème pendant lecture de l'en-tête";
lgCorps = recupEtatEntete( depuisServeur, rep);
estTexte = rep.typeCorps.indexOf("text") >= 0;
// Corps jusqu'à la fin
rep.msg="Problème pendant lecture du corps";
byte corOct[]= new byte[lgCorps];
for(int i=0; i= 0) {
lgCorps=Integer.parseInt(ligne.substring(attLong.length()));
}
else if (ligne.indexOf(attType) >= 0) {
rep.typeCorps = ligne.substring(attType.length());
}
rep.entete += ligne+"\n";
n=0; do b[n++]=(byte) f.read(); while(b[n - 1] != RC);
}
return lgCorps;
}
} // fin class ReponseHttp extends Thread
/** Traitement d'une réponse à un client */
class ReponseHttpF extends ReponseHttp {
EtudeHttp fen;
ReponseHttpF(Socket cl, EtudeHttp f) {
super(cl);
fen=f;
try {
versClient = socSurSeveur.getOutputStream();
depuisClient = new BufferedReader(
new InputStreamReader(socSurSeveur.getInputStream()));
}
catch(IOException e){EtudeHttp.a("Création flot vers client",e); }
// this.start();
}
/** Récupère la requête et y répond
si l'URL est de la forme http://127.0.0.1:8383//machine:80/index.html?a=9
alors le serveur sert de passerelle: il redirige la requête vers
machine:80, intercepte la réponse pour affichage, et la renvoie
au client.
*/
public void run() {
String msgErr="", macPortSer="", mac="";
String tChaine[] = new String[] {"","",""};
RqtRepHttp rqt=new RqtRepHttp(), rep=new RqtRepHttp();
int port=0; boolean estPasserelle=false; // passerelle ou simple serveur
// Récupérer la requête, y répondre ou la faire suivre (cas passerelle)
try {
// La commande; y-a-t-il indication d'un serveur ?
msgErr = recupRqt(depuisClient,rqt);
port = extraitMacPortSer(rqt.prem,tChaine);
estPasserelle = (port>0);
// si indication, la commande change
rqt.prem=tChaine[0]; macPortSer=tChaine[1]; mac=tChaine[2];
EtudeHttp.a_(":"+rqt.prem+", :"+macPortSer+", :"+port);
if(estPasserelle) {
// On sert de passerelle, donc on envoie cette requête à macPortSer
// modifier la commande et l'entête (changer serveur - Host:)
rqt.entete=this.modifEntete(rqt.entete,macPortSer);
EtudeHttp.a_(":"+rqt.entete+", :"+mac+":"+port);
rep = ReponseHttp.envoieRqt(mac,port,rqt);
}
else {
// Pas d'autre serveur: on prépare la réponse (corps avant en-tête
creeReponse(rqt,rep);
}
versClient.write((rep.prem+"\n"+rep.entete+"\n").getBytes());
versClient.write(rep.corps);
// flotVersClient.write(rep.corps);
versClient.close();
rep.msg="";
}
catch(IOException e){EtudeHttp.a("Réception depuis client",e); }
finally { try { socSurSeveur.close(); } catch(IOException e){}; }
fen.txtFen[fen.SERVEUR].rqt=rqt;
fen.txtFen[fen.SERVEUR].rep=rep;
fen.txtFen[fen.SERVEUR].qqinfo=msgErr;
fen.affRqtRep(fen.SERVEUR + (estPasserelle?1:0));
} // fin run()
/**
* @param cmd commande avec pseudo-url éventuelle
* @param tC[0]=nouvelle commande; tc[1]=machine:port; tc[2]=machine
* @return port=0 si pas de pseudo-url
* port=80 si machine et pas d'indication de port
*/
static int extraitMacPortSer(String cmd, String tC[]) {
int pesp, port; String h="Host:", macPortSer="", mac="";
port=0;
pesp = cmd.indexOf(" ")+1;
if(pesp>=0) {
macPortSer=cmd.substring(pesp);
// EtudeHttp.a_("ressource:"+macPortSer);
if(macPortSer.indexOf("//")==0) {
// il existe une indication de machine; extraire nom de machine
macPortSer = macPortSer.substring(2,macPortSer.indexOf("/",3));
// nouvelle commande
String ch = cmd.substring(3+pesp+macPortSer.length());
tC[0] = cmd.substring(0,pesp+1)+ch;
// mac = nom de machine : numéro de port
mac= macPortSer;
int pdp = macPortSer.indexOf(":");
if(pdp >= 0) {
port = Integer.parseInt(macPortSer.substring(pdp + 1));
mac = macPortSer.substring(0,pdp); // mac réduit à la machine
}
else port=80;
}
else { tC[0]=cmd; macPortSer=""; }
}
tC[1]=macPortSer; tC[2]=mac;
return port;
}
/** modifier l'entête (changer serveur - Host:) */
static String modifEntete(String entete, String macPort) {
String h="Host:", e=""; // entete modifie
int pah, prc, pmsp; // position après Host: et de machine:port
pah = entete.indexOf(h)+h.length();
prc = entete.indexOf("\n",pah);
if(pah
// fin