// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// OtherResources=certificates/server_chain.pem
// OtherResources=certificates/server_key.pem
// OtherResources=certificates/trusted_certs.pem

import "dart:async";
import "dart:io";
import 'dart:convert';
import "package:convert/convert.dart";
import "package:crypto/crypto.dart";
import "package:expect/expect.dart";

String localFile(path) => Platform.script.resolve(path).toFilePath();

final SecurityContext serverContext = new SecurityContext()
  ..useCertificateChain(localFile('certificates/server_chain.pem'))
  ..usePrivateKey(localFile('certificates/server_key.pem'),
      password: 'dartdart');

final SecurityContext clientContext = new SecurityContext()
  ..setTrustedCertificates(localFile('certificates/trusted_certs.pem'));

class Server {
  HttpServer server;
  bool secure;
  int proxyHops;
  List<String> directRequestPaths;
  int requestCount = 0;

  Server(this.proxyHops, this.directRequestPaths, this.secure);

  Future<Server> start() {
    return (secure
            ? HttpServer.bindSecure("localhost", 0, serverContext)
            : HttpServer.bind("localhost", 0))
        .then((s) {
      server = s;
      server.listen(requestHandler);
      return this;
    });
  }

  void requestHandler(HttpRequest request) {
    var response = request.response;
    requestCount++;
    // Check whether a proxy or direct connection is expected.
    bool direct = directRequestPaths.fold(
        false, (prev, path) => prev ? prev : path == request.uri.path);
    if (!secure && !direct && proxyHops > 0) {
      Expect.isNotNull(request.headers[HttpHeaders.viaHeader]);
      Expect.equals(1, request.headers[HttpHeaders.viaHeader].length);
      Expect.equals(proxyHops,
          request.headers[HttpHeaders.viaHeader][0].split(",").length);
    } else {
      Expect.isNull(request.headers[HttpHeaders.viaHeader]);
    }
    var body = new StringBuffer();
    onRequestComplete() {
      String path = request.uri.path.substring(1);
      if (path != "A") {
        String content = "$path$path$path";
        Expect.equals(content, body.toString());
      }
      response.write(request.uri.path);
      response.close();
    }

    request.listen((data) {
      body.write(new String.fromCharCodes(data));
    }, onDone: onRequestComplete);
  }

  void shutdown() {
    server.close();
  }

  int get port => server.port;
}

Future<Server> setupServer(int proxyHops,
    {List<String> directRequestPaths: const <String>[], secure: false}) {
  Server server = new Server(proxyHops, directRequestPaths, secure);
  return server.start();
}

class ProxyServer {
  final bool ipV6;
  HttpServer server;
  HttpClient client;
  int requestCount = 0;
  String authScheme;
  String realm = "test";
  String username;
  String password;

  var ha1;
  String serverAlgorithm = "MD5";
  String serverQop = "auth";
  Set ncs = new Set();

  var nonce = "12345678"; // No need for random nonce in test.

  ProxyServer({this.ipV6: false}) : client = new HttpClient();

  void useBasicAuthentication(String username, String password) {
    this.username = username;
    this.password = password;
    authScheme = "Basic";
  }

  basicAuthenticationRequired(request) {
    request.fold(null, (x, y) {}).then((_) {
      var response = request.response;
      response.headers
          .set(HttpHeaders.proxyAuthenticateHeader, "Basic, realm=$realm");
      response.statusCode = HttpStatus.proxyAuthenticationRequired;
      response.close();
    });
  }

  digestAuthenticationRequired(request, {stale: false}) {
    request.fold(null, (x, y) {}).then((_) {
      var response = request.response;
      response.statusCode = HttpStatus.proxyAuthenticationRequired;
      StringBuffer authHeader = new StringBuffer();
      authHeader.write('Digest');
      authHeader.write(', realm="$realm"');
      authHeader.write(', nonce="$nonce"');
      if (stale) authHeader.write(', stale="true"');
      if (serverAlgorithm != null) {
        authHeader.write(', algorithm=$serverAlgorithm');
      }
      if (serverQop != null) authHeader.write(', qop="$serverQop"');
      response.headers.set(HttpHeaders.proxyAuthenticateHeader, authHeader);
      response.close();
    });
  }

