10 changed files with 1092 additions and 6 deletions
			
			
		@ -0,0 +1,22 @@ | 
				
			|||
Copyright (c) 2016, Xinyun Zhou All rights reserved. | 
				
			|||
 | 
				
			|||
Redistribution and use in source and binary forms, with or without | 
				
			|||
modification, are permitted provided that the following conditions are met: | 
				
			|||
 | 
				
			|||
1. Redistributions of source code must retain the above copyright notice, this | 
				
			|||
list of conditions and the following disclaimer. | 
				
			|||
 | 
				
			|||
2. Redistributions in binary form must reproduce the above copyright notice, | 
				
			|||
this list of conditions and the following disclaimer in the documentation | 
				
			|||
and/or other materials provided with the distribution. | 
				
			|||
 | 
				
			|||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | 
				
			|||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 
				
			|||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 
				
			|||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | 
				
			|||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 
				
			|||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | 
				
			|||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | 
				
			|||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | 
				
			|||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 
				
			|||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
				
			|||
@ -0,0 +1,43 @@ | 
				
			|||
# go-http-digest-auth-client | 
				
			|||
Golang Http Digest Authentication Client | 
				
			|||
 | 
				
			|||
This client implements [RFC7616 HTTP Digest Access Authentication](https://www.rfc-editor.org/rfc/rfc7616.txt) | 
				
			|||
and by now the basic features should work. | 
				
			|||
 | 
				
			|||
# Usage | 
				
			|||
 | 
				
			|||
```go | 
				
			|||
// import | 
				
			|||
import dac "github.com/xinsnake/go-http-digest-auth-client" | 
				
			|||
 | 
				
			|||
// create a new digest authentication request | 
				
			|||
dr := dac.NewRequest(username, password, method, uri, payload) | 
				
			|||
response1, err := dr.Execute() | 
				
			|||
 | 
				
			|||
// check error, get response | 
				
			|||
 | 
				
			|||
// reuse the existing digest authentication request so no extra request is needed | 
				
			|||
dr.UpdateRequest(username, password, method, uri, payload) | 
				
			|||
response2, err := dr.Execute() | 
				
			|||
 | 
				
			|||
// check error, get response | 
				
			|||
``` | 
				
			|||
 | 
				
			|||
Or you can use it with `http.Request` | 
				
			|||
 | 
				
			|||
```go | 
				
			|||
t := dac.NewTransport(username, password) | 
				
			|||
req, err := http.NewRequest(method, uri, payload) | 
				
			|||
 | 
				
			|||
if err != nil { | 
				
			|||
    log.Fatalln(err) | 
				
			|||
} | 
				
			|||
 | 
				
			|||
resp, err := t.RoundTrip(req) | 
				
			|||
if err != nil { | 
				
			|||
    log.Fatalln(err) | 
				
			|||
} | 
				
			|||
defer resp.Body.Close() | 
				
			|||
 | 
				
			|||
fmt.Println(resp) | 
				
			|||
``` | 
				
			|||
@ -0,0 +1,180 @@ | 
				
			|||
package digest_auth_client | 
				
			|||
 | 
				
			|||
import ( | 
				
			|||
	"bytes" | 
				
			|||
	"crypto/md5" | 
				
			|||
	"crypto/sha256" | 
				
			|||
	"encoding/hex" | 
				
			|||
	"fmt" | 
				
			|||
	"hash" | 
				
			|||
	"io" | 
				
			|||
	"net/url" | 
				
			|||
	"regexp" | 
				
			|||
	"strings" | 
				
			|||
	"time" | 
				
			|||
) | 
				
			|||
 | 
				
			|||
type authorization struct { | 
				
			|||
	Algorithm string // unquoted
 | 
				
			|||
	Cnonce    string // quoted
 | 
				
			|||
	Nc        int    // unquoted
 | 
				
			|||
	Nonce     string // quoted
 | 
				
			|||
	Opaque    string // quoted
 | 
				
			|||
	Qop       string // unquoted
 | 
				
			|||
	Realm     string // quoted
 | 
				
			|||
	Response  string // quoted
 | 
				
			|||
	Uri       string // quoted
 | 
				
			|||
	Userhash  bool   // quoted
 | 
				
			|||
	Username  string // quoted
 | 
				
			|||
	Username_ string // quoted
 | 
				
			|||
} | 
				
			|||
 | 
				
			|||
func newAuthorization(dr *DigestRequest) (*authorization, error) { | 
				
			|||
 | 
				
			|||
	ah := authorization{ | 
				
			|||
		Algorithm: dr.Wa.Algorithm, | 
				
			|||
		Cnonce:    "", | 
				
			|||
		Nc:        0, | 
				
			|||
		Nonce:     dr.Wa.Nonce, | 
				
			|||
		Opaque:    dr.Wa.Opaque, | 
				
			|||
		Qop:       "", | 
				
			|||
		Realm:     dr.Wa.Realm, | 
				
			|||
		Response:  "", | 
				
			|||
		Uri:       "", | 
				
			|||
		Userhash:  dr.Wa.Userhash, | 
				
			|||
		Username:  "", | 
				
			|||
		Username_: "", // TODO
 | 
				
			|||
	} | 
				
			|||
 | 
				
			|||
	return ah.refreshAuthorization(dr) | 
				
			|||
} | 
				
			|||
 | 
				
			|||
func (ah *authorization) refreshAuthorization(dr *DigestRequest) (*authorization, error) { | 
				
			|||
 | 
				
			|||
	ah.Username = dr.Username | 
				
			|||
 | 
				
			|||
	if ah.Userhash { | 
				
			|||
		ah.Username = ah.hash(fmt.Sprintf("%s:%s", ah.Username, ah.Realm)) | 
				
			|||
	} | 
				
			|||
 | 
				
			|||
	ah.Nc++ | 
				
			|||
 | 
				
			|||
	ah.Cnonce = ah.hash(fmt.Sprintf("%d:%s:my_value", time.Now().UnixNano(), dr.Username)) | 
				
			|||
 | 
				
			|||
	url, err := url.Parse(dr.Uri) | 
				
			|||
	if err != nil { | 
				
			|||
		return nil, err | 
				
			|||
	} | 
				
			|||
 | 
				
			|||
	ah.Uri = url.RequestURI() | 
				
			|||
	ah.Response = ah.computeResponse(dr) | 
				
			|||
 | 
				
			|||
	return ah, nil | 
				
			|||
} | 
				
			|||
 | 
				
			|||
func (ah *authorization) computeResponse(dr *DigestRequest) (s string) { | 
				
			|||
 | 
				
			|||
	kdSecret := ah.hash(ah.computeA1(dr)) | 
				
			|||
	kdData := fmt.Sprintf("%s:%08x:%s:%s:%s", ah.Nonce, ah.Nc, ah.Cnonce, ah.Qop, ah.hash(ah.computeA2(dr))) | 
				
			|||
 | 
				
			|||
	return ah.hash(fmt.Sprintf("%s:%s", kdSecret, kdData)) | 
				
			|||
} | 
				
			|||
 | 
				
			|||
func (ah *authorization) computeA1(dr *DigestRequest) string { | 
				
			|||
 | 
				
			|||
	if ah.Algorithm == "" || ah.Algorithm == "MD5" || ah.Algorithm == "SHA-256" { | 
				
			|||
		return fmt.Sprintf("%s:%s:%s", ah.Username, ah.Realm, dr.Password) | 
				
			|||
	} | 
				
			|||
 | 
				
			|||
	if ah.Algorithm == "MD5-sess" || ah.Algorithm == "SHA-256-sess" { | 
				
			|||
		upHash := ah.hash(fmt.Sprintf("%s:%s:%s", ah.Username, ah.Realm, dr.Password)) | 
				
			|||
		return fmt.Sprintf("%s:%s:%s", upHash, ah.Nonce, ah.Cnonce) | 
				
			|||
	} | 
				
			|||
 | 
				
			|||
	return "" | 
				
			|||
} | 
				
			|||
 | 
				
			|||
func (ah *authorization) computeA2(dr *DigestRequest) string { | 
				
			|||
 | 
				
			|||
	if matched, _ := regexp.MatchString("auth-int", dr.Wa.Qop); matched { | 
				
			|||
		ah.Qop = "auth-int" | 
				
			|||
		return fmt.Sprintf("%s:%s:%s", dr.Method, ah.Uri, ah.hash(dr.Body)) | 
				
			|||
	} | 
				
			|||
 | 
				
			|||
	if dr.Wa.Qop == "auth" || dr.Wa.Qop == "" { | 
				
			|||
		ah.Qop = "auth" | 
				
			|||
		return fmt.Sprintf("%s:%s", dr.Method, ah.Uri) | 
				
			|||
	} | 
				
			|||
 | 
				
			|||
	return "" | 
				
			|||
} | 
				
			|||
 | 
				
			|||
func (ah *authorization) hash(a string) (s string) { | 
				
			|||
 | 
				
			|||
	var h hash.Hash | 
				
			|||
 | 
				
			|||
	if ah.Algorithm == "" || ah.Algorithm == "MD5" || ah.Algorithm == "MD5-sess" { | 
				
			|||
		h = md5.New() | 
				
			|||
	} else if ah.Algorithm == "SHA-256" || ah.Algorithm == "SHA-256-sess" { | 
				
			|||
		h = sha256.New() | 
				
			|||
	} | 
				
			|||
 | 
				
			|||
	io.WriteString(h, a) | 
				
			|||
	s = hex.EncodeToString(h.Sum(nil)) | 
				
			|||
 | 
				
			|||
	return | 
				
			|||
} | 
				
			|||
 | 
				
			|||
func (ah *authorization) toString() string { | 
				
			|||
	var buffer bytes.Buffer | 
				
			|||
 | 
				
			|||
	buffer.WriteString("Digest ") | 
				
			|||
 | 
				
			|||
	if ah.Algorithm != "" { | 
				
			|||
		buffer.WriteString(fmt.Sprintf("algorithm=%s, ", ah.Algorithm)) | 
				
			|||
	} | 
				
			|||
 | 
				
			|||
	if ah.Cnonce != "" { | 
				
			|||
		buffer.WriteString(fmt.Sprintf("cnonce=\"%s\", ", ah.Cnonce)) | 
				
			|||
	} | 
				
			|||
 | 
				
			|||
	if ah.Nc != 0 { | 
				
			|||
		buffer.WriteString(fmt.Sprintf("nc=%08x, ", ah.Nc)) | 
				
			|||
	} | 
				
			|||
 | 
				
			|||
	if ah.Opaque != "" { | 
				
			|||
		buffer.WriteString(fmt.Sprintf("opaque=\"%s\", ", ah.Opaque)) | 
				
			|||
	} | 
				
			|||
 | 
				
			|||
	if ah.Nonce != "" { | 
				
			|||
		buffer.WriteString(fmt.Sprintf("nonce=\"%s\", ", ah.Nonce)) | 
				
			|||
	} | 
				
			|||
 | 
				
			|||
	if ah.Qop != "" { | 
				
			|||
		buffer.WriteString(fmt.Sprintf("qop=%s, ", ah.Qop)) | 
				
			|||
	} | 
				
			|||
 | 
				
			|||
	if ah.Realm != "" { | 
				
			|||
		buffer.WriteString(fmt.Sprintf("realm=\"%s\", ", ah.Realm)) | 
				
			|||
	} | 
				
			|||
 | 
				
			|||
	if ah.Response != "" { | 
				
			|||
		buffer.WriteString(fmt.Sprintf("response=\"%s\", ", ah.Response)) | 
				
			|||
	} | 
				
			|||
 | 
				
			|||
	if ah.Uri != "" { | 
				
			|||
		buffer.WriteString(fmt.Sprintf("uri=\"%s\", ", ah.Uri)) | 
				
			|||
	} | 
				
			|||
 | 
				
			|||
	if ah.Userhash { | 
				
			|||
		buffer.WriteString("userhash=true, ") | 
				
			|||
	} | 
				
			|||
 | 
				
			|||
	if ah.Username != "" { | 
				
			|||
		buffer.WriteString(fmt.Sprintf("username=\"%s\", ", ah.Username)) | 
				
			|||
	} | 
				
			|||
 | 
				
			|||
	s := buffer.String() | 
				
			|||
 | 
				
			|||
	return strings.TrimSuffix(s, ", ") | 
				
			|||
} | 
				
			|||
@ -0,0 +1,156 @@ | 
				
			|||
package digest_auth_client | 
				
			|||
 | 
				
			|||
import ( | 
				
			|||
	"bytes" | 
				
			|||
	"fmt" | 
				
			|||
	"net/http" | 
				
			|||
	"time" | 
				
			|||
) | 
				
			|||
 | 
				
			|||
type DigestRequest struct { | 
				
			|||
	Body     string | 
				
			|||
	Method   string | 
				
			|||
	Password string | 
				
			|||
	Uri      string | 
				
			|||
	Username string | 
				
			|||
	Auth     *authorization | 
				
			|||
	Wa       *wwwAuthenticate | 
				
			|||
	header   http.Header | 
				
			|||
} | 
				
			|||
 | 
				
			|||
type DigestTransport struct { | 
				
			|||
	Password string | 
				
			|||
	Username string | 
				
			|||
} | 
				
			|||
 | 
				
			|||
// NewRequest creates a new DigestRequest object
 | 
				
			|||
func NewRequest(username, password, method, uri, body string, header http.Header) DigestRequest { | 
				
			|||
	dr := DigestRequest{} | 
				
			|||
	dr.UpdateRequest(username, password, method, uri, body, header) | 
				
			|||
	return dr | 
				
			|||
} | 
				
			|||
 | 
				
			|||
// NewTransport creates a new DigestTransport object
 | 
				
			|||
func NewTransport(username, password string) DigestTransport { | 
				
			|||
	dt := DigestTransport{} | 
				
			|||
	dt.Password = password | 
				
			|||
	dt.Username = username | 
				
			|||
	return dt | 
				
			|||
} | 
				
			|||
 | 
				
			|||
// UpdateRequest is called when you want to reuse an existing
 | 
				
			|||
//  DigestRequest connection with new request information
 | 
				
			|||
func (dr *DigestRequest) UpdateRequest(username, password, method, uri, body string, header http.Header) *DigestRequest { | 
				
			|||
	dr.Body = body | 
				
			|||
	dr.Method = method | 
				
			|||
	dr.Password = password | 
				
			|||
	dr.Uri = uri | 
				
			|||
	dr.Username = username | 
				
			|||
	dr.header = header | 
				
			|||
	return dr | 
				
			|||
} | 
				
			|||
 | 
				
			|||
// RoundTrip implements the http.RoundTripper interface
 | 
				
			|||
func (dt *DigestTransport) RoundTrip(req *http.Request) (resp *http.Response, err error) { | 
				
			|||
	username := dt.Username | 
				
			|||
	password := dt.Password | 
				
			|||
	method := req.Method | 
				
			|||
	uri := req.URL.String() | 
				
			|||
	header := req.Header | 
				
			|||
 | 
				
			|||
	var body string | 
				
			|||
	if req.Body != nil { | 
				
			|||
		buf := new(bytes.Buffer) | 
				
			|||
		buf.ReadFrom(req.Body) | 
				
			|||
		body = buf.String() | 
				
			|||
	} | 
				
			|||
 | 
				
			|||
	dr := NewRequest(username, password, method, uri, body, header) | 
				
			|||
	return dr.Execute() | 
				
			|||
} | 
				
			|||
 | 
				
			|||
// Execute initialise the request and get a response
 | 
				
			|||
func (dr *DigestRequest) Execute() (resp *http.Response, err error) { | 
				
			|||
 | 
				
			|||
	if dr.Auth != nil { | 
				
			|||
		return dr.executeExistingDigest() | 
				
			|||
	} | 
				
			|||
 | 
				
			|||
	var req *http.Request | 
				
			|||
	if req, err = http.NewRequest(dr.Method, dr.Uri, bytes.NewReader([]byte(dr.Body))); err != nil { | 
				
			|||
		return nil, err | 
				
			|||
	} | 
				
			|||
 | 
				
			|||
	req.Header = dr.header | 
				
			|||
 | 
				
			|||
	client := &http.Client{ | 
				
			|||
		Timeout: 30 * time.Second, | 
				
			|||
	} | 
				
			|||
	if resp, err = client.Do(req); err != nil { | 
				
			|||
		return nil, err | 
				
			|||
	} | 
				
			|||
 | 
				
			|||
	if resp.StatusCode == 401 { | 
				
			|||
		return dr.executeNewDigest(resp) | 
				
			|||
	} | 
				
			|||
 | 
				
			|||
	// return the resp to user to handle resp.body.Close()
 | 
				
			|||
	return resp, nil | 
				
			|||
} | 
				
			|||
 | 
				
			|||
func (dr *DigestRequest) executeNewDigest(resp *http.Response) (resp2 *http.Response, err error) { | 
				
			|||
	var ( | 
				
			|||
		auth     *authorization | 
				
			|||
		wa       *wwwAuthenticate | 
				
			|||
		waString string | 
				
			|||
	) | 
				
			|||
 | 
				
			|||
	// body not required for authentication, closing
 | 
				
			|||
	resp.Body.Close() | 
				
			|||
 | 
				
			|||
	if waString = resp.Header.Get("WWW-Authenticate"); waString == "" { | 
				
			|||
		return nil, fmt.Errorf("failed to get WWW-Authenticate header, please check your server configuration") | 
				
			|||
	} | 
				
			|||
	wa = newWwwAuthenticate(waString) | 
				
			|||
	dr.Wa = wa | 
				
			|||
 | 
				
			|||
	if auth, err = newAuthorization(dr); err != nil { | 
				
			|||
		return nil, err | 
				
			|||
	} | 
				
			|||
 | 
				
			|||
	if resp2, err = dr.executeRequest(auth.toString()); err != nil { | 
				
			|||
		return nil, err | 
				
			|||
	} | 
				
			|||
 | 
				
			|||
	dr.Auth = auth | 
				
			|||
	return resp2, nil | 
				
			|||
} | 
				
			|||
 | 
				
			|||
func (dr *DigestRequest) executeExistingDigest() (resp *http.Response, err error) { | 
				
			|||
	var auth *authorization | 
				
			|||
 | 
				
			|||
	if auth, err = dr.Auth.refreshAuthorization(dr); err != nil { | 
				
			|||
		return nil, err | 
				
			|||
	} | 
				
			|||
	dr.Auth = auth | 
				
			|||
 | 
				
			|||
	return dr.executeRequest(dr.Auth.toString()) | 
				
			|||
} | 
				
			|||
 | 
				
			|||
func (dr *DigestRequest) executeRequest(authString string) (resp *http.Response, err error) { | 
				
			|||
	var req *http.Request | 
				
			|||
 | 
				
			|||
	if req, err = http.NewRequest(dr.Method, dr.Uri, bytes.NewReader([]byte(dr.Body))); err != nil { | 
				
			|||
		return nil, err | 
				
			|||
	} | 
				
			|||
 | 
				
			|||
	req.Header = dr.header | 
				
			|||
 | 
				
			|||
	req.Header.Add("Authorization", authString) | 
				
			|||
 | 
				
			|||
	client := &http.Client{ | 
				
			|||
		Timeout: 30 * time.Second, | 
				
			|||
	} | 
				
			|||
 | 
				
			|||
	return client.Do(req) | 
				
			|||
} | 
				
			|||
@ -0,0 +1 @@ | 
				
			|||
test:Private:d75b886e0865b975d729deb19441ddde | 
				
			|||
@ -0,0 +1,17 @@ | 
				
			|||
version: "3.3" | 
				
			|||
services: | 
				
			|||
  httpd: | 
				
			|||
    image: httpd:latest | 
				
			|||
    volumes: | 
				
			|||
      - ./httpd.conf:/usr/local/apache2/conf/httpd.conf:ro | 
				
			|||
      - ./.htdigest:/usr/local/apache2/conf/.htdigest:ro | 
				
			|||
    networks: | 
				
			|||
      default_net: | 
				
			|||
        ipv4_address: 172.16.1.5 | 
				
			|||
networks: | 
				
			|||
  default_net: | 
				
			|||
    driver: bridge | 
				
			|||
    ipam: | 
				
			|||
      driver: default | 
				
			|||
      config: | 
				
			|||
        - subnet: 172.16.1.1/27 # 1-30 | 
				
			|||
@ -0,0 +1,553 @@ | 
				
			|||
# | 
				
			|||
# This is the main Apache HTTP server configuration file.  It contains the | 
				
			|||
# configuration directives that give the server its instructions. | 
				
			|||
# See <URL:http://httpd.apache.org/docs/2.4/> for detailed information. | 
				
			|||
# In particular, see  | 
				
			|||
# <URL:http://httpd.apache.org/docs/2.4/mod/directives.html> | 
				
			|||
# for a discussion of each configuration directive. | 
				
			|||
# | 
				
			|||
# Do NOT simply read the instructions in here without understanding | 
				
			|||
# what they do.  They're here only as hints or reminders.  If you are unsure | 
				
			|||
# consult the online docs. You have been warned.   | 
				
			|||
# | 
				
			|||
# Configuration and logfile names: If the filenames you specify for many | 
				
			|||
# of the server's control files begin with "/" (or "drive:/" for Win32), the | 
				
			|||
# server will use that explicit path.  If the filenames do *not* begin | 
				
			|||
# with "/", the value of ServerRoot is prepended -- so "logs/access_log" | 
				
			|||
# with ServerRoot set to "/usr/local/apache2" will be interpreted by the | 
				
			|||
# server as "/usr/local/apache2/logs/access_log", whereas "/logs/access_log"  | 
				
			|||
# will be interpreted as '/logs/access_log'. | 
				
			|||
 | 
				
			|||
# | 
				
			|||
# ServerRoot: The top of the directory tree under which the server's | 
				
			|||
# configuration, error, and log files are kept. | 
				
			|||
# | 
				
			|||
# Do not add a slash at the end of the directory path.  If you point | 
				
			|||
# ServerRoot at a non-local disk, be sure to specify a local disk on the | 
				
			|||
# Mutex directive, if file-based mutexes are used.  If you wish to share the | 
				
			|||
# same ServerRoot for multiple httpd daemons, you will need to change at | 
				
			|||
# least PidFile. | 
				
			|||
# | 
				
			|||
ServerRoot "/usr/local/apache2" | 
				
			|||
 | 
				
			|||
# | 
				
			|||
# Mutex: Allows you to set the mutex mechanism and mutex file directory | 
				
			|||
# for individual mutexes, or change the global defaults | 
				
			|||
# | 
				
			|||
# Uncomment and change the directory if mutexes are file-based and the default | 
				
			|||
# mutex file directory is not on a local disk or is not appropriate for some | 
				
			|||
# other reason. | 
				
			|||
# | 
				
			|||
# Mutex default:logs | 
				
			|||
 | 
				
			|||
# | 
				
			|||
# Listen: Allows you to bind Apache to specific IP addresses and/or | 
				
			|||
# ports, instead of the default. See also the <VirtualHost> | 
				
			|||
# directive. | 
				
			|||
# | 
				
			|||
# Change this to Listen on specific IP addresses as shown below to  | 
				
			|||
# prevent Apache from glomming onto all bound IP addresses. | 
				
			|||
# | 
				
			|||
#Listen 12.34.56.78:80 | 
				
			|||
Listen 80 | 
				
			|||
 | 
				
			|||
# | 
				
			|||
# Dynamic Shared Object (DSO) Support | 
				
			|||
# | 
				
			|||
# To be able to use the functionality of a module which was built as a DSO you | 
				
			|||
# have to place corresponding `LoadModule' lines at this location so the | 
				
			|||
# directives contained in it are actually available _before_ they are used. | 
				
			|||
# Statically compiled modules (those listed by `httpd -l') do not need | 
				
			|||
# to be loaded here. | 
				
			|||
# | 
				
			|||
# Example: | 
				
			|||
# LoadModule foo_module modules/mod_foo.so | 
				
			|||
# | 
				
			|||
LoadModule authn_file_module modules/mod_authn_file.so | 
				
			|||
#LoadModule authn_dbm_module modules/mod_authn_dbm.so | 
				
			|||
#LoadModule authn_anon_module modules/mod_authn_anon.so | 
				
			|||
#LoadModule authn_dbd_module modules/mod_authn_dbd.so | 
				
			|||
#LoadModule authn_socache_module modules/mod_authn_socache.so | 
				
			|||
LoadModule authn_core_module modules/mod_authn_core.so | 
				
			|||
LoadModule authz_host_module modules/mod_authz_host.so | 
				
			|||
LoadModule authz_groupfile_module modules/mod_authz_groupfile.so | 
				
			|||
LoadModule authz_user_module modules/mod_authz_user.so | 
				
			|||
#LoadModule authz_dbm_module modules/mod_authz_dbm.so | 
				
			|||
#LoadModule authz_owner_module modules/mod_authz_owner.so | 
				
			|||
#LoadModule authz_dbd_module modules/mod_authz_dbd.so | 
				
			|||
LoadModule authz_core_module modules/mod_authz_core.so | 
				
			|||
#LoadModule authnz_ldap_module modules/mod_authnz_ldap.so | 
				
			|||
#LoadModule authnz_fcgi_module modules/mod_authnz_fcgi.so | 
				
			|||
LoadModule access_compat_module modules/mod_access_compat.so | 
				
			|||
LoadModule auth_basic_module modules/mod_auth_basic.so | 
				
			|||
#LoadModule auth_form_module modules/mod_auth_form.so | 
				
			|||
LoadModule auth_digest_module modules/mod_auth_digest.so | 
				
			|||
#LoadModule allowmethods_module modules/mod_allowmethods.so | 
				
			|||
#LoadModule isapi_module modules/mod_isapi.so | 
				
			|||
#LoadModule file_cache_module modules/mod_file_cache.so | 
				
			|||
#LoadModule cache_module modules/mod_cache.so | 
				
			|||
#LoadModule cache_disk_module modules/mod_cache_disk.so | 
				
			|||
#LoadModule cache_socache_module modules/mod_cache_socache.so | 
				
			|||
#LoadModule socache_shmcb_module modules/mod_socache_shmcb.so | 
				
			|||
#LoadModule socache_dbm_module modules/mod_socache_dbm.so | 
				
			|||
#LoadModule socache_memcache_module modules/mod_socache_memcache.so | 
				
			|||
#LoadModule watchdog_module modules/mod_watchdog.so | 
				
			|||
#LoadModule macro_module modules/mod_macro.so | 
				
			|||
#LoadModule dbd_module modules/mod_dbd.so | 
				
			|||
#LoadModule bucketeer_module modules/mod_bucketeer.so | 
				
			|||
#LoadModule dumpio_module modules/mod_dumpio.so | 
				
			|||
#LoadModule echo_module modules/mod_echo.so | 
				
			|||
#LoadModule example_hooks_module modules/mod_example_hooks.so | 
				
			|||
#LoadModule case_filter_module modules/mod_case_filter.so | 
				
			|||
#LoadModule case_filter_in_module modules/mod_case_filter_in.so | 
				
			|||
#LoadModule example_ipc_module modules/mod_example_ipc.so | 
				
			|||
#LoadModule buffer_module modules/mod_buffer.so | 
				
			|||
#LoadModule data_module modules/mod_data.so | 
				
			|||
#LoadModule ratelimit_module modules/mod_ratelimit.so | 
				
			|||
LoadModule reqtimeout_module modules/mod_reqtimeout.so | 
				
			|||
#LoadModule ext_filter_module modules/mod_ext_filter.so | 
				
			|||
#LoadModule request_module modules/mod_request.so | 
				
			|||
#LoadModule include_module modules/mod_include.so | 
				
			|||
LoadModule filter_module modules/mod_filter.so | 
				
			|||
#LoadModule reflector_module modules/mod_reflector.so | 
				
			|||
#LoadModule substitute_module modules/mod_substitute.so | 
				
			|||
#LoadModule sed_module modules/mod_sed.so | 
				
			|||
#LoadModule charset_lite_module modules/mod_charset_lite.so | 
				
			|||
#LoadModule deflate_module modules/mod_deflate.so | 
				
			|||
#LoadModule xml2enc_module modules/mod_xml2enc.so | 
				
			|||
#LoadModule proxy_html_module modules/mod_proxy_html.so | 
				
			|||
LoadModule mime_module modules/mod_mime.so | 
				
			|||
#LoadModule ldap_module modules/mod_ldap.so | 
				
			|||
LoadModule log_config_module modules/mod_log_config.so | 
				
			|||
#LoadModule log_debug_module modules/mod_log_debug.so | 
				
			|||
#LoadModule log_forensic_module modules/mod_log_forensic.so | 
				
			|||
#LoadModule logio_module modules/mod_logio.so | 
				
			|||
#LoadModule lua_module modules/mod_lua.so | 
				
			|||
LoadModule env_module modules/mod_env.so | 
				
			|||
#LoadModule mime_magic_module modules/mod_mime_magic.so | 
				
			|||
#LoadModule cern_meta_module modules/mod_cern_meta.so | 
				
			|||
#LoadModule expires_module modules/mod_expires.so | 
				
			|||
LoadModule headers_module modules/mod_headers.so | 
				
			|||
#LoadModule ident_module modules/mod_ident.so | 
				
			|||
#LoadModule usertrack_module modules/mod_usertrack.so | 
				
			|||
#LoadModule unique_id_module modules/mod_unique_id.so | 
				
			|||
LoadModule setenvif_module modules/mod_setenvif.so | 
				
			|||
LoadModule version_module modules/mod_version.so | 
				
			|||
#LoadModule remoteip_module modules/mod_remoteip.so | 
				
			|||
#LoadModule proxy_module modules/mod_proxy.so | 
				
			|||
#LoadModule proxy_connect_module modules/mod_proxy_connect.so | 
				
			|||
#LoadModule proxy_ftp_module modules/mod_proxy_ftp.so | 
				
			|||
#LoadModule proxy_http_module modules/mod_proxy_http.so | 
				
			|||
#LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so | 
				
			|||
#LoadModule proxy_scgi_module modules/mod_proxy_scgi.so | 
				
			|||
#LoadModule proxy_fdpass_module modules/mod_proxy_fdpass.so | 
				
			|||
#LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so | 
				
			|||
#LoadModule proxy_ajp_module modules/mod_proxy_ajp.so | 
				
			|||
#LoadModule proxy_balancer_module modules/mod_proxy_balancer.so | 
				
			|||
#LoadModule proxy_express_module modules/mod_proxy_express.so | 
				
			|||
#LoadModule proxy_hcheck_module modules/mod_proxy_hcheck.so | 
				
			|||
#LoadModule session_module modules/mod_session.so | 
				
			|||
#LoadModule session_cookie_module modules/mod_session_cookie.so | 
				
			|||
#LoadModule session_crypto_module modules/mod_session_crypto.so | 
				
			|||
#LoadModule session_dbd_module modules/mod_session_dbd.so | 
				
			|||
#LoadModule slotmem_shm_module modules/mod_slotmem_shm.so | 
				
			|||
#LoadModule slotmem_plain_module modules/mod_slotmem_plain.so | 
				
			|||
#LoadModule ssl_module modules/mod_ssl.so | 
				
			|||
#LoadModule optional_hook_export_module modules/mod_optional_hook_export.so | 
				
			|||
#LoadModule optional_hook_import_module modules/mod_optional_hook_import.so | 
				
			|||
#LoadModule optional_fn_import_module modules/mod_optional_fn_import.so | 
				
			|||
#LoadModule optional_fn_export_module modules/mod_optional_fn_export.so | 
				
			|||
#LoadModule dialup_module modules/mod_dialup.so | 
				
			|||
#LoadModule http2_module modules/mod_http2.so | 
				
			|||
#LoadModule proxy_http2_module modules/mod_proxy_http2.so | 
				
			|||
#LoadModule lbmethod_byrequests_module modules/mod_lbmethod_byrequests.so | 
				
			|||
#LoadModule lbmethod_bytraffic_module modules/mod_lbmethod_bytraffic.so | 
				
			|||
#LoadModule lbmethod_bybusyness_module modules/mod_lbmethod_bybusyness.so | 
				
			|||
#LoadModule lbmethod_heartbeat_module modules/mod_lbmethod_heartbeat.so | 
				
			|||
LoadModule unixd_module modules/mod_unixd.so | 
				
			|||
#LoadModule heartbeat_module modules/mod_heartbeat.so | 
				
			|||
#LoadModule heartmonitor_module modules/mod_heartmonitor.so | 
				
			|||
#LoadModule dav_module modules/mod_dav.so | 
				
			|||
LoadModule status_module modules/mod_status.so | 
				
			|||
LoadModule autoindex_module modules/mod_autoindex.so | 
				
			|||
#LoadModule asis_module modules/mod_asis.so | 
				
			|||
#LoadModule info_module modules/mod_info.so | 
				
			|||
#LoadModule suexec_module modules/mod_suexec.so | 
				
			|||
<IfModule !mpm_prefork_module> | 
				
			|||
	#LoadModule cgid_module modules/mod_cgid.so | 
				
			|||
</IfModule> | 
				
			|||
<IfModule mpm_prefork_module> | 
				
			|||
	#LoadModule cgi_module modules/mod_cgi.so | 
				
			|||
</IfModule> | 
				
			|||
#LoadModule dav_fs_module modules/mod_dav_fs.so | 
				
			|||
#LoadModule dav_lock_module modules/mod_dav_lock.so | 
				
			|||
#LoadModule vhost_alias_module modules/mod_vhost_alias.so | 
				
			|||
#LoadModule negotiation_module modules/mod_negotiation.so | 
				
			|||
LoadModule dir_module modules/mod_dir.so | 
				
			|||
#LoadModule imagemap_module modules/mod_imagemap.so | 
				
			|||
#LoadModule actions_module modules/mod_actions.so | 
				
			|||
#LoadModule speling_module modules/mod_speling.so | 
				
			|||
#LoadModule userdir_module modules/mod_userdir.so | 
				
			|||
LoadModule alias_module modules/mod_alias.so | 
				
			|||
#LoadModule rewrite_module modules/mod_rewrite.so | 
				
			|||
 | 
				
			|||
<IfModule unixd_module> | 
				
			|||
# | 
				
			|||
# If you wish httpd to run as a different user or group, you must run | 
				
			|||
# httpd as root initially and it will switch.   | 
				
			|||
# | 
				
			|||
# User/Group: The name (or #number) of the user/group to run httpd as. | 
				
			|||
# It is usually good practice to create a dedicated user and group for | 
				
			|||
# running httpd, as with most system services. | 
				
			|||
# | 
				
			|||
User daemon | 
				
			|||
Group daemon | 
				
			|||
 | 
				
			|||
</IfModule> | 
				
			|||
 | 
				
			|||
# 'Main' server configuration | 
				
			|||
# | 
				
			|||
# The directives in this section set up the values used by the 'main' | 
				
			|||
# server, which responds to any requests that aren't handled by a | 
				
			|||
# <VirtualHost> definition.  These values also provide defaults for | 
				
			|||
# any <VirtualHost> containers you may define later in the file. | 
				
			|||
# | 
				
			|||
# All of these directives may appear inside <VirtualHost> containers, | 
				
			|||
# in which case these default settings will be overridden for the | 
				
			|||
# virtual host being defined. | 
				
			|||
# | 
				
			|||
 | 
				
			|||
# | 
				
			|||
# ServerAdmin: Your address, where problems with the server should be | 
				
			|||
# e-mailed.  This address appears on some server-generated pages, such | 
				
			|||
# as error documents.  e.g. admin@your-domain.com | 
				
			|||
# | 
				
			|||
ServerAdmin you@example.com | 
				
			|||
 | 
				
			|||
# | 
				
			|||
# ServerName gives the name and port that the server uses to identify itself. | 
				
			|||
# This can often be determined automatically, but we recommend you specify | 
				
			|||
# it explicitly to prevent problems during startup. | 
				
			|||
# | 
				
			|||
# If your host doesn't have a registered DNS name, enter its IP address here. | 
				
			|||
# | 
				
			|||
#ServerName www.example.com:80 | 
				
			|||
 | 
				
			|||
# | 
				
			|||
# Deny access to the entirety of your server's filesystem. You must | 
				
			|||
# explicitly permit access to web content directories in other  | 
				
			|||
# <Directory> blocks below. | 
				
			|||
# | 
				
			|||
<Directory /> | 
				
			|||
    AllowOverride none | 
				
			|||
    Require all denied | 
				
			|||
</Directory> | 
				
			|||
 | 
				
			|||
# | 
				
			|||
# Note that from this point forward you must specifically allow | 
				
			|||
# particular features to be enabled - so if something's not working as | 
				
			|||
# you might expect, make sure that you have specifically enabled it | 
				
			|||
# below. | 
				
			|||
# | 
				
			|||
 | 
				
			|||
# | 
				
			|||
# DocumentRoot: The directory out of which you will serve your | 
				
			|||
# documents. By default, all requests are taken from this directory, but | 
				
			|||
# symbolic links and aliases may be used to point to other locations. | 
				
			|||
# | 
				
			|||
DocumentRoot "/usr/local/apache2/htdocs" | 
				
			|||
<Directory "/usr/local/apache2/htdocs"> | 
				
			|||
    # | 
				
			|||
    # Possible values for the Options directive are "None", "All", | 
				
			|||
    # or any combination of: | 
				
			|||
    #   Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews | 
				
			|||
    # | 
				
			|||
    # Note that "MultiViews" must be named *explicitly* --- "Options All" | 
				
			|||
    # doesn't give it to you. | 
				
			|||
    # | 
				
			|||
    # The Options directive is both complicated and important.  Please see | 
				
			|||
    # http://httpd.apache.org/docs/2.4/mod/core.html#options | 
				
			|||
    # for more information. | 
				
			|||
    # | 
				
			|||
    Options Indexes FollowSymLinks | 
				
			|||
 | 
				
			|||
    # | 
				
			|||
    # AllowOverride controls what directives may be placed in .htaccess files. | 
				
			|||
    # It can be "All", "None", or any combination of the keywords: | 
				
			|||
    #   AllowOverride FileInfo AuthConfig Limit | 
				
			|||
    # | 
				
			|||
    AllowOverride None | 
				
			|||
 | 
				
			|||
    # | 
				
			|||
    # Controls who can get stuff from this server. | 
				
			|||
    # | 
				
			|||
    Require all granted | 
				
			|||
</Directory> | 
				
			|||
 | 
				
			|||
# | 
				
			|||
# DirectoryIndex: sets the file that Apache will serve if a directory | 
				
			|||
# is requested. | 
				
			|||
# | 
				
			|||
<IfModule dir_module> | 
				
			|||
    DirectoryIndex index.html | 
				
			|||
</IfModule> | 
				
			|||
 | 
				
			|||
# | 
				
			|||
# The following lines prevent .htaccess and .htpasswd files from being  | 
				
			|||
# viewed by Web clients.  | 
				
			|||
# | 
				
			|||
<Files ".ht*"> | 
				
			|||
    Require all denied | 
				
			|||
</Files> | 
				
			|||
 | 
				
			|||
# | 
				
			|||
# ErrorLog: The location of the error log file. | 
				
			|||
# If you do not specify an ErrorLog directive within a <VirtualHost> | 
				
			|||
# container, error messages relating to that virtual host will be | 
				
			|||
# logged here.  If you *do* define an error logfile for a <VirtualHost> | 
				
			|||
# container, that host's errors will be logged there and not here. | 
				
			|||
# | 
				
			|||
ErrorLog /proc/self/fd/2 | 
				
			|||
 | 
				
			|||
# | 
				
			|||
# LogLevel: Control the number of messages logged to the error_log. | 
				
			|||
# Possible values include: debug, info, notice, warn, error, crit, | 
				
			|||
# alert, emerg. | 
				
			|||
# | 
				
			|||
LogLevel warn | 
				
			|||
 | 
				
			|||
<IfModule log_config_module> | 
				
			|||
    # | 
				
			|||
    # The following directives define some format nicknames for use with | 
				
			|||
    # a CustomLog directive (see below). | 
				
			|||
    # | 
				
			|||
    LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined | 
				
			|||
    LogFormat "%h %l %u %t \"%r\" %>s %b" common | 
				
			|||
 | 
				
			|||
    <IfModule logio_module> | 
				
			|||
      # You need to enable mod_logio.c to use %I and %O | 
				
			|||
      LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio | 
				
			|||
    </IfModule> | 
				
			|||
 | 
				
			|||
    # | 
				
			|||
    # The location and format of the access logfile (Common Logfile Format). | 
				
			|||
    # If you do not define any access logfiles within a <VirtualHost> | 
				
			|||
    # container, they will be logged here.  Contrariwise, if you *do* | 
				
			|||
    # define per-<VirtualHost> access logfiles, transactions will be | 
				
			|||
    # logged therein and *not* in this file. | 
				
			|||
    # | 
				
			|||
    CustomLog /proc/self/fd/1 common | 
				
			|||
 | 
				
			|||
    # | 
				
			|||
    # If you prefer a logfile with access, agent, and referer information | 
				
			|||
    # (Combined Logfile Format) you can use the following directive. | 
				
			|||
    # | 
				
			|||
    #CustomLog "logs/access_log" combined | 
				
			|||
</IfModule> | 
				
			|||
 | 
				
			|||
<IfModule alias_module> | 
				
			|||
    # | 
				
			|||
    # Redirect: Allows you to tell clients about documents that used to  | 
				
			|||
    # exist in your server's namespace, but do not anymore. The client  | 
				
			|||
    # will make a new request for the document at its new location. | 
				
			|||
    # Example: | 
				
			|||
    # Redirect permanent /foo http://www.example.com/bar | 
				
			|||
 | 
				
			|||
    # | 
				
			|||
    # Alias: Maps web paths into filesystem paths and is used to | 
				
			|||
    # access content that does not live under the DocumentRoot. | 
				
			|||
    # Example: | 
				
			|||
    # Alias /webpath /full/filesystem/path | 
				
			|||
    # | 
				
			|||
    # If you include a trailing / on /webpath then the server will | 
				
			|||
    # require it to be present in the URL.  You will also likely | 
				
			|||
    # need to provide a <Directory> section to allow access to | 
				
			|||
    # the filesystem path. | 
				
			|||
 | 
				
			|||
    # | 
				
			|||
    # ScriptAlias: This controls which directories contain server scripts.  | 
				
			|||
    # ScriptAliases are essentially the same as Aliases, except that | 
				
			|||
    # documents in the target directory are treated as applications and | 
				
			|||
    # run by the server when requested rather than as documents sent to the | 
				
			|||
    # client.  The same rules about trailing "/" apply to ScriptAlias | 
				
			|||
    # directives as to Alias. | 
				
			|||
    # | 
				
			|||
    ScriptAlias /cgi-bin/ "/usr/local/apache2/cgi-bin/" | 
				
			|||
 | 
				
			|||
</IfModule> | 
				
			|||
 | 
				
			|||
<IfModule cgid_module> | 
				
			|||
    # | 
				
			|||
    # ScriptSock: On threaded servers, designate the path to the UNIX | 
				
			|||
    # socket used to communicate with the CGI daemon of mod_cgid. | 
				
			|||
    # | 
				
			|||
    #Scriptsock cgisock | 
				
			|||
</IfModule> | 
				
			|||
 | 
				
			|||
# | 
				
			|||
# "/usr/local/apache2/cgi-bin" should be changed to whatever your ScriptAliased | 
				
			|||
# CGI directory exists, if you have that configured. | 
				
			|||
# | 
				
			|||
<Directory "/usr/local/apache2/cgi-bin"> | 
				
			|||
    AllowOverride None | 
				
			|||
    Options None | 
				
			|||
    Require all granted | 
				
			|||
</Directory> | 
				
			|||
 | 
				
			|||
<IfModule headers_module> | 
				
			|||
    # | 
				
			|||
    # Avoid passing HTTP_PROXY environment to CGI's on this or any proxied | 
				
			|||
    # backend servers which have lingering "httpoxy" defects. | 
				
			|||
    # 'Proxy' request header is undefined by the IETF, not listed by IANA | 
				
			|||
    # | 
				
			|||
    RequestHeader unset Proxy early | 
				
			|||
</IfModule> | 
				
			|||
 | 
				
			|||
<IfModule mime_module> | 
				
			|||
    # | 
				
			|||
    # TypesConfig points to the file containing the list of mappings from | 
				
			|||
    # filename extension to MIME-type. | 
				
			|||
    # | 
				
			|||
    TypesConfig conf/mime.types | 
				
			|||
 | 
				
			|||
    # | 
				
			|||
    # AddType allows you to add to or override the MIME configuration | 
				
			|||
    # file specified in TypesConfig for specific file types. | 
				
			|||
    # | 
				
			|||
    #AddType application/x-gzip .tgz | 
				
			|||
    # | 
				
			|||
    # AddEncoding allows you to have certain browsers uncompress | 
				
			|||
    # information on the fly. Note: Not all browsers support this. | 
				
			|||
    # | 
				
			|||
    #AddEncoding x-compress .Z | 
				
			|||
    #AddEncoding x-gzip .gz .tgz | 
				
			|||
    # | 
				
			|||
    # If the AddEncoding directives above are commented-out, then you | 
				
			|||
    # probably should define those extensions to indicate media types: | 
				
			|||
    # | 
				
			|||
    AddType application/x-compress .Z | 
				
			|||
    AddType application/x-gzip .gz .tgz | 
				
			|||
 | 
				
			|||
    # | 
				
			|||
    # AddHandler allows you to map certain file extensions to "handlers": | 
				
			|||
    # actions unrelated to filetype. These can be either built into the server | 
				
			|||
    # or added with the Action directive (see below) | 
				
			|||
    # | 
				
			|||
    # To use CGI scripts outside of ScriptAliased directories: | 
				
			|||
    # (You will also need to add "ExecCGI" to the "Options" directive.) | 
				
			|||
    # | 
				
			|||
    #AddHandler cgi-script .cgi | 
				
			|||
 | 
				
			|||
    # For type maps (negotiated resources): | 
				
			|||
    #AddHandler type-map var | 
				
			|||
 | 
				
			|||
    # | 
				
			|||
    # Filters allow you to process content before it is sent to the client. | 
				
			|||
    # | 
				
			|||
    # To parse .shtml files for server-side includes (SSI): | 
				
			|||
    # (You will also need to add "Includes" to the "Options" directive.) | 
				
			|||
    # | 
				
			|||
    #AddType text/html .shtml | 
				
			|||
    #AddOutputFilter INCLUDES .shtml | 
				
			|||
</IfModule> | 
				
			|||
 | 
				
			|||
# | 
				
			|||
# The mod_mime_magic module allows the server to use various hints from the | 
				
			|||
# contents of the file itself to determine its type.  The MIMEMagicFile | 
				
			|||
# directive tells the module where the hint definitions are located. | 
				
			|||
# | 
				
			|||
#MIMEMagicFile conf/magic | 
				
			|||
 | 
				
			|||
# | 
				
			|||
# Customizable error responses come in three flavors: | 
				
			|||
# 1) plain text 2) local redirects 3) external redirects | 
				
			|||
# | 
				
			|||
# Some examples: | 
				
			|||
#ErrorDocument 500 "The server made a boo boo." | 
				
			|||
#ErrorDocument 404 /missing.html | 
				
			|||
#ErrorDocument 404 "/cgi-bin/missing_handler.pl" | 
				
			|||
#ErrorDocument 402 http://www.example.com/subscription_info.html | 
				
			|||
# | 
				
			|||
 | 
				
			|||
# | 
				
			|||
# MaxRanges: Maximum number of Ranges in a request before | 
				
			|||
# returning the entire resource, or one of the special | 
				
			|||
# values 'default', 'none' or 'unlimited'. | 
				
			|||
# Default setting is to accept 200 Ranges. | 
				
			|||
#MaxRanges unlimited | 
				
			|||
 | 
				
			|||
# | 
				
			|||
# EnableMMAP and EnableSendfile: On systems that support it,  | 
				
			|||
# memory-mapping or the sendfile syscall may be used to deliver | 
				
			|||
# files.  This usually improves server performance, but must | 
				
			|||
# be turned off when serving from networked-mounted  | 
				
			|||
# filesystems or if support for these functions is otherwise | 
				
			|||
# broken on your system. | 
				
			|||
# Defaults: EnableMMAP On, EnableSendfile Off | 
				
			|||
# | 
				
			|||
#EnableMMAP off | 
				
			|||
#EnableSendfile on | 
				
			|||
 | 
				
			|||
# Supplemental configuration | 
				
			|||
# | 
				
			|||
# The configuration files in the conf/extra/ directory can be  | 
				
			|||
# included to add extra features or to modify the default configuration of  | 
				
			|||
# the server, or you may simply copy their contents here and change as  | 
				
			|||
# necessary. | 
				
			|||
 | 
				
			|||
# Server-pool management (MPM specific) | 
				
			|||
#Include conf/extra/httpd-mpm.conf | 
				
			|||
 | 
				
			|||
# Multi-language error messages | 
				
			|||
#Include conf/extra/httpd-multilang-errordoc.conf | 
				
			|||
 | 
				
			|||
# Fancy directory listings | 
				
			|||
#Include conf/extra/httpd-autoindex.conf | 
				
			|||
 | 
				
			|||
# Language settings | 
				
			|||
#Include conf/extra/httpd-languages.conf | 
				
			|||
 | 
				
			|||
# User home directories | 
				
			|||
#Include conf/extra/httpd-userdir.conf | 
				
			|||
 | 
				
			|||
# Real-time info on requests and configuration | 
				
			|||
#Include conf/extra/httpd-info.conf | 
				
			|||
 | 
				
			|||
# Virtual hosts | 
				
			|||
#Include conf/extra/httpd-vhosts.conf | 
				
			|||
 | 
				
			|||
# Local access to the Apache HTTP Server Manual | 
				
			|||
#Include conf/extra/httpd-manual.conf | 
				
			|||
 | 
				
			|||
# Distributed authoring and versioning (WebDAV) | 
				
			|||
#Include conf/extra/httpd-dav.conf | 
				
			|||
 | 
				
			|||
# Various default settings | 
				
			|||
#Include conf/extra/httpd-default.conf | 
				
			|||
 | 
				
			|||
# Configure mod_proxy_html to understand HTML4/XHTML1 | 
				
			|||
<IfModule proxy_html_module> | 
				
			|||
Include conf/extra/proxy-html.conf | 
				
			|||
</IfModule> | 
				
			|||
 | 
				
			|||
# Secure (SSL/TLS) connections | 
				
			|||
#Include conf/extra/httpd-ssl.conf | 
				
			|||
# | 
				
			|||
# Note: The following must must be present to support | 
				
			|||
#       starting without SSL on platforms with no /dev/random equivalent | 
				
			|||
#       but a statically compiled-in mod_ssl. | 
				
			|||
# | 
				
			|||
<IfModule ssl_module> | 
				
			|||
SSLRandomSeed startup builtin | 
				
			|||
SSLRandomSeed connect builtin | 
				
			|||
</IfModule> | 
				
			|||
 | 
				
			|||
 | 
				
			|||
<Location "/"> | 
				
			|||
    AuthType Digest | 
				
			|||
    AuthName "Private" | 
				
			|||
    AuthDigestDomain / | 
				
			|||
    AuthDigestProvider file | 
				
			|||
    AuthUserFile "/usr/local/apache2/conf/.htdigest" | 
				
			|||
    Require valid-user | 
				
			|||
</Location> | 
				
			|||
@ -0,0 +1,36 @@ | 
				
			|||
package main | 
				
			|||
 | 
				
			|||
import ( | 
				
			|||
	"fmt" | 
				
			|||
	"io/ioutil" | 
				
			|||
	"log" | 
				
			|||
	"net/http" | 
				
			|||
 | 
				
			|||
	dac "github.com/xinsnake/go-http-digest-auth-client" | 
				
			|||
) | 
				
			|||
 | 
				
			|||
const ( | 
				
			|||
	username = "test" | 
				
			|||
	password = "test123" | 
				
			|||
	method   = "GET" | 
				
			|||
	uri      = "http://172.16.1.5" | 
				
			|||
) | 
				
			|||
 | 
				
			|||
func main() { | 
				
			|||
	var resp *http.Response | 
				
			|||
	var body []byte | 
				
			|||
	var err error | 
				
			|||
 | 
				
			|||
	dr := dac.NewRequest(username, password, method, uri, "") | 
				
			|||
 | 
				
			|||
	if resp, err = dr.Execute(); err != nil { | 
				
			|||
		log.Fatalln(err) | 
				
			|||
	} | 
				
			|||
	defer resp.Body.Close() | 
				
			|||
 | 
				
			|||
	if body, err = ioutil.ReadAll(resp.Body); err != nil { | 
				
			|||
		log.Fatalln(err) | 
				
			|||
	} | 
				
			|||
 | 
				
			|||
	fmt.Printf(string(body)) | 
				
			|||
} | 
				
			|||
@ -0,0 +1,79 @@ | 
				
			|||
package digest_auth_client | 
				
			|||
 | 
				
			|||
import ( | 
				
			|||
	"regexp" | 
				
			|||
	"strings" | 
				
			|||
) | 
				
			|||
 | 
				
			|||
type wwwAuthenticate struct { | 
				
			|||
	Algorithm string // unquoted
 | 
				
			|||
	Domain    string // quoted
 | 
				
			|||
	Nonce     string // quoted
 | 
				
			|||
	Opaque    string // quoted
 | 
				
			|||
	Qop       string // quoted
 | 
				
			|||
	Realm     string // quoted
 | 
				
			|||
	Stale     bool   // unquoted
 | 
				
			|||
	Charset   string // quoted
 | 
				
			|||
	Userhash  bool   // quoted
 | 
				
			|||
} | 
				
			|||
 | 
				
			|||
func newWwwAuthenticate(s string) *wwwAuthenticate { | 
				
			|||
 | 
				
			|||
	var wa = wwwAuthenticate{} | 
				
			|||
 | 
				
			|||
	algorithmRegex := regexp.MustCompile(`algorithm=([^ ,]+)`) | 
				
			|||
	algorithmMatch := algorithmRegex.FindStringSubmatch(s) | 
				
			|||
	if algorithmMatch != nil { | 
				
			|||
		wa.Algorithm = algorithmMatch[1] | 
				
			|||
	} | 
				
			|||
 | 
				
			|||
	domainRegex := regexp.MustCompile(`domain="(.+?)"`) | 
				
			|||
	domainMatch := domainRegex.FindStringSubmatch(s) | 
				
			|||
	if domainMatch != nil { | 
				
			|||
		wa.Domain = domainMatch[1] | 
				
			|||
	} | 
				
			|||
 | 
				
			|||
	nonceRegex := regexp.MustCompile(`nonce="(.+?)"`) | 
				
			|||
	nonceMatch := nonceRegex.FindStringSubmatch(s) | 
				
			|||
	if nonceMatch != nil { | 
				
			|||
		wa.Nonce = nonceMatch[1] | 
				
			|||
	} | 
				
			|||
 | 
				
			|||
	opaqueRegex := regexp.MustCompile(`opaque="(.+?)"`) | 
				
			|||
	opaqueMatch := opaqueRegex.FindStringSubmatch(s) | 
				
			|||
	if opaqueMatch != nil { | 
				
			|||
		wa.Opaque = opaqueMatch[1] | 
				
			|||
	} | 
				
			|||
 | 
				
			|||
	qopRegex := regexp.MustCompile(`qop="(.+?)"`) | 
				
			|||
	qopMatch := qopRegex.FindStringSubmatch(s) | 
				
			|||
	if qopMatch != nil { | 
				
			|||
		wa.Qop = qopMatch[1] | 
				
			|||
	} | 
				
			|||
 | 
				
			|||
	realmRegex := regexp.MustCompile(`realm="(.+?)"`) | 
				
			|||
	realmMatch := realmRegex.FindStringSubmatch(s) | 
				
			|||
	if realmMatch != nil { | 
				
			|||
		wa.Realm = realmMatch[1] | 
				
			|||
	} | 
				
			|||
 | 
				
			|||
	staleRegex := regexp.MustCompile(`stale=([^ ,])"`) | 
				
			|||
	staleMatch := staleRegex.FindStringSubmatch(s) | 
				
			|||
	if staleMatch != nil { | 
				
			|||
		wa.Stale = (strings.ToLower(staleMatch[1]) == "true") | 
				
			|||
	} | 
				
			|||
 | 
				
			|||
	charsetRegex := regexp.MustCompile(`charset="(.+?)"`) | 
				
			|||
	charsetMatch := charsetRegex.FindStringSubmatch(s) | 
				
			|||
	if charsetMatch != nil { | 
				
			|||
		wa.Charset = charsetMatch[1] | 
				
			|||
	} | 
				
			|||
 | 
				
			|||
	userhashRegex := regexp.MustCompile(`userhash=([^ ,])"`) | 
				
			|||
	userhashMatch := userhashRegex.FindStringSubmatch(s) | 
				
			|||
	if userhashMatch != nil { | 
				
			|||
		wa.Userhash = (strings.ToLower(userhashMatch[1]) == "true") | 
				
			|||
	} | 
				
			|||
 | 
				
			|||
	return &wa | 
				
			|||
} | 
				
			|||
					Loading…
					
					
				
		Reference in new issue