1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00
v/http/http_mac.v
Alexander Medvednikov 20b5c4b88b Remove println2
2019-06-23 10:03:03 +02:00

207 lines
5.2 KiB
Go
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Copyright (c) 2019 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
#include <curl/curl.h>
#flag windows -I/usr/local/opt/curl/include
#flag darwin -lcurl
#flag windows -lcurl
#flag linux -lcurl
@size_t kek
@CURL* curl_easy_init
type wsfn fn (s string, ptr voidptr)
struct MemoryStruct {
size size_t
ws_func wsfn
user_ptr voidptr // for wsfn
strings []string
}
import const (
CURLOPT_WRITEFUNCTION
CURLOPT_SSL_VERIFYPEER
CURLOPT_HEADERFUNCTION
CURLOPT_WRITEDATA
CURLOPT_HEADERDATA
CURLOPT_FOLLOWLOCATION
CURLOPT_URL
CURLOPT_VERBOSE
CURLOPT_HTTP_VERSION
CURL_HTTP_VERSION_1_1
CURLOPT_HTTPHEADER
CURLOPT_POSTFIELDS
CURLOPT_CUSTOMREQUEST
CURLOPT_TCP_KEEPALIVE
CURLE_OK
)
// type C.CURLcode {
// }
fn C.curl_easy_strerror(curl voidptr) byteptr
fn C.curl_easy_perform(curl voidptr) C.CURLcode
fn write_fn(contents byteptr, size, nmemb int, _mem *MemoryStruct) int {
mut mem = _mem
// # printf("size =%d nmemb=%d contents=%s\n", size, nmemb, contents);
realsize := size * nmemb// TODO size_t ?
// if !isnil(mem.ws_func) {
# if (mem->ws_func)
{
C.printf('\n\nhttp_mac.m: GOT WS FUNC. size=%d\n', realsize)
// Skip negative and 0 junk chars in the WS string
mut start := 0
for i := 0; i < realsize; i++ {
// printf("char=%d %c\n", s[i], s[i]);
if contents[i] == 0 && start == 0 {
start = i
break
}
}
contents += start + 1
// printf("GOOD CONTEnTS=%s\n", contents);
s := tos_no_len(contents)
// mem.ws_func('kek', 0)
# mem->ws_func(s, mem->user_ptr);
}
mut c := tos_no_len(contents)
c = c.trim_space()
// Need to clone because libcurl reuses this memory
mem.strings << c.clone()
return realsize
}
struct C.curl_slist { }
fn (req &Request) do() Response {
println('req.do() mac/linux url="$req.url" data="$req.data"')
// println('req.do() url="$req.url"')
/*
mut resp := Response {
headers: map[string]string{}
}
*/
mut headers := map[string]string{}
// no data at this point
chunk := MemoryStruct {
ws_func: req.ws_func
user_ptr: req.user_ptr
}
// header chunk
hchunk := MemoryStruct {
ws_func: 0
user_ptr: 0
}
// init curl
curl := C.curl_easy_init()
if isnil(curl) {
println('curl init failed')
return Response{}
}
// options
// url2 := req.url.clone()
C.curl_easy_setopt(curl, CURLOPT_URL, req.url.cstr())// ..clone())
// C.curl_easy_setopt(curl, CURLOPT_URL, 'http://example.com')
// return resp
// curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
$if windows {
C.curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0)
}
C.curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_fn)
C.curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, write_fn)
C.curl_easy_setopt(curl, CURLOPT_WRITEDATA, &chunk)
C.curl_easy_setopt(curl, CURLOPT_HEADERDATA, &hchunk)
C.curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1)
if req.typ == 'POST' {
C.curl_easy_setopt(curl, CURLOPT_POSTFIELDS, req.data.cstr())
C.curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, 'POST')
// req.headers << 'Content-Type: application/x-www-form-urlencoded'
}
// Add request headers
mut hlist := &C.curl_slist{!}
// for i, h := range req.headers {
for entry in req.headers.entries {
key := entry.key
val := req.headers[key]
h := '$key: $val'
hlist = C.curl_slist_append(hlist, h.cstr())
}
// curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, // (long)CURL_HTTP_VERSION_2TLS);<3B>`C<>ʀ9<CA80>
C.curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1)
if req.verbose {
C.curl_easy_setopt(curl, CURLOPT_VERBOSE, 1)
}
C.curl_easy_setopt(curl, CURLOPT_HTTPHEADER, hlist)
C.curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1)
C.curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1)
println('bef easy()')
res := C.curl_easy_perform(curl)
println('after easy()')
# if (res != CURLE_OK )
{
err := C.curl_easy_strerror(res)
println('curl_easy_perform() failed: $err')
}
body := chunk.strings.join('')// tos_no_len(chunk.memory)
// chunk.strings.free()
// resp.headers = hchunk.strings
if hchunk.strings.len == 0 {
return Response{}
}
first_header := hchunk.strings.first()
mut status_code := 0
if first_header.contains('HTTP/') {
val := first_header.find_between(' ', ' ')
status_code = val.to_i()
}
// Build resp headers map
// println('building resp headers hchunk.strings.len')
for h in hchunk.strings {
// break
// println(h)
vals := h.split(':')
pos := h.index(':')
if pos == -1 {
continue
}
if h.contains('Content-Type') {
continue
}
key := h.left(pos)
val := h.right(pos + 1)
// println('"$key" *** "$val"')
// val2 := val.trim_space()
// println('val2="$val2"')
headers[key] = val// val.trim_space()
}
// println('done')
// j.println(resp.status_code)
// println('body=')
// j.println(resp.body)
// j.println('headers=')
// j.println(hchunk.strings)
C.curl_easy_cleanup(curl)
println('end of req.do() url="$req.url"')
return Response {
body: body
}
}
fn unescape(s string) string {
return tos2(C.curl_unescape(s.cstr(), s.len))
}
fn escape(s string) string {
return tos2(C.curl_escape(s.cstr(), s.len))
}
// ////////////////
fn (req &Request) do2() Response {
mut resp := Response{}
return resp
}