github.com/Kong/go-pdk@v0.11.0/request/request.go (about) 1 /* 2 Client request module. 3 4 A set of functions to retrieve information about the incoming requests made by clients. 5 */ 6 package request 7 8 import ( 9 "errors" 10 "io/ioutil" //nolint:all // TODO: update to remove deprecated dependency 11 12 "github.com/Kong/go-pdk/bridge" 13 "github.com/Kong/go-pdk/server/kong_plugin_protocol" 14 "google.golang.org/protobuf/types/known/structpb" 15 ) 16 17 // Holds this module's functions. Accessible as `kong.Request` 18 type Request struct { 19 bridge.PdkBridge 20 } 21 22 // kong.Request.GetScheme() returns the scheme component of the request’s URL. 23 // The returned value is normalized to lower-case form. 24 func (r Request) GetScheme() (s string, err error) { 25 return r.AskString(`kong.request.get_scheme`, nil) 26 } 27 28 // kong.Request.GetHost() returns the host component of the request’s URL, 29 // or the value of the “Host” header. The returned value is normalized 30 // to lower-case form. 31 func (r Request) GetHost() (host string, err error) { 32 return r.AskString(`kong.request.get_host`, nil) 33 } 34 35 // kong.Request.GetPort() returns the port component of the request’s URL. 36 func (r Request) GetPort() (int, error) { 37 return r.AskInt(`kong.request.get_port`, nil) 38 } 39 40 // kong.Request.GetForwardedScheme() returns the scheme component 41 // of the request’s URL, but also considers X-Forwarded-Proto if it 42 // comes from a trusted source. The returned value is normalized to lower-case. 43 // 44 // Whether this function considers X-Forwarded-Proto or not depends 45 // on several Kong configuration parameters: 46 // 47 // - trusted_ips 48 // - real_ip_header 49 // - real_ip_recursive 50 // 51 // Note: support for the Forwarded HTTP Extension (RFC 7239) is not offered yet 52 // since it is not supported by ngx_http_realip_module. 53 func (r Request) GetForwardedScheme() (s string, err error) { 54 return r.AskString(`kong.request.get_forwarded_scheme`, nil) 55 } 56 57 // kong.Request.GetForwardedHost() returns the host component of the request’s URL 58 // or the value of the “host” header. Unlike kong.Request.GetHost(), this function 59 // will also consider X-Forwarded-Host if it comes from a trusted source. 60 // The returned value is normalized to lower-case. 61 // 62 // Whether this function considers X-Forwarded-Proto or not depends 63 // on several Kong configuration parameters: 64 // 65 // - trusted_ips 66 // - real_ip_header 67 // - real_ip_recursive 68 // 69 // Note: we do not currently offer support for Forwarded HTTP Extension (RFC 7239) 70 // since it is not supported by ngx_http_realip_module. 71 func (r Request) GetForwardedHost() (host string, err error) { 72 return r.AskString(`kong.request.get_forwarded_host`, nil) 73 } 74 75 // kong.Request.GetForwardedPort() returns the port component of the request’s URL, 76 // but also considers X-Forwarded-Host if it comes from a trusted source. 77 // 78 // Whether this function considers X-Forwarded-Proto or not depends 79 // on several Kong configuration parameters: 80 // 81 // - trusted_ips 82 // - real_ip_header 83 // - real_ip_recursive 84 // 85 // Note: we do not currently offer support for Forwarded HTTP Extension (RFC 7239) 86 // since it is not supported by ngx_http_realip_module. 87 func (r Request) GetForwardedPort() (int, error) { 88 return r.AskInt(`kong.request.get_forwarded_port`, nil) 89 } 90 91 // kong.Request.GetHttpVersion() returns the HTTP version 92 // used by the client in the request, returning values 93 // such as "1"", "1.1", "2.0", or nil for unrecognized values. 94 func (r Request) GetHttpVersion() (version float64, err error) { 95 return r.AskNumber(`kong.request.get_http_version`, nil) 96 } 97 98 // kong.Request.GetMethod() returns the HTTP method of the request. 99 // The value is normalized to upper-case. 100 func (r Request) GetMethod() (m string, err error) { 101 return r.AskString(`kong.request.get_method`, nil) 102 } 103 104 // kong.Request.GetPath() returns the path component of the request’s URL. 105 // It is not normalized in any way and does not include the querystring. 106 func (r Request) GetPath() (string, error) { 107 return r.AskString(`kong.request.get_path`, nil) 108 } 109 110 // kong.Request.GetPathWithQuery() returns the path, including 111 // the querystring if any. No transformations/normalizations are done. 112 func (r Request) GetPathWithQuery() (string, error) { 113 return r.AskString(`kong.request.get_path_with_query`, nil) 114 } 115 116 // kong.Request.GetRawQuery() returns the query component of the request’s URL. 117 // It is not normalized in any way (not even URL-decoding of special characters) 118 // and does not include the leading ? character. 119 func (r Request) GetRawQuery() (string, error) { 120 return r.AskString(`kong.request.get_raw_query`, nil) 121 } 122 123 // kong.Request.GetQueryArg() returns the value of the specified argument, 124 // obtained from the query arguments of the current request. 125 // 126 // The returned value is either a string, a boolean true if 127 // an argument was not given a value, or nil if no argument with name was found. 128 // 129 // If an argument with the same name is present multiple times in the querystring, 130 // this function will return the value of the first occurrence. 131 func (r Request) GetQueryArg(k string) (string, error) { 132 return r.AskString(`kong.request.get_query_arg`, bridge.WrapString(k)) 133 } 134 135 // kong.Request.GetQuery() returns a map of query arguments 136 // obtained from the querystring. Keys are query argument names. 137 // Values are either a string with the argument value, a boolean true 138 // if an argument was not given a value, or an array if an argument 139 // was given in the query string multiple times. Keys and values are 140 // unescaped according to URL-encoded escaping rules. 141 // 142 // Note that a query string `?foo&bar` translates to two boolean true arguments, 143 // and ?foo=&bar= translates to two string arguments containing empty strings. 144 // 145 // The max_args argument specifies the maximum number of returned arguments. 146 // Must be greater than 1 and not greater than 1000, or -1 to specify the 147 // default limit of 100 arguments. 148 func (r Request) GetQuery(max_args int) (map[string][]string, error) { 149 if max_args == -1 { 150 max_args = 100 151 } 152 153 arg := kong_plugin_protocol.Int{V: int32(max_args)} 154 out := new(structpb.Struct) 155 err := r.Ask("kong.request.get_query", &arg, out) 156 if err != nil { 157 return nil, err 158 } 159 160 return bridge.UnwrapHeaders(out), nil 161 } 162 163 // kong.Request.GetHeader() returns the value of the specified request header. 164 // 165 // The returned value is either a string, or can be nil if a header with name 166 // was not found in the request. If a header with the same name is present 167 // multiple times in the request, this function will return the value of the 168 // first occurrence of this header. 169 // 170 // Header names in are case-insensitive and are normalized to lowercase, 171 // and dashes (-) can be written as underscores (_); that is, the header 172 // X-Custom-Header can also be retrieved as x_custom_header. 173 func (r Request) GetHeader(k string) (string, error) { 174 return r.AskString(`kong.request.get_header`, bridge.WrapString(k)) 175 } 176 177 // kong.Request.GetHeaders() returns a map holding the request headers. 178 // Keys are header names. Values are either a string with the header value, 179 // or an array of strings if a header was sent multiple times. Header names 180 // in this table are case-insensitive and are normalized to lowercase, 181 // and dashes (-) can be written as underscores (_); that is, the header 182 // X-Custom-Header can also be retrieved as x_custom_header. 183 // 184 // The max_args argument specifies the maximum number of returned headers. 185 // Must be greater than 1 and not greater than 1000, or -1 to specify the 186 // default limit of 100 headers. 187 func (r Request) GetHeaders(max_headers int) (map[string][]string, error) { 188 if max_headers == -1 { 189 max_headers = 100 190 } 191 192 arg := kong_plugin_protocol.Int{V: int32(max_headers)} 193 out := new(structpb.Struct) 194 err := r.Ask("kong.request.get_headers", &arg, out) 195 if err != nil { 196 return nil, err 197 } 198 199 return bridge.UnwrapHeaders(out), nil 200 } 201 202 // kong.Request.GetRawBody() returns the plain request body. 203 // 204 // If the body has no size (empty), this function returns an empty string. 205 // 206 // If the size of the body is greater than the Nginx buffer size 207 // (set by client_body_buffer_size), this function will fail 208 // and return an error message explaining this limitation. 209 func (r Request) GetRawBody() ([]byte, error) { 210 out := new(kong_plugin_protocol.RawBodyResult) 211 err := r.Ask(`kong.request.get_raw_body`, nil, out) 212 if err != nil { 213 return nil, err 214 } 215 216 switch x := out.Kind.(type) { 217 case *kong_plugin_protocol.RawBodyResult_Content: 218 return x.Content, nil 219 220 case *kong_plugin_protocol.RawBodyResult_BodyFilepath: 221 return ioutil.ReadFile(x.BodyFilepath) 222 223 case *kong_plugin_protocol.RawBodyResult_Error: 224 return nil, errors.New(x.Error) 225 226 default: 227 return out.GetContent(), nil 228 } 229 } 230 231 // kong.Request.GetUriCaptures() returns the catured URI fragements. 232 // 233 // 234 func (r Request) GetUriCaptures() ([][]byte, map[string][]byte, error) { 235 out := new(kong_plugin_protocol.UriCapturesResult) 236 err := r.Ask("kong.request.get_uri_captures", nil, out) 237 if err != nil { 238 return nil, nil, err 239 } 240 return out.Unnamed, out.Named, nil 241 } 242 243 // TODO get_body