  Future<ProxyServer> start() {
    var x = new Completer<ProxyServer>();
    var host = ipV6 ? "::1" : "localhost";
    HttpServer.bind(host, 0).then((s) {
      server = s;
      x.complete(this);
      server.listen((HttpRequest request) {
        requestCount++;
        if (username != null && password != null) {
          if (request.headers[HttpHeaders.proxyAuthorizationHeader] == null) {
            if (authScheme == "Digest") {
              digestAuthenticationRequired(request);
            } else {
              basicAuthenticationRequired(request);
            }
            return;
          } else {
            Expect.equals(1,
                request.headers[HttpHeaders.proxyAuthorizationHeader].length);
            String authorization =
                request.headers[HttpHeaders.proxyAuthorizationHeader][0];
            if (authScheme == "Basic") {
              List<String> tokens = authorization.split(" ");
              Expect.equals("Basic", tokens[0]);
              String auth = base64.encode(utf8.encode("$username:$password"));
              if (auth != tokens[1]) {
                basicAuthenticationRequired(request);
                return;
              }
            } else {
              HeaderValue header =
                  HeaderValue.parse(authorization, parameterSeparator: ",");
              Expect.equals("Digest", header.value);
              var uri = header.parameters["uri"];
              var qop = header.parameters["qop"];
              var cnonce = header.parameters["cnonce"];
              var nc = header.parameters["nc"];
              Expect.equals(username, header.parameters["username"]);
              Expect.equals(realm, header.parameters["realm"]);
              Expect.equals("MD5", header.parameters["algorithm"]);
              Expect.equals(nonce, header.parameters["nonce"]);
              Expect.equals(request.uri.toString(), uri);
              if (qop != null) {
                // A server qop of auth-int is downgraded to none by the client.
                Expect.equals("auth", serverQop);
                Expect.equals("auth", header.parameters["qop"]);
                Expect.isNotNull(cnonce);
                Expect.isNotNull(nc);
                Expect.isFalse(ncs.contains(nc));
                ncs.add(nc);
              } else {
                Expect.isNull(cnonce);
                Expect.isNull(nc);
              }
              Expect.isNotNull(header.parameters["response"]);

              var digest = md5.convert("${request.method}:${uri}".codeUnits);
              var ha2 = hex.encode(digest.bytes);

              if (qop == null || qop == "" || qop == "none") {
                digest = md5.convert("$ha1:${nonce}:$ha2".codeUnits);
              } else {
                digest = md5.convert(
                    "$ha1:${nonce}:${nc}:${cnonce}:${qop}:$ha2".codeUnits);
              }
              Expect.equals(
                  hex.encode(digest.bytes), header.parameters["response"]);

              // Add a bogus Proxy-Authentication-Info for testing.
              var info = 'rspauth="77180d1ab3d6c9de084766977790f482", '
                  'cnonce="8f971178", '
                  'nc=000002c74, '
                  'qop=auth';
              request.response.headers.set("Proxy-Authentication-Info", info);
            }
          }
        }
        // Open the connection from the proxy.
        if (request.method == "CONNECT") {
          var tmp = request.uri.toString().split(":");
          Socket.connect(tmp[0], int.parse(tmp[1])).then((socket) {
            request.response.reasonPhrase = "Connection established";
            request.response.detachSocket().then((detached) {
              socket.cast<List<int>>().pipe(detached);
              detached.cast<List<int>>().pipe(socket);
            });
          });
        } else {
          client
              .openUrl(request.method, request.uri)
              .then((HttpClientRequest clientRequest) {
            // Forward all headers.
            request.headers.forEach((String name, List<String> values) {
              values.forEach((String value) {
                if (name != "content-length" && name != "via") {
                  clientRequest.headers.add(name, value);
                }
              });
            });
            // Special handling of Content-Length and Via.
            clientRequest.contentLength = request.contentLength;
            List<String> via = request.headers[HttpHeaders.viaHeader];
            String viaPrefix = via == null ? "" : "${via[0]}, ";
            clientRequest.headers
                .add(HttpHeaders.viaHeader, "${viaPrefix}1.1 localhost:$port");
            // Copy all content.
            return request.cast<List<int>>().pipe(clientRequest);
          }).then((clientResponse) {
            (clientResponse as HttpClientResponse)
                .cast<List<int>>()
                .pipe(request.response);
          });
        }
      });
    });
    return x.future;
  }

