* de 1 à 3: file: jar: http: https: ftp:
* autres : http: https: (notamment webdav) uniquement.
*
*/
if (opened) {
throw new InterpreterException(StdErrors.extend(StdErrors.Already_used, "File already open"));
}
opened = true;
startAt.isGoodArgsLength(false, 2);
SELF.require_SELF_mutable();
ExtURL url = new ExtURL(startAt.getSubNode(1, Node.TYPE_STRING).getString());
/*
* déterminer le protocol pour la suite...
*/
protocol = url.getProtocol();
/*
* protocol peut être:
*
* - file :
* ----
* Dans ce cas, le fichier est ouvert en lecture seul.
* Il n'y a pas non plus ce commande comme dans le cas du http.
* Deuxième paramètre facultatif peut être "r" ou "w".
*
* Note:
* ----
* Dans le cas du mode "w", il s'agit d'une émualation parce que java n'implémente
* pas l'accès en écriture au travers du protocole file:.
*
* Rappel:
* ------
* Sous Windows, la forme de l'url utilisant le protocole file:// est hérité du Java.
* Ainsi, pour accéder à un fichier sur le disque dur C:, l'url pourra prendre les formes
* suivantes (c'est assez déroutant, il faut l'avouer):
* file:/C:\\dossier\\fichier.ext
* file:///C:\\dossier\\fichier.ext
* file:/C|\\dossier\\fichier.ext
* file:///C|\\dossier\\fichier.ext
* file:/C|/dossier/fichier.ext
* ou encore...
* file://C:/dossier/fichier.ext
*
* Sous Linux et Unix, la forme est plus claire:
* file:///home/utilisateur/fichier
*
* - jar :
* ---
* Dans ce cas, le fichier d'archive est toujours ouvert en lecture seul.
* Il n'y a pas de commande comme en http.
* Deuxième paramètre facultatif possible "r".
*
* - http ou https :
* -------------
* Dans ce cas, il faut prendre en compte les éventuels paramètres d'en-têtes et le request.
* En outre, même s'il y a écriture de données vers la sortie, il est nécessaire de lire le
* résultat de retour dans tous les cas.
*
* -> envoie de données (request : GET, POST, PUT)
* <- lecture du résultat (response).
*
* - ftp :
* ---
* Dans ce cas, il faut déterminer si l'url est ouverte en lecture ou en écriture.
* Il ne faut donc tenir compte que le deuxième paramètre puisse être "r" ou "w".
*
* Note:
* ----
* L'url d'accès ftp a la forme suivante: "ftp://<login>:<pass>@<server>/<path>".
*
* Attention:
* ---------
* Si l'url est ouverte en écriture, les nouvelles données envoyées écrasent celles qui
* étaient précédemment dans le fichier à partir du début.
*
*/
String mode = null;
Node props = null;
Node datas = null;
byte[] buffer = null;
String old_c = null; // paramètres timeOut
String old_r = null;
int max_i = startAt.size() - 1;
/*
* propriétés headers...
*/
if (startAt.elementAt(max_i).getSymbolicValue().getQType()==Node.TYPE_CLIST) {
// il y a des propriétés header...
// La gestion des erreurs est plus loin...
props = startAt.getSubNode(max_i--, Node.TYPE_HASH);
}
/*
* 2ième paramètres...
*/
int i_ = 2;
if (i_ <= max_i) {
/*
* il existe...
*/
mode = startAt.getSubNode(i_++, Node.TYPE_STRING).getString().toUpperCase().trim();
/*
* cas des protocoles http:// et https:// ...
*/
if (protocol.equalsIgnoreCase("http") || protocol.equalsIgnoreCase("https")) {
// GET, POST et PUT possible uniquement en http/https...
if (!(mode.equals("GET") || mode.equals("POST") || mode.equals("PUT"))) {
throw new InterpreterException(128010, "Unsupported request methode");
}
}
/*
* cas des protocoles ftp:// et file://...
*/
else if (protocol.equalsIgnoreCase("ftp") || protocol.equalsIgnoreCase("file")) {
if (!(mode.equalsIgnoreCase("r") || mode.equalsIgnoreCase("w"))) {
throw new InterpreterException(128015, "Unsupported access methode");
}
}
/*
* cas des protocoles jar:// et stdin://
*/
else if (protocol.equalsIgnoreCase("jar") || protocol.equalsIgnoreCase("stdin")) {
if (!(mode.equalsIgnoreCase("r"))) {
throw new InterpreterException(128015, "Unsupported access methode");
}
}
/*
* cas des protocoles tcp:// et ssl+tcp://
*/
else if (protocol.equalsIgnoreCase("tcp") || protocol.equalsIgnoreCase("ssl+tcp")) {
if (!(mode.equalsIgnoreCase("rw"))) {
throw new InterpreterException(128015, "Unsupported access methode");
}
}
/*
* cas des protocoles stdout:// stderr://
*/
else if (protocol.equalsIgnoreCase("stdout") || protocol.equalsIgnoreCase("stderr")) {
if (!(mode.equalsIgnoreCase("w"))) {
throw new InterpreterException(128015, "Unsupported access methode");
}
}
/*
* autre non supporté....
*/
else {
throw new InterpreterException(128011, "Unsupported protocol");
}
}
/*
* des données à envoyer ? Uniquement pour http/https...
*/
if (i_ <= max_i) {
if (!protocol.equalsIgnoreCase("http") && !protocol.equalsIgnoreCase("https")) {
// uniquement possible avec le protocole http/https...
throw new InterpreterException(128016, "Unsupported request datas");
}
// datas...
datas = startAt.getSubNode(i_++, Node.TYPE_STRING | Node.TYPE_BYTES | Node.VTYPE_DELEGABLE);
buffer = Node.node2VBytes(datas).getBytes().getArray();
}
/*
* gestion d'erreurs: http GET envoie des données ????
*/
if (datas != null && mode != null && mode.equals("GET")) {
throw new InterpreterException(128012, "GET request with data body");
}
/*
* gestion d'erreur: des propriétés d'en-tête avec un autre protocol que http/https ????
*/
if (props != null && (!protocol.equalsIgnoreCase("http") && !protocol.equalsIgnoreCase("https"))) {
throw new InterpreterException(128013, "Cannot handle header properties in request");
}
try {
/*
* d'abord les protocoles émulés...
*/
/**
* cas particulier de file:// en écriture...
*
* Il s'agit d'une émulation...
*
*/
if (protocol.equalsIgnoreCase("file") && mode != null && mode.equalsIgnoreCase("w")) {
File f = new File(url.toURI());
output = new FileOutputStream(f);
this.setOptAccessList(new OptAccessList(this.getDEFAULT_OPTIONS()));
this.getOptAccessList().add(oa_Protocol);
}
/**
* cas de tcp://
*/
else if (protocol.equalsIgnoreCase("tcp")) {
tcpHost = url.getHost();
tcpPort = url.getPort();
if (tcpPort < 0 || tcpPort > 65535) {
throw new InterpreterException(StdErrors.extend(StdErrors.Out_of_range, "" + tcpPort));
}
//System.out.println("host:"+tcpHost); // debug
//System.out.println("port:"+tcpPort); // debug
socket = new Socket(tcpHost, tcpPort);
if (readTimeOut > 0) {
socket.setSoTimeout(readTimeOut);
}
tcpIP = socket.getInetAddress().getHostAddress();
tcpHost = socket.getInetAddress().getHostName();
input = socket.getInputStream();
output = socket.getOutputStream();
this.setOptAccessList(new OptAccessList(this.getSOCKET_OPTIONS()));
this.getOptAccessList().set(oa_Host);
this.getOptAccessList().set(oa_IP);
this.getOptAccessList().set(oa_Port);
}
/**
* cas de ssl+tcp://
*/
else if (protocol.equalsIgnoreCase("ssl+tcp")) {
tcpHost = url.getHost();
tcpPort = url.getPort();
if (tcpPort < 0 || tcpPort > 65535) {
throw new InterpreterException(StdErrors.extend(StdErrors.Out_of_range, "" + tcpPort));
}
SocketFactory socketFactory = SSLSocketFactory.getDefault();
socket = socketFactory.createSocket(tcpHost, tcpPort);
if (readTimeOut > 0) {
socket.setSoTimeout(readTimeOut);