checker: requre & in struct init; http: chunked encoding
parent
88e6d987d6
commit
4f307c1a78
|
@ -1224,6 +1224,21 @@ pub fn (s string) all_after(dot string) string {
|
|||
|
||||
pub fn (s string) after(dot string) string { return s.all_after(dot) }
|
||||
|
||||
pub fn (s string) after_char(dot byte) string {
|
||||
mut pos := 0
|
||||
for i, c in s {
|
||||
if c == dot {
|
||||
pos = i
|
||||
break
|
||||
}
|
||||
}
|
||||
if pos == 0 {
|
||||
return s
|
||||
}
|
||||
return s.right(pos+1)
|
||||
|
||||
}
|
||||
|
||||
// fn (s []string) substr(a, b int) string {
|
||||
// return join_strings(s.slice_fast(a, b))
|
||||
// }
|
||||
|
|
|
@ -463,6 +463,9 @@ fn test_all_after() {
|
|||
assert s.all_after('fn ') == 'hello'
|
||||
assert s.all_after('test') == s
|
||||
assert s.all_after('') == s
|
||||
assert s.after('e') == 'llo'
|
||||
x := s.after('e')
|
||||
assert x == 'llo'
|
||||
}
|
||||
|
||||
fn test_reverse() {
|
||||
|
|
|
@ -26,7 +26,7 @@ struct User {
|
|||
nums []int
|
||||
last_name string [json:lastName]
|
||||
is_registered bool [json:IsRegistered]
|
||||
typ int [json:'type']
|
||||
typ int [json:'type']
|
||||
pets string [raw; json:'pet_animals']
|
||||
}
|
||||
|
||||
|
@ -47,7 +47,7 @@ fn test_parse_user() {
|
|||
assert u.nums[0] == 1
|
||||
assert u.nums[1] == 2
|
||||
assert u.nums[2] == 3
|
||||
assert u.typ == 1
|
||||
assert u.typ == 1
|
||||
assert u.pets == '{"name":"Bob","animal":"Dog"}'
|
||||
}
|
||||
|
||||
|
@ -73,3 +73,25 @@ fn test_raw_json_field() {
|
|||
assert color.space == 'YCbCr'
|
||||
}
|
||||
|
||||
struct City {
|
||||
name string
|
||||
}
|
||||
|
||||
struct Country {
|
||||
cities []City
|
||||
name string
|
||||
}
|
||||
|
||||
fn test_struct_in_struct() {
|
||||
country := json.decode(Country, '{ "name": "UK", "cities": [{"name":"London"}, {"name":"Manchester"}]}') or {
|
||||
assert false
|
||||
exit(1)
|
||||
}
|
||||
assert country.name == 'UK'
|
||||
assert country.cities.len == 2
|
||||
assert country.cities[0].name == 'London'
|
||||
assert country.cities[1].name == 'Manchester'
|
||||
println(country.cities)
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -69,7 +69,7 @@ fn C.SSL_set_tlsext_host_name() int
|
|||
fn C.BIO_puts()
|
||||
|
||||
|
||||
fn C.BIO_read()
|
||||
fn C.BIO_read() int
|
||||
|
||||
|
||||
fn C.BIO_free_all()
|
||||
|
@ -83,6 +83,10 @@ fn init() int {
|
|||
return 1
|
||||
}
|
||||
|
||||
const (
|
||||
buf_size = 500 // 1536
|
||||
)
|
||||
|
||||
fn (req &Request) ssl_do(port int, method, host_name, path string) ?Response {
|
||||
// ssl_method := C.SSLv23_method()
|
||||
ssl_method := C.TLSv1_2_method()
|
||||
|
@ -111,6 +115,7 @@ fn (req &Request) ssl_do(port int, method, host_name, path string) ?Response {
|
|||
preferred_ciphers := 'HIGH:!aNULL:!kRSA:!PSK:!SRP:!MD5:!RC4'
|
||||
res = C.SSL_set_cipher_list(ssl, preferred_ciphers.str)
|
||||
if res != 1 {
|
||||
println('http: openssl: cipher failed')
|
||||
}
|
||||
res = C.SSL_set_tlsext_host_name(ssl, host_name.str)
|
||||
res = C.BIO_do_connect(web)
|
||||
|
@ -121,18 +126,44 @@ fn (req &Request) ssl_do(port int, method, host_name, path string) ?Response {
|
|||
C.SSL_get_peer_certificate(ssl)
|
||||
res = C.SSL_get_verify_result(ssl)
|
||||
// /////
|
||||
s := req.build_request_headers(method, host_name, path)
|
||||
C.BIO_puts(web, s.str)
|
||||
req_headers := req.build_request_headers(method, host_name, path)
|
||||
C.BIO_puts(web, req_headers.str)
|
||||
mut headers := strings.new_builder(100)
|
||||
mut h := ''
|
||||
mut headers_done := false
|
||||
mut sb := strings.new_builder(100)
|
||||
mut buff := [buf_size]byte
|
||||
mut is_chunk_encoding := false
|
||||
for {
|
||||
buff := [1536]byte
|
||||
len := int(C.BIO_read(web, buff, 1536))
|
||||
if len > 0 {
|
||||
sb.write(tos(buff, len))
|
||||
}
|
||||
else {
|
||||
len := C.BIO_read(web, buff, buf_size)
|
||||
if len <= 0 {
|
||||
break
|
||||
}
|
||||
mut chunk := (tos(buff, len))
|
||||
if !headers_done && chunk.contains('\r\n\r\n') {
|
||||
headers_done = true
|
||||
headers.write(chunk.all_before('\r\n'))
|
||||
h = headers.str()
|
||||
//println(h)
|
||||
sb.write(chunk.after('\r\n'))
|
||||
// TODO for some reason this can be missing from headers
|
||||
is_chunk_encoding = true //h.contains('chunked')
|
||||
//println(sb.str())
|
||||
continue
|
||||
}
|
||||
// TODO clean this up
|
||||
if is_chunk_encoding && len > 6 && ((buff[3] == 13 && buff[4] == 10) || (buff[2] ==13 && buff[3]==10)
|
||||
|| (buff[4] == 13 && buff[5] == 10) ) {
|
||||
chunk = chunk.after_char(10)
|
||||
}
|
||||
if chunk.len > 3 && chunk[chunk.len-2] == 13 && chunk[chunk.len-1] == 10 {
|
||||
chunk = chunk[..chunk.len-2]
|
||||
}
|
||||
if headers_done {
|
||||
sb.write(chunk)
|
||||
} else {
|
||||
headers.write(chunk)
|
||||
}
|
||||
}
|
||||
if !isnil(web) {
|
||||
C.BIO_free_all(web)
|
||||
|
@ -140,6 +171,8 @@ fn (req &Request) ssl_do(port int, method, host_name, path string) ?Response {
|
|||
if !isnil(ctx) {
|
||||
C.SSL_CTX_free(ctx)
|
||||
}
|
||||
return parse_response(sb.str())
|
||||
body:= sb.str()
|
||||
println(body)
|
||||
return parse_response(h +'\r\n\r\n'+ body)
|
||||
}
|
||||
|
||||
|
|
|
@ -45,11 +45,16 @@ pub:
|
|||
|
||||
pub fn new_request(method, url_, data string) ?Request {
|
||||
url := if method == 'GET' { url_ + '?' + data } else { url_ }
|
||||
// println('new req() method=$method url="$url" dta="$data"')
|
||||
//println('new req() method=$method url="$url" dta="$data"')
|
||||
return Request{
|
||||
method: method.to_upper()
|
||||
url: url
|
||||
data: data
|
||||
/*
|
||||
headers: {
|
||||
'Accept-Encoding': 'compress'
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -355,6 +355,10 @@ pub fn (mut c Checker) struct_init(mut struct_init ast.StructInit) table.Type {
|
|||
c.error('cannot assign `$expr_type_sym.name` as `$field_type_sym.name` for field `$info_field.name`',
|
||||
field.pos)
|
||||
}
|
||||
if info_field.typ.is_ptr() && !expr_type.is_ptr() && !expr_type.is_number(){
|
||||
c.error('ref', field.pos)
|
||||
}
|
||||
|
||||
struct_init.fields[i].typ = expr_type
|
||||
struct_init.fields[i].expected_type = info_field.typ
|
||||
}
|
||||
|
|
|
@ -2274,6 +2274,9 @@ fn (mut g Gen) struct_init(struct_init ast.StructInit) {
|
|||
}
|
||||
}
|
||||
if !cloned {
|
||||
if field.expected_type.is_ptr() && !field.typ.is_ptr() && !field.typ.is_number() {
|
||||
g.write('/* autoref */&')
|
||||
}
|
||||
g.expr_with_cast(field.expr, field.typ, field.expected_type)
|
||||
}
|
||||
g.writeln(',')
|
||||
|
|
Loading…
Reference in New Issue