1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00
v/vlib/net/http/http.v

176 lines
4.8 KiB
V
Raw Normal View History

// Copyright (c) 2019-2021 Alexander Medvednikov. All rights reserved.
2019-06-23 05:21:30 +03:00
// Use of this source code is governed by an MIT license
// that can be found in the LICENSE file.
2019-06-22 21:20:28 +03:00
module http
2019-08-06 15:43:09 +03:00
import net.urllib
const (
2020-05-16 17:12:23 +03:00
max_redirects = 4
2020-01-16 20:16:11 +03:00
content_type_default = 'text/plain'
bufsize = 1536
)
// FetchConfig holds configurations of fetch
2020-01-16 20:16:11 +03:00
pub struct FetchConfig {
pub mut:
method Method
header Header
data string
params map[string]string
cookies map[string]string
2020-05-20 09:58:57 +03:00
user_agent string = 'v.http'
verbose bool
2020-01-16 20:16:11 +03:00
}
pub fn new_request(method Method, url_ string, data string) ?Request {
url := if method == .get { url_ + '?' + data } else { url_ }
// println('new req() method=$method url="$url" dta="$data"')
return Request{
method: method
url: url
data: data
/*
headers: {
'Accept-Encoding': 'compress'
}
*/
}
}
// get sends a GET HTTP request to the URL
2020-01-16 20:16:11 +03:00
pub fn get(url string) ?Response {
return fetch_with_method(.get, url, FetchConfig{})
2020-01-15 01:19:50 +03:00
}
// post sends a POST HTTP request to the URL with a string data
pub fn post(url string, data string) ?Response {
return fetch_with_method(.post, url,
data: data
header: new_header(key: .content_type, value: http.content_type_default)
)
2020-01-15 01:19:50 +03:00
}
// post_json sends a POST HTTP request to the URL with a JSON data
pub fn post_json(url string, data string) ?Response {
return fetch_with_method(.post, url,
data: data
header: new_header(key: .content_type, value: 'application/json')
)
}
// post_form sends a POST HTTP request to the URL with X-WWW-FORM-URLENCODED data
2020-01-16 20:16:11 +03:00
pub fn post_form(url string, data map[string]string) ?Response {
return fetch_with_method(.post, url,
header: new_header(key: .content_type, value: 'application/x-www-form-urlencoded')
data: url_encode_form_data(data)
)
2020-01-15 01:19:50 +03:00
}
// put sends a PUT HTTP request to the URL with a string data
pub fn put(url string, data string) ?Response {
return fetch_with_method(.put, url,
data: data
header: new_header(key: .content_type, value: http.content_type_default)
)
2020-01-15 01:19:50 +03:00
}
// patch sends a PATCH HTTP request to the URL with a string data
pub fn patch(url string, data string) ?Response {
return fetch_with_method(.patch, url,
data: data
header: new_header(key: .content_type, value: http.content_type_default)
)
2019-07-29 20:18:26 +03:00
}
// head sends a HEAD HTTP request to the URL
2020-01-16 20:16:11 +03:00
pub fn head(url string) ?Response {
return fetch_with_method(.head, url, FetchConfig{})
2019-06-22 21:20:28 +03:00
}
// delete sends a DELETE HTTP request to the URL
2020-01-16 20:16:11 +03:00
pub fn delete(url string) ?Response {
return fetch_with_method(.delete, url, FetchConfig{})
}
// fetch sends an HTTP request to the URL with the given method and configurations
2020-01-16 20:16:11 +03:00
pub fn fetch(_url string, config FetchConfig) ?Response {
2019-07-29 20:18:26 +03:00
if _url == '' {
2020-01-16 20:16:11 +03:00
return error('http.fetch: empty url')
2019-07-29 20:18:26 +03:00
}
url := build_url_from_fetch(_url, config) or { return error('http.fetch: invalid url $_url') }
2020-01-16 20:16:11 +03:00
data := config.data
req := Request{
method: config.method
url: url
data: data
header: config.header
2020-01-16 20:16:11 +03:00
cookies: config.cookies
user_agent: config.user_agent
2019-06-22 21:20:28 +03:00
user_ptr: 0
2020-01-16 20:16:11 +03:00
verbose: config.verbose
2019-06-22 21:20:28 +03:00
}
res := req.do() ?
2020-01-16 20:16:11 +03:00
return res
2019-06-22 21:20:28 +03:00
}
// get_text sends a GET HTTP request to the URL and returns the text content of the response
2019-07-31 23:10:28 +03:00
pub fn get_text(url string) string {
resp := fetch(url, method: .get) or { return '' }
2019-10-24 19:44:49 +03:00
return resp.text
}
2019-07-31 23:10:28 +03:00
// url_encode_form_data converts mapped data to an URL encoded string
2020-01-16 20:16:11 +03:00
pub fn url_encode_form_data(data map[string]string) string {
2020-04-26 14:49:31 +03:00
mut pieces := []string{}
for key_, value_ in data {
key := urllib.query_escape(key_)
value := urllib.query_escape(value_)
2020-01-16 20:16:11 +03:00
pieces << '$key=$value'
}
return pieces.join('&')
}
fn fetch_with_method(method Method, url string, _config FetchConfig) ?Response {
2020-01-16 20:16:11 +03:00
mut config := _config
config.method = method
return fetch(url, config)
}
fn build_url_from_fetch(_url string, config FetchConfig) ?string {
mut url := urllib.parse(_url) ?
if config.params.len == 0 {
2020-01-16 20:16:11 +03:00
return url.str()
}
mut pieces := []string{cap: config.params.len}
for key, val in config.params {
pieces << '$key=$val'
2020-01-16 20:16:11 +03:00
}
mut query := pieces.join('&')
if url.raw_query.len > 1 {
query = url.raw_query + '&' + query
}
url.raw_query = query
return url.str()
}
// unescape_url is deprecated, use urllib.query_unescape() instead
pub fn unescape_url(s string) string {
2019-10-24 19:44:49 +03:00
panic('http.unescape_url() was replaced with urllib.query_unescape()')
}
// escape_url is deprecated, use urllib.query_escape() instead
pub fn escape_url(s string) string {
2019-10-24 19:44:49 +03:00
panic('http.escape_url() was replaced with urllib.query_escape()')
}
// unescape is deprecated, use urllib.query_escape() instead
pub fn unescape(s string) string {
2019-10-24 19:44:49 +03:00
panic('http.unescape() was replaced with http.unescape_url()')
}
// escape is deprecated, use urllib.query_unescape() instead
pub fn escape(s string) string {
2019-10-24 19:44:49 +03:00
panic('http.escape() was replaced with http.escape_url()')
}