mirror of
https://github.com/alibaba/higress.git
synced 2026-05-21 03:07:27 +08:00
fix: nil guards, safe type assertions, panic prevention, and rate limiter plugin (#3757)
Signed-off-by: Srikanth Patchava <spatchava@meta.com> Signed-off-by: Srikanth Patchava <srpatcha@users.noreply.github.com> Co-authored-by: Srikanth Patchava <srpatcha@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
1c4fe1c9f9
commit
29da03c371
30
README.md
30
README.md
@@ -7,7 +7,7 @@
|
||||
<h4 align="center"> AI Native API Gateway </h4>
|
||||
|
||||
<div align="center">
|
||||
|
||||
|
||||
[](https://github.com/alibaba/higress/actions)
|
||||
[](https://www.apache.org/licenses/LICENSE-2.0.html)
|
||||
[](https://discord.gg/tSbww9VDaM)
|
||||
@@ -34,7 +34,7 @@ Higress is a cloud-native API gateway based on Istio and Envoy, which can be ext
|
||||
|
||||
### Core Use Cases
|
||||
|
||||
Higress's AI gateway capabilities support all [mainstream model providers](https://github.com/alibaba/higress/tree/main/plugins/wasm-go/extensions/ai-proxy/provider) both domestic and international. It also supports hosting MCP (Model Context Protocol) Servers through its plugin mechanism, enabling AI Agents to easily call various tools and services. With the [openapi-to-mcp tool](https://github.com/higress-group/openapi-to-mcpserver), you can quickly convert OpenAPI specifications into remote MCP servers for hosting. Higress provides unified management for both LLM API and MCP API.
|
||||
Higress's AI gateway capabilities support all [mainstream model providers](https://github.com/alibaba/higress/tree/main/plugins/wasm-go/extensions/ai-proxy/provider) both domestic and international. It also supports hosting MCP (Model Context Protocol) Servers through its plugin mechanism, enabling AI Agents to easily call various tools and services. With the [openapi-to-mcp tool](https://github.com/higress-group/openapi-to-mcpserver), you can quickly convert OpenAPI specifications into remote MCP servers for hosting. Higress provides unified management for both LLM API and MCP API.
|
||||
|
||||
**🌟 Try it now at [https://mcp.higress.ai/](https://mcp.higress.ai/)** to experience Higress-hosted Remote MCP Servers firsthand:
|
||||
|
||||
@@ -51,7 +51,7 @@ You can click the button below to install the enterprise version of Higress:
|
||||
|
||||
## Summary
|
||||
|
||||
- [**Quick Start**](#quick-start)
|
||||
- [**Quick Start**](#quick-start)
|
||||
- [**Feature Showcase**](#feature-showcase)
|
||||
- [**Use Cases**](#use-cases)
|
||||
- [**Core Advantages**](#core-advantages)
|
||||
@@ -78,20 +78,20 @@ Port descriptions:
|
||||
|
||||
> All Higress Docker images use Higress's own image repository and are not affected by Docker Hub rate limits.
|
||||
> In addition, the submission and updates of the images are protected by a security scanning mechanism (powered by Alibaba Cloud ACR), making them very secure for use in production environments.
|
||||
>
|
||||
>
|
||||
> If you experience a timeout when pulling image from `higress-registry.cn-hangzhou.cr.aliyuncs.com`, you can try replacing it with the following docker registry mirror source:
|
||||
>
|
||||
>
|
||||
> **North America**: `higress-registry.us-west-1.cr.aliyuncs.com`
|
||||
>
|
||||
>
|
||||
> **Southeast Asia**: `higress-registry.ap-southeast-7.cr.aliyuncs.com`
|
||||
|
||||
> **For Kubernetes deployments**, you can configure the `global.hub` parameter in Helm values to use a mirror registry closer to your region. This applies to both Higress component images and built-in Wasm plugin images:
|
||||
>
|
||||
>
|
||||
> ```bash
|
||||
> # Example: Using North America mirror
|
||||
> helm install higress -n higress-system higress.io/higress --set global.hub=higress-registry.us-west-1.cr.aliyuncs.com --create-namespace
|
||||
> ```
|
||||
>
|
||||
>
|
||||
> Available mirror registries:
|
||||
> - **China (Hangzhou)**: `higress-registry.cn-hangzhou.cr.aliyuncs.com` (default)
|
||||
> - **North America**: `higress-registry.us-west-1.cr.aliyuncs.com`
|
||||
@@ -129,7 +129,7 @@ If you are deploying on the cloud, it is recommended to use the [Enterprise Edit
|
||||
- **Kubernetes ingress controller**:
|
||||
|
||||
Higress can function as a feature-rich ingress controller, which is compatible with many annotations of K8s' nginx ingress controller.
|
||||
|
||||
|
||||
[Gateway API](https://gateway-api.sigs.k8s.io/) is already supported, and it supports a smooth migration from Ingress API to Gateway API.
|
||||
|
||||
Compared to ingress-nginx, the resource overhead has significantly decreased, and the speed at which route changes take effect has improved by ten times.
|
||||
@@ -140,13 +140,13 @@ If you are deploying on the cloud, it is recommended to use the [Enterprise Edit
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
- **Microservice gateway**:
|
||||
|
||||
Higress can function as a microservice gateway, which can discovery microservices from various service registries, such as Nacos, ZooKeeper, Consul, Eureka, etc.
|
||||
|
||||
|
||||
It deeply integrates with [Dubbo](https://github.com/apache/dubbo), [Nacos](https://github.com/alibaba/nacos), [Sentinel](https://github.com/alibaba/Sentinel) and other microservice technology stacks.
|
||||
|
||||
|
||||
- **Security gateway**:
|
||||
|
||||
Higress can be used as a security gateway, supporting WAF and various authentication strategies, such as key-auth, hmac-auth, jwt-auth, basic-auth, oidc, etc.
|
||||
@@ -165,15 +165,15 @@ If you are deploying on the cloud, it is recommended to use the [Enterprise Edit
|
||||
Supports true complete streaming processing of request/response bodies, Wasm plugins can easily customize the handling of streaming protocols such as SSE (Server-Sent Events).
|
||||
|
||||
In high-bandwidth scenarios such as AI businesses, it can significantly reduce memory overhead.
|
||||
|
||||
|
||||
- **Easy to Extend**
|
||||
|
||||
|
||||
Provides a rich official plugin library covering AI, traffic management, security protection and other common functions, meeting more than 90% of business scenario requirements.
|
||||
|
||||
Focuses on Wasm plugin extensions, ensuring memory safety through sandbox isolation, supporting multiple programming languages, allowing plugin versions to be upgraded independently, and achieving traffic-lossless hot updates of gateway logic.
|
||||
|
||||
- **Secure and Easy to Use**
|
||||
|
||||
|
||||
Based on Ingress API and Gateway API standards, provides out-of-the-box UI console, WAF protection plugin, IP/Cookie CC protection plugin ready to use.
|
||||
|
||||
Supports connecting to Let's Encrypt for automatic issuance and renewal of free certificates, and can be deployed outside of K8s, started with a single Docker command, convenient for individual developers to use.
|
||||
|
||||
@@ -164,14 +164,14 @@ func (c *DBClient) DescribeTable(table string) ([]map[string]interface{}, error)
|
||||
switch c.dbType {
|
||||
case MYSQL:
|
||||
sql = `
|
||||
select
|
||||
select
|
||||
column_name,
|
||||
column_type,
|
||||
is_nullable,
|
||||
column_key,
|
||||
column_default,
|
||||
extra,
|
||||
column_comment
|
||||
column_comment
|
||||
from information_schema.columns
|
||||
where table_schema = database() and table_name = ?
|
||||
`
|
||||
@@ -179,17 +179,17 @@ func (c *DBClient) DescribeTable(table string) ([]map[string]interface{}, error)
|
||||
|
||||
case POSTGRES:
|
||||
sql = `
|
||||
select
|
||||
select
|
||||
column_name,
|
||||
data_type as column_type,
|
||||
is_nullable,
|
||||
case
|
||||
case
|
||||
when column_default like 'nextval%' then 'auto_increment'
|
||||
when column_default is not null then 'default'
|
||||
else ''
|
||||
end as column_key,
|
||||
column_default,
|
||||
case
|
||||
case
|
||||
when column_default like 'nextval%' then 'auto_increment'
|
||||
else ''
|
||||
end as extra,
|
||||
@@ -202,7 +202,7 @@ func (c *DBClient) DescribeTable(table string) ([]map[string]interface{}, error)
|
||||
|
||||
case CLICKHOUSE:
|
||||
sql = `
|
||||
select
|
||||
select
|
||||
name as column_name,
|
||||
type as column_type,
|
||||
if(is_nullable, 'YES', 'NO') as is_nullable,
|
||||
@@ -217,7 +217,7 @@ func (c *DBClient) DescribeTable(table string) ([]map[string]interface{}, error)
|
||||
|
||||
case SQLITE:
|
||||
sql = `
|
||||
select
|
||||
select
|
||||
name as column_name,
|
||||
type as column_type,
|
||||
not (notnull = 1) as is_nullable,
|
||||
@@ -236,6 +236,10 @@ func (c *DBClient) DescribeTable(table string) ([]map[string]interface{}, error)
|
||||
|
||||
// ListTables List all tables in the connected database.
|
||||
func (c *DBClient) ListTables() ([]string, error) {
|
||||
if err := c.reconnectIfDbEmpty(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var sql string
|
||||
switch c.dbType {
|
||||
case MYSQL:
|
||||
@@ -265,6 +269,10 @@ func (c *DBClient) ListTables() ([]string, error) {
|
||||
tables = append(tables, table)
|
||||
}
|
||||
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, fmt.Errorf("error iterating table rows: %w", err)
|
||||
}
|
||||
|
||||
return tables, nil
|
||||
}
|
||||
|
||||
@@ -335,6 +343,10 @@ func (c *DBClient) Query(sql string, args ...interface{}) ([]map[string]interfac
|
||||
results = append(results, rowMap)
|
||||
}
|
||||
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, fmt.Errorf("failed to iterate table rows in Query: %w", err)
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -792,22 +792,36 @@ func (m *MilvusProvider) ListDocs(ctx context.Context, limit int) ([]schema.Docu
|
||||
fieldName := strings.ToLower(fieldMapping.StandardName)
|
||||
switch fieldName {
|
||||
case "id":
|
||||
if v, err := col.(*entity.ColumnVarChar).Get(i); err == nil {
|
||||
id = v.(string)
|
||||
if typedCol, ok := col.(*entity.ColumnVarChar); ok {
|
||||
if v, err := typedCol.Get(i); err == nil {
|
||||
if s, ok := v.(string); ok {
|
||||
id = s
|
||||
}
|
||||
}
|
||||
}
|
||||
case "content":
|
||||
if v, err := col.(*entity.ColumnVarChar).Get(i); err == nil {
|
||||
content = v.(string)
|
||||
if typedCol, ok := col.(*entity.ColumnVarChar); ok {
|
||||
if v, err := typedCol.Get(i); err == nil {
|
||||
if s, ok := v.(string); ok {
|
||||
content = s
|
||||
}
|
||||
}
|
||||
}
|
||||
case "metadata":
|
||||
if v, err := col.(*entity.ColumnJSONBytes).Get(i); err == nil {
|
||||
if bytes, ok := v.([]byte); ok {
|
||||
_ = json.Unmarshal(bytes, &metadata)
|
||||
if typedCol, ok := col.(*entity.ColumnJSONBytes); ok {
|
||||
if v, err := typedCol.Get(i); err == nil {
|
||||
if bytes, ok := v.([]byte); ok {
|
||||
_ = json.Unmarshal(bytes, &metadata)
|
||||
}
|
||||
}
|
||||
}
|
||||
case "created_at":
|
||||
if v, err := col.(*entity.ColumnInt64).Get(i); err == nil {
|
||||
createdAt = v.(int64)
|
||||
if typedCol, ok := col.(*entity.ColumnInt64); ok {
|
||||
if v, err := typedCol.Get(i); err == nil {
|
||||
if ts, ok := v.(int64); ok {
|
||||
createdAt = ts
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,13 +87,17 @@ func parseConfig(json gjson.Result, config *RequestBlockConfig, log log.Log) err
|
||||
if regexpUrl == "" {
|
||||
continue
|
||||
}
|
||||
var reg *regexp.Regexp
|
||||
var err error
|
||||
if config.caseSensitive {
|
||||
reg := regexp.MustCompile(regexpUrl)
|
||||
config.blockRegExpArray = append(config.blockRegExpArray, reg)
|
||||
reg, err = regexp.Compile(regexpUrl)
|
||||
} else {
|
||||
reg := regexp.MustCompile(strings.ToLower(regexpUrl))
|
||||
config.blockRegExpArray = append(config.blockRegExpArray, reg)
|
||||
reg, err = regexp.Compile(strings.ToLower(regexpUrl))
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid regexp pattern %q: %w", regexpUrl, err)
|
||||
}
|
||||
config.blockRegExpArray = append(config.blockRegExpArray, reg)
|
||||
}
|
||||
for _, item := range json.Get("block_headers").Array() {
|
||||
header := item.String()
|
||||
|
||||
Reference in New Issue
Block a user