  void shutdown() {
    server.close();
    client.close();
  }

  int get port => server.port;
}

Future<ProxyServer> setupProxyServer({ipV6: false}) {
  ProxyServer proxyServer = new ProxyServer(ipV6: ipV6);
  return proxyServer.start();
}

testInvalidProxy() {
  HttpClient client = new HttpClient(context: clientContext);

  client.findProxy = (Uri uri) => "";
  client
      .getUrl(Uri.parse("http://www.google.com/test"))
      .catchError((error) {}, test: (e) => e is HttpException);

  client.findProxy = (Uri uri) => "XXX";
  client
      .getUrl(Uri.parse("http://www.google.com/test"))
      .catchError((error) {}, test: (e) => e is HttpException);

  client.findProxy = (Uri uri) => "PROXY www.google.com";
  client
      .getUrl(Uri.parse("http://www.google.com/test"))
      .catchError((error) {}, test: (e) => e is HttpException);

  client.findProxy = (Uri uri) => "PROXY www.google.com:http";
  client
      .getUrl(Uri.parse("http://www.google.com/test"))
      .catchError((error) {}, test: (e) => e is HttpException);
}

int testDirectDoneCount = 0;
void testDirectProxy() {
  setupServer(0).then((server) {
    HttpClient client = new HttpClient(context: clientContext);
    List<String> proxy = [
      "DIRECT",
      " DIRECT ",
      "DIRECT ;",
      " DIRECT ; ",
      ";DIRECT",
      " ; DIRECT ",
      ";;DIRECT;;"
    ];

    client.findProxy = (Uri uri) {
      int index = int.parse(uri.path.substring(1));
      return proxy[index];
    };

    for (int i = 0; i < proxy.length; i++) {
      client
          .getUrl(Uri.parse("http://localhost:${server.port}/$i"))
          .then((HttpClientRequest clientRequest) {
        String content = "$i$i$i";
        clientRequest.contentLength = content.length;
        clientRequest.write(content);
        return clientRequest.close();
      }).then((HttpClientResponse response) {
        response.listen((_) {}, onDone: () {
          testDirectDoneCount++;
          if (testDirectDoneCount == proxy.length) {
            Expect.equals(proxy.length, server.requestCount);
            server.shutdown();
            client.close();
          }
        });
      });
    }
  });
}

