nushell/crates
Julian Aichholz 9c7e37f728
Fix: return all headers with the same name from http <method> (#9594)
# Description

Hi nushell!

Thanks so much for [adding http headers][headers]! I've been waiting for
this feature for a long time and it's great. However, I found that
`Record` as a return type and using `ureq`'s `response.header` api
results in missing header values when there are multiple with the same
name, as can occur with `set-cookie` and others.

This issue with http has been discussed at length [on
stackoverflow][stackoverflow] and in [`ureq` itself][ureq]. It seems
like concatenating header values with `,` is a common solution, but
tricky especially with `set-cookie` which may contain `,` in the
`Expires` field, as discussed in the former post.

I propose changing the return type to a `List` of `Record` so we can get
all of the header values without relying on ad-hoc mutation. This
solution does not return the headers in the same order as they appear in
the `Response` due to `ureq`'s `Response.all` API, but it's better than
dropping values imo.

This is a **breaking change**. I'm sure `ureq`'s
[`CookieStore`][cookiestore] is a better long-term solution for
returning cookies as a separate record on `http <method>`, but other
headers can be set multiple times as well.

# User-Facing Changes
- Changes the return type of an `http <method>` `header` field from
`Record` to `List` (Table with columns `name` and `value`)
- Returns all values of a header set multiple times instead of just the
first one duplicated

# Implementation

Quick note that running `header_names.dedup()` does not resolve the
necessity to iterate through the previously parsed headers since `dedup`
only removes identical values when they are next to each other in the
`Vec`. You could do a `sort` first, but header ordering can be important
in some cases, so I tried to avoid messing with that more than is
already the case with `Response.all`. Would love to see a better way of
doing this though!

# Tests + Formatting
No tests broke implementing this change. Not sure what endpoint to hit
or mock server to use to verify this in tests. I have some screenshots
to illustrate what I'm talking about.

Before:
![Screenshot 2023-07-03 at 12 50 17
AM](https://github.com/nushell/nushell/assets/39018167/41604bef-54c6-424b-91b2-6b89a020e4ff)

> `set-cookie` has the same value for every record field.
> Even if it did not I'm not sure how you would access the different
values since they all have the same key.

After:
![Screenshot 2023-07-03 at 12 49 45
AM](https://github.com/nushell/nushell/assets/39018167/4ee45e6e-3785-471f-aee7-5af185cd06c2)

> Actual values from the response returned for the same name

Make sure you've run and fixed any issues with these commands:

- [x] `cargo fmt --all -- --check` to check standard code formatting
(`cargo fmt --all` applies these changes)
- [x] `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used -A
clippy::needless_collect -A clippy::result_large_err` to check that
you're using the standard code style
- [x] `cargo test --workspace` to check that all tests pass
- [x] `cargo run -- crates/nu-std/tests/run.nu` to run the tests for the
standard library <-- Note: I did not see a `crates/nu-std/test/run.nu`
file so I ran the snippet below which returned without error
```nushell
for $i in (ls crates/nu-std/tests/*.nu) {
   cargo run -- $i.name
}
```

# Code of Conduct

Apologies for not opening an issue first. Just did this fix for myself
because it seemed simple enough before deciding to open this PR.

# After Submitting
<!-- If your PR had any user-facing changes, update [the
documentation](https://github.com/nushell/nushell.github.io) after the
PR is merged, if necessary. This will help us keep the docs up to date.
-->
- [ ] update docs

[stackoverflow]:
https://stackoverflow.com/questions/3241326/set-more-than-one-http-header-with-the-same-name
[headers]: https://github.com/nushell/nushell/pull/8571
[ureq]: https://github.com/algesten/ureq/issues/95
[cookiestore]:
https://docs.rs/cookie_store/latest/cookie_store/struct.CookieStore.html
2023-07-03 10:20:39 -05:00
..
nu_plugin_custom_values Bump to 0.82.1 dev version (#9543) 2023-06-27 21:33:53 +02:00
nu_plugin_example Bump to 0.82.1 dev version (#9543) 2023-06-27 21:33:53 +02:00
nu_plugin_formats Bump to 0.82.1 dev version (#9543) 2023-06-27 21:33:53 +02:00
nu_plugin_gstat Bump to 0.82.1 dev version (#9543) 2023-06-27 21:33:53 +02:00
nu_plugin_inc Bump to 0.82.1 dev version (#9543) 2023-06-27 21:33:53 +02:00
nu_plugin_python update nu_plugin_python due to signature changes (#8107) 2023-02-18 13:27:24 +00:00
nu_plugin_query Bump to 0.82.1 dev version (#9543) 2023-06-27 21:33:53 +02:00
nu-cli Let with pipeline (#9589) 2023-07-03 17:45:10 +12:00
nu-cmd-base Bump to 0.82.1 dev version (#9543) 2023-06-27 21:33:53 +02:00
nu-cmd-dataframe Improve type hovers (#9515) 2023-06-29 05:19:48 +12:00
nu-cmd-extra convert a string to a raw binary string of 0s and 1s (#9534) 2023-06-28 13:04:07 -05:00
nu-cmd-lang Let with pipeline (#9589) 2023-07-03 17:45:10 +12:00
nu-color-config remove let-env, focus on mutating $env (#9574) 2023-07-01 07:57:51 +12:00
nu-command Fix: return all headers with the same name from http <method> (#9594) 2023-07-03 10:20:39 -05:00
nu-engine remove let-env, focus on mutating $env (#9574) 2023-07-01 07:57:51 +12:00
nu-explore Bump to 0.82.1 dev version (#9543) 2023-06-27 21:33:53 +02:00
nu-glob Bump to 0.82.1 dev version (#9543) 2023-06-27 21:33:53 +02:00
nu-json Bump to 0.82.1 dev version (#9543) 2023-06-27 21:33:53 +02:00
nu-parser Let with pipeline (#9589) 2023-07-03 17:45:10 +12:00
nu-path Bump to 0.82.1 dev version (#9543) 2023-06-27 21:33:53 +02:00
nu-plugin Improve type hovers (#9515) 2023-06-29 05:19:48 +12:00
nu-pretty-hex Bump to 0.82.1 dev version (#9543) 2023-06-27 21:33:53 +02:00
nu-protocol fix a few clippy issues (#9578) 2023-07-01 19:52:04 +12:00
nu-std Implement annotations support in test runner (#9406) 2023-07-02 10:41:33 +02:00
nu-system Bump to 0.82.1 dev version (#9543) 2023-06-27 21:33:53 +02:00
nu-table Fix #9548 (#9552) 2023-06-28 17:52:04 -05:00
nu-term-grid Bump to 0.82.1 dev version (#9543) 2023-06-27 21:33:53 +02:00
nu-test-support Bump to 0.82.1 dev version (#9543) 2023-06-27 21:33:53 +02:00
nu-utils use an easier-to-read date format in prompt (#9585) 2023-07-02 20:25:22 +12:00
README.md Remove old nushell/merge engine-q 2022-02-07 14:54:06 -05:00

Nushell core libraries and plugins

These sub-crates form both the foundation for Nu and a set of plugins which extend Nu with additional functionality.

Foundational libraries are split into two kinds of crates:

  • Core crates - those crates that work together to build the Nushell language engine
  • Support crates - a set of crates that support the engine with additional features like JSON support, ANSI support, and more.

Plugins are likewise also split into two types:

  • Core plugins - plugins that provide part of the default experience of Nu, including access to the system properties, processes, and web-connectivity features.
  • Extra plugins - these plugins run a wide range of different capabilities like working with different file types, charting, viewing binary data, and more.