Skip to content

Commit

Permalink
Feat: globalSslset
Browse files Browse the repository at this point in the history
  • Loading branch information
Leokuma committed Nov 28, 2023
1 parent 6b4bebf commit 3d10283
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 50 deletions.
10 changes: 8 additions & 2 deletions decurl.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
import {i32, u32, u64, f64} from 'https://deno.land/x/byte_type@0.2.2/types/primitive/mod.ts';
import libcurl from './libcurl.ts';
import {Auth, Code, CStr, CurlBlob, CurlTlssessioninfo, DoublePtrChar, DoublePtrSlist, EasyOption, ERROR_SIZE, GlobalInit, HttpVersion, Info, MimePart, Opt, ProxyCode, Sslbackend} from './types.ts';
import {Auth, Code, CStr, CurlBlob, TlssessioninfoStruct, DoublePtrChar, DoublePtrSlist, EasyOption, ERROR_SIZE, GlobalInit, HttpVersion, Info, MimePart, Opt, ProxyCode, Sslbackend, Sslset} from './types.ts';
const sym = libcurl.symbols;

let initialized = false;

/** @todo Implement third param. */
/** https://curl.se/libcurl/c/curl_global_sslset.html */
export function globalSslset(id: Sslbackend, name?: string): Sslset {
return sym.globalSslset(id, (name ? CStr(name) : null), null);
}

