Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

an attempt at better file parsing #223

Merged
merged 7 commits into from
Jun 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 51 additions & 2 deletions src/http.c
Original file line number Diff line number Diff line change
Expand Up @@ -300,12 +300,12 @@
clt->src->cancel(clt->src);
}

static void req_write_cb(uv_link_t *source, int status, void *arg) {

Check warning on line 303 in src/http.c

View workflow job for this annotation

GitHub Actions / build (windows, mbedtls)

'source': unreferenced formal parameter
UM_LOG(VERB, "request write completed: %d", status);
free(arg);
}

static void req_write_body_cb(uv_link_t *source, int status, void *arg) {

Check warning on line 308 in src/http.c

View workflow job for this annotation

GitHub Actions / build (windows, mbedtls)

'source': unreferenced formal parameter
UM_LOG(VERB, "request body write completed: %d", status);
struct body_chunk_s *chunk = arg;
if (chunk->cb) {
Expand All @@ -314,7 +314,7 @@
free(chunk);
}

static void chunk_hdr_wcb(uv_link_t *l, int status, void *arg) {

Check warning on line 317 in src/http.c

View workflow job for this annotation

GitHub Actions / build (windows, mbedtls)

'status': unreferenced formal parameter

Check warning on line 317 in src/http.c

View workflow job for this annotation

GitHub Actions / build (windows, mbedtls)

'l': unreferenced formal parameter
if (arg != NULL) {
free(arg);
}
Expand All @@ -340,7 +340,7 @@
uv_link_write((uv_link_t *) &clt->http_link, &buf, 1, NULL, chunk_hdr_wcb, buf.base);

buf.base = (char*)b->chunk;
buf.len = b->len;

Check warning on line 343 in src/http.c

View workflow job for this annotation

GitHub Actions / build (windows, mbedtls)

'=': conversion from 'size_t' to 'ULONG', possible loss of data
uv_link_write((uv_link_t *) &clt->http_link, &buf, 1, NULL, req_write_body_cb, b);

buf.base = "\r\n";
Expand All @@ -357,7 +357,7 @@
else {
buf = uv_buf_init((char*)b->chunk, (unsigned int)b->len);
uv_link_write((uv_link_t *) &clt->http_link, &buf, 1, NULL, req_write_body_cb, b);
if (req->body_sent_size > req->req_body_size) {

Check warning on line 360 in src/http.c

View workflow job for this annotation

GitHub Actions / build (windows, mbedtls)

'>': signed/unsigned mismatch
UM_LOG(WARN, "Supplied data[%ld] is larger than provided Content-Length[%ld]",
req->body_sent_size, req->req_body_size);
}
Expand Down Expand Up @@ -779,15 +779,64 @@
tlsuv_tls_link_free(&clt->tls_link);
}


int tlsuv_parse_url(struct tlsuv_url_s *url, const char *urlstr) {
memset(url, 0, sizeof(struct tlsuv_url_s));

const char *p = urlstr;

int file_prefix_len = strlen("file:/");
// special handling for file:/, file://, file://host/, file:///
if (strncmp(urlstr, "file:/", file_prefix_len) == 0) {
url->scheme = p;
url->scheme_len = 4; // strlen("file")
p += file_prefix_len;

if (p[0] == '/') {
p++;
if (p[0] == '/') {
// file:/// means empty hostname
p++;
} else {
// file://path means there must be a hostname. find the next slash
dovholuknf marked this conversation as resolved.
Show resolved Hide resolved
char *pos = strchr(p, '/');
if (pos != NULL) {
size_t index = pos - p;
url->hostname = p;
url->hostname_len = index;
p += index + 1;
} else {
// poorly formatted entry. this would be just `file://` or `file://hostnameonly`
url->hostname = p;
url->hostname_len = strlen(p);
return -1;
}
}
} else {
//one slash - else empty on purpose to indicate this is expected to be no-op
}

#ifdef _WIN32
if (strlen(p) > 0 && p[1] == ':') {
// expect a windows path to have a drive letter c:, d:, etc.
} else {
// if no ':' in position 2, back up to pickup the leading slash
p--;
}
#else
p--; //on non-windows, always backup to pickup the leading slash
#endif
url->path = p;
url->path_len = strlen(p);
return 0;
}


int count = 0;
int rc = sscanf(p, "%*[^:]%n://", &count);
if (rc == 0 &&
(p + count)[0] == ':' && (p + count)[1] == '/' && (p + count)[2] == '/'
) {
) {
url->scheme = p;
url->scheme_len = count;
p += (count + 3);
Expand Down Expand Up @@ -826,7 +875,7 @@
return -1;

if (lport > 0 && lport <= UINT16_MAX) {
url->port = (uint16_t)lport;
url->port = (uint16_t) lport;
p = pend;
} else {
return -1;
Expand Down
2 changes: 1 addition & 1 deletion tests/Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ The test server opens the following endpoints:
Start test server:
```console
cd ./tests/test_server
go run ./test-server.go -keyfile ../certs/server.key -certfile ../certs/server.crt
go run ./test-server.go -ca-key ../certs/server.key -ca ../certs/server.crt
```

now you're ready to run tests
17 changes: 16 additions & 1 deletion tests/http_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1121,13 +1121,28 @@ static void URL_TEST(const char *s, int RES, const char *SCHEME, const char *HOS
CHECK(url.port == (PORT));
}
}

#ifdef _WIN32
#define LEADING_SLASH ""
#else
#define LEADING_SLASH "/"
#endif
TEST_CASE("url parse", "[http]") {
URL_TEST("wss://websocket.org/echo?foo=bar", 0, "wss", "websocket.org", 0, "/echo", "foo=bar");
URL_TEST("wss://websocket.org:443/echo?foo=bar", 0, "wss", "websocket.org", 443, "/echo", "foo=bar");
URL_TEST("wss://websocket.org/echo", 0, "wss", "websocket.org", 0, "/echo", nullptr);
URL_TEST("websocket.org:443/echo", 0, nullptr, "websocket.org", 443, "/echo", nullptr);

URL_TEST("file:///echo.txt", 0, "file", nullptr, 0, "/echo.txt", nullptr);
URL_TEST("file:/echo.txt", 0, "file", nullptr, 0, "/echo.txt", nullptr);
URL_TEST("file://host/echo.txt", 0, "file", "host", 0, "/echo.txt", nullptr);
URL_TEST("file:///some/path/to/echo.txt", 0, "file", nullptr, 0, "/some/path/to/echo.txt", nullptr);
URL_TEST("file:///c:/echo.txt", 0, "file", nullptr, 0, LEADING_SLASH "c:/echo.txt", nullptr);
URL_TEST("file:///c:/some/other/path/to/echo.txt", 0, "file", nullptr, 0, LEADING_SLASH "c:/some/other/path/to/echo.txt", nullptr);

URL_TEST("file://", -1, "file", nullptr, 0, "/echo.txt", nullptr);
URL_TEST("file://hostnameonly", -1, "file", "hostnameonly", 0, nullptr, nullptr);
URL_TEST("file://hostnameonly/", 0, "file", "hostnameonly", 0, "/", nullptr);

URL_TEST("/path/only/echo.txt", 0, nullptr, nullptr, 0, "/path/only/echo.txt", nullptr);
URL_TEST(":443/echo", -1, nullptr, "websocket.org", 443, "/echo", nullptr);
URL_TEST("websocket.org:443echo", -1, nullptr, "websocket.org", 443, "/echo", nullptr);
Expand Down
Loading