Universeller Parser für beliebigen HTTP Content-Type im Request

Enctype application/x-www-form-urlencoded und multipart/form-data sind die Einzigen strukturierten Content-Types

Herkömmliche Parser unterstützen lediglich den Content-Type application/x-www-form-urlencoded oder multipart/form-data und unterliegen einer Logik, welche anhand der Request-Methode (POST,GET) über die Herkunft der Daten am Common Gateway entscheidet. So werden die Daten entweder aus STDIN oder aus dem QUERY_STRING gelesen. Es gibt jedoch Anforderungen wie Webservices, da werden die Daten anders verpackt, zum Beispiel als application/json oder application/soap+xml und ggf. Weitere

Diese Anforderungen begründen eine Eigenentwicklung, welche sich am vom Client gesendeten Content-Type orientiet und nicht an der HTTP-Request-Methode, ja von Letzterer gänzlich unabhängig ist.

Der für mein Framework entwickelte Parser unterstützt also beliebige Content-Types und ist in dieser Hinsicht leicht erweiterbar. Wesentlich ist, dass unabhängig vom gesendeten Content-Type nach dem Parsen stets diegleichen Datenstrukturen erzeugt werden. Mit:

ergeben sich also, außer Content-Type: application/octet-stream Schlüssel-Werte Paare, so wie das bisherige Parser auch handhaben. Damit ist ebenfalls die Abwärtskompatibilität meines universellen Parsers gesichert, Content-Type: application/x-www-form-urlencoded ist Default.

Mögliche Erweiterungen auf beliebige Content-Types hängen nur noch davon ab, ob serverseitig die entsprechenden Libraries verfügbar sind. Dem Parser folgender Programmcode bzw. Programmlogik ist dann unabhängig vom Content-Type im Request. Das setzt natürlich voraus, dass der Client im Request-Header-Content-Type einen solchen sendet, damit er serverseitig entsprechend geparst werden kann.

Der Vorteil dieser Abstraktion

Nur noch der Client bestimmt den Enctype für die zu übertragenden Daten. Beispielsweise werden bei einem Legacy Submit die Daten eines Formulars per Enctype= "application/x-www-form-urlencoded" übertragen, per Ajax hingegen wird dasselbe Formular als Enctype= "application/json" gesendet. Am serverseitigen Code ändert sich dadurch nichts, die Framework-Instanz greift wie immer mit $self->param('name') in die Parameter des Request.

Unabhängige Layer einbinden, Schichtenmodell

Zu Beachten: Der Client sendet dem passenden Content-Type im HTTP-Request Header. Somit wird der passende Layer automatisch geladen.

# hier werden die jeweiligen Layer geladen
sub _parse_rawdata{
    my $self = shift;
    if(    $self->{CONTENT_TYPE} eq 'multipart/c-eav' ){
        require cEAV;
        $self->{eav} = cEAV->decode_eav( $self->rawdata );
        $self->{param} = $self->{eav}->{param};
    }
    elsif( $self->{CONTENT_TYPE} eq 'bserialize/av' ){
        require bSerialize;
        my $bs = bSerialize->new;
        my $binary = $self->rawdata;
        $self->{param} = $bs->bin2av( \$binary );
    }
    elsif( $self->{CONTENT_TYPE} eq 'multipart/form-data' ){
        require ParseMultipart;
        $self->{STDIN}->seek(0,0);
        $self->{param} = ParseMultipart->parse_multipart( $self->{STDIN} );
    }
    elsif( $self->{CONTENT_TYPE} eq 'application/json' ){
        require JSON;
        my $json = JSON->new;
        $self->{json} = $json->decode($self->rawdata);
        $self->{param} = $self->{json}{param};
    }
    else{
        # Default Content-Type
        # Parameter: Name => [Value], application/x-www-form-urlencoded
        $self->{param} = $self->qparse( $self->rawdata );
    }
}

Das Schichtenmodell zeigt die Unabhängigkeit und die universelle Verwendbarkeit. Es ist beliebig erweiterbar.


Anbieter: nmq​rstx-18­@yahoo.de, die Seite verwendet funktionsbedingt einen Session-Cookie und ist Bestandteil meines nach modernen Aspekten in Perl entwickelten Frameworks.