docs: protected HttpURLConnection openConnection(String url, Map<String, String> header) throws IOException {
  		// Initialize connection
  		URL urlObj = null;
  		HttpURLConnection conn = null;
  
  		int redirectCount = 0;
  		boolean redirect = true;
  		while (redirect) {
  			if (redirectCount > 10) {
  				throw new ProtocolException("Too many redirects: " + redirectCount);
  			}
  
  			if (conn == null) {
  				urlObj = new URL(url);
  			} else {
  				// get redirect url from "location" header field
  				urlObj = new URL(conn.getHeaderField("Location"));
  			}
  
  			// open the new connection again
  			conn = (HttpURLConnection) urlObj.openConnection();
  			conn.setRequestMethod(header.get("method"));
  			conn.setInstanceFollowRedirects(true);
  
  			// Set output if PUT or POST
  			if (conn.getRequestMethod() == "POST" || conn.getRequestMethod() == "PUT") {
  				conn.setDoOutput(true);
  			}
  
  			// Set request header
  			for (Map.Entry<String, String> headerAttr : header.entrySet()) {
  				conn.addRequestProperty(headerAttr.getKey(), headerAttr.getValue());
  			}
  
  			// Check if redirect
  			redirect = false;
  			if (conn.getRequestMethod() == "GET") {
  				int status = conn.getResponseCode();
  				if (status != HttpURLConnection.HTTP_OK) {
  					if (status == HttpURLConnection.HTTP_MOVED_TEMP || status == HttpURLConnection.HTTP_MOVED_PERM || status == HttpURLConnection.HTTP_SEE_OTHER)
  						redirect = true;
  					redirectCount++;
  				}
  			}
  		}
  
  		return conn;
  	}