Página 1 de 2

Creación de un servicio web usando JSON

NotaPublicado: 2014-11-05 12:30 @563
por jero2528
Un cordial saludo.

Alguien que me pueda orientar sobre cómo desarrollar un servicio web en Perl, haciendo uso de Apache. Estuve indagando y lo más cercano que encontré a lo que quiero hacer es algo como esto:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. use JSON;
  2. use Data::Dumper;
  3.  
  4. $json = '{"nombre":"jero2528","ip":"200.1.223.58","interfaz":"GigabitEthernet1","serviceid":99998,"accion":"cancelar"}';
  5.  
  6. $text = decode_json($json);
  7. print  Dumper($text);
  8.  
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4


Básicamente quiero recibir como parámetro el JSON indicado anteriormente, pero no sé cómo hacer para guardar por ejemplo este .pl y que sea accesible desde la web. Mi idea es usar una función que reciba como parámetro el JSON, pero no logro entender cómo hacer que desde un cliente.pl le pueda enviar el JSON como parámetro y ese servicio web me lo reciba y haga ciertas tareas como cancelar, reactivar y suspender servicios. ¿Cómo lo publico en el servidor Apache? Estoy usando XAMPP, Strawberry en Windows 7 y trabajo desde mi máquina de forma local, pero no sé cómo hacer para simular lo indicado.

Perdón si me extendí mucho, espero me puedan ayudar :)

Saludos,

Jero2528

Re: Creación de un servicio web usando JSON

NotaPublicado: 2014-11-05 14:38 @651
por explorer
La forma más sencilla es que coloques el programa en la carpeta cgi-bin/ del Apache. De esa manera, el diálogo entre Apache y este programa seguirá el protocolo CGI.

Usa el sistema de búsqueda de este foro, hay muchas referencias a lo que es un CGI y a cómo hacerlo desde Perl. Y varios CGI completos. Por ejemplo: la configuración CGI para el Apache (el XAMPP suele hacer estos pasos por ti, por lo que solo tienes que colocar el programa en la carpeta adecuada). Y luego lo ejecutas con http://localhost/cgi-bin/programa.pl

El servidor web debe estar preparado para entender que cuando el usuario solicita acceso al programa, lo debe ejecutar, y esperar una salida, que será lo que finalmente envíe al usuario.

Puedes hacer pruebas con mi CGI mínimo. En tu caso, lo que quieres entregar es un JSON, por lo que la cabecera HTTP deberá ser application/json en lugar de la tradicional text/html.

Re: Creación de un servicio web usando JSON

NotaPublicado: 2014-11-05 15:11 @674
por jero2528
Gracias, explorer.

Me sirvió bastante. Ahora tengo una duda: ¿cómo haces para pasar los parámetros?
En realidad ahora no sé cómo hacer para pasarle un parámetro al CGI mínimo.pl

¿Funciona capturarlo con shift()?

Basado en tu ejemplo:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. # Aquí sacamos la lista de los parámetros
  2. # en caso de que le haya sido pasado alguno
  3. my @parametros = param();
  4. foreach my $par ( @parametros ) {
  5.         print p($par);
  6.         print blockquote(param( $par ));
  7. }
  8.  
  9. print end_html;
  10.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


¿De qué manera puede entender como parámetro un JSON completo?

Re: Creación de un servicio web usando JSON

NotaPublicado: 2014-11-06 03:13 @176
por explorer
Los parámetros se pueden pasar en el URL:

http://localhost/cgi-bin/programa.pl?pa ... ar3=valor3

Esto es para cuando en el formulario que lanza esta petición tiene definido el método GET. Si el formulario tiene el método POST entonces el cliente HTML formatea los parámetros y los pasa en el cuerpo de la petición, que llega al programa por la entrada estándar.

De todas maneras, en el programa no hay que hacer ninguna modificación: tanto si llegan por GET o por POST, el módulo CGI se encarga de sacarlos para que luego sea fácil sacarlos con param().

