commit 0205331de977c5f3970327c43078bc69877eec7b
parent 777550d534f2443cd95ecc3d2423ea7563d80248
Author: Jack Mordaunt <jackmordaunt.dev@gmail.com>
Date: Tue, 13 Feb 2024 10:25:25 +0800
http: refactor in terms of the core package
Use all core logic from the core package.
Signed-off-by: Jack Mordaunt <jackmordaunt.dev@gmail.com>
Diffstat:
2 files changed, 30 insertions(+), 197 deletions(-)
diff --git a/http_test.go b/http_test.go
@@ -3,7 +3,6 @@ package nativehttp
import (
"io"
"net/http"
- "strings"
"testing"
"github.com/stretchr/testify/assert"
@@ -14,7 +13,7 @@ func TestGet(t *testing.T) {
Addr: "localhost:1337",
Handler: http.HandlerFunc(func(wr http.ResponseWriter, r *http.Request) {
t.Log("request")
- if _, err := io.Copy(wr, strings.NewReader("hellope!")); err != nil {
+ if _, err := wr.Write([]byte("hellope!")); err != nil {
t.Fatalf("failed copying data to response writer")
}
}),
diff --git a/http_windows.go b/http_windows.go
@@ -2,40 +2,23 @@ package nativehttp
import (
"io"
- "net/url"
"runtime"
- "syscall"
"unsafe"
+ . "git.sr.ht/~jackmordaunt/nativehttp/core"
+ "git.sr.ht/~jackmordaunt/nativehttp/core/windows"
"git.sr.ht/~jackmordaunt/nativehttp/winhttp"
)
-func get(uri string) (io.ReadCloser, error) {
- openRequestFlags := winhttp.OpenRequestFlagNone
- port := uint32(winhttp.DEFAULT_PORT)
-
- if HasPrefix(uri, "https://") {
- openRequestFlags = winhttp.OpenRequestFlagSecure
- port = winhttp.DEFAULT_HTTPS_PORT
- }
-
- u, err := url.Parse(uri)
+func get(s string) (io.ReadCloser, error) {
+ url, err := ParseURL(s)
if err != nil {
- return nil, err
+ return nil, Err{Cause: err, Msg: "parsing url"}
}
- domain := u.Hostname()
- path := TrimPrefix(u.Path, "/")
+ domain, path, port := url.Domain, url.Path, url.Port
- if customPort := u.Port(); customPort != "" {
- n, err := parseUint(customPort)
- if err != nil {
- return nil, err
- }
- port = uint32(n)
- }
-
- agentStr, err := UTF16PtrFromString("HTTP Plato Desktop Spark/1.0")
+ agentStr, err := windows.UTF16PtrFromString("HTTP nativehttp/1.0")
if err != nil {
return nil, err
}
@@ -48,43 +31,48 @@ func get(uri string) (io.ReadCloser, error) {
winhttp.OpenFlagAsync,
)
if session == 0 {
- return nil, GetLastError()
+ return nil, windows.GetLastError()
}
- defer cleanup(&err, func() error {
+ defer Cleanup(&err, func() error {
if ok := winhttp.CloseHandle(session); ok == 0 {
- return GetLastError()
+ return windows.GetLastError()
}
return nil
})
- domainStr, err := UTF16PtrFromString(domain)
+ domainStr, err := windows.UTF16PtrFromString(domain)
if err != nil {
return nil, err
}
connect := winhttp.Connect(session, domainStr, port, 0)
if connect == 0 {
- return nil, GetLastError()
+ return nil, windows.GetLastError()
}
- defer cleanup(&err, func() error {
+ defer Cleanup(&err, func() error {
if ok := winhttp.CloseHandle(connect); ok == 0 {
- return GetLastError()
+ return windows.GetLastError()
}
return nil
})
- pathStr, err := UTF16PtrFromString(path)
+ pathStr, err := windows.UTF16PtrFromString(path)
if err != nil {
return nil, err
}
- getStr, err := UTF16PtrFromString("GET")
+ getStr, err := windows.UTF16PtrFromString("GET")
if err != nil {
return nil, err
}
+ var openRequestFlags winhttp.OpenRequestFlag
+ if url.Encrypted {
+ openRequestFlags = winhttp.OpenRequestFlagSecure
+ }
+
request := winhttp.OpenRequest(
connect,
getStr,
@@ -95,22 +83,22 @@ func get(uri string) (io.ReadCloser, error) {
openRequestFlags|winhttp.OpenRequestFlagNullCodepage,
)
if request == 0 {
- return nil, GetLastError()
+ return nil, windows.GetLastError()
}
- defer cleanup(&err, func() error {
+ defer Cleanup(&err, func() error {
if ok := winhttp.CloseHandle(request); ok == 0 {
- return GetLastError()
+ return windows.GetLastError()
}
return nil
})
if ok := winhttp.SendRequest(request, nil, 0, nil, 0, 0, 0); ok == 0 {
- return nil, GetLastError()
+ return nil, windows.GetLastError()
}
if ok := winhttp.ReceiveResponse(request, nil); ok == 0 {
- return nil, GetLastError()
+ return nil, windows.GetLastError()
}
runtime.KeepAlive(agentStr)
@@ -144,7 +132,7 @@ func (r *winhttpRequest) Read(p []byte) (int, error) {
var n winhttp.DWORD
if ok := winhttp.QueryDataAvailable(r.request, &size); ok == 0 {
- return 0, GetLastError()
+ return 0, windows.GetLastError()
}
if size <= 0 {
@@ -158,7 +146,7 @@ func (r *winhttpRequest) Read(p []byte) (int, error) {
data := unsafe.SliceData(r.buf)
if ok := winhttp.ReadData(r.request, unsafe.Pointer(data), size, &n); ok == 0 {
- return 0, GetLastError()
+ return 0, windows.GetLastError()
}
nn := copy(p, r.buf[:n])
@@ -170,161 +158,7 @@ func (r *winhttpRequest) Read(p []byte) (int, error) {
func (r *winhttpRequest) Close() error {
if ok := winhttp.CloseHandle(r.request); ok == 0 {
- return GetLastError()
+ return windows.GetLastError()
}
return nil
}
-
-// cleanup executes a fallible function if the captured error is not nil.
-func cleanup(err *error, fn func() error) {
- if err != nil && *err != nil {
- if e := fn(); e != nil {
- *err = ErrorJoin(*err, e)
- }
- }
-}
-
-/*
- package strconv
-*/
-
-// parseUint is a specialized helper that parses a sequence of digits into an unsigned integer.
-func parseUint(s string) (n uint, _ error) {
- const asciiDigitOffset = 48
-
- width := uint(len(s))
-
- for ii := width; ii > 0; ii-- {
- c := s[ii]
- switch c {
- case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
- d := uint(c) - asciiDigitOffset
- n += d * pow(10, width-ii)
- default:
- return 0, parseErr{literal: c}
- }
- }
-
- return n, nil
-}
-
-type parseErr struct {
- literal byte
-}
-
-func (p parseErr) Error() string {
- return "parse: invalid literal (not a digit) " + string(p.literal)
-}
-
-/*
- package math
-*/
-
-func pow(base, exponent uint) (n uint) {
- n = 1
- for ii := uint(0); ii < exponent; ii++ {
- n *= base
- }
- return n
-}
-
-/*
- package strings
-*/
-
-// TrimPrefix returns s without the provided leading prefix string.
-// If s doesn't start with prefix, s is returned unchanged.
-func TrimPrefix(s, prefix string) string {
- if HasPrefix(s, prefix) {
- return s[len(prefix):]
- }
- return s
-}
-
-// HasPrefix tests whether the string s begins with prefix.
-func HasPrefix(s, prefix string) bool {
- return len(s) >= len(prefix) && s[0:len(prefix)] == prefix
-}
-
-/*
- package errors
-*/
-
-// ErrorJoin returns an error that wraps the given errors.
-// Any nil error values are discarded.
-// ErrorJoin returns nil if every value in errs is nil.
-// The error formats as the concatenation of the strings obtained
-// by calling the Error method of each element of errs, with a newline
-// between each string.
-//
-// A non-nil error returned by ErrorJoin implements the Unwrap() []error method.
-func ErrorJoin(errs ...error) error {
- n := 0
- for _, err := range errs {
- if err != nil {
- n++
- }
- }
- if n == 0 {
- return nil
- }
- e := &joinError{
- errs: make([]error, 0, n),
- }
- for _, err := range errs {
- if err != nil {
- e.errs = append(e.errs, err)
- }
- }
- return e
-}
-
-type joinError struct {
- errs []error
-}
-
-func (e *joinError) Error() string {
- var b []byte
- for i, err := range e.errs {
- if i > 0 {
- b = append(b, '\n')
- }
- b = append(b, err.Error()...)
- }
- return string(b)
-}
-
-func (e *joinError) Unwrap() []error {
- return e.errs
-}
-
-// UTF16PtrFromString returns pointer to the UTF-16 encoding of
-// the UTF-8 string s, with a terminating NUL added. If s
-// contains a NUL byte at any location, it returns (nil, syscall.EINVAL).
-func UTF16PtrFromString(s string) (*uint16, error) {
- a, err := UTF16FromString(s)
- if err != nil {
- return nil, err
- }
- return &a[0], nil
-}
-
-// UTF16FromString returns the UTF-16 encoding of the UTF-8 string
-// s, with a terminating NUL added. If s contains a NUL byte at any
-// location, it returns (nil, syscall.EINVAL).
-func UTF16FromString(s string) ([]uint16, error) {
- return syscall.UTF16FromString(s)
-}
-
-var (
- modkernel32 = syscall.NewLazyDLL("kernel32")
- procGetLastError = modkernel32.NewProc("GetLastError")
-)
-
-func GetLastError() (lasterr error) {
- r0, _, _ := procGetLastError.Call()
- if r0 != 0 {
- lasterr = syscall.Errno(r0)
- }
- return
-}