// Copyright (c) 2019-2021 Alexander Medvednikov. All rights reserved. // Use of this source code is governed by an MIT license // that can be found in the LICENSE file. module http import net.urllib const ( max_redirects = 4 content_type_default = 'text/plain' bufsize = 1536 ) // FetchConfig holds configurations of fetch pub struct FetchConfig { pub mut: method Method header Header data string params map[string]string cookies map[string]string user_agent string = 'v.http' verbose bool } 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 pub fn get(url string) ?Response { return fetch_with_method(.get, url, FetchConfig{}) } // 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) ) } // 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 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) ) } // 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) ) } // 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) ) } // head sends a HEAD HTTP request to the URL pub fn head(url string) ?Response { return fetch_with_method(.head, url, FetchConfig{}) } // delete sends a DELETE HTTP request to the URL 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 pub fn fetch(_url string, config FetchConfig) ?Response { if _url == '' { return error('http.fetch: empty url') } url := build_url_from_fetch(_url, config) or { return error('http.fetch: invalid url $_url') } data := config.data req := Request{ method: config.method url: url data: data header: config.header cookies: config.cookies user_agent: config.user_agent user_ptr: 0 verbose: config.verbose } res := req.do() ? return res } // get_text sends a GET HTTP request to the URL and returns the text content of the response pub fn get_text(url string) string { resp := fetch(url, method: .get) or { return '' } return resp.text } // url_encode_form_data converts mapped data to an URL encoded string pub fn url_encode_form_data(data map[string]string) string { mut pieces := []string{} for key_, value_ in data { key := urllib.query_escape(key_) value := urllib.query_escape(value_) pieces << '$key=$value' } return pieces.join('&') } fn fetch_with_method(method Method, url string, _config FetchConfig) ?Response { 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 { return url.str() } mut pieces := []string{cap: config.params.len} for key, val in config.params { pieces << '$key=$val' } 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 { 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 { panic('http.escape_url() was replaced with urllib.query_escape()') } // unescape is deprecated, use urllib.query_escape() instead pub fn unescape(s string) string { panic('http.unescape() was replaced with http.unescape_url()') } // escape is deprecated, use urllib.query_unescape() instead pub fn escape(s string) string { panic('http.escape() was replaced with http.escape_url()') }