Un JSON es un trozo de código en formato JavaScript, pero sigue siendo texto, así que lo recibiremos tal cual se envió.

Re: Creación de un servicio web usando JSON

NotaPublicado: 2014-11-06 08:51 @410
por jero2528
Gracias nuevamente, explorer.

Me ha funcionado perfectamente para lo que requería, muchísimas gracias por tu ayuda, ahora pido consejos donde pueda aprender más sobre la sintaxis que usan en el print con HTML:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. print
  2.     header,
  3.     start_html('CGI MINIMO'),
  4.     h1('CGI MINIMO'),
  5.     hr,
  6.     p('Si ves este texto es que SÍ está funcionando bien.'),
  7.     hr;
  8.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Hasta ahora me entero que se puede trabajar de esa forma, agradezco la información al respecto :) :oops:

Re: Creación de un servicio web usando JSON

NotaPublicado: 2014-11-06 16:33 @731
por explorer
Están descritas en el manual de módulo CGI. En tu propio ordenador, con perldoc CGI

Re: Creación de un servicio web usando JSON

NotaPublicado: 2014-11-11 09:34 @440
por jero2528
Muchas gracias, explorer.

Estuve revisando y realicé lo que quería en mi máquina local usando Strawberry y lo demás que indiqué antes. Ahora tengo problemas en el servidor, ya que por alguna extraña razón me genera un error que desde mi máquina no ocurre. El servidor es un Centos 6. Este es el error. Eso sí: inicializo la variable $text haciendo uso de
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my $text=...
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
Type of arg 1 to each must be hash (not private variable) at /var/www/cgi-bin/webService.pl line 68, near "$text)"
Execution of /var/www/cgi-bin/webService.pl aborted due to compilation errors.
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


Y esto si no le pongo el my:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
Type of arg 1 to each must be hash (not scalar dereference) at /var/www/cgi-bin/wsDactoolAdmin.pl line 68, near "$text)"
Execution of /var/www/cgi-bin/wsDactoolAdmin.pl aborted due to compilation errors.
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

