Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
P
Pcap-Net
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
Pcap-Net
Commits
65032c0f
Commit
65032c0f
authored
Jun 12, 2010
by
Brickner_cp
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Simple HTTP Header fields
parent
36d1d759
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
337 additions
and
227 deletions
+337
-227
HttpTests.cs
PcapDotNet/src/PcapDotNet.Packets.Test/HttpTests.cs
+63
-3
HttpCommaSeparatedField.cs
...et/src/PcapDotNet.Packets/Http/HttpCommaSeparatedField.cs
+169
-158
HttpDatagram.cs
PcapDotNet/src/PcapDotNet.Packets/Http/HttpDatagram.cs
+1
-1
HttpField.cs
PcapDotNet/src/PcapDotNet.Packets/Http/HttpField.cs
+51
-24
HttpHeader.cs
PcapDotNet/src/PcapDotNet.Packets/Http/HttpHeader.cs
+2
-2
HttpParser.cs
PcapDotNet/src/PcapDotNet.Packets/Http/HttpParser.cs
+51
-39
No files found.
PcapDotNet/src/PcapDotNet.Packets.Test/HttpTests.cs
View file @
65032c0f
using
System
;
using
System
;
using
System.Linq
;
using
System.Text
;
using
System.Text
;
using
Microsoft.VisualStudio.TestTools.UnitTesting
;
using
Microsoft.VisualStudio.TestTools.UnitTesting
;
using
PcapDotNet.Base
;
using
PcapDotNet.Packets.Ethernet
;
using
PcapDotNet.Packets.Ethernet
;
using
PcapDotNet.Packets.Http
;
using
PcapDotNet.Packets.Http
;
using
PcapDotNet.Packets.IpV4
;
using
PcapDotNet.Packets.IpV4
;
...
@@ -55,8 +57,59 @@ namespace PcapDotNet.Packets.Test
...
@@ -55,8 +57,59 @@ namespace PcapDotNet.Packets.Test
TestHttpRequest
(
"GET /url HTTP/1.1"
,
"GET"
,
"/url"
);
TestHttpRequest
(
"GET /url HTTP/1.1"
,
"GET"
,
"/url"
);
TestHttpRequest
(
"GET HTTP/1.1"
,
"GET"
,
""
,
HttpVersion
.
Version11
);
TestHttpRequest
(
"GET HTTP/1.1"
,
"GET"
,
""
,
HttpVersion
.
Version11
);
TestHttpRequest
(
"GET /url HTTP/1.1\r\nCache-Control: no-cache"
,
"GET"
,
"/url"
,
HttpVersion
.
Version11
,
TestHttpRequest
(
"GET /url HTTP/1.1\r\n"
+
new
HttpHeader
(
HttpField
.
Create
(
"Cache-Control"
,
Encoding
.
ASCII
.
GetBytes
(
"no-cache"
))));
"Cache-Control: no-cache\r\n"
,
"GET"
,
"/url"
,
HttpVersion
.
Version11
,
new
HttpHeader
(
new
HttpField
(
"Cache-Control"
,
"no-cache"
)));
TestHttpRequest
(
"GET /url HTTP/1.1\r\n"
+
"A:B\r\n"
+
"B: C\r\n"
+
"C: \r\n \r\n D\r\n"
+
"D: E\r\n"
+
"D: F\r\n"
+
"E: G,H\r\n"
+
"E: I,J\r\n"
,
"GET"
,
"/url"
,
HttpVersion
.
Version11
,
new
HttpHeader
(
new
HttpField
(
"A"
,
"B"
),
new
HttpField
(
"B"
,
"C"
),
new
HttpField
(
"C"
,
"D"
),
new
HttpField
(
"D"
,
"E,F"
),
new
HttpField
(
"E"
,
"G,H,I,J"
)));
TestHttpRequest
(
"GET /url HTTP/1.1\r\n"
+
"\r\n"
+
"A: B\r\n"
,
"GET"
,
"/url"
,
HttpVersion
.
Version11
,
new
HttpHeader
());
TestHttpRequest
(
"GET /url HTTP/1.1\r\n"
+
"A: B\r\n"
+
"\r\n"
+
"B: C\r\n"
,
"GET"
,
"/url"
,
HttpVersion
.
Version11
,
new
HttpHeader
(
new
HttpField
(
"A"
,
"B"
)));
TestHttpRequest
(
"GET /url HTTP/1.1\r\n"
+
"A: B\r\n"
+
"abc\r\n"
+
"B: C\r\n"
,
"GET"
,
"/url"
,
HttpVersion
.
Version11
,
new
HttpHeader
(
new
HttpField
(
"A"
,
"B"
)));
TestHttpRequest
(
"GET /url HTTP/1.1\r\n"
+
"A: B\r\n"
+
"abc:\r\n"
+
"B: C\r\n"
,
"GET"
,
"/url"
,
HttpVersion
.
Version11
,
new
HttpHeader
(
new
HttpField
(
"A"
,
"B"
),
new
HttpField
(
"abc"
,
""
),
new
HttpField
(
"B"
,
"C"
)));
TestHttpResponse
(
"HTTP/"
);
TestHttpResponse
(
"HTTP/"
);
TestHttpResponse
(
"HTTP/1"
);
TestHttpResponse
(
"HTTP/1"
);
...
@@ -70,6 +123,12 @@ namespace PcapDotNet.Packets.Test
...
@@ -70,6 +123,12 @@ namespace PcapDotNet.Packets.Test
TestHttpResponse
(
"HTTP/1.1 200 OK"
,
HttpVersion
.
Version11
,
200
,
"OK"
);
TestHttpResponse
(
"HTTP/1.1 200 OK"
,
HttpVersion
.
Version11
,
200
,
"OK"
);
TestHttpResponse
(
"HTTP/1.1 200 OK"
,
HttpVersion
.
Version11
);
TestHttpResponse
(
"HTTP/1.1 200 OK"
,
HttpVersion
.
Version11
);
TestHttpResponse
(
"HTTP/1.1 200 OK"
,
HttpVersion
.
Version11
,
200
,
" OK"
);
TestHttpResponse
(
"HTTP/1.1 200 OK"
,
HttpVersion
.
Version11
,
200
,
" OK"
);
TestHttpResponse
(
"HTTP/1.1 200 OK\r\n"
+
"Cache-Control: no-cache\r\n"
,
HttpVersion
.
Version11
,
200
,
"OK"
,
new
HttpHeader
(
new
HttpField
(
"Cache-Control"
,
"no-cache"
)));
}
}
private
static
void
TestHttpRequest
(
string
httpString
,
string
expectedMethod
=
null
,
string
expectedUri
=
null
,
HttpVersion
expectedVersion
=
null
,
HttpHeader
expectedHeader
=
null
)
private
static
void
TestHttpRequest
(
string
httpString
,
string
expectedMethod
=
null
,
string
expectedUri
=
null
,
HttpVersion
expectedVersion
=
null
,
HttpHeader
expectedHeader
=
null
)
...
@@ -91,7 +150,7 @@ namespace PcapDotNet.Packets.Test
...
@@ -91,7 +150,7 @@ namespace PcapDotNet.Packets.Test
// Assert.IsNotNull(header);
// Assert.IsNotNull(header);
}
}
private
static
void
TestHttpResponse
(
string
httpString
,
HttpVersion
expectedVersion
=
null
,
uint
?
expectedStatusCode
=
null
,
string
expectedReasonPhrase
=
null
)
private
static
void
TestHttpResponse
(
string
httpString
,
HttpVersion
expectedVersion
=
null
,
uint
?
expectedStatusCode
=
null
,
string
expectedReasonPhrase
=
null
,
HttpHeader
expectedHeader
=
null
)
{
{
Packet
packet
=
BuildPacket
(
httpString
);
Packet
packet
=
BuildPacket
(
httpString
);
...
@@ -100,6 +159,7 @@ namespace PcapDotNet.Packets.Test
...
@@ -100,6 +159,7 @@ namespace PcapDotNet.Packets.Test
Assert
.
IsFalse
(
http
.
IsRequest
,
"IsRequest "
+
httpString
);
Assert
.
IsFalse
(
http
.
IsRequest
,
"IsRequest "
+
httpString
);
Assert
.
IsTrue
(
http
.
IsResponse
,
"IsResponse "
+
httpString
);
Assert
.
IsTrue
(
http
.
IsResponse
,
"IsResponse "
+
httpString
);
Assert
.
AreEqual
(
expectedVersion
,
http
.
Version
,
"Version "
+
httpString
);
Assert
.
AreEqual
(
expectedVersion
,
http
.
Version
,
"Version "
+
httpString
);
Assert
.
AreEqual
(
expectedHeader
,
http
.
Header
,
"Header "
+
httpString
);
HttpResponseDatagram
response
=
(
HttpResponseDatagram
)
http
;
HttpResponseDatagram
response
=
(
HttpResponseDatagram
)
http
;
Assert
.
AreEqual
(
expectedStatusCode
,
response
.
StatusCode
,
"StatusCode "
+
httpString
);
Assert
.
AreEqual
(
expectedStatusCode
,
response
.
StatusCode
,
"StatusCode "
+
httpString
);
...
...
PcapDotNet/src/PcapDotNet.Packets/Http/HttpCommaSeparatedField.cs
View file @
65032c0f
using
System
;
//using System;
using
System.Collections
;
//using System.Collections;
using
System.Collections.Generic
;
//using System.Collections.Generic;
using
System.Collections.ObjectModel
;
//using System.Collections.ObjectModel;
using
System.Linq
;
//using System.Linq;
using
System.Text
;
//using System.Text;
using
PcapDotNet.Base
;
//using System.Text.RegularExpressions;
using
IListExtensions
=
PcapDotNet
.
Base
.
IListExtensions
;
//using PcapDotNet.Base;
//using IListExtensions = PcapDotNet.Base.IListExtensions;
namespace
PcapDotNet.Packets.Http
//
{
//namespace PcapDotNet.Packets.Http
public
class
HttpCommaSeparatedField
:
HttpField
,
IEnumerable
<
HttpCommaSeparatedInnerField
>,
IEquatable
<
HttpCommaSeparatedField
>
//{
{
// public class HttpCommaSeparatedField : HttpField, IEnumerable<HttpCommaSeparatedInnerField>, IEquatable<HttpCommaSeparatedField>
// {
internal
HttpCommaSeparatedField
(
string
name
,
params
HttpCommaSeparatedInnerField
[]
value
)
//
:
this
(
name
,
(
IEnumerable
<
HttpCommaSeparatedInnerField
>)
value
)
// internal HttpCommaSeparatedField(string name, params HttpCommaSeparatedInnerField[] value)
{
// :this(name, (IEnumerable<HttpCommaSeparatedInnerField>)value)
}
// {
// }
internal
HttpCommaSeparatedField
(
string
name
,
IEnumerable
<
HttpCommaSeparatedInnerField
>
value
=
null
)
//
:
base
(
name
)
// internal HttpCommaSeparatedField(string name, IEnumerable<HttpCommaSeparatedInnerField> value = null)
{
// :base(name)
_innerFields
=
value
==
null
?
null
:
value
.
ToDictionary
(
innerField
=>
innerField
.
Name
,
innerField
=>
innerField
);
// {
}
// _innerFields = value == null ? null : value.ToDictionary(innerField => innerField.Name, innerField => innerField);
// }
public
bool
Equals
(
HttpCommaSeparatedField
other
)
//
{
// public bool Equals(HttpCommaSeparatedField other)
return
base
.
Equals
(
other
)
&&
_innerFields
.
DictionaryEquals
(
other
.
_innerFields
);
// {
}
// return base.Equals(other) && _innerFields.DictionaryEquals(other._innerFields);
// }
public
override
string
ToString
()
//
{
// public override string ToString()
return
base
.
ToString
()
+
(
_innerFields
==
null
?
string
.
Empty
:
_innerFields
.
Values
.
SequenceToString
(
","
));
// {
}
// return base.ToString() + (_innerFields == null ? string.Empty : _innerFields.Values.SequenceToString(","));
// }
internal
HttpCommaSeparatedField
(
string
name
,
IEnumerable
<
byte
>
value
)
//
:
base
(
name
)
// internal HttpCommaSeparatedField(string name, byte[] value)
{
// :base(name)
var
innerFields
=
new
Dictionary
<
string
,
List
<
ReadOnlyCollection
<
byte
>>>();
// {
foreach
(
var
commaValue
in
CommaSeparate
(
value
))
// string valueString = new string(value.Select(b => (char)b).ToArray());
{
// Regex regex = new Regex(Regex.);
string
innerFieldName
=
commaValue
.
Key
;
// HttpParser parser = new HttpParser(value);
// while (parser.Success)
List
<
ReadOnlyCollection
<
byte
>>
innerFieldValues
;
// {
if
(!
innerFields
.
TryGetValue
(
innerFieldName
,
out
innerFieldValues
))
// string directiveName;
{
// parser.Token(out directiveName);
innerFieldValues
=
new
List
<
ReadOnlyCollection
<
byte
>>();
// if (parser.)
innerFields
.
Add
(
innerFieldName
,
innerFieldValues
);
// if (parser..Skip(AsciiBytes.Space)
}
// }
innerFieldValues
.
Add
(
commaValue
.
Value
==
null
?
null
:
commaValue
.
Value
.
ToArray
().
AsReadOnly
());
// var innerFields = new Dictionary<string, List<ReadOnlyCollection<byte>>>();
}
// foreach (var commaValue in CommaSeparate(value))
// {
_innerFields
=
innerFields
.
ToDictionary
(
field
=>
field
.
Key
,
field
=>
new
HttpCommaSeparatedInnerField
(
field
.
Key
,
field
.
Value
));
// string innerFieldName = commaValue.Key;
}
//
// List<ReadOnlyCollection<byte>> innerFieldValues;
private
static
IEnumerable
<
KeyValuePair
<
string
,
IEnumerable
<
byte
>>>
CommaSeparate
(
IEnumerable
<
byte
>
buffer
)
// if (!innerFields.TryGetValue(innerFieldName, out innerFieldValues))
{
// {
do
// innerFieldValues = new List<ReadOnlyCollection<byte>>();
{
// innerFields.Add(innerFieldName, innerFieldValues);
string
key
=
Encoding
.
ASCII
.
GetString
(
buffer
.
TakeWhile
(
b
=>
b
.
IsToken
()).
ToArray
());
// }
if
(
key
.
Length
==
0
)
// innerFieldValues.Add(commaValue.Value == null ? null : commaValue.Value.ToArray().AsReadOnly());
yield
break
;
// }
//
buffer
=
buffer
.
Skip
(
key
.
Length
);
// _innerFields = innerFields.ToDictionary(field => field.Key, field => new HttpCommaSeparatedInnerField(field.Key, field.Value));
if
(!
buffer
.
Any
())
// }
{
//
yield
return
new
KeyValuePair
<
string
,
IEnumerable
<
byte
>>(
key
,
null
);
// private static IEnumerable<KeyValuePair<string, IEnumerable<byte>>> CommaSeparate(IEnumerable<byte> buffer)
continue
;
// {
}
// do
// {
switch
(
buffer
.
First
())
// string key = Encoding.ASCII.GetString(buffer.TakeWhile(b => b.IsToken()).ToArray());
{
// if (key.Length == 0)
case
AsciiBytes
.
EqualsSign
:
// yield break;
buffer
=
buffer
.
Skip
(
1
);
//
IEnumerable
<
byte
>
value
=
buffer
;
// buffer = buffer.Skip(key.Length);
int
count
=
0
;
// if (!buffer.Any())
if
(
buffer
.
Any
())
// {
{
// yield return new KeyValuePair<string, IEnumerable<byte>>(key, null);
byte
valueByte
=
buffer
.
First
();
// continue;
if
(
valueByte
.
IsToken
())
// Token value
// }
count
=
1
+
buffer
.
Skip
(
1
).
TakeWhile
(
b
=>
b
.
IsToken
()).
Count
();
//
else
if
(!
TryExtractQuotedString
(
buffer
,
out
count
))
// Not Quoted value - Illegal value
// switch (buffer.First())
yield
break
;
// {
buffer
=
buffer
.
Skip
(
count
);
// case AsciiBytes.EqualsSign:
}
// buffer = buffer.Skip(1);
yield
return
new
KeyValuePair
<
string
,
IEnumerable
<
byte
>>(
key
,
value
.
Take
(
count
));
// IEnumerable<byte> value = buffer;
// int count = 0;
if
(!
buffer
.
Any
())
// if (buffer.Any())
yield
break
;
// {
switch
(
buffer
.
First
())
// byte valueByte = buffer.First();
{
// if (valueByte.IsToken()) // Token value
case
AsciiBytes
.
Comma
:
// count = 1 + buffer.Skip(1).TakeWhile(b => b.IsToken()).Count();
case
AsciiBytes
.
Space
:
// else if (!TryExtractQuotedString(buffer, out count)) // Not Quoted value - Illegal value
buffer
=
buffer
.
Skip
(
1
).
SkipWhile
(
b
=>
b
==
AsciiBytes
.
Space
||
b
==
AsciiBytes
.
Comma
);
// yield break;
break
;
// buffer = buffer.Skip(count);
// }
default
:
// yield return new KeyValuePair<string, IEnumerable<byte>>(key, value.Take(count));
yield
break
;
//
}
// if (!buffer.Any())
break
;
// yield break;
// switch (buffer.First())
case
AsciiBytes
.
Comma
:
// {
case
AsciiBytes
.
Space
:
// case AsciiBytes.Comma:
yield
return
new
KeyValuePair
<
string
,
IEnumerable
<
byte
>>(
key
,
null
);
// case AsciiBytes.Space:
buffer
=
buffer
.
Skip
(
1
).
SkipWhile
(
b
=>
b
==
AsciiBytes
.
Space
||
b
==
AsciiBytes
.
Comma
);
// buffer = buffer.Skip(1).SkipWhile(b => b == AsciiBytes.Space || b == AsciiBytes.Comma);
break
;
// break;
//
default
:
// default:
yield
break
;
// yield break;
}
// }
}
while
(
buffer
.
Any
());
// break;
}
//
// case AsciiBytes.Comma:
private
static
bool
TryExtractQuotedString
(
IEnumerable
<
byte
>
buffer
,
out
int
count
)
// case AsciiBytes.Space:
{
// yield return new KeyValuePair<string, IEnumerable<byte>>(key, null);
count
=
0
;
// buffer = buffer.Skip(1).SkipWhile(b => b == AsciiBytes.Space || b == AsciiBytes.Comma);
if
(!
buffer
.
Any
()
||
buffer
.
First
()
!=
AsciiBytes
.
DoubleQuotationMark
)
// break;
return
false
;
//
// default:
++
count
;
// yield break;
buffer
=
buffer
.
Skip
(
1
);
// }
// } while (buffer.Any());
while
(
buffer
.
Any
())
// }
{
//
++
count
;
// private static bool TryExtractQuotedString(IEnumerable<byte> buffer, out int count)
byte
current
=
buffer
.
First
();
// {
// count = 0;
if
(
current
==
AsciiBytes
.
DoubleQuotationMark
)
// if (!buffer.Any() || buffer.First() != AsciiBytes.DoubleQuotationMark)
return
true
;
// return false;
//
buffer
=
buffer
.
Skip
(
1
);
// ++count;
if
(
current
==
AsciiBytes
.
BackSlash
&&
buffer
.
Any
())
// buffer = buffer.Skip(1);
{
//
current
=
buffer
.
First
();
// while (buffer.Any())
if
(
current
.
IsChar
())
// {
{
// ++count;
buffer
=
buffer
.
Skip
(
1
);
// byte current = buffer.First();
++
count
;
//
}
// if (current == AsciiBytes.DoubleQuotationMark)
}
// return true;
}
//
// buffer = buffer.Skip(1);
return
false
;
// if (current == AsciiBytes.BackSlash && buffer.Any())
}
// {
// current = buffer.First();
public
IEnumerator
<
HttpCommaSeparatedInnerField
>
GetEnumerator
()
// if (current.IsChar())
{
// {
return
_innerFields
.
Values
.
GetEnumerator
();
// buffer = buffer.Skip(1);
}
// ++count;
// }
IEnumerator
IEnumerable
.
GetEnumerator
()
// }
{
// }
return
GetEnumerator
();
//
}
// return false;
// }
private
readonly
Dictionary
<
string
,
HttpCommaSeparatedInnerField
>
_innerFields
;
//
}
// public IEnumerator<HttpCommaSeparatedInnerField> GetEnumerator()
}
// {
\ No newline at end of file
// return _innerFields.Values.GetEnumerator();
// }
//
// IEnumerator IEnumerable.GetEnumerator()
// {
// return GetEnumerator();
// }
//
// private readonly Dictionary<string, HttpCommaSeparatedInnerField> _innerFields;
// }
//}
\ No newline at end of file
PcapDotNet/src/PcapDotNet.Packets/Http/HttpDatagram.cs
View file @
65032c0f
...
@@ -262,7 +262,7 @@ namespace PcapDotNet.Packets.Http
...
@@ -262,7 +262,7 @@ namespace PcapDotNet.Packets.Http
{
{
string
fieldName
;
string
fieldName
;
IEnumerable
<
byte
>
fieldValue
;
IEnumerable
<
byte
>
fieldValue
;
parser
.
Token
(
out
fieldName
).
Colon
().
FieldValue
(
out
fieldValue
);
parser
.
Token
(
out
fieldName
).
Colon
().
FieldValue
(
out
fieldValue
)
.
CarraigeReturnLineFeed
()
;
if
(
parser
.
Success
)
if
(
parser
.
Success
)
yield
return
new
KeyValuePair
<
string
,
IEnumerable
<
byte
>>(
fieldName
,
fieldValue
);
yield
return
new
KeyValuePair
<
string
,
IEnumerable
<
byte
>>(
fieldName
,
fieldValue
);
}
}
...
...
PcapDotNet/src/PcapDotNet.Packets/Http/HttpField.cs
View file @
65032c0f
using
System
;
using
System
;
using
System.Collections.Generic
;
using
System.Collections.Generic
;
using
System.Collections.ObjectModel
;
using
System.Linq
;
using
System.Text
;
using
PcapDotNet.Base
;
namespace
PcapDotNet.Packets.Http
namespace
PcapDotNet.Packets.Http
{
{
public
class
HttpField
:
IEquatable
<
HttpField
>
public
class
HttpField
:
IEquatable
<
HttpField
>
{
{
public
static
HttpField
Create
(
string
name
,
IEnumerable
<
byte
>
value
)
public
HttpField
(
string
name
,
string
value
)
:
this
(
name
,
value
,
_defaultEncoding
)
{
}
public
HttpField
(
string
name
,
string
value
,
Encoding
encoding
)
:
this
(
name
,
encoding
.
GetBytes
(
value
))
{
}
public
HttpField
(
string
name
,
IEnumerable
<
byte
>
value
)
:
this
(
name
,
value
.
ToArray
())
{
}
public
HttpField
(
string
name
,
IList
<
byte
>
value
)
:
this
(
name
,
value
.
AsReadOnly
())
{
{
switch
(
name
)
{
// general-header
case
"Cache-Control"
:
return
new
HttpCommaSeparatedField
(
name
,
value
);
case
"Connection"
:
case
"Date"
:
case
"Pragma"
:
case
"Trailer"
:
case
"Transfer-Encoding"
:
case
"Upgrade"
:
case
"Via"
:
case
"Warning"
:
break
;
}
return
new
HttpField
(
name
);
}
}
public
HttpField
(
string
name
,
ReadOnlyCollection
<
byte
>
value
)
{
Name
=
name
;
Value
=
value
;
}
// public static HttpField Create(string name, byte[] value)
// {
// switch (name)
// {
// general-header
// case "Cache-Control":
// return new HttpCommaSeparatedField(name, value);
// case "Connection":
// case "Date":
// case "Pragma":
// case "Trailer":
// case "Transfer-Encoding":
// case "Upgrade":
// case "Via":
// case "Warning":
// break;
// }
//
// return new HttpField(name);
// }
public
string
Name
{
get
;
private
set
;
}
public
string
Name
{
get
;
private
set
;
}
public
ReadOnlyCollection
<
byte
>
Value
{
get
;
private
set
;
}
public
bool
Equals
(
HttpField
other
)
public
bool
Equals
(
HttpField
other
)
{
{
return
other
!=
null
&&
Name
.
Equals
(
other
.
Name
);
return
other
!=
null
&&
Name
.
Equals
(
other
.
Name
)
&&
Value
.
SequenceEqual
(
other
.
Value
)
;
}
}
public
override
bool
Equals
(
object
obj
)
public
override
bool
Equals
(
object
obj
)
...
@@ -40,12 +70,9 @@ namespace PcapDotNet.Packets.Http
...
@@ -40,12 +70,9 @@ namespace PcapDotNet.Packets.Http
public
override
string
ToString
()
public
override
string
ToString
()
{
{
return
string
.
Format
(
"{0}:
"
,
Name
);
return
string
.
Format
(
"{0}:
{1}"
,
Name
,
_defaultEncoding
.
GetString
(
Value
.
ToArray
())
);
}
}
internal
HttpField
(
string
name
)
private
static
readonly
Encoding
_defaultEncoding
=
Encoding
.
GetEncoding
(
28591
);
{
Name
=
name
;
}
}
}
}
}
\ No newline at end of file
PcapDotNet/src/PcapDotNet.Packets/Http/HttpHeader.cs
View file @
65032c0f
...
@@ -47,10 +47,10 @@ namespace PcapDotNet.Packets.Http
...
@@ -47,10 +47,10 @@ namespace PcapDotNet.Packets.Http
mergedFields
.
Add
(
fieldName
,
fieldValue
);
mergedFields
.
Add
(
fieldName
,
fieldValue
);
}
}
else
else
mergedFields
[
fieldName
]
=
fieldValue
.
Concat
(
AsciiBytes
.
Space
).
Concat
(
field
Value
);
mergedFields
[
fieldName
]
=
fieldValue
.
Concat
(
AsciiBytes
.
Comma
).
Concat
(
field
.
Value
);
}
}
_fields
=
mergedFields
.
ToDictionary
(
field
=>
field
.
Key
,
field
=>
HttpField
.
Create
(
field
.
Key
,
field
.
Value
));
_fields
=
mergedFields
.
ToDictionary
(
field
=>
field
.
Key
,
field
=>
new
HttpField
(
field
.
Key
,
field
.
Value
));
}
}
public
IEnumerator
<
HttpField
>
GetEnumerator
()
public
IEnumerator
<
HttpField
>
GetEnumerator
()
...
...
PcapDotNet/src/PcapDotNet.Packets/Http/HttpParser.cs
View file @
65032c0f
...
@@ -8,6 +8,11 @@ namespace PcapDotNet.Packets.Http
...
@@ -8,6 +8,11 @@ namespace PcapDotNet.Packets.Http
{
{
internal
class
HttpParser
internal
class
HttpParser
{
{
public
HttpParser
(
byte
[]
buffer
)
:
this
(
buffer
,
0
,
buffer
.
Length
)
{
}
public
HttpParser
(
byte
[]
buffer
,
int
offset
,
int
length
)
public
HttpParser
(
byte
[]
buffer
,
int
offset
,
int
length
)
{
{
_buffer
=
buffer
;
_buffer
=
buffer
;
...
@@ -43,31 +48,6 @@ namespace PcapDotNet.Packets.Http
...
@@ -43,31 +48,6 @@ namespace PcapDotNet.Packets.Http
return
this
;
return
this
;
}
}
private
HttpParser
Bytes
(
byte
value
)
{
if
(!
Success
)
return
this
;
var
range
=
Range
;
if
(!
range
.
Any
()
||
range
.
First
()
!=
value
)
return
Fail
();
++
_offset
;
return
this
;
}
private
HttpParser
Bytes
(
params
byte
[]
values
)
{
if
(!
Success
)
return
this
;
if
(!
Range
.
Take
(
values
.
Length
).
SequenceEqual
(
values
))
return
Fail
();
_offset
+=
values
.
Length
;
return
this
;
}
public
HttpParser
Colon
()
public
HttpParser
Colon
()
{
{
return
Bytes
(
AsciiBytes
.
Colon
);
return
Bytes
(
AsciiBytes
.
Colon
);
...
@@ -83,8 +63,6 @@ namespace PcapDotNet.Packets.Http
...
@@ -83,8 +63,6 @@ namespace PcapDotNet.Packets.Http
return
Bytes
(
AsciiBytes
.
Space
);
return
Bytes
(
AsciiBytes
.
Space
);
}
}
public
HttpParser
SkipLws
()
public
HttpParser
SkipLws
()
{
{
while
(
true
)
while
(
true
)
...
@@ -150,17 +128,6 @@ namespace PcapDotNet.Packets.Http
...
@@ -150,17 +128,6 @@ namespace PcapDotNet.Packets.Http
return
this
;
return
this
;
}
}
private
HttpParser
Fail
()
{
Success
=
false
;
return
this
;
}
private
IEnumerable
<
byte
>
Range
{
get
{
return
_buffer
.
Range
(
_offset
,
_totalLength
-
_offset
);
}
}
public
HttpParser
RequestUri
(
out
string
uri
)
public
HttpParser
RequestUri
(
out
string
uri
)
{
{
if
(!
Success
)
if
(!
Success
)
...
@@ -248,12 +215,57 @@ namespace PcapDotNet.Packets.Http
...
@@ -248,12 +215,57 @@ namespace PcapDotNet.Packets.Http
return
this
;
return
this
;
}
}
int
reasonPhraseLength
=
Range
.
Count
(
value
=>
!
value
.
IsControl
()
||
value
==
AsciiBytes
.
HorizontalTab
);
int
count
=
0
;
foreach
(
byte
b
in
Range
)
{
if
(!
b
.
IsControl
()
||
b
==
AsciiBytes
.
HorizontalTab
)
++
count
;
else
break
;
}
Console
.
WriteLine
(
count
);
int
reasonPhraseLength
=
Range
.
TakeWhile
(
value
=>
!
value
.
IsControl
()
||
value
==
AsciiBytes
.
HorizontalTab
).
Count
();
reasonPhrase
=
new
Datagram
(
_buffer
,
_offset
,
reasonPhraseLength
);
reasonPhrase
=
new
Datagram
(
_buffer
,
_offset
,
reasonPhraseLength
);
_offset
+=
reasonPhraseLength
;
_offset
+=
reasonPhraseLength
;
return
this
;
return
this
;
}
}
private
HttpParser
Fail
()
{
Success
=
false
;
return
this
;
}
private
IEnumerable
<
byte
>
Range
{
get
{
return
_buffer
.
Range
(
_offset
,
_totalLength
-
_offset
);
}
}
private
HttpParser
Bytes
(
byte
value
)
{
if
(!
Success
)
return
this
;
var
range
=
Range
;
if
(!
range
.
Any
()
||
range
.
First
()
!=
value
)
return
Fail
();
++
_offset
;
return
this
;
}
private
HttpParser
Bytes
(
params
byte
[]
values
)
{
if
(!
Success
)
return
this
;
if
(!
Range
.
Take
(
values
.
Length
).
SequenceEqual
(
values
))
return
Fail
();
_offset
+=
values
.
Length
;
return
this
;
}
private
static
readonly
byte
[]
_httpSlash
=
Encoding
.
ASCII
.
GetBytes
(
"HTTP/"
);
private
static
readonly
byte
[]
_httpSlash
=
Encoding
.
ASCII
.
GetBytes
(
"HTTP/"
);
private
readonly
byte
[]
_buffer
;
private
readonly
byte
[]
_buffer
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment