<commit_before>import Foundation
import AWSSDKSwiftCore

public struct S3RequestMiddleware: AWSServiceMiddleware {

    public init () {}

    public func chain(request: AWSRequest) throws -> AWSRequest {
        var request = request

        var paths = request.url.path.components(separatedBy: "/").filter({ $0 != "" })
        if paths.count == 0 {
            return request
        }

        switch request.httpMethod.lowercased() {
        case "get":
            let query = request.url.query != nil ? "?\(request.url.query!)" : ""
            let domain: String
            if let host = request.url.host, host.contains("amazonaws.com") {
                domain = host
            } else {
                let port = request.url.port == nil ? "" : ":\(request.url.port!)"
                domain = request.url.host!+port
            }
            request.url = URL(string: "\(request.url.scheme ?? "https")://\(paths.removeFirst()).\(domain)/\(paths.joined(separator: "/"))\(query)")!
        default:
            guard let host = request.url.host, host.contains("amazonaws.com") else { break }
            var pathes = request.url.path.components(separatedBy: "/")
            if paths.count > 1 {
                _ = pathes.removeFirst() // /
                let bucket = pathes.removeFirst() // bucket
                var urlString: String
                if let firstHostComponent = host.components(separatedBy: ".").first, bucket == firstHostComponent {
                    // Bucket name is part of host. No need to append bucket
                    urlString = "https://\(host)/\(pathes.joined(separator: "/"))"
                } else {
                    urlString = "https://\(bucket).\(host)/\(pathes.joined(separator: "/"))"
                }
                if let query = request.url.query {
                    urlString += "?\(query)"
                }
                request.url = URL(string: urlString)!
            }
        }

        switch request.operation {
        case "CreateBucket":
            var xml = ""
            if request.region != .useast1 {
                xml += "<CreateBucketConfiguration xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\">"
                xml += "<LocationConstraint>"
                xml += request.region.rawValue
                xml += "</LocationConstraint>"
                xml += "</CreateBucketConfiguration>"
            }
            request.body = .text(xml)

        default:
            break
        }

        if let data = request.body.asData() {
            let encoded = Data(md5(data)).base64EncodedString()
            request.addValue(encoded, forHTTPHeaderField: "Content-MD5")
        }

        return request
    }
    
    
    public func chain(responseBody: Body) throws -> Body {
        switch responseBody {
        case .xml(let element):
            if element.name == "LocationConstraint" {
                let parentElement = XML.Element(name: "BucketLocation")
                parentElement.addChild(element)
                return .xml(parentElement)
            }
        default:
            break
        }
        return responseBody<commit_msg>Fixup S3RequestMiddleware to work with new AWSResponse<commit_after>import Foundation
import AWSSDKSwiftCore

public struct S3RequestMiddleware: AWSServiceMiddleware {

    public init () {}

    public func chain(request: AWSRequest) throws -> AWSRequest {
        var request = request

        var paths = request.url.path.components(separatedBy: "/").filter({ $0 != "" })
        if paths.count == 0 {
            return request
        }

        switch request.httpMethod.lowercased() {
        case "get":
            let query = request.url.query != nil ? "?\(request.url.query!)" : ""
            let domain: String
            if let host = request.url.host, host.contains("amazonaws.com") {
                domain = host
            } else {
                let port = request.url.port == nil ? "" : ":\(request.url.port!)"
                domain = request.url.host!+port
            }
            request.url = URL(string: "\(request.url.scheme ?? "https")://\(paths.removeFirst()).\(domain)/\(paths.joined(separator: "/"))\(query)")!
        default:
            guard let host = request.url.host, host.contains("amazonaws.com") else { break }
            var pathes = request.url.path.components(separatedBy: "/")
            if paths.count > 1 {
                _ = pathes.removeFirst() // /
                let bucket = pathes.removeFirst() // bucket
                var urlString: String
                if let firstHostComponent = host.components(separatedBy: ".").first, bucket == firstHostComponent {
                    // Bucket name is part of host. No need to append bucket
                    urlString = "https://\(host)/\(pathes.joined(separator: "/"))"
                } else {
                    urlString = "https://\(bucket).\(host)/\(pathes.joined(separator: "/"))"
                }
                if let query = request.url.query {
                    urlString += "?\(query)"
                }
                request.url = URL(string: urlString)!
            }
        }

        switch request.operation {
        case "CreateBucket":
            var xml = ""
            if request.region != .useast1 {
                xml += "<CreateBucketConfiguration xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\">"
                xml += "<LocationConstraint>"
                xml += request.region.rawValue
                xml += "</LocationConstraint>"
                xml += "</CreateBucketConfiguration>"
            }
            request.body = .text(xml)

        default:
            break
        }

        if let data = request.body.asData() {
            let encoded = Data(md5(data)).base64EncodedString()
            request.addValue(encoded, forHTTPHeaderField: "Content-MD5")
        }

        return request
    }
    
    
    public func chain(response: AWSResponse) throws -> AWSResponse {
        switch response.body {
        case .xml(let element):
            if element.name == "LocationConstraint" {
                let parentElement = XML.Element(name: "BucketLocation")
                parentElement.addChild(element)
                
                var newResponse = response
                newResponse.body = .xml(parentElement)
                return newResponse
            }
        default:
            break
        }
        return response
{'fraction_non_alphanumeric': 0.1234338747099768, 'fraction_numerical': 0.005723124516627997, 'mean_word_length': 1.5709741550695826, 'pattern_counts': {'":': 6, '<': 11, '<?xml version=': 0, '>': 17, 'https://': 4, 'lorem ipsum': 0, 'www.': 0, 'xml': 20}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2558732', 'n_tokens_mistral': 1717, 'n_tokens_neox': 1597, 'n_words': 362}