// NewHTTPExchange creates and returns a HTTPExchange with the given packet data.
// it is important that the packet with the HTTP request be present in d[0], and
// it is assumed that the ACK for the last packet of response is in d[len(d)-1].
// Having a valid respIndex for the first packet of the response containing the 
// HTTP response header will speed this up, if it is not valid (<0 if unknown)
// then this method will search for it.  The Data for the HTTPExchange is a
// slice backed by the same array as d.
//
// This method does not check the rest of d to make sure that the packets are in
// fact part of this transfer, so only pass what should be used.
NewHTTPExchange creates and returns a HTTPExchange with the given packet data.
it is important that the packet with the HTTP request be present in d[0], and
it is assumed that the ACK for the last packet of response is in d[len(d)-1].
Having a valid respIndex for the first packet of the response containing the
HTTP response header will speed this up, if it is not valid (<0 if unknown)
then this method will search for it.  The Data for the HTTPExchange is a
slice backed by the same array as d.

This method does not check the rest of d to make sure that the packets are in
fact part of this transfer, so only pass what should be used.
// NewHTTPExchange creates and returns a HTTPExchange with the given packet data . // it is important that the packet with the HTTP request be present in d [ 0 ] and // it is assumed that the ACK for the last packet of response is in d [ len ( d ) - 1 ] . // Having a valid respIndex for the first packet of the response containing the // HTTP response header will speed this up if it is not valid ( <0 if unknown ) // then this method will search for it . The Data for the HTTPExchange is a // slice backed by the same array as d . // // This method does not check the rest of d to make sure that the packets are in // fact part of this transfer so only pass what should be used .
func NewHTTPExchange(d []*pkt.Packet, respIndex int) (*HTTPExchange, error) {
	var (
		httpHdr *pkt.HttpHdr 
		ok      bool         
	)
	e := &HTTPExchange{
		TCPTuple: &TCPTuple{
			Src: &net.TCPAddr{},
			Dst: &net.TCPAddr{},
		},
		Data: d,
		Resp: -1,
	}
	if len(d) == 0 {
		return e, ErrEmptyData
	}
	if len(d[0].Headers) > ApplicationLayer {
		ip, ok := d[0].Headers[pkt.NetworkLayer].(pkt.InetProtoHdr)
		if !ok || ip == nil {
			return e, ErrNetworkLayerHeader
		}
		tcp, ok := d[0].Headers[pkt.TransportLayer].(*pkt.TcpHdr)
		if !ok || tcp == nil {
			return e, ErrTransportLayerHeader
		}
		httpHdr, ok = d[0].Headers[ApplicationLayer].(*pkt.HttpHdr)
		if !ok || httpHdr == nil || httpHdr.StatusCode != 0 {
			return e, ErrApplicationLayerHeader
		}
		e.TCPTuple.Dst.IP = ip.Src()
		e.TCPTuple.Src.IP = ip.Dst()
		e.TCPTuple.Dst.Port = int(tcp.Source)
		e.TCPTuple.Src.Port = int(tcp.Dest)
		e.ReqHTTPHdr = httpHdr
	} else {
		return e, ErrApplicationLayerHeader
	}
	if respIndex > 0 && respIndex < len(d) {
		if len(d[respIndex].Headers) > ApplicationLayer {
			httpHdr, ok = d[respIndex].Headers[ApplicationLayer].(*pkt.HttpHdr)
			if ok {
				e.Resp = respIndex
				e.RespHTTPHdr = httpHdr
				return e, nil
			}
		}
	}
	for i := 1; i < len(d); i++ {
		if len(d[i].Headers) > ApplicationLayer {
			httpHdr, ok = d[i].Headers[ApplicationLayer].(*pkt.HttpHdr)
			if ok {
				if httpHdr.StatusCode > 0 {
					e.Resp = respIndex
					e.RespHTTPHdr = httpHdr
					return e, nil
				}
			}
		}
	}
	return e, nil
}
func NewHTTPExchange ( d [ ] * pkt . Packet , respIndex int ) ( * HTTPExchange , error ) { var ( httpHdr * pkt . HttpHdr ok bool ) e := & HTTPExchange { TCPTuple : & TCPTuple { Src : & net . TCPAddr { } , Dst : & net . TCPAddr { } , } , Data : d , Resp : - 1 , } if len ( d ) == 0 { return e , ErrEmptyData } if len ( d [ 0 ] . Headers ) > ApplicationLayer { ip , ok := d [ 0 ] . Headers [ pkt . NetworkLayer ] . ( pkt . InetProtoHdr ) if ! ok || ip == nil { return e , ErrNetworkLayerHeader } tcp , ok := d [ 0 ] . Headers [ pkt . TransportLayer ] . ( * pkt . TcpHdr ) if ! ok || tcp == nil { return e , ErrTransportLayerHeader } httpHdr , ok = d [ 0 ] . Headers [ ApplicationLayer ] . ( * pkt . HttpHdr ) if ! ok || httpHdr == nil || httpHdr . StatusCode != 0 { return e , ErrApplicationLayerHeader } e . TCPTuple . Dst . IP = ip . Src ( ) e . TCPTuple . Src . IP = ip . Dst ( ) e . TCPTuple . Dst . Port = int ( tcp . Source ) e . TCPTuple . Src . Port = int ( tcp . Dest ) e . ReqHTTPHdr = httpHdr } else { return e , ErrApplicationLayerHeader } if respIndex > 0 && respIndex < len ( d ) { if len ( d [ respIndex ] . Headers ) > ApplicationLayer { httpHdr , ok = d [ respIndex ] . Headers [ ApplicationLayer ] . ( * pkt . HttpHdr ) if ok { e . Resp = respIndex e . RespHTTPHdr = httpHdr return e , nil } } } for i := 1 ; i < len ( d ) ; i ++ { if len ( d [ i ] . Headers ) > ApplicationLayer { httpHdr , ok = d [ i ] . Headers [ ApplicationLayer ] . ( * pkt . HttpHdr ) if ok { if httpHdr . StatusCode > 0 { e . Resp = respIndex e . RespHTTPHdr = httpHdr return e , nil } } } } return e , nil }
NewHTTPExchange creates and returns a HTTPExchange with the given packet data.
NewHTTPExchange creates and returns a HTTPExchange with the given packet data .
// HTTP header - to gather per-packet HTTP data // caste success indicator // We don't use the NewTCPTuple method here because we want to // swap the Src and Dst. // We got an invalid respIndex so we will have to look for it here.