http: send headers and request data
							parent
							
								
									57880aed18
								
							
						
					
					
						commit
						a62e6b127a
					
				|  | @ -38,7 +38,7 @@ fn init_module() { | ||||||
| 	//C.OPENSSL_config(0) 
 | 	//C.OPENSSL_config(0) 
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn ssl_do(port int, method, host_name, path string) Response { | fn (req &Request) ssl_do(port int, method, host_name, path string) Response { | ||||||
| 	//ssl_method := C.SSLv23_method() 
 | 	//ssl_method := C.SSLv23_method() 
 | ||||||
| 	ssl_method := C.TLSv1_2_method()  | 	ssl_method := C.TLSv1_2_method()  | ||||||
| 	if isnil(method) {  | 	if isnil(method) {  | ||||||
|  | @ -73,7 +73,7 @@ fn ssl_do(port int, method, host_name, path string) Response { | ||||||
| 	cert := C.SSL_get_peer_certificate(ssl)  | 	cert := C.SSL_get_peer_certificate(ssl)  | ||||||
| 	res = C.SSL_get_verify_result(ssl)  | 	res = C.SSL_get_verify_result(ssl)  | ||||||
| 	///////
 | 	///////
 | ||||||
| 	s := build_request_headers('', method, host_name, path) | 	s := req.build_request_headers(method, host_name, path) | ||||||
| 	C.BIO_puts(web, s.str)  | 	C.BIO_puts(web, s.str)  | ||||||
| 	mut sb := strings.new_builder(100)  | 	mut sb := strings.new_builder(100)  | ||||||
| 	for { | 	for { | ||||||
|  |  | ||||||
|  | @ -16,14 +16,14 @@ import net.urllib | ||||||
| 
 | 
 | ||||||
| fn init_module() {} | fn init_module() {} | ||||||
| 
 | 
 | ||||||
| fn ssl_do(port int, method, host_name, path string) Response { | fn (req &Request) ssl_do(port int, method, host_name, path string) Response { | ||||||
| 	C.vschannel_init() | 	C.vschannel_init() | ||||||
| 	// TODO: joe-c
 | 	// TODO: joe-c
 | ||||||
| 	// dynamically increase in vschannel.c if needed
 | 	// dynamically increase in vschannel.c if needed
 | ||||||
| 	mut buff := malloc(44000) | 	mut buff := malloc(44000) | ||||||
| 	addr := host_name | 	addr := host_name | ||||||
| 	req := build_request_headers('', method, host_name, path) | 	sdata := req.build_request_headers(method, host_name, path) | ||||||
| 	length := int(C.request(port, addr.str, req.str, buff)) | 	length := int(C.request(port, addr.str, sdata.str, buff)) | ||||||
| 
 | 
 | ||||||
| 	C.vschannel_cleanup() | 	C.vschannel_cleanup() | ||||||
| 	return parse_response(string(buff, length)) | 	return parse_response(string(buff, length)) | ||||||
|  |  | ||||||
|  | @ -25,6 +25,7 @@ pub: | ||||||
| 	ws_func  voidptr | 	ws_func  voidptr | ||||||
| 	user_ptr voidptr | 	user_ptr voidptr | ||||||
| 	verbose  bool | 	verbose  bool | ||||||
|  | 	user_agent string | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| struct Response { | struct Response { | ||||||
|  | @ -66,6 +67,7 @@ pub fn new_request(typ, _url, _data string) ?Request { | ||||||
| 		ws_func: 0 | 		ws_func: 0 | ||||||
| 		user_ptr: 0 | 		user_ptr: 0 | ||||||
| 		headers: map[string]string | 		headers: map[string]string | ||||||
|  | 		user_agent: 'v' | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -109,7 +111,7 @@ pub fn (req &Request) do() ?Response { | ||||||
| 	mut no_redirects := 0 | 	mut no_redirects := 0 | ||||||
| 	for { | 	for { | ||||||
| 		if no_redirects == max_redirects { return error('http.request.do: maximum number of redirects reached ($max_redirects)') } | 		if no_redirects == max_redirects { return error('http.request.do: maximum number of redirects reached ($max_redirects)') } | ||||||
| 		qresp := method_and_url_to_response( req.typ, rurl ) or {	return error(err) } | 		qresp := req.method_and_url_to_response( req.typ, rurl ) or {	return error(err) } | ||||||
| 		resp = qresp | 		resp = qresp | ||||||
| 		if ! (resp.status_code in [301, 302, 303, 307, 308]) { break } | 		if ! (resp.status_code in [301, 302, 303, 307, 308]) { break } | ||||||
| 		// follow any redirects
 | 		// follow any redirects
 | ||||||
|  | @ -121,9 +123,9 @@ pub fn (req &Request) do() ?Response { | ||||||
| 	return resp | 	return resp | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn method_and_url_to_response(method string, url net_dot_urllib.URL) ?Response { | fn (req &Request) method_and_url_to_response(method string, url net_dot_urllib.URL) ?Response { | ||||||
|   host_name := url.hostname() | 	host_name := url.hostname() | ||||||
|   scheme := url.scheme | 	scheme := url.scheme | ||||||
| 	mut p := url.path.trim_left('/') | 	mut p := url.path.trim_left('/') | ||||||
| 	mut path := if url.query().size > 0 { '/$p?${url.query().encode()}' } else { '/$p' } | 	mut path := if url.query().size > 0 { '/$p?${url.query().encode()}' } else { '/$p' } | ||||||
| 	mut nport := url.port().int() | 	mut nport := url.port().int() | ||||||
|  | @ -134,10 +136,10 @@ fn method_and_url_to_response(method string, url net_dot_urllib.URL) ?Response { | ||||||
| 	//println('fetch $method, $scheme, $host_name, $nport, $path ')
 | 	//println('fetch $method, $scheme, $host_name, $nport, $path ')
 | ||||||
| 	if scheme == 'https' { | 	if scheme == 'https' { | ||||||
| 		//println('ssl_do( $nport, $method, $host_name, $path )')
 | 		//println('ssl_do( $nport, $method, $host_name, $path )')
 | ||||||
| 		return ssl_do( nport, method, host_name, path ) | 		return req.ssl_do( nport, method, host_name, path ) | ||||||
| 	} else if scheme == 'http' { | 	} else if scheme == 'http' { | ||||||
| 		//println('http_do( $nport, $method, $host_name, $path )')
 | 		//println('http_do( $nport, $method, $host_name, $path )')
 | ||||||
| 		return http_do( nport, method, host_name, path ) | 		return req.http_do(nport, method, host_name, path ) | ||||||
| 	} | 	} | ||||||
| 	return error('http.request.do: unsupported scheme: $scheme') | 	return error('http.request.do: unsupported scheme: $scheme') | ||||||
| } | } | ||||||
|  | @ -190,12 +192,21 @@ fn parse_response(resp string) Response { | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn build_request_headers(user_agent, method, host_name, path string) string { | fn (req &Request) build_request_headers(method, host_name, path string) string { | ||||||
| 	ua := if user_agent == '' { 'v' } else { user_agent } | 	ua := req.user_agent | ||||||
|  | 	mut uheaders := []string | ||||||
|  | 	for key, val in req.headers {	 | ||||||
|  | 		uheaders << '${key}: ${val}\r\n'  | ||||||
|  | 	} | ||||||
|  | 	if req.data.len > 0 { | ||||||
|  | 		uheaders << 'Content-Length: ${req.data.len}\r\n' | ||||||
|  | 	} | ||||||
| 	return '$method $path HTTP/1.1\r\n' +  | 	return '$method $path HTTP/1.1\r\n' +  | ||||||
| 		   'Host: $host_name\r\n' +  | 		'Host: $host_name\r\n' +  | ||||||
| 		   'User-Agent: $ua\r\n' + | 		'User-Agent: $ua\r\n' + | ||||||
| 		   'Connection: close\r\n\r\n' | 		uheaders.join('') + | ||||||
|  | 		'Connection: close\r\n\r\n' +  | ||||||
|  | 		req.data | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub fn unescape_url(s string) string { | pub fn unescape_url(s string) string { | ||||||
|  |  | ||||||
|  | @ -3,11 +3,11 @@ module http | ||||||
| import net | import net | ||||||
| import strings | import strings | ||||||
| 
 | 
 | ||||||
| fn http_do(port int, method, host_name, path string) ?Response { | fn (req &Request) http_do(port int, method, host_name, path string) ?Response { | ||||||
| 	bufsize := 512 | 	bufsize := 512 | ||||||
| 	rbuffer := [512]byte | 	rbuffer := [512]byte | ||||||
| 	mut sb := strings.new_builder(100) | 	mut sb := strings.new_builder(100) | ||||||
| 	s := build_request_headers('', method, host_name, path) | 	s := req.build_request_headers(method, host_name, path) | ||||||
| 	 | 	 | ||||||
| 	client := net.dial( host_name, port) or { return error(err) } | 	client := net.dial( host_name, port) or { return error(err) } | ||||||
| 	client.send( s.str, s.len ) | 	client.send( s.str, s.len ) | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue