chore: generate
This commit is contained in:
@@ -30,9 +30,7 @@ export function headers(input: Request | HeadersInit | Record<string, string>, e
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function websocketProtocols(input: Request | Record<string, string | undefined>) {
|
export function websocketProtocols(input: Request | Record<string, string | undefined>) {
|
||||||
const value = input instanceof Request
|
const value = input instanceof Request ? input.headers.get("sec-websocket-protocol") : input["sec-websocket-protocol"]
|
||||||
? input.headers.get("sec-websocket-protocol")
|
|
||||||
: input["sec-websocket-protocol"]
|
|
||||||
if (!value) return []
|
if (!value) return []
|
||||||
return value
|
return value
|
||||||
.split(",")
|
.split(",")
|
||||||
|
|||||||
@@ -1,6 +1,13 @@
|
|||||||
import { ProxyUtil } from "@/server/proxy-util"
|
import { ProxyUtil } from "@/server/proxy-util"
|
||||||
import { Effect, Stream } from "effect"
|
import { Effect, Stream } from "effect"
|
||||||
import { FetchHttpClient, HttpBody, HttpClient, HttpClientRequest, HttpServerRequest, HttpServerResponse } from "effect/unstable/http"
|
import {
|
||||||
|
FetchHttpClient,
|
||||||
|
HttpBody,
|
||||||
|
HttpClient,
|
||||||
|
HttpClientRequest,
|
||||||
|
HttpServerRequest,
|
||||||
|
HttpServerResponse,
|
||||||
|
} from "effect/unstable/http"
|
||||||
import * as Socket from "effect/unstable/socket/Socket"
|
import * as Socket from "effect/unstable/socket/Socket"
|
||||||
|
|
||||||
function webSource(request: HttpServerRequest.HttpServerRequest): Request | undefined {
|
function webSource(request: HttpServerRequest.HttpServerRequest): Request | undefined {
|
||||||
@@ -35,7 +42,9 @@ export function websocket(
|
|||||||
Effect.catchReason("SocketError", "SocketCloseError", (reason) =>
|
Effect.catchReason("SocketError", "SocketCloseError", (reason) =>
|
||||||
writeInbound(new Socket.CloseEvent(reason.code, reason.closeReason)).pipe(Effect.catch(() => Effect.void)),
|
writeInbound(new Socket.CloseEvent(reason.code, reason.closeReason)).pipe(Effect.catch(() => Effect.void)),
|
||||||
),
|
),
|
||||||
Effect.catch(() => writeInbound(new Socket.CloseEvent(1011, "proxy error")).pipe(Effect.catch(() => Effect.void))),
|
Effect.catch(() =>
|
||||||
|
writeInbound(new Socket.CloseEvent(1011, "proxy error")).pipe(Effect.catch(() => Effect.void)),
|
||||||
|
),
|
||||||
Effect.forkScoped,
|
Effect.forkScoped,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
+12
-8
@@ -27,10 +27,13 @@ type RequestPlan = Data.TaggedEnum<{
|
|||||||
}>
|
}>
|
||||||
const RequestPlan = Data.taggedEnum<RequestPlan>()
|
const RequestPlan = Data.taggedEnum<RequestPlan>()
|
||||||
|
|
||||||
export class WorkspaceRouteContext extends Context.Service<WorkspaceRouteContext, {
|
export class WorkspaceRouteContext extends Context.Service<
|
||||||
readonly directory: string
|
WorkspaceRouteContext,
|
||||||
readonly workspaceID?: WorkspaceID
|
{
|
||||||
}>()("@opencode/ExperimentalHttpApiWorkspaceRouteContext") {}
|
readonly directory: string
|
||||||
|
readonly workspaceID?: WorkspaceID
|
||||||
|
}
|
||||||
|
>()("@opencode/ExperimentalHttpApiWorkspaceRouteContext") {}
|
||||||
|
|
||||||
export class WorkspaceRoutingMiddleware extends HttpApiMiddleware.Service<
|
export class WorkspaceRoutingMiddleware extends HttpApiMiddleware.Service<
|
||||||
WorkspaceRoutingMiddleware,
|
WorkspaceRoutingMiddleware,
|
||||||
@@ -110,7 +113,10 @@ function proxyRemote(
|
|||||||
if (headers["upgrade"]?.toLowerCase() === "websocket") return yield* HttpApiProxy.websocket(request, proxyURL)
|
if (headers["upgrade"]?.toLowerCase() === "websocket") return yield* HttpApiProxy.websocket(request, proxyURL)
|
||||||
const response = yield* HttpApiProxy.http(proxyURL, target.headers, request)
|
const response = yield* HttpApiProxy.http(proxyURL, target.headers, request)
|
||||||
const sync = Fence.parse(new Headers(response.headers))
|
const sync = Fence.parse(new Headers(response.headers))
|
||||||
if (sync) yield* Effect.promise(() => Fence.wait(workspace.id, sync, request.source instanceof Request ? request.source.signal : undefined))
|
if (sync)
|
||||||
|
yield* Effect.promise(() =>
|
||||||
|
Fence.wait(workspace.id, sync, request.source instanceof Request ? request.source.signal : undefined),
|
||||||
|
)
|
||||||
return response
|
return response
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -157,9 +163,7 @@ function routeWorkspace<E>(
|
|||||||
MissingWorkspace: ({ workspaceID }) => Effect.succeed(missingWorkspaceResponse(workspaceID)),
|
MissingWorkspace: ({ workspaceID }) => Effect.succeed(missingWorkspaceResponse(workspaceID)),
|
||||||
Remote: ({ request, workspace, target, url }) => proxyRemote(request, workspace, target, url),
|
Remote: ({ request, workspace, target, url }) => proxyRemote(request, workspace, target, url),
|
||||||
Local: ({ directory, workspaceID }) =>
|
Local: ({ directory, workspaceID }) =>
|
||||||
effect.pipe(
|
effect.pipe(Effect.provideService(WorkspaceRouteContext, WorkspaceRouteContext.of({ directory, workspaceID }))),
|
||||||
Effect.provideService(WorkspaceRouteContext, WorkspaceRouteContext.of({ directory, workspaceID })),
|
|
||||||
),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -90,9 +90,9 @@ const instanceApiRoutes = HttpApiBuilder.layer(InstanceHttpApi).pipe(
|
|||||||
|
|
||||||
const rawInstanceRoutes = Layer.mergeAll(eventRoute, ptyConnectRoute).pipe(
|
const rawInstanceRoutes = Layer.mergeAll(eventRoute, ptyConnectRoute).pipe(
|
||||||
Layer.provide(
|
Layer.provide(
|
||||||
instanceRouterMiddleware.combine(workspaceRouterMiddleware).layer.pipe(
|
instanceRouterMiddleware
|
||||||
Layer.provide(Socket.layerWebSocketConstructorGlobal),
|
.combine(workspaceRouterMiddleware)
|
||||||
),
|
.layer.pipe(Layer.provide(Socket.layerWebSocketConstructorGlobal)),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
const instanceRoutes = Layer.mergeAll(rawInstanceRoutes, instanceApiRoutes).pipe(
|
const instanceRoutes = Layer.mergeAll(rawInstanceRoutes, instanceApiRoutes).pipe(
|
||||||
|
|||||||
@@ -22,14 +22,17 @@ describe("HttpApi workspace proxy", () => {
|
|||||||
Effect.gen(function* () {
|
Effect.gen(function* () {
|
||||||
const req = yield* HttpServerRequest.HttpServerRequest
|
const req = yield* HttpServerRequest.HttpServerRequest
|
||||||
const body = yield* req.text
|
const body = yield* req.text
|
||||||
return yield* HttpServerResponse.json({ path: req.url, method: req.method, body }, {
|
return yield* HttpServerResponse.json(
|
||||||
status: 201,
|
{ path: req.url, method: req.method, body },
|
||||||
headers: {
|
{
|
||||||
"content-encoding": "identity",
|
status: 201,
|
||||||
"content-length": "999",
|
headers: {
|
||||||
"x-remote": "yes",
|
"content-encoding": "identity",
|
||||||
|
"content-length": "999",
|
||||||
|
"x-remote": "yes",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
})
|
)
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
const url = yield* serverUrl()
|
const url = yield* serverUrl()
|
||||||
|
|||||||
Reference in New Issue
Block a user