/** https://curl.se/libcurl/c/curl_global_init.html */
export function globalInit(globalInit = GlobalInit.Default): Code | null {
if (!initialized) {
Expand Down Expand Up @@ -1659,7 +1665,7 @@ export default class Decurl implements Disposable {
sym.easyGetinfoBuf(this.#ptr, Info.TlsSslPtr, pptr);
const ptr = Deno.UnsafePointer.create(u64.read(new DataView(pptr)));
if (!ptr) return null;
return CurlTlssessioninfo.read(new DataView(new Deno.UnsafePointerView(ptr).getArrayBuffer(16)));
return TlssessioninfoStruct.read(new DataView(new Deno.UnsafePointerView(ptr).getArrayBuffer(TlssessioninfoStruct.byteLength)));
}

getHttpVersion(): HttpVersion {
Expand Down
File renamed without changes.
4 changes: 2 additions & 2 deletions libcurl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const libcurl = await dlopen({
x86_64: '/usr/lib/x86_64-linux-gnu/libcurl.so.4',
},
windows: {
x86_64: 'https://deno.land/x/decurl@0.7.0/lib/libcurl-x64.dll'
x86_64: 'https://deno.land/x/decurl@0.9.0/lib/libcurl-x64_8.4.0.dll'
}
}}, {
easyCleanup: {name: 'curl_easy_cleanup', parameters: ['pointer'], result: 'void'},
Expand Down Expand Up @@ -49,7 +49,7 @@ const libcurl = await dlopen({
globalCleanup: {name: 'curl_global_cleanup', parameters: [], result: 'void'},
globalInit: {name: 'curl_global_init', parameters: ['i64'], result: CURL_CODE},
// global_init_mem: {parameters: [''], result: ''},
globalSslset: {name: 'curl_global_sslset', parameters: ['u32', 'buffer', 'pointer'], result: 'i32'},
globalSslset: {name: 'curl_global_sslset', parameters: ['u32', 'buffer', 'buffer'], result: 'u32'},
// global_trace: {name: 'curl_global_trace', parameters: ['buffer'], result: 'i32'},
mimeAddpart: {name: 'curl_mime_addpart', parameters: [MIME_HANDLE], result: 'pointer'},
mimeData: {name: 'curl_mime_data', parameters: [MIME_PART, 'buffer', 'u64'], result: CURL_CODE},
Expand Down
131 changes: 87 additions & 44 deletions tests/http.ts → tests.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import {assert, assertEquals, assertGreater, assertGreaterOrEqual, assertLess, assertLessOrEqual} from 'https://deno.land/std@0.203.0/assert/mod.ts';
import Decurl, {globalInit, globalCleanup} from '../decurl.ts';
import {Code, HttpVersion} from '../types.ts';
import {STATUS_CODE as HTTP_STATUS_CODE} from 'https://deno.land/std@0.208.0/http/status.ts';
import {isHttpMethod} from "https://deno.land/std@0.205.0/http/unstable_method.ts";
import {assert, assertEquals, assertGreater, assertGreaterOrEqual, assertLess, assertLessOrEqual} from 'https://deno.land/std@0.208.0/assert/mod.ts';
import Decurl, {globalInit, globalCleanup, globalSslset} from './decurl.ts';
import {Code, HttpVersion, Sslbackend, Sslset} from './types.ts';
import {isStatus} from 'https://deno.land/std@0.208.0/http/status.ts';


Deno.test('Readme', () => {
Expand All @@ -27,31 +26,75 @@ Deno.test('Readme', () => {
globalCleanup()
})

Deno.test('Small GET text', async () => {
Deno.test('Init - SSL backend', () => {
assertEquals(globalSslset(Sslbackend.Bearssl), Sslset.UnknownBackend);
assertEquals(globalSslset(Sslbackend.Openssl), Sslset.Ok);
assertEquals(globalSslset(Sslbackend.Bearssl), Sslset.TooLate);
assertEquals(globalInit(), 0);
globalCleanup();

if (Deno.build.os == 'windows') {
assertEquals(globalSslset(Sslbackend.Schannel), Sslset.Ok);
assertEquals(globalSslset(Sslbackend.Bearssl), Sslset.TooLate);
assertEquals(globalInit(), 0);
globalCleanup();
}
})

Deno.test('GET - Big text', async () => {
globalInit();

using d = new Decurl();

if (Deno.build.os == 'windows')
assertEquals(d.setSslVerifypeer(0), Code.Ok);

assertEquals(d.setUrl('https://example.com'), Code.Ok);
assertEquals(d.setUrl('https://html.spec.whatwg.org/'), Code.Ok);
assertEquals(d.perform(), Code.Ok);
consistResponse(d);
assertEquals(d.getResponseCode(), 200);
assertEquals(d.getEffectiveUrl(), 'https://example.com/');

const dRes = d.getWriteFunctionData();
assert(dRes);

const fetchRes = await fetch('https://example.com').then(r => r.text());
const fetchRes = await fetch('https://html.spec.whatwg.org/').then(r => r.text());

assertEquals(new TextDecoder().decode(dRes), fetchRes);

globalCleanup();
})

Deno.test('Not found GET', async () => {
Deno.test('GET - Multiple handles', async () => {
globalInit();

using d1 = new Decurl();
using d2 = new Decurl();

if (Deno.build.os == 'windows')
assertEquals(d1.setSslVerifypeer(0), Code.Ok);

if (Deno.build.os == 'windows')
assertEquals(d2.setSslVerifypeer(0), Code.Ok);

assertEquals(d1.setUrl('https://example.com'), Code.Ok);
assertEquals(d2.setUrl('https://example.com'), Code.Ok);
assertEquals(d1.perform(), Code.Ok);
assertEquals(d2.perform(), Code.Ok);
consistResponse(d1);
consistResponse(d2);
const d1Res = d1.getWriteFunctionData();
const d2Res = d2.getWriteFunctionData();
assert(d1Res);
assert(d2Res);

const fetchRes = await fetch('https://example.com').then(r => r.text());

const txtDec = new TextDecoder();
assertEquals(txtDec.decode(d1Res), txtDec.decode(d2Res));
assertEquals(txtDec.decode(d2Res), fetchRes);

globalCleanup();
})

Deno.test('GET - Not found', async () => {
globalInit();

using d = new Decurl();
Expand All @@ -74,88 +117,88 @@ Deno.test('Not found GET', async () => {
globalCleanup();
})

Deno.test('Big GET text', async () => {
Deno.test('GET - PDF', async () => {
globalInit();

using d = new Decurl();

if (Deno.build.os == 'windows')
assertEquals(d.setSslVerifypeer(0), Code.Ok);

assertEquals(d.setUrl('https://html.spec.whatwg.org/'), Code.Ok);
assertEquals(d.setUrl('https://html.spec.whatwg.org/print.pdf'), Code.Ok);
assertEquals(d.perform(), Code.Ok);
consistResponse(d);
const dRes = d.getWriteFunctionData();
assert(dRes);

const fetchRes = await fetch('https://html.spec.whatwg.org/').then(r => r.text());
const fetchRes = await fetch('https://html.spec.whatwg.org/print.pdf').then(r => r.arrayBuffer());

assertEquals(new TextDecoder().decode(dRes), fetchRes);
const shaDecurl = await crypto.subtle.digest('SHA-256', dRes);
const shaFetch = await crypto.subtle.digest('SHA-256', fetchRes);
assertEquals(new Uint8Array(shaDecurl), new Uint8Array(shaFetch)); // asserting ArrayBuffers directly doesn't work

globalCleanup();
})

Deno.test('GET PDF', async () => {
Deno.test('GET - Small text', async () => {
globalInit();

using d = new Decurl();

if (Deno.build.os == 'windows')
assertEquals(d.setSslVerifypeer(0), Code.Ok);

assertEquals(d.setUrl('https://html.spec.whatwg.org/print.pdf'), Code.Ok);
assertEquals(d.setUrl('https://example.com'), Code.Ok);
assertEquals(d.perform(), Code.Ok);
consistResponse(d);
assertEquals(d.getResponseCode(), 200);
assertEquals(d.getEffectiveUrl(), 'https://example.com/');

const dRes = d.getWriteFunctionData();
assert(dRes);

const fetchRes = await fetch('https://html.spec.whatwg.org/print.pdf').then(r => r.arrayBuffer());
const fetchRes = await fetch('https://example.com').then(r => r.text());

const shaDecurl = await crypto.subtle.digest('SHA-256', dRes);
const shaFetch = await crypto.subtle.digest('SHA-256', fetchRes);
assertEquals(new Uint8Array(shaDecurl), new Uint8Array(shaFetch)); // asserting ArrayBuffers directly doesn't work
assertEquals(new TextDecoder().decode(dRes), fetchRes);

globalCleanup();
})

Deno.test('Multiple handles GET', async () => {
Deno.test('Cookies', () => {
globalInit();

using d1 = new Decurl();
using d2 = new Decurl();
using d = new Decurl();

if (Deno.build.os == 'windows')
assertEquals(d1.setSslVerifypeer(0), Code.Ok);
assertEquals(d.setSslVerifypeer(0), Code.Ok);

if (Deno.build.os == 'windows')
assertEquals(d2.setSslVerifypeer(0), Code.Ok);
assertEquals(d.setUrl('https://google.com/'), Code.Ok);
assertEquals(d.setFollowlocation(1), Code.Ok);
assertEquals(d.setCookiefile(''), Code.Ok); // activate cookie engine. Ref: https://curl.se/libcurl/c/CURLOPT_COOKIEFILE.html
d.perform();

assertEquals(d1.setUrl('https://example.com'), Code.Ok);
assertEquals(d2.setUrl('https://example.com'), Code.Ok);
assertEquals(d1.perform(), Code.Ok);
assertEquals(d2.perform(), Code.Ok);
consistResponse(d1);
consistResponse(d2);
const d1Res = d1.getWriteFunctionData();
const d2Res = d2.getWriteFunctionData();
assert(d1Res);
assert(d2Res);
const cookies = d.getCookielist();
console.log(cookies);
assert(cookies);
console.log(d.setCookielist('.localhost\tTRUE\t/\tTRUE\t1702320540\t1P_JAR\t2023-11-11-18'));
d.setUrl('http://localhost:8000');
console.log(d.perform());
assert(d.getCookielist());

const fetchRes = await fetch('https://example.com').then(r => r.text());
consistResponse(d);

const txtDec = new TextDecoder();
assertEquals(txtDec.decode(d1Res), txtDec.decode(d2Res));
assertEquals(txtDec.decode(d2Res), fetchRes);
assert(d.getWriteFunctionData());

globalCleanup();
})



function consistResponse(d: Decurl) {
assert(d.getHttpVersion() in HttpVersion);
assert(isHttpMethod(d.getEffectiveMethod()));
assert(d.getEffectiveMethod() == 'GET' || d.getEffectiveMethod() == 'POST');
assert(d.getScheme()?.includes('HTTP'));
assert(Object.values(HTTP_STATUS_CODE).find(resCode => resCode == d.getResponseCode()));
assert(isStatus(d.getResponseCode()));
assert(d.getContentType());
assertGreater(d.getLocalIp()!.length, 3);
assertGreaterOrEqual(d.getLocalPort(), 8000);
Expand Down
16 changes: 14 additions & 2 deletions types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -729,10 +729,22 @@ enum Sslbackend {
Rustls = 14
}

const CurlTlssessioninfo = new AlignedStruct({
const SslbackendStruct = new AlignedStruct({
id: u32,
pName: u64
});

enum Sslset {
Ok = 0,
UnknownBackend,
TooLate,
NoBackends
}

const TlssessioninfoStruct = new AlignedStruct({
backend: u32,
pInternals: u64
});


export {Auth, Code, CStr, CurlBlob, CurlTlssessioninfo, DoublePtrChar, DoublePtrSlist, EasyOption, ERROR_SIZE, FtpAuth, GlobalInit, HttpVersion, Info, type MimePart, Opt, ProxyCode, Sslbackend};
export {Auth, Code, CStr, CurlBlob, TlssessioninfoStruct, DoublePtrChar, DoublePtrSlist, EasyOption, ERROR_SIZE, FtpAuth, GlobalInit, HttpVersion, Info, type MimePart, Opt, ProxyCode, Sslbackend, SslbackendStruct, Sslset};

0 comments on commit 3d10283

Please sign in to comment.