Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
227 changes: 102 additions & 125 deletions pkts-sip/src/main/java/io/pkts/packet/sip/SipMessage.java

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ default boolean isAddressParametersHeader() {
return true;
}

@Override
default AddressParametersHeader toAddressParametersHeader() throws ClassCastException {
return this;
}
Expand Down Expand Up @@ -100,6 +101,7 @@ protected Builder(final Buffer name, final ParametersSupport params) {
}


@Override
public final Builder<T> withValue(final Buffer buffer) {
throw new RuntimeException("Not implemented yet");
// Address.frame(buffer).copy();
Expand Down Expand Up @@ -388,6 +390,7 @@ public final Builder<T> withAddress(final Address address) throws SipParseExcept
* @throws SipParseException in case anything goes wrong while constructing the
* {@link ToHeader}.
*/
@Override
public final T build() throws SipParseException {
if (addressBuilder == null) {
throw new SipParseException("You must specify an address of some sort.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ public Builder withValue(Buffer value) {
throw new RuntimeException("Not implemented yet");
}

@Override
public CSeqHeader build() {
final int size = Buffers.stringSizeOf(this.cseq);
final Buffer value = Buffers.createBuffer(size + 1 + this.method.getReadableBytes());
Expand Down
188 changes: 110 additions & 78 deletions pkts-sip/src/main/java/io/pkts/packet/sip/header/SipHeader.java

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package io.pkts.packet.sip.header;

import io.pkts.buffer.Buffer;
import io.pkts.buffer.Buffers;
import io.pkts.packet.sip.SipParseException;
import io.pkts.packet.sip.header.impl.WWWAuthenticateHeaderImpl;


public interface WWWAuthenticateHeader extends SipHeader {

Buffer NAME = Buffers.wrap("WWW-Authenticate");

Buffer getRealm();

Buffer getNonce();

Buffer getAlgorithm();

Buffer getQop();

static WWWAuthenticateHeader frame(final Buffer buffer) throws SipParseException {
try {
return new WWWAuthenticateHeader.Builder(buffer).build();
} catch (final Exception e) {
throw new SipParseException(0, "Unable to frame the WWWAuthenticate header due to IOException", e);
}
}

@Override
default WWWAuthenticateHeader toWWWAuthenticateHeader() {
return this;
}


class Builder implements SipHeader.Builder<WWWAuthenticateHeader> {
private Buffer value;

private Buffer realm;
private Buffer nonce;
private Buffer algorithm;
private Buffer qop;

public Builder() {

}

public Builder(Buffer value) {
this.value = value;
}

@Override
public WWWAuthenticateHeader.Builder withValue(Buffer value) {
this.value = value;
return this;
}

public WWWAuthenticateHeader.Builder withRealm(Buffer realm) {
this.realm = realm;
return this;
}

public WWWAuthenticateHeader.Builder withNonce(Buffer nonce) {
this.nonce = nonce;
return this;
}

public WWWAuthenticateHeader.Builder withAlgorithm(Buffer algorithm) {
this.algorithm = algorithm;
return this;
}

public WWWAuthenticateHeader.Builder withQop(Buffer qop) {
this.qop = qop;
return this;
}

@Override
public WWWAuthenticateHeader build() throws SipParseException {
if (value == null &&
(this.realm == null && this.nonce == null)) {
throw new SipParseException("You must specify the [value] or [realm/nonce] of the WWWAuthenticate-Header");
}

if (this.value != null) {
return new WWWAuthenticateHeaderImpl(value);
} else {
return new WWWAuthenticateHeaderImpl(realm, nonce, algorithm, qop);
}
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public Address getAddress() {
return this.address;
}

@Override
public AddressParametersHeader.Builder copy() {
AddressParametersHeader.Builder b = AddressParametersHeader.with(getName());
b.withParameters(getRawParams());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
package io.pkts.packet.sip.header.impl;

import io.pkts.buffer.Buffer;
import io.pkts.buffer.Buffers;
import io.pkts.packet.sip.SipParseException;
import io.pkts.packet.sip.header.WWWAuthenticateHeader;
import io.pkts.packet.sip.impl.SipParser;

import java.util.LinkedHashMap;
import java.util.Map;

public class WWWAuthenticateHeaderImpl extends SipHeaderImpl implements WWWAuthenticateHeader {


private Map<Buffer, Buffer> paramMap = new LinkedHashMap<>();

private Buffer realm;
private Buffer nonce;
private Buffer algorithm;
private Buffer qop;


/**
* @param value
*/
public WWWAuthenticateHeaderImpl(Buffer value) {
super(WWWAuthenticateHeader.NAME, value);

Buffer original = value.clone();
Buffer params = null;
if (original.hasReadableBytes()) {
params = original.slice("Digest ".length(), original.getUpperBoundary());
}

final byte[] VALUE_END_1 = Buffers.wrap("\", ").getArray();
final byte[] VALUE_END_2 = Buffers.wrap(", ").getArray();

//WWW-Authenticate: Digest realm="10.32.26.25",
// nonce="bee3366b-cf59-476e-bc5e-334e0d65b386",
// algorithm=MD5,
// qop="auth"

try {
// 思路:
// 1 遇到[=]号是key结束,遇到[,]或[", ]或[\r\n]是value结束
// 2 每次遇"="或”,”标识lastMarkIndex
int lastMarkIndex = params.getReaderIndex();
boolean inKey = true;
Buffer latestKey = Buffers.EMPTY_BUFFER, latestValue;
while (params.hasReadableBytes() && params.getReaderIndex() <= params.getUpperBoundary()) {
if (inKey && SipParser.isNext(params, SipParser.EQ)) {
//遇到[=]认为key结束
latestKey = params.slice(lastMarkIndex, params.getReaderIndex());
params.setReaderIndex(params.getReaderIndex() + 1);
if (SipParser.isNext(params, SipParser.DQUOT)) {
//跳过[="]等号后的第1个双引号
params.setReaderIndex(params.getReaderIndex() + 1);
inKey = false;
}
lastMarkIndex = params.getReaderIndex();
} else if (params.getReadableBytes() == 1 ||
SipParser.isNext(params, VALUE_END_1) ||
SipParser.isNext(params, VALUE_END_2)) {
//遇到[", ]或[, ]视为value结束
if (params.getReadableBytes() == 1 && params.peekByte() != SipParser.DQUOT) {
latestValue = params.slice(lastMarkIndex, params.getReaderIndex() + 1);
} else {
latestValue = params.slice(lastMarkIndex, params.getReaderIndex());
}

paramMap.put(latestKey, latestValue);

if (params.getReadableBytes() == 1) {
params.setReaderIndex(params.getReaderIndex() + 1);
} else if (SipParser.isNext(params, VALUE_END_1)) {
params.setReaderIndex(params.getReaderIndex() + VALUE_END_1.length);
} else if (SipParser.isNext(params, VALUE_END_2)) {
params.setReaderIndex(params.getReaderIndex() + VALUE_END_2.length);
}

lastMarkIndex = params.getReaderIndex();

inKey = true;
} else {
params.setReaderIndex(params.getReaderIndex() + 1);
}
}
} catch (Exception e) {
throw new SipParseException(NAME + " parse error, " + e.getCause());
}
}


public WWWAuthenticateHeaderImpl(Buffer realm, Buffer nonce, Buffer algorithm, Buffer qop) {
super(WWWAuthenticateHeader.NAME, Buffers.EMPTY_BUFFER);
this.realm = realm;
this.nonce = nonce;
this.algorithm = algorithm;
this.qop = qop;
}

@Override
public Buffer getValue() {
Buffer value = super.getValue();
if (value != null && value != Buffers.EMPTY_BUFFER) {
return value;
}
StringBuilder sb = new StringBuilder("Digest realm=\"" + this.getRealm() + "\", nonce=\"" + this.getNonce() + "\"");
if (this.getAlgorithm() != null) {
sb.append(", algorithm=" + this.getAlgorithm());
}
if (this.getQop() != null) {
sb.append(", qop=\"" + this.getQop() + "\"");
}
value = Buffers.wrap(sb.toString());
return value;
}

@Override
public String toString() {
StringBuilder sb = new StringBuilder(NAME.toString());
sb.append(": Digest realm=\"" + this.getRealm() + "\", nonce=\"" + this.getNonce() + "\"");
if (this.getAlgorithm() != null) {
sb.append(", algorithm=" + this.getAlgorithm());
}
if (this.getQop() != null) {
sb.append(", qop=\"" + this.getQop() + "\"");
}
return sb.toString();
}


@Override
public WWWAuthenticateHeader.Builder copy() {
return new WWWAuthenticateHeader.Builder(getValue());
}

@Override
public WWWAuthenticateHeader ensure() {
return this;
}

@Override
public WWWAuthenticateHeader clone() {
final Buffer value = getValue();
return new WWWAuthenticateHeaderImpl(value.clone());
}

@Override
public Buffer getRealm() {
if (realm != null) {
return realm;
}
realm = paramMap.get(Buffers.wrap("realm"));
return realm;
}

@Override
public Buffer getNonce() {
if (nonce != null) {
return nonce;
}
nonce = paramMap.get(Buffers.wrap("nonce"));
return nonce;
}

@Override
public Buffer getAlgorithm() {
if (algorithm != null) {
return algorithm;
}
algorithm = paramMap.get(Buffers.wrap("algorithm"));
return algorithm;
}

@Override
public Buffer getQop() {
if (qop != null) {
return qop;
}
qop = paramMap.get(Buffers.wrap("qop"));
return qop;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,7 @@
import io.pkts.buffer.Buffer;
import io.pkts.packet.sip.SipMessage;
import io.pkts.packet.sip.SipParseException;
import io.pkts.packet.sip.header.CSeqHeader;
import io.pkts.packet.sip.header.CallIdHeader;
import io.pkts.packet.sip.header.ContactHeader;
import io.pkts.packet.sip.header.ContentLengthHeader;
import io.pkts.packet.sip.header.ContentTypeHeader;
import io.pkts.packet.sip.header.ExpiresHeader;
import io.pkts.packet.sip.header.FromHeader;
import io.pkts.packet.sip.header.MaxForwardsHeader;
import io.pkts.packet.sip.header.RecordRouteHeader;
import io.pkts.packet.sip.header.RouteHeader;
import io.pkts.packet.sip.header.SipHeader;
import io.pkts.packet.sip.header.ToHeader;
import io.pkts.packet.sip.header.ViaHeader;
import io.pkts.packet.sip.header.*;

import java.util.ArrayList;
import java.util.Collections;
Expand Down Expand Up @@ -239,6 +227,12 @@ public ExpiresHeader getExpiresHeader() throws SipParseException {
return header != null ? header.ensure().toExpiresHeader() : null;
}

@Override
public WWWAuthenticateHeader getWWWAuthenticateHeader() throws SipParseException{
final SipHeader header = findHeader(WWWAuthenticateHeader.NAME.toString());
return header != null ? header.ensure().toWWWAuthenticateHeader() : null;
}

@Override
public ContactHeader getContactHeader() throws SipParseException {
return contactHeader != null ? contactHeader.ensure().toContactHeader() : null;
Expand Down
Loading