-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
e9d6634
commit 073af36
Showing
13 changed files
with
442 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
93 changes: 93 additions & 0 deletions
93
webserver/src/main/java/io/kestra/webserver/controllers/EditorController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
package io.kestra.webserver.controllers; | ||
|
||
import io.kestra.webserver.controllers.domain.MarketplaceRequestType; | ||
import io.kestra.webserver.services.MarketplaceRequestMapper; | ||
import io.micronaut.core.async.publisher.Publishers; | ||
import io.micronaut.http.*; | ||
import io.micronaut.http.annotation.*; | ||
import io.micronaut.http.client.HttpClient; | ||
import io.micronaut.http.client.annotation.Client; | ||
import io.micronaut.http.server.util.HttpHostResolver; | ||
import io.micronaut.scheduling.TaskExecutors; | ||
import io.micronaut.scheduling.annotation.ExecuteOn; | ||
import io.swagger.v3.oas.annotations.Operation; | ||
import io.swagger.v3.oas.annotations.Parameter; | ||
import jakarta.inject.Inject; | ||
import org.reactivestreams.Publisher; | ||
|
||
import javax.annotation.Nullable; | ||
import java.net.URI; | ||
import java.net.URISyntaxException; | ||
import java.util.Optional; | ||
|
||
@Controller("/api/v1/editor") | ||
public class EditorController { | ||
@Inject | ||
@Client("remote-api") | ||
private HttpClient httpClient; | ||
|
||
@Inject | ||
private HttpHostResolver httpHostResolver; | ||
|
||
@Inject | ||
private MarketplaceRequestMapper marketplaceRequestMapper; | ||
|
||
@ExecuteOn(TaskExecutors.IO) | ||
@Get(uri = "/marketplace/{type}{/path:/.*}", produces = MediaType.APPLICATION_JSON) | ||
@Operation(tags = {"Marketplace"}, summary = "Marketplace extensions operations") | ||
public HttpResponse<String> marketplaceGet( | ||
@Parameter(description = "Type of request") @PathVariable MarketplaceRequestType type, | ||
@Parameter(description = "Additional path") @PathVariable @Nullable String path | ||
) { | ||
// proxied | ||
return null; | ||
} | ||
|
||
@ExecuteOn(TaskExecutors.IO) | ||
@Post(uri = "/marketplace/{type}{/path:/.*}", consumes = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON) | ||
@Operation(tags = {"Marketplace"}, summary = "Marketplace extensions operations") | ||
public HttpResponse<String> marketplacePost( | ||
@Parameter(description = "Type of request") @PathVariable MarketplaceRequestType type, | ||
@Parameter(description = "Additional path") @PathVariable @Nullable String path | ||
) throws URISyntaxException { | ||
// proxied | ||
return null; | ||
} | ||
|
||
@ExecuteOn(TaskExecutors.IO) | ||
@Get(uri = "/marketplace/resource/{publisher}/{extension}/{version}{/path:/.*}") | ||
@Operation(tags = {"Marketplace"}, summary = "Marketplace extensions resources operations") | ||
public Publisher<HttpResponse<String>> marketplaceResource( | ||
@Parameter(description = "Publisher id") @PathVariable String publisher, | ||
@Parameter(description = "Extension name") @PathVariable String extension, | ||
@Parameter(description = "Extension version") @PathVariable String version, | ||
@Parameter(description = "Path of the resource") @PathVariable String path, | ||
HttpRequest<?> httpRequest | ||
) { | ||
String localhost = httpHostResolver.resolve(httpRequest); | ||
String resourceBaseUrl = marketplaceRequestMapper.resourceBaseUrl(publisher); | ||
|
||
return Publishers.map( | ||
httpClient.exchange( | ||
httpRequest.mutate() | ||
.uri(URI.create(resourceBaseUrl + "/" + publisher + "/" + extension + "/" + version + path)) | ||
.headers(headers -> headers.set("Host", resourceBaseUrl.replaceFirst("https?://([^/]*).*", "$1").toLowerCase())), | ||
String.class | ||
), response -> { | ||
String body = response.body(); | ||
if (body == null) { | ||
return response; | ||
} | ||
|
||
MutableHttpResponse<String> newResponse = HttpResponse.ok( | ||
path.equals("/extension") | ||
? body.replace(resourceBaseUrl, localhost + "/api/v1/editor/marketplace/resource") | ||
: body | ||
); | ||
return Optional.ofNullable(response.header("Content-Type")) | ||
.map(contentType -> newResponse.header("Content-Type", contentType)) | ||
.orElse(newResponse); | ||
} | ||
); | ||
} | ||
} |
29 changes: 29 additions & 0 deletions
29
webserver/src/main/java/io/kestra/webserver/controllers/domain/MarketplaceRequestType.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package io.kestra.webserver.controllers.domain; | ||
|
||
import com.fasterxml.jackson.annotation.JsonCreator; | ||
import lombok.Getter; | ||
|
||
public enum MarketplaceRequestType { | ||
NLS("https://vscode-unpkg.net/_lp"), | ||
SERVICE("https://marketplace.visualstudio.com/_apis/public/gallery"), | ||
SEARCH("https://marketplace.visualstudio.com/_apis/public/gallery/searchrelevancy/extensionquery"), | ||
SERVICEPPE("https://marketplace.vsallin.net/_apis/public/gallery"), | ||
CACHE("https://vscode.blob.core.windows.net/gallery/index"), | ||
ITEM("https://marketplace.visualstudio.com/items"), | ||
PUBLISHER("https://marketplace.visualstudio.com/publishers"), | ||
CONTROL("https://az764295.vo.msecnd.net/extensions/marketplace.json"); | ||
|
||
@Getter | ||
private final String url; | ||
|
||
MarketplaceRequestType(String url) { | ||
this.url = url; | ||
} | ||
|
||
@JsonCreator | ||
public static MarketplaceRequestType fromString(String key) { | ||
return key == null | ||
? null | ||
: MarketplaceRequestType.valueOf(key.toUpperCase()); | ||
} | ||
} |
73 changes: 73 additions & 0 deletions
73
webserver/src/main/java/io/kestra/webserver/filter/MarketplaceFilter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
package io.kestra.webserver.filter; | ||
|
||
import io.kestra.webserver.controllers.domain.MarketplaceRequestType; | ||
import io.kestra.webserver.services.MarketplaceRequestMapper; | ||
import io.micronaut.core.async.publisher.Publishers; | ||
import io.micronaut.http.HttpAttributes; | ||
import io.micronaut.http.HttpRequest; | ||
import io.micronaut.http.MutableHttpRequest; | ||
import io.micronaut.http.MutableHttpResponse; | ||
import io.micronaut.http.annotation.Filter; | ||
import io.micronaut.http.client.ProxyHttpClient; | ||
import io.micronaut.http.client.annotation.Client; | ||
import io.micronaut.http.filter.*; | ||
import io.micronaut.web.router.RouteMatch; | ||
import jakarta.inject.Inject; | ||
import org.reactivestreams.Publisher; | ||
|
||
import java.net.URI; | ||
import java.util.Collections; | ||
import java.util.Map; | ||
import java.util.Optional; | ||
|
||
@Filter("/api/v1/editor/marketplace/**") | ||
public class MarketplaceFilter implements HttpServerFilter { | ||
@Inject | ||
@Client("proxy") | ||
private ProxyHttpClient httpClient; | ||
|
||
@Inject | ||
private MarketplaceRequestMapper marketplaceRequestMapper; | ||
|
||
@Override | ||
public int getOrder() { | ||
return ServerFilterPhase.RENDERING.order(); | ||
} | ||
|
||
@Override | ||
public Publisher<MutableHttpResponse<?>> doFilter(HttpRequest<?> request, ServerFilterChain chain) { | ||
MutableHttpRequest<?> httpRequest = request.mutate(); | ||
|
||
httpRequest.headers(headers -> { | ||
if (Optional.ofNullable(headers.get("Origin")).map(origin -> !origin.contains("localhost")).orElse(true)) { | ||
headers.set("Origin", "http://localhost:8080"); | ||
} | ||
headers.remove("Cookie"); | ||
headers.remove("Accept-Encoding"); | ||
}); | ||
|
||
Map<String, Object> matchValues = request.getAttribute(HttpAttributes.ROUTE_MATCH, RouteMatch.class) | ||
.map(RouteMatch::getVariableValues) | ||
.orElse(Collections.emptyMap()); | ||
MarketplaceRequestType type = Optional.ofNullable(matchValues.get("type")) | ||
.map(String.class::cast) | ||
.map(MarketplaceRequestType::fromString) | ||
.orElse(null); | ||
|
||
String path = Optional.ofNullable(matchValues.get("path")).map(Object::toString).orElse(""); | ||
|
||
Publisher<MutableHttpResponse<?>> publisher; | ||
if (type == null) { | ||
publisher = chain.proceed(httpRequest); | ||
} else { | ||
httpRequest.uri(URI.create(marketplaceRequestMapper.url(type) + path)); | ||
|
||
publisher = httpClient.proxy(httpRequest); | ||
} | ||
|
||
return Publishers.map( | ||
publisher, | ||
mutableHttpResponse -> mutableHttpResponse.headers(headers -> headers.remove("Access-Control-Allow-Origin")) | ||
); | ||
} | ||
} |
16 changes: 16 additions & 0 deletions
16
webserver/src/main/java/io/kestra/webserver/services/MarketplaceRequestMapper.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package io.kestra.webserver.services; | ||
|
||
import jakarta.inject.Singleton; | ||
import io.kestra.webserver.controllers.domain.MarketplaceRequestType; | ||
|
||
@Singleton | ||
// This mapper is almost a no-op but is necessary to ease testing MarketplaceFilter | ||
public class MarketplaceRequestMapper { | ||
public String url(MarketplaceRequestType type) { | ||
return type.getUrl(); | ||
} | ||
|
||
public String resourceBaseUrl(String publisher) { | ||
return "https://" + publisher + ".vscode-unpkg.net"; | ||
} | ||
} |
Oops, something went wrong.