<commit_before>use HTTP::Message;

use URI;

unit class HTTP::Request is HTTP::Message;

has $.method is rw;
has $.url is rw;
has $.file is rw;
has $.uri is rw;

my $CRLF = "\r\n";

multi method new(*%args) {
    my ($method, $url, $file, %fields, $uri);
    
    for %args.kv -> $key, $value {
        if $key.lc ~~ any(<get post head put delete>) {
            $uri = $value.isa(URI) ?? $value !! URI.new($value);
            $url = $uri.grammar.parse_result.orig;
            $method = $key.uc;
            $file = $uri.path || '/';
            $file ~= "?{$uri.query}" if $uri.query;
        } else {
            %fields{$key} = $value;
        }
    }

    my $header = HTTP::Header.new(|%fields);
    $header.field(Host => get-host-value($uri)) if $uri;
    self.bless(:$method, :$url, :$header, :$file, :$uri);
}

sub get-host-value(URI $uri --> Str) {
   my $host = $uri.host;

   if ( $uri.port != $uri.default_port ) {
      $host ~= ':' ~ $uri.port;
   }
   $host;
}

method set-method($method) { $.method = $method.uc }

multi method uri($uri is copy where URI|Str) {
    $!uri = $uri.isa(Str) ?? URI.new($uri) !! $uri ;
    $!url = $!uri.grammar.parse_result.orig;
    $.header.field(Host => get-host-value($!uri));
    $!uri;
}

multi method uri() is rw {
    $!uri;
}

method Str {
    my $s = "$.method $.file $.protocol";
    $s ~= $CRLF ~ callwith($CRLF);
}

method parse($raw_request) {<commit_msg>Make host, port, scheme attributes<commit_after>use HTTP::Message;

use URI;

unit class HTTP::Request is HTTP::Message;

has $.method is rw;
has $.url is rw;
has $.file is rw;
has $.uri is rw;

has Str $.host is rw;
has Int $.port is rw;
has Str $.scheme is rw;

my $CRLF = "\r\n";

multi method new(*%args) {
    my ($method, $url, $file, %fields, $uri);
    
    for %args.kv -> $key, $value {
        if $key.lc ~~ any(<get post head put delete>) {
            $uri = $value.isa(URI) ?? $value !! URI.new($value);
            $url = $uri.grammar.parse_result.orig;
            $method = $key.uc;
            $file = $uri.path || '/';
            $file ~= "?{$uri.query}" if $uri.query;
        } else {
            %fields{$key} = $value;
        }
    }

    my $header = HTTP::Header.new(|%fields);
    $header.field(Host => get-host-value($uri)) if $uri;
    self.bless(:$method, :$url, :$header, :$file, :$uri);
}

sub get-host-value(URI $uri --> Str) {
    my Str $host = $uri.host;

    if $host {
        if ( $uri.port != $uri.default_port ) {
            $host ~= ':' ~ $uri.port;
        }
    }
    $host;
}

method set-method($method) { $.method = $method.uc }

multi method uri($uri is copy where URI|Str) {
    $!uri = $uri.isa(Str) ?? URI.new($uri) !! $uri ;
    $!url = $!uri.grammar.parse_result.orig;
    $.header.field(Host => get-host-value($!uri));
    $!uri;
}

multi method uri() is rw {
    $!uri;
}

multi method host() returns Str is rw {
    if not $!host.defined {
         $!host = ~self.header.field('Host').values;
    }
    $!host;
}

multi method  port() returns Int is rw {
    if not $!port.defined {
        # if there isn't a scheme the no default port
        if try self.uri.scheme {
            $!port = self.uri.port;
        }
    }
    $!port;
}

multi method scheme() returns Str is rw {
    if not $!scheme.defined {
        $!scheme = self.uri.scheme;

        CATCH {
            default {
                $!scheme = 'http';
            }
        }
    }
    $!scheme
}


method Str {
    my $s = "$.method $.file $.protocol";
    $s ~= $CRLF ~ callwith($CRLF);
}

method parse($raw_request) {
{'fraction_non_alphanumeric': 0.19292333614153329, 'fraction_numerical': 0.0, 'mean_word_length': 2.180357142857143, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3177349', 'n_tokens_mistral': 1319, 'n_tokens_neox': 1310, 'n_words': 333}