Skip to content

988 feature implement http1 transport#1004

Merged
hulto merged 21 commits intomainfrom
988-feature-implement-http1-transport
Nov 15, 2025
Merged

988 feature implement http1 transport#1004
hulto merged 21 commits intomainfrom
988-feature-implement-http1-transport

Conversation

@hulto
Copy link
Copy Markdown
Collaborator

@hulto hulto commented Nov 11, 2025

What type of PR is this?

/kind feature

What this PR does / why we need it:

  • Add HTTP1 transport
  • Create a tavern redirector sub commands

Which issue(s) this PR fixes:

Fixes #988

@hulto hulto linked an issue Nov 11, 2025 that may be closed by this pull request
@hulto
Copy link
Copy Markdown
Collaborator Author

hulto commented Nov 11, 2025

  • Cleanup build warnings
  • Test with GCP deployment
  • Test with https
  • Test with hostnames

Copy link
Copy Markdown
Collaborator

@Cictrone Cictrone left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leaving the Golang for @KCarretto

Comment thread implants/imix/Cargo.toml Outdated

pb = { workspace = true, features = ["imix"]}
transport = { workspace = true, features = ["grpc"] }
transport = { workspace = true, features = ["http"] }
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want main branch to be http1 by default?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tru

Ok(res)
}

fn encrypt_impl(pt_vec: Vec<u8>) -> Result<Vec<u8>> {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we touching this?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Each transport needs to implement their own crypto.
I refactored the crypto to be easier for each transport to work with swapping input / output types to Vec instead of the specific buffer each transport expects.

Comment thread implants/lib/transport/src/http.rs
Comment thread tavern/app.go Outdated
Usage: "Run a redirector connecting agents using a specific transport to the server",
Subcommands: []cli.Command{
{
Name: "http",
Copy link
Copy Markdown
Collaborator

@KCarretto KCarretto Nov 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make this "http1"? Feels like the default should be http/2

Copy link
Copy Markdown
Collaborator Author

@hulto hulto Nov 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've been using http and grpc to differentiate.

Would you prefer http1 and grpc?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah I think it's good to be clear that it's forcing http1

return
}

fmt.Printf("[gRPC -> HTTP] Response size: %d bytes\n", len(responseBody))
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't plan to leave the print statements here right? If we do, we should move this to slog like we do elsewhere

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh good catch yeah i'll add it to slog debug

Comment thread tavern/app.go
Action: func(cCtx *cli.Context) error {
// Convert main.Config options to redirector.Config options
redirectorOptions := []func(*redirector.Config){
func(cfg *redirector.Config) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can probably clean this up a bit but feel free to land and I'll make changes later on


// streamConfig represents gRPC stream configuration
type streamConfig struct {
StreamName string
Copy link
Copy Markdown
Collaborator

@KCarretto KCarretto Nov 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Just embed a grpc.StremDesc here since you're using the same fields

type streamConfig struct {
    *grpc.StreamDesc
    // other fields that aren't in that
}

func createStream(ctx context.Context, conn *grpc.ClientConn, cfg streamConfig) (grpc.ClientStream, error) {
return conn.NewStream(
ctx,
&grpc.StreamDesc{
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if you do the embedding I mentioned above, you can just pass the cfg here (or it might require cfg.StreamDesc)

// RawCodec passes through raw bytes without marshaling/unmarshaling
type RawCodec struct{}

func (RawCodec) Marshal(v interface{}) ([]byte, error) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Use any instead of interface {}

// HTTPRedirectorRun starts an HTTP/1.1 to gRPC proxy/redirector
func HTTPRedirectorRun(ctx context.Context, upstream string, options ...func(*Config)) error {
// Initialize Config
cfg := &Config{}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to set any defaults? This would be the place to do it

return fmt.Errorf("failed to parse upstream address: %v", err)
}

port := url.Port()
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

port := url.Port()
if port == "" {
   if(url.Scheme == "http") {
       port = "80"
   }
   port = "443"
}

url.Host,
grpc.WithTransportCredentials(tc),
grpc.WithContextDialer(func(ctx context.Context, _ string) (net.Conn, error) {
// Resolve using IPv4 only (A records, not AAAA records)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we want to support IPv6?

Copy link
Copy Markdown
Collaborator Author

@hulto hulto Nov 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, I don't think we should. By default it uses IPv6 if a AAAA record is present.
If IPv6 isn't supported on the network, it'll fail.
This caused issues on my dev machine since my network doesn't support V6 and I imagine this will be an issue for other people as well I think only supporting ipv4 is a reasonable assumption.

@KCarretto
Copy link
Copy Markdown
Collaborator

some small changes but nothing blocking, lgtm

KCarretto
KCarretto previously approved these changes Nov 14, 2025
@hulto
Copy link
Copy Markdown
Collaborator Author

hulto commented Nov 15, 2025

shell mux test is failing again gonna force merge.

@hulto hulto merged commit 957db65 into main Nov 15, 2025
9 of 12 checks passed
@hulto hulto deleted the 988-feature-implement-http1-transport branch November 15, 2025 00:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[feature] Implement HTTP1 transport

3 participants