http: initial windows schannel http support

pull/1532/head
joe-conigliaro 2019-08-09 20:52:14 +10:00 committed by Alexander Medvednikov
parent 181a39d752
commit d9a83481a5
6 changed files with 1246 additions and 3 deletions

1161
thirdparty/vschannel/vschannel.c vendored 100644

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,47 @@
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <winsock.h>
#include <wincrypt.h>
#include <wintrust.h>
#include <schannel.h>
#define SECURITY_WIN32
#include <security.h>
#include <sspi.h>
#define IO_BUFFER_SIZE 0x10000
#define TLS_MAX_BUFSIZ 32768
// Define here to be sure
#define SP_PROT_TLS1_2_CLIENT 0x00000800
INT request(CHAR *host, CHAR *req, CHAR *out);
static SECURITY_STATUS create_credentials(PCredHandle phCreds);
static INT connect_to_server(CHAR *host, INT port_number, SOCKET *pSocket);
static SECURITY_STATUS perform_client_handshake(
SOCKET Socket, PCredHandle phCreds, CHAR *host,
CtxtHandle *phContext, SecBuffer *pExtraData);
static SECURITY_STATUS client_handshake_loop(
SOCKET Socket, PCredHandle phCreds, CtxtHandle *phContext,
BOOL fDoInitialRead, SecBuffer *pExtraData);
static SECURITY_STATUS https_make_request(
SOCKET Socket, PCredHandle phCreds,
CtxtHandle *phContext, CHAR *req, CHAR *out, int *length);
// CtxtHandle *phContext, CHAR *path);
static DWORD verify_server_certificate(
PCCERT_CONTEXT pServerCert, PSTR host, DWORD dwCertFlags);
static LONG disconnect_from_server(
SOCKET Socket, PCredHandle phCreds, CtxtHandle *phContext);
static void get_new_client_credentials(CredHandle *phCreds, CtxtHandle *phContext);

View File

@ -0,0 +1,30 @@
// 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
import strings
#flag windows -I @VROOT/thirdparty/vschannel
#flag -lws2_32 -lcrypt32
#include "vschannel.c"
fn init_module() {}
fn ssl_do(method, host_name, path string) string {
mut buff := malloc(10000)
req := '$method $path HTTP/1.0\r\nUser-Agent: v\r\nAccept:*/*\r\n\r\n'
length := int(C.request(host_name.str, req.str, buff))
if length == 0 {
return ''
}
resp := tos(buff, length)
return resp
}

View File

@ -4,11 +4,15 @@
module http
#flag -l Urlmon
#include <Urlmon.h>
fn download_file_with_progress(url, out string, cb, cb_finished voidptr) {
}
pub fn download_file(url, out string) {
C.URLDownloadToFileW(0, url.to_wide(), out.to_wide(), 0, 0)
C.URLDownloadToFile(0, url.to_wide(), out.to_wide(), 0, 0)
/*
if (res == S_OK) {
println('Download Ok')

View File

@ -109,6 +109,7 @@ pub fn (req &Request) do() Response {
panic('non https requests are not supported right now')
}
s := ssl_do(req.typ, url.host, url.path)
// s := ssl_do(req.typ, url.host, url.path)
first_header := s.all_before('\n')
mut status_code := 0
if first_header.contains('HTTP/') {