El código que estoy usando en el servicio web:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl -w
  2.  
  3. #####################################################################################
  4. # Noviembre 2014
  5. # Descripcion: Web Service para realizar Cancelacion, Suspension y Reactivación de
  6. # Servicios.
  7. #####################################################################################
  8.  
  9. print "Content-type: application/json\n\n";
  10. use CGI qw(:standard      );
  11. use CGI::Carp qw( fatalsToBrowser );
  12. use JSON;
  13. use Data::Dumper;
  14. use Digest::MD5 qw(md5 md5_hex md5_base64);
  15.  
  16. ########################################################################
  17. ## Se puede recibir tanto parámetros enviados a través del método GET,
  18. ## como parámetros a través del método POST.
  19. ########################################################################
  20.  
  21. my $json         = "";
  22. my $securityCode = "xxx123456721";
  23.  
  24. #$json = '{"nombre":"Server1","ip":"190.168.11.22","interfaz":"GigabitEthernet1/0.1","serviceid":95198,"accion":"cancelar"}';
  25.  
  26. ## Valido desde cual IP quieren Consumir el Servicio. Si no esta dentro de las aceptadas se retorna mensaje de error. ##
  27. $remote_host = remote_addr();
  28. &manInTheMiddle($remote_host);
  29.  
  30. ####################################################################################################
  31. sub requestParameters {
  32.  
  33.     # Aquí sacamos la lista de los parámetros
  34.     # en caso de que le haya sido pasado alguno
  35.     my @params = param();
  36.     foreach my $par (@params) {
  37.  
  38.         #print p($par);
  39.         #print blockquote(param( $par ));
  40.         $json .= param($par);
  41.     }
  42.     &JsonParser($json);
  43.  
  44.     #print "my Parameter: $json\n\n";
  45. }
  46.  
  47. sub JsonParser {
  48.     my $jsonr = shift;
  49.     my $hash  = "";
  50.     my ( $hashDos, $serviceID, $interfaz, $ip, $name, $action ) = "";
  51.     my $encrpass = "";
  52.     $hash .= $securityCode;
  53.  
  54.     $text = decode_json($jsonr);
  55.  
  56.     #print "\n\nDecodificado:\n\n";
  57.     #print  Dumper($text);
  58.     while ( ( $key, $value ) = each($text) ) {
  59.  
  60.         #print $key."-".$value."\n";
  61.         unless ( $key =~ /(hash)/is ) {
  62.             $hash .= $value;
  63.         }
  64.         if ( $key eq 'serviceID' ) {
  65.             $serviceID = $value;
  66.         }
  67.         elsif ( $key eq 'interfaz' ) {
  68.             $interfaz = $value;
  69.         }
  70.         elsif ( $key eq 'ip' ) {
  71.             $ip = $value;
  72.         }
  73.         elsif ( $key eq 'name' ) {
  74.             $name = $value;
  75.         }
  76.         elsif ( $key eq 'action' ) {
  77.             $action = $value;
  78.         }
  79.         elsif ( $key eq 'hash' ) {
  80.             $hashDos = $value;
  81.         }
  82.     }
  83.  
  84.     #print "Hash Decoded-->$hash\n\n";
  85.     $encrpass = md5_hex($hash);
  86.     print "HashQ -->$hashDos - $encrpass <--- HashWs\n\n";
  87.     if ( $hashDos != $encrpass ) {
  88.         print "Man in the Middle\n\n";
  89.     }
  90.     else {
  91.         print "action= $action\n\n";
  92.         if ( $action eq 'cancel' ) {
  93.             &CancelService( $serviceID, $name, $ip, $interfaz );
  94.         }
  95.         elsif ( $action eq 'reactivate' ) {
  96.             &ReactivateService( $serviceID, $name, $ip, $interfaz );
  97.         }
  98.         elsif ( $action eq 'suspend' ) {
  99.             &SuspendService( $serviceID, $name, $ip, $interfaz );
  100.         }
  101.     }
  102. }
  103.  
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4

Ese código funciona sin problema en mi máquina, pero no en el servidor. Por favor, ¿me indican cómo puedo hacer para resolverlo? ¿O de qué manera podría hacerlo? Quise usar el switch pero no me funcionaba en mi máquina, ya en el servidor está con (use Switch) para el manejo de los valores del JSON. Agradezco de antemano la ayuda que me puedan prestar :)

Re: Creación de un servicio web usando JSON

NotaPublicado: 2014-11-11 10:14 @468
por explorer
En la línea 53 tienes esto:

while (($key, $value) = each($text)) {

La función each() solo se aplica a un hash (y a un array, en las últimas versiones de Perl). Y lo que tienes es un escalar.

Eso es justo lo que dice el mensaje de error: "El tipo del argumento 1 a each() debe ser un hash (no una variable privada)".

Edito: solo en las versiones de Perl a partir de 5.14 se puede pasar a each() una referencia a un hash, que es justo lo que $text contiene al recibir la decodificación del JSON. Así que lo que te pasa es que tienes distintas versiones de Perl en la máquina local y en el servidor.

Puedes solventarlo desreferenciando el hash:

while (($key, $value) = each %$text) {

Edito: La línea

print "Content-type: application/json\n\n";

queda mejor si en el primer print del programa lo pones así:

print header('application/json');

(Curiosamente, esta línea sale al principio del manual de CGI)

Re: Creación de un servicio web usando JSON

NotaPublicado: 2014-11-11 10:56 @497
por jero2528
¡¡¡Perfecto!!! Muchas gracias, explorer, por toda la ayuda que me has brindado :) :o :oops:

Re: Creación de un servicio web usando JSON

NotaPublicado: 2020-05-26 11:49 @534
por programadorCO
Hola, explorer. ¿Se puede agregar algún tipo de seguridad, como un token, cuando se haga el llamado al servicio?