int testProxyDoneCount = 0;
void testProxy() {
  setupProxyServer().then((proxyServer) {
    setupServer(1, directRequestPaths: ["/4"]).then((server) {
      setupServer(1, directRequestPaths: ["/4"], secure: true)
          .then((secureServer) {
        HttpClient client = new HttpClient(context: clientContext);

        List<String> proxy;
        if (Platform.operatingSystem == "windows") {
          proxy = [
            "PROXY localhost:${proxyServer.port}",
            "PROXY localhost:${proxyServer.port}; PROXY hede.hule.hest:8080",
            "PROXY localhost:${proxyServer.port}",
            ""
                " PROXY localhost:${proxyServer.port}",
            "DIRECT",
            "PROXY localhost:${proxyServer.port}; DIRECT"
          ];
        } else {
          proxy = [
            "PROXY localhost:${proxyServer.port}",
            "PROXY localhost:${proxyServer.port}; PROXY hede.hule.hest:8080",
            "PROXY hede.hule.hest:8080; PROXY localhost:${proxyServer.port}",
            "PROXY hede.hule.hest:8080; PROXY hede.hule.hest:8181;"
                " PROXY localhost:${proxyServer.port}",
            "PROXY hede.hule.hest:8080; PROXY hede.hule.hest:8181; DIRECT",
            "PROXY localhost:${proxyServer.port}; DIRECT"
          ];
        }
        client.findProxy = (Uri uri) {
          // Pick the proxy configuration based on the request path.
          int index = int.parse(uri.path.substring(1));
          return proxy[index];
        };

        for (int i = 0; i < proxy.length; i++) {
          test(bool secure) {
            String url = secure
                ? "https://localhost:${secureServer.port}/$i"
                : "http://localhost:${server.port}/$i";

            client
                .postUrl(Uri.parse(url))
                .then((HttpClientRequest clientRequest) {
              String content = "$i$i$i";
              clientRequest.write(content);
              return clientRequest.close();
            }).then((HttpClientResponse response) {
              response.listen((_) {}, onDone: () {
                testProxyDoneCount++;
                if (testProxyDoneCount == proxy.length * 2) {
                  Expect.equals(proxy.length, server.requestCount);
                  Expect.equals(proxy.length, secureServer.requestCount);
                  proxyServer.shutdown();
                  server.shutdown();
                  secureServer.shutdown();
                  client.close();
                }
              });
            });
          }

          test(false);
          test(true);
        }
      });
    });
  });
}

int testProxyChainDoneCount = 0;
void testProxyChain() {
  // Setup two proxy servers having the first using the second as its proxy.
  setupProxyServer().then((proxyServer1) {
    setupProxyServer().then((proxyServer2) {
      proxyServer1.client.findProxy =
          (_) => "PROXY localhost:${proxyServer2.port}";

      setupServer(2, directRequestPaths: ["/4"]).then((server) {
        HttpClient client = new HttpClient(context: clientContext);

        List<String> proxy;
        if (Platform.operatingSystem == "windows") {
          proxy = [
            "PROXY localhost:${proxyServer1.port}",
            "PROXY localhost:${proxyServer1.port}; PROXY hede.hule.hest:8080",
            "PROXY localhost:${proxyServer1.port}",
            "PROXY localhost:${proxyServer1.port}",
            "DIRECT",
            "PROXY localhost:${proxyServer1.port}; DIRECT"
          ];
        } else {
          proxy = [
            "PROXY localhost:${proxyServer1.port}",
            "PROXY localhost:${proxyServer1.port}; PROXY hede.hule.hest:8080",
            "PROXY hede.hule.hest:8080; PROXY localhost:${proxyServer1.port}",
            "PROXY hede.hule.hest:8080; PROXY hede.hule.hest:8181;"
                " PROXY localhost:${proxyServer1.port}",
            "PROXY hede.hule.hest:8080; PROXY hede.hule.hest:8181; DIRECT",
            "PROXY localhost:${proxyServer1.port}; DIRECT"
          ];
        }

        client.findProxy = (Uri uri) {
          // Pick the proxy configuration based on the request path.
          int index = int.parse(uri.path.substring(1));
          return proxy[index];
        };

        for (int i = 0; i < proxy.length; i++) {
          client
              .getUrl(Uri.parse("http://localhost:${server.port}/$i"))
              .then((HttpClientRequest clientRequest) {
            String content = "$i$i$i";
            clientRequest.contentLength = content.length;
            clientRequest.write(content);
            return clientRequest.close();
          }).then((HttpClientResponse response) {
            response.listen((_) {}, onDone: () {
              testProxyChainDoneCount++;
              if (testProxyChainDoneCount == proxy.length) {
                Expect.equals(proxy.length, server.requestCount);
                proxyServer1.shutdown();
                proxyServer2.shutdown();
                server.shutdown();
                client.close();
              }
            });
          });
        }
      });
    });
  });
}

main() {
  testInvalidProxy();
  testDirectProxy();
  testProxy();
  testProxyChain();
}
