diff --git a/http_server/count_body.py b/http_server/count_body.py index 60c4413..012a63c 100644 --- a/http_server/count_body.py +++ b/http_server/count_body.py @@ -55,7 +55,8 @@ def elaborate(self, _platform): m.submodules.printer = printer = PrinterSeq([ Printer("requests: "), count_req, Printer(" ok_responses: "), count_ok, - Printer(" error_responses: "), count_error + Printer(" error_responses: "), count_error, + Printer("\r\n") ]) m.d.comb += [ diff --git a/http_server/count_body_test.py b/http_server/count_body_test.py index cf5704a..045e922 100644 --- a/http_server/count_body_test.py +++ b/http_server/count_body_test.py @@ -6,7 +6,7 @@ def test_count_body(): dut = CountBody() - expected = "requests: 0003 ok_responses: 0002 error_responses: 0001" + expected = "requests: 0003 ok_responses: 0002 error_responses: 0001\r\n" sim = Simulator(dut) sim.add_clock(1e-6) diff --git a/http_server/simple_led_http.py b/http_server/simple_led_http.py index a2580c4..220797f 100644 --- a/http_server/simple_led_http.py +++ b/http_server/simple_led_http.py @@ -81,7 +81,6 @@ def elaborate(self, _platform): "Host: Fomu", "Content-Type: text/plain; charset=utf-8", "", - "", '👍']) + "\r\n" ok_response = ok_response.encode("utf-8") ok_printer = m.submodules.ok_printer = Printer(ok_response) @@ -99,7 +98,6 @@ def elaborate(self, _platform): "Host: Fomu", "Content-Type: text/plain; charset=utf-8", "", - "", '👎']) + "\r\n" not_found_response = not_found_response.encode("utf-8") not_found_printer = m.submodules.not_found_printer = Printer(not_found_response) @@ -117,7 +115,6 @@ def elaborate(self, _platform): "Host: Fomu", "Content-Type: text/plain; charset=utf-8", "", - "", '🛑']) + "\r\n" not_allowed_response = not_allowed_response.encode("utf-8") not_allowed_printer = m.submodules.not_allowed_printer = Printer(not_allowed_response) @@ -135,7 +132,6 @@ def elaborate(self, _platform): "Host: Fomu", "Content-Type: text/plain; charset=utf-8", "", - "", "short and stout"]) + "\r\n" teapot_response = teapot_response.encode("utf-8") teapot_printer = m.submodules.teapot_printer = Printer(teapot_response) diff --git a/http_server/simple_led_http_test.py b/http_server/simple_led_http_test.py index f131915..aac0e37 100644 --- a/http_server/simple_led_http_test.py +++ b/http_server/simple_led_http_test.py @@ -16,13 +16,11 @@ def test_ok_handling(): "User-Agent: test-agent\r\n" "Content-Type: text/plain\r\n" "\r\n" - "\r\n" "123456\r\n") expected_output = ("HTTP/1.0 200 OK\r\n" "Host: Fomu\r\n" "Content-Type: text/plain; charset=utf-8\r\n" "\r\n" - "\r\n" "👍\r\n") async def driver(ctx): @@ -57,13 +55,12 @@ async def driver(ctx): # Doesn't appear to be a way to _remove_ a testbench; # I guess .reset() is "just" to allow a different initial state? - with sim.write_vcd(sys.stdout): - sim.run_until(0.001) + #with sim.write_vcd("test.vcd"): + sim.run_until(0.0005) # Now that the test is done: collector.assert_eq(expected_output) - def test_404_handling(): dut = SimpleLedHttp() sim = Simulator(dut) @@ -74,13 +71,11 @@ def test_404_handling(): "User-Agent: evil-agent\r\n" "Content-Type: text/bad\r\n" "\r\n" - "\r\n" "123456\r\n") expected_output = ("HTTP/1.0 404 Not Found\r\n" "Host: Fomu\r\n" "Content-Type: text/plain; charset=utf-8\r\n" "\r\n" - "\r\n" "👎\r\n") async def driver(ctx): @@ -125,13 +120,11 @@ def test_405_handling(): "User-Agent: evil-agent\r\n" "Content-Type: text/bad\r\n" "\r\n" - "\r\n" "What're your LEDs doing?\r\n") expected_output = ("HTTP/1.0 405 Method Not Allowed\r\n" "Host: Fomu\r\n" "Content-Type: text/plain; charset=utf-8\r\n" "\r\n" - "\r\n" "🛑\r\n") async def driver(ctx): @@ -175,42 +168,36 @@ def test_count_handling(): "User-Agent: test-agent\r\n" "Content-Type: text/plain\r\n" "\r\n" - "\r\n" "123456\r\n") error_input = ("BREW /cocoa HTTP/1.0\r\n" "Host: test\r\n" "User-Agent: test-agent\r\n" "Content-Type: text/plain\r\n" "\r\n" - "\r\n" "With marshmallows, please\r\n") count_input = ("GET /count HTTP/1.0\r\n" "Host: test\r\n" "User-Agent: test-agent\r\n" "Content-Type: text/plain\r\n" "\r\n" - "\r\n" "\r\n") expected_output = ("HTTP/1.0 200 OK\r\n" "Host: Fomu\r\n" "Content-Type: text/plain; charset=utf-8\r\n" "\r\n" - "\r\n" "👍\r\n" "HTTP/1.0 404 Not Found\r\n" "Host: Fomu\r\n" "Content-Type: text/plain; charset=utf-8\r\n" "\r\n" - "\r\n" "👎\r\n" "HTTP/1.0 200 OK\r\n" "Host: Fomu\r\n" "Content-Type: text/plain; charset=utf-8\r\n" "\r\n" - "\r\n" "👍\r\n" - "requests: 0003 ok_responses: 0002 error_responses: 0001") + "requests: 0003 ok_responses: 0002 error_responses: 0001\r\n") async def driver(ctx): @@ -263,13 +250,11 @@ def test_coffee_handling(): "User-Agent: evil-agent\r\n" "Content-Type: text/bad\r\n" "\r\n" - "\r\n" "Black, medium roast Ethiopian, pour over\r\n") expected_output = ("HTTP/1.0 418 I'm a teapot\r\n" "Host: Fomu\r\n" "Content-Type: text/plain; charset=utf-8\r\n" "\r\n" - "\r\n" "short and stout\r\n") async def driver(ctx): diff --git a/http_server/string_contains_match.py b/http_server/string_contains_match.py index 3e6cef5..33a5d42 100644 --- a/http_server/string_contains_match.py +++ b/http_server/string_contains_match.py @@ -68,8 +68,20 @@ def elaborate(self, _platform): shift_reg = [Signal(8) for _ in range(len(self._message))] + latched_accept = Signal(1) + + matched = Signal(len(self._message)) + m.d.comb += matched[0].eq(c == self._message[len(self._message)-1]) + for i in range(1,len(self._message)): + m.d.comb += matched[i].eq(shift_reg[i-1] == self._message[len(self._message)-i-1]) + + with m.If(matched.all()): + m.d.sync += latched_accept.eq(1) + m.d.comb += self.accepted.eq(matched.all() | latched_accept) + + with m.If(self.reset): - m.d.sync += self.accepted.eq(Const(0)) + m.d.sync += latched_accept.eq(0) for i in range(len(self._message)): m.d.sync += shift_reg[i].eq(0) with m.Elif(self.input.valid): @@ -77,19 +89,5 @@ def elaborate(self, _platform): m.d.sync += shift_reg[i+1].eq(shift_reg[i]) m.d.sync += shift_reg[0].eq(c) - matched = [Signal(1) for _ in range(len(self._message))] - for i in range(len(self._message)): - m.d.comb += matched[i].eq(shift_reg[i] == self._message[len(self._message)-i-1]) - - # Note: Doing a linear reduction here. Could be a problem for very long - # matches. If it ends up being an issue, switch to a tree. - matched_chain = [Signal(1) for _ in range(len(self._message)+1)] - m.d.comb += matched_chain[0].eq(Const(1)) - for i in range(len(self._message)): - m.d.comb += matched_chain[i+1].eq(matched_chain[i] & matched[i]) - - # Latch acceptance - with m.If(matched_chain[len(self._message)]): - m.d.sync += self.accepted.eq(1) return m