mirror of
https://github.com/projectdiscovery/httpx
synced 2026-06-08 16:50:17 +00:00
c48909f64f
* Added .idea to .gitignore * Updated the README * Added more verbose information on preset extractors * removing deprecated ioutil Co-authored-by: Mzack9999 <mzack9999@protonmail.com>
82 lines
1.8 KiB
Go
82 lines
1.8 KiB
Go
package httpx
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
|
|
"github.com/projectdiscovery/gologger"
|
|
"github.com/projectdiscovery/retryablehttp-go"
|
|
)
|
|
|
|
const (
|
|
// HTTP defines the plain http scheme
|
|
HTTP = "http"
|
|
// HTTPS defines the secure http scheme
|
|
HTTPS = "https"
|
|
// HTTPorHTTPS defines both http and https scheme in mutual exclusion
|
|
HTTPorHTTPS = "http|https"
|
|
// HTTPandHTTPS defines both http and https scheme
|
|
HTTPandHTTPS = "http&https"
|
|
)
|
|
|
|
// SupportHTTP2 checks if the target host supports HTTP2
|
|
func (h *HTTPX) SupportHTTP2(protocol, method, targetURL string) bool {
|
|
// http => supports HTTP1.1 => HTTP/2 (H2C)
|
|
if protocol == HTTP {
|
|
req, err := retryablehttp.NewRequest(method, targetURL, nil)
|
|
if err != nil {
|
|
return false
|
|
}
|
|
req.Header.Set("Connection", "Upgrade, HTTP2-Settings")
|
|
req.Header.Set("Upgrade", "h2c")
|
|
req.Header.Set("HTTP2-Settings", "AAMAAABkAARAAAAAAAIAAAAA")
|
|
httpresp, err := h.client.Do(req)
|
|
if err != nil {
|
|
return false
|
|
}
|
|
|
|
err = freeHTTPResources(httpresp)
|
|
if err != nil {
|
|
gologger.Error().Msgf("%s", err)
|
|
return false
|
|
}
|
|
|
|
return httpresp.StatusCode == http.StatusSwitchingProtocols
|
|
}
|
|
|
|
// attempts a direct http2 connection
|
|
req, err := http.NewRequestWithContext(context.Background(), method, targetURL, nil)
|
|
if err != nil {
|
|
return false
|
|
}
|
|
|
|
httpresp, err := h.client2.Do(req)
|
|
if err != nil {
|
|
return false
|
|
}
|
|
|
|
err = freeHTTPResources(httpresp)
|
|
if err != nil {
|
|
gologger.Error().Msgf("%s", err)
|
|
return false
|
|
}
|
|
|
|
return httpresp.Proto == "HTTP/2.0"
|
|
}
|
|
|
|
func freeHTTPResources(response *http.Response) error {
|
|
_, err := io.Copy(io.Discard, response.Body)
|
|
if err != nil {
|
|
return fmt.Errorf("could not discard response body: %s", err)
|
|
}
|
|
|
|
err = response.Body.Close()
|
|
if err != nil {
|
|
return fmt.Errorf("could not close response body: %s", err)
|
|
}
|
|
|
|
return nil
|
|
}
|