public Branch(URI uri) {
   _uri = uri;
   _request = (SipRequest) ((SipRequest) getOriginalRequest()).clone();
   _request.setProxyImpl(((SipRequest) getOriginalRequest()).getProxyImpl());
   if (getOriginalRequest().isInitial())
     _request.setRoutingDirective(SipApplicationRoutingDirective.CONTINUE, getOriginalRequest());
 }
  public SipProxy(SipRequest request) throws TooManyHopsException {
    _tx = (ServerTransaction) request.getTransaction();
    _tx.setListener(this);

    int maxForwards = request.getMaxForwards();
    if (maxForwards == 0) throw new TooManyHopsException();
    else if (maxForwards == -1) request.setMaxForwards(70);

    if (LOG.isDebugEnabled()) LOG.debug("Created proxy for tx {}", _tx, null);
  }
    protected void start() {
      int mf = _request.getMaxForwards();
      if (mf == -1) mf = __maxForwards;
      else mf--;

      _request.setMaxForwards(mf);
      _request.setRequestURI(_uri);

      if (_branchRRUri != null) _request.addRecordRoute(new NameAddr(_branchRRUri));

      if (_branchPathUri != null && _request.isRegister())
        _request.addAddressHeader(SipHeaders.PATH, new NameAddr(_branchPathUri), true);

      // _ctx = _request.getCallSession().getServer().sendRequest(_request, this);
      try {
        _ctx = _request.session().sendRequest(_request, this);

        if (_request.isInvite()) startTimerC();

        _actives++;
      } catch (Exception e) {
        LOG.debug(e);
        // TODO
      }
    }
  /** Make sure that all our Via-headers can be modified the way we need it. */
  @Test
  public void testViaHeaderManipulation() throws Exception {
    final SipRequest request = (SipRequest) parseMessage(RawData.sipInvite);
    final ViaHeader topMostVia = request.getViaHeader();
    assertThat(topMostVia.getBranch().toString(), is("z9hG4bK-16732-1-0"));
    assertThat(topMostVia.getHost().toString(), is("127.0.1.1"));
    assertThat(topMostVia.getPort(), is(5060));

    assertTopMostVia(request, "192.168.0.100", 6789, "TCP");
    assertTopMostVia(request, "192.168.0.101", 1111, "UDP");
    final String str = request.toString();
    assertThat(str.contains("Via: SIP/2.0/TCP 192.168.0.100:6789"), is(true));
    assertThat(str.contains("Via: SIP/2.0/UDP 192.168.0.101:1111"), is(true));
  }
  public void handleCancel(ServerTransaction tx, SipRequest cancel) {
    cancel.setSession(_tx.getRequest().session());
    SipResponse response = new SipResponse(cancel, SipServletResponse.SC_OK, null);
    ((ServerTransaction) cancel.getTransaction()).send(response);

    cancel();
    try {
      if (!_started) // case no request has not been proxied
      _tx.getRequest().createResponse(SipServletResponse.SC_REQUEST_TERMINATED).send();

      cancel.session().invokeServlet(cancel);
    } catch (Exception e) {
      LOG.debug(e);
    }
  }
 public void customizeRequest(SipRequest request, SipConnection connection) {
   SipConnector connector = _tx.getRequest().getConnection().getConnector();
   if (getRecordRoute() && connection.getConnector() != connector) {
     SipURI rrUri = newProxyURI(connection.getConnector(), true);
     rrUri.setParameter(SipParams.DRR, "2");
     _branchRRUri.setParameter(SipParams.DRR, "");
     if (connector.getTransportOrdinal() == SipConnectors.TCP_ORDINAL)
       _branchRRUri.setTransportParam("tcp");
     if (connection.getConnector().getTransportOrdinal() == SipConnectors.TCP_ORDINAL)
       rrUri.setTransportParam("tcp");
     request.addRecordRoute(new NameAddr(rrUri));
   }
 }
    /** @see ProxyBranch#cancel(String[], int[], String[]) */
    public void cancel(String[] protocol, int[] reasonCode, String[] reasonText) {
      if (!_ctx.isCompleted()) {
        stopTimerC();

        SipRequest cancel = (SipRequest) _ctx.getRequest().createCancel();
        if (protocol != null) {
          for (int i = 0; i < protocol.length; i++) {
            String reason =
                protocol[i]
                    + ";cause="
                    + reasonCode[i]
                    + ";reason=\""
                    + SipGrammar.escapeQuoted(reasonText[i])
                    + "\"";
            cancel.addHeader(SipHeaders.REASON, reason);
          }
        }
        _ctx.cancel(cancel);
      }

      for (int i = LazyList.size(_recursedBranches); i-- > 0; ) {
        ((Branch) LazyList.get(_recursedBranches, i)).cancel(protocol, reasonCode, reasonText);
      }
    }
    public void handleResponse(SipResponse response) {
      _response = response;

      int status = response.getStatus();

      if (status == 100) return;

      if (_tx.isCompleted() && !response.is2xx()) {
        if (LOG.isDebugEnabled())
          LOG.debug("Dropping response " + response.getStatus() + " since proxy is completed");
        return;
      }

      if (LOG.isDebugEnabled()) LOG.debug("Got response {}", response, null);

      SipRequest request = _tx.getRequest();

      Session session = request.session();

      if (request.isInitial() && status < 300) {
        if (!session.isSameDialog(response)) {
          AppSession appSession = session.appSession();
          Session derived = appSession.getSession(response);
          if (derived == null) derived = appSession.createDerivedSession(session);
          session = derived;
        }
      }

      response.setSession(session);
      if (status < 300) session.updateState(response, false);

      response.removeTopVia();
      response.setProxyBranch(this);

      if (status < 200) {
        if (response.isInvite()) updateTimerC();

        invokeServlet(response);
        forward(response);
      } else {
        _actives--;

        stopTimerC();

        if ((300 <= status && status < 400) && _branchRecurse) {
          try {
            Iterator<Address> it = response.getAddressHeaders(SipHeaders.CONTACT);
            while (it.hasNext()) {
              Address contact = (Address) it.next();
              if (contact.getURI().isSipURI()) {
                Branch branch = addTarget(contact.getURI());
                if (branch != null) {
                  _recursedBranches = LazyList.add(_recursedBranches, branch);
                  branch.setRecurse(_branchRecurse);
                }
              }
            }
          } catch (ServletParseException e) {
            LOG.ignore(e);
          }
        }

        if (_best == null
            || (_best.getStatus() < 600 && (status < _best.getStatus() || status >= 600))) {
          _best = response;
        }

        if (status >= 600) {
          SipProxy.this.doCancel(null, null, null);
        }

        if (status < 300) {
          invokeServlet(response);
          forward(response);

          SipProxy.this.doCancel(null, null, null);
        } else {
          if (LazyList.size(_targets) > 0) startProxy();

          if (_actives > 0) {
            response.setBranchResponse(true);
            invokeServlet(response);
          } else {
            tryFinal();
          }
        }
      }
    }