nu_command/network/http/
http_.rs

1use nu_engine::{command_prelude::*, get_full_help};
2
3use super::get::run_get;
4use super::post::run_post;
5
6#[derive(Clone)]
7pub struct Http;
8
9impl Command for Http {
10    fn name(&self) -> &str {
11        "http"
12    }
13
14    fn signature(&self) -> Signature {
15        Signature::build("http")
16            .input_output_types(vec![(Type::Nothing, Type::Any)])
17            // common to get more than help. Get by default
18            .optional(
19                "URL",
20                SyntaxShape::String,
21                "The URL to fetch the contents from.",
22            )
23            // post
24            .optional(
25                "data",
26                SyntaxShape::Any,
27                "The contents of the post body. Required unless part of a pipeline.",
28            )
29            .named(
30                "content-type",
31                SyntaxShape::Any,
32                "the MIME type of content to post",
33                Some('t'),
34            )
35            // common
36            .named(
37                "user",
38                SyntaxShape::Any,
39                "the username when authenticating",
40                Some('u'),
41            )
42            .named(
43                "password",
44                SyntaxShape::Any,
45                "the password when authenticating",
46                Some('p'),
47            )
48            .named(
49                "max-time",
50                SyntaxShape::Duration,
51                "max duration before timeout occurs",
52                Some('m'),
53            )
54            .named(
55                "headers",
56                SyntaxShape::Any,
57                "custom headers you want to add ",
58                Some('H'),
59            )
60            .switch(
61                "raw",
62                "fetch contents as text rather than a table",
63                Some('r'),
64            )
65            .switch(
66                "insecure",
67                "allow insecure server connections when using SSL",
68                Some('k'),
69            )
70            .switch(
71                "full",
72                "returns the full response instead of only the body",
73                Some('f'),
74            )
75            .switch(
76                "allow-errors",
77                "do not fail if the server returns an error code",
78                Some('e'),
79            )
80            .named(
81                "redirect-mode",
82                SyntaxShape::String,
83                "What to do when encountering redirects. Default: 'follow'. Valid options: 'follow' ('f'), 'manual' ('m'), 'error' ('e').",
84                Some('R')
85            )
86            .category(Category::Network)
87    }
88
89    fn description(&self) -> &str {
90        "Various commands for working with http methods."
91    }
92
93    fn extra_description(&self) -> &str {
94        "Without a subcommand but with a URL provided, it performs a GET request by default or a POST request if data is provided. You can use one of the following subcommands. Using this command as-is will only display this help message."
95    }
96
97    fn search_terms(&self) -> Vec<&str> {
98        vec![
99            "network", "fetch", "pull", "request", "download", "curl", "wget",
100        ]
101    }
102
103    fn run(
104        &self,
105        engine_state: &EngineState,
106        stack: &mut Stack,
107        call: &Call,
108        input: PipelineData,
109    ) -> Result<PipelineData, ShellError> {
110        let url = call.opt::<Value>(engine_state, stack, 0)?;
111        let data = call.opt::<Value>(engine_state, stack, 1)?;
112        match (url.is_some(), data.is_some()) {
113            (true, true) => run_post(engine_state, stack, call, input),
114            (true, false) => run_get(engine_state, stack, call, input),
115            (false, true) => Err(ShellError::NushellFailed {
116                msg: (String::from("Default verb is get with a payload. Impossible state")),
117            }),
118            (false, false) => Ok(Value::string(
119                get_full_help(self, engine_state, stack),
120                call.head,
121            )
122            .into_pipeline_data()),
123        }
124    }
125
126    fn examples(&self) -> Vec<Example> {
127        vec![
128            Example {
129                description: "Get content from example.com with default verb",
130                example: "http https://www.example.com",
131                result: None,
132            },
133            Example {
134                description: "Post content to example.com with default verb",
135                example: "http https://www.example.com 'body'",
136                result: None,
137            },
138            Example {
139                description: "Get content from example.com with explicit verb",
140                example: "http get https://www.example.com",
141                result: None,
142            },
143        ]
144    }
145}