zig icon indicating copy to clipboard operation
zig copied to clipboard

std.http: Use '/' for a empty path

Open musaprg opened this issue 2 years ago • 0 comments

Hi, thank you for working on HTTP client implementations as part of std. I'm trying to use it, but I faced one issue regarding an empty path. The current implementation doesn't allow missing trailing slashes for URLs, which should be acceptable. This PR fixes to accept regardless of the trailing slash, that is, both http://example.com and http://example.com/

Current behavior

https://gist.github.com/musaprg/b73aa918816989db7c15b7b75d214ca4#file-main-zig

environment:

  • macOS 12.5 (Darwin 21.6.0 arm64)
  • zig version 0.11.0-dev.1929+4ea2f441d

Without trailing slash (http://example.com)

return 400 (bad_request)

execution result
parsed schema: http
parsed path:
parsed host: example.com
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
         "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
	<head>
		<title>400 - Bad Request</title>
	</head>
	<body>
		<h1>400 - Bad Request</h1>
	</body>
</html>
Method: GET
Status code: bad_request
Version: HTTP/1.0

With trailing slash (http://example.com/)

return 200 (ok)

execution result
parsed schema: http
parsed path: /
parsed host: example.com
<!doctype html>
<html>
<head>
    <title>Example Domain</title>

    <meta charset="utf-8" />
    <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <style type="text/css">
    body {
        background-color: #f0f0f2;
        margin: 0;
        padding: 0;
        font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;

    }
    div {
        width: 600px;
        margin: 5em auto;
        padding: 2em;
        background-color: #fdfdff;
        border-radius: 0.5em;
        box-shadow: 2px 3px 7px 2px rgba(0,0,0,0.02);
    }
    a:link, a:visited {
        color: #38488f;
        text-decoration: none;
    }
    @media (max-width: 700px) {
        div {
            margin: 0 auto;
            width: auto;
        }
    }
    </style>
</head>

<body>
<div>
    <h1>Example Domain</h1>
    <p>This domain is for use in illustrative examples in documents. You may use this
    domain in literature without prior coordination or asking for permission.</p>
    <p><a href="https://www.iana.org/domains/example">More information...</a></p>
</div>
</body>
</html>
Method: GET
Status code: ok
Version: HTTP/1.1

Expected behavior

Both http://example.com and http://example.com/ should return 200.

According to RFC3986, in general, an empty path should be normalized to "/" for HTTP(s).

In general, a URI that uses the generic syntax for authority with an empty path should be normalized to a path of "/". Likewise, an explicit ":port", for which the port is empty or the default for the scheme, is equivalent to one where the port and its ":" delimiter are elided and thus should be removed by scheme-based normalization. For example, the second URI above is the normal form for the "http" scheme. https://www.rfc-editor.org/rfc/rfc3986#section-6.2.3

musaprg avatar Mar 11 '23 17:03 musaprg