mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
http: follow redirects (openssl & schannel) + fix url params
This commit is contained in:
parent
a4e648627e
commit
56566ba3d0
@ -93,5 +93,5 @@ fn ssl_do(method, host_name, path string) Response {
|
|||||||
C.SSL_CTX_free(ctx)
|
C.SSL_CTX_free(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
return parse_response(sb.str() )
|
return parse_response(sb.str())
|
||||||
}
|
}
|
||||||
|
@ -14,10 +14,6 @@ import net.urllib
|
|||||||
|
|
||||||
#include "vschannel.c"
|
#include "vschannel.c"
|
||||||
|
|
||||||
const (
|
|
||||||
max_redirects = 4
|
|
||||||
)
|
|
||||||
|
|
||||||
fn init_module() {}
|
fn init_module() {}
|
||||||
|
|
||||||
fn ssl_do(method, host_name, path string) Response {
|
fn ssl_do(method, host_name, path string) Response {
|
||||||
@ -26,22 +22,9 @@ fn ssl_do(method, host_name, path string) Response {
|
|||||||
// dynamically increase in vschannel.c if needed
|
// dynamically increase in vschannel.c if needed
|
||||||
mut buff := malloc(44000)
|
mut buff := malloc(44000)
|
||||||
|
|
||||||
mut p := if path == '' { '/' } else { path }
|
p := if path == '' { '/' } else { path }
|
||||||
mut req := build_request_headers('', method, host_name, p)
|
req := build_request_headers('', method, host_name, p)
|
||||||
mut length := int(C.request(host_name.str, req.str, buff))
|
length := int(C.request(host_name.str, req.str, buff))
|
||||||
mut resp := parse_response(string(buff, length))
|
|
||||||
|
|
||||||
mut no_redirects := 0
|
return parse_response(string(buff, length))
|
||||||
for resp.status_code == 301 && no_redirects <= max_redirects {
|
|
||||||
u := urllib.parse(resp.headers['Location']) or { break }
|
|
||||||
p = if u.path == '' { '/' } else { u.path }
|
|
||||||
req = build_request_headers('', method, u.hostname(), p)
|
|
||||||
length = int(C.request(u.hostname().str, req.str, buff))
|
|
||||||
resp = parse_response(string(buff, length))
|
|
||||||
no_redirects++
|
|
||||||
}
|
|
||||||
|
|
||||||
free(buff)
|
|
||||||
C.vschannel_cleanup()
|
|
||||||
return resp
|
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,10 @@ module http
|
|||||||
import net.urllib
|
import net.urllib
|
||||||
import http.chunked
|
import http.chunked
|
||||||
|
|
||||||
|
const (
|
||||||
|
max_redirects = 4
|
||||||
|
)
|
||||||
|
|
||||||
struct Request {
|
struct Request {
|
||||||
pub:
|
pub:
|
||||||
headers2 []string
|
headers2 []string
|
||||||
@ -100,15 +104,33 @@ pub fn (req &Request) do() Response {
|
|||||||
//h := '$key: $val'
|
//h := '$key: $val'
|
||||||
}
|
}
|
||||||
url := urllib.parse(req.url) or {
|
url := urllib.parse(req.url) or {
|
||||||
// panic('http.request.do: invalid URL $req.url'
|
panic('http.request.do: invalid URL $req.url')
|
||||||
return Response{} //error('ff')}
|
// return Response{} //error('ff')}
|
||||||
}
|
}
|
||||||
is_ssl := url.scheme == 'https'
|
is_ssl := url.scheme == 'https'
|
||||||
if !is_ssl {
|
if !is_ssl {
|
||||||
panic('non https requests are not supported right now')
|
panic('non https requests are not supported right now')
|
||||||
}
|
}
|
||||||
|
|
||||||
return ssl_do(req.typ, url.hostname(), url.path)
|
// first request
|
||||||
|
mut u := if url.query().size > 0 { '$url.path?${url.query().encode()}' } else { url.path }
|
||||||
|
mut resp := ssl_do(req.typ, url.hostname(), u)
|
||||||
|
// follow any redirects
|
||||||
|
mut no_redirects := 0
|
||||||
|
for resp.status_code in [301, 302, 303, 307 ,308] {
|
||||||
|
if no_redirects == max_redirects {
|
||||||
|
panic('http.request.do: maximum number of redirects reached ($max_redirects)')
|
||||||
|
}
|
||||||
|
h_loc := resp.headers['Location']
|
||||||
|
r_url := urllib.parse(h_loc) or {
|
||||||
|
panic('http.request.do: cannot follow redirect, location header has invalid url $h_loc')
|
||||||
|
}
|
||||||
|
u = if r_url.query().size > 0 { '$r_url.path?${r_url.query().encode()}' } else { r_url.path }
|
||||||
|
resp = ssl_do(req.typ, r_url.hostname(), u)
|
||||||
|
no_redirects++
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_response(resp string) Response {
|
fn parse_response(resp string) Response {
|
||||||
|
Loading…
Reference in New Issue
Block a user